DokcerFile 镜像定制

更多精彩内容请关注微信公众号:新猿技术生态圈

定制docker镜像的方式有两种:

  1. 手动修改容器内容,导出新的镜像。

  2. 基于dockerfile自行编写指令,基于指令流程创建镜像。

Dockerfile简介

镜像是多层存储,每一层都是在前一层的基础上进行修改;

容器也是多层存储,以镜像为基础层,在其基础上加一层作为容器运行时的存储层。



刚才说了,创建镜像的两个方法:

  1. 手动修改容器内容,然后dokcer commit提交容器为新的镜像

  2. 通过在dockerfile中定义一系列的命令和参数构建成的脚本,然后这些命令应用于基础镜像,依次添加层,最终生成一个新的镜像。极大的简化了部署工作。

Dockerfile主要组成部分

  1. 基础镜像信息 FROM centos:7.9
  2. 制作镜像操作指令 RUN yum install -y nginx
  3. 容器启动时执行指令 CMD ["/bin/bash"]

宿主机直接部署软件流程与Dockerfile部署软件流程对比

需求 : 安装一个mysql,并启动。

虚拟机部署形式:

  1. 1. 开启vmware
  2. 2. 运行某一个虚拟即,centos7
  3. 3. centos7安装mysql yum install mysql-server
  4. 4. 通过脚本或者命令,启动mysql即可
  5. 部署缓慢,且修改了宿主机的环境,删除较为麻烦,占用宿主机的一个3306端口

容器的部署形式:

  1. 1. 开始vmware
  2. 2. 运行虚拟机centos7(宿主机)
  3. 3. 安装docker容器软件
  4. 4. 获取mysql镜像即可,docker pull mysql:tag(你无法自由控制,该mysql的基础镜像时什么发行版本,你获取的镜像,是别人定制好的,你下载使用的默认时Debian发行版,你希望得到一个基于centos7.9的发行版本,运行mysql)
  5. 5. 直接运行该镜像,通过端口映射,运行mysql
  6. 6. 访问宿主机对的一个映射端口,访问到容器内的mysql

想自定义镜像,就得自己写脚本,也就是dockerfile了

Dokcerfile指令

  1. FROM 指定基础镜像
  2. MAINTAINER 指定维护者信息,可以没有
  3. RUN 你想让它干啥(在命令前面加上RUN即可)
  4. ADD 添加宿主机的文件到容器内,还多了一个自动解压的功能
  5. # RUN tar -Zxf /opt/xx.tgz # 报错!该tgz文件不存在! !
  6. COPY 作用和ADD是一样的,都是拷贝宿主机的文件到容器内, COPY就是仅仅拷贝
  7. WORKDIR 相当于cd命令,设置当前工作目录
  8. VOLUME 设置目录映射,挂载主机目录
  9. EXPOSE 指定对外的端口,在容器内暴露一个端口,端口 EXPORT 80
  10. CMD 指定容器启动后的要干的事情
  11. ENTRYPOINT 作用和CMD一样,都是在指定容器启动程序以及参数。
  12. # 当指定了ENTRYPOINT之后,CMD指令的语义就有了变化,而是把CMD的内容当作参数传递给ENTRYPOINT指令。
  13. ARG 设置环境变量
  14. # ARG只是用于构建镜像需要设置的变量,容器运行时就消失了
  15. ENV ARG一样,都是设置环境变量
  16. # 区别在于ENV无论是在镜像构建时,还是容器运行,该变量都可以使用
  17. USER 用于改变环境,用于切换用户

Dokcerfile实践

需求:通过dockerfile,构建nginx镜像,且运行容器后,生成的页面是"辣辣小姐姐"。

  1. 1. 创建Dockerfile,注意文件名,必须是这个
  2. [root@docker01 ~]# mkdir /learn_docker
  3. [root@docker01 ~]# cd /learn_docker/
  4. [root@docker01 learn_docker]# vim Dockerfile
  5. FROM nginx
  6. RUN echo "<meta charset=utf-8>辣辣小姐姐" > /usr/share/nginx/html/index.html
  7. 2. 构建Dockerfile
  8. [root@docker01 learn_docker]# docker build .
  9. 3. 修改镜像名字
  10. [root@docker01 learn_docker]# docker images
  11. REPOSITORY TAG IMAGE ID CREATED SIZE
  12. <none> <none> 950549357c1f 18 seconds ago 133MB
  13. nginx latest 08b152afcfae 6 days ago 133MB
  14. [root@docker01 learn_docker]# docker tag 950549357c1f my_nginx
  15. 4. 运行该镜像
  16. docker run -d -p 80:80 my_nginx
  17. 5. 查看宿主机的80端口
  18. http://192.168.15.80/
  19. # 辣辣小姐姐

