企业级Docker虚拟化平台实战

企业级Docker虚拟化平台实战

1.虚拟化技术概述及简介

  • 通俗的说,虚拟化就是把物理资源转变为逻辑上可以管理的资源,以打破物理结构间的壁垒,计算元件运行在虚拟的基础上而不是真实的基础上,可以扩大硬件的容量,简化软件的重新配置过程。

  • 允许一个平台同时运行多个操作系统,并且应用程序都可以在相互独立的空间内运行而互不影响,从而显著提高计算机的工作效率,是一个为了简化管理,优化资源的解决方案。

  • 目前主流的虚拟化技术主要有:KVM、Xen、VMware Esxi、VirtualBox、Docker,虚拟化技术也越来越广泛的应用在企业中,例如Taobao、Google等。

  • 虚拟化原理:虚拟化解决方案的底部是要进行虚拟化的物理机器,这台机器可能直接支持虚拟化,也可能不会直接支持虚拟化,那么就需要系统管理程序层的支持。

  • 系统管理程序(Virtual machine monitor),或称为 VMM,可以看作是平台硬件和操作系统的抽象化。在某些情况中,这个系统管理程序就是一个操作系统,此时它就称为主机操作系统。
    图 1. 虚拟化的分层抽象
    企业级Docker虚拟化平台实战_第1张图片

  • 完全拟化技术实际上是通过软件实现对操作系统的资源再分配,比较成熟,例如我们的KVM、VirtualBOX;

  • 半虚拟化技术则是通过代码修改已有的系统,形成一种新的可虚拟化的系统,调用硬件资源去安装多个系统,整体速度上相对高一点,代表产品有Xen。

  • 轻量级虚拟化,Docker虚拟化(介于完全虚拟化、半虚拟化之间),轻量级虚拟化;

2.Docker虚拟化入门简介

  • Docker技术类似集装箱,最早集装箱没有出现的时候,码头上有许多搬运的工人在搬运货物,集装箱出现以后,码头上看到更多的不是工人,而且集装箱的搬运模式更加单一,更加高效,还有其他的好处。

  • 例如:货物多打包在集装箱里面,可以防止货物之间相互影响。并且到了另外一个码头需要转运的话,有了集装箱以后,直接把它运送到另一个容器内即可,完全可以保证里面的货物是整体的搬迁,并且不会损坏货物本身。如图所示:
    企业级Docker虚拟化平台实战_第2张图片

  • Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化

  • 容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app)。几乎没有性能开销,可以很容易地在机器和数据中心中运行。最重要的是,他们不依赖于任何语言、框架或包括系统。

  • Docker应该是近年最火爆的技术之一,如果没有听说过,那么你就out了,2018年将开启新的跨越。

  • Docker 自开源后受到广泛的关注和讨论,以至于 dotCloud 公司后来都改名为 Docker Inc。Redhat 已经在其 RHEL6.5 中集中支持Docker;Google 也在其 PaaS 产品中广泛应用。

  • Docker 项目的目标是实现轻量级的操作系统虚拟化解决方案。 Docker 的基础是 Linux 容器(LXC)等技术。在LXC的基础上 Docker 进行了进一步的封装,让用户不需要去关心容器的管理,使得操作更为简便。用户操作 Docker 的容器就像操作一个快速轻量级的虚拟机一样简单。

  • 下面对比了Docker 和传统虚拟化(KVM、XEN等)方式的不同之处,Docker容器是在操作系统层面上实现虚拟化,直接复用本地主机的操作系统,而传统方式则是在硬件的基础上,虚拟出自己的系统,再在系统上部署相关的APP应用。

  • 下图为传统虚拟化方案需要部署Nginx,先部署OS系统,基于OS系统再部署Nginx;
    企业级Docker虚拟化平台实战_第3张图片

  • 如下为Docker虚拟化方案需要部署Nginx,无需部署OS系统,基于Docker引擎直接部署Nginx;
    企业级Docker虚拟化平台实战_第4张图片

  • Docker虚拟化有三个概念需要理解,分别镜像、容器、仓库

  • 镜像:Docker的镜像其实就是模板,跟我们常见的ISO镜像类似,是一个样板。

  • 容器:使用镜像常见的应用或者系统,我们称之为一个容器。

  • 仓库:仓库是存放镜像的地方,分为公开仓库(Public)和私有仓库(Private)两种形式。

3.Docker虚拟化特点

3.1跟传统VM比较具有如下优点:

  • 操作启动快

运行时的性能可以获取极大提升,管理操作(启动,停止,开始,重启等等) 都是以秒或毫秒为单位的。

  • 轻量级虚拟化

你会拥有足够的“操作系统”,仅需添加或减小镜像即可。在一台服务器上可以布署100~1000个Containers容器。但是传统虚拟化,你虚拟10-20个虚拟机就不错了。

  • 开源免费

开源的,免费的,低成本的。由现代Linux内核支持并驱动。注*
轻量的Container必定可以在一个物理机上开启更多“容器”,注定比VMs要便宜。

  • 前景及云支持

正在越来越受欢迎,包括各大主流公司都在推动docker的快速发展,性能有很大的优势。

3.2.跟传统VM比较具有如下缺点:

目前知道的人比较少; 相关的中文技术资料欠缺; Go语言还未完全成熟。

4.为什么使用docker

4.1.Docker 在如下几个方面具有较大的优势:

  • 更快速的交付和部署
  • Docker在整个开发周期都可以完美的辅助你实现快速交付。Docker允许开发者在装有应用和服务本地容器做开发。可以直接集成到可持续开发流程中。
  • 开发者可以使用一个标准的镜像来构建一套开发容器,开发完成之后,运维人员可以直接使用这个容器来部署代码。 Docker可以快速创建容器,快速迭代应用程序,并让整个过程全程可见,使团队中的其他成员更容易理解应用程序是如何创建和工作的。 Docker容器很轻很快!容器的启动时间是秒级的,大量地节约开发、测试、部署的时间。
  • 高效的部署和扩容
  • Docker容器几乎可以在任意的平台上运行,包括物理机、虚拟机、公有云、私有云、个人电脑、服务器等。这种兼容性可以让用户把一个应用程序从一个平台直接迁移到另外一个。
  • Docker的兼容性和轻量特性可以很轻松的实现负载的动态管理。你可以快速扩容或方便的下线的你的应用和服务,这种速度趋近实时。
  • 更高的资源利用率
  • Docker 对系统资源的利用率很高,一台主机上可以同时运行数千个 Docker容器。容器除了运行其中应用外,基本不消耗额外的系统资源,使得应用的性能很高,同时系统的开销尽量小。传统虚拟机方式运行 10个不同的应用就要起 10 个虚拟机,而Docker 只需要启动 10 个隔离的应用即可。
  • 更简单的管理
  • 使用 Docker,只需要小小的修改,就可以替代以往大量的更新工作。所有的修改都以增量的方式被分发和更新,从而实现自动化并且高效的管理。

5.Docker的组成

  • docker引擎是一个C/S结构的应用,组件如图所示:
    企业级Docker虚拟化平台实战_第5张图片
  • 客户端与Docker服务器的守护进程进行通信,守护进程根据请求来实现构建、运行和发布。客户机可以与服务器在同一台主机,也可以在不同网络之间进行通信
  • Docker Client:客户端
    用户与Docker交互的主要方式,Docker客户端可以与多个守护进程进行交互
  • Docker Daemon:守护进程
    用来监听Docker API的请求并管理对象,例如镜像、容器、网络和卷,守护进程还可以与其他的守护进程通信以管理Docker服务
  • Docker Image:镜像
    Docker镜像是一个只读模板,包含创建Docker容器的说明,通常一个镜像基于另一个镜像,并带有一些额外的自定义镜像,可以自定义创建一个镜像,也可以使用其他人再Docker仓库创建发布的镜像
  • Docker Container:容器
    容器是镜像可以运行的实例,可以通过Docker API或者客户端创建、启动、停止、移动或者删除容器,可以将容器连接到一个或者多个网络,将存储附加到该网络中,也可以根据当前的状态进行创建新的镜像
  • Docker Registry:镜像仓库
    Docker仓库用来存储Docker的镜像,Docker Hub是任何人都可以使用的Docker镜像仓库,Docker配置项也默认在这上面查找镜像

