You are on page 1of 23

齐雷- qilei@tedu.

cn

容器化技术 56 问

1 Docker 基本概念

1.1 容器化技术的背景?

现阶段的软件技术水平已经真正的进入到了云计算时代,我们的应用现在也正在逐步的部
署到云端,部署到云端的服务需要相互隔离,让每个服务都运行在独立的容器中,而
Docker 正是当下最主流的容器化技术。

1.2 什么是容器化技术?

容器化实际上是一种轻量级的虚拟化技术。只不过相对于 VM,属于进程级别的隔离(通过
linux namespace 实现),具备以下特点:

1)更大的弹性
2)更快的启动速度
3)更少的资源消耗

而最为大家熟悉的容器化运行时技术就非 Docker 莫属了。

1.3 Docker 是什么?

Docker 是一个虚拟化平台( 官网 https://www.docker.com/),诞生于 2013 年初,


基于 Google 公司的 Go 语言进行实现。可以通过虚拟化方式,为应用提供可运行的容器,
容器之间可以相互隔离,独自运行。基于这种方式,我们可以更快地打包、部署和运行应
用程序,实现软件的快速交付。如图所示:

1
齐雷- qilei@tedu.cn

Docker 底层是基于 Linux 内核的 cgroup 和 namespace,对进程进行了封装隔离,属


于操作系统层面虚拟化技术。

传统虚拟化技术是虚拟出一套硬件后,在其基础上运行一个完整的操作系统,再在此
系统上运行所需的应用进程。而 Docker 技术是容器内的应用进程直接运行于宿主机的内
核,容器内没有自己的内核,而且也不虚拟出硬件。因此,相对于传统的虚拟化技术而言
Docker 更加轻便。

1.4 Docker 主要应用在什么场景?

 应用交付。
Docker 技术为应用交付领域带来的最大的变化就是开发环境的的一致性。传统的开
发方式需要开发者自己在本地进行开发,但是本地的开发环境和和远端的的测试和正式环
境还是存在差异,所以每次开发完成都需要反复比对环境的差异,包括操作系统以及操作
系统里面的的依赖软包是否齐全,,非常的麻烦。但是使用 Docker 镜像,我们可以将所
有的环境依赖都打包到镜像中,然后通过镜像来传输,这样会更加地高效。例如,直接在
linux 系统上安装 MySql 过程并不简单,要配置安装源,安装依赖包,对 mysql 进行配置等,
如果要在多台主机上安装,每台主机都要进行这些繁琐的操作,万一服务器挂了,这一系列
操作还要再重来一遍,但有了 docker,一个安装配置好的 mysql 容器,可以直接拿到另一
台主机上启动,而不必重新安装 mysql。同时,还可以保证开发,测试和生产环境的一致。

 多版本混合部署。
随着产品的不断更新换代,一台服务器上部署同一个应用的多个版本在企业内部非常
常见。但一台服务器上部署同一个软件的多个版本,文件路径、端口等资源往往会发生冲
突,造成多个版本无法共存的问题。如果用 docker,这个问题将非常简单。由于每个容
器都有自己独立的文件系统,所以根本不存在文件路径冲突的问题;对于端口冲突问题,
只需要在启动容器时指定不同的端口映射即可解决问题。

 内部开发测试环境。
传统的开发测试环境都是由运维人员进行专门的环境配置而搭建出来的,而且需要运
维人员进行专门维护。环境一旦出现问题,恢复起来也很麻烦。借助于 Docker 技术,我
们将应用程序需要的依赖都固化到到 Docker 镜像中,然后在对应 Docker 容器中进行开

2
齐雷- qilei@tedu.cn
发测试。就算环境出现问题,我们只要将当前容器删除重新启动即可恢复。

1.5 你了解 Docker 的版本吗?

Docker 分成了两个版本:Docker EE (企业版)和 Docker CE(社区版本),其中,


Docker EE 由公司支持,可在经过认证的操作系统和云提供商中使用。Docker CE 是免费
的 Docker 产品的新名称,Docker CE 包含了完整的 Docker 平台,非常适合开发人员和运
维团队构建容器 APP。

1.6 什么是 Docker 镜像(image)?

Docker 镜像可以看成是磁盘上特殊的文件系统(https://hub.docker.com/),镜
像打包了应用的运行环境以及应用程序,是静态的。可以通过 Docker 启动这个镜像,进
而将镜像中的程序在一个容器中启动运行起来。在 Docker 镜像中,操作系统是高度精简
的,镜像中的操作系统还不包含内核,容器都是共享所在的宿主机的内核。所以有时会说
容器仅包含必要的操作系统(通常只有操作系统文件和文件系统对象),容器中查看到的
Linux 内核版本与宿主机一致。假如现在理解镜像有些抽象,可以暂时先将其理解为一个
安装程序。

1.7 什么是容器(container)?

Docker 容 器 可 以 将 其 理 解 为 一 个 运 行 镜 像 的 载 体 , 镜 像 ( Image ) 和 容 器
(Container)的关系,就像是光盘和光驱。容器基于镜像创建、启动,然后运行镜像的
中的文件。容器是轻量级的,它不需要管理程序的额外负担,而是直接在主机的内核中运
行。我们常常说使用镜像打包应用程序,使用 Docker 发布、部署应用程序。当你的应用
成功在 Docker 上运行时,这个应用就是容器化应用。我们还可以将通过 Docker 启动
的容器看成是操作系统中的一个进程。

1.8 Docker 的逻辑架构师怎样的?

Docker 是一种 Client/Server 架构的应用程序,Docker 客户端与 Docker 守护进


程进行对话,该守护进程完成了构建,运行和分发 Docker 容器的繁重工作。Docker 客户
端和守护程序可以 在同一系统上运行,或者您可以将 Docker 客户端连接到远程 Docker
守 护 程 序 。 如 图 -5 所 示 ( 参 考 docker 官 网 https://docs.docker.com/get-
started/overview/)。

3
齐雷- qilei@tedu.cn

图-5

其中:
 Docker Client 是安装完 Docker 之后,直接使用的 docker 命令。
 Docker Host 是我们的 docker 宿主机(就是安装了 docker 的操作系统)
 Docker Daemon 是 docker 的后台守护进程,侦听并处理 Docker 客户端命令,管
理 Docker 对象,例如镜像,容器,网络和卷。
 Registry 是 docker 拉取镜像的远程仓库,提供大量的镜像供下载,下载完成之
后保存在 Images(本地镜像仓库)中.
 Images 是 Docker 本地的镜像仓库,可以通过 docker images 查看镜像文件。

1.9 Docker Pull 的运行机制是怎样的?

1) 客户端将指令发送给 docker daemon。


2) docker daemon 先检查本地 images 中有没有相关的镜像。
3) 如果本地没有相关的镜像,则向镜像服务器请求,将远程镜像下载到本地。

