Docker
什么是 Docker?
Docker 是一个开源的应用容器引擎,可以轻松的为任何应用创建一个轻量级的、可移植的、自给自足的容器。开发者在本地编译测试通过的容器可以批量地在生产环境中部署,包括VMs(虚拟机)、bare metal、OpenStack 集群和其他的基础应用平台。
简单的理解,Docker类似于集装箱,各式各样的货物,经过集装箱的标准化进行托管,而集装箱和集装箱之间没有影响。也就是说,Docker平台就是一个软件集装箱化平台,这就意味着我们自己可以构建应用程序,将其依赖关系一起打包到一个容器中,然后这容器就很容易运送到其他的机器上进行运行,而且非常易于装载、复制、移除,非常适合软件弹性架构。
实际例子:
一个货轮上可以有很多集装箱,不同集装箱中装着不同的东西,他们是相互隔离,互不影响的。如果货轮上的东西不用单独集装箱去装载,将所有东西都放在货轮上,在卸载货物的时候,又要重新理一遍,进行分类。
Docker 和 虚拟机的区别
特性 | 容器 | 虚拟机 |
---|---|---|
启动 | 秒级 毫秒级 | 分钟级 |
硬盘使用 | 一般为MB | 一般为 |
性能 | 接近原生 | 若雨 |
系统支持量 | 单机支持上千个容器 | 一般几十个 |
为什么要用 Docker 容器技术?
为了进一步提升系统的安全性,把不同的程序和宿主机进行隔离,使得某个程序(应用)的执行不会影响到系统本身。
Docker 技术可以实现程序和宿主机的隔离。
作为一种新兴的虚拟化方式,Docker 跟传统的虚拟化方式相比具有众多的优势。
1.更高效的利用系统资源。
由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,Docker 对系统资源的利用率更高。无论是应用执行速度、内存损耗或者文件存储速度,都要比传统虚拟机技术更高效。因此,相比虚拟机技术,一个相同配置的主机,往往可以运行更多数量的应用。
2.更快速的启动时间
传统的虚拟机技术启动应用服务往往需要数分钟,而 Docker 容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。
3.一致的运行环境
开发过程中一个常见的问题是环境一致性问题。由于开发环境、测试环境、生产环境不一致,导致有些 bug 并未在开发过程中被发现。而 Docker 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现 「这段代码在我机器上没问题啊」 这类问题。
4.持续交付和部署
对开发和运维(DevOps)人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。
使用 Docker 可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过 Dockerfile 来进行镜像构建,并结合 持续集成(Continuous Integration) 系统进行集成测试,而运维人员则可以直接在生产环境中快速部署该镜像,甚至结合 持续部署(Continuous Delivery/Deployment) 系统进行自动部署。
而且使用 Dockerfile 使镜像构建透明化,不仅仅开发团队可以理解应用运行环境,也方便运维团队理解应用运行所需条件,帮助更好的生产环境中部署该镜像。
5.更轻松的迁移
由于 Docker 确保了执行环境的一致性,使得应用的迁移更加容易。Docker 可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运行结果是一致的。因此用户可以很轻易的将在一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。
6.更轻松的维护和扩展
Docker 使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。此外,Docker 团队同各个开源项目团队一起维护了一大批高质量的 官方镜像,既可以直接在生产环境使用,又可以作为基础进一步定制,大大的降低了应用服务的镜像制作成本。
Docker 基本概念
镜像:用来创建容器的安装包,可以理解为给电脑安装操作系统的系统镜像。
容器:通过镜像来创建的一套运行环境,一个容器里可以运行多个程序,可以理解为一个电脑实例。
Dockerfile:制作镜像的文件,可以理解为制作镜像的一个清单。
镜像仓库:存放镜像的仓库,用户可以从仓库下载现成的镜像,也可以把做好的镜像放到仓库里。
推荐使用 docker 官方的镜像仓库:https://hub.docker.com/search?q=nginx
Docker 架构
Docker 使用客户端-服务器 (C/S) 架构模式,使用远程API来管理和创建Docker容器。Docker 容器通过 Docker 镜像来创建。容器与镜像的关系类似于面向对象编程中的对象与类。
Docker | 面向对象 |
---|---|
镜像 | 类 |
容器 | 对象 |
镜像(lmage):Docker镜像(lmage),就相当于是个root文件系统。比如官方镜像Ubuntu:16.04就包含了完整的一套Ubuntu16.04最小系统的root文件系统。
容器(Container):镜像(lmage)和容器(Container)的关系,就像是面向对象程序设计中的类和对象一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
仓库(Repository):仓库可看成一个代码控制中心,用来保存镜像。
参考文章:
https://www.cnblogs.com/codelove/p/10030439.html
Docker 入门到实战教程(一)介绍Docker-CSDN博客
Docker容器化技术(从零学会Docker)_容器技术 docker-CSDN博客
Docker 安装
1. 下载VMware
2. 下载Ubuntu镜像
镜像下载网址:Ubuntu 18.04.6 LTS (Bionic Beaver)
3. 创建虚拟机
1、选择虚拟机硬件兼容性
2、选择Ubuntu镜像文件
3、个性化设置
4、修改虚拟机保存的位置
5、选择虚拟机的配置
中间一直点下一步知道这个磁盘容量
6、完成创建 等待安装
4. 配置Ubuntu系统相关配置
a. 修改语言为简体中文
按win键 点击语言支持
输入源换成拼音 shift切换 中文和拼音
b. 调整时间
5. 安装Docker
切换管理员身份 输入命令安装docker:
sudo apt install docker.io
输入命令查看安装是否完成
docker -v
安装查看网络所需的工具
查看当前ip
6. 设置镜像加速器
阿里云官网:阿里云-计算,为了无法计算的价值
设置完成
7. 测试docker
输入命令 拉取镜像
sudo docker run hello-world
拉取镜像成功
8. 安装 ssh 服务器
sudo apt-get install openssh-server、
输入命令查看配置ssh是否成功
ps -ef | grep ssh
9. 更新本地软件的安装包的信息
a. 安装 jdk 8
sudo apt install openjdk-8-jdk
b. 查看 jdk 版本信息
java -version
c. 安装maven
sudo apt install maven
查看maven 版本信息
10. 常见 Docker 命令
a. 查看命令用法
docker --help
查看具体子命令的用法:
docker run --help
b. 从远程仓库拉取现成的镜像
docker pull [OPTIONS] NAME[:TAG|@DIGEST]
示例:
docker pull hello-world
c. 根据镜像创建容器实例:
docker create [OPTIONS] IMAGE [COMMAND] [ARG...]
启动实例,得到容器实例 containerId:
sudo docker create hello-world
d. 查看容器状态:
docker ps
e. 启动容器:
docker start [OPTIONS] CONTAINER [CONTAINER...]
启动示例:
sudo docker start beautiful_cartwright
f. 查看日志:
docker logs [OPTIONS] CONTAINER
查看日志实例:
sudo docker logs beautiful_cartwright
g. 删除容器实例:
docker rm [OPTIONS] CONTAINER [CONTAINER...]
删除示例:
sudo docker rm beautiful_cartwright
h. 查看镜像:
docker imgages
查看镜像实例:
sudo docker images
i. 删除镜像:
docker rmi --help
示例,强制删除:
sudo docker rmi hello-world -f
再次查看镜像
Java 远程操作 Docker
前置准备
使用 Docker-Java:GitHub - docker-java/docker-java: Java Docker API Client
官方入门:docker-java/docs/getting_started.md at main · docker-java/docker-java · GitHub
maven仓库: https://mvnrepository.com/
引入依赖:
https://mvnrepository.com/artifact/com.github.docker-java/docker-java/3.3.0
<!-- 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>
Docker 相关配置类:
DockerClientConfig:用于定义初始化 DockerClient 的配置(类比 MySQL 的连接、线程数配置)
DockerHttpClient:用于向 Docker 守护进程(操作 Docker 的接口)发送请求的客户端,低层封装(不推荐使用),你要自己构建请求参数(简单地理解成 JDBC)
DockerClient(推荐):才是真正和 Docker 守护进程交互的、最方便的 SDK,高层封装,对 DockerHttpClient 再进行了一层封装(理解成 MyBatis),提供了现成的增删改查
IEDA远程连接 操作Docker 的第一种方式
1.先查看 Docker ip 地址
2.配置远程SSH
识别根路径
新建一个文件夹 将本地代码同步到这个文件夹下
同步代码 到上述文件夹中
点击上述第3步后 点击同步所有文件
查看同步的文件
设置自动上传
IEDA远程连接 操作Docker 的第二种方式
第一种 远程连接 Docker 的方式特点:
代码存在本地,本地写好以后,通过同步代码到远程服务器,需要很多操作,可能会遗漏步骤。
第二种 远程连接 Docker 的方式特点:
直接建立远程连接 ,运行代码,存储代码都在服务器上, 代码不再是存在本地。本地只负责编写代码。所有操作都是在服务器上执行。
SSH相关博客:什么叫SSH?原理详解,看这一篇就够了!-CSDN博客
通过 SSH 建立远程连接
选择IDEA安装路径
等待下载完成 此步骤是直接将 idea 安装到虚拟机上
安装好 IDEA 后 随便创建一个文件 在查看是否同步文件
查看 已经在此目录下 创建aa.txt
创建Docker Demo
-Djdk.lang.Process.launchMechanism=vfork
启动失败 权限不足
解决方案:
- 增加权限
- 重启虚拟机!重启远程开发环境!重启程序!
常规操作
ⅰ. 拉取镜像:
DockerClient dockerClient = DockerClientBuilder.getInstance().build();
String image = "nginx:latest";
PullImageCmd pullImageCmd = dockerClient.pullImageCmd(image);
PullImageResultCallback pullImageResultCallback = new PullImageResultCallback() {
@Override
public void onNext(PullResponseItem item) {
System.out.println("下载镜像:" + item.getStatus());
super.onNext(item);
}
};
pullImageCmd
.exec(pullImageResultCallback)
.awaitCompletion();
System.out.println("下载完成");
查看拉取的镜像
ⅱ. 创建容器
CreateContainerCmd containerCmd = dockerClient.createContainerCmd(image);
CreateContainerResponse createContainerResponse = containerCmd
.withCmd("echo", "Hello Docker")
.exec();
System.out.println(createContainerResponse);
ⅲ. 查看容器
// 查看容器状态
ListContainersCmd listContainersCmd = dockerClient.listContainersCmd();
List<Container> containers = listContainersCmd
.withShowAll(true)
.exec();
for (Container container : containers) {
System.out.println(container);
}
ⅳ. 启动容器
dockerClient.startContainerCmd(containerId);
启动前:
启动后:
显示结果: nginx 没有开守护线程 没启动 不影响后续操作
ⅴ. 查看日志:
// 查看日志
LogContainerResultCallback logContainerResultCallback = new LogContainerResultCallback() {
@Override
public void onNext(Frame item) {
System.out.println(item.getStreamType());
System.out.println("日志:" + new String(item.getPayload()));
super.onNext(item);
}
};
// 阻塞等待日志输出
dockerClient.logContainerCmd(containerId)
.withStdErr(true)
.withStdOut(true)
.exec(logContainerResultCallback)
.awaitCompletion();
ⅵ. 删除容器
// 删除容器
dockerClient.removeContainerCmd(containerId).withForce(true).exec();
ⅶ. 删除镜像
// 删除镜像
dockerClient.removeImageCmd(image).exec();
刚刚好不容易下的镜像 先不强制删除了