Docker是什么?
Docker是一个开源的容器化平台,用于构建、封装和运行应用程序。它使用了操作系统级别的虚拟化技术,将应用程序及其依赖项打包成轻量级、可移植的容器,实现了快速、可靠和可重复部署的应用环境。
Docker的核心概念
-
镜像(Image):镜像是Docker的基本构建单元。它是一个只读的模板,包含了运行应用程序所需的一切,包括代码、运行时环境、系统工具、库和依赖项等。通过镜像,我们可以创建容器实例。
-
容器(Container):容器是基于镜像创建的可运行实例。它是一个隔离的、独立的运行环境,具有自己的文件系统、进程空间和网络接口等。容器可以被启动、停止、删除,并且可以与其他容器和主机进行通信。
-
仓库(Repository):仓库是用于存储和管理镜像的地方。它可以本地存在,也可以是公共或私有的远程仓库。Docker Hub是一个知名的公共仓库,包含了大量的镜像供用户使用。
Docker的底层原理涉及到了几个关键的技术和组件:
-
Linux容器(Linux Containers):Docker利用Linux内核提供的容器化技术来创建和管理容器。Linux容器是一种轻量级的虚拟化技术,它利用Linux内核的功能,通过进程隔离、文件系统隔离、网络隔离等机制,使得应用程序可以在独立、安全的运行环境中运行,而与宿主机和其他容器隔离开来。
-
命名空间(Namespaces):命名空间是Linux内核提供的一种机制,用于隔离系统资源。Docker利用了多个命名空间(如PID命名空间、网络命名空间、挂载命名空间等)来实现容器之间的隔离。每个容器在各个命名空间中有自己独立的视图,使得容器可以拥有自己的进程树、网络栈、文件系统等。
-
控制组(cgroups):控制组是Linux内核提供的一种资源管理技术,用于限制和隔离资源的使用。Docker使用控制组来限制容器对CPU、内存、磁盘IO等资源的访问,确保容器之间资源的公平分配和隔离。
-
Union文件系统(UnionFS):Union文件系统是一种将多个文件系统联合挂载为单一文件系统的机制。Docker利用Union文件系统来实现镜像的分层和联合挂载,通过构建基于镜像的分层文件系统来提供容器的可写层。
-
Docker镜像(Docker Images):Docker镜像是容器的基础,它包含了运行容器所需的完整文件系统、运行时环境、应用程序和配置等。Docker镜像是通过Dockerfile定义的,Dockerfile是一个文本文件,其中包含了一系列构建镜像所需的指令和配置,比如基础镜像、环境变量、依赖项等。
-
Docker守护进程(Docker Daemon):Docker守护进程是运行在宿主机上的系统服务,负责接收和处理Docker客户端的请求,管理容器的创建、运行和销毁,以及镜像的构建、存储和分发。Docker守护进程使用Linux容器技术以及其他相关技术来实现容器的隔离、资源管理和文件系统等功能。
Docker的使用步骤
命令行用法
使用Docker的一般步骤如下:
1) 查看命令用法:
docker --help
查看具体指令的用法
docker run --help
-
从远程仓库拉取镜像
docker pull 镜像名:版本号
3) 启动镜像,创建容器
docker create 镜像名:版本号
-
查看容器状态
docker ps -a
-
启动容器
docker start 镜面名
-
查看执行日志
docker logs 容器名
-
删除容器实例
docker rm 容器名
-
删除镜像:
docker rmi 镜像名
挂载相关指令:
docker volume create
- 创建一个数据卷。docker volume ls
- 列出所有数据卷。docker volume rm
- 删除一个数据卷。docker run -v
- 挂载一个数据卷到容器中。docker run --mount
- 通过挂载选项挂载一个数据卷或主机目录到容器中。
示例:
bash
# 创建一个数据卷
docker volume create myvolume
# 运行容器并挂载数据卷
docker run -d -v myvolume:/path/to/mount somerepo/someimage
# 运行容器并挂载主机目录
docker run -d --mount type=bind,source=/host/path,target=/container/path somerepo/someimage
Java操作Docker
使用docker-Java:GitHub - docker-java/docker-java: Java Docker API Client
引入maven依赖:
XML
<!-- https://mvnrepository.com/artifact/com.github.docker-java/docker-java -->
<dependency>
<groupId>com.github.docker-java</groupId>
<artifactId>docker-java</artifactId>
<version>3.3.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.github.docker-java/docker-java-transport-httpclient5 -->
<dependency>
<groupId>com.github.docker-java</groupId>
<artifactId>docker-java-transport-httpclient5</artifactId>
<version>3.3.0</version>
</dependency>
DockerClientConfig:定义初始化的DockerClient的配置(类比MySQL链接、线程数配置)
DockerHttpClient:用于向docker发送请求的客户端
DockerClient:和Docker守护进程交互的SDK,封装了DockerHttpClient,提供了增啥改查接口了
Java SDK 使用操作如下:
java
private static DockerClient dockerClient = DockerClientBuilder.getInstance().build();
// 拉取镜像
public static void pull() throws InterruptedException {
String image = "nginx:latest";
PullImageCmd pullImageCmd = dockerClient.pullImageCmd(image);
// 拉取镜像
PullImageResultCallback pullImageResultCallback = new PullImageResultCallback() {
@Override
public void onNext(PullResponseItem item) {
System.out.println("下载镜像");
super.onNext(item);
}
};
pullImageCmd.exec(pullImageResultCallback).awaitCompletion();
System.out.println("下载成功");
}
// 创建容器
public static void create(String image) throws InterruptedException {
CreateContainerCmd createContainerCmd = dockerClient.createContainerCmd(image);
CreateContainerResponse createContainerResponse = createContainerCmd
.withCmd("echo","Hello Docker")
.exec();
System.out.println(createContainerResponse);
}
// 查看容器状态
public static void showAll(){
ListContainersCmd listContainersCmd = dockerClient.listContainersCmd();
List<Container> containerList = listContainersCmd.withShowAll(true).exec();
containerList.forEach(container -> {
System.out.println(container);
});
}
// 启动容器
public static void start(String containerId){
dockerClient.startContainerCmd(containerId).exec();
}
// 查看日志
public void logs(String containerId) throws InterruptedException {
// 异步
LogContainerResultCallback logContainerResultCallback = new LogContainerResultCallback(){
@Override
public void onNext(Frame item) {
System.out.println("日志:"+new String(item.getPayload()));
super.onNext(item);
}
};
dockerClient.logContainerCmd(containerId).withStdErr(true).withStdOut(true).exec(logContainerResultCallback).awaitCompletion();
}
// 删除容器
public void rm(String containerId){
dockerClient.removeContainerCmd(containerId).withForce(true).exec();
}
// 删除镜像
public void rmi(String image){
dockerClient.removeImageCmd(image).exec();
}