总结了一些容器的知识,回答别人的问题
应用部署
实际上,容器技术流行之后最受益的是开发者,因为开发者可以借助容器技术快速的部署好开发测试环境,也可以将自己的应用打包成一个镜像发放出去,用户可以直接拥有和开发者相同的环境,不需要繁琐的部署
CI/CD(持续集成、持续部署)
容器非常适合敏捷开发模式,开发者将代码通过 svn/git 提交到远程仓库后,通过 jenkins/gitlab-ci 等持续集成工具直接构建包含最新代码的镜像,运行测试,测试成功后自动将新版本的代码的镜像滚动更新到线上环境,完全自动化,解放运维
微服务
将大型应用解耦成若干个服务模块,各服务模块松耦合,独立部署,各服务模块通过 HTTP API/RPC 通信,这种架构使得每个服务皆可以实现横向扩展,故障转移,滚动更新等高级特性,不过对于微服务来说,容器技术只是辅助,最关键的还是服务的设计
疑问
别人如何使用我的容器?
容器不是虚拟机,一般不会直接进入内部操作,打包一个镜像后,用户只需要最简单的 docker run
,需要的时候提供一些环境变量用来初始化应用即可,并不需要进入内部!
就比如 mysql 官方的镜像
docker pull mysql |
相比与在 centos 上安装 mysql 需要做的步骤…
yum install mysql mysql-server -y |
当然,这只是最简单的一个数据库安装,如果你的应用 前端用的是 nginx,后端是 mysql,还要部署 php 环境呢?假设你的应用叫做 summer-blog
docker pull summer-blog |
将复杂的环境直接打包成一个镜像,用户直接通过 docker run
就可以得到和你一样的环境,直接运行你的应用,再也不需要 *** install… 操作了
不过一般不推荐这么做,因为将那么多组件打包在一个镜像里面,无法追踪其状态
推荐分别将 nginx, mysql, php 环境独立为一个容器,再通过一些编排工具 例如 docker-compose
将每个容器连接起来
就可以使用一些很高级的功能,比如 health check
,检测到 nginx 异常退出了,自动将 nginx 容器重启,提高整个架构的可用性
RUN、CMD、ENTRYPOINT 的区别
Dockerfile 中有三个用来执行命令的方式,分别是 RUN、CMD、ENTRYPOINT
它们分别有什么区别呢?
RUN 是用来指定构建镜像(build image) 过程中执行的命令
CMD 是指定容器运行时(docker run) 默认命令和参数,可以被
docker run *** command
的命令所覆盖ENTRYPOINT 也是容器运行时执行的命令,但是可以接受
docker run *** args
或者 CMD 提供的参数,一般用于容器配置初始化
主要是 CMD 和 ENTRYPOINT 之间的差异,一个 Dockerfile 中,如果 CMD 和 ENTRYPOINT 同时存在,那么 CMD 的会传给 ENTRYPOINT,我们来看一个例子
通过 CMD 的方式输出字符串
cat Dockerfile |
如果我们想自定义输出的字符串的,可以修改 Dockerfile 重新 build 镜像,或者手动传递执行的命令,像下面这样
docker run test echo hello docker |
因为 CMD 是容器启动时候的默认命令,是会被 docker run image 后面的内容给覆盖的
通过 ENTRYPOINT 输出字符串
cat Dockerfile |
可以看出,使用 ENTRYPOINT 之后,docker run image 后面的内容就作为位置参数传递进去了,并没有覆盖原有的命令
CMD 和 ENTRYPOINT 同时存在
cat Dockerfile |
会看到 CMD 也作为参数传递到 ENTRYPOINT 后面了,因为 Dockerfile 中的 CMD 其实和命令行 docker run image 后面跟的内容是等价的,但是命令行的优先级更高
docker run test hello python |
实际使用
现在比较流行的做法是 ENTRYPOINT 和 CMD 混用,ENTRYPOINT 指定一个初始化容器的脚本,CMD 指定启动前台应用的命令,我们来看看 redis 官方镜像是怎么做的
省略前面 |
MySQL 的 docker-entrypoint 大概的意思就是,可以手动传递一些选项,或者通过 -e 设置类似 MYSQL_ROOT_PASSWORD
这样的环境变量来初始化 MySQL