Docker 镜像制作及分层
指尖二进制 • 1 年前 • 733 次点击 • DOCKER
[TOC]
一:手动将容器保存为镜像
一:制作单服务镜像,centos7.x
制作一个ssh带有ssh端口的镜像
1.1:启动一个基础容器
ssh默认的端口为22,我们将docker中centos的22端口映射到宿主机的10022端口
[root@docker-01 ~]# docker run -d -p 10022:22 --name centos7 --privileged=true centos:7 /usr/sbin/init
进入容器
[root@docker-01 ~]# docker exec -it centos7 /bin/bash
安装常用工具
[root@c3807dc80b0f /]# yum install -y openssh-server vim net-tools wget initscripts openssh-clients
配置ssh服务
[root@c3807dc80b0f /]# vim /etc/ssh/sshd_config
79 GSSAPIAuthentication no
115 UseDNS no
[root@c3807dc80b0f /]# systemctl restart sshd
[root@c3807dc80b0f /]# systemctl enable sshd
[root@c3807dc80b0f /]# netstat -auntlp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 315/sshd
tcp6 0 0 :::22 :::* LISTEN 315/sshd
查看容器ip地址并设置密码
[root@c3807dc80b0f /]# hostname -i
172.17.0.2
[root@c3807dc80b0f /]# echo 123456|passwd --stdin root
Changing password for user root.
passwd: all authentication tokens updated successfully.
在windows连接试试
[c:\~]$ ssh 10.0.0.11 10022
[root@c3807dc80b0f ~]# hostname -i
172.17.0.2
1.2:把容器提交为镜像
docker container commit 容器id 名称
[root@docker-01 ~]# docker container commit c3807dc80b0f centos7_7_ssh_v1
[root@docker-01 ~]# docker image ls|grep centos7_7
centos7_7_ssh_v1 latest bdf665d619cd 13 seconds ago 378MB
1.3:测试镜像功能
基于centos7.7_ssh_v1启动一个新的容器。(启动服务,又能夯住的命令)
[root@docker-01 ~]# docker run -d -p 10023:22 centos7_7_ssh_v1 /usr/sbin/sshd -D
[root@docker-01 ~]# docker ps -a -l
CONTAINER ID COMMAND
d8ec89e49f7a "/usr/sbin/sshd -D"
[root@docker-01 ~]# docker container exec -it d8ec89e49f7a /bin/bash
[root@d8ec89e49f7a /]# hostname -i
172.17.0.2
[root@d8ec89e49f7a /]# ps -ef|grep -v ps
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 04:51 ? 00:00:00 /usr/sbin/sshd -D
root 26 0 0 04:52 pts/1 00:00:00 /bin/bash
[c:\~]$ ssh 10.0.0.11 10023
[root@d8ec89e49f7a ~]# ifconfig
inet 172.17.0.2 netmask 255.255.0.0 broadcast 172.17.255.255
1.4:导出镜像
[root@docker-01 ~]# docker image ls |grep centos7_7
centos7_7_ssh_v1 latest b70924598385 19 minutes ago 378MB
[root@docker-01 ~]# docker image save -o /opt/docker_centos7_7_ssh_v1.tar.gz centos7_7_ssh_v1
[root@docker-01 ~]# ll -h /opt/docker_centos7_7_ssh_v1.tar.gz
-rw------- 1 root root 372M Mar 24 12:55 /opt/docker_centos7_7_ssh_v1.tar.gz
二:制作多服务镜像
2.1:启动一个基础容器并设置基础服务
[root@docker-01 ~]# docker run -d -p 10023:22 centos7_7_ssh_v1 /usr/sbin/sshd -D
1cf7c1c7293f717c87aa02758841ce71427f7cd018e319a86cb2bbf9cf5471d1
[root@docker-01 ~]# docker ps -a -l
CONTAINER ID COMMAND
1cf7c1c7293f "/usr/sbin/sshd -D"
[root@docker-01 ~]# docker container exec -it 1cf7c1c7293f /bin/bash
[root@1cf7c1c7293f /]# hostname -i
172.17.0.2
[root@1cf7c1c7293f ~]# yum install nginx-1.16.1-1.el7.ngx.x86_64.rpm -y
[root@1cf7c1c7293f ~]# systemctl start nginx
[root@1cf7c1c7293f ~]# systemctl enable nginx
[root@eada2109fd0e /]# vim /init.sh
#!/bin/bash
systemctl start nginx
systemctl start sshd
[root@1cf7c1c7293f /]# exit
2.2:打包容器为镜像
[root@docker-01 ~]# docker ps
CONTAINER ID
1cf7c1c7293f
[root@docker-01 ~]# docker container commit 1cf7c1c7293f centos7_7_ssh_nginx_v1
2.3:测试
[root@docker-01 ~]# docker run -d -p 10022:22 -p 80:80 --privileged=true centos7_7_ssh_nginx_v1 /usr/sbin/init
浏览器访问10.0.0.11测试
三:制作单服务镜像,centos6.9
3.1:启动一个基础容器
ssh默认的端口为22,我们将docker中centos的22端口映射到宿主机的10022端口
[root@docker-01 ~]# docker run --name centos6.9 -itd centos:6.9 /bin/bash
进入容器
[root@docker-01 ~]# docker exec -it centos6.9 /bin/bash
安装常用工具
[root@c3807dc80b0f /]# yum install -y openssh-server vim net-tools wget initscripts openssh-clients
配置ssh服务
[root@c3807dc80b0f /]# vim /etc/ssh/sshd_config
79 GSSAPIAuthentication no
115 UseDNS no
[root@c3807dc80b0f /]# /etc/init.d/sshd restart
[root@c3807dc80b0f /]# chkconfig sshd on
[root@c3807dc80b0f /]# netstat -auntlp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 315/sshd
tcp6 0 0 :::22 :::* LISTEN 315/sshd
查看容器ip地址并设置密码
[root@c3807dc80b0f /]# hostname -i
172.17.0.2
[root@c3807dc80b0f /]# echo 123456|passwd --stdin root
Changing password for user root.
passwd: all authentication tokens updated successfully.
在windows连接试试
[root@docker-01 ~]# ssh 172.17.0.2
root@172.17.0.2's password:
Last login: Wed May 6 09:05:04 2020 from 172.17.0.1
[root@c3807dc80b0f ~]#
3.2:把容器提交为镜像
docker container commit 容器id 名称
[root@docker-01 ~]# docker container commit c3807dc80b0f centos6.9_ssh:v1
[root@docker-01 ~]# docker image ls|grep centos6.9
centos6.9_ssh v1 e6cfae2404a2 About a minute ago 395MB
3.3:测试镜像功能
基于centos7.7_ssh_v1启动一个新的容器。(启动服务,又能夯住的命令)
[root@docker-01 ~]# docker run -itd -p 10022:22 centos6.9_ssh:v1 /usr/sbin/sshd -D
[root@docker-01 ~]# docker ps -a -l
CONTAINER ID COMMAND
a3cc8f1141e6 "/bin/bash"
[root@docker-01 ~]# docker container exec -it a3cc8f1141e6 /bin/bash
[root@d8ec89e49f7a /]# hostname -i
172.17.0.2
[root@d8ec89e49f7a /]# ps -ef|grep -v ps
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 09:11 pts/0 00:00:00 /bin/bash
root 16 0 0 09:12 pts/1 00:00:00 /bin/bash
[c:\~]$ ssh 10.0.0.11 10022
[root@d8ec89e49f7a ~]# ifconfig
inet 172.17.0.2 netmask 255.255.0.0 broadcast 172.17.255.255
3.4:导出镜像
[root@docker-01 ~]# docker image ls |grep centos6.9_ssh
centos6.9_ssh v1 e6cfae2404a2 3 hours ago 395MB
[root@docker-01 ~]# docker image save -o /opt/docker_centos6.9_ssh_v1.tar.gz centos6.9_ssh:v1
[root@docker-01 ~]# ll -h /opt/docker_centos6.9_ssh_v1.tar.gz
-rw------- 1 root root 388M May 6 19:46 /opt/docker_centos6.9_ssh_v1.tar.gz
二:dockerfile自动构建docker镜像
一:释意
FROM #指定基础镜像
MAINTAINER #告诉别人(指定维护者信息,可以没有)描述,标签
LABLE #描述,标签
RUN #你想让它干啥(在命令前面加上RUN即可)
ADD #可以自动解压tar,写脚本 制作docker基础的系统镜像
WORKDIR #设置当前工作目录。docker run -it --workdir /tmp centos:6.9
[root@docker-01 ~]# docker run -it --workdir /tmp centos:6.9
[root@a16f905425a6 tmp]# pwd
/tmp
VOLUME #设置卷,挂载主机目录。写到dockerfile里面启动容器就会创建卷
EXPOSE #指定对外的端口(-P 随机端口)
CMD #指定容器启动后的要干的事情(容易被替换)
dockerfile其他指令:
COPY #复制文件(不会解压)root.tar.gz
ENV #环境变量
ENTRYPOINT #容器启动后执行的命令(无法被替换,启容器的时候指定的命令,会被当成参数)
.dockerignore #选择那些文件不发送给docker-server端
二:支持单服务dockerfile
2.1:编写dockerfile
[root@docker-01 ~]# docker pull centos:6.9
[root@docker-01 ~]# mkdir /dockerfile/centos6_9_ssh -pv
[root@docker-01 ~]# cd /dockerfile/centos6_9_ssh
[root@docker-01 centos6_9_ssh]# vim dockerfile
FROM centos:6.9
RUN yum install -y openssh-server vim net-tools wget initscripts openssh-clients
RUN /etc/init.d/sshd restart
RUN echo 123456|passwd --stdin root
CMD ["/usr/sbin/sshd","-D"]
2.2:制作镜像并利用新镜像启动容器
[root@docker-01 centos7_7_ssh]# docker build --network=host -t centos6_9_ssh:v1 .
[root@docker-01 centos7_7_ssh]# docker run -d -p 10022:22 centos6_9_ssh:v1
2.3:测试容器
[root@docker-01 centos7_7_ssh]# ssh root@10.0.0.11 -p 10022
[root@64845f457303 ~]#
[c:\~]$ ssh 10.0.0.11 10022
[root@64845f457303 ~]#
三:支持多服务dockerfile
3.1:编写dockerfile
[root@docker-01 ~]# cd /dockerfile/
[root@docker-01 dockerfile]# cp -a centos6_9_ssh/ centos6_9_ssh_nginx
[root@docker-01 dockerfile]# cd centos6_9_ssh_nginx/
[root@docker-01 centos6_9_ssh_nginx]# vim dockerfile
FROM centos:6.9
RUN yum install -y wget
RUN wget -P /etc/yum.repos.d/ http://mirrors.aliyun.com/repo/epel-6.repo
RUN yum install -y openssh-server vim net-tools initscripts openssh-clients nginx
RUN /etc/init.d/sshd restart
RUN echo 123456|passwd --stdin root
ADD init.sh /init.sh
CMD ["/bin/bash","init.sh"]
[root@docker-01 centos6_9_ssh_nginx]# vim init.sh
#/bin/bash
service sshd restart
nginx -g 'daemon off;'
3.2:制作镜像并利用新镜像启动容器
[root@docker-01 centos6_9_ssh_nginx]# docker build --network=host -t centos6_9_ssh_nginx:v1 .
[root@docker-01 centos6_9_ssh_nginx]# docker run -d -p 10022:22 -p 80:80 centos6_9_ssh_nginx:v1
3.3:测试容器
[root@docker-01 centos6_9_ssh_nginx]# docker ps -a -l
[root@docker-01 centos6_9_ssh_nginx]# curl -I 10.0.0.11 2>/dev/null |head -3
HTTP/1.1 200 OK
Server: nginx/1.10.3
Date: Thu, 26 Mar 2020 13:48:46 GMT
[root@docker-01 centos6_9_ssh_nginx]# ssh root@10.0.0.11 -p 10022
[root@458e64371097 ~]#
三:docker镜像分层
镜像分层的好处:复用,节省磁盘空间,相同的内容只需加载一份到内存。 修改dockerfile之后,再次构建速度快
dockerfile 优化:
1:尽可能选择体积小linux,alpine
2:尽可能合并RUN指令,清理无用的文件(yum缓存,源码包)
3:修改dockerfile,把变化的内容尽可能放在dockerfile结尾
4:使用.dockerignore,减少不必要的文件ADD . /html
查看镜像分层
镜像只要有变化提交(制作)之后就是一层,每次制作就是需要改变有变化的目录或者文件
[root@docker-01 ~]# docker image save -o /opt/docker_centos6_9_ssh_nginx.tar.gz centos6_9_ssh_nginx:v1
[root@docker-01 ~]# sz /opt/docker_centos6_9_ssh_nginx.tar.gz
在windows桌面解压,并打开查看有一个287694012464......的文件夹就是几层
[root@docker-01 ~]# docker image load -i /opt/docker_centos6_9_ssh_nginx.tar.gz
f07502887b0e: Loading layer [===============================>] 96.78MB/96.78MB
8b6966c0b92b: Loading layer [===============================>] 3.584kB/3.584kB
6248c8712e5e: Loading layer [===============================>] 290.9MB/290.9MB
007e13cda921: Loading layer [===============================>] 13.82kB/13.82kB
86e701f1d956: Loading layer [===============================>] 3.584kB/3.584kB
0cf5ad5aad60: Loading layer [===============================>] 2.048kB/2.048kB
Loaded image: centos6_9_ssh_nginx:v1
[root@docker-01 ~]# docker image history centos6_9_ssh_nginx:v1 #查看有几层出现变化
这个时候问题来了。在制作dockerfile时候,每一个RUN是一层,层越多加载的越慢
释意
FROM centos:6.9 #镜像本身就是一层
RUN yum install -y wget #每执行一个RUN就是一层
RUN wget -P /etc/yum.repos.d/ http://mirrors.aliyun.com/repo/epel-6.repo
RUN yum install -y openssh-server vim net-tools initscripts openssh-clients nginx
RUN /etc/init.d/sshd restart
RUN echo 123456|passwd --stdin root
ADD init.sh /init.sh #ADD也是一层
CMD ["/bin/bash","init.sh"]
这个层在docker里面不允许超过128层,怎么优化?
把RUN能合并的合并
[root@docker-01 centos6_9_ssh_nginx]# docker build --network=host -t centos6_9_ssh_nginx:v2 .
FROM centos:6.9
RUN yum install -y wget && \
wget -P /etc/yum.repos.d/ http://mirrors.aliyun.com/repo/epel-6.repo && \
yum install -y openssh-server vim net-tools initscripts openssh-clients nginx && \
/etc/init.d/sshd restart && \
echo 123456|passwd --stdin root
ADD init.sh /init.sh
CMD ["/bin/bash","init.sh"]
[root@docker-01 ~]# docker image history centos6_9_ssh_nginx:v2
[root@docker-01 ~]# docker image save -o /opt/docker_centos6_9_ssh_nginx_v2.tar.gz centos6_9_ssh_nginx:v2
[root@docker-01 ~]# docker image rm centos6_9_ssh_nginx:v2
[root@docker-01 ~]# docker image load -i /opt/docker_centos6_9_ssh_nginx_v2.tar.gz #再次导入发现只有两层出现变化
630e34fa77ed: Loading layer [=========================>] 292.7MB/292.7MB
0cf5ad5aad60: Loading layer [=========================>] 2.048kB/2.048kB