Docker启用TLS
前言
最近在开发人工智能平台,需要远程操控docker ,正好docker提供了 Remote API。普通的没有任何安全防护,同时也提供TLS的安全认证方式,为了安全我们采用TLS方式,同时把操作过程记录下来
环境
CentOS7、docker ce 20.10.9
安装docker
通过yum 命令安装
开启 Remote API
为了安全考虑docker默认是不开启远程访问,所以需要配置
在
/etc/docker/daemon.json
文件中添加以下配置1
2
3{
"hosts": ["tcp://0.0.0.0:2375", "unix:///var/run/docker.sock"]
}修改docker.service文件,把
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
修改为ExecStart=/usr/bin/dockerd
1
2#ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecStart=/usr/bin/dockerd重启docker服务
1
2systemctl deamon-reload
systemctl restart docker测试
在浏览器输入docker服务器的IP加端口就可以访问
开启安全的远程访问
在docker服务器上,生成 CA 私钥和公钥
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24$ openssl genrsa -aes256 -out ca-key.pem 4096
Generating RSA private key, 4096 bit long modulus
............................................................................................................................................................................................++
........++
e is 65537 (0x10001)
Enter pass phrase for ca-key.pem:
Verifying - Enter pass phrase for ca-key.pem:
$ openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem
Enter pass phrase for ca-key.pem:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:Queensland
Locality Name (eg, city) []:Brisbane
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Docker Inc
Organizational Unit Name (eg, section) []:Sales
Common Name (e.g. server FQDN or YOUR name) []:$HOST
Email Address []:Sven@home.org.auPS:$HOST就是当前docker服务器的IP
有了 CA,可以创建服务器密钥和证书签名请求 (CSR)
1
2
3
4
5
6
7$ openssl genrsa -out server-key.pem 4096
Generating RSA private key, 4096 bit long modulus
.....................................................................++
.................................................................................................++
e is 65537 (0x10001)
$ openssl req -subj "/CN=$HOST" -sha256 -new -key server-key.pem -out server.csr用 CA 签署公钥
1
2echo subjectAltName = DNS:$HOST,IP:10.10.10.20,IP:127.0.0.1 >> extfile.cnf
echo extendedKeyUsage = serverAuth >> extfile.cnf生成服务端签名证书
1
2
3
4
5
6
7$ openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem \
-CAcreateserial -out server-cert.pem -extfile extfile.cnf
Signature ok
subject=/CN=your.host.com
Getting CA Private Key
Enter pass phrase for ca-key.pem:创建客户端密钥和证书签名请求
1
2
3
4
5
6
7
8
9
$ openssl genrsa -out key.pem 4096
Generating RSA private key, 4096 bit long modulus
.........................................................++
................++
e is 65537 (0x10001)
$ openssl req -subj '/CN=client' -new -key key.pem -out client.csr为生成客户端签名证书,创建一个新的扩展配置文件
1
echo extendedKeyUsage = clientAuth > extfile-client.cnf
生成客户端签名证书
1
2
3
4
5
6$ openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem \
-CAcreateserial -out cert.pem -extfile extfile-client.cnf
Signature ok
subject=/CN=client
Getting CA Private Key
Enter pass phrase for ca-key.pem:删除证书签名和扩展配置文件
1
rm -v client.csr server.csr extfile.cnf extfile-client.cnf
在在`/etc/docker/daemon.json 文件中配置TLS
1
2
3
4
5
6
7
8{
"hosts": ["tcp://0.0.0.0:2375", "unix:///var/run/docker.sock"],
"tls": true,
"tlsverify": true,
"tlscacert": "/etc/docker/ca.pem",
"tlscert": "/etc/docker/server-cert.pem",
"tlskey": "/etc/docker/server-key.pem"
}重启启动docker服务
1
systemctl restart docker
用
curl
命令来验证1
curl https://192.168.56.105:2375/info --cert /etc/docker/cert.pem --key /etc/docker/key.pem --cacert /etc/docker/ca.pem
docker java 客户端来调用docker
复制
ca.pem
,cert.pem
,key.pem
三个文件到客户端我们把这三个文件复制到开发机器的
D:\\docker\\
目录下,需要注意,不要修改这三个文件的名称创建maven工程并引人docker-java的坐标
编写测试代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22public class DockerClientDemo {
public static void main(String[] args) {
DockerClient dockerClient = getDC();
List<Image> images = dockerClient.listImagesCmd().exec();
images.forEach(item -> System.out.println("id : " + item.getId()));
}
public static DockerClient getDC() {
DockerClientConfig dockerClientConfig = DefaultDockerClientConfig.createDefaultConfigBuilder()
.withApiVersion("1.41")
.withDockerTlsVerify(true)
.withDockerCertPath("D:\\docker\\")
.withDockerHost("tcp://192.168.56.105:2375").build();
DockerClient dockerClient = DockerClientBuilder.getInstance(dockerClientConfig).build();
return dockerClient;
}
}