Docker- 7、网络

本文围绕Docker网络展开,介绍了none/host/bridge网络、自定义网络。阐述了容器间多种通信方式,如IP通信、Docker DNS Server等。还说明了容器与外网的访问情况,包括容器默认可访问外网及外部访问容器的端口映射,最后提及了Docker网络架构。

一、none/host/bridge网络

Docker安装时会自动在host上创建3个网络,使用 docker network ls 查看:
none网络:
   就是什么都没有的网络,挂在这个网络下的容器ifconfig只能查到lo,没其他任何网卡,可通过--network=none指定使用none网络
   应用场景:一些安全性高并且不需要联网的应用可以使用none网络。(比如容器的唯一用途用于生成随机密码,这可以避免密码被窃取)
host网络:
  这个容器将不会获得一个独立的network namespace,而是和主机共同使用一个。
   连接到host网络的容器共享Docker host的网络,容器的网络配置与host完全一样可通过--network=host指定使用host网络
   应用场景:性能好,若容器对网络传输效率有较高要求,可选择host网络,但要考虑端口冲突,Docker host(宿主机)上已使用的端口就不能用了。
容器中看到的网卡和主机名跟宿主机host的完全一样。
bridge网络:
   Docker 安装时会创建一个命名为 docker0 的 linux bridge,创建容器时,若不指定--network,会默认挂到docker0上。
   它是Docker的默认网络模式,可以连接到主机的其它接口以及容器之间。
一个新的网络接口veth84f3dc9被挂在docker0,veth84f3dc9是新创建容器的虚拟网卡。

二、自定义网络

Docker提供了3种user-defined网络驱动:bridge、overlay、macvlanoverlay与macvlan用于创建跨主机的网络
通过bridge驱动创建bridge网络:docker network create --driver bridge my_net
查看Docker host的网络结构变化brctl show
查看my_net的配置信息              docker network inspect my_net
若要指定IP段,只需在创建网段时指定--subnet和--gateway参数
docker network create --driver bridge --subnet 172.22.16.0/24 --gateway 172.22.16.1  my_net2
创建容器,默认网络docker0,想使用新网络,在创建容器时通过--network指定,--ip用于指定一个静态IP:
只有使用--subnet创建的网络才能指定静态IP.
docker run -it --network=my_net2 --ip 172.22.16.8 busybox

三、容器间的多种通信方式

ip、Docker DNS SErver、joined容器、容器连接

3.1、容器间通信-IP通信

同一网络中的容器、网关间是可以通信的,my_net2与默认bridge(docker0)属于不同的网桥,二者间不连通。
两个容器要能通信,必须有属于同一个网络的网卡
方法:
  1. 创建容器时指定通过--network指定相同的网络;
  2. 对于已经创建的容器,为容器添加网卡docker network connect my_net2 httpd容器ID

3.2、容器间通信-Docker DNS Server

IP通信不够灵活,因为部署应用前可能无法确定IP,可通过docker自带的DNS服务解决。
1.10版本后,Docker daemon有个内嵌的DNS Server,使容器可以通过“容器名”通信,只需要在启动时用--name为容器命名即可。
docker run  -it  --network=my_net2  --name=bbox2  busybox
局限:只能在自定义网络中使用dockers dns server

3.3、容器间通信-joined容器

joined容器时实现容器间通信的方式,它可以使多个容器共享一个网络栈,共享网卡、配置信息,joined容器间可以通过127.0.0.1直接通信
先创建httpd容器:docker run  -it  --name=web1  httpd,然后创建busybox容器,并通过--network=container:web1指定joined容器为web1
docker run -it --network=container:web1 busybox
busybox容器与httpd容器的网卡mac地址、IP完全一样,他们共享了相同的网络栈,busybox可直接使用127.0.0.1访问web1的httpd服务。
使用场景:
  1. 不同容器的程序希望通过loopback高效快速通信;
  2. 希望监控其它容器的网络流量。

3.4、容器连接

