3.制作docker镜像
孙富阳, 江湖人称没人称。多年互联网运维工作经验,曾负责过孙布斯大规模集群架构自动化运维管理工作。擅长Web集群架构与自动化运维,曾负责国内某大型博客网站运维工作。
1.手动制作一个docker镜像
制作一个基于centos7系统的nginx镜像(单服务)
1:启动一个纯净的centos:7容器,安装nginx
[root@docker01 ~]# docker run -d -it -p 80:80 centos:7
[root@docker01 ~]# docker exec -it bold_feynman /bin/bash
#然后执行以下命令
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
yum install nginx -y
cd /usr/share/nginx/html
rm -f img index.html en-US
echo sfy > index.html
打开网页可以看到index文件的内容
2:把安装好服务的容器,提交为镜像
[root@docker01 ~]# docker container commit bold_feynman centos_nginx:v1
3:测试镜像的功能(如果不加nginx -g ‘'daemon off;'’参数的话nginx是起不来的)
[root@docker01 ~]# docker run -d -p 82:80 centos_nginx:v1 nginx -g 'daemon off;'
4.运行docker imsges查看制作的docker资料包
[root@docker01 ~]# docker images
2.使用dockerfile自动制作镜像
手动镜像: 就像抓好的中药打成包给你
自动制作镜像:就像是我把药方给你,你自己按照药方来制作镜像
两种方法最终都可以得到一个一模一样的镜像
手动制作镜像与自动制作镜像的区别:
dockerfile: 就相当于那个配方
1.dockerfile常用指令
FROM 基础镜像
RUN 制作镜像过程中需要的执行命令(安装服务不能出现夯住的命令就是交互式命令)
CMD 容器启动的时候执行的初始命令,容易被替换(启动服务)
ENTRYPOINT 容器启动的时候执行的初始命令,不能被替换,如果同时使用CMD和ENTRYPOINT,cmd命令将作为ENTRYPOINT命令的参数
CMD指令在启动容器时指定了初始命令,那CMD会被替换
ENTRYPOINT指令在启动容器时不会替换,反而会将其转换为参数。
例如在启动容器时指定了echo 123 那么初始命令是"/bin/bash /init.sh echo 123",如果脚本里有调用变量的会很方便
ADD 把dockerfile当前目录下的文件拷贝到容器中(自动解压tar包)
COPY 把dockerfile当前目录下的文件拷贝到容器中(不解压tar包)
WORKDIR 指定容器的默认工作目录
EXPOSE 镜像要暴露的端口#-P参数随机端口是宿主机随机端口映射暴露的容器端口
VOLUME 随机的持久化卷,跟上你要持久化的目录,多个目录空格分开
ENV 环境变量(ssh的密码,数据库的密码)ENV SSH_Pass 123
LABEL 镜像的属性标签
MAINTAINER 管理者标识
例子:
FROM centos
RUN yum -y install php && yum -y install nginx && rm -f /usr/share/nginx/html/index.html
ADD ssh_host_ecdsa_key /etc/ssh/ssh_host_ecdsa_key
ADD ssh_host_ecdsa_key.pub /etc/ssh/ssh_host_ecdsa_key.pub
RUN chmod 600 /etc/ssh/ssh_host_ecdsa_key && chmod 600 /etc/ssh/ssh_host_ecdsa_key.pub
RUN yum install openssh-server -y && yum install initscripts -y && /usr/sbin/sshd && yum -y install passwd && echo '123456'|passwd --stdin root
ADD init.sh /init.sh
EXPOSE 80 22
ADD xiaoniao.tar.gz /usr/share/nginx/html
#CMD ["nginx","-g","daemon off;"]
VOLUME /etc /root
ENV Ssh_pass 123
CMD ["/bin/bash","/init.sh"]
根据dockerfile自动构建镜像的思路
a: 手动制作docker镜像,记录历史命令
b: 根据历史命令编写dockerfile文件
c: docker build构建docker镜像
d: 测试镜像的功能
2.dockerfile单服务例子
1.创建对应目录,编写dockerfile
[root@docker01 ~]# mkdir dockerfile
[root@docker01 ~]# cd dockerfile
[root@docker01 ~/dockerfile]# mkdir centos7_nginx/
[root@docker01 ~/dockerfile]# mkdir centos7_nginx/
[root@docker01 ~/dockerfile]# cd centos7_nginx/
[root@docker01 ~/dockerfile/centos7_nginx]# vi dockerfile
[root@docker01 ~/dockerfile/centos7_nginx]# cat dockerfile
FROM centos:7
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
RUN curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
RUN yum install nginx -y
RUN rm -rf /usr/share/nginx/html/index.html
RUN echo '孙富阳' >/usr/share/nginx/html/index.html
##CMD nginx -g 'daemon off' ###官方推荐下面这种写法
CMD ["nginx","-g","daemon off;"]
2.开始自动构建镜像
-t指定标签,镜像的名字#build后可以跟dockerfile绝对路径的目录
[root@docker01 ~/dockerfile/centos7_nginx]# docker build -t centos7_nginx_ssh:v3 .
3.启动容器,测试容器
[root@docker01 ~]# docker run -d -p 80:80 centos7_nginx_ssh:v3
[root@docker01 ~]# curl 10.0.0.11
孙富阳
4.自动构建镜像小提示:
自动构建镜像过程中如果ctrl+c了,就会产生一些临时镜像
删除临时镜像的命令
[root@docker01 ~]# docker image prune

