Docker虚拟化
1. Docker虚拟化特点
跟传统VM比较具有如下优点:
- 操作启动快
运行时的性能可以获取极大提升,管理操作(启动,停止,开始,重启等等) 都是以秒或毫秒为单位的。
- 轻量级虚拟化
你会拥有足够的“操作系统”,仅需添加或减小镜像即可。在一台服务器上可以布署100~1000个Containers容器。但是传统虚拟化,你虚拟10-20个虚拟机就不错了。
- 开源免费
开源的,免费的,低成本的。由现代Linux内核支持并驱动。注* 轻量的Container必定可以在一个物理机上开启更多“容器”,注定比VMs要便宜。
2. 为什么使用docker
Docker 在如下几个方面具有较大的优势:
- 更快速的交付和部署
Docker在整个开发周期都可以完美的辅助你实现快速交付。Docker允许开发者在装有应用和服务本地容器做开发。可以直接集成到可持续开发流程中。
开发者可以使用一个标准的镜像来构建一套开发容器,开发完成之后,运维人员可以直接使用这个容器来部署代码。 Docker 可以快速创建容器,快速迭代应用程序,并让整个过程全程可见,使团队中的其他成员更容易理解应用程序是如何创建和工作的。 Docker 容器很轻很快!容器的启动时间是秒级的,大量地节约开发、测试、部署的时间。
- 高效的部署和扩容
Docker容器几乎可以在任意的平台上运行,包括物理机、虚拟机、公有云、私有云、个人电脑、服务器等。 这种兼容性可以让用户把一个应用程序从一个平台直接迁移到另外一个。
Docker的兼容性和轻量特性可以很轻松的实现负载的动态管理。你可以快速扩容或方便的下线的你的应用和服务,这种速度趋近实时。
- 更高的资源利用率
Docker 对系统资源的利用率很高,一台主机上可以同时运行数千个 Docker 容器。容器除了运行其中应用外,基本不消耗额外的系统资源,使得应用的性能很高,同时系统的开销尽量小。传统虚拟机方式运行 10 个不同的应用就要起 10 个虚拟机,而Docker 只需要启动 10 个隔离的应用即可。
- 更简单的管理
使用 Docker,只需要小小的修改,就可以替代以往大量的更新工作。所有的修改都以增量的方式被分发和更新,从而实现自动化并且高效的管理。
3. Docker镜像原理
一个完整的Docker镜像可以支撑一个Docker容器的运行,在Docker容器运行过程中主要提供文件系统数据支撑。
Docker镜像作为docker中最基本的概念,有以下几个特性:
- 镜像分层,每个镜像都由一个或多个镜像层组成;
- 可通过在某个镜像加上一定的镜像层得到新镜像(此过程可通过编写dockerfile或基于容器Commit实现);
- 每个镜像层拥有唯一镜像ID;
- 镜像在存储和使用时共享相同的镜像层(根据ID),所以在pull镜像时,已有的镜像层会自动跳过下载;
- 每个镜像层都是只读,即使启动成容器,也无法对其真正的修改,修改只会作用于最上层的容器层;
Docker容器,可以理解为一个或多个运行进程,而这些运行进程将占有相应的内存,相应的CPU计算资源,相应的虚拟网络设备以及相应的文件系统资源。而Docker容器所占用的文件系统资源,则通过Docker镜像的镜像层文件来提供。
基于每个镜像的json文件,Docker可以通过解析Docker镜像的json的文件,获知应该在这个镜像之上运行什么样的进程,应该为进程配置怎么样的环境变量,Docker守护进程实现了静态向动态的转变。
4. Docker安装配置
CentOS7.x Linux,基于YUM二进制方式,操作命令如下:
#安装第三方Epel-relase扩展源; yum install epel-release -y #安装Docker软件包程序; yum install docker -y #查看Docker软件包是否部署; yum list docker rpm -qa|grep -w docker #启动Docker Engine服务; systemctl start docker.service #查看Docker版本信息; docker version |
5. Docker仓库源更新实战
Docker默认连接的国外官方镜像,通常根据网络情况不同,访问时快时慢,大多时候获取速度非常慢,为了提示效率可以自建仓库或者先修改为国内仓库源,提升拉取镜像的速度。
Docker可以配置的国内镜像有很多可供选择,例如:Docker中国区官方镜像、阿里云、网易蜂巢、DaoCloud等,这些都是国内比较快的镜像仓库。
从国外官网下载Docker Tomcat镜像,访问速度慢,
Docker镜像修改方法,vim /etc/docker/daemon.json,执行如下命令即可:
cat>/etc/docker/daemon.json<<EOF
{
"registry-mirrors": ["https://registry.docker-cn.com","http://hub-mirror.c.163.com"]
}
EOF
service docker restart
systemctl start docker.service
重启Docker服务即可,修改仓库地址为国内仓库后,获取镜像速度非常快。
6. Docker常用命令讲解
Docker常用命令详解:
docker version #查看版本 docker search centos #搜索可用docker镜像 docker images 查看当前docker所有镜像 docker pull centos #下载镜像 cat centos.tar | docker import - centos6 #Docker导入镜像 docker export 容器id > cenos6.tar #Docker导出镜像 docker run centos echo "hello word" #在docker容器中运行hello world! docker run centos yum install ntpdate #在容器中安装ntpdate的程序 docker ps -l 命令获得最后一个容器的id, docker ps -a查看所有的容器。 运行docker commit 提交刚修改的容器,例如: docker commit 2313132(容器的id) centos:v1 docker run -it -d --privileged --name docker-web centos /bin/bash 生成一个新的/bin/bash shell环境的容器,可以登录进入操作,其中-t 表示打开一个终端的意思,-i表示可以交互输入,--name 表示容器的名字, --privileged表示特权较高可以mount并容器里面启动容器 docker exec -it id /bin/bash 进入容器里面 docker run -d centos:v1 /bin/bash ,-d表示在后台启动,以daemon方式启动。 docker stop id 关闭容器 docker start id 启动某个容器 docker rm id 删除容器,docker rmi images删除镜像 docker run -d -p 80:80 centos:v2,解析:-p指定容器启动后docker上运行的端口映射及容器里运行的端口,80:80,第一个80表示docker系统上的80,第二个80表示docker虚拟机里面的端口。用户默认访问本机80端口,自动映射到容器里面的80端口。 |
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 |
Docker registry退出; |
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 |
截取容器停止时的退出状态值。 |
7. Docker虚拟化平台的案例
- Docker镜像
- Docker容器(虚拟机)
- Docker仓库
- -i,interactive交互模式;
- -t,tty打开一个终端;
- -d,daemon后台启动;
- -p,开启DNAT映射,将宿主机80映射至容器的80,用户访问宿主机的80即是访问容器的80。
- docker ps
#查看虚拟机(容器)的IP地址;
docker inspect 3d5559023d71|grep -i ipaddr|tail -1|awk -F\" '{print $4}'
#将宿主机的index.html文件部署至Nginx容器(虚拟机)中;
docker cp index.html 3d5559023d71:/usr/share/nginx/html/
8.WEB平台管理&镜像管理
通常来讲,开发人员和管理人员默认通过命令行来创建及运行Docker容器,但Docker的Remote API让他们可以通过充分利用REST(代表性状态传输协议)的API,运行相同的命令。Docker UI也是基于API方式管理宿主机的Docker引擎。Docker UI Web前端程序让你可以处理通常通过Web浏览器的命令行来管理的许多任务。主机上的所有容器都可以通过仅仅一条连接来处理,该项目几乎没有任何依赖关系。该软件目前仍在大力开发之中,但是它采用麻省理工学院(MIT)许可证,所以可以免费地重复使用。
Docker UI不包含任何内置的身份验证或安全机制,所以务必将任何公之于众的DockerUI连接放在用密码来保护的系统后面。
1)下载Docker UI镜像;
只需要在宿主机pull相关的镜像即可,指令如下:
docker pull uifd/ui-for-docker
docker images
2)启动docker-UI服务,并且映射9000至容器9000;
docker run -it -d --name docker-web -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock docker.io/uifd/ui-for-docker
如果启动Docker端口映射,报错信息如下:
docker0: iptables: No chain/target/match by that name.
解决方法:
如上报错信息是因为本地iptables规则策略没有匹配的链表,解决方案如下:
pkill docker iptables -t nat -F ifconfig docker0 down yum install -y bridge* -y brctl delbr docker0 service docker restart |
宿主机访问:9000端口
管理启动,停止容器实例
#将修改的新容器提交为新镜像; docker commit f43cc8b041d0 #默认会提交到images列表中; docker images #默认提交的镜像名称是None,可以修改镜像名称; docker tag b95ad546e113 nginx2 |
#将修改的新容器提交为新镜像;docker export c16d454849b6 >centos-v2.tar #默认不会提交到images列表中,而是在当前目录; ls -l centos-v2.tar #如果将导出tar镜像文件,导入镜像列表&可以加上名称; cat centos-v2.tar |docker import - cat centos-v2.tar |docker import - centos:v2 |
5)Docker 镜像管理Load|Save(主要是针对镜像|完整导出)
#导入images列表中的镜像为tar文件; docker save centos:v1 >centos-v3.tar #导入tar文件至镜像列表&默认无需修改名称; docker load < centos-v3.tar |
9.Docker网络剖析&Pipework网络
基于Docker run创建Docker容器时,可以使用--net选项指定容器的网络模式,Docker默认有以下四种网络模式:
- host模式,使用--net=host指定;
- container模式,使用--net=container:NAME_or_ID指定;
- none模式,使用--net=none指定;,
- bridge模式,使用--net=bridge指定,默认设置;
1) Host模式详解:
默认Docker容器运行会分配独立的Network Namespace隔离子系统,基于host模式,容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace,容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。
2) Container模式详解:
熟悉了host模式,Container模式也非常好理解,Container模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。
即新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样两个容器除了网络方面相同之外,其他的如文件系统、进程列表等还是隔离的。
3) None模式详解:
None模式与其他的模式都不同,如果处于None模式,Docker容器拥有自己的Network Namespace,但是并不为Docker容器进行任何网络配置。也就是说该Docker容器没有网卡、IP、路由等信息,需要手工为Docker容器添加网卡、配置IP等,典型Pipework工具为Docker容器指定IP等信息;
4) Bridge桥接模式
Bridge模式是Docker默认的网络模式,该模式会为每一个容器分配Network Namespace、设置IP、路由等配置,默认会将Docker容器连接到一个虚拟网桥交换机Docker0上。
Docker Bridge创建过程:
1) 首先宿主机上创建一对虚拟网卡veth pair设备,veth设备总是成对出现的,组成了一个数据的通道,数据从一个设备进入,就会从另一个设备出来,veth设备常用来连接两个网络设备。
2) Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0,然后将另一端放在宿主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到docker0网桥中,可以通过brctl show命令查看。
3) 从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。
4) 此时容器IP与宿主机能够通信,宿主机也可以访问容器中的IP地址,在Bridge模式下,连在同一网桥上的容器之间可以相互通信,同时容器也可以访问外网,但是其他物理机不能访问docker容器IP,需要通过NAT将容器IP的port映射为宿主机的IP和port。
Bridge自定义桥接br0:
基于CentOS7.x构建Docker桥接网络,案例方法如下:
配置bridge桥接网络可以直接设置网卡配置文件:
/etc/sysconfig/network-scripts/下,修改ifcfg-ens32网卡配置,同时增加ifcfg-br0桥接网卡配置,操作流程如下:
DEVICE=ens32 BOOTPROTO=static ONBOOT=yes TYPE=Ethernet BRIDGE="br0" IPADDR=192.168.86.128 NETMASK=255.255.255.0 GATEWAY=192.168.86.2 |
DEVICE="br0" BOOTPROTO=static ONBOOT=yes TYPE="Bridge" IPADDR=192.168.86.128 NETMASK=255.255.255.0 GATEWAY=192.168.86.2 |
service network restart
systemctl daemon-reload
systemctl restart docker.service
Docker默认提供了一个隔离的内网环境,启动时会建立一个docker0的虚拟网卡,每个容器都是连接到docker0网卡上的。而docker0的ip段为172.17.0.1,如果想让容器与宿主机同一网段的其他机器访问,就必须在启动docker的时候将某个端口映射到宿主机的端口。
KVM的桥接网络非常方便,其实docker也比较方便,至少不是自带的桥接而已,今天我们来讲解centos7下如果快速实现docker容器桥接网络,并为容器分配外网IP。如下为通过pipework工具配置容器IP方法:
安装pipework git clone https://github.com/jpetazzo/pipework cp ~/pipework/pipework /usr/local/bin/ 下载centos镜像启动容器并设置网络 docker pull docker.io/jdeathe/centos-ssh docker tag docker.io/jdeathe/centos-ssh centos-ssh (修改镜像别名) docker run -itd --privileged --net=none --name=ssh_86.131 centos-ssh /bin/bash pipework br0 centos-ssh 192.168.86.131/24@192.168.86.2(@后面是bro网卡) 进入容器查看ip docker exec -it 8dec649772d4 /bin/bash |
10.Docker仓库构建&仓库管理
- Docker公共仓库:零配置、公共的、相对稳定、不安全、速度比较慢;
- Docker私有仓库:手工配置、私有、很稳定、安全、速度非常快。
docker pull docker.io/registry |
mkdir -p /data/registry/ docker run -itd -p 5000:5000 -v /data/registry:/var/lib/registry docker.io/registry |
Docker本地仓库启动后台容器启动,如图所示:
for i in `docker images |awk 'NR>1 {print $1":"$2}'`;do echo $i ;done for i in `docker images |awk 'NR>1 {print $1":"$2}'`;do docker tag $i localhost:5000/$i ;docker push localhost:5000/$i;done |
docker pull busybox docker tag busybox 192.168.86.128:5000/busybox docker push 192.168.86.128/busybox |
curl -XGET http://192.168.86.128:5000/v2/_catalog curl -XGET http://192.168.86.128:5000/v2/busybox/tags/list |
OPTIONS='--selinux-enabled --log-driver=journald --signature-verification=false --insecure-registry 192.168.86.128:5000' ADD_REGISTRY='--add-registry 192.168.86.128:5000' |
至此,docker本地私有仓库部署完毕,可以向仓库中添加或者更新Docker镜像。
11.Dockerfile企业案例
- Docker commit|export将新容器提交至Images列表;
- 编写Dockerfile,bulid新的镜像至镜像列表;
1. Dockerfile语法命令详解一
FROM 指定所创建镜像的基础镜像; MAINTAINER 指定维护者信息; RUN 运行命令; CMD 指定启动容器时默认执行的命令; LABEL 指定生成镜像的元数据标签信息; EXPOSE 声明镜像内服务所监听的端口; ENV 指定环境变量; ADD 赋值指定的<src>路径下的内容到容器中的<dest>路径下,<src>可以为URL;如果为tar文件,会自动解压到<dest>路径下 COPY 赋值本地主机的<scr>路径下的内容到容器中的<dest>路径下;一般情况下推荐使用COPY而不是ADD; ENTRYPOINT 指定镜像的默认入口; VOLUME 创建数据挂载点; USER 指定运行容器时的用户名或UID; WORKDIR 配置工作目录; ARG 指定镜像内使用的参数(例如版本号信息等); ONBUILD 配置当前所创建的镜像作为其他镜像的基础镜像时,所执行的创建操作的命令; STOPSIGNAL 容器退出的信号; HEALTHCHECK 如何进行健康检查; SHELL 指定使用SHELL时的默认SHELL类型; |
2. Dockerfile语法命令详解二
FROM指定所创建的镜像的基础镜像,如果本地不存在,则默认会去Docker Hub下载指定镜像。 格式为:FROM<image>,或FROM<image>:<tag>,或FROM<image>@<digest>。任何Dockerfile中的第一条指令必须为FROM指令。并且,如果在同一个Dockerfile文件中创建多个镜像,可以使用多个FROM指令(每个镜像一次)。 MAINTAINER指定维护者信息,格式为MAINTAINER<name>。例如:MAINTAINER image_creator@docker.com 该信息将会写入生成镜像的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该指令将复制指定的<src>路径下的内容到容器中的<dest>路径下。 格式为:ADD<src> <dest> 其中<src>可以使Dockerfile所在目录的一个相对路径(文件或目录),也可以是一个URL,还可以是一个tar文件(如果是tar文件,会自动解压到<dest>路径下)。<dest>可以使镜像内的绝对路径,或者相当于工作目录(WORKDIR)的相对路径。路径支持正则表达式,例如: ADD *.c /code/ COPY复制本地主机的<src>(为Dockerfile所在目录的一个相对路径、文件或目录)下的内容到镜像中的<dest>下。目标路径不存在时,会自动创建。路径同样支持正则。格式为:COPY <src> <dest>当使用本地目录为源目录时,推荐使用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<varname>=<value>格式传入。格式为: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? ~* |
3.Dockerfile制作规范及技巧
从企业需求出发,定制适合自己需求、高效方便的镜像,可以参考官方Dockerfile文件,也可以根据自身的需求,逐步的完善,在构建中不断优化Dockerfile文件;
Dockerfile制作镜像规范和技巧如下:
- 精简镜像用途:尽量让每个镜像的用途都比较集中、单一,避免构造大而复杂、多功能的镜像;
- 选用合适的基础镜像:过大的基础镜像会造成构建出臃肿的镜像,一般推荐比较小巧的镜像作为基础镜像;
- 提供详细的注释和维护者信息: Dockerfile也是一种代码,需要考虑方便后续扩展和他人使用;
- 正确使用版本号:使用明确的具体数字信息的版本号信息,而非latest,可以避免无法确认具体版本号,统一环境;
- 减少镜像层数:减少镜像层数建议尽量合并RUN指令,可以将多条RUN指令的内容通过&&连接;
- 及时删除临时和缓存文件:这样可以避免构造的镜像过于臃肿,并且这些缓存文件并没有实际用途;
- 提高生产速度:合理使用缓存、减少目录下的使用文件,使用.dockeringore文件等;
- 调整合理的指令顺序:在开启缓存的情况下,内容不变的指令尽量放在前面,这样可以提高指令的复用性;
- 减少外部源的干扰:如果确实要从外部引入数据,需要制定持久的地址,并带有版本信息,让他人可以重复使用而不出错。
4.DockerFile企业案例一
DockerFile企业案例一,将启动Docker容器,同时开启Docker容器对外的22端口的监听,实现通过CRT或者Xshell登录:
#进入容器
docker exec -it 85aa1a867c3f /bin/bash
rpm --rebuilddb && yum install pam cracklib-dicts -y
[root@5255b18871ae /]# echo '123456' | passwd --stdin root
Changing password for user root.
passwd: all authentication tokens updated successfully.
我们如果现在启动sshd,sshd会报错:
Could not load host key: /etc/ssh/ssh_host_rsa_key
Could not load host key: /etc/ssh/ssh_host_ecdsa_key
Could not load host key: /etc/ssh/ssh_host_ed25519_key
所以我们先生成/etc/ssh/ssh_host_rsa_key和/etc/ssh/ssh_host_ecdsa_key和/etc/ssh/ssh_host_ed25519_key:
[root@85aa1a867c3f /]# ssh-keygen -q -t rsa -b 2048 -f /etc/ssh/ssh_host_rsa_key -N ''
[root@85aa1a867c3f /]# ssh-keygen -q -t rsa -b 2048 -f /etc/ssh/ssh_host_ecdsa_key -N ''
[root@85aa1a867c3f /]# ssh-keygen -q -t rsa -b 2048 -f /etc/ssh/ssh_host_ed25519_key -N ''
然后查一下容器的IP,启动sshd:
[root@5255b18871ae /]# /usr/sbin/sshd
我们看到容器IP为192.168.1.3,从外部远程ssh到这个容器:
发现容器立即关闭了连接,原因是容器的ssh使用了pam_loginuid.so模块,我们把它关掉:
[root@5255b18871ae /]# sed -i '/^session\s\+required\s\+pam_loginuid.so/s/^/#/' /etc/pam.d/sshd
上述命令的意思是:在/etc/pam.d/sshd文件里注释掉"session required pam_loginuid.so"这一行。
然后重新启动sshd:
[root@5255b18871ae /]# /usr/sbin/sshd
再次尝试远程ssh登入:
[root@localhost ~]# ssh root@192.168.1.3
root@192.168.1.3's password:
Last login: Tue Dec 2 03:00:07 2014 from 192.168.1.3
[root@5255b18871ae ~]#
登录成功!
Dockerfile文件方式制作如下:
Docker服务端创建Dockerfile文件,实现容器运行开启22端口,内容如下:
# 设置基本的镜像,后续命令都以这个镜像为基础 FROM centos # 作者信息 MAINTAINER JFEDU.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 RUN ssh-keygen -q -t rsa -b 2048 -f /etc/ssh/ssh_host_rsa_key -N '' RUN ssh-keygen -q -t rsa -b 2048 -f /etc/ssh/ssh_host_ecdsa_key -N '' RUN ssh-keygen -q -t rsa -b 2048 -f /etc/ssh/ssh_host_ed25519_key -N '' RUN sed -i '/^session\s\+required\s\+pam_loginuid.so/s/^/#/' /etc/pam.d/sshd # 暴露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 .
5. 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 |
6. 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 service httpd start;/bin/bash |
最终截图如下:
7. 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/mysq l-$MYSQL_VERSION-linux-glibc2.5-x86_64.tar.gz" -o mysql.tar.gz \ && curl -SL "http://mysql.he.net/Downloads/MySQL-$MYSQL_MAJOR/mysql-$MY SQL_VERSION-linux-glibc2.5x86_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 /usr/local/mysql/bin/mysqld_safe |
12.Docker容器CPU&MEM&DISK资源扩容
1、Docker容器CPU&MEM资源扩容
1) Docker容器支持CPU、MEM、DISK的资源的配置的,默认配置的参数指令:
- CPU配置:--cpuset-cpus=0-0;
- MEM配置:-m 512m;
启动容器:
- privileged:特权:允许执行mount等root执行的命令,还可以容器里面启动容器
docker run -itd --privileged --net=none --cpuset-cpus=0-1 -m 1024m --name=ssh_86.132 centos-ssh:v1 /bin/bash
2、Docker容器Disk硬盘资源扩容一(Overlay2驱动方式)
#查看docker默认驱动命令是docker info|egrep "Storage Driver"
第一种方式:指定容器启动默认磁盘大小
Overlay2驱动方式:不支持在线扩容
Docker容器默认启动的虚拟机,会占用宿主机的资源(CPU、内存、硬盘),例如默认Docker基于Overlay2驱动方式,容器硬盘的rootfs 根分区空间是整个宿主机的空间大小。
可以指定默认容器的大小(在启动容器的时候指定),可以在docker配置文件:/etc/sysconfig/docker中,OPTIONS参数后面添加如下代码,指定Docker容器rootfs容量大小为10G:
vi /etc/sysconfig/docker
OPTIONS='--storage-opt overlay2.size=10G'
修改Docker存储配置文件,加入如下代码:(默认如果已经为overlay2,则无需修改)
vi /etc/sysconfig/docker-storage
DOCKER_STORAGE_OPTIONS="--storage-driver overlay2 "
然后重启docker即可;
Overlay2 Docker磁盘驱动模式,如果要调整其大小,通过如上的方法,会导致Docker引擎服务无法启动,还需要文件系统设置为xfs,并且支持目录级别的磁盘配额功能;
CentOS7.x Xfs磁盘配额配置,新添加一块硬盘,设置磁盘配额方法步骤如下:
1)添加新的硬盘如图所示:
2)格式化硬盘为xfs文件系统格式,命令如下:
mkfs.xfs -f /dev/sdb
3)创建data目录,后续将作为docker数据目录;
mkdir /data/ -p
4)挂载data目录,
mount -o uquota,prjquota /dev/sdb /data/
或者写入fstab执行mount -a
5)将docker引擎默认数据存储目录:/var/lib/docker重命名,并且将/data/docker目录软链接至/var/lib/下即可;
mkdir -p /data/docker/
cd /var/lib/
mv docker docker.bak
ln -s /data/docker/ .
6)重启Docker服务,并且查看进程,可以看到docker overlay2.size大小配置,如图所示:
7) 基于Docker客户端指令启动Docker容器,并且查看最新容器的磁盘空间为10G,则设置容器大小成功,如图所示:
以上方法只适用于新容器生成,并且修改后需要重启docker,无法做到动态给正在运行容器指定大小,
3、Docker容器Disk硬盘资源扩容二(DeviceMapper驱动方式)
第一种方式:指定容器启动默认磁盘大小
DeviceMapper驱动方式:支持在线扩容
Docker容器硬盘热扩容操作记录centos 7里使用docker的时候默认存储引擎是Overlay2,而DeviceMapper驱动支持ext2、ext3、ext4,不支持xfs,而xfs是CentOS7的默认文件系统类型。
所以建议docker服务器的文件系统格式调整为ext4(在centos7系统安装时可以手动指定所在分区为ext4格式)。
操作步骤:
1,以在docker配置文件:/etc/sysconfig/docker中,OPTIONS参数后面添加如下代码,指定Docker容器rootfs容量大小为10G:
OPTIONS='--storage-opt dm.basesize=10G'
2,修改Docker存储配置文件,修改默认存储引擎为DeviceMapper,加入如下代码:(默认如果已经为devicemapper,则无需修改)
vi /etc/sysconfig/docker-storage
DOCKER_STORAGE_OPTIONS="--storage-driver devicemapper"
然后重启docker即可;
devicemapper Docker磁盘驱动模式,如果要调整其大小,通过如上的方法,会导致Docker引擎服务无法启动,还需要格式化文件系统设置为ext4,并且支持目录级别的磁盘配额功能;
CentOS7.x ext4磁盘配额配置,新添加一块硬盘,设置磁盘配额方法步骤如下:
2)格式化硬盘为ext4文件系统格式,命令如下:
mkfs.ext4 -f /dev/sdb
3)创建data目录,后续将作为docker数据目录;
mkdir /data/ -p
4)挂载data目录下,vi /etc/fstab && mount -a
5)将docker引擎默认数据存储目录:/var/lib/docker重命名,并且将/data/docker目录软链接至/var/lib/下即可;
mkdir -p /data/docker/
cd /var/lib/
mv docker docker.bak
ln -s /data/docker/ .
6)重启Docker服务,并且查看进程,可以看到docker dm.basesize大小配置,如图所示:
7) 基于Docker客户端指令启动Docker容器,并且查看最新容器的磁盘空间为10G,则设置容器大小成功,如图所示:
第二种方法:在线扩容正在运行容器指定大小 :
xfs文件系统修改文件系统大小命令:xfs_growfs
ext4文件系统修改文件系统大小命令: resize2fs
1)查看现有的容器磁盘大小:
2)查看mapper设备:
3)查看卷信息表:
4)根据要扩展的大小,计算需要多少扇区:
第二个数字是设备的大小,表示有多少个512-bytes 的扇区. 这个值略高于 10GB 的大小。
我们来计算一下一个 15GB 的卷需要多少扇区,
echo $((15*1024*1024*1024/512)) 31457280
5)修改卷信息表--激活--并且验证(红色3个部分)
echo 0 31457280 thin 253:2 62|dmsetup load docker-8:16-131100-7181dfff737acecb33c71d4b8dd79beef3bd84e34df6c4e51cd5096591548009
dmsetup resume docker-8:16-131100-7181dfff737acecb33c71d4b8dd79beef3bd84e34df6c4e51cd5096591548009
dmsetup table docker-8:16-131100-7181dfff737acecb33c71d4b8dd79beef3bd84e34df6c4e51cd5096591548009
6)修改文件系统大小:
先查看卷所在的目录是什么文件系统,centos7默认为xfs用xfs_growfs 命令,如果是ext4则用resize2fs命令
8)最后验证磁盘大小:
Docker虚拟化的更多相关文章
- XP+devOps开发模式与scrum敏捷开发对比,docker虚拟化
XP+devOps开发模式与scrum敏捷开发对比,docker虚拟化 我们现在用的就是典型的XP+devOps模式,已经放弃scrum了 现在还很多公司弄docker虚拟化docker非常复杂,当然 ...
- Docker虚拟化平台
1.虚拟化技术的概念 1)虚拟化就是把物理资源转变为逻辑上可以管理的资源,以打破物理结构间的壁垒,让计算机的元件运行在虚拟的基础上,而不是真实的物理设备: 2)虚拟化技术可以将物理机硬件资源虚拟生成单 ...
- Docker虚拟化实战学习——基础篇(转)
Docker虚拟化实战学习——基础篇 2018年05月26日 02:17:24 北纬34度停留 阅读数:773更多 个人分类: Docker Docker虚拟化实战和企业案例演练 深入剖析虚拟化技 ...
- Docker虚拟化之<基础理论>
1.虚拟化技术的概念 (1)虚拟化技术主要是将物理的资源转变为逻辑上可以管理的资源,以打破物理结构上的壁垒,让计算元件运行在虚拟的基础上,而不是真实的物理资源上.(2)虚拟化技术的底层是要进行虚拟化的 ...
- docker虚拟化平台构建
docker虚拟化平台构建 从1.13版本以后的docker软件分为连个版本:企业版.社区版,在企业中推荐社区版本. 构建docker平台环境,系统选择centos7.x,推荐linux内核3.10 ...
- Linux运维之docker虚拟化部署nginx
一.Docker的概念 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱 ...
- 基于docker虚拟化创建hadoop集群
最近想用hadoop做一个测试,与性能无关的测试,但是可与屌丝的命,手头没有太多机器,也租不起云主机.这里使用docker进行虚拟化,并搭建hadoop集群,在这里将过程记录如下. 首先安装docke ...
- Docker虚拟化容器的使用
Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从Apache2.0协议开源. Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级.可移植的容器中,然后发布到任何流行的 Li ...
- docker虚拟化之将容器做成镜像
1,docker ps -a 选择要启动的容器. 2,docker start 容器+ID 启动容器 3,docker exec -i -t 容器ID /bin/bash 进入容器 这里的/ ...
随机推荐
- flume的sink写入hive表
flume的配置文件如下: a1.sources=r1 a1.channels=c1 a1.sinks=s1 a1.sources.r1.type=netcat a1.sources.r1.bind= ...
- NOI2018游记【一年后的回忆】
今天是2019年9月6日,我坐在大学的宿舍里,同样敲着键盘,在一年前充满回忆与汗水的博客上,又一次地回忆往事. 那是2018年的7月,我停了三个月的课,攥着一张thusc的安慰约,放手在OI的生涯最后 ...
- LeetCode 838. Push Dominoes
原题链接在这里:https://leetcode.com/problems/push-dominoes/ 题目: There are N dominoes in a line, and we plac ...
- php解决大文件断点续传
核心原理: 该项目核心就是文件分块上传.前后端要高度配合,需要双方约定好一些数据,才能完成大文件分块,我们在项目中要重点解决的以下问题. * 如何分片: * 如何合成一个文件: * 中断了从哪个分片开 ...
- git create remote branch (五)
admin@PC-panzidong MINGW64 ~/WebstormProjects/backEndServer (master) 查看本地分支信息$ git branch* master ad ...
- python 微服务开发书中几个方便的python框架
python 微服务开发是一本讲python 如果进行微服务开发的实战类书籍,里面包含了几个很不错的python 模块,记录下,方便后期回顾学习 处理并发的模块 greenlet && ...
- 【算法编程 C++ Python】根据前序遍历、中序遍历重建二叉树
题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7, ...
- 安装关系型数据库MySQL 安装大数据处理框架Hadoop
作业要求来自:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE2/homework/3161 1.Hadoop的介绍 Hadoop最早起源于Nutch.Nut ...
- JavaBitSet学习
一.背景 之前公司项目需要对会员人群进行去重过滤,人群的维度是user_id: 因此采用了BitSet做简单的去重,方案将user_id作为bitset中的bit索引: 通过and\or\xor基础运 ...
- 剑指offer:整数中1出现的次数
题目描述: 求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1.10.11.12.13因此共出现6次,但是对于后面问题他就没辙了 ...