Java API 操作Docker淺談

2023-12-12 12:00:44

背景:

使用com.github.docker-java庫可以很方便地在Java中操作Docker。下面是一個詳細的教學,包括建立映象、建立容器、啟動容器、停止容器和刪除容器的步驟以及每一步的說明。

前提:

首先,在你的Java專案中新增com.github.docker-java庫的依賴。你可以在你的構建工具(如Maven或Gradle)的組態檔中新增以下依賴項:

 
<dependency>
    <groupId>com.github.docker-java</groupId>
    <artifactId>docker-java</artifactId>
    <version>3.2.5</version>
</dependency>

建立Docker使用者端

import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.DockerClientBuilder;

DockerClient dockerClient = DockerClientBuilder.getInstance()
        .withDockerHost("tcp://localhost:2375")
        .withDockerCertPath("/path/to/cert")
        .withApiVersion("1.41")
        .build();

通過withDockerHost()方法設定了Docker守護行程的連線地址,withDockerCertPath()方法設定了TLS證書的路徑,withApiVersion()方法設定了Docker API的版本。最後,通過呼叫build()方法構建了一個DockerClient物件。

  1. DockerClientBuilder類是用於構建和設定DockerClient物件的構建器類。它提供了一組方法,用於設定與Docker守護行程通訊所需的引數和設定。

  2. getInstance()DockerClientBuilder類的靜態方法。通過呼叫該方法,可以獲取DockerClientBuilder的單例範例。

  3. DockerClientBuilder使用單例模式的設計,主要是為了提供對Docker守護行程的存取的全域性共用範例。這樣可以避免重複建立和銷燬DockerClientBuilder範例,提高了效能和效率。

  4. 使用DockerClientBuilder.getInstance()方法獲取DockerClientBuilder的範例後,可以通過該範例進行鏈式呼叫,設定各種與Docker守護行程通訊相關的引數和設定。

  5. 通過鏈式呼叫DockerClientBuilder的方法,可以設定例如Docker守護行程的連線地址、認證資訊、超時時間、TLS設定等。這些方法包括withDockerHost()withDockerCertPath()withDockerConfig()withApiVersion()等。

  6. 最後,通過呼叫build()方法,可以構建出一個DockerClient物件,用於與Docker守護行程進行互動。該物件可以執行各種Docker操作,如建立容器、啟動容器、構建映象等。

建立映象

import com.github.dockerjava.api.command.BuildImageResultCallback;

String dockerfilePath = "/path/to/dockerfile";
String imageName = "my-image";
String imageTag = "latest";

dockerClient.buildImageCmd()
    .withDockerfile(new File(dockerfilePath))
    .withTags(Collections.singleton(imageName + ":" + imageTag))
    .exec(new BuildImageResultCallback())
    .awaitCompletion();
  • withDockerfile(new File(dockerfilePath)):指定Dockerfile的路徑,用於構建映象。
  • withTags(Collections.singleton(imageName + ":" + imageTag)):指定映象的標籤。可以通過withTags方法傳遞一個包含映象標籤的集合,這裡使用Collections.singleton()方法建立一個只包含一個元素的集合 
  • withBaseDirectory(baseDirectory):設定基礎目錄,該目錄中包含了構建映象所需的所有檔案。與withDockerfile()一起使用時,會自動將基礎目錄中的Dockerfile關聯到構建命令中。
  • withNoCache():禁用快取,每次構建映象時都會重新執行所有命令,確保使用最新的檔案和依賴項。
  • withPull(pull):指定是否應該在構建之前拉取最新的基礎映象,預設為false,即不拉取。
  • withQuiet():設定靜默模式,不輸出構建映象的紀錄檔資訊。
  • withBuildArg(buildArg):使用Map<String, String>型別的引數設定構建引數。鍵值對錶示構建引數的名稱和值。
  • withLabels(labels):使用Map<String, String>型別的引數設定映象的標籤。鍵值對錶示標籤的鍵和值。
  • withBuildArgs(buildArgs):使用Map<String, String>型別的引數設定構建引數。與withBuildArg()類似,但可以一次設定多個構建引數。
  • withPull():設定是否應該在構建之前拉取最新的基礎映象。
  • withProgressHandler(progressHandler):設定用於處理構建映象進度的ProgressHandler

建立容器

import com.github.dockerjava.api.command.CreateContainerResponse;
import com.github.dockerjava.api.model.Bind;
import com.github.dockerjava.api.model.PortBinding;
import com.github.dockerjava.api.model.Volume;

String imageName = "my-image";
String containerName = "my-container";
int hostPort = 8080;
int containerPort = 80;
String volumeHostPath = "/host/path";
String volumeContainerPath = "/container/path";

CreateContainerResponse container = dockerClient.createContainerCmd(imageName)
    .withName(containerName)
    .withPortBindings(new PortBinding(
        new Binding(null, null, hostPort),
        new ExposedPort(containerPort)))
    .withBinds(new Bind(volumeHostPath, new Volume(volumeContainerPath)))
    .exec();

在上述程式碼中,imageName表示要使用的映象的名稱,containerName表示要建立的容器的名稱。hostPortcontainerPort分別表示主機埠和容器埠,用於進行埠對映。volumeHostPathvolumeContainerPath表示主機路徑和容器路徑,用於掛載卷。其中,CreateContainerResponse物件,包含了有關新建立容器的資訊,比如容器的ID、名稱等。以便接下來的啟動停止容器等操作

  • withName(containerName):為容器指定一個名稱。
  • withPortBindings(portBindings):指定容器的埠繫結。portBindings是一個PortBinding物件,用於將主機埠對映到容器內的埠。
  • withBinds(bindings):指定容器的卷繫結。bindings是一個Bind物件,用於將主機的目錄或卷掛載到容器內的路徑。

啟動容器

dockerClient.startContainerCmd(container.getId()).exec();

停止和刪除容器

dockerClient.stopContainerCmd(container.getId()).exec();
dockerClient.removeContainerCmd(container.getId()).exec();

在上述程式碼中,container.getId()獲取到的是容器的ID。