文章目录
Docker 是什么
Docker 容器
标准化的软件单元。Docker 是开发人员或系统管理员使用容器 开发,部署和运行 应用程序的平台。使用Linux容器部署应用程序称为容器化
容器化越来越受欢迎,因为容器
- 灵活:即使是最复杂的应用也可以集装箱化。
- 轻量级:容器利用并共享主机内核。
- 可互换:您可以即时部署更新和升级。
- 便携式:您可以在本地构建,部署到云,并在任何地方运行。
- 可扩展:您可以增加并自动分发容器副本。
- 可堆叠:您可以垂直和即时堆叠服务。
容器是一个标准的软件单元,它将代码及其所有依赖关系打包,以便应用程序从一个计算环境快速可靠地运行到另一个计算环境。Docker 容器镜像是一个轻量级,独立的可执行软件包,包含运行应用程序所需的一切:代码,运行时,系统工具,系统库和设置。镜像在运行时成为容器,容器将应用与其环境隔离开来,并确保它可以统一运行
在Docker Engine上运行的Docker容器:
- 标准: Docker创建了容器的行业标准,因此它们可以随处携带
- 轻量级: 容器共享机器的操作系统内核,因此不需要每个应用程序的操作系统,从而提高服务器效率并降低服务器和许可成本
- 安全: 应用程序在容器中更安全,Docker提供业界最强大的默认隔离功能(类似“沙箱“)
镜像和容器
通过运行镜像启动容器。一个镜像是一个可执行的包,其中包括运行应用程序所需的所有内容----代码,运行时,库,环境变量,和配置文件。而容器是镜像的运行时实例,当执行镜像时,即在内存中变成用户进程,可以使用 docker ps
命令查看正在运行的容器列表
镜像和容器的关系有些像 Java 中类和对象实例的关系
容器和虚拟机
容器和虚拟机具有类似的资源隔离和分配优势,但功能不同,因为容器虚拟化操作系统而不是硬件。容器更便携,更高效。
一个容器中运行原生 Linux和共享主机与其它容器的内核。它运行一个独立的进程,不占用任何其他可执行文件的内存,使其轻量级。容器是应用层的抽象,它将代码和依赖关系打包在一起。多个容器可以在同一台机器上运行,并与其他容器共享操作系统内核,每个容器在用户空间中作为独立进程运行。容器占用的空间比VM少(容器映像的大小通常为几十MB),可以处理更多的应用程序,并且需要更少的VM和操作系统
相比之下,虚拟机(VM)运行一个完整的“客户”操作系统,通过虚拟机管理程序对主机资源进行虚拟访问。通常,VM提供的环境比大多数应用程序需要的资源更多。虚拟机(VM)是物理硬件的抽象,将一台服务器转变为多台服务器。管理程序允许多台VM在单台机器上运行。每个VM都包含操作系统的完整副本,应用程序,必要的二进制文件和库 - 占用数十GB。虚拟机也可能很慢启动。
安装
mac 和 windows 可以直接安装 Docker Desktop 即可,方便开发
Linux 安装我这里以 Centos 7 为例
安装 Docker CE
Docker Community Edition 是社区版,适用于个人开发者和小团队
官方提供了三种方式安装 Docker CE:
- 设置 Docker 存储库并安装,便于安装和升级(推荐)
- 使用 rpm 包手动安装,需要手动管理升级
- 使用便捷脚本安装(不建议生产使用)
这里使用 Docker 存储库安装
设置存储库
1)安装需要的包
yum-utils
提供了 yum-config-manager
的功能,devicemapper
存储驱动需要 device-mapper-persistent-data
和 lvm2
$ sudo yum install -y yum-utils \
device-mapper-persistent-data \
lvm2
2)设置稳定的存储库
$ sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
安装 Docker
安装最新的 Docker CE 和 containerd
$ sudo yum install docker-ce docker-ce-cli containerd.io
若需安装特定版本的 Docker CE,可以在 repo 中列出可用版本,并选择安装
$ yum list docker-ce --showduplicates | sort -r
然后在安装命令上加上版本号即可,假如是 docker-ce-18.09.1
$ sudo yum install docker-ce-18.09.1 docker-ce-cli-18.09.1 containerd.io
启动 Docker
$ sudo systemctl start docker
验证
运行 hello-world
镜像验证是否正确安装
$ sudo docker run hello-world
使用 rpm 包安装
到地址 https://download.docker.com/linux/centos/7/x86_64/stable/Packages/ 下载对应版本的 rpm 包,安装对应路径下的包
$ sudo yum install /path/to/package.rpm
Docker 系统架构
Docker使用客户端 - 服务器架构。Docker 客户端与 Docker 守护进程通信,后者负责构建,运行和分发Docker容器。Docker客户端和守护程序可以在同一系统上运行,也可以将Docker客户端连接到远程Docker守护程序。Docker客户端和守护程序使用REST API,通过UNIX套接字或网络接口进行通信
[外链图片转存失败(img-3OQgl7uc-1562295058980)(https://docs.docker.com/engine/images/architecture.svg)]
- Client: 表示 Docker 客户端,通过
docker build
命令创建 Docker 镜像,docker pull
拉取镜像,docker run
运行镜像,并启动 Docker 容器 - DOCKER_HOST: 运行 Docker 引擎的宿主机,包括 Docker daemon 后台进程,可通过该进程来创建镜像,并在镜像上启动容器
- Registry: Docker 官方镜像注册中心,包含大量的Docker 镜像仓库,可以通过 Docker 引擎拉取所需的 Docker 镜像到宿主机。
Docker Hub
是公共注册中心,Docker 配置为默认在Docker Hub 上查找镜像 - Images: Docker 镜像是一个只读模板,它包含创建 Docker容器的说明。它和系统安装光盘有点像,使用系统安装光盘可以安装系统,同理,使用Docker镜像可以运行 Docker镜像中的程序
- Container: 容器是镜像的可运行实例。镜像和容器的关系有点类似于面向对象中,类和对象的关系。可通过 Docker API或者 CLI命令来启停、移动、删除容器
使用 Dockerfile 构建镜像
Dockerfile 是一个文本文件,包含了一些指令,这些指令描述了创建镜像的细节
# 设置 nginx 基础镜像
FROM nginx:1.15
# 也可以用 LABEL maintainer="zouxq <zouxq412@foxmial.com>"
MAINTAINER zouxq <zouxq412@foxmial.com>
# 将 dist 文件中的内容复制到 /usr/share/nginx/html/ 这个目录下面
COPY dist/ /usr/share/nginx/html/
上面就是简单构建一个静态服务器镜像的 Dockerfile
Dockerfile 指令介绍
上面例子的 FROM
、MAINTAINER
、COPY
就是 Dockerfile 指令,指令的一般格式为:指令名称 参数
1)FROM 指定基础镜像
FROM 指令一般要写在其他指令之前,它指定我们要创建新镜像所依赖的基础镜像
FROM <image>
FROM <image>:<tag>
FROM <image>@<digest>
例如我们需要构建 Java 应用程序的镜像
FROM java
这里使用了 Docker 官方提供的 Java 镜像,是基于 open Jdk 制作的镜像
2)RUN 设置镜像制作过程中需要执行的命令
RUN <command>
(该命令在 shell 中运行,在 Linux 默认/bin/sh -c
,Windows是cmd /S /C
)RUN ["executable", "param1", "param2"]
(使用 exec 执行)
RUN /bin/bash -c 'source $HOME/.bashrc; \
echo $HOME'
可以使用多行 RUN 指令,但多条指令通过
\
命令换行符合并成一条,可以减少所构建的镜像的体积,因为在镜像中每执行一条命令,都会形成新的 “镜像层”
RUN ["/bin/bash", "-c", "echo hello"]
exec 表单被解析为JSON数组,所以这种方式要使用双引号而不能使用单引号
3)ADD 设置需要添加到容器中的文件
ADD [--chown=<user>:<group>] <src>... <dest>
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]
从 src 目录复制文件到容器的 dest, 其中 src 可以是 Dockerfile 所在目录的相对路径,也可以是一个 URL,还可以是个压缩包
4)COPY 复制文件
COPY [--chown=<user>:<group>] <src>... <dest>
COPY [--chown=<user>:<group>] ["<src>",... "<dest>"]
COPY 指令和 ADD 指令类似,COPY 不支持 URL 和压缩包
5)CMD 设置容器启动时需要执行的命令
CMD ["executable","param1","param2"]
(推荐)CMD ["param1","param2"]
(作为ENTRYPOINT的默认参数)CMD command param1 param2
(在 shell 中执行)
每个 Dockerfile 只有一个 CMD 命令,多个只有最后被执行
CMD echo "This is a test." | wc -
Dockerfile 指令汇总
Dockerfile 指令
Dockerfile 指令 | 描述 |
---|---|
FROM | 设置基础镜像 |
RUN | 设置镜像制作过程中需要执行的命令 |
CMD | 设置容器启动时需要执行的命令(可被覆盖) |
LABEL | 添加元数据到镜像(键值对) |
MAINTAINER (deprecated) | 设置维护者信息(被启用,可使用更灵活的LABEL指令) |
EXPOSE | 设置可被暴露的端口号(端口映射) |
ENV | 设置环境变量,可在 RUN 指令中使用 |
ADD | 设置需要添加到容器中的文件(自动解压) |
COPY | 设置需要复制到容器中的文件(无法解压) |
ENTRYPOINT | 设置容器启动时需要运行的命令(无法覆盖) |
VOLUME | 设置可被挂载的数据卷(目录映射) |
USER | 设置运行 RUN 指令的用户 |
WORKDIR | 设置进入容器时的工作目录 |
ARG | |
ONBUILD | 设置在构建时需自动执行的指令 |
STOPSIGNAL | 设置将发送到容器的系统调用信号以退出 |
HEALTHCHECK | 设置容器的健康检查 |
SHELL |
使用 Dockerfile 构建镜像
上面介绍了部分的 Dockerfile 指令,接下来我们用 Dockerfile 去创建一个 Spring Boot 应用的镜像
1、准备工作
搭建一个简单的 Spring Boot 应用程序,这里以 Hello World 为例
@SpringBootApplication
@RestController
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@RequestMapping("/")
public String hello(){
return "Hello World";
}
}
使用 maven 打包项目 mvn clean package
2、创建 Dockerfile 文件
在工程目录下创建一个 Dockerfile 文件,添加以下内容
# 基于 java8
FROM java:8
# 将本地文件夹挂载到当前容器
VOLUME /tmp
# 添加文件到容器
ADD target/demo-0.0.1-SNAPSHOT.jar /home/demo.jar
# 声明需要暴露的端口
EXPOSE 8081
# 配置容器启动后执行的命令
ENTRYPOINT ["java","-jar","/home/demo.jar"]
3、使用 docker build 命令构建镜像
docker build -t demo-server:0.0.1 .
格式: docker build -t 仓库名称/镜像名称(:标签) Dockerfile的相对位置
-t
表示以“name:tag”格式命名和选择标记
执行命令后,会看到以下信息,可以看到镜像构建的详细过程和结果
我们可以通过 docker image ls
或者 docker images
命令来查看镜像列表
4、启动容器
运行上面创建的镜像启动容器
docker run -d -p 8081:8081 demo-server:0.0.1
-d
表示在后台运行容器并打印容器ID
-p
表示将容器的端口发布到主机
后面是镜像名称加上标签版本号
可以使用 docker container ls
或者 docker ps
来查看在运行的容器,如果要查看所有的容器在后面加上 --all