美文网首页Docker
使用Java操作Docker

使用Java操作Docker

作者: 攻城老狮 | 来源:发表于2021-08-07 17:45 被阅读0次

    本人在做实验过程中,需要通过Java程序部署docker容器。故尝试搜集资料,实现在Java端可以操作部署docker容器。过程中遇到一些bug和坑,在此总结,供有需要的童鞋使用。主体配置以Ubuntu16为例。后面会附加给出mac的配置说明。

    1. docker安装
    # 安装docker
    curl -sSL https://get.daocloud.io/docker | sh 
    
    # 查看是否安装成功
    docker version
    
    # 配置镜像加速
    vim /etc/docker/daemon.json
    
    {
        "registry-mirrors": [
            "https://registry.docker-cn.com"
        ]
    }
    
    # 重启docker服务
    systemctl restart docker
    systemctl enable docker
    
    # 查看是否配置成功
    docker info
    
    # 安装hello-world
    docker pull hello-world
    # 运行容器
    docker run hello-world
    
    1. 开放docker的对外访问端口2375(docker默认只能通过本地访问,我们需要开放其对外暴露的端口,供Java连接使用)
    # docker.service的位置可以通过 systemctl status docker.service 查看获取
    root@WebServer:~# systemctl status docker.service
    ● docker.service - Docker Application Container Engine
       Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
       Active: active (running) since Sat 2021-08-07 15:19:45 CST; 2h 11min ago
        
    # 编辑 docker.service文件
    vim /lib/systemd/system/docker.service
    
    # 替换文件中的ExecStart字段
    ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock
    
    # 使配置生效 需要重启docker服务
    systemctl daemon-reload
    systemctl restart docker
    
    # 再次运行该命令,可以看到已经暴露2375端口
    systemctl status docker.service
    
    1. Java端添加pom依赖
    <dependency>
      <groupId>com.github.docker-java</groupId>
      <artifactId>docker-java</artifactId>
      <version>3.0.14</version>
    </dependency>
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>1.2.4</version>
    </dependency>
    <dependency>
      <groupId>javax.ws.rs</groupId>
      <artifactId>javax.ws.rs-api</artifactId>
      <version>2.1</version>
    </dependency>
    <dependency>
      <groupId>org.glassfish.jersey.inject</groupId>
      <artifactId>jersey-hk2</artifactId>
      <version>2.26</version>
    </dependency>
    

    注意:测试过程中,我在项目中使用到了springboot和eureka,后两个依赖是为了解决和springboot中的依赖冲突问题而引入的依赖。另外,eureka中也会存在依赖冲突,需要再多做一个配置(如果项目中没有eureka依赖可以忽略下面的配置)

    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
      <exclusions>
        <!-- Causes java.lang.NoSuchMethodError: javax.ws.rs.core.Response$Status$Family.familyOf(I)Ljavax/ws/rs/core/Response$Status$Family; -->
        <exclusion>
          <groupId>javax.ws.rs</groupId>
          <artifactId>jsr311-api</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    
    1. 编写工具类,用于操作docker

    注:使用该工具类来操作docker,需要将main中的ip换为自己的服务器ip地址。通过运行该main方法,可以实现在远端服务器中创建一个hello-world的容器(远端服务器已经存在hello-world的镜像,没有镜像需要先拉取)

    package com.ustb.zerotrust.util;
    
    import com.alibaba.fastjson.JSONObject;
    import com.github.dockerjava.api.DockerClient;
    import com.github.dockerjava.api.command.CreateContainerResponse;
    import com.github.dockerjava.core.DockerClientBuilder;
    
    
    
    /*
    # 开放docker的对外服务端口
    vim /lib/systemd/system/docker.service
    
    ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock
    
    systemctl daemon-reload
    systemctl restart docker
     */
    
    public class DockerClientUtils {
        /**
         * 连接Docker服务器
         * @return
         */
        public DockerClient connectDocker(String dockerInstance){
            DockerClient dockerClient = DockerClientBuilder.getInstance(dockerInstance).build();
            dockerClient.infoCmd().exec();
            return dockerClient;
        }
    
        /**
         * 创建容器
         * @param client
         * @return
         */
        public CreateContainerResponse createContainers(DockerClient client, String containerName, String imageName){
            CreateContainerResponse container = client.createContainerCmd(imageName)
                    .withName(containerName)
                    .exec();
            return container;
        }
    
        /**
         * 启动容器
         * @param client
         * @param containerId
         */
        public void startContainer(DockerClient client,String containerId){
            client.startContainerCmd(containerId).exec();
        }
    
        /**
         * 启动容器
         * @param client
         * @param containerId
         */
        public void stopContainer(DockerClient client,String containerId){
            client.stopContainerCmd(containerId).exec();
        }
    
        /**
         * 删除容器
         * @param client
         * @param containerId
         */
        public void removeContainer(DockerClient client,String containerId){
            client.removeContainerCmd(containerId).exec();
    
        }
    
        public static void main(String[] args){
            DockerClientUtils dockerClientUtils =new DockerClientUtils();
            //连接Docker服务器
            DockerClient client = dockerClientUtils.connectDocker("tcp://远程服务器的ip:2375");
            //创建容器
            CreateContainerResponse container = dockerClientUtils.createContainers(client,"sny_hello","hello-world");
            //启动容器
            dockerClientUtils.startContainer(client,container.getId());
        }
    
    }
    
    1. 运行程序后,可以在服务器中查看是否成功创建容器
    docker ps -a
    
    1. 至此,完成了通过Java来操作docker的全过程,enjoy!!

    附:若只想操作本机的话,另外本机是mac系统,可以进行如下操作来开放2375对外暴露端口

    1. 首先,需要下载安装docker的mac版本,在此不做过多赘述,可以参考其他博客文章
    2. 可以用 socat 来 fork 一个端口出来执行
    docker run -it -d --name=socat -p 2375:2375 -v    /var/run/docker.sock:/var/run/docker.sock bobrik/socat TCP4-LISTEN:2375,fork,reuseaddr UNIX-CONNECT:/var/run/docker.sock
    
    1. 验证是否开放成功
    lsof -i:2375
    
    1. Java程序端,将ip地址变为本机地址 localhost 即可成功部署到本地容器

    相关文章

      网友评论

        本文标题:使用Java操作Docker

        本文链接:https://www.haomeiwen.com/subject/atjgvltx.html