当前位置: 首页 > news >正文

网站建设制度制定贵州网站建设推荐

网站建设制度制定,贵州网站建设推荐,重庆推广网站排名,网站建设技术网Docker镜像构成和定制 利用 commit 理解镜像构成 docker commit 命令应用场合 docker commit 命令除了学习之外#xff0c;还有一些特殊的应用场合#xff0c;比如被***后保存现场等。但是#xff0c;不要使用 docker commit 定制镜像#xff0c;定制镜像应该使用 Dockerfi…Docker镜像构成和定制 利用 commit 理解镜像构成 docker commit 命令应用场合 docker commit 命令除了学习之外还有一些特殊的应用场合比如被***后保存现场等。但是不要使用 docker commit 定制镜像定制镜像应该使用 Dockerfile 来完成。 慎用 docker commit 使用 docker commit 意味着所有对镜像的操作都是黑箱操作生成的镜像也被称为黑箱镜像换句话说就是除了制作镜像的人知道执行过什么命令、怎么生成的镜像别人根本无从得知。而且即使是这个制作镜像的人过一段时间后也无法记清具体在操作的。虽然 docker diff 或许可以告诉得到一些线索但是远远不到可以确保生成一致镜像的地步。这种黑箱镜像的维护工作是非常痛苦的。 使用 Dockerfile 定制镜像 Dockerfile 是一个文本文件其内包含了一条条的指令(Instruction)每一条指令构建一层因此每一条指令的内容就是描述该层应当如何构建。 Dockerfile 指令介绍 COPY 复制文件 格式 * COPY 源路径... 目标路径 * COPY [源路径1,... 目标路径] 比如 COPY package.json /usr/src/app/ 说明 源路径 可以是多个甚至可以是通配符其通配符规则要满足 Go 的 filepath.Match 规则如 COPY hom* /mydir/ COPY hom?.txt /mydir/ 目标路径 可以是容器内的绝对路径也可以是相对于工作目录的相对路径工作目录可以用 WORKDIR 指令来指定。目标路径不需要事先创建如果目录不存在会在复制文件前先行创建缺失目录。 注意 使用 COPY 指令源文件的各种元数据都会保留。比如读、写、执行权限、文件变更时间等。这个特性对于镜像定制很有用。特别是构建相关文件都在使用 Git 进行管理的时候。 ADD 更高级的复制文件 ADD 指令和 COPY 的格式和性质基本一致。但是在 COPY 基础上增加了一些功能。如果 源路径 为一个 tar 压缩文件的话压缩格式为 gzip, bzip2 以及 xz 的情况下ADD 指令将会自动解压缩这个压缩文件到 目标路径 去。最适合使用 ADD 的场合就是当我们需要自动解压缩的场合。如官方镜像 ubuntu 中 FROM scratch ##空白镜像 ADD ubuntu-xenial-core-cloudimg-amd64-root.tar.gz / ... 由于ADD 则包含了更复杂的功能其行为也不一定很清晰。它不像COPY 的语义很明确就是复制文件而已。所以我们还是尽可能使用COPY吧。 CMD 容器启动命令 CMD 指令就是用于指定默认的容器主进程的启动命令的。 CMD 指令的格式和 RUN 相似也是两种格式 * shell 格式CMD 命令 * exec 格式CMD [可执行文件, 参数1, 参数2...] * 参数列表格式CMD [参数1, 参数2...]。在指定了 ENTRYPOINT 指令后用 CMD 指定具体的参数。 在运行时可以指定新的命令来替代镜像设置中的这个默认命令比如nginx1.7.9 镜像默认的 CMD 是 /bin/bash 如果我们直接使用 docker run -it nginx1.7.9 的话会直接进入 bash 。我们也可以在运行时指定运行别的命令如 docker run -it nginx:1.7.9 cat /etc/os-release。这就是用 cat /etc/os-release 命令替换了默认的 /bin/bash 命令了输出了系统版本信息。在指令格式上一般推荐使用 exec 格式这类格式在解析时会被解析为 JSON 数组因此一定要使用双引号 而不要使用单引号。 shell格式 CMD echo $HOME exec格式 CMD [ sh, -c, echo $HOME ] 这就是为什么我们可以使用环境变量的原因因为这些环境变量会被 shell 进行解析处理。 容器中应用在前台执行和后台执行的问题 Docker 不是虚拟机容器中的应用都应该以前台执行而不是像虚拟机、物理机里面那样用 upstart/systemd 去启动后台服务容器内没有后台服务的概念。 比如关于nginx的启动我们错误的写成 CMD service nginx start 或 CMD systemctl start nginx 然后发现容器执行后就立即退出了。对于容器而言其启动程序就是容器应用进程容器就是为了主进程而存在的主进程退出容器就失去了存在的意义从而退出其它辅助进程不是它需要关心的东西。 而使用 service nginx start 命令则是希望 upstart 来以后台守护进程形式启动 nginx 服务。通过上面内容我们了解到 CMD service nginx start 会被理解为 CMD [ sh, -c, service nginx start]因此主进程实际上是 sh。那么当 service nginx start 命令结束后sh 也就结束了sh 作为主进程退出了自然就会令容器退出。 正确的做法是直接执行 nginx 可执行文件并且以前台形式运行如 CMD [nginx, -g, daemon off;] ENTRYPOINT 入口点 ENTRYPOINT 的格式和 RUN 指令格式一样分为 exec 格式和 shell 格式。ENTRYPOINT 的目的和 CMD 一样都是在指定容器启动程序及参数。ENTRYPOINT 在运行时也可以替代不过比 CMD 要略显繁琐需要通过 docker run 的参数 --entrypoint 来指定。当指定了 ENTRYPOINT 后CMD 的含义就发生了改变不再是直接的运行其命令而是将 CMD 的内容作为参数传给 ENTRYPOINT 指令换句话说实际执行时将变为 ENTRYPOINT CMD 那么有了 CMD 后为什么还要有 ENTRYPOINT 呢这种 ENTRYPOINT CMD 有什么好处么让我们来看两个场景。 场景一让镜像变成像命令一样使用 假设我们需要一个得知自己当前公网 IP 的镜像那么可以先用 CMD 来实现 FROM ubuntu:16.04 RUN apt-get update \ apt-get install -y curl \ rm -rf /var/lib/apt/lists/* CMD [ curl, -s, http://ip.cn ] 假如我们使用 docker build -t myip . 来构建镜像的话如果我们需要查询当前公网 IP只需要执行 $ docker run myip 当前 IP61.148.226.66 来自北京市 联通 从上面的 CMD 中可以看到实质的命令是 curl那么如果我们希望显示 HTTP 头信息就需要加上 -i 参数。那么我们可以直接加 -i 参数给 docker run myip 么 docker run myip -i docker: Error response from daemon: invalid header field value oci runtime error: container_linux.go:247: starting container process caused \exec: \\\-i\\\: executable file not found in $PATH\\n. 执行报错executable file not found。之前我们说过跟在镜像名后面的是 command运行时会替换 CMD 的默认值。因此这里的 -i 替换了原来的 CMD而不是添加在原来的 curl -s http://ip.cn 后面。而 -i 根本不是命令所以自然找不到。那么如果我们希望加入 -i 这参数我们就必须重新完整的输入这个命令 docker run myip curl -s http://ip.cn -i 这显然不是很好的解决方案而使用 ENTRYPOINT 就可以解决这个问题。现在我们重新用 ENTRYPOINT 来实现这个镜像 FROM ubuntu:16.04 RUN apt-get update \ apt-get install -y curl \ rm -rf /var/lib/apt/lists/* ENTRYPOINT [ curl, -s, http://ip.cn ] 这次我们再来尝试直接使用 docker run myip -i docker run myip 当前 IP61.148.226.66 来自北京市 联通docker run myip -i HTTP/1.1 200 OK ... 这次成功了。这是因为当存在 ENTRYPOINT 后CMD 的内容将会作为参数传给 ENTRYPOINT而这里 -i 就是新的 CMD因此会作为参数传给 curl从而达到了我们预期的效果。 场景二应用运行前的准备工作 启动容器就是启动主进程但有些时候启动主进程前需要一些准备工作。比如 mysql 类的数据库可能需要一些数据库配置、初始化的工作这些工作要在最终的 mysql 服务器运行之前解决。此外可能希望避免使用 root 用户去启动服务从而提高安全性而在启动服务前还需要以 root 身份执行一些必要的准备工作最后切换到服务用户身份启动服务。或者除了服务外其它命令依旧可以使用 root 身份执行方便调试等。这些准备工作是和容器 CMD 无关的无论 CMD 为什么都需要事先进行一个预处理的工作。这种情况下可以写一个脚本然后放入 ENTRYPOINT 中去执行而这个脚本会将接到的参数也就是 CMD作为命令在脚本最后执行。比如官方镜像 redis 中就是这么做的 FROM alpine:3.4 ... RUN addgroup -S redis adduser -S -G redis redis ... ENTRYPOINT [docker-entrypoint.sh]EXPOSE 6379 CMD [ redis-server ] 可以看到其中为了 redis 服务创建了 redis 用户并在最后指定了 ENTRYPOINT 为 docker-entrypoint.sh 脚本。 #!/bin/sh ... # allow the container to be started with --user if [ $1 redis-server -a $(id -u) 0 ]; thenchown -R redis .exec su-exec redis $0 $ fiexec $ 该脚本的内容就是根据 CMD 的内容来判断如果是 redis-server 的话则切换到 redis 用户身份启动服务器否则依旧使用 root 身份执行。比如 docker run -it redis id uid0(root) gid0(root) groups0(root) ENV 设置环境变量 这个指令很简单就是设置环境变量. 格式有两种 * ENV key value * ENV key1value1 key2value2... 实例如下 ENV MYSQL_ROOT_PASSWORD123456 \MYSQL_DATABASEedusoho \ MYSQL_USERedusoho \MYSQL_PASSWORDedusoho 这个例子中演示了如何换行以及对含有空格的值用双引号括起来的办法这和 Shell 下的行为是一致的。定义了环境变量那么在后续的指令中就可以使用这个环境变量。比如在官方 node 镜像 Dockerfile 中就有类似这样的代码 ENV NODE_VERSION 7.2.0RUN curl -SLO https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz \ curl -SLO https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc \ gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc \ grep node-v$NODE_VERSION-linux-x64.tar.xz\$ SHASUMS256.txt | sha256sum -c - \ tar -xJf node-v$NODE_VERSION-linux-x64.tar.xz -C /usr/local --strip-components1 \ rm node-v$NODE_VERSION-linux-x64.tar.xz SHASUMS256.txt.asc SHASUMS256.txt \ ln -s /usr/local/bin/node /usr/local/bin/nodejs 在这里先定义了环境变量 NODE_VERSION其后的 RUN 这层里多次使用 $NODE_VERSION 来进行操作定制。可以看到将来升级镜像构建版本的时候只需要更新 7.2.0 即可Dockerfile 构建维护变得更轻松了。下列指令可以支持环境变量展开 ADD、COPY、ENV、EXPOSE、LABEL、USER、WORKDIR、VOLUME、STOPSIGNAL、ONBUILD 可以从这个指令列表里感觉到环境变量可以使用的地方很多很强大。通过环境变量我们可以让一份 Dockerfile 制作更多的镜像只需使用不同的环境变量即可。 ARG 构建参数 格式 ARG 参数名[默认值]构建参数和 ENV 的效果一样都是设置环境变量。所不同的是ARG 所设置的构建环境的环境变量在将来容器运行时是不会存在这些环境变量的。但是不要因此就使用 ARG 保存密码之类的信息因为 docker history 还是可以看到所有值的。Dockerfile 中的 ARG 指令是定义参数名称以及定义其默认值。该默认值可以在构建命令 docker build 中用 --build-arg 参数名值 来覆盖。在 1.13 之前的版本要求 --build-arg 中的参数名必须在 Dockerfile 中用 ARG 定义过了换句话说就是 --build-arg 指定的参数必须在 Dockerfile 中使用了。如果对应参数没有被使用则会报错退出构建。从 1.13 开始这种严格的限制被放开不再报错退出而是显示警告信息并继续构建。报错信息如下例所示 [Warning] One or more build-args [foo] were not consumed. VOLUME 定义匿名卷 格式为 VOLUME [路径1, 路径2...]VOLUME 路径容器运行时应该尽量保持容器存储层不发生写操作对于数据库类需要保存动态数据的应用其数据库文件应该保存于卷(volume)中关于Docker 卷的概念和使用可参考本库文章“Docker基本介绍和操作.md”。为了防止运行时用户忘记将动态文件所保存目录挂载为卷在 Dockerfile 中我们可以事先指定某些目录挂载为匿名卷这样在运行时如果用户不指定挂载其应用也可以正常运行不会向容器存储层写入大量数据。比如 VOLUME /data 这里的 /data 目录就会在运行时自动挂载为匿名卷任何向 /data 中写入的信息都不会记录进容器存储层从而保证了容器存储层的无状态化。如果我们想把这个匿名卷中的内容挂载到主机上呢 docker run -itd --name busytest --mount typebind,source/teng,target/data busytest:v1 或 docker run -itd --name busytest -v /teng:/data busytest:v1 EXPOSE 声明端口 EXPOSE port [port/protocol...]该EXPOSE指令通知Docker容器在运行时侦听指定的网络端口。可以指定端口是侦听TCP还是UDP如果未指定协议则默认为TCP。EXPOSE 指令是声明运行时容器提供服务端口这只是一个声明在运行时并不会因为这个声明应用就会开启这个端口的服务。在 Dockerfile 中写入这样的声明有两个好处一个是帮助镜像使用者理解这个镜像服务的守护端口以方便配置映射另一个用处则是在运行时使用随机端口映射时也就是 docker run -P 时会自动随机映射 EXPOSE 的端口。 比如我这里编写一个Dockerfile文件 FROM busybox VOLUME /data EXPOSE 80docker build -t busytest:v2 .docker run -itd --name busytest -P busytest:v2docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 30614a66bff0 busytest:v2 sh 3 seconds ago Up 2 seconds 0.0.0.0:32771-80/tcp busytest 无论EXPOSE设置如何您都可以使用-p标志在运行时覆盖它们。例如 docker run -itd --name busytest -p 8080:80 busytest:v2docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b07c5575afa1 busytest:v2 sh 3 seconds ago Up 2 seconds 0.0.0.0:8080-80/tcp busytest WORKDIR 指定工作目录 格式为 WORKDIR 工作目录路径。使用 WORKDIR 指令可以来指定工作目录或者称为当前目录以后各层的当前目录就被改为指定的目录如该目录不存在WORKDIR 会帮你建立目录。在Dockerfile中可以多次使用WORKDIR指令。如果提供了相对路径则它将相对于前一条WORKDIR指令的路径 。例如 WORKDIR /a WORKDIR b WORKDIR c RUN pwd最终pwd命令的输出Dockerfile将是 /a/b/c。 该WORKDIR指令可以解析先前使用的环境变量 ENV。您只能使用显式设置的环境变量Dockerfile。例如 ENV DIRPATH /path WORKDIR $DIRPATH/$DIRNAME RUN pwd最终pwd命令的输出Dockerfile将是 /path/$DIRNAME USER 指定当前用户 格式USER user[:group] orUSER UID[:GID] USER 指令和 WORKDIR 相似都是改变环境状态并影响以后的层。WORKDIR 是改变工作目录USER 则是改变之后层的执行 RUN, CMD 以及 ENTRYPOINT 这类命令的身份。当然和 WORKDIR 一样USER 只是帮助你切换到指定用户而已这个用户必须是事先建立好的否则无法切换。如 RUN groupadd -r redis useradd -r -g redis redis USER redis RUN [ redis-server ] 如果以 root 执行的脚本在执行期间希望改变身份比如希望以某个已经建立好的用户来运行某个服务进程不要使用 su 或者 sudo这些都需要比较麻烦的配置而且在 TTY 缺失的环境下经常出错。建议使用 gosu。 # 建立 redis 用户并使用 gosu 换另一个用户执行命令 RUN groupadd -r redis useradd -r -g redis redis # 下载 gosu RUN wget -O /usr/local/bin/gosu https://github.com/tianon/gosu/releases/download/1.7/gosu-amd64 \ chmod x /usr/local/bin/gosu \ gosu nobody true # 设置 CMD并以另外的用户执行 CMD [ exec, gosu, redis, redis-server ] 参考文档 Dockerfile 最佳实践文档Dockerfie 官方文档转载于:https://blog.51cto.com/wutengfei/2156797
http://www.sadfv.cn/news/287158/