1.10 Docker run 的执行过程是怎样的?

1) 检查本地是否存在指定的镜像,不存在就从公有仓库下载。
2) 利用镜像创建并启动一个容器。
3) 分配一个文件系(简版 linux 系统),并在只读的镜像层外面挂载一层可读写层。
4) 从宿主机配置的网桥接口中桥接一个虚拟接口到容器中去。
5) 从地址池配置一个 ip 地址给容器。
6) 执行用户指定的应用程序。

4
齐雷- qilei@tedu.cn
1.11 Docker 是如何在线安装的?

第一步:安装一组工具。

sudo yum install -y yum-utils

第二步:设置 yum 仓库地址。

sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo

sudo yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

第三步:更新 yum 缓存。

sudo yum makecache fast #yum 是包管理器

第四步:安装新版 docker。

sudo yum install -y docker-ce docker-ce-cli containerd.io

2 Docker 服务操作

2.1 如何查看 Docker 状态?

查看 docker 是否启动了,是否是运行状态。

5
齐雷- qilei@tedu.cn
systemctl status docker

如图-1 所示:

图-1

2.2 如何停止 Docker 服务?

systemctl stop docker

2.3 如何启动 Docker 服务?

systemctl start docker

2.4 如何设置 Docker 开机自启?

systemctl enable docker

2.5 如何禁用 Docker 开机自启?

systemctl disable docker

6
齐雷- qilei@tedu.cn
2.6 如何重启 Docker 服务?

systemctl restart docker

2.7 如何查看 Docker 信息?

docker info

查看 docker info 中具体 key 的信息,例如:

docker info | grep 'Docker Root Dir:'

