Docker 生产环境容器化
修改存储目录
生产环境中,镜像多了之后很容易把硬盘写满造成服务器宕机,所以需要挂载一块较大的硬盘,修改 docker 的默认存储路径,下面提供两种方案。
方案一:软连接
1 | service docker stop |
方案二:修改配置
配置 deamon 启动时 -g
参数,可以直接改变存储路径。
Ubuntu 系统需要先修改 /lib/systemd/system/docker.service
文件:
1 | ... |
其中 ExecStart
就是 deamon 的启动命令,可以直接在后面加参数,也可以选择上述 EnvironmentFile
配置 ,然后将启动参数写到 /etc/default/docker
文件中:
1 | DOCKER_OPTS="-g /mnt/sdc/docker" |
配置好之后,执行下面命令重新加载配置文件:
1 | systemctl daemon-reload |
参考:How do I change the Docker image installation directory?
Insecure Registry
生产环境中部署 docker,需要在搭建一个私有 registry:
1 | docker run -d -p 5000:5000 --restart=always --name registry registry:2 |
启动之后,没法直接进行镜像的 push/pull,因为默认要求配置 TLS。
为了图方便,可以暂时把私有的 registry 加入为 insecure-registry
进行测试。
insecure-registry
也是通过添加 deamon 的启动参数实现的,可在 /etc/default/docker
中配置:
1 | DOCKER_OPTS="--insecure-registry 192.168.1.19:5000" |
然后重启即可。
参考:Deploying a plain HTTP registry
集群方案
docker 集群部署目前有两种方案,一般称作 一代 swarm
和 二代 swarm
。
一代 swarm
官方文档。
一代 swarm 是以容器的方式进行集群管理的,需要在每个节点上运行一个 swarm 容器,便可进行集群管理。
需要注意的是,一代 swarm 还需要自己手动运行 k/v 服务容器,参考,运行起来之后可能会遇到报错:
1 | Error response from daemon: datastore for scope "global" is not initialized |
这其实是 deamon 没有配置 cluster-advertise
和 cluster-store
所致,需要在/etc/default/docker
中配置这两项,具体可参考 Nodes discovery。
二代 swarm
官方文档。
二代 swarm 直接将 swarm 模式集成在 docker 里面,只需要简单的配置即可,参考:Create a swarm。
界面方案
ui-for-docker 作为管理的 web 界面,但是过于简陋,后来有找到一个基于 ui-for-docker 实现的 portainer,支持 swarm mode,使用起来非常方便,也可以根据自己的需求修改。
集群实践
实践过程中我分别尝试了一代 swarm 和二代 swarm。
版本 | 配置过程 | 管理 | 扩容 |
---|---|---|---|
一代 | 1. 配置 k/v store。2. 宿主机 docker deamon 监听某个端口。 3.在每台宿主机上运行 swarm 容器。 | 在任何一个节点都可以进行集群的管理 | 手动扩容 |
二代 | 1. manager init swarm mode 2. worker join | 只能在 manager 节点进行管理 | 自动扩容 |
简单的说就是一个 nginx 的环境,以下是具体步骤:
- 使用二代 swarm。
- 创建一个 overlay 网络。
- 创建 nginx 服务。
需要明确的几点:
- 二代 swarm 在同一个网络下服务可以通过服务名发现其他服务。
- 二代 swarm 部署之后,将会监听每个节点上 publish 的端口,收到的请求会负载均衡到所有的 tasks 中。
nginx
nginx 服务只需选择官方提供的镜像,建议使用最轻量的 nginx:alpine
版本,自定义配置文件覆盖原生的即可。
更改时区
1 | RUN apk update && apk add ca-certificates && \ |
DNS 服务
docker 容器的 /etc/hosts
文件默认是不允许修改的,所以要自定义域名的解析就需要配置自己的内网 DNS 服务,推荐使用 dnsmsq
, 然后将 deamon 的启动参数修改为 --dns=192.168.x.x
自己的 DNS 服务器,就可以实现自定义域名解析的需求。
上述修改可解决服务器被墙导致谷歌、Facebook 等三方API无法使用的问题,也可以加速服务器访问外网。
代码更新
作为 web 应用,代码需要时常上线更新,又需要在集群中部署,如果使用目录挂载的办法将带来额外的工作量,所以选择把代码直接打包到容器中,每次上线重新构建镜像,具体步骤:
- 代码 push 到 gitlab,触发 CI 或者 webhook,构建镜像。
- 镜像 push 到私有的 registry 仓库中。
- 二代 swarm 提供 rolling update 的机制,执行相关命令即可。
一些经验
- Docker 是进程容器,理论上一个容器只跑一个进程,杜绝当虚拟机使用。
- 要使用和宿主机一个体系的基础镜像。
- 国内使用建议搜索下 daocloud 镜像加速,会提升幸福感。
- DNS 服务器会默认使用
8.8.8.8
,所以正式环境一定要配置 DNS 服务器,否则一些三方登录的接口将会变得异常缓慢。 - Docker 里面包含了很多新的思路,如果总是用老套路去思考,很可能就走入死胡同。
- 不要用百度搜索中文资料,一定要看最新的英文资料。
- 为了安全,确保 deamon 只监听
/var/run/docker.sock
。