更多精彩内容请关注微信公众号:新猿技术生态圈

Dokcerfile相关指令用法

COPY

  1. copy指令从宿主机复制文件或者目录到新的一层镜像内
  2. 如:
  3. copy nana.py /opt
  4. 支持多个文件,以及通配符形式的复制,语法要满足Golangfilepath.Match
  5. copy na* /tmp/cc?.txt /opt
  6. COPY指令能够保留源文件的元数据,访问时间等等,这点很重要

ADD

  1. 特性和COPY基本一致,不过多了些功能
  2. 1. 源文件是一个URL,此时dockcer引擎会下载该链接,放入目标路径,且权限自动设为600。若这不是期望结果,还得增加一层RUN指令进行调整
  3. # ADD nana.tgz /home
  4. # RUN xxx修改命令
  5. 2. 源文件是一个URL,且是一个压缩包,不会自动解压,也得单独用RUN指令解压
  6. 3. 源文件是一个压缩文件,且是gzipbzipxztar情况,ADD指令会自动解压压缩该文件到没有文件

CMD

  1. 用法,注意是双引号
  2. # CMD在容器内运行某个命令,启动程序
  3. # 该镜像在运行容器实例的时候,执行的具体参数是什么
  4. CMD["参数1","参数2"]
  5. 在指定了entrypoint指令后,用CMD指定具体的参数
  6. dokcer不是虚拟机,容器就是一个进程,既然是进程,那么程序在启动的时候需要指定些运行参数,这就是CMD指令作用
  7. 例如centos镜像默认的CMD是/bin/bash,直接docker run -it centos会直接进入bash解释器。
  8. 也可以启动容器时候,指定参数: docker run -it centos cat /etc/os-release
  9. CMD ["/bin/bash"]
  10. # 该容器运行时,执行的命令
  11. # 等同于命令行的直接操作:docker run -it centos cat /etc/os-release
  12. CMD ["cat","/etc/os-release"]

容器内运行程序

这里要注意的是,docker不是虚拟机的概念,虚拟机的程序运行,基本上都是在后台运行,利用systemctl运行,但是容器内没有后台进程的概念,必须在前台运行

容器就是为了主进程而存在的,主进程如果退出了,容器也就失去意义,自动退出。

  1. 例如一个经典的问题:
  2. # 这样的写法是错误的,容器会立即退出
  3. CMD systemctl start nginx
  4. 因为systemctl start nginx是以守护进程(默认在后台运行)的形式启动nginx,且CMD命令会转化为
  5. CMD ["sh","-c","systemctl start nginx" ]
  6. 这样的命令主进程是sh解释器,执行完毕后立即结束了,因此容器也就退出了。
  7. # 相当于nginx -g daemon off
  8. 因此正确的做法应该是 CMD ["nginx","-g","daemon off;"]
  1. 把宿主机安装,启动nginx的理念放入到dockerfile
  2. 1. RUN yum install nginx
  3. 2. RUN 配置文件修改 sed
  4. # RUN systemctl start nginx 容器内的程序必须在前台运行,容器时启动不了的
  5. 3. 正确的写法应该时CMD ["nginx","-g","daemon off;"]

ENTRYPOINT

dokcer面试题:

ENTRYPOINT和CMD的区别以及用法! ! !

  1. ENTRYPOINT作用和CMD一样,都是在指定容器启动程序以及参数。
  2. 当指定了ENTRYPOINT之后,CMD指令的语义就有了变化,而是把CMD的内容当作参数传递给ENTRYPOINT指令。

