背景
每次部署环境的时候,尤其是环境中有各种依赖,小心翼翼地做着重复的工作,会让人觉得很不爽。docker容器技术就可以将人从这些复杂重复的工作中拯救出来。这里分享一个用docker构建线上环境的实例。
相关名词
Docker 镜像:镜像,就是把程序运行的环境按照自己的实际需求打成的包。比如Centos 是一个镜像, 你在centos上装了redis相关的服务也可以打包成一个镜像。下次加载镜像的时候,就有了之前装的 redis环境了。所以把服务制作成镜像, 那么你到一台新的环境上部署服务时,只需要加载这个镜像就好了,不需要再进行繁琐的环境安装。
Docker Hub: 类比github, github是代码托管中心,而docker hub是镜像托管中心。自己制作的镜像可以上传至docker hub 共享至全世界。当然我们生产环境一般不用docker hub, 就像公司不会把代码放到github上一样的道理。一般会选择自己搭一个docker registry环境,托管公司内部的镜像。
Docker 容器: 容器就是镜像的运行状态。可以用同一个镜像启动多个容器。值得注意的是,容器需要保存成镜像,才能保存对该容器的操作。可以理解为,改动容器,就是在你本地改代码,没有同步到github上。
Docker Compose: compose 编排,就是组合各种docker。比如一个web docker, 一个redisdocker。你可以选择一个一个服务docker run ... 。 这样服务跟参数一多起来,就很容易出错,也很繁琐。这时候,把各种服务写到compose的配置文件中去,然后docker-compose up 就可以将所有的服务拉起,并且可以设定挂掉是否重启等。
一、 环境 centos6.5 + docker1.7 + docker compose 1.5
二、用单个Dockerfile产生镜像
三、用docker compose 管理多个服务
环境
主机Centos6.5
Docker1.7 由于新版的docker要求主机centos7以上版本,所以我们用docker1.7支持Centos6.5的主机。
docker compose 1.5 选1.5道理同上
docker是用来制作镜像的,一个服务一个镜像,但是很多情况下一个主机有多个服务,要是用手动一个一个启动docker容器,那是很繁琐的事情。所以,docker compose就是用来解决这个问题的。compose只能用来编排单个主机上的多个服务。如果需要用到集群,去了解k8s之类的吧。compose只适合部署同一台机器上的的服务。
Dockerfile产生镜像
创建自己的镜像
1. 通过commit 容器得到
2.通过Dockerfile得到
尽量减少docker的层, dockerfile 中每一个指令都会使docker添加一层
先想想我们需要什么,我们是想做到 改了代码,然后打包到镜像里面,安装或者更新线上环境的时候下载镜像重新加载就好了。如果这样的话,那么我们需要先把基础依赖打包成镜像。把服务需要的依赖,打包成镜像,然后我们的代码更新是基于这个镜像的。产生镜像的方式就两种, 一个是通过更改容器,保存成镜像;另一个就是用dockerfile产生一个镜像。选dockerfile的原因是,比起容器,其对镜像的操作是可见的,是一个脚本化的操作,便于维护和理解。
我们还需要什么?在运维方面,日志和coredump总不该放容器里面吧,因为容器重启,就像是重装系统,容器在运行过程中产生的数据是不能保存的。所以产生的数据不要放在容器里面。docker提供了挂载目录的功能。就是能将容器中的目录,与主机的目录相关联。那么容器产生的数据,就保存在主机了,即使容器挂了那数据也还在。
FROM centos:6.8
COPY . /tmp
RUN mkdir -p "/tmp/logs" && mkdir -p "/tmp/coredumps"
CMD ["echo", "'/tmp/coredumps/core.%t.%e.%p' | tee /proc/sys/kernel/core_pattern"]
ENTRYPOINT ["bash","/tmp/bin/start.sh"]
有了dockerfile ,在dockerfile所在目录,执行 docker build -t name:tag .
则会得到一个名叫name ,标签是tag的镜像。
上面的dockerfile文件就满足了需求,来分析一下:
FROM 就是from哪个镜像, 可以认为是基于cents 6.8的环境, 当然这里可以根据需要制作镜像。FROM 会先查看你本地的镜像列表里有没有这个镜像,没有则再从docker hub里面找。用docker images查看本地的镜像列表是这样的:
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
centos/lb v2 1f92b59af388 2 hours ago 476.6 MB
centos/mls v2 d8b7a277a161 2 hours ago 476.4 MB
centos/mls v1 84f90b204719 5 hours ago 200.5 MB
centos/lb v1 76882cfa249c 5 hours ago 200.8 MB
centos 6.8 e8cf8129749b 8 months ago 194.5 MB
centos:6.8 就是最后那个镜像了。
COPY 就是将主机上的文件拷贝至镜像中。copy 当前路径的文件至镜像中的tmp目录下,我的目录是这样的:
bin conf Dockerfile
bin里面是可执行文件, conf是配置文件
RUN 就是执行一个bash命令,我这里创建了两个文件夹logs, coredumps。 这两个文件夹放日志和coredumps,所以这两文件夹必须要挂载到主机的目录上。挂载放到compose里面去了,不在dockerfile里面。
CMD 差不多,执行echo 命令。 更改coredump生成路径。coredump默认会在可执行文件的目录下产生,我不想暴露可执行文件到主机上,所以更改了coredump路径。
ENTRYPOINT 执行start脚本,关于cmd run entrypoint 区别,
- RUN 执行命令并创建新的镜像层,RUN 经常用于安装软件包。
- CMD 设置容器启动后默认执行的命令及其参数,但 CMD 能够被
docker run
后面跟的命令行参数替换 - ENTRYPOINT 配置容器启动时运行的命令。
以上,包含我们代码的镜像就制作好了,目录挂载我们放在compose里面做。
Docker compose编排
compose 编排,就是把多个镜像组合起来跑,就是管理多个服务。compose的配置文件是yaml格式的。
还是基于我们服务的需求, 1.服务挂了自动重启 2.端口映射,docker内部端口,映射到主机的端口 3.更改coredump的生成路径 4.将日志,配置文件,core文件映射到主机上,长久保存。以下配置文件满足这些需求。
注意: 有可能出现compose启动了服务,马上退出的情况,这是因为容器保持运行状态,需要一个显示的终端。类似top 命令这种, 对于我们的服务的start.sh内部, 启动一个服务不要加-d 就可以解决这个问题了。来看看这个例子。
lbserver:
image: centos/lb:v2
#build: .
restart: always
net: "host"
privileged: true
volumes:
- /tmp/lb/logs:/tmp/logs
- /tmp/lb/coredumps:/tmp/coredumps
- /tmp/lb/conf:/tmp/conf
tty: true
mlsserver:
image: centos/mls:v2
restart: always
net: "host"
privileged: true
volumes:
- /tmp/mls/logs:/tmp/logs
- /tmp/mls/coredumps:/tmp/coredumps
- /tmp/mls/conf:/tmp/conf
tty: true
这里有两个服务, lbserver 、mlsserver , 我这里的两个服务没有启动的先后顺序,如有这方面需求请查阅相关资料。image 是这个服务依赖的镜像,我们代码是放这个镜像里面了。restart always就是挂了就重启。net host, 就是docker的所有端口与主机的端口一一对应。如果只开放特定端口,也是可以设置的。 privileged这个选项是为了有修改coredump文件产生目录的权限。没有这个选项,是改不了特殊目录的文件的。volumes 选项,左边是主机路径,右边是对应的docker路径。就是将docker中的路径,挂载到主机上。这里挂载了日志,coredump文件,配置文件,可以按需求添加。tty 就是虚拟终端,对应run docker的时候的-t参数。
写好了上面这个yml文件,则在该文件的目录下sudo docker-compose up, 或者root权限下docker-compose up将这两个服务拉起。