$ cat /proc/filesystems | grep overlay nodev overlay
②、创建分层的工作目录(相当于除了容器层以外的其他层);
$ mkdir base $ echo "layer 1" > base/metadata $ echo "hello,docker!" > base/data $ mkdir overlay $ echo "layer 2" > overlay/metadata $ echo "hello,k8s!" > overlay/data2
③、创建顶层目录(相当于容器层),以及OverlayFS所必需的work工作目录、文件系统挂点;
$ mkdir top work point
④、将分层以overlay文件系统类型挂载到挂载点;
$ mount -t overlay overlay -o lowerdir=overlay:base,upperdir=top,workdir=work point #-t:指定文件系统类型 #-o:指定挂载选项,lowerdir指定底层目录(从高层向低层指定),upperdir指定顶层目录 (也就是容器层),workdir指定工作目录 #最后指定挂载点
⑤、在挂载点目录下可以看到联合目录,目录所处的层级是很重要的,上层的文件会覆盖同名的下层文件;
#可以看到挂载点处显示出的联合目录 $ ll */* -rw-r--r-- 1 root root 14 ... base/data -rw-r--r-- 1 root root 10 ... base/metadata -rw-r--r-- 1 root root 11 ... overlay/data2 -rw-r--r-- 1 root root 10 ... overlay/metadata -rw-r--r-- 1 root root 14 ... point/data -rw-r--r-- 1 root root 11 ... point/data2 -rw-r--r-- 1 root root 10 ... point/metadata #查看具有同名的上下层文件metadata $ cat point/metadata layer 2 #内容为overlay层的metadata文件内容,而base层的metadata文件内容被覆盖
⑥、当容器启动时,一个新的可写层被加载到镜像的顶部,这一层通常被称作“容器层","容器层”之下的都叫“镜像层”,只有容器层是可写的,容器层下面的所有镜像层都是只读的;修改文件时同理,当在容器中修改已存在的文件时,Docker会从上往下依次在各镜像层中查找此文件,一旦找到,立即将其复制到容器层(top层),然后再修改;
此处仅做目录模拟,所以其他镜像层仍是可以写的。
#当向point目录中写入数据时,会写入到top目录(顶层目录)中 $ echo "top layer" > point/frame $ ll */* ... -rw-r--r-- 1 root root 10 ... point/frame -rw-r--r-- 1 root root 10 ... top/frame $ cat top/frame #查看容器层写入的文件内容,即为写入到挂载点同名文件中的内容 top layer #修改point/data文件内容 $ cat point/data hello,docker! test modify #然后会在top顶层目录中新增一个同名文件,内容即为修改后的内容 $ ll */* ... -rw-r--r-- 1 root root 10 ... top/data $ cat top/data hello,docker! test modify #查看底层base/data文件,发现内容并未改变 $ cat base/data hello,docker!
⑦、当在容器中删除文件时, Docker 也是从上往下依次在镜像层中查找此文件。找到后,UnionFS会在容器层创建一个"whiteout"文件将被删除的文件进行遮挡,并且在容器层会创建一个同名的、主次设备号均为0的字符设备,文件不会被删除(空间不一定会被回收);如果制作 image 时使用到了一些关键的信息(用户名、密码等),则需要在所在层删除,不然这些信息依然会存在于 image 中。
c--------- 1 root root 0, 0 ... top/data
$ wget -O /etc/yum.repos.d/docker-ce.repo https://img.hflfx.com/pic/wgjhkkt0yaw $ sudo sed -i 's download.docker.com repo.huaweicloud.com/docker-ce ' /etc/yum.repos.d/docker-ce.repo #修改获取镜像的地址 #如果是Centos8版本的系统,则可以参照之前的《00:先让Docker跑起来》文章。
❷、配置Docker镜像加速器:如果使用公共镜像仓库,由于是在国外网速限制,须要通过镜像加速站来获取镜像,以下以华为云平台镜像加速站配置为例(需提前注册华为云账号,并在控制台中找到容器镜像服务)
当镜像仓库使用"https",使用时则需要先进行登录验证,然后才能从镜像仓库拉取镜像;当镜像仓库使用"http"(或私有镜像仓库,直接使用IP地址),则不需要,可以直接拉取使用。
$ vim /etc/docker/daemon.json #如果该文件没有,则需要手动创建 { "registry-mirrors": ["https://******.myhuaweicloud.com"] } $ systemctl daemon-reload #重新加载daemon服务器配置文件 $ systemctl restart docker.service
❸、首先须要登录获取访问权限,u是用户,p是密码(在个人控制台自动生成)
$ docker login -u *** -p *** swr.cn-north-1.myhuaweicloud.com
❹、拉取镜像
$ docker pull httpd:2.4 2.4: Pulling from library/httpd ...Pull complete Status: Downloaded newer image for httpd:2.4 $ docker image list REPOSITORY TAG IMAGE ID CREATED SIZE httpd 2.4 683a7aad17d3 2 months ago 138MB
$ docker load -i dockviz.tar
2、然后在 /etc/bashrc文件中最后一行添加命令别名,保证每次执行dockviz命令时都会临时运行一个dockerviz的容器来执行相应的动作;(退出重新登录后生效)
$ alias dockviz="docker run --rm -v /var/run/docker.sock:/var/run/docker.sock dockviz:latest"
3、执行以下命令,让镜像文件以分层的形式保存在images.png图片中
#将所有的镜像信息以png的格式保存到images.png文件中 $ dockviz images -d | dot -Tpng -o images.png #最后可以下载到Windows本地查看图片
2. 构建镜像 Docker提供了两种构建镜像的方法:docker commit命令与Dockerfile构建文件
$ docker run -it centos:7 # -it表示以交互的方式运行容器,并进入到容器 Unable to find image 'centos:7' locally #由于已登录到华为云,将从huaweicloud.com拉取镜像 ...: Pull complete
❷、在base镜像中安装软件,并退出;
$ vim bash: vim: command not found #base镜像中没有安装vim工具 $ yum install vim -y #使用yum安装vim工具 ... Complete! $ rpm -qa | grep vim #检查已正常安装vim工具 vim-common... $ exit
❸、使用commit命令将修改后的centos7容器封装成一个名为my_iamge的镜像。
$ docker ps -a CONTAINER ID IMAGE ... NAMES ff9a563e9fd8 centos:7 ... vibrant_sammet $ docker commit vibrant_sammet my_image #直接将容器commit成名为my_image的镜像 $ docker image list REPOSITORY TAG IMAGE ID CREATED SIZE my_image latest cfdce8636c33 39 seconds ago 366MB centos 7 8652b9f0cb4c 4 months ago 204MB
❹、验证:可以看到my_image镜像比centos:7镜像多了一层镜像
# docker history指令会显示镜像的分层结构,并且按照镜像层的顺序由上至下排列 $ docker history centos:7 IMAGE CREATED BY SIZE 8652b9f0cb4c /bin/sh -c #(nop) CMD ["/bin/bash"] 0B <missing> /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B <missing> /bin/sh -c #(nop) ADD file:b3ebbe8bd304723d4… 204MB $ docker history my_image:latest IMAGE CREATED BY SIZE cfdce8636c33 /bin/bash 162MB #安装了vim编辑器8652b9f0cb4c /bin/sh -c #(nop) CMD ["/bin/bash"] 0B <missing> /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B <missing> /bin/sh -c #(nop) ADD file:b3ebbe8bd304723d4… 204MB
RUN/CMD/ENTRYPOINT <command>ENV name Cloud #指定环境变量name的值为 Cloud ENTRYPOINT echo "Hello, $name" #启动容器后输出即为 Hello,Cloud
Exec:直接调用 [command],但是不会被底层的shell解析,其格式为
RUN/CMD/ENTRYPOINT ["executable", "paraml", "param2", ...]ENV name Cloud #指定环境变量name的值为 Cloud ENTRYPOINT ["/bin/echo","Hello,$name"] #启动容器后输出即为 Hello,$name
❶ RUN:指令通常用于给容器安装应用和软件包;Dockerfile中常常包含多个RUN指令,在当前镜像的顶部执行命令,完成一条RUN指令之后就会创建新的镜像层,也就是说不同的RUN指令代表了不同的镜像层。
❷ CMD:指令允许用户指定容器的默认执行的命令,因为容器是为应用而生的,启动容器最终目的是启动应用(或者是执行一个循环语句)以避免容器启动后无应用而退出(状态为exited),在容器启动且docker run没有指定其他命令时运行
注:如果docker run指定了其他命令,CMD指定的默认命令将被忽略;如果Dockerfile中有多个CMD指令,只有最后一个CMD有效。
❸ ENTRYPOINT:指令可让容器以应用程序或者服务的形式运行,和CMD不同的地方在于ENTRYPOINT 不会被忽略,一定会被执行,即使运行 docker run 时指定了其他命令。
④、实现步骤:使用Dockerfile构建镜像
❶、构建前需要准备build context目录、准备好base镜像
$ pwd #新建一个dockerfile目录作为build context /root/dockerfile $ ls #目录下保存base镜像,dockerfile文件以及需要的file2 CentOS-7-x86_64-docker.img.tar.xz dockerfile file2
❷、写一个dockerfile文件
注:可以从一个空镜像开始,也可以从base镜像开始,如果从空镜像开始,必须指定进入到容器之后的shell,如Centos系统是bash shell
$ vim dockerfile FROM scratch #指定从一个空镜像开始 MAINTAINER KnockCloud #指定镜像作者 ADD CentOS-7-x86_64-docker.img.tar.xz / #添加一个Centos系统的base镜像 CMD ["/bin/bash"] #必须指定进入到容器之后使用的shell WORKDIR /testdir #用于指定进入到容器之后的目录(如果没有会创建) RUN touch file1 COPY file2 . #将file2拷贝到容器的 /testdir 目录下,注意file2文件必须提前在docker context中存在 ENV WELCOME "You are in my container,welcome!"
❸、使用dockerfile创建一个名为first-dockerfile的镜像
#这里的"."表示dockerfile所在的目录,在本实验中是当前目录 $ docker build -t first-dockerfile . #docker会将build context中的文件发送给docker daemon Sending build context to Docker daemon 36.29MB Step 1/8 : FROM scratch #从一个空镜像开始 ---> Step 2/8 : MAINTAINER Docker ---> Running in b9617c3257db Removing intermediate container b9617c3257db ---> db4a3a49178d #添加一个Centos系统的base镜像到容器的根目录下 Step 3/8 : ADD CentOS-7-x86_64-docker.img.tar.xz / ---> 5ed7df8f5c30 #指定进入到容器之后使用bash shell(必须指定) Step 4/8 : CMD ["/bin/bash"] ---> Running in d5bc15e94c2c Removing intermediate container d5bc15e94c2c ---> 7695f1da0b99 Step 5/8 : WORKDIR /testdir #指定进入容器之后的工作目录 ---> Running in 02bf878461a7 Removing intermediate container 02bf878461a7 ---> 8bee16518a33 Step 6/8 : RUN touch file1 ---> Running in 12b2f04b31ed Removing intermediate container 12b2f04b31ed ---> abdb9cbd61c7 Step 7/8 : COPY file2 . #这里的"."表示上面指定的工作目录 ---> 2d32516ab12f Step 8/8 : ENV WELCOME "You are in my container,welcome!" ---> Running in 6e6857f7ad1b Removing intermediate container 6e6857f7ad1b ---> 29e652e510d5 Successfully built 29e652e510d5 Successfully tagged first-dockerfile:latest
❹、验证结果
$ docker run -it first-dockerfile bash-4.2# pwd #查看进入容器之后的工作目录 /testdir bash-4.2# ls #查看工作目录下的文件 file1 file2 bash-4.2# cat file2 #从docker context拷贝过来的file2文件 It's worked! bash-4.2# echo $WELCOME #设置的变量值 You are in my container,welcome!
3.镜像仓库$ docker run -d -p 5000:5000 #指定端口映射,将主机端口映射给容器(网络章节会详解) -v /myregistry:/var/lib/registry #指定存储位置映射(存储章节会详解) registry:2.7 ...Pull complete .
②、修改daemon.json文件中的镜像仓库地址,如果地址是私有仓库的地址,应按照registry-host:[port]的格式修改地址
#设置以非安全模式(即非HTTPS)连接到本仓库$ cat /etc/docker/daemon.json { "insecure-registries": ["192.168.1.11:5000"] #本机地址:映射端口号 }
③、通过 docker tag 重命名镜像,使之与registry相匹配
#username可以任意但不能包含大写字母 $ docker tag httpd:2.4 192.168.1.11:5000/docker/httpd:2.4
④、通过 docker push 上传镜像
$ docker push 192.168.1.11:5000/docker/httpd:2.4 The push refers to repository [192.168.1.11:5000/docker/httpd] ... Pushed $ pwd /myregistry/docker/registry/v2/repositories $ ls #镜像文件保存在本地指定的用户文件夹里 docker
⑤、验证,尝试从私有镜像仓库拉取镜像
注:拉取镜像时必须指定镜像仓库和用户名,不然就会到docker官方网站上去拉取了
#到私有镜像仓库拉取镜像时要补全镜像的tag $ docker pull 192.168.1.11:5000/docker/httpd:2.4 2.4: Pulling from docker/httpd Digest: sha256:88fb0fb4b406f944e220f082b5a56d1f0e8471abc45fd... Status: Downloaded newer image for 192.168.1.11:5000/docker/httpd:2.4 192.168.1.11:5000/docker/httpd:2.4 $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE 192.168.1.11:5000/docker/httpd 2.4 683a7aad17d3 2 months ago 138MB
docker save <IMAGE_NAME> -o <TAR_NAME>
docker load:将镜像tar包加载为镜像,格式为:
docker load -i <TAR_NAME>
花粉社群VIP加油站
猜你喜欢