环境

虚拟机:ubuntu
主机:win10

步骤

本期将介绍java中使用dockerAPI的工具类封装以及常用的操作。
经过前两期,相信各位朋友都已经引入好docker的相关jar包了,那么就让我们以最简单的training/webapp为例,介绍一些基本操作吧!
首先笔者已通过命令行docker pull training/webapp拉取好相关的镜像了,当然通过dockerAPI拉取也是可以的,这将放在最后说明。如果拉取速度较慢,建议去设置镜像。
下面直接附上工具类:

package com.utils;

import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.command.CreateContainerResponse;
import com.github.dockerjava.api.command.DockerCmdExecFactory;
import com.github.dockerjava.api.model.ExposedPort;
import com.github.dockerjava.api.model.Info;
import com.github.dockerjava.api.model.Ports;
import com.github.dockerjava.core.DefaultDockerClientConfig;
import com.github.dockerjava.core.DockerClientBuilder;
import com.github.dockerjava.core.DockerClientConfig;
import com.github.dockerjava.jaxrs.JerseyDockerCmdExecFactory;
import net.sf.json.JSONObject;

/**
 * @author Tiecheng Jia
 * @date 2020/2/15 9:45
 * @instruction docker连接、操作工具类
 */
public class DockerClientUtil {
    public DockerClient connectDocker() {
        /**
         * 连接docker服务器(安全认证方式)
         * @return DockerClient
         * @param  dockerHost:docker服务器ip地址和端口号
         *         dockercertPath:windows的密钥文件存放地址
         *         dockerconfig:同Path,配置地址
         *         apiVersion:dockerAPI的版本,通过docker version命令在docker服务器上获取版本号
         */
        DockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder().withDockerTlsVerify(true)
                .withDockerCertPath("D:/docker-java/").withDockerHost("tcp://192.168.184.128:2375")
                .withDockerConfig("D:/docker-java/").withApiVersion("1.40").withRegistryUrl("https://index.docker.io/v1/")
                .withRegistryUsername("dockeruser").withRegistryPassword("ilovedocker")
                .withRegistryEmail("dockeruser@github.com").build();
        DockerCmdExecFactory dockerCmdExecFactory =  new JerseyDockerCmdExecFactory()
                .withReadTimeout(1000)
                .withConnectTimeout(1000)
                .withMaxTotalConnections(100)
                .withMaxPerRouteConnections(10);
        // 连接
        DockerClient dockerClient = DockerClientBuilder.getInstance(config).withDockerCmdExecFactory(dockerCmdExecFactory).build();
        Info info = dockerClient.infoCmd().exec();
        JSONObject jsonObject = JSONObject.fromObject(info);
        System.out.println("docker的环境信息如下:=================");
        System.out.println(jsonObject.toString());
        return dockerClient;
    }
    /**
     * 创建容器
     * @param client,imageName
     * @return
     */
    public CreateContainerResponse createContainers(DockerClient client, String imageName){
        // 暴露的端口
        ExposedPort tcp80 = ExposedPort.tcp(5000);
        Ports portBindings = new Ports();
        // 绑定主机随机端口 -> docker服务器5000端口
        portBindings.bind(tcp80, Ports.Binding.empty());
        CreateContainerResponse container = client.createContainerCmd(imageName)
                .withPortBindings(portBindings)
                .withExposedPorts(tcp80).exec();
        return container;
    }

    /**
     * 启动容器
     * @param client,containerId
     * @param containerId
     */
    public void startContainer(DockerClient client,String containerId){
        client.startContainerCmd(containerId).exec();
    }

    /**
     * 关闭容器
     * @param client,containerId
     * @param containerId
     */
    public void stopContainer(DockerClient client,String containerId){
        client.stopContainerCmd(containerId).exec();
    }

    /**
     * 删除容器
     * @param client,containerId
     * @param containerId
     */
    public void removeContainer(DockerClient client,String containerId){
        client.removeContainerCmd(containerId).exec();
    }

    /**
     * 删除镜像
     * @param client,imageId
     * @return
     */
    public void removeImage(DockerClient client,String imageId){
        client.removeImageCmd(imageId).exec();
    }

}

可以看见,我们这里封装了包括创建、开始、停止、删除容器和删除镜像五个方法。
下面上测试:

    @Test
    public void CreateContainer() {
        DockerClientUtil dockerClientUtil = new DockerClientUtil();
        // 连接获得client对象
        DockerClient client = dockerClientUtil.connectDocker();
        // 创建容器
        CreateContainerResponse container = dockerClientUtil.createContainers(client,"6fae60ef3446");
        // 开始容器
        client.startContainerCmd(container.getId()).exec();
    }

在该方法中,我们将进行创建容器和开始容器的操作,下面我们运行该方法,可以看见输出了如下信息:

docker的环境信息如下:=================
{"IPv4Forwarding":true,"NCPU":4,"NEventsListener":0,"NFd":23,"NGoroutines":37,"architecture":"x86_64","bridgeNfIp6tables":true,"bridgeNfIptables":true,"clusterAdvertise":"","clusterStore":"","containers":0,"containersPaused":0,"containersRunning":0,"containersStopped":0,"cpuCfsPeriod":true,"cpuCfsQuota":true,"cpuSet":true,"cpuShares":true,"debug":true,"discoveryBackend":"","dockerRootDir":"/var/lib/docker","driver":"overlay2","driverStatuses":[["Backing Filesystem","extfs"],["Supports d_type","true"],["Native Overlay Diff","true"]],"executionDriver":"","experimentalBuild":false,"httpProxy":"","httpsProxy":"","id":"ZKNS:CDJA:GJ3G:6YJ3:YADZ:WVBU:SERB:FNBY:Z4DO:YOHK:G62G:VZ6V","images":5,"indexServerAddress":"https://index.docker.io/v1/","initPath":"","initSha1":"","kernelVersion":"4.15.0-45-generic","labels":[],"loggingDriver":"json-file","memTotal":4112039936,"memoryLimit":true,"name":"ubuntu","noProxy":"","oomKillDisable":true,"oomScoreAdj":0,"operatingSystem":"Ubuntu 16.04.6 LTS","osType":"linux","plugins":{"Volume":["local"],"Network":["bridge","host","ipvlan","macvlan",null,"overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","local","logentries","splunk","syslog"]},"registryConfig":{"indexConfigs":{"docker.io":{"mirrors":["http://hub-mirror.c.163.com/"],"name":"docker.io","official":true,"secure":true}},"insecureRegistryCIDRs":["127.0.0.0/8"],"mirrors":["http://hub-mirror.c.163.com/"]},"serverVersion":"19.03.4","sockets":[],"swapLimit":false,"systemStatus":[],"systemTime":"2020-02-14T22:21:10.913398917-08:00"}

docker连接上输出的。

3 > POST https://192.168.184.128:2375/v1.40/containers/create
3 > Accept: application/json
3 > Content-Type: application/json
{"Image":"6fae60ef3446","Volumes":{},"ExposedPorts":{"5000/tcp":{}},"HostConfig":{"PortBindings":{"5000/tcp":[{"HostIp":"","HostPort":""}]}}}

创建容器输出的,其中显示了镜像的5000端口随机映射到本机端口。

4 < 201
4 < Api-Version: 1.40
4 < Content-Length: 88
4 < Content-Type: application/json
4 < Date: Sat, 15 Feb 2020 06:21:11 GMT
4 < Docker-Experimental: false
4 < Ostype: linux
4 < Server: Docker/19.03.4 (linux)
{"Id":"207d69b5a9636c612640e1164518e0aea65d3e25e20eb1b9f543908bf84fb6b8","Warnings":[]}

创建的容器ID为207d69b5a9636c612640e1164518e0aea65d3e25e20eb1b9f543908bf84fb6b8

5 > POST https://192.168.184.128:2375/v1.40/containers/207d69b5a9636c612640e1164518e0aea65d3e25e20eb1b9f543908bf84fb6b8/start
5 > Accept: application/json

开始容器输出的。
让我们看下虚拟机中,容器是否创建并开启呢?
在这里插入图片描述
可以看见确实开启,并且容器的5000端口映射到了虚拟机的32774端口,我们访问一下看,确实可以访问,最简单的hello-world。
在这里插入图片描述
下面尝试下停止和删除容器。
停止容器:

    @Test
    public void StopContainer() {
        DockerClientUtil dockerClientUtil = new DockerClientUtil();
        DockerClient client = dockerClientUtil.connectDocker();
        client.stopContainerCmd("207d69b5a9636c612640e1164518e0aea65d3e25e20eb1b9f543908bf84fb6b8").exec();
    }

在这里插入图片描述
确实停止了。
删除容器:

    @Test
    public void DeleteContainer() {
        DockerClientUtil dockerClientUtil = new DockerClientUtil();
        DockerClient client = dockerClientUtil.connectDocker();
        client.removeContainerCmd("207d69b5a9636c612640e1164518e0aea65d3e25e20eb1b9f543908bf84fb6b8").exec();
    }

在这里插入图片描述
确实删除了。
下面将删除镜像:

    @Test
    public void RemoveImage() {
        DockerClientUtil dockerClientUtil = new DockerClientUtil();
        DockerClient client = dockerClientUtil.connectDocker();
        client.removeImageCmd("6fae60ef3446").exec();
    }

在这里插入图片描述
可以看见先前training/webapp ID:6fae60ef3446的镜像确实被删除了。
经过以上测试,可以确认我们的工具类使用没有问题,那么说到前文的使用API拉取镜像,相信经过以上测试的朋友应该已经知道了,那就是通过client.pullImageCmd().exec();来拉取相应的镜像啦。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