相关文章:

  • 市住房城乡建设网站网站建设有哪些渠道
  • 天津市做网站公司链接网站开发需要多少钱
  • 职业做网站游戏的天津市建设公司网站
  • 用thinkphp做音乐网站品牌网站建设解决
  • 网易暴雪最新消息网站建设专家推荐乐云seo
  • 信息发布的网站怎么做陕西网站制
  • 电子商务网站开发的任务书企业网站 合同
  • 芙蓉区营销型网站建设定制wordpress 过滤器
  • 网站用什么语言开发wordpress 注册 验证码
  • 手机钓鱼网站制作wordpress 菜单间隔
  • 滁州建设局网站如何做跨境电商新手入门教程
  • 黄金网站软件app下载安装专业做网站 上海
  • 东营seo网站建设费用杭州人才招聘网
  • 大网站制作公司企业型网站建设怎样收费
  • 免费做网站txt外链推广深圳
  • 哪个网站查食品建设好wordpress 打开空白
  • 网站建设硬件投入表wordpress主题动漫
  • 网站开发用什么数据库网站如何做404
  • 做优秀网站有什么做家常菜的网站
  • 福建中国建设工程造价管理协会网站asp网站显示空白
  • 网站备案 地域深圳建设网站排名
  • 企业网站页面宽哪里设置wordpress 爬虫插件
  • 怎样做网站备份禹州做网站的公司
  • 国外做兼职的网站网站用哪些系统做的比较好
  • 网站子页设计用wordpress建医疗网站
  • 快彩网站开发网站内容管理系统建设
  • app与网站的区别功能自己做的网站能备案
  • 中山网站建设咨询建设银行咸阳交费网站
  • 做网站要用到哪些架包网站定制怎么收费
  • 好玩有趣的网站网上做兼职老师的正规网站