3.dockerfile 基础系统镜像制作
1.下载清华源的tar包
[root@docker01 /centos]# wget https://mirrors.tuna.tsinghua.edu.cn/lxc-images/images/alpine/3.14/amd64/default/20210727_13%3A00/rootfs.tar.xz
2.解压
[root@docker01 ~/centos]# tar xf rootfs.tar.xz
[root@docker01 /centos]# ls
bin dev etc home lib media mnt opt proc root run sbin srv sys tar.gz tmp usr var
###实际上就是把系统所有文件下载下来了
3.删除源包,在打包移动到dockerfile目录下的oldzhanglinux目录下
[root@docker01 ~/centos]# rm -rf rootfs.tar.xz
[root@docker01 /centos]# tar czf /tmp/centos_sfy.tar.gz *
[root@docker01 /centos]# mkdir /docker/centos_sfy
[root@docker01 /centos]# cd /docker/centos_sfy/
[root@docker01 /docker/centos_sfy]# mv /tmp/centos_sfy.tar.gz .
[root@docker01 /docker/centos_sfy]# cat dockerfile
FROM scratch
ADD centos_sfy.tar.gz /
CMD ["/bin/sh"]
4.创建镜像
[root@docker01 /docker/centos_sfy]# docker build . -t sfy_centos:v1.
[root@docker01 /docker/centos_sfy]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
sfy_centos v1 54a9458b9add 44 seconds ago 7.85MB
5.启动镜像
[root@docker01 /docker/centos_sfy]# docker container run -d -it sfy_centos:v1
6.如何查看镜像的构建历史?
#比如,查看nginx镜像的
[root@docker01 ~]# docker image history nginx:latest
LABEL只是打个标签,没啥实际用处

3.docker镜像的分层
验证:
1.先导出两个镜像
[root@docker01 ~]# docker save centos:7 -o docker_centos7.tar.gz
[root@docker01 ~]# docker save centos_nginx:v1 -o docker_centos7_nginx.tar.gz
2.删除12机器上的镜像
[root@docker02 ~]# docker images
[root@docker02 ~]# systemctl stop docker.socket
[root@docker02 ~]# systemctl stop docker
3.删除docker数据目录下的文件全部清空(相当于物理删除数据库)
[root@docker02 ~]# rm -rf /var/lib/docker/*
4.重启docker,删除的这些数据目录还会在
[root@docker02 ~]# systemctl restart docker
#确认没有镜像文件了
[root@docker02 ~]# docker images
5.把11机器上的镜像发送给12机器
[root@docker01 ~]# scp -rp docker_centos7* root@10.0.0.12:/root
6.回到12机器上把镜像导入
[root@docker02 ~]# docker load -i docker_centos7.tar.gz (一层镜像)
[root@docker02 ~]# docker load -i docker_centos7_nginx.tar.gz (两层镜像)
属于同一层的文件不需要重复导入,只需要导入一个没有的就可以了,看似两个文件加起来是600多MB,其实在docker上只占用400多MB,这就说明文件被复用了,只占400多MB的磁盘空间。下图:#可以看一下docker的目录/var/lib/docker大小
7.删除镜像。接下来咱们换个顺序来导入镜像,看看效果
[root@docker02 ~]# docker rmi centos:7 centos_nginx:v1
[root@docker02 ~]# docker load -i docker_centos7_nginx.tar.gz
[root@docker02 ~]# docker load -i docker_centos7.tar.gz

