在DCOS中管理和使用镜像的方式有多种,各有优劣。但是,在DCOS集群内部维护一个私有容器仓库仍然是值得推荐的。它有两个主要优势:
它仅限于你的DCOS集群范围内,安全可控。
DCOS集群对容器镜像依赖较重且镜像文件都比较大,可以节省带宽,减少镜像拉取和推送的时间,加快部署速度。
私有容器仓库的选择
从容器仓库的实现产品来讲,当前支持容器仓库的产品包括:
Docker Trusted Registry(Docker)
Registry(Docker)
Artifactory
Gitlab
Nexus3
从安全角度,因Docker守护程序默认强制要求仓库处于可信的环境,在具体实践时,根据环境的可信度,通常有三种方案:
可信证书颁发机构
自签名证书
非安全
容器仓库服务作为DCOS集群内部的一个服务,必须很容易的供内部访问,同时也可能面临来自部分集群外部的访问(如推送部分外部基础镜像到容器仓库)。在DCOS中,服务命名与发现策略有:
Mesos-DNS
Layer 4 Load Balancer
Marathon-LB
本方案的选择充分结合DCOS集群的特性,采用Docker官方提供的Registry镜像,自签名证书和VIPs + Marathon-LB的方式。
主要搭建步骤
集群环境准备。
创建具有正确的公用名和主题备用名的自签名证书。
使用证书的公钥和私钥配置Docker Registry服务。
在所有Agent节点上配置Docker守护程序以信任自签名证书。
部署Docker Registry服务。
在集群内部使用容器仓库。
在集群外部访问容器仓库。
集群环境准备
为便于后续命令可以同时在所有Agent节点上执行,可根据自己熟悉的方法构建一个运维节点到所有Agent节点之间的可信任的SSH连接。一种方法可参考SSHing into Nodes,也可以选择在一台Master上配置公私钥并将公钥添加到所有Agent节点的authorized_keys列表中。
使用下述配置调整Layer 4负载均衡(放弃对TCP状态的途中检测),让所有节点都能够从Registry中拉取和推送镜像。
for i in $(curl -sS master.mesos:5050/slaves | jq '.slaves[] | .hostname' | tr -d '"'); do ssh "$i" -oStrictHostKeyChecking=no "sudo sysctl -w net.netfilter.nf_conntrack_tcp_be_liberal=1"; done
使用自签名证书搭建私有容器仓库
创建自签名证书
确保创建自签名证书的主机上安装了OpenSSL(本例使用DCOS集群中的一个Master节点,OpenSSL位于/opt/mesosphere/packages/openssl--8042860cf76ca9ef965af9ee6d59acace266356e。
创建一个certs目录:
注1:本例使用的VIP的名字为192.168.0.1:443
注2:除了直接使用VIP,还可以使用服务的Mesos-DNS名称或引用第4层负载均衡VIP的名称创建证书。
使用Mesos DNS:
使用引用VIP的主机名:
拷贝证书和私钥到所有Agent节点
使用下述命令将证书和私钥拷贝到集群所有Agent节点。注意,下述命令仅适用于从DCOS集群的Master节点中的当前Leader节点进行操作。
配置所有Agent节点上的Docker守护程序信任为私有容器仓库创建的自签名证书。
注1:上述命令重启Docker引擎服务时会导致当前正在运行的容器服务重启。 注2:对于Docker in Docker(DnD),可以将容器的/etc/docker/certs.d映射到Agent节点宿主机的相同路径。
部署Registry到DCOS集群
将上述Marathon APP的JSON定义保存到一个JSON文件(如docker-registry.json),通过调用DCOS的WEB API或者通过DCOS CLI将服务部署到DCOS集群。
WEB API:
或CLI
dcos marathon app add docker-registry.json
在集群内部访问容器仓库
如果前述私有容器仓库搭建过程中采用的是VIP模式,则在集群内部访问容器仓库时,需要使用VIP:“192.168.0.1”。
curl -k https://192.168.0.1/v2/_catalog
在Dockerfile中设置基础镜像时,也需要进行调整:
FROM 192.168.0.1/base/docker-tomcat-base
另外,除了前述提到的DnD需要映射主机的/etc/docker/certs.d
来使用私有容器的签名证书外,对于一些由服务动态创建的容器也需要添加映射配置,如Jenkins动态创建的Slave容器主机。否则,可能会碰到类似x509: certificate signed by unknown authority
的异常。
注意,使用自签名证书时,要在DC/OS集群内部访问镜像仓库,因为Marathon使用CURL拉取镜像,因此必须将自签名证书附加到所有Agent节点的:
/opt/mesosphere/active/python-requests/lib/python3.5/site-packages/requests/cacert.pem
注意,解决UCR用CURL访问采用自签名证书的私有Registry的另一种方案是将签名证书放置于:
/var/lib/dcos/pki/tls/certs
在集群外部访问容器仓库
因为DCOS集群内部使用VIP“192.168.0.1”来访问容器仓库,VIP“192.168.0.1”对集群外部环境来说是无法访问的,那么集群外部如何访问该私有容器仓库?
从集群外部访问容器仓库有两种途径。
第一种方案:注意到前述Registry的JSON定义中,我们为APP设置了值为5000的servicePort并且添加了HAPROXY_GROUP标签,如果DCOS集群中在Public Agent节点上部署了Marathon-LB服务,则可以通过MLB访问容器仓库。
假设Public Agent节点的IP地址为192.168.1.50,则
curl -k https://192.168.1.50:5000/v2/_catalog
可以向仓库推送容器镜像:
docker push 192.168.1.50:5000/base/docker-tomcat-base
在Dockerfile中设置基础镜像时,同样需要进行调整:
FROM 192.168.1.50:5000/base/docker-tomcat-base
第二种方案是为部署的Registry服务设置固定的hostPort(如5000),并固定到一个Agent节点(如:192.168.1.70)上,则可以用与MLB方案相同的方式访问容器仓库。
推荐使用MLB方案。
参考
https://dcos.io/docs/1.9/usage/tutorials/registry