Docker Java API创建容器并映射端口

本文最后更新于:几秒前

准备条件

确保已开启2375端口,若未开启,则按照如下步骤开启:

1
2
3
4
5
6
7
8
vim /lib/systemd/system/docker.service
# 修改如下行
# ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
# 改为如下
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock
# 重启
systemctl daemon-reload
systemctl restart docker

Maven加入依赖

在POM中加入如下依赖:

1
2
3
4
5
6
<!-- https://mvnrepository.com/artifact/com.github.docker-java/docker-java -->
<dependency>
<groupId>com.github.docker-java</groupId>
<artifactId>docker-java</artifactId>
<version>3.2.13</version>
</dependency>

这里使用的是3.2.13版本,可以自行选择版本,不同版本可能写法不同。

编写工具类

创建DockerUtils类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class DockerUtils {
// 定义dockerClient操作docker
private DockerClient dockerClient;
// 重新定义无参构造函数,初始化dockerCilent
DockerUtils(){
dockerClient = DockerClientBuilder.getInstance(DefaultDockerClientConfig.createDefaultConfigBuilder()
.withDockerHost("tcp://x.x.x.x:2375").build()).build();
}
// 或直接如下写法,这个版本如下方法已被弃用,不推荐,但是可以用
/*
DockerUtils(){
dockerClient = DockerClientBuilder.getInstance("tcp://x.x.x.x:2375").build();
}
*/
// region 编写操作Docker的方法
...
// endregion
}

接下来是操作Docker的方法,为了更加直观,就不写在一起了,在region块中编写就行

创建容器

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
/**
* 创建容器
* @param iamgeName 镜像名称
* @param portMap 端口映射Map,key是hostPort,value是containerPort
* @return 创建完的容器
*/
public CreateContainerResponse createCon(String iamgeName, Map<String,Port> portMap) {
// 创建容器需要使用的命令
CreateContainerCmd ccm = dockerClient.createContainerCmd(iamgeName);
// 封装端口映射
List<PortBinding> list = new ArrayList<>();
for (String hostPort : portMap.keySet()) {
// 暴露端口
ccm = ccm.withExposedPorts(ExposedPort.parse(portMap.get(hostPort) + "/tcp"));
// 绑定主机端⼝ -> docker容器端⼝
list.add(PortBinding.parse(hostPort + ":" + portMap.get(hostPort)));
}
HostConfig hostConfig = HostConfig.newHostConfig()
.withPortBindings(list);
// 执行创建命令
CreateContainerResponse container = ccm
.withHostConfig(hostConfig)
.exec();

return container;
}

容器基本操作

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
/**
* 开启容器
* @param id 容器ID
*/
public void startCon(String id) {
dockerClient.startContainerCmd(id).exec();
}

/**
* 关闭容器
* @param id 容器ID
*/
public void stopCon(String id) {
dockerClient.stopContainerCmd(id).exec();
}

/**
* 暂停容器
* @param id 容器ID
*/
public void pauseCon(String id) {
dockerClient.pauseContainerCmd(id).exec();
}

/**
* 重启容器
* @param id 容器ID
*/
public void restartCon(String id) {
dockerClient.restartContainerCmd(id).exec();
}

删除容器

1
2
3
4
5
6
7
8
9
/**
* 删除容器
* @param id 容器ID
*/
public void startCon(String id) {
// 删除之前请先调用关闭方法关闭容器!!!!!
DockerClient dockerClientByIp = DockerClientBuilder.getInstance("tcp://" + hostip + ":2375").build();
dockerClientByIp.startContainerCmd(id).exec();
}

将容器保存为镜像

1
2
3
4
5
6
7
8
9
10
/**
* docker容器commit为镜像
* @param containerID 容器id
* @param rep 镜像的仓库,就相当于【ubuntu:latest】中的【ubuntu】
* @param tag 镜像的标签,就相当于【ubuntu:latest】中的【latest】
* @return
*/
public void createImageByContainer(String containerID, String rep, String tag) throws Exception{
dockerClientByIp.commitCmd(containerID).withRepository(rep).withTag(tag).exec();
}

完整代码大放送

写到这怕是还会有人不知道完整的怎么写,我还是写出来吧。

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
public class DockerUtils {
// 定义dockerClient操作docker
private DockerClient dockerClient;
// 重新定义无参构造函数,初始化dockerCilent
DockerUtils(){
dockerClient = DockerClientBuilder.getInstance(DefaultDockerClientConfig.createDefaultConfigBuilder()
.withDockerHost("tcp://x.x.x.x:2375").build()).build();
}
// 或直接如下写法,这个版本如下方法已被弃用,不推荐,但是可以用
/*
DockerUtils(){
dockerClient = DockerClientBuilder.getInstance("tcp://x.x.x.x:2375").build();
}
*/
/**
* 创建容器
* @param iamgeName 镜像名称
* @param portMap 端口映射Map,key是hostPort,value是containerPort
* @return 创建完的容器
*/
public CreateContainerResponse createCon(String iamgeName, Map<String,Port> portMap) {
// 创建容器需要使用的命令
CreateContainerCmd ccm = dockerClient.createContainerCmd(iamgeName);
// 封装端口映射
List<PortBinding> list = new ArrayList<>();
for (String hostPort : portMap.keySet()) {
// 暴露端口
ccm = ccm.withExposedPorts(ExposedPort.parse(portMap.get(hostPort) + "/tcp"));
// 绑定主机端⼝ -> docker容器端⼝
list.add(PortBinding.parse(hostPort + ":" + portMap.get(hostPort)));
}
HostConfig hostConfig = HostConfig.newHostConfig()
.withPortBindings(list);
// 执行创建命令
CreateContainerResponse container = ccm
.withHostConfig(hostConfig)
.exec();

return container;
}
/**
* 开启容器
* @param id 容器ID
*/
public void startCon(String id) {
dockerClient.startContainerCmd(id).exec();
}

/**
* 关闭容器
* @param id 容器ID
*/
public void stopCon(String id) {
dockerClient.stopContainerCmd(id).exec();
}

/**
* 暂停容器
* @param id 容器ID
*/
public void pauseCon(String id) {
dockerClient.pauseContainerCmd(id).exec();
}

/**
* 重启容器
* @param id 容器ID
*/
public void restartCon(String id) {
dockerClient.restartContainerCmd(id).exec();
}
/**
* 删除容器
* @param id 容器ID
*/
public void startCon(String id) {
// 删除之前请先调用关闭方法关闭容器!!!!!
DockerClient dockerClientByIp = DockerClientBuilder.getInstance("tcp://" + hostip + ":2375").build();
dockerClientByIp.startContainerCmd(id).exec();
}/**
* docker容器commit为镜像
* @param containerID 容器id
* @param rep 镜像的仓库,就相当于【ubuntu:latest】中的【ubuntu】
* @param tag 镜像的标签,就相当于【ubuntu:latest】中的【latest】
* @return
*/
public void createImageByContainer(String containerID, String rep, String tag) throws Exception{
dockerClientByIp.commitCmd(containerID).withRepository(rep).withTag(tag).exec();
}
}

结语

Api中还有好多好多操作,各自在研究清楚基本操作之后,估计别的也就融汇贯通了,根据需求自己搭配吧


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!