企业级Docker虚拟化平台实战_第6张图片

6.Docker镜像原理

  • 一个完整的Docker镜像可以支撑一个Docker容器的运行,在Docker容器运行过程中主要提供文件系统数据支撑。
  • Docker镜像作为docker中最基本的概念,有以下几个特性:
  • 镜像分层,每个镜像都由一个或多个镜像层组成;
  • 可通过在某个镜像加上一定的镜像层得到新镜像(此过程可通过编写dockerfile或基于容器Commit实现);
  • 每个镜像层拥有唯一镜像ID; 镜像在存储和使用时共享相同的镜像层(根据ID),所以在pull镜像时,已有的镜像层会自动跳过下载;
  • 每个镜像层都是只读,即使启动成容器,也无法对其真正的修改,修改只会作用于最上层的容器层;

企业级Docker虚拟化平台实战_第7张图片

  • Docker容器,可以理解为一个或多个运行进程,而这些运行进程将占有相应的内存,相应的CPU计算资源,相应的虚拟网络设备以及相应的文件系统资源。而Docker容器所占用的文件系统资源,则通过Docker镜像的镜像层文件来提供。
  • 基于每个镜像的json文件,Docker可以通过解析Docker镜像的json的文件,获知应该在这个镜像之上运行什么样的进程,应该为进程配置怎么样的环境变量,Docker守护进程实现了静态向动态的转变。

7.Docker安装配置

  • 本文主要讲解如何在Centos7.x系列服务器安装,默认docker只有在 Centos6.5以上机器才能使用yum直接安装。
  • docker官方文档说要求Linux kernel至少3.8以上,一般为centos6.5或者Ubuntu系统,那 centos7.x如何来安装呢?
  • Centos7.x系列安装docker软件,首先要关闭selinux,然后需要配置docker镜像源,如下:
##关闭selinux
 setenforce 0
 sed -i '/SELINUX/s/enforcing/disabled/g' /etc/selinux/config 
##安装依赖包
 yum -y install yum-utils device-mapper-persistent-data lvm2
##配置docker镜像源
wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
##安装docker
yum -y install docker-ce
  • 安装完后启动docker:
systemctl start docker
systemctl enable docker

8.Docker仓库源加速实战

  • Docker默认连接的国外官方镜像,通常根据网络情况不同,访问时快时慢,大多时候获取速度非常慢,为了提示效率可以自建仓库或者先修改为国内仓库源,提升拉取镜像的速度。
    Docker可以配置的国内镜像有很多可供选择,例如:Docker中国区官方镜像、阿里云、网易蜂巢、DaoCloud等,这些都是国内比较快的镜像仓库。
    从国外官网下载Docker Tomcat镜像,访问速度慢,如图所示:
    企业级Docker虚拟化平台实战_第8张图片

  • Docker镜像修改方法如下:

 cat>/etc/docker/daemon.json<<EOF 
 {
 "registry-mirrors":["https://registry.docker-cn.com"] }
  EOF 
  systemctl restart docker
  • 重启Docker服务即可,修改仓库地址为国内仓库后,获取镜像速度非常快,如图所示:
    企业级Docker虚拟化平台实战_第9张图片

9.Docker典型命令演练

  • 要使用docker虚拟化,需要下载镜像,使用docker命令启动,为了好让大家理解,这里直接利用docker启动centos系统。
    公共仓库下载centos镜像:
    企业级Docker虚拟化平台实战_第10张图片

  • 网络比较慢,可以下载好,然后导入镜像也可以,如下为Docker常用命令详解:

命令 描述
docker search 在docker hub中搜索镜像;
docker pull 从docker镜像源服务器拉取指定镜像或者库镜像;
docker push 推送指定镜像或者库镜像至docker源服务器;
docker history 展示一个镜像形成历史;
docker images 列出系统当前镜像;
docker run 创建一个新的容器并运行一个命令;
docker start 启动容器;
docker stop 停止容器;
docker attach 当前shell下attach连接指定运行镜像;
docker build 通过Dockerfile定制镜像;
docker commit 提交当前容器为新的镜像;
docker cp 从容器中拷贝指定文件或者目录到宿主机中;
docker create 创建一个新的容器,同run,但不启动容器;
docker diff 查看docker容器变化;
docker events 从docker服务获取容器实时事件;
docker exec 在已存在的容器上运行命令;
docker export 导出容器的内容流作为一个tar归档文件[对应import];
docker import 从tar包中的内容创建一个新的文件系统映像[对应export];
docker info 显示系统相关信息;
docker inspect 查看容器详细信息;
docker kill 指定docker容器;
docker load 从一个tar包中加载一个镜像[对应save];
docker login 注册或者登陆一个docker源服务器;
docker logout Dockerregistry退出;
docker logs 输出当前容器日志信息;
docker port 查看映射端口对应的容器内部源端口;
docker pause 暂停容器;
docker ps 列出容器列表;
docker restart 重启运行的容器;
docker rm 移除一个或者多个容器;
docker rmi 移除一个或多个镜像;
docker save 保存一个镜像为一个tar包[对应load];
docker tag 给源中镜像打标签;
docker top 查看容器中运行的进程信息;
docker unpause 取消暂停容器;
docker version 查看docker版本号;
docker wait 截取容器停止时的退出状态值;

10.Docker网络深入剖析

  • 基于Docker run创建Docker容器时,可以使用–net选项指定容器的网络模式,Docker默认有以下四种网络模式:
  • host模式,使用–net=host指定;
  • container模式,使用–net=container:NAME_or_ID指定;
  • none模式,使用–net=none指定;
  • bridge模式,使用–net=bridge指定,默认设置;

10.1. Host模式详解:

  • 默认Docker容器运行会分配独立的Network Namespace隔离子系统,基于host模式,容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace,容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。

10.2. Container模式详解:

  • 熟悉了host模式,Container模式也非常好理解,Container模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。
  • 即新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样两个容器除了网络方面相同之外,其他的如文件系统、进程列表等还是隔离的。

10.3. None模式详解:

  • None模式与其他的模式都不同,如果处于None模式,Docker容器拥有自己的Network Namespace,但是并不为Docker容器进行任何网络配置。也就是说该Docker容器没有网卡、IP、路由等信息,需要手工为Docker容器添加网卡、配置IP等,典型Pipework工具为Docker容器指定IP等信息;

10.4. Bridge桥接模式

  • Bridge模式是Docker默认的网络模式,该模式会为每一个容器分配Network Namespace、设置IP、路由等配置,默认会将Docker容器连接到一个虚拟网桥交换机Docker0上。本文采用Bridge模式,如下为桥接模式拓扑图:
    企业级Docker虚拟化平台实战_第11张图片企业级Docker虚拟化平台实战_第12张图片

10.5. Docker Bridge创建过程:

  • 首先宿主机上创建一对虚拟网卡veth pair设备,veth设备总是成对出现的,组成了一个数据的通道,数据从一个设备进入,就会从另一个设备出来,veth设备常用来连接两个网络设备。
  • Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0,然后将另一端放在宿主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到docker0网桥中,可以通过brctl show命令查看。
  • 从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。
  • 此时容器IP与宿主机能够通信,宿主机也可以访问容器中的IP地址,在Bridge模式下,连在同一网桥上的容器之间可以相互通信,同时容器也可以访问外网,但是其他物理机不能访问docker容器IP,需要通过NAT将容器IP的port映射为宿主机的IP和port。