ENTRYPOINT和CMD的实际用法

  1. 实际用法:
  2. 1. 准备一个Dokcerfile
  3. [root@docker01 ~]# cd /learn_docker/
  4. [root@docker01 learn_docker]# > Dockerfile
  5. [root@docker01 learn_docker]# vim Dockerfile
  6. FROM centos:7.8.2003
  7. RUN rpm --rebuilddb && yum install epel-release -y
  8. RUN rpm --rebuilddb && yum install curl -y
  9. CMD ["curl","-s","ip.sb"]
  10. # 用法如下
  11. dokcer run my_centos curl -s ip.sb # curl -s ip.sb获取本机的公网ip地址
  12. 2. 构建镜像
  13. [root@docker01 learn_docker]# docker build .
  14. Sending build context to Docker daemon 2.048kB
  15. Step 1/4 : FROM centos:7.8.2003
  16. ---> afb6fca791e0
  17. Step 2/4 : RUN rpm --rebuilddb && yum install epel-release -y
  18. ---> Using cache
  19. ---> 81b4e83fb0a5
  20. Step 3/4 : RUN rpm --rebuilddb && yum install curl -y
  21. ---> Using cache
  22. ---> bd0074c78b6c
  23. Step 4/4 : CMD ["curl","-s","ip.sb"]
  24. ---> Running in 295418f71093
  25. Removing intermediate container 295418f71093
  26. ---> c920b743282a
  27. Successfully built c920b743282a
  28. 3. 查看结果(出现Successfully代表镜像构建完成)
  29. Step 4/4 : CMD ["curl","-s","ip.sb"]
  30. ---> Running in 295418f71093
  31. Removing intermediate container 295418f71093
  32. ---> c920b743282a
  33. Successfully built c920b743282a
  34. 4. 检查镜像
  35. [root@docker01 learn_docker]# docker tag c920b743282a centos_curl
  36. [root@docker01 learn_docker]# docker images | grep curl
  37. centos_curl latest c920b743282a 3 minutes ago 471MB
  38. 5. 运行镜像,生成容器记录,没有前台运行,因此立即挂了
  39. [root@docker01 learn_docker]# docker run centos_curl
  40. 139.227.102.189
  41. 6. 上述运行正确,但是我想再传入一个参数,该怎么办
  42. # 发现是无法直接传入参数的,该形式是覆盖镜像中的cmd
  43. # 就好比把docker镜像,当作一个环境,去执行后面的命令
  44. [root@docker01 learn_docker]# docker run centos_curl pwd
  45. /
  46. [root@docker01 learn_docker]#
  47. [root@docker01 learn_docker]# docker run centos_curl -I
  48. docker: Error response from daemon: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "-I": executable file not found in $PATH: unknown.
  49. 7. 想要正确的给容器传入一个参数该怎么办
  50. 希望容器内能够正确完整的运作该命令的执行结果
  51. [root@docker01 learn_docker]# curl -s ip.sb -I # 获取http报头信息
  52. HTTP/1.1 200 OK
  53. Date: Wed, 28 Jul 2021 15:16:18 GMT
  54. ...
  55. 8. 解决办法
  56. 方式一:给容器传入新的完整的命令,让后面的命令覆盖镜像中的cmd
  57. # 这是投机取巧的办法,不合适
  58. [root@docker01 learn_docker]# docker run centos_curl curl -s ip.sb -I
  59. HTTP/1.1 200 OK
  60. Date: Wed, 28 Jul 2021 15:18:05 GMT
  61. Content-Type: text/plain
  62. 9. 正确的解决办法
  63. [root@docker01 learn_docker]# vim Dockerfile
  64. FROM centos:7.8.2003
  65. RUN rpm --rebuilddb && yum install epel-release -y
  66. RUN rpm --rebuilddb && yum install curl -y
  67. ENTRYPOINT ["curl","-s","ip.sb"]
  68. 10. 重新构建镜像
  69. # 重新构建镜像速度特别快,并且我们发现镜像的前三个Step的IMAGE ID是一致的,说明前三个的IMAGE ID是直接从缓存中拿的。
  70. # 只有Step 4/4的IMAGE ID发生了变化(Dockerfile文件的第四步是更改过的,是重新构建的镜像层),因此更加验证了我们之前所提到的镜像是分层构建的。
  71. [root@docker01 learn_docker]# docker build .
  72. Sending build context to Docker daemon 2.048kB
  73. Step 1/4 : FROM centos:7.8.2003
  74. ---> afb6fca791e0
  75. Step 2/4 : RUN rpm --rebuilddb && yum install epel-release -y
  76. ---> Using cache
  77. ---> 81b4e83fb0a5
  78. Step 3/4 : RUN rpm --rebuilddb && yum install curl -y
  79. ---> Using cache
  80. ---> bd0074c78b6c
  81. Step 4/4 : ENTRYPOINT ["curl","-s","ip.sb"]
  82. ---> Running in df106e04d533
  83. Removing intermediate container df106e04d533
  84. ---> e9479067148c
  85. Successfully built e9479067148c
  86. 11. 重新运行该镜像,看结果,以及传入新的参数
  87. [root@docker01 learn_docker]# docker tag e9479067148c centos_curl_new
  88. # 此时发现,传入的CMD指令,当作了ENTRYPOINT的参数
  89. # 其实容器内,执行的完命令是: curl -s ip.sb -I
  90. [root@docker01 learn_docker]# docker run centos_curl_new -I
  91. HTTP/1.1 200 OK
  92. Date: Wed, 28 Jul 2021 15:24:58 GMT
  93. ...

