Docker是目前很流行的一个平台工具。虽然我比较喜欢用命令行使用docker,但是用类似Portainer的可视化面板管理docker也是个不错的选择,检查docker的配置和状态都非常便捷。
Portainer不止能管理本机的docker,通过docker api ,进行一定的配置,可以通过网络远程连接和管理其它机器上的docker容器。具体教程可以参见以下两个链接:
Docker开启TLS和CA认证 配置Docker 远程访问TLS 认证 - 乌帮图
但是每次新建一台VPS后,按照这些命令输入来开启docker的远程访问实在是太繁琐了,于是我整理了一下相关命令,编制了一个脚本,一键执行来完成相关配置。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
#!/bin/bash
root_need(){
if [[ $EUID -ne 0 ]]; then
echo "Error:这个脚本必须以root身份运行!"
exit 1
fi
}
# 检查docker是否已经安装
if ! command -v docker &> /dev/null
then
echo "Docker未安装,开始安装Docker..."
# 安装Docker
wget -qO- get.docker.com | bash
systemctl enable docker
# 输出安装结果
docker --version
else
echo "Docker已经安装"
# 输出Docker版本
docker --version
fi
# 获取主机的 IP 地址
IP=$(curl -s http://ipv4.icanhazip.com)
# 设置证书目录
CERT_DIR="/root/docker_data/ca"
mkdir -p "$CERT_DIR"
# 生成 CA 证书
openssl genrsa -aes256 -passout pass:changepasswd -out "$CERT_DIR/ca-key.pem" 4096
openssl req -new -x509 -days 365 -key "$CERT_DIR/ca-key.pem" -passin pass:changepasswd -sha256 -out "$CERT_DIR/ca.pem" \
-subj "/C=US/ST=New York/L=New York/O=Example Company/OU=IT Department/CN=example.com/[email protected]"
# 生成服务器证书
openssl genrsa -out "$CERT_DIR/server-key.pem" 4096
openssl req -subj "/CN=$(hostname)" -sha256 -new -key "$CERT_DIR/server-key.pem" -out "$CERT_DIR/server.csr"
echo "subjectAltName = DNS:$(hostname),IP:$IP" > "$CERT_DIR/extfile.cnf"
read -p "你想添加一个受信任的域名吗? (y/n): " add_domain
if [ "$add_domain" == "y" ]; then
read -p "输入域名: " domain_name
echo "subjectAltName = DNS:$domain_name" >> "$CERT_DIR/extfile.cnf"
echo "将$domain_name添加到受信任域列表中"
else
echo "跳过将域添加到受信任域列表的步骤"
fi
echo "extendedKeyUsage = serverAuth" >> "$CERT_DIR/extfile.cnf"
openssl x509 -req -days 365 -sha256 -in "$CERT_DIR/server.csr" -CA "$CERT_DIR/ca.pem" -CAkey "$CERT_DIR/ca-key.pem" -CAcreateserial -out "$CERT_DIR/server-cert.pem" -extfile "$CERT_DIR/extfile.cnf" -passin pass:changepasswd
# 生成客户端证书
openssl genrsa -out "$CERT_DIR/client-key.pem" 4096
openssl req -subj '/CN=client' -new -key "$CERT_DIR/client-key.pem" -out "$CERT_DIR/client.csr"
echo "extendedKeyUsage = clientAuth" > "$CERT_DIR/client-extfile.cnf"
openssl x509 -req -days 365 -sha256 -in "$CERT_DIR/client.csr" -CA "$CERT_DIR/ca.pem" -CAkey "$CERT_DIR/ca-key.pem" -CAcreateserial -out "$CERT_DIR/client-cert.pem" -extfile "$CERT_DIR/client-extfile.cnf" -passin pass:changepasswd
# 生成 Docker 配置文件
cp /usr/lib/systemd/system/docker.service /usr/lib/systemd/system/docker.service.bak
sed -i "s|^ExecStart=.*$|ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2376 -H fd:// --containerd=/run/containerd/containerd.sock --tlsverify --tlscacert=${CERT_DIR}/ca.pem --tlscert=${CERT_DIR}/server-cert.pem --tlskey=${CERT_DIR}/server-key.pem|" /usr/lib/systemd/system/docker.service
# 重新加载 Docker 服务
systemctl daemon-reload
systemctl restart docker
# 检查 Docker 服务是否正常启动
if systemctl is-active --quiet docker; then
echo -e "Docker TLS配置已经成功完成。"
else
# Docker 服务启动失败, 恢复原配置并报错
echo "Error: docker服务启动失败。恢复到原来的配置..."
cp /usr/lib/systemd/system/docker.service.bak /usr/lib/systemd/system/docker.service
systemctl daemon-reload
systemctl restart docker
echo "docker服务已被恢复到原始配置。"
exit 1
fi
# 配置证书自动更新脚本
cat > $CERT_DIR/renewcert.sh <<'EOF'
#!/bin/bash
CURRENT_TIME=$(date +"%F %T")
# check if CA certificate is expired
if openssl x509 -checkend 1728000 -noout -in $(dirname "$0")/ca.pem; then
echo "[$CURRENT_TIME] CA certificate is still valid" >> $(dirname "$0")/crontab_log.txt
else
echo "[$CURRENT_TIME] CA certificate has expired. Renewing all certificates..." >> $(dirname "$0")/crontab_log.txt
# regenerate server and client certificates using existing CA
openssl req -new -x509 -days 365 -key "$(dirname "$0")/ca-key.pem" -passin pass:changepasswd -sha256 -out "$(dirname "$0")/ca.pem" \
-subj "/C=US/ST=New York/L=New York/O=Example Company/OU=IT Department/CN=example.com/[email protected]"
openssl x509 -req -days 365 -sha256 -in "$(dirname "$0")/server.csr" -CA "$(dirname "$0")/ca.pem" -CAkey "$(dirname "$0")/ca-key.pem" -CAcreateserial -out "$(dirname "$0")/server-cert.pem" -extfile "$(dirname "$0")/extfile.cnf" -passin pass:changepasswd
openssl x509 -req -days 365 -sha256 -in "$(dirname "$0")/client.csr" -CA "$(dirname "$0")/ca.pem" -CAkey "$(dirname "$0")/ca-key.pem" -CAcreateserial -out "$(dirname "$0")/client-cert.pem" -extfile "$(dirname "$0")/client-extfile.cnf" -passin pass:changepasswd
systemctl daemon-reload
systemctl restart docker
echo "[$CURRENT_TIME] All certificates have been renewed" >> $(dirname "$0")/crontab_log.txt
fi
EOF
# 配置脚本定时任务
chmod +x $CERT_DIR/renewcert.sh
crontab -l | { cat; echo "0 0 */15 * * bash $CERT_DIR/renewcert.sh"; } | crontab -
|
执行成功后应该如下图所示:

注意:
1、添加受信任域名适用于仅IPV6地址的VPS,如果VPS有ipv4公网地址可以不添加。
2、脚本适用于debian系统,其它系统请自行修改。
3、docker如果更新,/usr/lib/systemd/system/docker.service这个文件会重置,导致远程访问服务被关闭,有时间我再优化一下脚本吧,偷懒~
脚本执行完成后,docker api 运行于2376端口,如果有防火墙的话记得放行此端口。
把/root/docker_data/ca目录下的ca.pem, client-cert.pem, client-key.pem共三个文件下载下来。
打开portainer页面,进入Environment选项卡。

把上图进行配置即可连接docker环境了。