11.基于Docker WEB管理Docker容器

  • 通常来讲,开发人员和管理人员默认通过命令行来创建及运行Docker容器,但Docker的Remote API让他们可以通过充分利用REST(代表性状态传输协议)的API,运行相同的命令。
  • Docker UI也是基于API方式管理宿主机的Docker引擎。Docker UI Web前端程序让你可以处理通常通过Web浏览器的命令行来管理的许多任务。
    主机上的所有容器都可以通过仅仅一条连接来处理,该项目几乎没有任何依赖关系。该软件目前仍在大力开发之中,但是它采用麻省理工学院(MIT)许可证,所以可以免费地重复使用。
  • Docker UI不包含任何内置的身份验证或安全机制,所以务必将任何公之于众的DockerUI连接放在用密码来保护的系统后面。

11.1. 下载Docker UI镜像;

只需要在宿主机pull相关的镜像即可,指令如下:

docker pull uifd/ui-for-docker
docker images
REPOSITORY           TAG       IMAGE ID       CREATED       SIZE
uifd/ui-for-docker   latest    965940f98fa5   5 years ago   8.1MB

11.2. 启动docker-UI服务,并且映射9000至容器9000

docker run -itd --name docker-web -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock   uifd/ui-for-docker

11.3. 如果启动Docker端口映射,报错信息如下:

docker0: iptables: No chain/target/match by that name.

解决方法:
如上报错信息是因为本地iptables规则策略没有匹配的链表,解决方案如下:

systemctl stop docker
iptables -t nat -F
ifconfig docker0 down
yum install -y bridge* -y
brctl delbr docker0
systemctl start docker

11.4. 通过docker ps 查看Docker UI状态;

[root@localhost ~]# docker ps
CONTAINER ID   IMAGE                COMMAND            CREATED         STATUS         PORTS                                       NAMES
cc5e52023066   uifd/ui-for-docker   "/ui-for-docker"   6 minutes ago   Up 6 minutes   0.0.0.0:9000->9000/tcp, :::9000->9000/tcp   docker-web

5)通过浏览器登录WEB 9000端口访问如图所示:
企业级Docker虚拟化平台实战_第13张图片

6)选择WEB界面images镜像列表,如图所示:
企业级Docker虚拟化平台实战_第14张图片

12.Dockerfile企业案例演练

  • 由于Docker官网公共仓库镜像大多不完整,无法真正满足企业的生产环境系统,此时需要我们自行定制镜像或者重新打包镜像。
  • Docker镜像制作是管理员的必备工作之一,Docker镜像制作的方法主要有两种,制作方法如下:
  • Docker commit|export将新容器提交至Images列表;
  • 编写Dockerfile,bulid新的镜像至镜像列表;

13.Dockerfile语法命令详解一

  • 企业生产环境推荐使用Dockerfile制作镜像,Dockerfile制作原理:将基于一个基础镜像,通过编写Dockerfile方式,将各个功能进行叠加,最终形成新的Docker镜像,是目前互联网企业中打包镜像最为推荐的方式。
  • Dockerfile是一个镜像的表示,也是一个镜像的原材料,可以通过Dockerfile来描述构建镜像,并自动构建一个容器。
  • 如下为DockerFile制作镜像,必备的指令和参数的详解:
  • FROM 指定所创建镜像的基础镜像;
  • MAINTAINER 指定维护者信息;
  • RUN 运行命令;
  • CMD 指定启动容器时默认执行的命令;
  • LABEL 指定生成镜像的元数据标签信息;
  • EXPOSE 声明镜像内服务所监听的端口;
  • ENV 指定环境变量;
  • ADD 赋值指定的路径下的内容到容器中的路径下,可以为URL;如果为tar文件,会自动解压到路径下
  • COPY 赋值本地主机的路径下的内容到容器中的路径下;一般情况下推荐使用COPY而不是ADD;
  • ENTRYPOINT 指定镜像的默认入口;
  • VOLUME 创建数据挂载点;
  • USER 指定运行容器时的用户名或UID;
  • WORKDIR 配置工作目录; ARG 指定镜像内使用的参数(例如版本号信息等);
  • ONBUILD 配置当前所创建的镜像作为其他镜像的基础镜像时,所执行的创建操作的命令; STOPSIGNAL 容器退出的信号;
  • HEALTHCHECK 如何进行健康检查;
  • SHELL 指定使用SHELL时的默认SHELL类型;

14.Dockerfile语法命令详解二

  • FROM指定所创建的镜像的基础镜像,如果本地不存在,则默认会去Docker Hub下载指定镜像。
格式为:FROM<image>,或FROM<image>:<tag>,或FROM<image>@<digest>。
任何Dockerfile中的第一条指令必须为FROM指令。
并且,如果在同一个Dockerfile文件中创建多个镜像,可以使用多个FROM指令(每个镜像一次)
  • MAINTAINER指定维护者信息,
格式为MAINTAINER<name>。例如:
MAINTAINER [email protected]
该信息将会写入生成镜像的Author属性域中。
  • RUN运行指定命令。
格式为:RUN<command>或RUN ["executable","param1","param2"]。
注意:后一个指令会被解析为json数组,所以必须使用双引号。
前者默认将在shell终端中运行命令,即/bin/sh -c;后者则使用exec执行,不会启动shell环境。
指定使用其他终端类型可以通过第二种方式实现,例如:
RUN ["/bin/bash","-c","echo hello"]
每条RUN指令将在当前镜像的基础上执行指定命令,并提交为新的镜像。当命令较长时可以使用\换行。例如:
RUN apt-get update \
&& apt-get install -y libsnappy-dev zliblg-dev libbz2-dev \
&& rm -rf /var/cache/apt
  • CMD用来指定启动容器时默认执行的命令。它支持三种格式:
CMD ["executable","param1","param2"] 使用exec执行,是推荐使用的方式;
CMD param1 param2 在/bin/sh中执行,提供给需要交互的应用;
CMD ["param1","param2"] 提供给ENTRYPOINT的默认参数。
每个Dockerfile只能有一条CMD命令。如果指定了多条命令,只有最后一条会被执行。
入股用户启动容器时指定了运行的命令(作为run的参数),则会覆盖掉CMD指定的命令。
  • LABEL指令用来生成用于生成镜像的元数据的标签信息。
格式为:LABEL <key>=<value> <key>=<value> <key>=<value> ...。
例如:
LABEL version="1.0"
LABEL description="This text illustrates \ that label-values can span multiple lines."
  • EXPOSE声明镜像内服务所监听的端口。
格式为:EXPOSE <port> [<port>...]
例如:
EXPOSE 22 80 443 3306
注意:该命令只是起到声明作用,并不会自动完成端口映射。
在容器启动时需要使用-P(大写P),Docker主机会自动分配一个宿主机未被使用的临时端口转发到指定的端口;
使用-p(小写p),则可以具体指定哪个宿主机的本地端口映射过来。
  • ENV指定环境变量,在镜像生成过程中会被后续RUN指令使用,在镜像启动的容器中也会存在。
格式为:ENV <key><value>或ENV<key>=<value>...。
例如:
ENV GOLANG_VERSION 1.6.3
ENV GOLANG_DOWNLOAD_RUL https://golang.org/dl/go$GOLANG_VERSION.linux-amd64.tar.gz
ENV GOLANG_DOWNLOAD_SHA256 cdd5e08530c0579255d6153b08fdb3b8e47caabbe717bc7bcd7561275a87aeb
RUN curl -fssL "$GOLANG_DOWNLOAD_RUL" -o golang.tar.gz && echo "$GOLANG_DOWNLOAD_SHA256 golang.tar.gz" | sha256sum -c - && tar -C /usr/local -xzf golang.tar.gz && rm golang.tar.gz
ENV GOPATH $GOPATH/bin:/usr/local/go/bin:$PATH
RUN mkdir -p "$GOPATH/bin" && chmod -R 777 "$GOPATH"
指令指定的环境变量在运行时可以被覆盖掉,如docker run --env <key>=<value> built_image。
  • ADD该指令将复制指定的路径下的内容到容器中的路径下。
