1、云原生
1.1、什么是云原生
云原生(CloudNative)指的是基于在云中构建、运行应用程序的理念,而打造的一套技术体系。不同于传统数据中心的软件开发、构建模式,云原生包含有“原生为云而设计”的含义,能够有效提升云上资源利用率、缩短开发周期
1.2、云原生架构
从技术的角度出发,云原生架构是基于云原生技术的一组架构原则和设计模式的集合,旨在帮助企业和开发人员充分利用云平台所提供的平台化能力和弹性资源能力
简单说就是业务代码和基础平台分割,进行指责划分。打造Paas(平台即服务)、技术产品化思维
1.3、虚拟技术发展
- 应用程序无法定义资源边界,这会导致资源分配问题
- 解决资源竞争,不同服务器上运行不同程序。维护成本、服务器成本提升
虚拟化部署时代:为了资源隔离问题,引入了虚拟化
容器部署时代:容器类似于VM,但是它们具有轻松的隔离属性
2、Docker什么?
Docker是一个用于开发,交付和运行应用程序的开放平台
Docker是基于Go语言实现的开源容器项目。它诞生于2013年初,最初发起者是dotCloud公司,在2013年年底直接改名为Docker Inc。并专注于Docker相关技术和产品的开发,目前已经成为全球最大的Docker容器服务提供商。官方网站为docker.com
Docker的构想是要实现"Build, Ship and Run Any App, Anywhere",即通过对应用的封装(Packaging)、分发(Distribution)、部署(Deployment)、运行(Runtime)生命周期进行管理,达到应用组件级别的一次构建(封装),到处运行
3、Docker架构
Docker使用客户端-服务器架构。Docker客户端与Docker守护进程对话,后者负责构建、运行和分发Docker容器的繁重工作。Docker 客户端和守护程序可以运行在同一系统上,或者您可以将Docker客户端连接到远程Docker守护程序。Docker客户端和守护进程使用REST API、UNIX 套接字或网络接口进行通信。另一个Docker客户端是Docker Compose,它允许您使用由一组容器组成的应用程序
Docker架构升级
Docker首次发布时,Docker引擎由两个核心组件构成:LXC(Linux Container)和Docker daemon。
Docker daemon是单一的二进制文件,包含诸如Docker客户端、Docker API、容器运行时、镜像构建等
LXC提供了对诸如命名空间(Namespace)和控制组(CGroup等基础工具的操作能力,它们是基于Linux内核的容器虚拟化技术Linux Container容器是一种内核虚拟化技术,可以提供轻量级的虚拟化,以便隔离进程和资源
首先,LXC是基于Linux的。这对于一个立志于跨平台的项目来说是个问题,其次,如此核心的组件依赖于外部工具,这会给项目带来巨大风险,甚至影响其发展
因此,Docker公司开发了名为Libcontainer的自研工具,用于替代LXC。Libcontainer的目标是成为与平台无关的工具,可基于不同内核为Docker上层提供必要的容器交互功能。在Docker 0.9版本中,Libcontainer取代LXC成为默认的执行驱动
OCI:当Docker公司正在进行Docker daemon进程的拆解和重构的时候,OCI也正在着手定义两个容器相关的规范(或者说标准)。比如:镜像规范和容器运行时规范。两个规范均于2017年7月发布了1.0版
所有的容器运行代码在一个单独的OCI兼容层中实现。默认情况下,Docker使用runc来实现这一点。runc是OCI容器运行时标准的参考实现
Runc : runc是OCI容器运行时规范的参考实现。Docker公司参与了规范的制定以及runc的开发。去粗取精,会发现runc实质上是一个轻量级的、针对Libcontainer进行了包装的命令行交互工具(Libcontainer取代了早期Docker架构中的LXC)。
containerd在Linux和Windows中以daemon的方式运行,从1.11版本之后Docker就开始在Linux上使用它。Docker引擎技术栈中,containerd位于daemon和runc所在的OCI层之间。Kubernetes也可以通过cri-containerd使用containerd。containerd是由Docker公司开发的,并捐献给了云原生计算基金会(CloudNative Computing Foundation, CNCF)
Docker整体架构
[root@node1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v1 a80567189207 2 days ago 141MB
bjbfd/nginx latest 605c77e624dd 17 months ago 141MB
bjbfd/nginx v1 605c77e624dd 17 months ago 141MB
nginx latest 605c77e624dd 17 months ago 141MB
wordpress latest c3c92cc3dcb1 17 months ago 616MB
mariadb 10.6.4-focal 12e05d5da3c5 19 months ago 409MB
bjbfd/stress latest 89e5b79daa74 7 years ago 215MB
[root@node1 ~]# docker run -itd nginx:latest
2d95b4eee9cd96a5e47b132e884eb0f4697db593d4275f2324e6b0224e38314b
[root@node1 ~]# docker run -itd bjbfd/nginx:v1
ae04ef37f2c1367117fdf4ac7e6f7167103b18a617c0f3b5b06a88c5c3bb6a84
[root@node1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ae04ef37f2c1 bjbfd/nginx:v1 "/docker-entrypoint.…" 2 seconds ago Up 1 second 80/tcp interesting_gates
2d95b4eee9cd nginx:latest "/docker-entrypoint.…" 13 seconds ago Up 13 seconds 80/tcp funny_bartik
以上启动了两个nginx容器,看一下Linux中的进程
[root@node1 ~]# ps -ef | grep container
root 1262 1 0 09:00 ? 00:00:00 /usr/bin/containerd
root 1271 1 0 09:00 ? 00:00:00 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
root 1629 1209 0 09:02 pts/1 00:00:00 grep --color=auto container
[root@node1 ~]# ps -ef | grep container
root 1262 1 0 09:00 ? 00:00:00 /usr/bin/containerd
root 1271 1 0 09:00 ? 00:00:00 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
root 1676 1 0 09:02 ? 00:00:00 /usr/bin/containerd-shim-runc-v2 -namespace moby -id 2d95b4eee9cd96a5e47b132e884eb0f4697db593d4275f2324e6b0224e38314b -address /run/containerd/containerd.sock
root 1768 1 0 09:03 ? 00:00:00 /usr/bin/containerd-shim-runc-v2 -namespace moby -id ae04ef37f2c1367117fdf4ac7e6f7167103b18a617c0f3b5b06a88c5c3bb6a84 -address /run/containerd/containerd.sock
root 1853 1209 0 09:03 pts/1 00:00:00 grep --color=auto container
Docker通过DockerDaemon的管理,libcontainer的执行,最终创建Docker容器
模块解说 :
模块 | 职责 | 进程 |
---|---|---|
DockerClient | 容器的管理客户端 | Docker run...... |
DockerDaemon | 服务端的能力,包括:Docker Server、Egine和Job。主负责接收Client请求,并通过Engine的Job完成任务执行,比如镜像下载等 | Dockerd |
DockerRegistry | Docker注册服务器,主要负责仓库管理 | |
Graph | 容器镜像的保管者,包括下载、构建镜像以及镜像的分层存储管理 | Dockerd |
Driver | Docker架构中的驱动模块,实现对Docker容器运行环境的定制,定制的维度主要有网络环境、存储方式以及容器的执行方式。实现包括graphdriver、networkdriver和execdriver | Dockerd |
Libcontainer | Libcontainer是一套独立的容器管理解决方案。主要是与Linux内核特征的封装,包括 : namespaces、cgroups以及capabilities等 | Containerd |
DockerContainer | Docker容器运行时,功能类似于传统意义上的虚拟机,具备资源受限、环境与外界隔离的特点。启动几个容器就有几个containerd-shim-runc | containerd-shim-runc |
Docker run时序图
4、Docker安装
1、卸载老的版本
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
2、设置仓库
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
3、安装docker引擎
sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
注意 :
1、老版本需要docker compose的单独安装,新版本docker集成了docker compose,不需要单独安装
2、如果是阿里云ECS云主机,中文乱码解决方式参考 : https://blog.csdn.net/qq_41661056/article/details/105730143
3、阿里云镜像加速器
阿里云 -> 页面搜索 -> 容器镜像服务 -> 镜像工具 -> 镜像加速器
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://xxx.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
5、Docker组件
5.1、镜像
- 把Docker镜像理解为VM模板,VM模板就像停止运行的VM,而Docker镜像就像停止运行的容器
- 镜像由多个层组成,每层叠加之后,从外部看来就如一个独立的对象
- 镜像内部是一个精简的操作系统(OS),同时还包含应用运行所必须的文件和依赖包
5.2、镜像分层
Docker镜像由一些松耦合的只读镜像层组成。所有的Docker镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上,创建新的镜像层
示例 :
[root@node1 wordpress]# docker run -itd nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
Digest: sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31
Status: Downloaded newer image for nginx:latest
0131fa2a222628418fe7462dfadcb2ccec2c3a333a58b8f875d211a7ec4772e1
[root@node1 wordpress]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
bjbfd/nginx latest 605c77e624dd 17 months ago 141MB
nginx latest 605c77e624dd 17 months ago 141MB
wordpress latest c3c92cc3dcb1 17 months ago 616MB
mariadb 10.6.4-focal 12e05d5da3c5 19 months ago 409MB
bjbfd/stress latest 89e5b79daa74 7 years ago 215MB
[root@node1 wordpress]#
[root@node1 nginx]# cat Dockerfile
FROM nginx
RUN echo '这是一个本地构建的nginx镜像' > /usr/share/nginx/html/index.html
基于nginx基础镜像构建一个镜像
[root@node1 nginx]# docker build -t nginx:v1 .
[+] Building 0.1s (6/6) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 133B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/nginx:latest 0.0s
=> [1/2] FROM docker.io/library/nginx 0.0s
=> CACHED [2/2] RUN echo '这是一个本地构建的nginx镜像' > /usr/share/nginx/html/index.html 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:a805671892075472b21360ead42fb53a2ad798b0ab56bab450c52d428ce1441b 0.0s
=> => naming to docker.io/library/nginx:v1 0.0s
[root@node1 nginx]#
[root@node1 nginx]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v1 a80567189207 2 days ago 141MB
bjbfd/nginx latest 605c77e624dd 17 months ago 141MB
nginx latest 605c77e624dd 17 months ago 141MB
wordpress latest c3c92cc3dcb1 17 months ago 616MB
mariadb 10.6.4-focal 12e05d5da3c5 19 months ago 409MB
bjbfd/stress latest 89e5b79daa74 7 years ago 215MB
[root@node1 nginx]#
docker inspect nginx:latest
LowerDir 如下 :
/var/lib/docker/overlay2/b00f6bf28e2dc408c796f09ad94d3f28c64e0a28cbdd6964087e2b26228b2328/diff:
/var/lib/docker/overlay2/ca904171aa0883178d573b413ca24013e624e90395197a2e4914ebbae8388e7d/diff:
/var/lib/docker/overlay2/4885892662a64db663878aee6f36c32d8196195e47a20ff2e0680256e28c20ac/diff:
/var/lib/docker/overlay2/4eb0162b58d4f18bca9c0d48fb39f275dfbf92a59227dc380b7d36f614b45a4e/diff:
/var/lib/docker/overlay2/a8c3e0d43b8b27fd19a575c3051c9cea6450d39d8fbb58c3d34c7d8b898d3b97/diff
docker inspect nginx:v1
LowerDir 如下 :
/var/lib/docker/overlay2/9d155c02707c57771128e397e6e43c9c9691a544e8e5749b87da9ebc5857f554/diff:
/var/lib/docker/overlay2/b00f6bf28e2dc408c796f09ad94d3f28c64e0a28cbdd6964087e2b26228b2328/diff:
/var/lib/docker/overlay2/ca904171aa0883178d573b413ca24013e624e90395197a2e4914ebbae8388e7d/diff:
/var/lib/docker/overlay2/4885892662a64db663878aee6f36c32d8196195e47a20ff2e0680256e28c20ac/diff:
/var/lib/docker/overlay2/4eb0162b58d4f18bca9c0d48fb39f275dfbf92a59227dc380b7d36f614b45a4e/diff:
/var/lib/docker/overlay2/a8c3e0d43b8b27fd19a575c3051c9cea6450d39d8fbb58c3d34c7d8b898d3b97/diff
看到不一样了么?就是v1比latest多了一层,/var/lib/docker/overlay2/9d155c02707c57771128e397e6e43c9c9691a544e8e5749b87da9ebc5857f554/diff:
5.3、容器
- 在虚拟机模型中,一旦启动,就会占有机器上的全部物理资源,如CPU、RAM、存储等
- 容器引擎可以获取系统资源,比如进程树、文件系统以及网络栈,接着将资源分割为安全的互相隔离的资源结构,称之为容器
5.4、容器测试
[root@node1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v1 a80567189207 2 days ago 141MB
bjbfd/nginx latest 605c77e624dd 17 months ago 141MB
nginx latest 605c77e624dd 17 months ago 141MB
wordpress latest c3c92cc3dcb1 17 months ago 616MB
mariadb 10.6.4-focal 12e05d5da3c5 19 months ago 409MB
bjbfd/stress latest 89e5b79daa74 7 years ago 215MB
[root@node1 ~]# docker run -itd nginx:v1
7d63e23cd145290fd49108049940b470f00bea5fc78f5a5dd83288493356415b
[root@node1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7d63e23cd145 nginx:v1 "/docker-entrypoint.…" 3 seconds ago Up 2 seconds 80/tcp stupefied_fermi
10cc2cc80377 nginx:latest "/docker-entrypoint.…" 31 seconds ago Up 30 seconds 80/tcp great_edison
[root@node1 ~]# docker exec -it 7d63e23cd145 /bin/bash
root@7d63e23cd145:/# curl 127.0.0.1
这是一个本地构建的nginx镜像
root@7d63e23cd145:/#
5.5、容器生命周期
5.6、docker仓库
- 仓库(Repository)是集中存放镜像的地方,又分公共仓库和私有仓库
- 注册服务器(Register)是来保存仓库的服务器。一个Register可以支持多个仓库
- Docker运行中使用的默认仓库是Docker Hub公共仓库
简单说,就像maven仓库一样,有本地仓库和原生仓库,本地仓库用来缓存一些包,远程仓库用来保存第三方包,供自己远程发布让别人使用及使用别人的第三方包
登录,输入用户名/密码,因为我已经登录,所以直接success
[root@node1 ~]# docker login
Authenticating with existing credentials...
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
[root@node1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v1 a80567189207 2 days ago 141MB
bjbfd/nginx latest 605c77e624dd 17 months ago 141MB
nginx latest 605c77e624dd 17 months ago 141MB
wordpress latest c3c92cc3dcb1 17 months ago 616MB
mariadb 10.6.4-focal 12e05d5da3c5 19 months ago 409MB
bjbfd/stress latest 89e5b79daa74 7 years ago 215MB
[root@node1 ~]# docker tag bjbfd/nginx:latest bjbfd/nginx:v1
[root@node1 ~]# docker push bjbfd/nginx:v1
The push refers to repository [docker.io/bjbfd/nginx]
d874fd2bc83b: Layer already exists
32ce5f6a5106: Layer already exists
f1db227348d0: Layer already exists
b8d6e692a25e: Layer already exists
e379e8aedd4d: Layer already exists
2edcec3590a4: Layer already exists
v1: digest: sha256:ee89b00528ff4f02f2405e4ee221743ebc3f8e8dd0bfd5c4c20a2fa2aaa7ede3 size: 1570
[root@node1 ~]#
6、详说Libcontainer
上面说到Libcontainer是一套独立的容器管理解决方案,里面包含什么组件呢?
6.1、namespace
namespace是对全局系统资源的一种封装隔离,使得处于不同namespace的进程拥有独立的全局系统资源,改变一个namespace中的系统资源只会影响当前namespace里的进程,对其他namespace中的进程没有影响
[root@node1 ~]# ls -l /proc/1/ns
总用量 0
lrwxrwxrwx 1 root root 0 5月 30 09:56 ipc -> ipc:[4026531839]
lrwxrwxrwx 1 root root 0 5月 30 09:56 mnt -> mnt:[4026531840]
lrwxrwxrwx 1 root root 0 5月 30 09:00 net -> net:[4026531956]
lrwxrwxrwx 1 root root 0 5月 30 09:56 pid -> pid:[4026531836]
lrwxrwxrwx 1 root root 0 5月 30 09:56 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 5月 30 09:56 uts -> uts:[4026531838]
[root@node1 ~]# ls -l /proc/2/ns
总用量 0
lrwxrwxrwx 1 root root 0 5月 30 09:56 ipc -> ipc:[4026531839]
lrwxrwxrwx 1 root root 0 5月 30 09:56 mnt -> mnt:[4026531840]
lrwxrwxrwx 1 root root 0 5月 30 09:56 net -> net:[4026531956]
lrwxrwxrwx 1 root root 0 5月 30 09:56 pid -> pid:[4026531836]
lrwxrwxrwx 1 root root 0 5月 30 09:56 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 5月 30 09:56 uts -> uts:[4026531838]
看到进程1和进程2是在同一个命名空间的
- namespace是libcontainer的左膀右臂,可以说没有隔离即不存在容器
- 容器的本质也是进程,故在派生进程时,Docker Daemon传入了与namespace相关的flag参数,实现namespace的创建,确保容器(进程)被执行之后,也就是在进程在运行时达到namespace隔离的效果
- 容器的整个生命周期中,namespace是最为基础的一块。Docker容器的很多功能均在namespace的基础上完成。简单的理解是:隔离的环境创建完毕之后,内部环境的初始化才能登场
[root@node1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ae04ef37f2c1 bjbfd/nginx:v1 "/docker-entrypoint.…" About an hour ago Up About an hour 80/tcp interesting_gates
2d95b4eee9cd nginx:latest "/docker-entrypoint.…" About an hour ago Up About an hour 80/tcp funny_bartik
[root@node1 ~]# ps -ef | grep nginx
root 1697 1676 0 09:02 pts/0 00:00:00 nginx: master process nginx -g daemon off;
101 1746 1697 0 09:02 pts/0 00:00:00 nginx: worker process
101 1747 1697 0 09:02 pts/0 00:00:00 nginx: worker process
root 1790 1768 0 09:03 pts/0 00:00:00 nginx: master process nginx -g daemon off;
101 1834 1790 0 09:03 pts/0 00:00:00 nginx: worker process
101 1835 1790 0 09:03 pts/0 00:00:00 nginx: worker process
root 3312 1193 0 10:16 pts/0 00:00:00 grep --color=auto nginx
[root@node1 ~]# ls -l /proc/1697/ns
总用量 0
lrwxrwxrwx 1 root root 0 5月 30 10:16 ipc -> ipc:[4026532295]
lrwxrwxrwx 1 root root 0 5月 30 10:16 mnt -> mnt:[4026532293]
lrwxrwxrwx 1 root root 0 5月 30 09:02 net -> net:[4026532298]
lrwxrwxrwx 1 root root 0 5月 30 09:03 pid -> pid:[4026532296]
lrwxrwxrwx 1 root root 0 5月 30 10:16 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 5月 30 10:16 uts -> uts:[4026532294]
[root@node1 ~]# ls -l /proc/1790/ns
总用量 0
lrwxrwxrwx 1 root root 0 5月 30 10:16 ipc -> ipc:[4026532358]
lrwxrwxrwx 1 root root 0 5月 30 10:16 mnt -> mnt:[4026532356]
lrwxrwxrwx 1 root root 0 5月 30 09:03 net -> net:[4026532361]
lrwxrwxrwx 1 root root 0 5月 30 09:03 pid -> pid:[4026532359]
lrwxrwxrwx 1 root root 0 5月 30 10:16 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 5月 30 10:16 uts -> uts:[4026532357]
[root@node1 ~]#
不同容器命名空间一般不相同,但是也是可以相同的
简单来说,命名空间就是用来隔离进程的
6.2、Cgroup
cgroup(control group)是控制组群,是Linux内核的一个特性功能,用来限制、控制与分离一个进程组的资源
内存
准备环境
yum install -y libcgroup libcgroup-tools
修改下内核,让程序可以随便申请内存
echo 1 > /proc/sys/vm/overcommit_memory
关闭交换分区
swapoff -a
1、创建一个cgroup限制
cd /sys/fs/cgroup/memory/
mkdir journey
cd journey
[root@node1 journey]# ll
总用量 0
-rw-r--r-- 1 root root 0 5月 30 15:11 cgroup.clone_children
--w--w--w- 1 root root 0 5月 30 15:11 cgroup.event_control
-rw-r--r-- 1 root root 0 5月 30 15:11 cgroup.procs
-rw-r--r-- 1 root root 0 5月 30 15:11 memory.failcnt
--w------- 1 root root 0 5月 30 15:11 memory.force_empty
-rw-r--r-- 1 root root 0 5月 30 15:11 memory.kmem.failcnt
-rw-r--r-- 1 root root 0 5月 30 15:11 memory.kmem.limit_in_bytes
-rw-r--r-- 1 root root 0 5月 30 15:11 memory.kmem.max_usage_in_bytes
-r--r--r-- 1 root root 0 5月 30 15:11 memory.kmem.slabinfo
-rw-r--r-- 1 root root 0 5月 30 15:11 memory.kmem.tcp.failcnt
-rw-r--r-- 1 root root 0 5月 30 15:11 memory.kmem.tcp.limit_in_bytes
-rw-r--r-- 1 root root 0 5月 30 15:11 memory.kmem.tcp.max_usage_in_bytes
-r--r--r-- 1 root root 0 5月 30 15:11 memory.kmem.tcp.usage_in_bytes
-r--r--r-- 1 root root 0 5月 30 15:11 memory.kmem.usage_in_bytes
-rw-r--r-- 1 root root 0 5月 30 15:11 memory.limit_in_bytes
-rw-r--r-- 1 root root 0 5月 30 15:11 memory.max_usage_in_bytes
-rw-r--r-- 1 root root 0 5月 30 15:11 memory.memsw.failcnt
-rw-r--r-- 1 root root 0 5月 30 15:11 memory.memsw.limit_in_bytes
-rw-r--r-- 1 root root 0 5月 30 15:11 memory.memsw.max_usage_in_bytes
-r--r--r-- 1 root root 0 5月 30 15:11 memory.memsw.usage_in_bytes
-rw-r--r-- 1 root root 0 5月 30 15:11 memory.move_charge_at_immigrate
-r--r--r-- 1 root root 0 5月 30 15:11 memory.numa_stat
-rw-r--r-- 1 root root 0 5月 30 15:11 memory.oom_control
---------- 1 root root 0 5月 30 15:11 memory.pressure_level
-rw-r--r-- 1 root root 0 5月 30 15:11 memory.soft_limit_in_bytes
-r--r--r-- 1 root root 0 5月 30 15:11 memory.stat
-rw-r--r-- 1 root root 0 5月 30 15:11 memory.swappiness
-r--r--r-- 1 root root 0 5月 30 15:11 memory.usage_in_bytes
-rw-r--r-- 1 root root 0 5月 30 15:11 memory.use_hierarchy
-rw-r--r-- 1 root root 0 5月 30 15:11 notify_on_release
-rw-r--r-- 1 root root 0 5月 30 15:11 tasks
2、修改配置,限制内存在100MB内
echo $((100*1024*1024)) > memory.limit_in_bytes
3、编译一个程序来测试下,看能否限制在100M内,代码如下:
#include
#include
#include
int main(int argc, char **argv)
{
int max = -1;
int mb = 0;
char *buffer;
int i;
#define SIZE 500
unsigned int *p = malloc(1024 * 1024 * SIZE);
printf("malloc buffer: %p\n", p);
for (i = 0; i < 1024 * 1024 * (SIZE/sizeof(int)); i++) {
p[i] = 123;
if ((i & 0xFFFFF) == 0) {
printf("%dMB written\n", i >> 18);
usleep(100000);
}
}
pause();
return 0;
}
编译一下
gcc oom.c
使用cgroup来测试下
cgexec -g memory:journey ./a.out
[root@node1 cgroup]# cgexec -g memory:journey ./a.out
malloc buffer: 0x7f7cf9772010
0MB written
4MB written
8MB written
12MB written
16MB written
20MB written
24MB written
28MB written
32MB written
36MB written
40MB written
44MB written
48MB written
52MB written
56MB written
60MB written
64MB written
68MB written
72MB written
76MB written
80MB written
84MB written
88MB written
92MB written
96MB written
已杀死
[root@node1 cgroup]#
注意 : 说白了其实就是把当前的进程id让如到了journey下的tasks中
[root@node1 journey]# cat tasks
9131
[root@node1 journey]# cat tasks
9131
清除环境
删除cgroup下的journey目录的步骤如下:
rmdir /sys/fs/cgroup/memory/journey
如果报错没权限,看看是不是把当前会话的pid放进去了,如果是则把它移出来,命令如下 :
echo $$ > /sys/fs/cgroup/memory/tasks
之后再删除journey目录
CPU
1、安装cgcreate
yum install -y libcgroup
yum install -y libcgroup-tools
2、自定义cgroup
cd /sys/fs/cgroup/cpu
sudo cgcreate -g cpu:journey
cd journey
echo 50000 > cpu.cfs_quota_us
3、模拟消耗CPU进程
while true;do i=i+1;i=i;done
4、给进程设置tasks
cgclassify -g cpu:erikguan 1189
Docker资源隔离
[root@node1 journey]# docker run -it --rm -c 512 bjbfd/stress --cpu 2
stress: info: [1] dispatching hogs: 2 cpu, 0 io, 0 vm, 0 hdd
[root@node1 journey]# docker run -it --cpu-period=100000 --cpu-quota=50000 --rm -c 512 bjbfd/stress --cpu 2
stress: info: [1] dispatching hogs: 2 cpu, 0 io, 0 vm, 0 hdd
[root@node1 journey]# docker run -it --cpu-period=100000 --cpu-quota=100000 --rm -c 512 bjbfd/stress --cpu 2
stress: info: [1] dispatching hogs: 2 cpu, 0 io, 0 vm, 0 hdd
可以看到,如果--cpu-period 和 --cpu-quota 是可以针对多个CPU设置的,如果是多个CPU,那么就会进行资源的平衡分配
比如说如果是一个CPU,那如果--cpu-period=--cpu-quota,自然会让CPU飙到100%左右
如果是--cpu-period等于--cpu-quota,但是CPU设置的是2个,那么各自CPU资源50%左右
如果是--cpu-period是--cpu-quota的一倍,但是CPU设置的是2个,那么各自CPU资源25%左右
Network
[root@node1 wordpress]# cat docker-compose.yml
services:
db:
# We use a mariadb image which supports both amd64 & arm64 architecture
image: mariadb:10.6.4-focal
# If you really want to use MySQL, uncomment the following line
#image: mysql:8.0.27
command: '--default-authentication-plugin=mysql_native_password'
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
- MYSQL_ROOT_PASSWORD=somewordpress
- MYSQL_DATABASE=wordpress
- MYSQL_USER=wordpress
- MYSQL_PASSWORD=wordpress
expose:
- 3306
- 33060
wordpress:
image: wordpress:latest
volumes:
- wp_data:/var/www/html
ports:
- 80:80
restart: always
environment:
- WORDPRESS_DB_HOST=db
- WORDPRESS_DB_USER=wordpress
- WORDPRESS_DB_PASSWORD=wordpress
- WORDPRESS_DB_NAME=wordpress
volumes:
db_data:
wp_data:
[root@node1 wordpress]# docker compose up -d
[+] Building 0.0s (0/0)
[+] Running 3/3
✔ Network wordpress_default Created 0.0s
✔ Container wordpress-wordpress-1 Started 0.6s
✔ Container wordpress-db-1 Started 0.5s
[root@node1 wordpress]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
241beb742e3a wordpress:latest "docker-entrypoint.s…" 6 seconds ago Up 5 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp wordpress-wordpress-1
df4edffe6f14 mariadb:10.6.4-focal "docker-entrypoint.s…" 6 seconds ago Up 5 seconds 3306/tcp, 33060/tcp wordpress-db-1
注意: docker-compose.yml 其中 WORDPRESS_DB_HOST=db,为什么会配置成db呢?
登录 wordpress 容器中,ping一下db看网络是不是通的?
[root@node1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
241beb742e3a wordpress:latest "docker-entrypoint.s…" 18 minutes ago Up 18 minutes 0.0.0.0:80->80/tcp, :::80->80/tcp wordpress-wordpress-1
df4edffe6f14 mariadb:10.6.4-focal "docker-entrypoint.s…" 18 minutes ago Up 18 minutes 3306/tcp, 33060/tcp wordpress-db-1
[root@node1 ~]# docker exec -it 241beb742e3a /bin/bash
root@241beb742e3a:/var/www/html# ping db
bash: ping: command not found
root@241beb742e3a:/var/www/html# cp /etc/apt/sources.list /etc/apt/sources.list.bak && sed -i "s@http://deb.debian.org@http://mirrors.aliyun.com@g" /etc/apt/sources.list && rm -rf /var/lib/apt/lists/* && apt-get update
Get:1 http://mirrors.aliyun.com/debian bullseye InRelease [116 kB]
Get:2 http://mirrors.aliyun.com/debian bullseye-updates InRelease [44.1 kB]
Get:3 http://security.debian.org/debian-security bullseye-security InRelease [48.4 kB]
Get:4 http://mirrors.aliyun.com/debian bullseye/main amd64 Packages [8183 kB]
Get:5 http://security.debian.org/debian-security bullseye-security/main amd64 Packages [245 kB]
Get:6 http://mirrors.aliyun.com/debian bullseye-updates/main amd64 Packages [14.8 kB]
Fetched 8650 kB in 5s (1684 kB/s)
Reading package lists... Done
root@241beb742e3a:/var/www/html# apt-get install iputils-ping
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
libcap2 libcap2-bin libpam-cap
The following NEW packages will be installed:
iputils-ping libcap2 libcap2-bin libpam-cap
0 upgraded, 4 newly installed, 0 to remove and 77 not upgraded.
Need to get 121 kB of archives.
After this operation, 348 kB of additional disk space will be used.
Do you want to continue? [Y/n] Y
Get:1 http://mirrors.aliyun.com/debian bullseye/main amd64 libcap2 amd64 1:2.44-1 [23.6 kB]
Get:2 http://mirrors.aliyun.com/debian bullseye/main amd64 libcap2-bin amd64 1:2.44-1 [32.6 kB]
Get:3 http://mirrors.aliyun.com/debian bullseye/main amd64 iputils-ping amd64 3:20210202-1 [49.8 kB]
Get:4 http://mirrors.aliyun.com/debian bullseye/main amd64 libpam-cap amd64 1:2.44-1 [15.4 kB]
Fetched 121 kB in 0s (391 kB/s)
debconf: delaying package configuration, since apt-utils is not installed
Selecting previously unselected package libcap2:amd64.
(Reading database ... 16124 files and directories currently installed.)
Preparing to unpack .../libcap2_1%3a2.44-1_amd64.deb ...
Unpacking libcap2:amd64 (1:2.44-1) ...
Selecting previously unselected package libcap2-bin.
Preparing to unpack .../libcap2-bin_1%3a2.44-1_amd64.deb ...
Unpacking libcap2-bin (1:2.44-1) ...
Selecting previously unselected package iputils-ping.
Preparing to unpack .../iputils-ping_3%3a20210202-1_amd64.deb ...
Unpacking iputils-ping (3:20210202-1) ...
Selecting previously unselected package libpam-cap:amd64.
Preparing to unpack .../libpam-cap_1%3a2.44-1_amd64.deb ...
Unpacking libpam-cap:amd64 (1:2.44-1) ...
Setting up libcap2:amd64 (1:2.44-1) ...
Setting up libcap2-bin (1:2.44-1) ...
Setting up libpam-cap:amd64 (1:2.44-1) ...
debconf: unable to initialize frontend: Dialog
debconf: (No usable dialog-like program is installed, so the dialog based frontend cannot be used. at /usr/share/perl5/Debconf/FrontEnd/Dialog.pm line 78.)
debconf: falling back to frontend: Readline
Setting up iputils-ping (3:20210202-1) ...
Processing triggers for libc-bin (2.31-13+deb11u2) ...
root@241beb742e3a:/var/www/html# ping db
PING db (172.18.0.2) 56(84) bytes of data.
64 bytes from wordpress-db-1.wordpress_default (172.18.0.2): icmp_seq=1 ttl=64 time=0.093 ms
64 bytes from wordpress-db-1.wordpress_default (172.18.0.2): icmp_seq=2 ttl=64 time=0.076 ms
^C
--- db ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 0.076/0.084/0.093/0.008 ms
root@241beb742e3a:/var/www/html# cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.18.0.3 241beb742e3a
root@241beb742e3a:/var/www/html#
注意,ubuntu加速器 :
cp /etc/apt/sources.list /etc/apt/sources.list.bak && sed -i "s@http://deb.debian.org@http://mirrors.aliyun.com@g" /etc/apt/sources.list && rm -rf /var/lib/apt/lists/* && apt-get update
发现直接ping db是通的
[root@node1 wordpress]# docker inspect wordpress-db-1
[
{
"Id": "df4edffe6f1440a55fe7368d304ff4f5bb3f7b2dfe991372c81d7510de847aed",
"Created": "2023-05-31T03:02:26.234155577Z",
"Path": "docker-entrypoint.sh",
"Args": [
"--default-authentication-plugin=mysql_native_password"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 1696,
"ExitCode": 0,
"Error": "",
"StartedAt": "2023-05-31T03:02:26.766497036Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:12e05d5da3c5223e9877e8eb90d68560ff66cedcb955131061d60d093a908f0c",
"ResolvConfPath": "/var/lib/docker/containers/df4edffe6f1440a55fe7368d304ff4f5bb3f7b2dfe991372c81d7510de847aed/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/df4edffe6f1440a55fe7368d304ff4f5bb3f7b2dfe991372c81d7510de847aed/hostname",
"HostsPath": "/var/lib/docker/containers/df4edffe6f1440a55fe7368d304ff4f5bb3f7b2dfe991372c81d7510de847aed/hosts",
"LogPath": "/var/lib/docker/containers/df4edffe6f1440a55fe7368d304ff4f5bb3f7b2dfe991372c81d7510de847aed/df4edffe6f1440a55fe7368d304ff4f5bb3f7b2dfe991372c81d7510de847aed-json.log",
"Name": "/wordpress-db-1",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "wordpress_default",
"PortBindings": {},
"RestartPolicy": {
"Name": "always",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"ConsoleSize": [
0,
0
],
"CapAdd": null,
"CapDrop": null,
"CgroupnsMode": "host",
"Dns": null,
"DnsOptions": null,
"DnsSearch": null,
"ExtraHosts": [],
"GroupAdd": null,
"IpcMode": "private",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": null,
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": null,
"DeviceCgroupRules": null,
"DeviceRequests": null,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": false,
"PidsLimit": null,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"Mounts": [
{
"Type": "volume",
"Source": "wordpress_db_data",
"Target": "/var/lib/mysql",
"VolumeOptions": {}
}
],
"MaskedPaths": [
"/proc/asound",
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/e3318886258229021434b6efcb9a5a13d10c44ff8e9ec0c670518af592273512-init/diff:/var/lib/docker/overlay2/9f6770cf9af716ae27c68881ee5858253a65ad6fa0f49554cbf49039b12b391f/diff:/var/lib/docker/overlay2/5a8d99a9b8f7de0449343243b04a1e7dbd78ad76f3a45c209f442cedc71533ae/diff:/var/lib/docker/overlay2/4c84801e8550ff953f976d734abb86f437124fbf67031943e732d68f3ed2e303/diff:/var/lib/docker/overlay2/215f31fe18a49c02cf3f14897d8f7fc689354666b06ec55222c4ff3ceeed348f/diff:/var/lib/docker/overlay2/3d0b32da1b848f2e1baad8e6aee469d757aeb990333033299fec356160139a53/diff:/var/lib/docker/overlay2/95a21c51856d00bfc79de70dabcc798eb866ff5c0ec93128cc39fe7a8170cf2b/diff:/var/lib/docker/overlay2/df2dfff8612dbe3c56ca544418d9c7cdacb0bd06d94118b9e8283b3115ed3023/diff:/var/lib/docker/overlay2/374bc7160fbc3f6b1f391a9a1ce05d9210dbb5627bc7e0eca1534d64bc982b51/diff:/var/lib/docker/overlay2/a9777594ba1d0930e43bf7ffc84be1db32419feb61d7e692b73e7a58ca4295f7/diff:/var/lib/docker/overlay2/9ea529592dbb052f869f8ab86a3d7169ea9dd107d49465d84c8d87aa68913785/diff",
"MergedDir": "/var/lib/docker/overlay2/e3318886258229021434b6efcb9a5a13d10c44ff8e9ec0c670518af592273512/merged",
"UpperDir": "/var/lib/docker/overlay2/e3318886258229021434b6efcb9a5a13d10c44ff8e9ec0c670518af592273512/diff",
"WorkDir": "/var/lib/docker/overlay2/e3318886258229021434b6efcb9a5a13d10c44ff8e9ec0c670518af592273512/work"
},
"Name": "overlay2"
},
"Mounts": [
{
"Type": "volume",
"Name": "wordpress_db_data",
"Source": "/var/lib/docker/volumes/wordpress_db_data/_data",
"Destination": "/var/lib/mysql",
"Driver": "local",
"Mode": "z",
"RW": true,
"Propagation": ""
}
],
"Config": {
"Hostname": "df4edffe6f14",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": true,
"AttachStderr": true,
"ExposedPorts": {
"3306": {},
"3306/tcp": {},
"33060": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"MYSQL_ROOT_PASSWORD=somewordpress",
"MYSQL_DATABASE=wordpress",
"MYSQL_USER=wordpress",
"MYSQL_PASSWORD=wordpress",
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"GOSU_VERSION=1.13",
"MARIADB_MAJOR=10.6",
"MARIADB_VERSION=1:10.6.4+maria~focal"
],
"Cmd": [
"--default-authentication-plugin=mysql_native_password"
],
"Image": "mariadb:10.6.4-focal",
"Volumes": {
"/var/lib/mysql": {}
},
"WorkingDir": "",
"Entrypoint": [
"docker-entrypoint.sh"
],
"OnBuild": null,
"Labels": {
"com.docker.compose.config-hash": "1a931c5225f4f77e1bc71a07a8f2f658f90aba92bcdb6b64dd98afe54569e3b7",
"com.docker.compose.container-number": "1",
"com.docker.compose.depends_on": "",
"com.docker.compose.image": "sha256:12e05d5da3c5223e9877e8eb90d68560ff66cedcb955131061d60d093a908f0c",
"com.docker.compose.oneoff": "False",
"com.docker.compose.project": "wordpress",
"com.docker.compose.project.config_files": "/opt/docker-compose/wordpress/docker-compose.yml",
"com.docker.compose.project.working_dir": "/opt/docker-compose/wordpress",
"com.docker.compose.service": "db",
"com.docker.compose.version": "2.18.1"
}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "f67ea95d2e2f40c27e142f49f592632c48f2163a9b3c7af1afd11cf420831993",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {
"3306/tcp": null,
"33060/tcp": null
},
"SandboxKey": "/var/run/docker/netns/f67ea95d2e2f",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "",
"Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "",
"IPPrefixLen": 0,
"IPv6Gateway": "",
"MacAddress": "",
"Networks": {
"wordpress_default": {
"IPAMConfig": null,
"Links": null,
"Aliases": [
"wordpress-db-1",
"db",
"df4edffe6f14"
],
"NetworkID": "b9c6885f3d356548ec1cb4425bdf5b4667517952a1be99a5fce866fe4031366e",
"EndpointID": "860ab7e75760b245f736458c8d5193582a6ada76236ec49e7c288865c533fd0a",
"Gateway": "172.18.0.1",
"IPAddress": "172.18.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:12:00:02",
"DriverOpts": null
}
}
}
}
]
查看容器wordpress-wordpress-1的元数据,发现
"Aliases": [
"wordpress-db-1",
"db",
"df4edffe6f14"
],
看到db和df4edffe6f14有一个别名映射,具体之后再说,现在就知道有映射就可以通过db别名,找到对应容器主机了哈
Docker容器通讯网络
[root@node1 wordpress]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
21c2026e2432 wordpress:latest "docker-entrypoint.s…" 3 seconds ago Up 2 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp wordpress-wordpress-1
2ea884834c25 mariadb:10.6.4-focal "docker-entrypoint.s…" 3 seconds ago Up 2 seconds 3306/tcp, 33060/tcp wordpress-db-1
[root@node1 wordpress]# docker network ls
NETWORK ID NAME DRIVER SCOPE
13cca099cd6e bridge bridge local
4882bc599fcc docker_gwbridge bridge local
06d4d17eacbf host host local
zylych55j9kk ingress overlay swarm
276755b5e003 none null local
36ca37c22576 wordpress_default bridge local
Name | Driver | Desc |
---|---|---|
bridge | bridge | 容器配置veth网络接口对,并配置loopback接口 |
host | host | 不为容器创建网络命名空间 |
none | null | 容器创建网络命名空间,配置loopback接口 |
wordpress_default | bridge | 自定义网络,同一个网络内容器可以互连互通 |
ingress | overlay | 集群外网,不同节点的容器互通 |
docker_gwbridge | bridge | 集群网络,集群的中转网络 |
网络分析
1、启动wordpress,使用docker compose
[root@node1 wordpress]# cat docker-compose.yml
services:
db:
# We use a mariadb image which supports both amd64 & arm64 architecture
image: mariadb:10.6.4-focal
# If you really want to use MySQL, uncomment the following line
#image: mysql:8.0.27
command: '--default-authentication-plugin=mysql_native_password'
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
- MYSQL_ROOT_PASSWORD=somewordpress
- MYSQL_DATABASE=wordpress
- MYSQL_USER=wordpress
- MYSQL_PASSWORD=wordpress
expose:
- 3306
- 33060
wordpress:
image: wordpress:latest
volumes:
- wp_data:/var/www/html
ports:
- 80:80
restart: always
environment:
- WORDPRESS_DB_HOST=db
- WORDPRESS_DB_USER=wordpress
- WORDPRESS_DB_PASSWORD=wordpress
- WORDPRESS_DB_NAME=wordpress
volumes:
db_data:
wp_data:
[root@node1 wordpress]# docker compose up -d
[+] Building 0.0s (0/0)
[+] Running 3/3
✔ Network wordpress_default Created 0.0s
✔ Container wordpress-wordpress-1 Started 0.5s
✔ Container wordpress-db-1 Started 0.5s
2、启动nginx容器
[root@node1 wordpress]# docker run -itd nginx:v1
aa4debaeb394d3463eb73bcd42d135e30bc3d209557ff6837ca48254ea3048e1
[root@node1 wordpress]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
aa4debaeb394 nginx:v1 "/docker-entrypoint.…" 35 minutes ago Up 35 minutes 80/tcp jolly_volhard
3fa6d26fe395 wordpress:latest "docker-entrypoint.s…" 36 minutes ago Up 36 minutes 0.0.0.0:80->80/tcp, :::80->80/tcp wordpress-wordpress-1
580586a0ec98 mariadb:10.6.4-focal "docker-entrypoint.s…" 36 minutes ago Up 36 minutes 3306/tcp, 33060/tcp wordpress-db-1
[root@node1 wordpress]#
3、查看宿主机的网卡
[root@node1 wordpress]# ip a
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
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
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:16:3e:0e:fb:d8 brd ff:ff:ff:ff:ff:ff
inet 172.24.251.132/20 brd 172.24.255.255 scope global dynamic eth0
valid_lft 315354942sec preferred_lft 315354942sec
inet6 fe80::216:3eff:fe0e:fbd8/64 scope link
valid_lft forever preferred_lft forever
3: docker0: mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:83:63:06:bd brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:83ff:fe63:6bd/64 scope link
valid_lft forever preferred_lft forever
4: docker_gwbridge: mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:27:54:34:5a brd ff:ff:ff:ff:ff:ff
inet 172.19.0.1/16 brd 172.19.255.255 scope global docker_gwbridge
valid_lft forever preferred_lft forever
inet6 fe80::42:27ff:fe54:345a/64 scope link
valid_lft forever preferred_lft forever
14: veth3093d94@if13: mtu 1500 qdisc noqueue master docker_gwbridge state UP group default
link/ether fa:3a:5d:53:b9:b8 brd ff:ff:ff:ff:ff:ff link-netnsid 3
inet6 fe80::f83a:5dff:fe53:b9b8/64 scope link
valid_lft forever preferred_lft forever
25: br-0e99973cc931: mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:10:ff:d9:3e brd ff:ff:ff:ff:ff:ff
inet 172.21.0.1/16 brd 172.21.255.255 scope global br-0e99973cc931
valid_lft forever preferred_lft forever
inet6 fe80::42:10ff:feff:d93e/64 scope link
valid_lft forever preferred_lft forever
27: vethd41b331@if26: mtu 1500 qdisc noqueue master br-0e99973cc931 state UP group default
link/ether f6:c3:92:e4:27:9d brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::f4c3:92ff:fee4:279d/64 scope link
valid_lft forever preferred_lft forever
29: veth3d7965e@if28: mtu 1500 qdisc noqueue master br-0e99973cc931 state UP group default
link/ether 46:dd:7c:1a:81:19 brd ff:ff:ff:ff:ff:ff link-netnsid 1
inet6 fe80::44dd:7cff:fe1a:8119/64 scope link
valid_lft forever preferred_lft forever
31: vethff85fdb@if30: mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether aa:17:c7:84:22:dd brd ff:ff:ff:ff:ff:ff link-netnsid 4
inet6 fe80::a817:c7ff:fe84:22dd/64 scope link
valid_lft forever preferred_lft forever
宿主机的网卡,每台机器都有回环地址和网卡:
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
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
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:16:3e:0e:fb:d8 brd ff:ff:ff:ff:ff:ff
inet 172.24.251.132/20 brd 172.24.255.255 scope global dynamic eth0
valid_lft 315354942sec preferred_lft 315354942sec
inet6 fe80::216:3eff:fe0e:fbd8/64 scope link
valid_lft forever preferred_lft forever
docker0 是默认的桥接网络。是运行了 docker 这个软件就会有 docker0
3: docker0: mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:83:63:06:bd brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:83ff:fe63:6bd/64 scope link
valid_lft forever preferred_lft forever
br开头是 docker-compose 创建的网络
25: br-0e99973cc931: mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:10:ff:d9:3e brd ff:ff:ff:ff:ff:ff
inet 172.21.0.1/16 brd 172.21.255.255 scope global br-0e99973cc931
valid_lft forever preferred_lft forever
inet6 fe80::42:10ff:feff:d93e/64 scope link
valid_lft forever preferred_lft forever
查看ningx网络
[root@node1 wordpress]# docker exec -it aa4debaeb394 /bin/bash
root@aa4debaeb394:/# ip a
bash: ip: command not found
root@aa4debaeb394:/# cp /etc/apt/sources.list /etc/apt/sources.list.bak && sed -i "s@http://deb.debian.org@http://mirrors.aliyun.com@g" /etc/apt/sources.list && rm -rf /var/lib/apt/lists/* && apt-get update
Get:1 http://mirrors.aliyun.com/debian bullseye InRelease [116 kB]
Get:2 http://mirrors.aliyun.com/debian bullseye-updates InRelease [44.1 kB]
Get:3 http://mirrors.aliyun.com/debian bullseye/main amd64 Packages [8183 kB]
Get:4 http://security.debian.org/debian-security bullseye-security InRelease [48.4 kB]
Get:5 http://security.debian.org/debian-security bullseye-security/main amd64 Packages [245 kB]
Get:6 http://mirrors.aliyun.com/debian bullseye-updates/main amd64 Packages [14.8 kB]
Fetched 8651 kB in 23s (369 kB/s)
Reading package lists... Done
root@aa4debaeb394:/# ip a
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
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
30: eth0@if31: mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
是不是发现 ip 是 172.17.0.2,docker0的ip 是 172.17.0.1,同一个网段
看wordpress
root@3fa6d26fe395:/var/www/html# ip a
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
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
28: eth0@if29: mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:15:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.21.0.3/16 brd 172.21.255.255 scope global eth0
valid_lft forever preferred_lft forever
看 mariadb:10.6.4-focal
[root@node1 wordpress]# docker exec -it 580586a0ec98 /bin/bash
root@580586a0ec98:/# ip a
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
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
26: eth0@if27: mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:15:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.21.0.2/16 brd 172.21.255.255 scope global eth0
valid_lft forever preferred_lft forever
root@580586a0ec98:/#
是不是发现 ip 是 172.21.0.2和172.21.0.3,br-0e99973cc931的ip 是 172.21.0.1,同一个网段
总结 :
- docker0 是默认的桥接网络。是运行了 docker 这个软件就会有docker0
- veth开头是docker0的儿子
- br开头是docker-compose创建的网络
- br就是bridge 的缩写,docker0 也是 bridge。br和docker0是并列的
如感兴趣,点赞加关注,谢谢!!!