容器启动后,一般通过端口映射来使用容器提供的服务,端口映射只是使用容器服务的一种方式,还可以使用容器连接的方式使用容器服务。
例子:两个容器,一个nginx,一个ubuntu,,启动nginx容器但不分配端口映射,再启动ubuntu,通过容器连接直接在ubuntu中访问nginx服务。
1、启动nginx容器,不分配端口:
   docker run -d --name=nginx1  nginx # 宿主机无法访问
2、启动ubuntu容器,并和nginx容器建立连接:
   docker run -itd --name=ubuntu  --link nginx1:mylink  ubuntu bash  # nginx1是要建立连接的容器,mylink是连接的别名
3、进入ubuntu容器:docker exec -it ubuntu bash
  在ubuntu控制台直接输入 env, 查看环境变量信息:
 
 可以看到,docker为nginx创建了一系列环境变量,每个前缀变量是MYLINK(设置的别名)。开发者使用这些环境变量配置应用程序连接到nginx。该连接是安全的、私有的。

四、容器与外网访问

4.1、容器默认就能访问外网

能访问外网的本质是NAT,查看docker host上的iptables规则iptables -t -nat -S:
这条规则的含义:如果网桥 docker0 收到来自 172.17.0.0/16 网段的外出包,把它交给 MASQUERADE 处理。而 MASQUERADE 的处理方式是将包的源地址替换成 host 的地址发送出去,即做了一次网络地址转换(NAT)

4.2、外部访问容器--端口映射