格式为:ADD<src> <dest>
其中<src>可以使Dockerfile所在目录的一个相对路径(文件或目录),也可以是一个URL,还可以是一个tar文件(如果是tar文件,会自动解压到<dest>路径下)<dest>可以使镜像内的绝对路径,或者相当于工作目录(WORKDIR)的相对路径。路径支持正则表达式,例如:
ADD *.c /code/
  • COPY复制本地主机的(为Dockerfile所在目录的一个相对路径、文件或目录)下的内容到镜像中的下。目标路径不存在时,会自动创建。路径同样支持正则。格式为:COPY 当使用本地目录为源目录时,推荐使用COPY。
  • ENTRYPOINT指定镜像的默认入口命令,该入口命令会在启动容器时作为根命令执行,所有传入值作为该命令的参数。
    支持两种格式:
ENTRYPOINT ["executable","param1","param2"] (exec调用执行);
ENTRYPOINT command param1 param2(shell中执行)。
此时,CMD指令指定值将作为根命令的参数。
每个Dockerfile中只能有一个ENTRYPOINT,当指定多个时,只有最后一个有效。
在运行时可以被--entrypoint参数覆盖掉,如docker run --entrypoint。
  • VOLUME 创建一个数据卷挂载点。
 格式为:VOLUME ["/data"] 可以从本地主机或者其他容器挂载数据卷。
 一般用来存放数据库和需要保存的数据等。
  • USER 指定运行容器时的用户名或UID,后续的RUN等指令也会使用特定的用户身份。格式为:USER daemon
当服务不需要管理员权限时,可以通过该指令指定运行用户,并且可以在之前创建所需要的用户。例如:
RUN groupadd -r nginx && useradd -r -g nginx nginx要临时获取管理员权限可以用gosu或者sudo。
  • WORKDIR为后续的RUN、CMD和ENTRYPOINT指令配置工作目录。
格式为:WORKDIR /path/to/workdir。
可以使用多个WORKDIR指令,后续命令如果参数是相对的,则会基于之前命令指定的路径。例如:
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
则最终路径为/a/b/c
  • ARG指定一些镜像内使用的参数(例如版本号信息等),这些参数在执行docker build命令时才以–build-arg=格式传入。
格式为:ARG<name>[=<default value>]。
则可以用docker build --build-arg<name>=<value>来指定参数值。
  • ONBUILD配置当所创建的镜像作为其他镜像的基础镜像的时候,所执行创建操作指令。
格式为:ONBUILD [INSTRUCTION]。
例如Dockerfile使用如下的内容创建了镜像image-A:
[...]
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
[...]
如果基于image-A镜像创建新的镜像时,新的Dockerfile中使用FROM image-A指定基础镜像。
会自动执行ONBUILD指令的内容,等价于在后面添加了两条指令:
FROM image-A
# Automatically run the following
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
使用ONBUILD指令的镜像,推荐在标签中注明,例如:ruby:1.9-onbuild。
  • STOPSIGNAL 指定所创建镜像启动的容器接收退出的信号值。例如:
    STOPSIGNAL singnal
  • HEALTHCHECK 配置所启动容器如何进行健康检查(如何判断是否健康),自Docker 1.12开始支持。格式有两种:
HEALTHCHECK [OPTIONS] CMD command    :根据所执行命令返回值是否为0判断;HEALTHCHECK NONE:禁止基础镜像中的健康检查。
 [OPTION]支持:
--inerval=DURATION  (默认为:30s):多久检查一次;
--timeout=DURATION  (默认为:30s):每次检查等待结果的超时时间;
--retries=N        (默认为:3):如果失败了,重试几次才最终确定失败。
  • SHELL指定其他命令使用shell时的默认shell类型。
格式为: SHELL ["executable","parameters"]默认值为 ["bin/sh","-c"]。
注意:对于Windows系统,建议在Dockerfile开头添加# escape=`来指定转移信息。
  • 创建镜像

编写Dockerfile之后,可以通过docker build命令来创建镜像。 基本的docker build [选项]
内容路径,该命令将读取指定路径下(包括子目录)的Dockerfile,并将该路径下的所有内容发送给Docker服务端,由服务端来创建镜像。因此除非生成镜像需要,否则一般建议放置Dockerfile的目录为空目录。
如果使用非内容路径下的Dockerfile,可以通过-f选项来指定其路径; 要指定生成镜像的标签信息,可以使用-t选项。
例如:指定Dockerfile所在路径为
/tmp/docker_builder/,并且希望生成镜像标签为build_repo/first_image,可以使用下面的命令:
docker build -t build_repo/first_image /tmp/docker_builder
使用.dockerignore文件
可以通过.dockeringore文件(每一行添加一条匹配模式)来让Docker忽略匹配模式路径下的目录和文件。例如:

# comment
*/tmp*
*/*/tmp*
tmp?
~*

15.Dockerfile制作规范及技巧

  • 从企业需求出发,定制适合自己需求、高效方便的镜像,可以参考官方Dockerfile文件,也可以根据自身的需求,逐步的完善,在构建中不断优化Dockerfile文件;
  • Dockerfile制作镜像规范和技巧如下:
  • 精简镜像用途:尽量让每个镜像的用途都比较集中、单一,避免构造大而复杂、多功能的镜像;
  • 选用合适的基础镜像:过大的基础镜像会造成构建出臃肿的镜像,一般推荐比较小巧的镜像作为基础镜像; 提供详细的注释和维护者信息: Dockerfile也是一种代码,需要考虑方便后续扩展和他人使用;
  • 正确使用版本号:使用明确的具体数字信息的版本号信息,而非latest,可以避免无法确认具体版本号,统一环境;
  • 减少镜像层数:减少镜像层数建议尽量合并RUN指令,可以将多条RUN指令的内容通过&&连接;
  • 及时删除临时和缓存文件:这样可以避免构造的镜像过于臃肿,并且这些缓存文件并没有实际用途;
  • 提高生产速度:合理使用缓存、减少目录下的使用文件,使用.dockeringore文件等;
  • 调整合理的指令顺序:在开启缓存的情况下,内容不变的指令尽量放在前面,这样可以提高指令的复用性;
  • 减少外部源的干扰:如果确实要从外部引入数据,需要制定持久的地址,并带有版本信息,让他人可以重复使用而不出错。

16.DockerFile企业案例一

  • DockerFile企业案例一,将启动Docker容器,同时开启Docker容器对外的22端口的监听,实现通过CRT或者Xshell登录。
    Docker服务端创建Dockerfile文件,实现容器运行开启22端口,内容如下:
# 设置基本的镜像,后续命令都以这个镜像为基础
FROM centos:v1
# 作者信息
MAINTAINER  YS.NET
# RUN命令会在上面指定的镜像里执行任何命令
RUN rpm --rebuilddb;yum install passwd openssl openssh-server -y
RUN echo '123456' | passwd --stdin root
RUN mkdir -p /root/.ssh && chown root.root /root && chmod 700 /root/.ssh
# 暴露ssh端口22
EXPOSE  22
# 设定运行镜像时的默认命令:输出ip,并以daemon方式启动sshd
CMD /usr/sbin/sshd;/bin/bash
基于Dockerfile来创建生成镜像,命令如下:
用docker build根据Dockerfile创建镜像(centos:ssh):
docker  build  -t  centos:ssh  -  <  Dockerfile
docker  build  -t  centos:ssh  .

17.DockerFile企业案例二

  • DockerFile企业案例二,开启SSH 6379端口,让Redis端口对外访问,Dockerfile内容如下:
# 设置基本的镜像,后续命令都以这个镜像为基础
FROM centos_lamp:v1 
# 作者信息
MAINTAINER  JFEDU.NET
# RUN命令会在上面指定的镜像里执行任何命令
RUN rpm --rebuilddb;yum install redis* -y
RUN sed -i '/bind/127.0.0.1/0.0.0.0/g' /etc/redis.conf 
#暴露ssh端口6379
EXPOSE  6379
#设定运行以daemon方式启动sshd
CMD /usr/sbin/redis -D

18.DockerFile企业案例三

  • DockerFile企业案例三,基于Dockerfile开启Apache 80端口,并远程连接服务器,dockerfile内容如下:
# 设置基本的镜像,后续命令都以这个镜像为基础
FROM centos_lamp:v1
# 作者信息
MAINTAINER  JFEDU.NET
# RUN命令会在上面指定的镜像里执行任何命令
RUN rpm --rebuilddb;yum install pcre-devel -y
RUN rpm --rebuilddb;yum install httpd httpd-devel –y
RUN  echo<h1>The Test Page JFEDU</h1>>>/var/www/html/index.html
#暴露ssh端口80
EXPOSE 80
#启动httpd
CMD ["/usr/sbin/apachectl", "-D", "FOREGROUND"]

企业级Docker虚拟化平台实战_第15张图片

最终截图如下:

企业级Docker虚拟化平台实战_第16张图片

19.DockerFile企业案例四

  • DockerFile企业案例四,Docker虚拟化中,如何来构建我们的MYSQL数据库服务器呢?答案很简单,我们可以是dockerfile来生成mysql镜像并启动运行即可。
FROM centos:v1
RUN groupadd -r mysql && useradd -r -g mysql mysql
RUN rpm --rebuilddb;yum install -y gcc zlib-devel gd-devel
ENV MYSQL_MAJOR 5.6
ENV MYSQL_VERSION 5.6.20
RUN 
	&& curl -SL "http://dev.mysql.com/get/Downloads/MySQL-$MYSQL_MAJOR/mysql-$MYSQL_VERSION-linux-glibc2.5-x86_64.tar.gz" -o mysql.tar.gz \
	&& curl -SL "http://mysql.he.net/Downloads/MySQL-$MYSQL_MAJOR/mysql-$MYSQL_VERSION-linux-glibc2.5-x86_64.tar.gz.asc" -o mysql.tar.gz.asc \
	&& mkdir /usr/local/mysql \
	&& tar -xzf mysql.tar.gz -C /usr/local/mysql \
	&& rm mysql.tar.gz* \
ENV PATH $PATH:/usr/local/mysql/bin:/usr/local/mysql/scripts
WORKDIR /usr/local/mysql
VOLUME /var/lib/mysql
EXPOSE 3306
CMD ["mysqld", "--datadir=/var/lib/mysql", "--user=mysql"]

20.Docker本地私有仓库实战

  • Docker仓库主要用于存放Docker镜像,Docker仓库分为公共仓库和私有仓库,基于registry可以搭建本地私有仓库,使用私有仓库的优点如下:
  • 节省网络带宽,针对于每个镜像不用去Docker官网仓库下载;
  • 下载Docker镜像从本地私有仓库中下载;
  • 组件公司内部私有仓库,方便各部门使用,服务器管理更加统一;
  • 可以基于GET或者SVN、Jenkins更新本地Docker私有仓库镜像版本。
  • 官方提供Docker Registry来构建本地私有仓库,目前最新版本为v2,最新版的docker已不再支持v1,Registry v2使用Go语言编写,在性能和安全性上做了很多优化,重新设计了镜像的存储格式。如下为在192.168.0.123服务器上构建Docker本地私有仓库的方法及步骤:
(1)下载Docker registry镜像,命令如下:
docker pull docker.io/registry
(2)启动私有仓库容器,启动命令如下:
mkdir -p  /data/registry/
docker run -itd  -p  5000:5000 -v /data/registry:/var/lib/registry  docker.io/registry
  • Docker本地仓库启动后台容器启动,如图所示:
    企业级Docker虚拟化平台实战_第17张图片
  • 默认情况下,会将仓库存放于容器内的/tmp/registry目录下,这样如果容器被删除,则存放于容器中的镜像也会丢失,所以我们一般情况下会指定本地一个目录挂载到容器内的/tmp/registry下。
(3)上传镜像至本地私有仓库:
客户端上传镜像至本地私有仓库,如下以busybox镜像为例,将busybox上传至私有仓库服务器。
docker   pull    busybox
docker   tag    busybox  192.168.0.123:5000/busybox
docker   push  192.168.0.123:5000/busybox
(4)检测本地私有仓库:
curl -XGET http://192.168.0.123:5000/v2/_catalog
curl -XGET http://192.168.0.123:5000/v2/busybox/tags/list
(5)客户端使用本地私有仓库:
客户端docker /etc/docker/daemon.json配置文件添加如下代码,同时重启docker服务,获取本地私有仓库如图24-3所示:
OPTIONS='--selinux-enabled --log-driver=journald --signature-verification=false --insecure-registry 192.168.0.123:5000'
ADD_REGISTRY='--add-registry 192.168.0.123:5000'
  • 至此,docker本地私有仓库部署完毕,可以向仓库中添加或者更新Docker镜像。

21.Docker磁盘&内存&CPU资源实战

  • Docker容器默认启动的虚拟机,会占用宿主机的资源(CPU、内存、硬盘),例如默认Docker基于Overlay2驱动方式,容器硬盘的rootfs根分区空间是整个宿主机的空间大小。
  • 可以指定默认容器的大小(在启动容器的时候指定),可以在docker配置文件:/etc/sysconfig/docker中,OPTIONS参数后面添加如下代码,指定Docker容器rootfs容量大小为40G:
OPTIONS='--storage-opt overlay2.size=40G'

以上方法只适用于新容器生成,并且修改后需要重启docker,无法做到动态给正在运行容器指定大小,如下图为默认容器大小:

修改Docker存储配置文件,加入如下代码:(默认如果已经为overlay2,则无需修改)

vi /etc/sysconfig/docker-storage
DOCKER_STORAGE_OPTIONS="--storage-driver overlay2 "
  • 然后重启docker即可;

  • Overlay2 Docker磁盘驱动模式,如果要调整其大小,通过如上的方法,会导致Docker引擎服务无法启动,还需要让Linux文件系统设置为xfs,并且支持目录级别的磁盘配额功能;

  • CentOS7.x Xfs磁盘配额配置,新添加一块硬盘,设置磁盘配额方法步骤如下:
    1)添加新的硬盘如图所示:
    企业级Docker虚拟化平台实战_第18张图片

2)格式化硬盘为xfs文件系统格式,命令如下:

mkfs.xfs -f /dev/sdb

3)创建data目录,后续将作为docker数据目录;
mkdir /data/ -p
4)挂载data目录,并且开启磁盘配额功能(默认xfs支持配额功能);
mount -o uquota,prjquota /dev/sdb /data/
企业级Docker虚拟化平台实战_第19张图片

  • 挂载配额类型如下:
  • 根据用户(uquota/usrquota/quota)
  • 根据组(gquota/grpquota) ;
  • 根据目录(pquota/prjquota)(不能与grpquota同时设定) 。

5)查看配额-配置详情,命令如下:

xfs_quota -x -c 'report' /data/

6)可以通过命令xfs_quota设置来为用户和目录分配配额,也可以通过命令来查看配额信息;

xfs_quota -x -c 'limit bsoft=10M bhard=10M jfedu' /data
xfs_quota -x -c 'report' /data/

7)将docker引擎默认数据存储目录:/var/lib/docker重命名,并且将/data/docker目录软链接至/var/lib/下即可;

mkdir -p /data/docker/
cd /var/lib/
mv docker docker.bak
ln -s /data/docker/  .

8)重启Docker服务,并且查看进程,可以看到docker overlay2.size大小配置,如图所示:
企业级Docker虚拟化平台实战_第20张图片

9)基于Docker客户端指令启动Docker容器,并且查看最新容器的磁盘空间为10G,则设置容器大小成功,如图所示:
企业级Docker虚拟化平台实战_第21张图片企业级Docker虚拟化平台实战_第22张图片

22.Docker构建Nginx服务器实战

  • Nginx [engine x]是Igor Sysoev编写的一个HTTP和反向代理服务器,另外它也可以作为邮件代理服务器。 它已经在众多流量很大的俄罗斯网站上使用了很长时间,这些网站包括Yandex、Mail.Ru、VKontakte,以及Rambler。
  • 据Netcraft统计,在2012年8月份,世界上最繁忙的网站中有11.48%使用Nginx作为其服务器或者代理服务器。目前互联网主流公司360、百度、新浪、腾讯、阿里等都在使用nginx作为自己的web服务器。
  • Nginx由内核和模块组成,其中,内核的设计非常微小和简洁,完成的工作也非常简单,仅仅通过查找配置文件将客户端请求映射到一个location block(location是Nginx配置中的一个指令,用于URL匹配),而在这个location中所配置的每个指令将会启动不同的模块去完成相应的工作。
  • Nginx相对于Apache优点:
  • 高并发响应性能非常好,官方Nginx处理静态文件并发5w/s
  • 反向代理性能非常好。(可用于负载均衡)
  • 内存和cpu占用率低。(为Apache的1/5-1/10)
  • 功能较Apache少(常用功能均有)
  • 对php可使用cgi方式和fastcgi方式。
  • Nginx WEB安装
首先需要安装pcre库,然后再安装Nginx:
#安装pcre支持rewrite库,也可以安装源码,注*安装源码时,指定pcre路径为解压
源码的路径,而不是编译后的路径,否则会报错
(make[1]: *** [/usr/local/pcre/Makefile] Error 127 错误)
yum install pcre-devel pcre -y
#下载Nginx源码包
cd /usr/src ;wget -c http://nginx.org/download/nginx-1.4.2.tar.gz 
#解压Nginx源码包
tar -xzf nginx-1.4.2.tar.gz
#进入解压目录,然后sed修改Nginx版本信息为WS
cd nginx-1.4.2 ; sed -i -e 's/1.4.2//g' -e 's/nginx\//WS/g' -e 
's/"NGINX"/"WS"/g' src/core/nginx.h
#预编译Nginx
useradd www ;./configure --user=www --group=www --prefix=/usr/local/nginx --with-
http_stub_status_module --with-http_ssl_module
#.configure预编译成功后,执行make命令进行编译
make
#make执行成功后,执行make install 正式安装
make install
#自此Nginx安装完毕
/usr/local/nginx/sbin/nginx  -t  检查nginx配置文件是否正确,返回OK即正确。
[root@localhost ~]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@localhost ~]#
然后启动nginx,/usr/local/nginx/sbin/nginx 回车即可。查看进程是否已启动:
[root@localhost ~]# ps -ef |grep nginx
nobody    5381 30285  0 May16 ?        00:04:31 nginx: worker process         
root     30285     1  0  2014 ?        00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
root     32260 32220  0 12:34 pts/0    00:00:00 grep nginx
[root@localhost ~]#
然后我们可以通过docker 的ip去访问即可。
以上的操作是在docker上启动了一个centos7的系统不是应用,还有一种可以直接在docker官网下载Nginx镜像直接启动然后修改配置文件即可。

23.Docker构建LNAMP架构实战

  • LNAMP(Linux+Nginx+Apache+Mysql+PHP)架构受到很多IT企业的青睐,取代了原来认为很好的LNMP(Linux+Nginx+Mysql+PHP)架构,那我们说LNAMP到底有什么优点呢,还得从Nginx和apache的优缺点说起。
  • Nginx处理静态文件能力很强,Apache处理动态文件很强而且很稳定,把二者综合在一块,性能提升很多倍。可能很多Linux SA在从事LNMP运维中,会发现PHP(FastCGI)模式会出现一些502错误的现象,这是因为Nginx+PHP(FastCGI)组合不稳定的原因造成的。
YUM 安装LAMP方式:
yum install httpd httpd-tools mysql mysql-server mysql-devel php php-devel php-mysql -y
源码安装LNAMP之Nginx
yum install prce-devel -y ;cd  /usr/src ;wget http://nginx.org/download/nginx-1.6.0.tar.gz  ;cd nginx-1.6.0 ;./configure -prefix=/usr/local/nginx && make &&make install
源码安装LNAMP之Apache
yum install apr-devel apr-util-devel –y;
cd  /usr/src ; wget http://mirror.bit.edu.cn/apache/httpd/httpd-2.2.27.tar.gz ;tar xzf  httpd-2.2.27.tar.gz ;cd httpd-2.2.27 ;./configure --prefix=/usr/local/apache --enable-so --enable-rewrite &&make &&make install
源码安装LNAMP之MySQL
cd /usr/src ;wget http://downloads.mysql.com/archives/mysql-5.1/mysql-5.1.63.tar.gz ;tar xzf mysql-5.1.63.tar.gz ;cd mysql-5.1.63 ;./configure  --prefix=/usr/local/mysql --enable-assembler &&make &&make install
配置Mysql服务为系统服务:
cp /usr/local/mysql/share/mysql/my-medium.cnf /etc/my.cnf
cp /usr/local/mysql/share/mysql/mysql.server /etc/rc.d/init.d/mysqld
chkconfig --add mysqld 
chkconfig --level 345 mysqld on
cd /usr/local/mysql
useradd mysql
chown -R  mysql.mysql /usr/local/mysql 
/usr/local/mysql/bin/mysql_install_db --user=mysql  
chown -R mysql  var 
/usr/local/mysql/bin/mysqld_safe --user=mysql &
源码安装LNAMP之PHP
cd /usr/src ;wget http://mirrors.sohu.com/php/php-5.3.28.tar.bz2 ;tar jxf  php-5.3.28.tar.bz2 ;cd php-5.3.28 ;./configure --prefix=/usr/local/php5 --with-config-file-path=/usr/local/php/etc   --with-apxs2=/usr/local/apache/bin/apxs --with-mysql=/usr/local/mysql/
  • 源码安装Apache+PHP整合
整合apache+php环境,修改httpd.conf配置文件,然后加入如下语句:
LoadModule     php5_module modules/libphp5.so (默认已存在)
AddType     application/x-httpd-php .php
DirectoryIndex  index.php index.html (把index.php加入index.html之前)
然后在/usr/local/apache/htdocs目录下创建index.php测试页面,执行如下命令:
cat >>/usr/local/apache/htdocs/index.php <<EOF

EOF
重新启动apache服务,通过IP访问界面如下图,即代表LAMP环境搭建成功。
  • 源码安装DISCUZ论坛
下载discuz源码包文件,然后解压:
cd  /usr/src ;wget http://download.comsenz.com/DiscuzX/3.1/Discuz_X3.1_SC_UTF8.zip 
解压discuz程序包:unzip Discuz_X3.1_SC_UTF8.zip -d /usr/local/apache/htdocs/ 
重命名程序文件:cd /usr/local/apache/htdocs/ ;mv upload/* .
赋予discuz目录完全访问权限:cd /usr/local/apache/htdocs/ ;chmod 777 -R data/ uc_server/ config/ uc_client/
  • 然后访问IP安装discuz论坛,如下图,选择“我同意”
    企业级Docker虚拟化平台实战_第23张图片

  • 进入如下界面,数据库安装,如果不存在则需要新建数据库并授权。
    企业级Docker虚拟化平台实战_第24张图片

  • 数据库创建及授权命令如下:

create database discuz charset=utf8;
grant all on discuz.* to root@'localhost' identified by "123456";

企业级Docker虚拟化平台实战_第25张图片

  • 点击下一步,直至安装完成,进入等待已久的论坛画面:
    企业级Docker虚拟化平台实战_第26张图片

  • 自此LAMP环境整合并搭建成功,那如何使用Nginx来整合LAMP呢?

24.Docker自动化部署一

  • 生产环境中,由于Docker指令过多,操作比较繁琐,可以编写SHELL自动安装并配置Docker虚拟化及桥接网络,同时使用pipework脚本来配置容器IP,能够实现容器的批量管理,此脚本适用于CentOS6.x系统;
  • CentOS6.x系列Docker批量管理脚本代码如下:
#!/bin/bash
#auto install docker and Create VM
#by wugk 2021-10-22
#Define PATH Varablies
IPADDR=`ifconfig |grep "Bcast"|awk '{print $2}'|cut -d: -f2|grep "192.168"|head -1`
GATEWAY=`route -n|grep "UG"|awk '{print $2}'|grep "192.168"|head -1`
DOCKER_IPADDR=$1
IPADDR_NET=`ifconfig |grep "Bcast"|awk '{print $2}'|cut -d: -f2|grep "192.168"|head -1|awk -F. '{print $1"."$2"."$3".""xxx"}'`

NETWORK=(
    HWADDR=`ifconfig eth0 |egrep "HWaddr|Bcast" |tr "\n" " "|awk '{print $5,$7,$NF}'|sed -e 's/addr://g' -e 's/Mask://g'|awk '{print $1}'`
    IPADDR=`ifconfig eth0 |egrep "HWaddr|Bcast" |tr "\n" " "|awk '{print $5,$7,$NF}'|sed -e 's/addr://g' -e 's/Mask://g'|awk '{print $2}'`
    NETMASK=`ifconfig eth0 |egrep "HWaddr|Bcast" |tr "\n" " "|awk '{print $5,$7,$NF}'|sed -e 's/addr://g' -e 's/Mask://g'|awk '{print $3}'`
    GATEWAY=`route -n|grep "UG"|awk '{print $2}'`
)

if [ -z "$1" -o -z "$2" -o -z "$3" -o -z "$4" ];then

	echo -e "\033[32m---------------------------------\033[0m"
	echo -e "\033[32mPlease exec $0 IPADDR CPU(C) MEM(G) DISK(G),example $0 $IPADDR_NET 16 32 50\033[0m" 
	exit 0
fi
CPU=`expr $2 - 1`
if [ ! -e /usr/bin/bc ];then
	yum install bc -y >>/dev/null 2>&1
fi
MEM_F=`echo $3 \* 1024|bc`
MEM=`printf "%.0f\n" $MEM_F`
DISK=$4
USER=$5
REMARK=$6

ping $DOCKER_IPADDR -c 1 >>/dev/null 2>&1

if [ $? -eq 0 ];then

	echo -e "\033[32m---------------------------------\033[0m"
	echo -e "\033[32mThe IP address to be used,Please change other IP,exit.\033[0m"
	exit 0
fi

if [ ! -e /etc/init.d/docker ];then
	rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
	yum install docker-io -y
	yum install device-mapper*  -y
	/etc/init.d/docker start
	if [ $? -ne 0 ];then
		echo "Docker install error ,please check."
		exit 
	fi
fi	


cd  /etc/sysconfig/network-scripts/
    mkdir -p /data/backup/`date +%Y%m%d-%H%M`
    yes|cp ifcfg-eth* /data/backup/`date +%Y%m%d-%H%M`/
if
    [ -e /etc/sysconfig/network-scripts/ifcfg-br0 ];then
	echo
else
    cat >ifcfg-eth0 <<EOF
    DEVICE=eth0
    BOOTPROTO=none
    ${NETWORK[0]}
    NM_CONTROLLED=no
    ONBOOT=yes
    TYPE=Ethernet
    BRIDGE="br0"
    ${NETWORK[1]}
    ${NETWORK[2]}
    ${NETWORK[3]}
    USERCTL=no
EOF
    cat >ifcfg-br0 <<EOF
    DEVICE="br0"
    BOOTPROTO=none
    ${NETWORK[0]}
    IPV6INIT=no
    NM_CONTROLLED=no
    ONBOOT=yes
    TYPE="Bridge"
    ${NETWORK[1]}
    ${NETWORK[2]}
    ${NETWORK[3]}
    USERCTL=no
EOF

    /etc/init.d/network restart

fi
echo 'Your can restart Ethernet Service: /etc/init.d/network restart !'
echo '---------------------------------------------------------'
cd -
#######create docker container
service docker status >>/dev/null
if [ $? -ne 0 ];then 
	/etc/init.d/docker restart
fi
NAME="Docker$$_`echo $DOCKER_IPADDR|awk -F"." '{print $(NF-1)"_"$NF}'`"
IMAGES=`docker images|grep -v "REPOSITORY"|grep -v "none"|head -1|awk '{print $1}'`
CID=$(docker run -itd --cpuset-cpus=0-$CPU -m ${MEM}m --net=none --name=$NAME $IMAGES /bin/bash)

if [ -z $IMAGES ];then
	echo "Plesae Download Docker Centos Images,you can to be use docker search centos,and docker pull centos6.5-ssh,exit 0"
	exit 0
fi

if [ ! -f /usr/local/bin/pipework ];then
	yum install wget unzip zip -y
	wget https://github.com/jpetazzo/pipework/archive/master.zip
        unzip master
        cp pipework-master/pipework  /usr/local/bin/
        chmod +x /usr/local/bin/pipework
        rm -rf master
fi

ip netns >>/dev/null
if [ $? -ne 0 ];then
	rpm -e iproute --nodeps
        rpm -ivh https://repos.fedorapeople.org/openstack/EOL/openstack-grizzly/epel-6/iproute-2.6.32-130.el6ost.netns.2.x86_64.rpm
fi
pipework br0 $NAME  $DOCKER_IPADDR/24@$IPADDR

docker ps -a |grep "$NAME"

DEV=$(basename $(echo /dev/mapper/docker-*-$CID)) 
dmsetup table $DEV | sed "s/0 [0-9]* thin/0 $((${DISK}*1024*1024*1024/512)) thin/" | dmsetup load $DEV 
dmsetup resume $DEV 
resize2fs /dev/mapper/$DEV 
docker start $CID 
docker logs $CID
LIST="docker_vmlist.csv"
if [ ! -e $LIST ];then
	echo "编号,容器ID,容器名称,CPU,内存,硬盘,容器IP,宿主机IP,使用人,备注" >$LIST
fi
###################
NUM=`cat docker_vmlist.csv |grep -v CPU|tail -1|awk -F, '{print $1}'`
if [[ $NUM -eq "" ]];then
        NUM="1"
else
        NUM=`expr $NUM + 1`
fi
##################	
echo -e "\033[32mCreate virtual client Successfully.\n$NUM `echo $CID|cut -b 1-12` $NAME $2C ${MEM}M ${DISK}G $DOCKER_IPADDR $IPADDR $USER $REMARK\033[0m"
if [ -z $USER ];then
	USER="NULL"
	REMARK="NULL"
fi
echo $NUM,`echo $CID|cut -b 1-12`,$NAME,${2}C,${MEM}M,${DISK}G,$DOCKER_IPADDR,$IPADDR,$USER,$REMARK >>$LIST
rm -rf docker_vmlist_*
iconv -c -f utf-8 -t gb2312 docker_vmlist.csv -o docker_vmlist_`date +%H%M`.csv

25.Docker自动化部署二

  • 生产环境中,由于Docker指令过多,操作比较繁琐,可以编写SHELL自动安装并配置Docker虚拟化及桥接网络,同时使用pipework脚本来配置容器IP,能够实现容器的批量管理,此脚本适用于CentOS7.x系统;
  • CentOS7.x系列Docker批量管理脚本代码如下:
#!/bin/bash
#auto install docker and Create VM
#by jfedu.net 2017
#Define PATH Varablies
IPADDR=`ifconfig|grep -E "\"|awk '{print $2}'|grep "192.168"|head -1`
GATEWAY=`route -n|grep "UG"|awk '{print $2}'|grep "192.168"|head -1`
IPADDR_NET=`ifconfig|grep -E "\"|awk '{print $2}'|grep "192.168"|head -1|awk -F. '{print $1"."$2"."$3"."}'`
LIST="/root/docker_vmlist.csv"
if [ ! -f /usr/sbin/ifconfig ];then
	yum install net-tools* -y
fi
for i in `seq 1 253`;do ping -c 1 ${IPADDR_NET}${i} ;[ $? -ne 0 ]&& DOCKER_IPADDR="${IPADDR_NET}${i}" &&break;done >>/dev/null 2>&1
echo "##################"
echo -e "Dynamic get docker IP,The Docker IP address\n\n$DOCKER_IPADDR"
NETWORK=(
    HWADDR=`ifconfig eth0|grep ether|awk '{print $2}'`
    IPADDR=`ifconfig eth0|grep -E "\"|awk '{print $2}'`
    NETMASK=`ifconfig eth0|grep -E "\"|awk '{print $4}'`
    GATEWAY=`route -n|grep "UG"|awk '{print $2}'`
)
if [ -z "$1" -o -z "$2" ];then
	echo -e "\033[32m---------------------------------\033[0m"
	echo -e "\033[32mPlease exec $0 CPU(C) MEM(G),example $0 4 8\033[0m" 
	exit 0
fi
#CPU=`expr $2 - 1`
if [ ! -e /usr/bin/bc ];then
	yum install bc -y >>/dev/null 2>&1
fi
CPU_ALL=`cat /proc/cpuinfo |grep processor|wc -l`
if [ ! -f $LIST ];then
	CPU_COUNT=$1	
	CPU_1="0"
	CPU1=`expr $CPU_1 + 0`
	CPU2=`expr $CPU1 + $CPU_COUNT - 1`
	if [ $CPU2 -gt $CPU_ALL ];then
		echo -e "\033[32mThe System CPU count is $CPU_ALL,not more than it.\033[0m"
		exit
	fi
else
	CPU_COUNT=$1	
	CPU_1=`cat $LIST|tail -1|awk -F"," '{print $4}'|awk -F"-" '{print $2}'`
	CPU1=`expr $CPU_1 + 1`
	CPU2=`expr $CPU1 + $CPU_COUNT - 1`
	if [ $CPU2 -gt $CPU_ALL ];then
		echo -e "\033[32mThe System CPU count is $CPU_ALL,not more than it.\033[0m"
		exit
	fi
fi
MEM_F=`echo $2 \* 1024|bc`
MEM=`printf "%.0f\n" $MEM_F`
DISK=20
USER=$3
REMARK=$4
ping $DOCKER_IPADDR -c 1 >>/dev/null 2>&1
if [ $? -eq 0 ];then
	echo -e "\033[32m---------------------------------\033[0m"
	echo -e "\033[32mThe IP address to be used,Please change other IP,exit.\033[0m"
	exit 0
fi
if [ ! -e /usr/bin/docker ];then
	yum install docker* device-mapper* lxc  -y
	mkdir -p /export/docker/
	cd /var/lib/ ;rm -rf docker ;ln -s /export/docker/ .
	mkdir -p /var/lib/docker/devicemapper/devicemapper
	dd if=/dev/zero of=/var/lib/docker/devicemapper/devicemapper/data bs=1G count=0 seek=2000
	service docker start
	if [ $? -ne 0 ];then
		echo "Docker install error ,please check."
		exit 
	fi
fi	

cd  /etc/sysconfig/network-scripts/
    mkdir -p /data/backup/`date +%Y%m%d-%H%M`
    yes|cp ifcfg-eth* /data/backup/`date +%Y%m%d-%H%M`/
if
    [ -e /etc/sysconfig/network-scripts/ifcfg-br0 ];then
	echo
else
    cat >ifcfg-eth0<<EOF
    DEVICE=eth0
    BOOTPROTO=none
    ${NETWORK[0]}
    NM_CONTROLLED=no
    ONBOOT=yes
    TYPE=Ethernet
    BRIDGE="br0"
    ${NETWORK[1]}
    ${NETWORK[2]}
    ${NETWORK[3]}
    USERCTL=no
EOF
    cat >ifcfg-br0 <<EOF
    DEVICE="br0"
    BOOTPROTO=none
    ${NETWORK[0]}
    IPV6INIT=no
    NM_CONTROLLED=no
    ONBOOT=yes
    TYPE="Bridge"
    ${NETWORK[1]}
    ${NETWORK[2]}
    ${NETWORK[3]}
    USERCTL=no
EOF
    /etc/init.d/network restart

fi
echo 'Your can restart Ethernet Service: /etc/init.d/network restart !'
echo '---------------------------------------------------------'

cd -
#######create docker container
service docker status >>/dev/null
if [ $? -ne 0 ];then 
	service docker restart
fi

NAME="Docker_`echo $DOCKER_IPADDR|awk -F"." '{print $(NF-1)"_"$NF}'`"
IMAGES=`docker images|grep -v "REPOSITORY"|grep -v "none"|grep "centos"|head -1|awk '{print $1}'`
if [ -z $IMAGES ];then
	echo "Plesae Download Docker Centos Images,you can to be use docker search centos,and docker pull centos6.5-ssh,exit 0"
	if [ ! -f jfedu_centos68.tar ];then
		echo "Please upload jfedu_centos68.tar for docker server."
		exit
	fi
	cat jfedu_centos68.tar|docker import - jfedu_centos6.8
fi
IMAGES=`docker images|grep -v "REPOSITORY"|grep -v "none"|grep "centos"|head -1|awk '{print $1}'`
CID=$(docker run -itd --privileged --cpuset-cpus=${CPU1}-${CPU2} -m ${MEM}m --net=none --name=$NAME $IMAGES /bin/bash)
echo $CID
docker ps -a |grep "$NAME"
pipework br0 $NAME  $DOCKER_IPADDR/24@$IPADDR
docker exec $NAME /etc/init.d/sshd start
if [ ! -e $LIST ];then
	echo "编号,容器ID,容器名称,CPU,内存,硬盘,容器IP,宿主机IP,使用人,备注" >$LIST
fi
###################
NUM=`cat $LIST |grep -v CPU|tail -1|awk -F, '{print $1}'`
if [[ $NUM -eq "" ]];then
        NUM="1"
else
        NUM=`expr $NUM + 1`
fi
##################	
echo -e "\033[32mCreate virtual client Successfully.\n$NUM `echo $CID|cut -b 1-12`,$NAME,$CPU1-$CPU2,${MEM}M,${DISK}G,$DOCKER_IPADDR,$IPADDR,$USER,$REMARK\033[0m"
if [ -z $USER ];then
	USER="NULL"
	REMARK="NULL"
fi
echo $NUM,`echo $CID|cut -b 1-12`,$NAME,$CPU1-$CPU2,${MEM}M,${DISK}G,$DOCKER_IPADDR,$IPADDR,$USER,$REMARK >>$LIST
rm -rf /root/docker_vmlist_*
iconv -c -f utf-8 -t gb2312 $LIST  -o /root/docker_vmlist_`date +%H%M`.csv

你可能感兴趣的:(docker,容器,运维)