这就是镜像分层,因为第一个导入的镜像已经包含了centos7的镜像,所以在单独导入centos7镜像的时候就不会再导入了
8.但如果是dockerfile构建的镜像,就不止一层
因为dockerfile的RUN指令的原理是在执行RUN指令时会创建临时的容器
9.接下来试验一下dockerfile的镜像
[root@docker01 ~]# docker save centos7_nginx_ssh:v3 -o docker_centos7_nginx_v2.tar.gz
[root@docker01 ~]# scp -rp docker_centos7_nginx_v2.tar.gz root@10.0.0.12:/root
10.删除12机器上的镜像,并导入新的镜像
[root@docker02 ~]# docker rmi centos:7 centos_nginx:v1
[root@docker02 ~]# docker load -i docker_centos7_nginx_v2.tar.gz
如下图一共六层

11.总结:
分层的好处是能提高我们的上传下载的速度,我们每次启动的容器都是在镜像的基础上挂一个可写层,所得安装,所有的操作都是在这个可写层执行的。一旦把这个可写层提交为镜像,那么这个镜像又会多一层。(只要commit提交,就会变成只读层,就会有一个新的镜像。新的镜像在原来的基础上又多了一层)
然后我们可以继续docker run、又会有一个可写层。docker镜像最多可以叠加到127层!所以我们使用的时候要适当分层,虽说我们用不到127层
4.dockerfile的优化
优化原则:构建的镜像尽可能小,构建速度尽可能快
a: 使用体积小的linux镜像alpine作为基础镜像
b:尽可能的清理无用的缓存文件,(尽可能把多个RUN合并)
c:修改dockerfile的时候,尽可能把修改的内容放在最后
d:使用.dockerignore忽略构建docker镜像时,不需要的文件
a: 使用体积小的linux镜像alpine作为基础镜像
alpine+nginx=20M (使用alpine系统,什么软件都会小,缺点是兼容性差)
ubuntu+nginx=70M
centos+nginx=400M
使用alpine系统,需要配置yum源,使用的是apk命令
##首先替换为清华源
/ # sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories
##更新软件仓库
/ # apk update
##安装nginx
/ # apk add nginx
##查看nginx版本
/ # nginx -v
##创建nginx父及目录,不然nginx启动不了。(小系统的bug……)
/ # mkdir /run/nginx
##启动nginx服务
nginx
##接下来退出容器,将它提交未镜像
[root@docker01 ~]# docker commit magical_greider alpine_nginx:v1
[root@docker01 ~]# docker images alpine_nginx:v1
查看发现镜像大小才9M多一点,十分节省空间
b:尽可能的清理无用的缓存文件,(尽可能把多个RUN合并)以centos为例
##进入目录
[root@docker01 ~]# cd /opt/dockerfile/cenos7_nginx
##编辑dockerfile
[root@docker01 /opt/dockerfile/cenos7_nginx]# cat dockerfile
FROM centos:7
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo && \
curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo && \
yum install nginx -y && \
rm -rf /var/cache/yum/* &&\
rm -rf /usr/share/nginx/html/index.html && \
echo 'oldzhang' >/usr/share/nginx/html/index.html
#CMD nginx -g 'daemon off;'
CMD ["nginx ","-g","daemon off;"]
##制作镜像
[root@docker01 /opt/dockerfile/cenos7_nginx]# docker build --network=host -t centos7_nginx:v1

如上图这就是清理缓存的作用
c:修改dockerfile的时候,尽可能把修改的内容放在最后
如果在前几行加了内容,在docker build的时候就不会走缓存了,又会重新下载。
原因是docker分层的原理,他会在基础镜像的基础上重新分层
d:使用.dockerignore忽略构建docker镜像时,不需要的文件
[root@docker01 /opt/dockerfile/cenos7_nginx]# vim .dockerignore
[root@docker01 /opt/dockerfile/cenos7_nginx]# cat .dockerignore
docker_centos7.tar.gz
##因为docker是cs架构,每次构建镜像时都会向服务端提交当前路径的所有文件,占用内存空间,所以需要忽略这些文件,来节省内存,提高构建速度
未经允许不得转载:孙某某的运维之路 » 3.制作docker镜像
评论已关闭