如何利用 Docker 安全的发布服务, 以及 Serverless 是什么

Kubernetes 的出现让 Docker 直接发布服务显得黯然失色。但是,在一些边缘节点的部署上,直接基于 Docker 发布服务却是最佳选择。本地 Docker 用得久了,很多人常常把它仅仅当成了一个命令行(CLI)工具,而忘了 Docker 其实是一个 C/S 架构的服务, 即我们操作的 Docker 命令只是一个简单的 Client 端接口而已,其主要功能都是在 Dockerd 的服务端程序中运行的。

利用 Docker 的 C/S 架构特点就可以非常方便的将其发布过程集成到 CI/CD 中,唯一需要考虑就是生产环境的安全性问题。本文主要记录一下 Docker 安全发布服务的基本操作过程。

证书生成

实现 C/S 架构安全通信的方法有很多,官方提供了证书双向认证的方式。现在,首先生成一组 CA/Server/Client 证书,用于双向认证。

生成证书的工具有很多,OpenSSL 生成参数过于复杂,我主要使用 certstrap 工具。具体命令如下:

$: certstrap init --common-name "ca" --expires "20 years" --organization "example.com"
$: certstrap request-cert -cn server -ip 127.0.0.1 -domain "*.example.com, *.example.net"
$: certstrap sign server --CA ca --expires "5 years"
$: certstrap request-cert -cn client
$: certstrap sign client --CA ca
$: tree .
.
├── README.md
└── out
    ├── ca.crl
    ├── ca.crt
    ├── ca.key
    ├── client.crt
    ├── client.csr
    ├── client.key
    ├── server.crt
    ├── server.csr
    └── server.key

服务端配置

以 ubuntu 系统为例,记录一下简单的安装配置过程。

Docker 安装

$: apt-get -q update && \
apt remove docker docker-engine docker.io && \
apt install -y apt-transport-https ca-certificates curl software-properties-common && \
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - && \
apt-key fingerprint 0EBFCD88 && \
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" && \
apt update && \
apt install -y docker-ce 

Docker 配置

默认情况下,Docker 安装完成后,服务自动启动。不过默认的启动方式仅仅打开本地服务端口,无法远程访问。需要将服务启动方式更新为远端启动并设置证书验证功能。

将 CA/Server 端证书拷贝到远端机器目标路径/root/.docker/上。

查询启动项:

$: systemctl cat docker
# /lib/systemd/system/docker.service
...

修改启动项配置:

$: vim /lib/systemd/system/docker.service
...
ExecStart=
ExecStart=/usr/bin/dockerd --tlsverify --tlscacert=/root/.docker/ca.crt --tlscert=/root/.docker/server.crt --tlskey=/root/.docker/server.key -H=0.0.0.0:2376 -H fd:// --containerd=/run/containerd/containerd.sock
...

修改启动命令,重启服务。

$: systemctl daemon-reload #重新加载配置
$: systemctl restart docker #重启服务
$: systemctl enable docker #开机自启动
$: systemctl is-enabled docker #检查自启动状态
$: systemctl is-active docker  #检查服务状态

以上就完成了服务端的配置。因为 dockerd 会暴露 2376 端口,需要相应设置好机器的网络设置。

客户端配置

命令行访问

服务端完成配置后,客户端访问,就需要配置相应的证书参数:

$: docker --tlsverify \
  --tlscacert=out/ca.crt \
  --tlscert=out/client.crt \
  --tlskey=out/client.key \
  -H=$HOST:2376 version

默认配置

除了直接在命令行上设置证书参数外, 还可以将证书配置作为默认配置,设置到系统到环境变量中。

$: mkdir -pv ~/.docker/remote
$: cp out/ca.crt ~/.docker/remote/ca.pem
$: cp out/client.crt ~/.docker/remote/cert.pem
$: cp out/client.key ~/.docker/remote/key.pem
$: export DOCKER_CERT_PATH=~/.docker/remote/
$: export DOCKER_HOST=tcp://[YOUR.HOST.ADDRESS]:2376

完成以上环境变量设置后,就可以简化本地访问命令:

$: docker --tlsverify version

Serverless 是什么

直接利用 Docker 发布容器服务过程非常的简单也很有必要。不过,如今很多云服务商已经将这一过程产品化成了 Serverless 服务,即将以上的容器的发布过程服务化。不过,大部分云服务商提供的 Serverless 服务的实现都是基于 Kubernetes 平台。

至于在实际业务是否需要选择 Serverless 服务取代自行构建容器发布服务,我想关键取决于业务的实际需要。因为技术的每一次向上抽象,肯定会以牺牲部分功能为代价

阅读