Kubernetes认证考试自学系列 | 自定义镜像

83 阅读6分钟

书籍来源:《CKA/CKAD应试指南:从Docker到Kubernetes完全攻略》

一边学习一边整理读书笔记,并与大家分享,侵权即删,谢谢支持!

附上汇总贴:Kubernetes认证考试自学系列 | 汇总_COCOgsta的博客-CSDN博客


要自定义镜像的话就需要写Dockerfile文件了,如果文件名不是Dockerfile的话,那么编译镜像的时候需要使用-f来指定文件名,如图2-1所示。

构建镜像的本质就是,先利用基镜像生成一个临时容器,然后在这个临时容器里执行Dockerfile里指定的命令, 等做完所有的操作之后, 会把这个临时容器导出为一个新的镜像。

关键就是如何写Dockerfile。

练习1:创建可以执行 ifconfig centos 镜像

Dockerfile内容如下。

[root@vms100 ~]# cat Dockerfile
FROM hub.c.163.com/library/centos 
MAINTAINER duan
RUN yum install net-tools -y 

CMD ["/bin/bash"]
[root@vms100 ~]#

这个文件里指明了基于hub.c.163.com/library/centos这个镜像自定义新的镜像,在新的镜像里安装net-tools工具包。

docker build -t 新镜像名:tag . -f file

开始构建。

[root@vms100 ~]# docker build -t centos:v1 .
Sending build context to Docker daemon 230.1MB 
...输出...
Step 4/4: CMD /bin/bash
 ---> Running in 8e0fb6170a3b
 ---> b3c554b578c4
Removing intermediate container 8e0fb6170a3b 
Successfully built b3c554b578c4
[root@vms100 ~]# 

构建完成,查看现有镜像。

[root@vms100 ~]# docker images
REPOSITORY      TAG    IMAGEID         CREATED        SIZE
centos          v1     b3c554b578c4    22 seconds ago 301MB
docker.io/nginx latest 5a3221f0137b    2 weeks ago    126MB 
...
[root@vms100 ~]#

使用该镜像创建出一个容器, 验证是否可以使用ifconfig命令。

[root@vms100 ~]# docker run --rm -it centos:v1
[root@cea78ca52d6f /]# ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
         inet 172.17.0.4  netmask 255.255.0.0  broadcast 0.0.0.0
         inet6 fe80::42:acff:fe11:4  prefixlen 64  scopeid 0x20<link>
         ether 02:42:ac:11:00:04  txqueuelen 0  (Ethernet)
         RX packets 5  bytes 418 (418.0 B)
         RX errors 0  dropped 0  overruns 0  frame 0
         TX packets 6  bytes 508 (508.0 B)
         TX errors 0  dropped 0  overruns 0  carrier 0  collisions 0

[root@cea78ca52d6f /]# exit 
exit
[root@vms100 ~]#

可以看到一切是正常的。

练习2:自定义nginx镜像

先做准备工作, 把所需要的repo文件拷贝出来。

[root@vms100 ~]# cd/etc/yum.repos.d/
[root@vms100 yum.repos.d]# tar zcf /root/repo.tar.gz *
[root@vms100 yum.repos.d]# cd
[root@vms100 ~]#  

这里把物理机/etc/yum.repos.d里的repo文件放在压缩文件repo.tar.gz里了。

创建index.html内容如下。

[root@vms100 ~]# cat index.html 
test11
[root@vms100 ~]#

写dockerfile1, 内容如下。

