docker 常见操作(下)

2020-12-13  本文已影响0人  djz0306

太久了,甚至一度以为自己已经上传了另一部分内容,哈哈哈。今天更新下。发现直接从 Typora 复制过来我的代码部分和图片都没了,一条条粘贴上去了,如果有错误,先说声抱歉,欢迎评论告诉我,谢谢

docker 镜像

镜像是可以执行的独立轻量软件包,可以用于打包软件运行环境和对应开发的软件,包括了代码,库,环境变量等等。

docker 镜像的基础是 Union 文件系统,支持对文件系统的下去该作为一次提交来叠加,将不同目录挂载到同一个虚拟文件系统下,所以外部看上去只能看到一个文件系统,实际上一次同事加载了多个文件系统。

这样的号出就是共享,例如有多个镜像从相同的 base 镜像构建而来,那么宿主机只需要在存一份 base 镜像即可。镜像的每一层都可以被共用。

容器启动的时候新的可写层被加载到镜像的顶部,被称作容器层,下面的层被称作镜像层,docker 的镜像都是只读的。

打包镜像

  1. 运行从 docker hub 上下载的镜像:
docker run -it -p 8080:8080 tomcat
  1. 访问最新版 tomcat 首页可以看到会提示 404:
image-20200304134442907.png

因为文件都处于 webapps.dist 中而不是默认的 webapps 中。

  1. 使用 docker exec -it 636c0b8b498a /bin/bash重新进入到 tomcat 对应的容器中,使用cp -r webapps.dist/* webapps复制 webapps.dist 中的文件到 webapps 中

  2. 刷新浏览器就能看到正常的 tomcat 首页了

    image-20200304135623974.png
  1. 以修改过的容器为模板生成一个新的镜像,并命名为 iot/tomcat
docker commit -a="iot" -m="move webapps.dist to webapps" 636c0b8b498a iot/tomcat:8.5.51
  1. 查看现有镜像可以看到一个为 iot/tomcat 的镜像,然后运行他:
docker run -it -p 8081:8080 iot/tomcat:8.5.51

访问 8081 端口,正常访问

docker 数据卷

docker 容器中产生的数据如果不通过 commit 生成新的镜像,使得数据成为镜像的一部分,那么当容器删除以后数据就消失了。为了保存数据,可以使用数据卷的方式。数据卷使得 docker 做到荣期间继承和共享数据。

命令添加方式

运行容器时添加 -v 参数可以指定数据卷:

docker run -it -v /宿主机绝对路径:/容器内目录 镜像名

运行后会自动创建目录,也可以选择已有目录进行挂载。挂载后可以通过docker inspect 容器ID 的方式进行查看,如下:

image-20200304163622516.png

通过 dockerfile 添加

在dockerfile 中添加目录

/mydocker中新建文件 Dockerfile 文件

在 dockerfile 中添加

VOLUME ["/dataContainer","/dataContainer2","/dataContainer3"]

表示容器内的 "/dataContainer","/dataContainer2","/dataContainer3" 与宿主机绑定。最简单的 dockerfile 可以是:

# volume test

FROM centos

VOLUME ["/dataContainer","/dataContainer2","/dataContainer3"]

CMD echo "Hello world!!!"

CMD /bin/bash

由于考虑到 dockerfile 的移植性考虑,不能使用类似-v /宿主机绝对路径:容器路径的方式在 dockerfile 中实现

build 生成镜像

通过

docker build -f /mydocker/Dockerfile -t iot/centos .

生成新的镜像,注意最后有个点。然后运行他:

docker run -it iot/centos /bin/bash

值得注意的是:在 Dockerfile 中使用 VOLUME 指令之后的代码,如果尝试对这个数据卷进行修改,这些修改都不会生效!

权限

容器向挂载的目录写入文件或者增加目录以后,主机上可能会遇到没有访问权限的问题,因为 docker 内部默认使用的是 root 用户。例如使用如下命令创建一个容器,同时挂载当前目录到容器内,并再容器内创建文件 tmp.txt

docker run -rm -v "$PWD":/project centos bash -c "touch /project/tmp.txt"

查看 tmp.txt 的文件信息:

image-20200305100505569.png

权限、用户,组都是 root,其他用户只能 read,切换其他用户尝试向里面写入东西:

image-20200305100947924.png

命令添加 user 参数方式

docker 提供了 --user 参数,可以指定用户名或者 UID,修改命令如下:

docker run --rm --user=$UID:$(id -g $USER) -v "$PWD":/project centos bash -c "touch /project/tmp.txt"

执行后发现已经可以正常在里面写入东西了:

image-20200305105534948.png

但是使用 user 参数会有两个缺陷:

image-20200305111457611.png

为了解决这个问题可以编写一个 docker-entrypoint.sh 脚本作为 Dockerfile 的 ENTRYPOINT,在脚本中创建一个和宿主机上相同 UID 的用户,并用用 gosu 切换到还用户执行命令,UID 需要在 docker run 阶段通过参数传入

如果是希望容器只能访问宿主机上的目录,则可以在容器内路径后面加上 ro,如下:

docker run -it -v /datahost/:/datacontainer:ro centos

数据卷容器

命名的容器挂载数据卷,其它容器通过挂载这个(父容器)实现数据共享,挂载数据卷的容器,称之为数据卷容器。

  1. iot/centos为模板,分别启动三个容器,container1,container2,container3。container2 、container3 均继承自 container1。如下:
image-20200305144518769.png

这三个容器都拥有容器卷 dataVolumeContainer0dataVolumeContainer1。可以通过docker inspect 看到他们指向宿主机上的同一个目录。

  1. 分别在 container2 与 container3 中新增文件:
image-20200305145202825.png image-20200305145300403.png

可以看到 container3 新增的文件在 container2 中同样能看到。

回到 container1,子容器中添加的内容在父容器中同样可以看到。

image-20200305145513404.png
  1. 在父容器中删除 c2_add.txt 同时在 c3_add.txt 中添加 "c1 hello world"。

    image-20200305151119932.png
  1. 回到 container2 中查看,并且修改 c1_add.txt 与 c3_add.txt:

    image-20200305151414993.png
  1. 回到 container3 中查看:

    image-20200305151531320.png
  2. 现在删除 container1 ,然后查看 container 修改 c1_add.txt ,在 container3 中是否可以访问:

image-20200305151951645.png image-20200305152039580.png

可见即使父容器被删除了,其新建的文件其他子容器仍然能修改,读取。

  1. 新建容器 container4 ,继承自 container3,然后删除 container2 和 container3,查看在 container4 中是否还能查看之前的文件

    image-20200305154418348.png
image-20200305154451715.png

可知:容器之间配置信息可以互相传递,数据卷的生命周期一直持续到没有容器使用它为止。

dockerfile

dockerfile 是用来构建 docker 镜像的文件。

dockerfile 构建流程

  1. docker 从基础镜像运行一个容器

  2. 执行一条指令并对容器做出修改

  3. 执行类似 docker commit 的操作并且提交一个新的镜像层

  4. docker 再鲸鱼刚提交的镜像层运行一个新的的容器

  5. 执行 dockerfile 中下一条指令知道所有指令都执行完成

dockerfile、镜像、容器三者关系.png

dockerfile 关键字

关键字 含义
FROM 基础镜像,表示新镜像是基于那个镜像的
MAINTAINER 镜像维护者的姓名和邮箱地址
RUN 容器构建是需要运行的命令
EXPOSE 当前容器对外暴露的端口
WORKDIR 创建容器后终端登录的默认路径
ENV 用来构建镜像过程中设置环境变量
ADD 将宿主机目录下的文件拷贝进镜像且 ADD 命令会自动处理 URL 与解压 tar 压缩包
COPY 类似 ADD
VOLUME 容器数据卷
CMD 指定容器启动时要运行的命令
ENTRYPOINT 指定容器启动时要运行的命令
ONBUILD 当构建一个被继承的 dockerfile 时运行的命令,父镜像被子继承后父镜像的 ONBUILD 被触发

备注:

ENV TEST /usr/test

WORKDIR $TEST

WORKDIR $TEST</pre>

编写 dockerfile 文件

FROM         centos
MAINTAINER    djz<jinzhuang.dong@unilever-le.com>

# 把宿主机当前上下文的c.txt拷贝到容器/usr/local/路径下
COPY c.txt /usr/local/cincontainer.txt

# 把 test.tar.gz 添加到容器中
ADD test.tar.gz /usr/local/

# 安装vim编辑器
RUN yum -y install vim

# 设置工作访问时候的WORKDIR路径,登录目录
ENV WORKSPACE /usr/local
WORKDIR $WORKSPACE

# 容器运行时监听的端口
EXPOSE  80

CMD echo $MYPATH
CMD echo "success--------------ok"
CMD /bin/bash

保存然后运行:

docker build -f Dockerfile -t iotvim/centos:7.1 .

即可生成镜像,然按照正常镜像运行方式即可运行

 docker run -it iotvim/centos:7.1

会发现默认处在 /usr/local下,且可以使用 vim

上一篇下一篇

猜你喜欢

热点阅读