ARG和ENV指令

设置环境变量

  1. dockerfile脚本,shell脚本
  2. ENV NAME="nana"
  3. ENV AGE=18
  4. ENV MYSQL_VERSION=5.6
  5. 后续所有的操作,通过$NAMME就可以直接获取变量值使用了,维护dockerfile更加方便
  6. ARGENV一样,都是设置环境变量
  7. ENV无论是在镜像构建时,还是容器运行,该变量都可以使用
  8. ARG只是用于构建镜像需要设置的变量,容器运行时就消失了

VOLUME

容器在运行时,应该保证在存储层不写入任何数据,运行在容器内产生的数据,我们推荐是挂载,写入到宿主机上,进行维护。

  1. # mount /mnt
  2. VOLUME /data
  3. # 将容器内的/data文件夹,在容器运行时,该目录自动挂载为匿名卷,任何向该目录中写入数据的操作,都不会被容器记录,保证的容器存储无状态理念。
  4. # Dockerfile
  5. [root@docker01 ~]# cd /learn_docker/
  6. [root@docker01 learn_docker]# > Dockerfile
  7. [root@docker01 learn_docker]# vim Dockerfile
  8. FROM centos
  9. MAINTAINER nana
  10. VOLUME ["/data1","/data2"]
  11. # 该容器运行的时候,这两个目录自动和宿主机的目录做好映射关系
  12. docker build .
  13. # 运行该镜像
  14. docker run 86b4dceba89a
  15. # 查看生成的容器信息
  16. [root@docker01 nana]# docker ps -a | head -2
  17. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  18. 84014622b3a4 86b4dceba89a "/bin/bash" 2 minutes ago Exited (0) 2 minutes ago sharp_noether
  19. # dokcer inspect命令查看
  20. [root@docker01 learn_docker]# docker inspect 86b4dceba89a
  21. "Volumes": {
  22. "/data1": {},
  23. "/data2": {}
  24. },
  25. 1. 容器数据挂载的方式,通过dockerfile,指定VOLUME目录
  26. 2. 通过docker run -v参数,直接设置需要映射挂载的目录

EXPOSE

指定容器运行时对外提供的端口服务。

  1. 帮助使用该镜像的人,快速理解该容器的一个端口业务
  2. docker port 容器
  3. dokcer run -p 宿主机端口:容器端口
  4. docker run -P # 作用是随机 宿主机端口:容器内端口

WORKDIR

用于在dockerfile中,目录的切换,更改工作目录

  1. WORKDIR /opt

USER

用于改变环境,用于切换用户

  1. USER root
  2. USER nana

使用Dockerfile构建一个网站镜像

传统方式创建一个网站站点

  1. nginx,修改首页内容,html网站就跑起来了。web server,提供web服务,提供代理转发,提供网关,限流等等。。。
  2. web framework。web框架,一般由开发,通过某个开发语言,基于某个web框架,自己去开发一个web站点,python,django框架。

使用Dockerfile创建一个网站站点

  1. 用python语言,基于flask web框架,开发一个自己的网站,写一个后端的网站代码
  2. 开发dockerfile,部署该代码,生成镜像
  3. 其他人基于该镜像,docker run就可以在电脑跑起来你这个网站

