使用docker-java远程管理docker精进版(二)
在前一篇小编介绍了Ubuntu下安装docker如何进行端口绑定,阐述了直接这样绑定端口容易造成入侵问题,今天我们就来使用认证书来解决这个问题。 现在Docker Java API默认的连接方式就是基于签名证书认证的。如果我们的Docker没有签名认证过,Docker Java是无法连接到Docker的,也就是说,要想连Docker,必须做签名认证。证书的生成详细信息。移步官网Pr...
在前一篇小编介绍了Ubuntu下安装docker如何进行端口绑定,阐述了直接这样绑定端口容易造成入侵问题,今天我们就来使用认证书来解决这个问题。
现在Docker Java API默认的连接方式就是基于签名证书认证的。如果我们的Docker没有签名认证过,Docker Java是无法连接到Docker的,也就是说,要想连Docker,必须做签名认证。
证书的生成详细信息。移步官网
Protect the Docker daemon socket(https://docs.docker.com/engine/security/https/#create-a-ca-server-and-client-keys-with-openssl)。其原理是通过指定tlsverify标志并将Docker的tlscacert标志指向受信任的CA证书来启用TLS。在守护进程模式下,它只允许来自由该CA签名的证书认证的客户端的连接。 在客户端模式下,它将只连接到具有由该CA签名的证书的服务器。
现在我们将认证流程简化一下。
下列一系列的命令,让我们可以生成认证证书。注意:下面这些TLS命令将只在Linux上生成一组有效的证书。 macOS附带的OpenSSL版本与Docker所需的证书不兼容。我没有Mac笔记本,所以没有机会试一试,请大家自行试试吧。
第一步:
首先,我们需要选择一个放证书的文件夹,这个文件夹很多文章,包括官网都建议创建一个.docker文件夹,我个人认为,这个文件夹在哪里不重要,只要能保证服务器安全,防火墙有效,就可以了。
我在/home/user/下面创建了一个/certs/文件夹。用$pwd,就可以看到该文件夹是/home/user/certs/。转到该文件夹,
执行如下命令:$ openssl genrsa -aes256 -out ca-key.pem 4096,
生成CA私钥,并设置pass phrase,我设置的就是123456,比较简单,因为是测试环境。但是要记住这个密码,后边命令还会用到。
再输入:$ openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem,
生成CA公钥,也就是证书。还让你输入国家名,省名啥的,这些都是随便填一个就行,因为密钥算法会把这些信息加密进密钥的。值得一提的是Common Name,说是要你填写,server FQDN或your name,意味着可以随便写,但是我在这里建议,写Docker所在服务器的IP,这个很重要。这个IP后边还会用到,我这里是192.168.99.101,在生产环境下,用使用你docker宿主机的DNS name替换下面的填入Common name,如api.google.com等,这个IP不难拿到,你用$ifconfig命令就可以拿到。我在这里填CDH是错误的
第二步:
生成服务器私钥,命令如下:
$openssl genrsa -out server-key.pem 4096
再用私钥生成服务器公钥请求文件,也就是证书,命令如下:
$openssl req -subj "/CN=192.168.99.101" -sha256 -new -key server-key.pem -out server.csr,
这里的192.168.99.101同样是Docker所在服务器的IP,你不要照抄,用自己的Docker服务器替换上去。
下面我们可以用CA来签署证书了。这里我们可以填写IP地址或则DNS name,如,我们需要允许10.10.10.20和127.0.0.1连接:
$echo subjectAltName = IP:10.10.10.20, IP:127.0.0.1 > extfile.cnf,
上述命令有点像一个过滤器,如果地址填的不全,远程API就无法访问该Docker,那么我们就把,地址填的全一些,我的命令是这样滴:
$echo subjectAltName = DNS:192.168.99.101, IP: 192.168.99.101, IP: 192.168.1.101, IP:0.0.0.0, IP:127.0.0.1 > extfile.cnf
然后,将上述多个生成信息,写入文件。用如下命令。
$openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -extfile extfile.cnf
再看客户端私钥:
$openssl genrsa -out key.pem 4096
下一步再生成客户端证书请求文件:
$openssl req -subj '/CN=client' -new -key key.pem -out client.csr
用CA为客户端签署证书文件:
$openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -extfile extfile.cnf
这时候,还需要输入你的密码,我的密码是123456,输上去即可。
第三步:使用证书
还是要回到我们上文提到的docker.service文件中,那个文件里需要添加上你为它生成的文件的路径和文件名。如下图红色方框所示:
字比较小啊看不清。嗯,我们来把它放大:
ExecStart=/usr/bin/dockerd -D --tlsverify=true --tlscert=/home/user/certs/server-cert.pem --tlskey=/home/user/certs/server-key.pem --tlscacert=/home/user/certs/ca.pem -H tcp://0.0.0.0:2376 -H fd://
注意到没有,我这里把所有的认证文件都加上了准确的路径。用Ctrl+X,按Y保存退出。
再重新装载配置文件
$sudo systemctl daemon-reload,回车
$sudo service docker restart,回车
$sudo service docker status,来查看进程状态。
第四步:客户端签名证书设置
在home/user/certs文件夹下下载几个文件,放到我的本地机上d:/data/certs/文件夹下,如下图蓝色方框部分,这样Java客户端就可以通过这些证书来访问Docker服务器了
第五步:使用证书来访问
程序代码段
public class DockerJavaClient {
public DockerJavaClient() {
}
public static void main(String[] args) {
DockerCmdExecFactory dockerCmdExecFactory = new JerseyDockerCmdExecFactory().withReadTimeout(1000)
.withConnectTimeout(1000).withMaxTotalConnections(100).withMaxPerRouteConnections(10);
DockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder().withDockerTlsVerify(true)
.withDockerCertPath("D:/Data/cert/").withDockerHost("tcp://192.168.99.101:2376")
.withDockerConfig("D:/Data/cert/").withApiVersion("1.23").withRegistryUrl("https://index.docker.io/v1/")
.withRegistryUsername("username").withRegistryPassword("password")
.withRegistryEmail("email").build();
//根据自己的情况,按需填写
DockerClient dockerClient = DockerClientBuilder.getInstance(config)
.withDockerCmdExecFactory(dockerCmdExecFactory).build();
CreateContainerResponse container1 = dockerClient.createContainerCmd("tomcat:latest").exec();
dockerClient.startContainerCmd(container1.getId()).exec();
}
至此,我们的Docker访问就配置成功了。
更多推荐
所有评论(0)