2.8 如何进行 Docker 镜像加速?

由 于 国 内 网 络 问 题 , 需 要 配 置 加 速 器 来 加 速 。 修 改 配 置 文 件
/etc/docker/daemon.json

下面命令直接生成文件 daemon.json

cat <<EOF > /etc/docker/daemon.json


{
"registry-mirrors": [
"https://docker.mirrors.ustc.edu.cn",
"http://hub-mirror.c.163.com"
],
"max-concurrent-downloads": 10,
"log-driver": "json-file",
"log-level": "warn",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"data-root": "/var/lib/docker"
}
EOF

说明:在执行如上指令时,保证你的登录用户为 root 管理员用户,并且设置好以后重启


docker 服务。

7
齐雷- qilei@tedu.cn
3 Docker 镜像操作

3.1 如何下载镜像?

语法:docker pull 镜像名


案例:

docker pull hello-world

3.2 如何浏览本地镜像?

语法如下:

docker images

3.3 如何查看镜像详情?

语法:docker inspect 镜像名或镜像 id。

docker inspect hello-world

3.4 如何查看镜像历史?

一个镜像是由多个层(layer)组成的,那么,我们要如何知道各个层的具体内容呢 ?
通过 docker history 命令,可以列出各个层(layer)的创建信息,例如:

docker history hello-world

8
齐雷- qilei@tedu.cn
3.5 如何导出镜像文件?

镜像导出(linux 系统中的镜像文件下载到本地-例如 window),导出后给他人使用。

docker save hello-world | gzip > hello-world.tar.gz

3.6 如何删除镜像文件?

语法:docker image rm 镜像名或镜像 id。

docker image rm hello-world

3.7 如何导入镜像文件

镜像导入(要在 hello-world.tar.gz 文件所在目录下执行)。

docker load < hello-world.tar.gz

3.8 如何运行镜像文件?

基于镜像,启动容器运行。

docker run hello-world

4 Docker 容器操作

4.1 如何下载镜像?

9
齐雷- qilei@tedu.cn
通过 docker pull 指令下载 CentOS 镜像,例如:

docker pull centos:7

说 明 , 官 方 镜 像 仓 库 地 址 为 https://hub.docker.com/ , 下 载 完 以 后 , 查 看
centos7 镜像文件。

docker images

4.2 如何创建并启动容器?

基本语法解析:

docker run -it xxxx bash

其中:

1)xxxx - 镜像名, 或 image id 的前几位。


2)-it 这是两个参数(-i 表示交互式操作, -t 表示终端)。
3) bash 表示进入操作终端,基于交互式进行相关操作(例如执行 linux 相关指令)。

案例:通过 docker 启动运行 centos7 镜像

docker run -it centos:7 bash

4.3 如何查看 Docker 中容器?

查看 docker 运行中的容器(要在宿主机执行 docker 指令)

docker ps

说明,不要在容器中执行 docker 指令。

查看 docker 运行中的所有容器,包括运行的,也包括没有运行的。

docker ps -a

10
齐雷- qilei@tedu.cn
其中,-a 表示全部(all)。

4.4 查看容器日志信息

查看容器启动运行日志时,这个指令非常重要,假如容器没有启动,要通过此指令去
看一下错误日志。

docker container logs 802 #802 为自己的容器 id(一般写前三位即可)

说明,查看容器的运行日志时,容器应该处于一种运行状态.

4.5 停止或重启容器

停止运行的容器,代码如下:

docker container stop 802 #802 为容器自己的 id

重新启动容器,代码如下:

docker container restart 802 #802 位容器自己的 id

4.6 如何进入容器?

当容器处于运行状态,要进入容器,可以使用 docker exec 命令,例如:

docker exec -it 802 bash #802 为容器 id

说明,假如容器处于一种非运行状态,此时通过 docker exec 指令无法进入容器。

4.7 如何从容器中退出?

11
齐雷- qilei@tedu.cn
假如从宿主机进入了启动的容器,退出容器需要使用 exit 指令,例如:

Exit

4.8 如何删除容器?

假如容器不用了,可执行删除操作,例如:

docker container rm 802 #802 为容器 id

假如容器正在运行,执行上面的指令不能删除容器。如果删除运行中的容器,需要添
加 -f 参数执行强制删除,例如:

docker container rm -f 802 #802 为容器 id

清理所有处于终止状态容器,例如:

docker container prune

说明,执行完这个指令以后,可以通过 docker ps -a 再查看容器,看看是否有删除.

5 Docker 数据管理

5.1 Docker 中管理的方式有哪些?

在容器中管理数据主要有两种方式:
 数据卷(Volumes)。
 挂载主机目录 (Bind mounts)。

5.2 什么是数据卷(Volumes)

12
齐雷- qilei@tedu.cn
数据卷是一个可供一个或多个容器使用的特殊目录,可以在容器之间共享和重用,默认会
一直存在,即使容器被删除。

5.3 如何创建数据卷?

创建数据卷,例如:

docker volume create container-vol

5.4 如何查看所有数据卷?

docker volume ls

5.5 如何查看指定数据卷的信息?

docker volume inspect container-vol

查询的结果:

[
{
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/container-vol/_data",
"Name": "container-vol",
"Options": {},
"Scope": "local"
}
]

13
齐雷- qilei@tedu.cn
5.6 如何进行数据卷挂载?

我们可以在创建容器时,进行数据卷的挂载。例如:

docker run -it --mount source=container-vol,target=/root centos:7


bash

或者采用如下简写方式

docker run -it -v container-vol:/root centos:7 bash

-v container-vol:/root 把数据卷 container-vol 挂载到容器的 /root 目录

5.7 如何删除数据卷?

删除数据卷(如果数据卷被容器使用则无法删除),例如

docker volume rm container-vol

清理无主数据卷

docker volume prune

5.8 如何进行直接挂载主机目录?

我们还可以在启动容器时,以目录直接挂载的方式进行数据操作,例如:

docker run -it -v /usr/app:/opt/app centos:7 bash

其中:
1)/usr/app:为宿主机目录。
2)/opt/app: 为启动容器的一个目录。
3)-v 用于指定挂载目录,如果本地目录(宿主机目录)不存在, Docker 会自动为你

14
齐雷- qilei@tedu.cn
按照挂载目录进行目录的创建。

如图-2 所示:

图-2

查看挂载目录信息,例如:

docker inspect 91a #91a 为容器 id

显示结果,例如:

...

"Mounts": [
{
"Type": "bind",
"Source": "/usr/app",
"Destination": "/opt/app",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],

...

15
齐雷- qilei@tedu.cn
6 Docker 容器互联

6.1 为什么要进行容器互联?

Docker 中存在多个容器时,容器与容器之间经常需要进行通讯, 例如容器 A 与容器


B 进行通讯。

6.2 如何实现容器互联操作?

Docker 中容器与容器之间进行通讯的解决方案一般有两种:
 第一种:两个容器通过宿主机进行通讯(容器中的端口会映射到宿主机上)。
 第二种:两个容器之间直接通过虚拟网络进行连接,但是需要我们在 docker 中创
建网络。

6.3 如何创建网络?

例如:创建名字为 t-net 的网络。

docker network create -d bridge t-net #t-net 为自己起的网络名称

其中,-d driver,网络类型,默认 bridge。创建好这个网络以后,在网落上添加容


器,容器就可以通讯了。

查看 docker 是否启动了,是否是运行状态。

systemctl status docker

6.4 如何查看网络信息?

列出所有网络。

16
齐雷- qilei@tedu.cn
docker network ls

查看网络信息。

docker inspect 67d #67d 为创建的网络 id

6.5 如何创建容器?

打开终端,基于 centos:7 这个镜像启动容器,并加入到 t-net 这个网络。

docker run -it --name app1 --network t-net centos:7

新开终端执行,基于 centos:7 这个镜像再启动容器,同时也加入到 t-net 网络。

docker run -it --name app2 --network t-net centos:7

6.6 如何测试网络?

在两个终端命令行分别执行 ping 操作,例如:

ping app1

ping app2

结果显示有数据传输,表示网络是通的,例如:

[root@35569c623c4c /]# ping app1


PING app1 (172.18.0.2) 56(84) bytes of data.
64 bytes from 35569c623c4c (172.18.0.2): icmp_seq=1 ttl=64
time=0.577 ms
64 bytes from 35569c623c4c (172.18.0.2): icmp_seq=2 ttl=64

17
齐雷- qilei@tedu.cn
time=0.061 ms
64 bytes from 35569c623c4c (172.18.0.2): icmp_seq=3 ttl=64
time=0.066 ms
......

7 Docker 镜像制作

7.1 为什么要自己制作镜像?

镜像市场中提供的镜像不满足我们的需求,我们需要将我们研发的软件做成镜像,然后进
行部署运行。

7.2 制作镜像的过程是怎样的?

通过 Docker build 操作构建一个镜像的过程如下,如图所示:

其中,图中的 Dockerfile 用来构建镜像的文本文件,内部会包含一条条构建镜像所需的指令和说明。

7.3 制作 JDK 镜像需要做哪些准备工作?

18
齐雷- qilei@tedu.cn
1) centos:7 镜像 (所有的镜像文件创建时都需要有一个空的 centos 镜像,就类似通过
一个空的光盘或 u 盘创建一个系统启动盘是一样的)
2) jdk 压缩包 jdk-8u51-linux-x64.tar.gz(可以从课前资料获取),基于此压缩包,制作
jdk 镜像。
3) Dockerfile 文件