使用docker的优势

  • 比如安装一个etcd、naco,都是一些比较复杂的软件。

  • 需要依赖于go语言环境,比如需要依赖于java环境,在自己的机器安装好对应的开发环境,以及对应的版本,以及各种依赖。。。

    1. tomcat 依赖于jdk环境
    2. 当你有了docker
    3. docker pull tomcat # 这些主流的镜像都可以直接找到,并且该镜像中,就已经打包好了java环境
    4. docker run tomcat xxx ... # 直接可以访问tomcat了
  1. 1. 在宿主机下,准备一个目录,准备好dockerfile,代码文件
  2. # 写一个flask的python代码
  3. # 创建代码文件
  4. [root@docker01 ~]# cd /learn_docker/
  5. [root@docker01 ~]# vim nana_flask.py
  6. #coding:utf8
  7. from flask import Flask
  8. app=Flask(__name__)
  9. # @app.route(装饰器),网站的route,指的是url地址后面的文件路径
  10. @app.route("/nana")
  11. def nana():
  12. return "From Docker,nana是只臭猪猪!!!"
  13. if __name__=="__main__":
  14. app.run(host="0.0.0.0",port=8080)
  15. 2. 编写Dockerfile
  16. [root@docker01 learn_docker]# vim Dockerfile
  17. FROM centos:7.8.2003
  18. RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo;
  19. RUN curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo;
  20. RUN yum makecache fast;
  21. RUN yum install python3-devel python3-pip -y
  22. RUN pip3 install -i https://pypi.douban.com/simple flask
  23. COPY nana_flask.py /opt
  24. WORKDIR /opt
  25. EXPOSE 8080
  26. CMD ["python3","nana_flask.py"]
  27. 3. 构建镜像
  28. # --no-cache不是使用之前旧的缓存,重新构建镜像
  29. [root@docker01 learn_docker]# docker build --no-cache -t "nana_flask" .
  30. ...
  31. Successfully built 9e731f439e41
  32. Successfully tagged nana_flask:latest
  33. 4. 查看构建好的镜像
  34. [root@docker01 learn_docker]# docker images | head -2
  35. REPOSITORY TAG IMAGE ID CREATED SIZE
  36. nana_flask latest 9e731f439e41 3 minutes ago 649MB
  37. 5. 运行镜像,生成容器
  38. [root@docker01 learn_docker]# docker run -d --name nana_flask_web01 -p 90:8080 nana_flask
  39. d9f2f83d16bdd0364473d6e4043c433cbd8e3286e87ecbf93fb3fd5e08ac8002
  40. [root@docker01 learn_docker]# docker ps
  41. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  42. d9f2f83d16bd nana_flask "python3 nana_flask.…" 2 minutes ago Up 2 minutes 0.0.0.0:90->8080/tcp, :::90->8080/tcp nana_flask_web01
  43. 6. 访问宿主主机,查看容器内的flask web网站
  44. 浏览器输入: http://192.168.15.80:90/nana
  45. # From Docker,nana是只臭猪猪!!!

如何修改容器内的网站的内容

方法一:修改宿主机的代码,以及dockerfile,重新构建镜像

  1. [root@docker01 ~]# vim nana_flask.py
  2. ...
  3. def nana():
  4. return "From Docker,nana是只臭猪猪!!!" # 修改return值,重新生成镜像
  5. ...

方法二:你可以经入到已经运行的容器内,修改代码,重启容器即可

  1. 1. 进入容器内部
  2. [root@docker01 learn_docker]# docker exec -it d9f2f83d16bd bash
  3. [root@d9f2f83d16bd opt]# ls
  4. nana_flask.py
  5. 2. 修改容器内的代码
  6. [root@d9f2f83d16bd opt]# vi nana_flask.py
  7. #coding:utf8
  8. from flask import Flask
  9. app=Flask(__name__)
  10. # @app.route(装饰器),网站的route,指的是url地址后面的文件路径
  11. @app.route("/nana")
  12. def nana():
  13. return "From Docker,nana是只臭猪猪!!!ABC!!!"
  14. if __name__=="__main__":
  15. app.run(host="0.0.0.0",port=8080)
  16. 3. 退出容器并重启容器
  17. [root@d9f2f83d16bd opt]# exit
  18. exit
  19. [root@docker01 learn_docker]# docker restart d9f2f83d16bd
  20. d9f2f83d16bd
  21. [root@docker01 learn_docker]# docker ps
  22. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  23. d9f2f83d16bd nana_flask "python3 nana_flask.…" 4 minutes ago Up About a minute 0.0.0.0:90->8080/tcp, :::90->8080/tcp nana_flask_web01
  24. 4. 访问宿主主机,查看容器内的flask web网站
  25. 浏览器输入: http://192.168.15.80:90/nana
  26. # From Docker,nana是只臭猪猪!!!ABC!!!

