接上:企业级容器技术Docker 20250917总结-CSDN博客
八、Docker网络管理
1.Docker的默认的网络通信(学习)
2.创建容器后的网络配置
3.容器间的通信
4.修改默认docker0网桥的网络配置
[root@ubuntu1804 ~]#cat /etc/docker/daemon.json
{
"bip": "192.168.100.1/24",
"registry-mirrors": ["https://si7y70hh.mirror.aliyuncs.com"] }
[root@ubuntu1804 ~]#systemctl restart docker.service
#方法2 docker.service 配置修改
[root@ubuntu1804 ~]#vim /lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
--bip=192.168.100.1/24
[root@ubuntu1804 ~]#systemctl daemon-reload
[root@ubuntu1804 ~]#systemctl restart docker.service
5.修改默认网络设置使用自定义网桥


九、容器名称互联(了解)
实战案例1: 使用容器名称进行容器间通信
实战案例2: 实现 wordpress 和 MySQL 两个容器互连

十、Docker 网络连接模式(重点)
1.Bridge网络模式(默认模式)
[root@ubuntu1804 ~]#cat /proc/sys/net/ipv4/ip_forward #安装docker后.默认启用ip_forward 为1
[root@ubuntu1804 ~]#iptables -vnL -t nat #宿主机的网络状态
范例: 通过宿主机的物理网卡利用SNAT访问外部网络