7.4 制作 JDK 镜像的 Dockerfile 如何编写?

FROM centos:7
ADD jdk-8u51-linux-x64.tar.gz /usr/local/docker
ENV JAVA_HOME=/usr/local/docker/jdk1.8.0_51 \
PATH=/usr/local/docker/jdk1.8.0_51/bin:$PATH
CMD ['bash']

其中:
1) jdk-8u51-linux-x64.tar.gz 要与 Dockerfile 文件放在同一个目录。
2) add 用于将 jdk 添加到/usr/local/docker 容器中目录
3) ENV 用于设置容器中的环境变量
4) CMD 用于指定容器启动后要执行的指令。

其它操作说明,例如:

19
齐雷- qilei@tedu.cn

8 创建创建镜像容器

8.1 如何创建 mysql 镜像容器?

20
齐雷- qilei@tedu.cn
第一步:拉取指定版本的 mysql,也可以指定拉取版本,例如:

docker pull mysql:8.0.23

第二步:检查 mysql 镜像。

docker images

第三步:启动运行 mysql 镜像 (docker run 用于启动一个容器)。

docker run -p 3306:3306 --name mysql \


-v /usr/local/docker/mysql/mysql-files:/var/lib/mysql-files \
-v /usr/local/docker/mysql/conf:/etc/mysql \
-v /usr/local/docker/mysql/logs:/var/log/mysql \
-v /usr/local/docker/mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:8.0.23

假如安装过程中失败了,则可通过 docker ps -a 查看以前的容器,假如已存在,则通过


docker rm 镜像 id 删除再重新安装即可。

8.2 如何创建 Redis 镜像容器?

第一步:下载镜像文件。

docker pull redis

第二步:准备配置文件。

创建 redis 配置文件目录

mkdir -p /usr/local/docker/redis01/conf

在配置文件录下创建 redis.conf 配置文件(这个文件一定要创建,否在我们进行目录挂载


时默认生成的是一个目录)

touch /usr/local/docker/redis01/conf/redis.conf

21
齐雷- qilei@tedu.cn
第三步:创建 redis 实例并启动。

docker run -p 6379:6379 --name redis01 \


-v /usr/local/docker/redis01/data:/data \
-v /usr/local/docker/redis01/conf/redis.conf:/etc/redis/redis.conf \
-d redis redis-server /etc/redis/redis.conf

第四步:查看正在运行的进程。

docker ps

8.3 如何创建 Nginx 镜像容器?

第一步:拉取 nginx 镜像 (从这里 hub.docker.com 去查找)。

docker pull nginx

第二步:查看 images 镜像。

docker images

第三步:创建数据卷(这个对象会在宿主机直接创建一个目录)。

docker volume create nginx-vol

说明:查看数据卷对应的宿主机目录,可以通过如下指令:

docker inspect nginx-vol

第四步:启动 nginx 服务

docker run --name nginx -p 80:80 -v nginx-vol:/etc/nginx -d nginx

其中:/etc/nginx 为 nginx 容器启动时,nginx 镜像文件默认的解压目录。

22
齐雷- qilei@tedu.cn
第五步:打开浏览器,进行访问测试,如图所示:

23

You might also like