更多精彩内容请关注微信公众号:新猿技术生态圈

Docker基础复习

Docker容器文件系统

容器是docker的一个核心概念,容器使用一个或者一组应用,他的运行状态如下:

  • docker利用容器运行应用程序

  • 容器是镜像的运行实例,可以被run、start、stop、rm

  • 每个容器都是互相隔离,保证平台暗转

  • 容器可以看作是一个简易版Linux环境(没有Linux内核,有root权限、进程、用户空间、网络)

  • 镜像是只读的,容器在启动的时候创建一层可写层



    dokcerfile面向开发,docker image(镜像)作为交付标准,docker container(容器)涉及部署和运维,三者合起来完成docker体系。

    1. FROM ubuntu:14.04 选择基础镜像
    2. ADD run.sh 添加文件镜像,这一层镜像只有一个内容,就是这个文件
    3. VOLUME /data 设定存储目录,并未添加文件,只是更新了镜像的json文件,便于启动时候读取该层信息
    4. CMD ["./run.sh"] 更新json文件,设定程序入口

docker容器管理总结

  1. # 运行镜像,且进入容器内
  2. [root@docker01 ~]# docker run -it ubuntu bash
  3. root@7478064e9fff:/#
  4. # 容器运行web程序
  5. # 注意端口使用,数字大一点,建议8000以后开始使用
  6. # --restart=always容器在后台挂掉后,默认重启容器
  7. [root@docker01 ~]# docker run --name my_nginx -d --restart=always -p 8000:80 nginx
  8. 79d7fcfdc60f2c40e6d92790be6ad6f3bf9db49fda0e46cadb196be6677b4f73
  9. [root@docker01 ~]# docker ps | head -2
  10. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  11. 79d7fcfdc60f nginx "/docker-entrypoint.…" 40 seconds ago Up 39 seconds 0.0.0.0:8000->80/tcp, :::8000->80/tcp my_nginx
  12. 浏览器访问:http://192.168.15.80:8000/ ==> 可以访问到nginx
  13. # 查看容器内日志,实时刷新
  14. docker logs -f
  15. # 查看运行时,以及挂掉的容器记录
  16. docker ps 在运行的容器
  17. dokcer ps -a 挂掉以及活着的容器
  18. # 停止启动
  19. docker start
  20. docker stop
  21. # 进入容器内
  22. docker exec -it 容器id bash
  23. # 删除容器
  24. docker rm 容器id
  25. docker rm `docker ps -qa`
  26. # 强制杀死并删除容器
  27. docker rm -f 容器id
  28. # 查看容器进程资源信息
  29. docker top 容器id
  30. # 查看容器内资源
  31. docker stats 容器id
  32. # 查看容器具体信息
  33. docker inspect 容器id
  34. # 获取容器内的ip地址,容器的格式化参数
  35. docker inspect --format '{{ .NetworkSettings.IPAddress }}' 容器id

dokcer run启动容器的时候,dokcer后台操作流程是

  • 检查本地是否有该镜像,没有就下载
  • 利用镜像创建且启动一个容器
  • 分配容器文件系统,在只读的镜像层挂载读写层
  • 宿主机的网桥接口会分配一个虚拟接口到容器中
  • 容器获得地址池的ip地址
  • 执行用户指定的程序
  • 若程序里没有进程在运行,容器执行完毕后立即终止

更多精彩内容请关注微信公众号:新猿技术生态圈

更多精彩内容请关注微信公众号:新猿技术生态圈

更多精彩内容请关注微信公众号:新猿技术生态圈