2.修改默认的 Bridge 模式网络配置
.....
范例: 修改Bridge网络配置方法2
{
"hosts": ["tcp://0.0.0.0:2375", "fd://"],
"bip": "192.168.100.100/24", // 分配docker0网卡的IP,24是容器IP的netmask
"fixed-cidr": "192.168.100.128/26", // 分配容器IP范围,26不是容器IP的子网掩码,只表示地址范围
"fixed-cidr-v6": "2001:db8::/64",
"mtu": 1500,
"default-gateway": "192.168.100.200",// 网关必须和bip在同一个网段
"default-gateway-v6": "2001:db8:abcd::89",
"dns": ["1.1.1.1", "8.8.8.8"]
}
3.Host 模式
范例:
[root@ubuntu1804 ~] #route -n
[root@ubuntu1804 ~] #ss -ntl|grep :80 # 打开容器前确认宿主机的 80/tcp 端口没有打开
4.None 模式
5.Container 模式
范例: 通过容器模式实现 wordpress
方法 1:WordPress 作为网络基础,MySQL 共享其网络
# 启动WordPress容器,暴露80端口并挂载数据卷
[root@ubuntu2004 ~]# docker run -d \
-p 80:80 \
--name wordpress \
-v /data/wordpress:/var/www/html \
--restart=always \
registry.cn-beijing.aliyuncs.com/xiaoming/wordpress:php8.2-apache
# 启动MySQL容器,共享WordPress的网络命名空间(无需单独暴露端口)
[root@ubuntu2004 ~]# docker run \
--network container:wordpress \
-e MYSQL_ROOT_PASSWORD=123456 \
-e MYSQL_DATABASE=wordpress \
-e MYSQL_USER=wordpress \
-e MYSQL_PASSWORD=123456 \
--name mysql \
-d \
-v /data/mysql:/var/lib/mysql \
--restart=always \
registry.cn-beijing.aliyuncs.com/xiaoming/mysql:8.0.29-oracle
方法 2:MySQL 作为网络基础,WordPress 共享其网络
# 启动MySQL容器,配置数据库参数(未显式暴露端口,通过后续共享网络访问)
[root@ubuntu2004 ~]# docker run -d \
-e MYSQL_ROOT_PASSWORD=123456 \
-e MYSQL_DATABASE=wordpress \
-e MYSQL_USER=wordpress \
-e MYSQL_PASSWORD=123456 \
--name mysql \
--restart=always \
registry.cn-beijing.aliyuncs.com/xiaoming/mysql:8.0.29-oracle
# 启动WordPress容器,共享MySQL的网络命名空间(通过MySQL的网络暴露80端口)
[root@ubuntu2004 ~]# docker run -d \
--network container:mysql \
--name wordpress \
--restart=always \
registry.cn-beijing.aliyuncs.com/xiaoming/wordpress:php8.2-apache
两种方法的核心区别
- 网络共享方向不同:方法 1 中 MySQL 共享 WordPress 的网络(依赖 WordPress 暴露的 80 端口);方法 2 中 WordPress 共享 MySQL 的网络(需确保 MySQL 网络能对外提供 80 端口访问)。
- 端口暴露方式:方法 1 显式通过
-p 80:80
暴露端口;方法 2 隐式通过共享网络使用端口(需注意端口冲突)。
server {
listen 80;
server_name www.wang.org;
root /var/www/html;
index index.php index.html index.htm;
client_max_body_size 100m;
location ~ \.php$ {
root /var/www/html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
6.自定义网络模式
注意: 自定义网络内的容器可以直接通过容器名进行相互的访问,而无需使用 --link
1.实战案例: 自定义网络

利用自定义的网络创建容器
[root@ubuntu1804 ~]#docker run -it --rm --network test-net alpine sh
/ # ping -c1 www.baidu.com 可以ping通一次
[root@ubuntu1804 ~]#docker inspect test-net #再开一个新终端窗口查看网络
2.实战案例: 自定义网络中的容器之间通信
[root@ubuntu1804 ~]#docker run -it --rm --network test-net --name test2 alpine sh
/ # ping -c1 test1 #能正常访问
结论: 自定义网络中的容器之间可以直接利用容器名进行通信
3.实战案例: 利用自定义网络实现 Redis Cluster
创建6个 redis 容器
测试访问 redis cluster
4.同一个宿主机之间不同网络的容器通信


实战案例 1: 修改iptables实现同一宿主机上的不同网络的容器间通信

实战案例 2: 通过解决docker network connect 实现同一个宿主机不同网络的容器间通信
1. 创建两个不同的 Docker 网络
打开终端,执行以下命令,创建两个不同的自定义桥接网络net1
和net2
:
docker network create net1
docker network create net2
2. 启动两个容器并分别连接到不同网络
启动容器container1
并将其连接到net1
网络:
docker run -d --name container1 --network net1 alpine sleep infinity
启动容器container2
并将其连接到net2
网络:
docker run -d --name container2 --network net2 alpine sleep infinity
此时,container1
在net1
网络,container2
在net2
网络,它们之间默认无法直接通信。
3. 使用 docker network connect 将容器连接到另一个网络
将container1
连接到net2
网络: 主要步骤
docker network connect net2 container1
现在,container1
同时处于net1
和net2
两个网络中,它可以与这两个网络中的其他容器进行通信。
4. 验证容器间的通信
进入container2
容器:
docker exec -it container2 sh
在container2
容器内,使用ping
命令测试与container1
的连通性,由于container1
现在也在net2
网络,所以可以通过容器名来 ping 通:
ping -c 3 container1
如果看到类似如下的输出,说明通信正常:
PING container1 (172.18.0.3): 56 data bytes
64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.078 ms
64 bytes from 172.18.0.3: seq=1 ttl=64 time=0.070 ms
64 bytes from 172.18.0.3: seq=2 ttl=64 time=0.070 ms
--- container1 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.070/0.072/0.078 ms
同样,也可以进入container1
容器,使用ping
命令测试与container2
的连通性:
docker exec -it container1 sh
ping -c 3 container2
实现跨宿主机的容器之间网络互联(了解)343前
十一、 Docker Compose 容器单机编排(了解)
1.安装docker compose
2.用 docker compose 启动多个容器
# Nginx 服务配置(用于反向代理或静态资源服务)
service-nginx-web:
image: 10.0.0.102/example/nginx-centos7-base:1.6.1
container_name: nginx-web
volumes:
# 宿主机 /data/nginx 目录挂载到容器 /apps/nginx/html,实现静态资源持久化
- /data/nginx:/apps/nginx/html
expose:
# 容器内部暴露的端口(仅用于容器间通信,不对外映射)
- 80
- 443
ports:
# 宿主机端口:容器端口,对外映射 HTTP(80) 和 HTTPS(443) 端口
- "80:80"
- "443:443"
# Tomcat 应用服务 1(业务应用实例 1)
service-tomcat-app1:
image: 10.0.0.102/example/tomcat-web:app1
container_name: tomcat-app1
expose:
# 容器内部暴露 Tomcat 默认端口 8080(供其他容器访问)
- 8080
ports:
# 宿主机 8081 端口映射到容器 8080,对外提供 app1 访问
- "8081:8080"
# Tomcat 应用服务 2(业务应用实例 2)
service-tomcat-app2:
image: 10.0.0.102/example/tomcat-web:app2
container_name: tomcat-app2
expose:
# 容器内部暴露 Tomcat 默认端口 8080(供其他容器访问)
- 8080
ports:
# 宿主机 8082 端口映射到容器 8080,对外提供 app2 访问
- "8082:8080"
十二、Docker 仓库管理

1.下载离线完整安装包,推荐使用
https://github.com/goharbor/harbor/releases/download/v1.10.19/harbor-offline-installer-v1.10.19.tgz
2.解压harbor前先安装docker和docker-compose
3.解压安装harbor
4.运行 harbor 安装脚本
5.使用单主机 Harbor




6.实现 Harbor 高可用
1.安装第二台 harbor主机
2.哪台harbor是源主机,就先在此主机上新建目标


3 在源harbor上新建复制规则实现到目标harbor的单向复制


4.在源harbor上仓库管理中手动执行复制实现初始的同步

5.在目标harbor主机上重复上面操作

6.确认同步成功

7.上传镜像观察是否可以双高同步
1. Docker 有哪些常用指令?
-
docker run
:创建并启动一个新容器。 -
docker start/stop/restart
:启动、停止、重启容器。 -
docker ps
:列出运行中的容器(加-a
选项列出所有容器)。 -
docker images
:列出本地镜像。 -
docker rmi
:删除镜像。 -
docker rm
:删除容器。 -
docker build
:根据 Dockerfile 构建镜像。 -
docker pull/push
:从仓库拉取或推送镜像。 -
docker exec
:在运行中的容器内执行命令。 -
docker logs
:查看容器的日志输出。 -
docker network
:管理网络。 -
docker volume
:管理数据卷。
2. Dockerfile 有哪些指令?
-
FROM
:指定基础镜像。 -
RUN
:执行命令并创建新的镜像层,常用于安装软件包。 -
CMD
:指定容器启动时默认执行的命令。 -
ENTRYPOINT
:配置容器启动后执行的命令(不可被覆盖)。 -
COPY
:从构建上下文复制文件到镜像中。 -
ADD
:类似COPY
,但支持 URL 和自动解压压缩包。 -
ENV
:设置环境变量。 -
ARG
:定义构建时的变量。 -
EXPOSE
:声明容器运行时监听的端口。 -
WORKDIR
:设置工作目录。 -
USER
:指定运行后续命令的用户。 -
VOLUME
:创建挂载点(数据卷)。
3. 两个服务器装了 Docker,双方的容器之间如何实现通信,有几种方式,不同主机的两个容器之间能够通信吗,怎么实现?
-
可以通信。实现跨主机容器通信的主要方式有:
-
Overlay 网络: Docker 自带的 Swarm 模式或第三方网络方案(如 Calico、Flannel)可以创建覆盖网络,使不同主机上的容器仿佛在同一个局域网内。
-
主机网络模式: 使用
--net=host
将容器网络直接绑定到主机网络栈上,容器通过主机IP直接通信。但此方式牺牲了隔离性。 -
端口映射 + 已知IP: 将容器端口映射到主机端口,容器通过对方主机的IP地址和映射出的端口进行通信。这是最简单但不够优雅的方式。
-
服务发现与负载均衡: 使用 Docker Swarm 或 Kubernetes 等编排工具,它们提供内置的服务发现机制,容器只需通过服务名即可访问,无需关心对方的具体IP和主机位置。
-
4. Docker 的网络模式有几种?
Docker 主要有以下几种网络模式:
-
bridge: 默认模式。为容器创建独立的网络命名空间,并通过虚拟网桥(docker0)与主机通信。容器分配私有IP,并通过NAT与外部通信。
-
host: 容器共享主机的网络命名空间,直接使用主机的IP和端口。性能最好,但网络隔离性最差。
-
none: 禁用所有网络,容器只有一个回环接口(lo),不与任何网络连接。
-
**container`: 新容器共享另一个已存在容器的网络命名空间,两者网络环境完全相同。
-
overlay: 用于跨主机通信的覆盖网络,是 Docker Swarm 集群的核心网络模式。
5. Docker的版本号是多少
这个问题没有标准答案,因为 Docker 一直在迭代更新。您可以通过命令 docker version
或 docker --version
来查看您当前安装的 Docker 客户端和服务器(引擎)的具体版本号。
6. Docker容器中如何对外映射内部的端口?
使用 docker run
命令的 -p
或 -P
参数。
-
-p
: 将容器的内部端口映射到主机的指定端口(例如:-p 8080:80
)。 -
-p
: 将容器的内部端口映射到主机的随机高端口。 -
-P
(大写): 自动将 Dockerfile 中EXPOSE
声明的所有端口映射到主机的随机端口。
7. 如何找到某个 Docker容器的输出日志的宿主机位置?
默认情况下,Docker 容器日志存储在宿主机的特定目录下。路径为:
/var/lib/docker/containers//-json.log
其中 `` 是容器的完整ID或名称。您可以使用 docker inspect
命令,并查找 LogPath
字段来精确找到该路径。
8. Docker的Dockerfile中的expose端口暴露与命令执行暴露的区别
-
EXPOSE
(端口暴露): 这是一个声明性的指令。它只在镜像元数据中记录容器运行时将会监听哪些端口。它并不会实际在宿主机上打开或映射这些端口。它主要用于文档说明,以及在使用-P
参数时告知 Docker 需要映射哪些端口。 -
命令执行暴露(
-p
参数): 这是在运行容器时(docker run
)通过-p
参数执行的操作。它完成了实际的端口映射工作,将容器内部的端口绑定到宿主机的端口上,从而使外部能够访问容器内的服务。
9. Docker 如何查看镜像
使用 docker images
或 docker image ls
命令来列出本地主机上的所有镜像。
10. Docker 如何实现容器间互联
-
通过 Docker 网络: 这是推荐的最佳实践。将需要通信的容器加入同一个自定义的 Docker 网络(使用
docker network create
创建)。之后,容器可以通过容器名(由--name
指定)自动解析到对方的IP地址,实现互联。 -
通过 --link 参数: 旧式方法(已废弃),在
docker run
时使用--link
连接另一个容器。不推荐使用,因为它功能有限且可能被移除。
11. Docker使用到哪些技术?分别有什么作用?
Docker 的核心技术基于 Linux 内核的特性:
-
Namespaces: 提供隔离性,包括 PID(进程)、Net(网络)、IPC(进程间通信)、Mnt(文件系统挂载)、UTS(主机名)等命名空间,使容器拥有独立的运行环境。
-
Cgroups: 提供资源限制与统计,控制和管理容器对CPU、内存、磁盘I/O等硬件资源的使用。
-
Union File Systems: 联合文件系统(如 Overlay2、AUFS),通过分层镜像和写时复制(Copy-on-Write)机制,实现镜像的轻量化和高效存储。
12. docker run 运行一个容器,端口映射为8080,一段时间之后忘记当初运行这个容器的命令,请问如何修改映射的端口?
-
首先停止并删除当前运行的容器:
docker stop && docker rm
。 -
然后根据原来的镜像,使用
docker run
命令并指定新的端口映射参数-p
重新运行一个容器。注意:无法直接修改一个已运行容器的端口映射。
13. Dockerfile常用指令有哪些?CMD和entrypoint有什么区别?ADD和COPY有什么区别?
-
常用指令: 参见问题2的答案。
-
CMD vs ENTRYPOINT:
-
CMD
: 定义容器启动时的默认命令和参数。容易被docker run
后面接的命令行参数覆盖。 -
ENTRYPOINT
: 定义容器启动时执行的固定命令。docker run
后面的参数会作为参数传递给ENTRYPOINT
指令的命令。 -
通常组合使用:
ENTRYPOINT
定义可执行文件,CMD
定义默认参数。
-
-
ADD vs COPY:
-
COPY
: 更透明、更推荐。仅支持将本地文件或目录从构建上下文复制到镜像中。 -
ADD
: 在COPY
功能基础上,增加了:-
可以从 URL 下载文件并复制到镜像中。
-
会自动解压压缩文件(如 tar, gzip, zip等)。
-
-
最佳实践: 除非确需自动解压或从远程URL添加,否则应优先使用
COPY
。
-
14. Docker是使用什么协议进行通信的?
Docker 守护进程(Docker Engine)默认通过 Unix 套接字(unix:///var/run/docker.sock
)与客户端(CLI)进行本地通信。也可以配置为监听 TCP 端口(2375/2376),使用 REST API 进行远程通信。2375端口为未加密的HTTP,2376端口为TLS加密的HTTPS。
15. Dockerfile CMD,RUN 区别
-
RUN
: 在构建镜像的过程中执行命令,并提交结果作为一个新的镜像层。常用于安装软件、创建目录等。 -
CMD
: 在容器启动时运行命令。它不会在构建过程中执行,而是指定了镜像被运行成容器后默认执行的命令。
16. Dockerfile 做了哪些优化
优化 Dockerfile 旨在构建更小、更安全、构建缓存更高效的镜像。
-
使用合适的小体积基础镜像: 如 Alpine Linux 或官方提供的
-slim
版本。 -
合并RUN指令: 将多个
RUN
指令用&&
和 ``连接成一个,减少镜像层数。 -
利用构建缓存: 将变化频率低的操作(如拷贝依赖管理文件
package.json
、pipfile
)放在 Dockerfile 前面,变化频率高的操作(如拷贝源代码)放在后面。 -
使用
.dockerignore
文件: 排除构建上下文中不必要的文件,加速构建过程和减小镜像体积。 -
选择性的复制文件: 精确使用
COPY
或ADD
,而不是复制整个构建上下文。 -
使用多阶段构建: 将编译环境和运行环境分离,最终只将编译好的产物复制到小的运行环境镜像中,极大减小最终镜像的大小。
17. Docker 打镜像时需不需要对容器内操作系统进行内核参数优化?
-
通常不需要。容器与宿主机共享同一个内核,容器内部的操作系统(基础镜像)只是文件系统,其内核参数实际是宿主机的内核参数。
-
因此,内核参数的优化应该在宿主机操作系统上进行。在容器镜像内修改内核参数通常是无效的,或者需要特权模式(
--privileged
)才能生效,但这会带来严重的安全风险。正确的做法是直接优化宿主机内核。