docker可将容器对外提供服务的端口映射到host的某个端口,外网则可以通过该端口访问容器。容器启动时通过-p参数映射端口:docker run -d -p 80 httpd 或者 docker run -d -p 32768:80 httpd (将容器80端口映射到host上指定端口32768
[root@syslog ~]# docker port 866acde6b80a    # 通过docker ps或docker port查看到host映射的端口,容器80端口映射到host上的32768,可通过<host ip>:<port>访问容器的web服务了
80/tcp -> 0.0.0.0:32768
[root@syslog ~]# curl 10.21.144.111:32768
<html><body><h1>It works!</h1></body></html>
[root@syslog ~]#

每映射一个端口,host会启动一个docker-proxy进程处理访问容器的流量。

外网访问容器用到了docker-proxy和iptables DNAT。

宿主机访问本机容器使用的是iptables DNAT。

外部主机访问容器或容器之间的访问是docker-proxy实现。

五、docker网络架构

    早在Docker1.7版本中,网络部分代码就已经被抽离并单独成为了Docker的网络库,即libnetwork。在此之后,容器的网络模式也被抽像变成了统一接口的驱动。
    为了标准化网络的驱动开发步骤和支持多种网络驱动,Docker公司在libnetwork中使用了CNM(Container Network Model)。CNM定义了构建容器虚拟化网络的模型。同时还提供了可以用于开发多种网络驱动的标准化接口和组件
 libnetwork和Docker daemon及各个网络驱动的关系可以通过下面的图进行形象的表示。

    如上图所示,Docker daemon通过调用libnetwork对外提供的API完成网络的创建和管理等功能。libnetwrok中则使用了CNM来完成网络功能的提供。而CNM中主要有沙盒(sandbox)、端点(endpoint)、网络(network)这3种组件
  libnetwork中内置的5种驱动( bridge驱动、host驱动、overlay驱动、remote驱动、null驱动)则为libnetwork提供了不同类型的网络服务。

docker的bridge自定义网络之间默认是有域名解析的-----容器间通信-Docker DNS Server
docker的bridge自定义网络与系统自带的网桥之间默认是有解析的;
但是docker的系统自带的网桥之间默认是没有解析的。
docker的bridge自定义网络之间:双方可以随便添加对方的网卡
docker的bridge自定义网络与系统自带的网桥之间:只能是系统自带的网桥对应的容器 添加 bridge自定义网络对应的容器的网卡,而反过来会报错。
但是docker的系统自带的网桥之间:是可以通信的,因为是在一个网络桥接上。
docker 1.10开始,内嵌了一个DNS server。dns解析功能必须在自定义网络中使用
<think>我们面对的问题是:在执行 `sudo yum remove docker ...` 命令时,系统返回 `sudo: yum: command not found` 错误。这意味着系统无法找到 `yum` 命令。这通常发生在以下情况: 1. 系统未安装 `yum`(例如,使用 `apt` 的 Debian 系系统) 2. `yum` 的路径不在 `sudo` 的安全路径中 3. `yum` 被损坏或删除 根据引用内容,我们注意到用户在之前的步骤中尝试在 CentOS 系统上安装 Docker,但当前错误提示表明系统可能不是基于 Red Hat 的发行版(如 CentOS、RHEL 等),或者系统环境异常。 ### 解决方案步骤: #### 1. **确认操作系统类型** 首先,我们需要确认操作系统的类型。因为 `yum` 是 Red Hat 系发行版(如 CentOS、RHEL、Fedora)的包管理工具,而 Debian 系(如 Ubuntu、Debian)使用 `apt`。 ```bash cat /etc/os-release ``` 或者 ```bash lsb_release -a ``` 这将显示操作系统的详细信息。 #### 2. **根据系统类型选择正确的包管理工具** - 如果是 **Debian/Ubuntu** 系统: - 卸载 Docker 的命令应使用 `apt`: ```bash sudo apt-get remove docker docker-engine docker.io containerd runc ``` 或者使用更彻底的移除方式(参考 Docker 官方文档): ```bash sudo apt-get purge docker-ce docker-ce-cli containerd.io ``` - 如果是 **CentOS/RHEL** 系统,出现 `yum` 未找到,可能是由于 `yum` 未安装或环境变量问题。可以尝试: - 检查 `yum` 是否存在: ```bash which yum ``` - 如果返回路径(如 `/usr/bin/yum`),则可能是 `sudo` 的 `secure_path` 设置问题。可以尝试: ```bash sudo /usr/bin/yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine ``` - 如果 `which yum` 没有返回,则说明 `yum` 未安装。在 CentOS 系统中,这几乎不可能,除非被误删。可以尝试重新安装 `yum`,但需要谨慎操作。 #### 3. **重新安装 yum(仅限 CentOS/RHEL 系统且确认 yum 被删除)** 如果确认是 CentOS 系统且 `yum` 被删除,需要重新安装。但请注意,重新安装 `yum` 是一个复杂的操作,通常需要从其他正常系统复制或下载 RPM 包。步骤可能如下(以 CentOS 7 为例): - 从镜像站点下载 `yum` 及其依赖的 RPM 包,例如: - 通过 `curl` 或 `wget` 下载(需要事先安装这些工具) - 访问 CentOS 官方镜像站(如 `http://mirror.centos.org/centos/7/os/x86_64/Packages/`)搜索以下包: - yum - yum-metadata-parser - yum-plugin-fastestmirror - python-iniparse - 以及其他依赖(如 `rpm` 等) - 然后使用 `rpm` 命令安装: ```bash sudo rpm -ivh yum-*.rpm ``` 然而,这个过程非常复杂且容易出错,通常建议重装系统更为高效。 #### 4. **使用 Docker 官方提供的卸载脚本** 无论是什么系统,Docker 官方提供了一个便捷的卸载脚本,可以尝试使用: ```bash sudo curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh --uninstall ``` 注意:这个脚本可能只适用于使用官方脚本安装的 Docker。 #### 5. **手动删除 Docker 相关文件** 如果以上方法都失效,可以手动删除: - 删除 Docker 二进制文件: ```bash sudo rm -rf /usr/bin/docker* ``` - 删除 Docker 配置文件: ```bash sudo rm -rf /etc/docker ``` - 删除 Docker 相关库文件: ```bash sudo rm -rf /var/lib/docker ``` ### 总结: 1. 首先确认操作系统类型。 2. 根据系统类型选择正确的包管理工具(Debian/Ubuntu 用 `apt`,CentOS/RHEL 用 `yum`)。 3. 对于 CentOS/RHEL 系统,如果 `yum` 命令找不到,尝试使用绝对路径(`/usr/bin/yum`)或重新安装 `yum`(不推荐,复杂且风险高)。 4. 考虑使用 Docker 官方卸载脚本。 5. 作为最后手段,手动删除 Docker 相关文件。 ### 相关问题: 1. 如何在 Ubuntu 系统上彻底卸载 Docker? 2. 如何修复 CentOS 系统中缺失的 `yum` 命令? 3. 如何手动删除 Docker 的所有残留文件和目录? 4. 如何确认 Docker 是否已经被完全卸载? 5. 在 Linux 系统上,如何根据操作系统类型选择正确的包管理命令? </think>### 解决 `sudo: yum: command not found` 错误的完整指南 #### **问题原因分析** 这个错误通常表明: 1. **系统非CentOS/RHEL系**:您可能在使用Debian/Ubuntu等APT系系统(使用`apt`而非`yum`)[^2] 2. **yum被卸载或损坏**:系统可能已删除yum包管理器 3. **PATH环境变量异常**:系统无法定位yum可执行文件 4. **系统架构不匹配**:可能使用了ARM等特殊架构的镜像 --- ### **解决方案步骤** #### **1. 确认操作系统类型** ```bash # 查看系统信息 cat /etc/os-release # 检查包管理器 which apt || which yum || which dnf ``` - 若输出包含 `ubuntu` 或 `debian` → 使用 **APT** 命令 - 若输出包含 `centos` 或 `rhel` → 使用 **YUM** 命令 #### **2. 根据系统类型选择正确命令** **情况1:Debian/Ubuntu系统(使用APT)** ```bash # 正确卸载命令 sudo apt-get purge docker-ce docker-ce-cli containerd.io docker-buildx-plugin # 彻底清理残留 sudo rm -rf /var/lib/docker sudo rm -rf /var/lib/containerd ``` **情况2:CentOS系统但yum缺失** ```bash # 安装yum(需要网络连接) sudo rpm -ivh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm sudo yum update -y # 验证安装 which yum # 应输出/usr/bin/yum ``` #### **3. 修复PATH环境变量** ```bash # 临时修复PATH export PATH=$PATH:/usr/bin # 永久修复(添加到~/.bashrc) echo 'export PATH=$PATH:/usr/bin' >> ~/.bashrc source ~/.bashrc ``` #### **4. 完整卸载Docker(CentOS系统)** ```bash sudo yum remove -y \ docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine # 清理残留文件 sudo rm -rf /var/lib/docker sudo rm -rf /etc/docker ``` --- ### **关键注意事项** 1. **系统架构验证**: ```bash uname -m # 确认是x86_64还是arm架构 ``` 若使用ARM设备(如树莓派),需用专用命令: ```bash sudo apt-get remove docker.io ``` 2. **安装历史检查**: ```bash # 查看已安装docker包 rpm -qa | grep docker || dpkg -l | grep docker ``` 3. **多版本处理**: - 若同时存在`docker-ce`和`docker.io`,需分别卸载 ```bash sudo apt remove --purge docker-ce docker.io ``` --- ### **卸载验证** ```bash # 检查docker进程 ps aux | grep -i docker # 尝试运行docker命令 docker --version # 应显示"command not found" ``` --- ### **相关问题** 1. 如何在Debian系统上彻底卸载Docker及其所有依赖项? 2. 系统提示`sudo: apt: command not found`时应如何解决? 3. 误删yum后如何在不联网的情况下恢复包管理器? 4. 如何判断Linux系统使用的是APT还是YUM包管理? 5. Docker卸载后为什么仍有残留目录?如何安全清理? > 通过系统类型确认包管理工具是解决问题的关键。Debian系用`apt`,RedHat系用`yum`,两者命令不可混用[^2][^3]。若yum确实丢失,需先恢复基础包管理功能再操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值