K8S系列第四篇(Dockerfile)的更多相关文章

  1. 深入理解javascript作用域系列第四篇——块作用域

    × 目录 [1]let [2]const [3]try 前面的话 尽管函数作用域是最常见的作用域单元,也是现行大多数javascript最普遍的设计方法,但其他类型的作用域单元也是存在的,并且通过使用 ...

  2. 前端工程师技能之photoshop巧用系列第四篇——图片格式

    × 目录 [1]图片格式 [2]保存设置 前面的话 对于前端来说,图片格式是需要重要掌握的知识.本文是photoshop巧用系列第四篇——图片格式 图片格式 目前在前端的开发中常用的图片格式有jpg. ...

  3. 深入理解javascript作用域系列第四篇

    前面的话 尽管函数作用域是最常见的作用域单元,也是现行大多数javascript最普遍的设计方法,但其他类型的作用域单元也是存在的,并且通过使用其他类型的作用域单元甚至可以实现维护起来更加优秀.简洁的 ...

  4. javascript面向对象系列第四篇——选项卡的实现

    前面的话 面向对象的应用并非只是读几本书那么容易,需要有大量的工程实践做基础才能真正理解并学会使用它.本文将用面向对象的技术来制作一个简单的选项卡 图示说明 由图示结果看到,这是一个非常简单的选项卡. ...

  5. 【Windows编程】系列第四篇:使用Unicode编程

    上一篇我们学习了Windows编程的文本及字体输出,在以上几篇的实例中也出现了一些带有“TEXT”的Windows宏定义,有朋友留言想了解一些ANSI和Unicode编程方面的内容,本章就来了解和学习 ...

  6. chromium浏览器开发系列第四篇:如何调试最新chromium源码

    转自:http://blog.itpub.net/20687969/viewspace-1586513/ 附上上几篇文章地址,方便大家查看: 下载源码 编译源码 目录结构 接二连三的事情,时间比较紧张 ...

  7. Java系列--第四篇 基于Maven的SSME之发送邮件

    在系列第一篇中,使用的是mybatis得到了一个小小的项目,而该项目的用户对象是有邮件地址的,如果按照邮件地址给对方去一封邮件会不会更能体现针对性呢,所以,我在这篇准备加入发送邮件的功能,利用的就是s ...

  8. Laravel 源码解读系列第四篇-Auth 机制

    前言 Laravel有一个神器: php artisan make:auth 能够快速的帮我们完成一套注册和登录的认证机制,但是这套机制具体的是怎么跑起来的呢?我们不妨来一起看看他的源码.不过在这篇文 ...

  9. Android异步处理系列文章四篇之三

    Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面Android异步处理二:使用AsyncTask异步更新UI界面Android异步处理三:Handler+Loope ...

随机推荐

  1. 一、安装Tomcat服务器

    [root@ web1 ~]# yum -y install java-1.8.0-openjdk   #安装jdk [root@web1 ~]# yum -y install java-1.8.0- ...

  2. redis为什么要提供pipeline功能

    通常我们用redis做接口缓存后,查询接口的性能就能提升到ms级别: 但是redis是纯内存操作啊,总不至于要到ms吧,根据官方的 benchmark 单实例也是能抗 7w+ qps 也就是说单个re ...

  3. 【模拟8.03】斐波那契(fibonacci) (规律题)

    就是找规律,发现每个父亲和孩子的差值都是距儿子最大的fibonacc 也是可证的 f[i]表示当前月的兔子总数 f[i]=f[i-1]+f[i-2](f[i-2]是新生的,f[i-1]是旧有的) 然后 ...

  4. WPF中ListView控件怎么添加新的tiem时滚动条一直在最下面

    listBox.ScrollIntoView(listBox.Items[listBox.Items.Count - 1])

  5. excel用函数去掉单元格内容中的括号,并只保留单元格里面的内容

    1.substitute(需要执行替换操作的单元格,需要替换的字符,替换后的字符,有多个需要替换的字符可以指定替换的第几个) 例如:aab--substitute("aab",&q ...

  6. AWS上创建EKS(K8S)集群

    1.注意事项及准备工作 EKS分为EKS Master和EKS Node两种角色;EKS Master为全托管,EKS Node为CloudFormation创建 EKS Node若在NAT网络里,一 ...

  7. 24、dhcp服务搭建

    1.dhcp介绍: DHCP(Dynamic Host Configuration Protocol),动态主机配置协议,DHCP 协议主要是用来自动为局域网中的客户机分配 TCP/IP 信息的网络协 ...

  8. COURSES 赤裸裸的二分匹配大水题

    COURSES 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include ...

  9. JDK1.8 ArrayList 源码解析

    源码的解读逻辑按照程序运行的轨迹展开 Arraylist的继承&实现关系 打开ArrayList源码,会看到有如下的属性定义, ArrayList中定义的属性 /** * Default in ...

  10. nginx 基本配置

    server { listen 80; server_name 域名; #access_log /var/log/nginx/admin.log; index index.html index.htm ...