一文搞懂docker容器基础:docker镜像管理,docker容器管理
一.系统环境
服务器版本 | docker软件版本 | CPU架构 |
---|---|---|
CentOS Linux release 7.4.1708 (Core) | Docker version 20.10.12 | x86_64 |
二.docker
2.1 Docker 概述
Docker 是一个用于开发、发布和运行应用程序的开放平台。Docker 使您能够将应用程序与基础架构分离,以便您可以快速交付软件。使用 Docker,您可以像管理应用程序一样管理基础设施。通过利用 Docker 快速交付、测试和部署代码的方法,您可以显著减少编写代码和在生产环境中运行之间的延迟。
2.2 Docker 平台
Docker 提供了在称为容器的松散隔离环境中打包和运行应用程序的能力。隔离和安全性允许您在给定主机上同时运行多个容器。容器是轻量级的,包含运行应用程序所需的一切,因此您无需依赖主机上当前安装的内容。您可以在工作时轻松共享容器,并确保与您共享的每个人都获得以相同方式工作的同一个容器。
Docker 提供工具和平台来管理容器的生命周期:
- 使用容器开发您的应用程序及其支持组件。
- 容器成为分发和测试应用程序的单元。
- 准备就绪后,将应用程序部署到生产环境中,作为容器或编排的服务。无论您的生产环境是本地数据中心、云提供商还是两者的混合,这都是一样的。
2.3 我可以使用 Docker 做什么?
2.3.1 快速、一致地交付您的应用程序
Docker 通过允许开发人员使用提供应用程序和服务的本地容器在标准化环境中工作来简化开发生命周期。容器非常适合持续集成和持续交付 (CI/CD) 工作流程。
考虑以下示例场景:
- 您的开发人员在本地编写代码并使用 Docker 容器与同事分享他们的工作。
- 他们使用 Docker 将他们的应用程序推送到测试环境中并执行自动化和手动测试。
- 当开发者发现bug时,可以在开发环境中修复,重新部署到测试环境中进行测试和验证。
- 测试完成后,将修复程序提供给客户就像将更新的映像推送到生产环境一样简单。
2.3.2 响应式部署和扩展
Docker 基于容器的平台允许高度可移植的工作负载。Docker 容器可以在开发人员的本地笔记本电脑、数据中心的物理或虚拟机、云提供商或混合环境中运行。
Docker 的可移植性和轻量级特性还使得动态管理工作负载、根据业务需求近乎实时地扩展或拆除应用程序和服务变得容易。
2.3.3 在相同硬件上运行更多工作负载
Docker 是轻量级和快速的。它为基于管理程序的虚拟机提供了一种可行且经济高效的替代方案,因此您可以使用更多计算容量来实现业务目标。Docker 非常适合高密度环境以及需要用更少资源完成更多工作的中小型部署。
2.4 Docker 架构
Docker 使用客户端-服务器架构。Docker客户端与 Docker守护进程对话,后者负责构建、运行和分发 Docker 容器的繁重工作。Docker 客户端和守护程序可以 在同一系统上运行,或者您可以将 Docker 客户端连接到远程 Docker 守护程序。Docker 客户端和守护程序使用 REST API,通过 UNIX 套接字或网络接口进行通信。另一个 Docker 客户端是 Docker Compose,它允许您使用由一组容器组成的应用程序。
2.4.1 The Docker daemon(Docker 守护进程)
Docker 守护程序 ( dockerd) 侦听 Docker API 请求并管理 Docker 对象,例如镜像、容器、网络和卷。守护进程还可以与其他守护进程通信以管理 Docker 服务。
2.4.2 The Docker client(Docker 客户端)
Docker 客户端 ( docker) 是许多 Docker 用户与 Docker 交互的主要方式。当您使用诸如docker run之类的命令时,客户端会将这些命令发送到dockerd执行它们。该docker命令使用 Docker API。Docker 客户端可以与多个守护进程通信。
2.4.3 Docker Desktop(Docker 桌面)
Docker Desktop 是一个易于安装的应用程序,适用于您的 Mac、Windows 或 Linux 环境,使您能够构建和共享容器化应用程序和微服务。Docker Desktop 包括 Docker 守护程序 ( dockerd)、Docker 客户端 ( docker)、Docker Compose、Docker Content Trust、Kubernetes 和 Credential Helper。
2.4.4 Docker registries(Docker 镜像仓库)
Docker镜像仓库存储 Docker 镜像。Docker Hub 是一个任何人都可以使用的公共镜像仓库,并且 Docker 默认配置为在 Docker Hub 上查找镜像。您甚至可以运行自己的私有镜像仓库。
当您使用docker pull或者docker run命令时,将从您配置的镜像仓库中拉取所需的镜像。当您使用该docker push命令时,您的镜像会被推送到您配置的镜像仓库中。
2.4.5 Docker objects(Docker 对象)
当您使用 Docker 时,您正在创建和使用镜像、容器、网络、卷、插件和其他对象。
2.4.6 Images(镜像)
镜像是一个只读模板,其中包含创建 Docker 容器的说明。通常,一个镜像基于另一个镜像,并带有一些额外的自定义。例如,您可以基于该镜像构建一个镜像ubuntu ,但安装 Apache Web 服务器和您的应用程序,以及使您的应用程序运行所需的配置详细信息。
您可以创建自己的镜像,也可以只使用其他人创建并在镜像仓库中发布的镜像。要构建您自己的镜像,您需要使用简单的语法创建一个Dockerfile ,用于定义创建和运行镜像所需的步骤。Dockerfile 中的每条指令都会在镜像中创建一个层。当您更改 Dockerfile 并重建镜像时,仅重建那些已更改的层。与其他虚拟化技术相比,这是使镜像如此轻量、小巧和快速的部分原因。
运行容器时,它使用隔离的文件系统。此自定义文件系统由容器镜像提供。由于镜像包含容器的文件系统,它必须包含运行应用程序所需的一切(所有依赖项、配置、脚本、二进制文件等)。镜像还包含容器的其他配置,例如环境变量、要运行的默认命令、和其他元数据。
2.4.7 Containers(容器)
容器是镜像的可运行实例。您可以使用 Docker API 或 CLI 创建、启动、停止、移动或删除容器。您可以将容器连接到一个或多个网络,将存储附加到它,甚至可以根据其当前状态创建新镜像。
默认情况下,一个容器与其他容器及其主机的隔离相对较好。您可以控制容器的网络、存储或其他底层子系统与其他容器或主机的隔离程度。
容器由其镜像以及您在创建或启动它时提供给它的任何配置选项定义。当容器被移除时,任何未存储在持久存储中的状态更改都会消失。
容器是您机器上的沙盒进程,与主机上的所有其他进程隔离。这种隔离利用了内核命名空间和 cgroups,这些特性在 Linux 中已经存在了很长时间。Docker 致力于使这些功能变得平易近人且易于使用。总而言之,一个容器:
- 是镜像的可运行实例。您可以使用 DockerAPI 或 CLI 创建、启动、停止、移动或删除容器。
- 可以在本地机器、虚拟机上运行或部署到云端。
- 是可移植的(可以在任何操作系统上运行)。
- 与其他容器隔离并运行自己的软件、二进制文件和配置。
三.docker的安装部署
3.1 安装docker
1.安装docker
[root@k8scloude1 ~]# yum -y install docker-ce
已加载插件:fastestmirror
base | 3.6 kB 00:00:00
......
已安装:
docker-ce.x86_64 3:20.10.12-3.el7
......
完毕!
2.设置docker开机自启动并现在启动docker
[root@k8scloude1 ~]# systemctl enable docker --now
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.
[root@k8scloude1 ~]# systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
Active: active (running) since 六 2022-01-08 22:10:38 CST; 18s ago
Docs: https://docs.docker.com
Main PID: 1377 (dockerd)
Memory: 30.8M
CGroup: /system.slice/docker.service
└─1377 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
3.查看docker版本
[root@k8scloude1 ~]# docker --version
Docker version 20.10.12, build e91ed57
4.docker info : 显示 Docker 系统信息,包括镜像和容器数等等
3.2 配置阿里云docker镜像加速器
1.配置docker镜像加速器
[root@k8scloude1 ~]# cat > /etc/docker/daemon.json <<EOF
> {
> "registry-mirrors": ["https://frz7i079.mirror.aliyuncs.com"]
> }
> EOF
[root@k8scloude1 ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://frz7i079.mirror.aliyuncs.com"]
}
2.重启docker
[root@k8scloude1 ~]# systemctl restart docker
[root@k8scloude1 ~]# systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
Active: active (running) since 六 2022-01-08 22:17:45 CST; 8s ago
Docs: https://docs.docker.com
Main PID: 1529 (dockerd)
Memory: 32.4M
CGroup: /system.slice/docker.service
└─1529 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
四.docker的管理
4.1 docker镜像的管理
1.docker镜像命名规范
给镜像打标签(tag)时需要注意命名的规范,一般为:系统名称+系统版本+服务名+服务版本:代码版本如:centos7.6-nginx-1.47:2.0。
2.docker镜像管理命令
#搜索镜像:docker search 镜像
#拉取镜像:docker pull [选项] [Docker Registey 地址[:端口号]/] 镜像名[:标签]
#在镜像列表中,可能会存在一种特殊的镜像,该镜像既没有仓库名/镜像名称,也没有标签/版本号,这两个位置均显示<none>,这种镜像通常被称为虚悬镜像,一般来说,虚悬镜像已经失去了存在的价值,是可以随意删除的,使用下面的命令删除:docker image prune
#给镜像打标签:docker tag 镜像
#删除本地镜像:docker rmi 镜像
#导出镜像为tar包:docker save 镜像名 > filename.tar
#导入镜像:docker load -i filename.tar
#把容器导出为镜像tar包: docker export 容器名 > filename.tar
#导入镜像tar包: cat filename.tar | docker import - 镜像名
列出镜像:docker images
[root@k8smaster ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hub.c.163.com/library/centos latest 328edcd84f1b 4 years ago 193MB
查看指定镜像的创建历史:docker history xxxx --no-trunc 可以显示完整的内容
[root@k8smaster ~]# docker history hub.c.163.com/library/centos
IMAGE CREATED CREATED BY SIZE COMMENT
328edcd84f1b 4 years ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 4 years ago /bin/sh -c #(nop) LABEL name=CentOS Base Im… 0B
<missing> 4 years ago /bin/sh -c #(nop) ADD file:63492ba809361c51e… 193MB
[root@k8smaster ~]# docker history hub.c.163.com/library/centos --no-trunc
IMAGE CREATED CREATED BY SIZE COMMENT
sha256:328edcd84f1bbf868bc88e4ae37afe421ef19be71890f59b4b2d8ba48414b84d 4 years ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 4 years ago /bin/sh -c #(nop) LABEL name=CentOS Base Image vendor=CentOS license=GPLv2 build-date=20170801 0B
<missing> 4 years ago /bin/sh -c #(nop) ADD file:63492ba809361c51e75605d70390b549ff1187076b6d00485a1a0bb175daa40e in / 193MB
4.2 docker容器的管理
4.2.1 docker容器管理命令
#运行容器:docker run 镜像
#删除容器:docker rm 容器名
#显示容器:docker ps
#列出指定容器的端口映射:docker port 容器名
[root@etcd2 ~]# docker port harbor-log
10514/tcp -> 127.0.0.1:1514
#在运行的容器中执行命令:docker exec xxxx 命令
#启动容器:docker start xxxx
#停止容器:docker stop xxxxx
#重启容器:docker restart xxxxx
#杀掉一个运行中的容器:docker kill 容器名
#进入运行中的容器(连接到正在运行中的容器使用exit退出后容器自动关闭,不推荐使用):docker attach CONTAINER
#查看容器中运行的进程信息:docker top xxxxx
#查看所有容器运行的进程:for i in `docker ps |grep Up|awk '{print $1}'`;do echo \ &&docker top $i; done
#获取容器的日志:docker logs -f node
#获取容器的详细信息:docker inspect 容器名
#容器与主机之间的数据拷贝:
#从容器里复制数据到主机:docker cp CONTAINER:SRC_PATH DEST_PATH
#从主机里复制数据到容器:docker cp SRC_PATH| CONTAINER:DEST_PATH
[root@etcd2 ~]# docker cp /opt/ 7c677fb67522:/home
运行容器:
#运行容器:docker run 镜像
#docker run 镜像 ---最简单的一个容器
#docker run -it --rm hub.c.163.com/library/centos /bin/bash
#docker run -dit -h node --name=c1 镜像名 命令
#docker run -dit --restart=always 镜像名 命令
#docker run -dit --restart=always -e 变量1=值1 -e 变量2=值2 镜像
常见参数
-a stdin: 指定标准输入输出内容类型,可选 STDIN/STDOUT/STDERR 三项;
-d: 后台运行容器,并返回容器ID;
-i: 以交互模式运行容器,通常与 -t 同时使用;
-P: 随机端口映射,容器内部端口随机映射到主机的端口
-p: 指定端口映射,格式为:主机(宿主)端口:容器端口
-t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;
--name="nginx-lb": 为容器指定一个名称;
--dns 8.8.8.8: 指定容器使用的DNS服务器,默认和宿主一致;
--dns-search example.com: 指定容器DNS搜索域名,默认和宿主一致;
-h "mars": 指定容器的hostname;
-e username="ritchie": 设置环境变量;
--env-file=[]: 从指定文件读入环境变量;
--cpuset="0-2" or --cpuset="0,1,2": 绑定容器到指定CPU运行;
-m :设置容器使用内存最大值;
--net="bridge": 指定容器的网络连接类型,支持 bridge/host/none/container: 四种类型;
--link=[]: 添加链接到另一个容器;
--expose=[]: 开放一个端口或一组端口;
--volume , -v: 绑定一个卷
4.2.2 容器管理示例
#运行一个容器并进入到里面
[root@k8smaster ~]# docker run -it --restart=always --name=centos hub.c.163.com/library/centos:latest
[root@3c6f6cc36259 /]# ps | grep bash
1 pts/0 00:00:00 bash
[root@3c6f6cc36259 /]# cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core)
#退出容器
[root@3c6f6cc36259 /]# exit
exit
#退出之后,查看发现容器进程还在
[root@k8smaster ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3c6f6cc36259 hub.c.163.com/library/centos:latest "/bin/bash" About a minute ago Up 3 seconds centos
#再次进入容器
[root@k8smaster ~]# docker attach centos
[root@3c6f6cc36259 /]#
#删除容器,-f强制删除
[root@k8smaster ~]# docker rm -f centos
centos
[root@k8smaster ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
#运行一个容器但是不进入到里面,-d dettach
[root@k8smaster ~]# docker run -dit --restart=always --name=centos hub.c.163.com/library/centos:latest
0f683a6c33868fee306b26b9d84fbf1ddbe1522f5c6d49944324ec57e1eb5990
[root@k8smaster ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0f683a6c3386 hub.c.163.com/library/centos:latest "/bin/bash" 8 seconds ago Up 6 seconds centos
#运行容器,运行命令:sleep 100
[root@k8smaster ~]# docker run -dit --restart=always --name=centos hub.c.163.com/library/centos:latest sleep 100
ae064dd568d9b489329d8c6e7f7c0795fb40efec1f4424a9137ce1f076946502
#进入容器什么也做不了,因为没有/bin/bash接待你
[root@k8smaster ~]# docker attach centos
4.2.3 运行nginx容器示例,容器端口映射
#运行nginx容器,容器端口为80,物理机端口随机生成
[root@k8smaster ~]# docker run -dit --name=web --restart=always -p 80 hub.c.163.com/library/nginx:latest
bee79324ce9bfbef6bfaf7bdf671ff74007e12e2ffac5e0662fb8522442e275f
#物理机端口为49153
[root@k8smaster ~]# docker ps | grep web
bee79324ce9b hub.c.163.com/library/nginx:latest "nginx -g 'daemon of…" 39 seconds ago Up 37 seconds 0.0.0.0:49153->80/tcp, :::49153->80/tcp web
#访问nginx
[root@k8smaster ~]# curl 192.168.110.137:49153
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
#-p 80:80表示物理机端口:容器端口
[root@k8smaster ~]# docker run -dit --name=web --restart=always -p 80:80 hub.c.163.com/library/nginx:latest
c027df65a8894f1b82cd38bc15a016a6b5b2c9e3ba36487a7692363fce9ee91b
[root@k8smaster ~]# docker ps | grep web
c027df65a889 hub.c.163.com/library/nginx:latest "nginx -g 'daemon of…" 7 seconds ago Up 3 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp web
#执行容器变量,-e指定容器的变量
[root@k8smaster ~]# docker run -dit --restart=always --name=centos -e xx=12 -e yy=13 hub.c.163.com/library/centos:latest
8b9c2042ffe2e7bc1e7b263128b8fe903b9b3fa403030c23024b0a8c055b0b3c
[root@k8smaster ~]# docker attach centos
[root@8b9c2042ffe2 /]# echo $xx
12
[root@8b9c2042ffe2 /]# echo $yy
13
[root@8b9exit
exit
#--rm创建临时容器
[root@k8smaster ~]# docker run -it --rm --name=test -e xx=12 -e yy=13 hub.c.163.com/library/centos:latest
[root@328ca3ac967f /]# echo $xx
12
[root@328ca3ac967f /]# exit
exit
4.2.4 运行mysql容器示例,练习容器基本操作
#拉取mysql镜像
[root@k8smaster ~]# docker pull hub.c.163.com/library/mysql:latest
[root@k8smaster ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hub.c.163.com/library/mysql latest 9e64176cd8a2 4 years ago 407MB
[root@k8smaster ~]# docker run -dit --restart=always --name=db hub.c.163.com/library/mysql
a0d580fc15c6487b2d639c92c0024ad6125af649067fee55eebcd8f9fa58bdb8
#发现mysql容器的状态是Restarting
[root@k8smaster ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a0d580fc15c6 hub.c.163.com/library/mysql "docker-entrypoint.s…" 8 seconds ago Restarting (1) 2 seconds ago db
#查看mysql容器的日志,发现是没有指定mysql的密码
[root@k8smaster ~]# docker logs db
error: database is uninitialized and password option is not specified
You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD
error: database is uninitialized and password option is not specified
You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD
error: database is uninitialized and password option is not specified
You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD
error: database is uninitialized and password option is not specified
You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD
error: database is uninitialized and password option is not specified
You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD
error: database is uninitialized and password option is not specified
You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD
error: database is uninitialized and password option is not specified
You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD
[root@k8smaster ~]# docker rm -f db
db
[root@k8smaster ~]# docker run -dit --restart=always --name=db -e MYSQL_ROOT_PASSWORD=qwerty hub.c.163.com/library/mysql
01d83d13eb32e25c72cd39290ab12d5f69b994cec3e48dd9c8608e719cd2181c
[root@k8smaster ~]# docker ps | grep hub.c.163.com/library/mysql
01d83d13eb32 hub.c.163.com/library/mysql "docker-entrypoint.s…" 19 seconds ago Up 15 seconds 3306/tcp db
#查看容器里运行的进程
[root@k8smaster ~]# docker top db
UID PID PPID C STIME TTY TIME CMD
polkitd 93764 93742 7 16:40 pts/0 00:00:02 mysqld
#因为运行的是mysqld进程,没有bash进程,所以attach进不去
[root@k8smaster ~]# docker attach db
#在容器外面执行shell命令
[root@k8smaster ~]# docker exec db ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1
link/ipip 0.0.0.0 brd 0.0.0.0
62: eth0@if63: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:04 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.4/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
#可以自带bash,进入容器
[root@k8smaster ~]# docker exec -it db /bin/bash
root@01d83d13eb32:/#
root@01d83d13eb32:/# exit
exit
#停止/启动/重启容器
[root@k8smaster ~]# docker stop db
db
[root@k8smaster ~]# docker start db
db
[root@k8smaster ~]# docker restart db
db
[root@k8smaster ~]# docker exec db ls /tmp
#复制文件
[root@k8smaster ~]# docker cp /etc/docker/daemon.json db:/tmp
[root@k8smaster ~]# docker exec db ls /tmp
daemon.json
[root@k8smaster ~]# docker cp db:/tmp/daemon.json ./
[root@k8smaster ~]# ls daemon.json
daemon.json
#查看容器日志
[root@k8smaster ~]# docker logs -f db
#查看容器的属性(容器详细信息)
[root@k8smaster ~]# docker inspect db
[
{
"Id": "01d83d13eb32e25c72cd39290ab12d5f69b994cec3e48dd9c8608e719cd2181c",
"Created": "2021-12-28T08:40:56.781434728Z",
"Path": "docker-entrypoint.sh",
"Args": [
"mysqld"
],
......
"DriverOpts": null
}
}
}
}
]
#查看容器IP地址
[root@k8smaster ~]# docker inspect db | grep IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.4",
"IPAddress": "172.17.0.4",
4.2.5 容器数据卷volumes(容器目录映射)
数据卷是保存由 Docker 容器生成和使用的数据的首选机制。虽然绑定挂载依赖于主机的目录结构和操作系统,但数据卷完全由 Docker 管理。与绑定挂载相比,数据卷有几个优点:
- 数据卷比绑定挂载更容易备份或迁移。
- 您可以使用 Docker CLI 命令或 Docker API 管理数据卷。
- 数据卷适用于 Linux 和 Windows 容器。
- 数据卷可以在多个容器之间更安全地共享。
- 数据卷驱动程序允许您将数据卷存储在远程主机或云提供商上,以加密数据卷的内容或添加其他功能。
- 新数据卷的内容可以由容器预先填充。
- Docker Desktop 上的数据卷比来自 Mac 和 Windows 主机的绑定挂载具有更高的性能。
此外,与在容器的可写层中持久化数据相比,数据卷通常是更好的选择,因为数据卷不会增加使用它的容器的大小,并且数据卷的内容存在于给定容器的生命周期之外。
如果您的容器生成非持久状态数据,请考虑使用 tmpfs 挂载以避免将数据永久存储在任何地方,并通过避免写入容器的可写层来提高容器的性能。
数据卷挂载可以使用-v 参数或者 --mount参数,本文使用-v参数
#挂载数据卷:-v 本地目录:容器目录 -v /centos-test:/tmp
[root@k8smaster ~]# docker run -it --restart=always --name=centos-test -v /centos-test:/tmp hub.c.163.com/library/centos:latest
[root@38702e15b0d4 /]# ls /tmp/
[root@38702e15b0d4 /]# touch /tmp/aa.txt
[root@38702e15b0d4 /]# ls /tmp/
aa.txt bb.txt
[root@38702e15b0d4 /]# exit
exit
[root@k8smaster ~]# docker inspect centos-test
[
{
"Id": "38702e15b0d49e1b7dcd8ddaa0e98dc050c520e323e6fe45ce773072e8bd2d9b",
......
"Mounts": [
{
"Type": "bind",
"Source": "/centos-test",
"Destination": "/tmp",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
......
}
}
}
}
]
[root@k8smaster ~]# docker rm -f centos-test
centos-test
#-v /centos-test:/tmp:ro容器目录只读挂载
[root@k8smaster ~]# docker run -it --restart=always --name=centos-test -v /centos-test:/tmp:ro hub.c.163.com/library/centos:latest
[root@0c2793968ab4 /]# touch /tmp/cc.txt
touch: cannot touch '/tmp/cc.txt': Read-only file system
[root@0c2793968ab4 /]# exit
exit
#另外一种挂载数据卷的方法:
[root@k8smaster ~]# docker volume create v1
v1
[root@k8smaster ~]# docker volume list
DRIVER VOLUME NAME
local 3512441fd63342a92e4642d4332c2e8c9603b4b536b45173bb77802d1f3db52f
local e58e312c1517081a8508838d8fcda74b895ac034d53740af478c6a18b6552f34
local f80a9bd35412905392fad18903053e122e3d3066239751e0ceca6a5b5fb8884e
local v1
[root@k8smaster ~]# docker volume inspect v1
[
{
"CreatedAt": "2021-12-28T21:57:33+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/v1/_data",
"Name": "v1",
"Options": {},
"Scope": "local"
}
]
[root@k8smaster ~]# docker run -it --restart=always --name=centos-test1 -v v1:/opt:ro hub.c.163.com/library/centos:latest
[root@4f48281dfc07 /]# ls /opt/
[root@4f48281dfc07 /]# exit
exit
[root@k8smaster ~]# docker run -dit --restart=always --name=db -e MYSQL_ROOT_PASSWORD=qwerty hub.c.163.com/library/mysql
eedcd260e5758013bde97205bea0a3c7c4c04bfab8dce308bc41b1b6cac262f4
[root@k8smaster ~]# docker inspect db | grep -i ipaddr
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.6",
"IPAddress": "172.17.0.6",
[root@k8smaster ~]# mysql -uroot -pqwerty -h 172.17.0.6
MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)
MySQL [(none)]> exit
Bye
[root@k8smaster ~]# docker rm -f db
db
[root@k8smaster ~]# docker run -dit --restart=always --name=db -e MYSQL_ROOT_PASSWORD=qwerty -v /mysqldir:/var/lib/mysql hub.c.163.com/library/mysql
09973a94e99861fd5f19e63bf3947d95a3e14fd0de40c1aa0af605af1fad3ab7
[root@k8smaster ~]# ls /mysqldir/