[root@vms100 ~]# cat dockerfile1
FROM hub.c.163.com/library/centos 
MAINTAINER duan
# 清除自带的yum源文件
RUN rm -rf /etc/yum.repos.d/*
# 把打包好的repo文件拷贝到/etc/yum.repos.d里, 作为新的yum 
ADD repo.tar.gz /etc/yum.repos.d/
RUN yum install -y nginx
# 把nginx默认主页文件拷贝进去
ADD index.html /usr/share/nginx/html

EXPOSE 80

CMD ["nginx", "-g", "daemon off; "]
[root@vms100 ~]#

开始构建,指定镜像的名字为nginx:v1。

[root@vms100 ~]# docker build -t nginx:v1 . -f dockerfile1
Sending build context to Docker daemon 1.293 GB 
Step 1/7:FROM hub.c.163.com/library/centos
 --->328edcd84f1b 
...大量输出...
Successfully built cd67044bfa52
Successfully tagged nginx:v1
[root@vms100 ~]#

因为文件名是dockerfile1, 不是Dockerfile, 所以这里需要-f来指定。

使用此镜像运行一个容器,并验证。

[root@vms100 ~]# docker run-d --name=web --restart=always -p 80:80 nginx:v1
654d73edf7dd51242511014605bbea5908d984d4a65fb96190d6210dabe60120
[root@vms100 ~]#

在浏览器里打开192.168.26.100,查看结果,如图2-2所示。

练习3:验证ADD和COPY的区别

ADD和COPY都可以把当前目录里的文件拷贝到临时容器里, 但是ADD和COPY在拷贝压缩文件的时候存在一些区别。ADD把压缩文件拷贝到临时容器里时会自动解压, COPY不带解压功能。

在当前目录随意创建一个压缩文件, 这里有个aa.tar.gz, 内容如下。

[root@vms100 ~]# tar ztf aa.tar.gz 
epel.repo
index.html
[root@vms100 ~]#

创建dockerfile2, 内容如下。

[root@vms100 ~]# cat dockerfile2、
FROM hub.c.163.com/library/centos 
MAINTAINER duan 
# 在临时容器里创建目录/11和/22
RUN mkdir /11 /22
# 利用ADD把aa.tar.gz拷贝到/11里, 利用COPY把aa.tar.gz拷贝到/22里
ADD aa.tar.gz /11
COPY aa.tar.gz /22

CMD ["/bin/bash"]
[root@vms100 ~]# 

aa.tar.gz以ADD的方式拷贝到镜像的/11目录。

aa.tar.gz以COPY的方式拷贝到镜像的/22目录。

编译镜像,镜像名为centos:add-copy。

[root@vms100 ~]# docker build -t centos:add-copy . -f dockerfile2
Sending build context to Docker daemon 1.293 GB 
Step 1/6 : FROM hub.c.163.com/library/centos 
...
Removing intermediate container 7d00f53629f3 
Successfully built d21b6fa6234a
[root@vms100 ~]#

使用该镜像创建出容器验证结果。

[root@vms100 ~]# docker run --rm -it centos:add-copy ep 
[root@7bdd096a6221 /]# ls /11
el.repo  index.html 
[root@7bdd096a6221 /]# ls /22/
aa.tar.gz
[root@7bdd096a6221 /]# exit
exit
[root@vms100 ~]#

可以看到, 以ADD方式拷贝过去的压缩文件进行了解压操作, 而以COPY方式拷贝过去的并没有解压。

练习4:USER命令的使用

前面做的镜像里, 都是以root来运行进程, 如果要以指定的用户来运行进程, 可以使用USER命令, 创建dockerfile3, 内容如下。

[root@vms100 ~]# cat dockerfile3
FROM hub.c.163.com/library/centos 
MAINTAINER duan 
RUN useradd lduan 
USER lduan
CMD ["/bin/bash"]
[root@vms100 ~]#

这里首先创建出lduan用户, 然后用USER指定后面容器里要以lduan来运行进程。

编译镜像,镜像为centos:user。

[root@vms100 ~]# docker build -t centos:user . -f dockerfile3
Removing intermediate container 97e2d65cb77f 
Successfully built 518cea386492
[root@vms100 ~]#

使用该镜像创建容器。

[root@vms100 ~]# docker run --restart=always --name=c1 -it centos:user
[lduan@a7f0227edfb7 /]$ 
[lduan@a7f0227edfb7 /]$ whoami 
lduan 
[lduan@a7f0227edfb7 /]$ exit 
exit 
[root@vms100 ~]#

可以看到容器里的进程是以lduan的身份来运行的。如果要以root身份进入容器里的话,加上--user-root选项即可。

[root@vms100 ~]# docker exec -it --user=root c1 bash
[root@a7f0227edfb7 /]# 
[root@a7f0227edfb7 /]# whoami
root
[root@a7f0227edfb7 /]# exit
exit
[root@vms100 ~]#

练习5:用ENV来指定变量

创建dockerfile4。

[root@vms100 ~]# cat dockerfile4
FROM hub.c.163.com/library/centos 
MAINTAINER duan 
ENV myenv=/aa 
CMD ["/bin/bash"]
[root@vms100 ~]#

构建镜像名字为centos:env。

[root@vms100 ~]# docker build -t centos:env . -f dockerfile4

使用该镜像创建出来一个容器。

[root@vms100 ~]# docker run --rm -it centos:env 
[root@457c99cfd44b /]# echo $myenv
/aa
[root@457c99cfd44b /]# exit 
exit
[root@vms100 ~]#

可以看到容器里存在一个变量myenv=aa。

在创建容器的时候是可以使用-e来指定变量的值的。

[root@vms100 ~]# docker run --rm -it -e myenv=xxx centos:env 
[root01084136a59d2 /]# echo $myenv 
xxx
[root@1084136a59d2 /]# exit 
exit
[root@vms100 ~]#

练习6:数据卷

创建dockerfile5。

[root@vms100 ~]# cat dockerfile5
FROM hub.c.163.com/library/centos 
MAINTAINER duan 
VOLUME ["/data1"]

CMD ["/bin/bash"]
[root@vms100 ~]#

此新镜像创建出来的容器里, 会创建一个目录/data1绑定物理机的随机目录。

构建镜像,名字为centos:volume。

[root@vms100 ~]# docker build -t centos:volume . -f dockerfile5

使用此镜像创建一个容器出来。

[root@vms100 ~]# docker run --rm -it centos:volume 
[root@ff3ee713ea74 /]# ls/data1/
[root@ff3ee713ea74 /]#

在其他终端查看此容器的属性。

[root@vms100 ~]# docker inspect ff3ee713ea74 | grep -A5 Mounts
        ...
                 "Source": "/var/lib/docker/volumes/44a9c964f8192431aa18c5861e5ac80364133639a5615c29d1201fee3ac3e70a/_data",
                 "Destination": "/data1",
[root@vms100 ~]#

注意:如果想有多个挂载点的话, 应该写成VOLUME["/data1","/data"] 。

作业:创建可以ssh的 centos

dockerfile内容如下。

FROM centos:v1
MAINTAINER duan
RUN rm -rf /etc/yum.repos.d/*
ADD epel.repo /etc/yum.repos.d/
ADD CentOS-Base.repo /etc/yum.repos.d/
RUN yum install openssh-clients openssh-server -y 
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key && ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key && ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key
RUN sed -i '/UseDNS/cUseDNS no' /etc/ssh/sshd_config 

RUN echo "root:redhat" | chpasswd
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]

更好的写法:

FROM centos:v1
MAINTAINER duan
RUN rm -rf /etc/yum.repos.d/*
ADD repo.tar.gz /etc/yum.repos.d/
RUN yum install openssh-clients openssh-server -y && \
    ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key && \
    ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key && \
    ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key && \
    sed -i '/UseDNS/cUseDNS no' /etc/ssh/sshd_config && \
    echo "root:redhat" | chpasswd
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]