强曰为道

与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

07 - 容器网络

第 07 章 — 容器网络

7.1 网络后端概览

Podman 4.0 起默认使用 Netavark 替代旧版的 CNI(Container Network Interface)。

网络后端版本说明
CNIPodman ≤ 3.x旧版,兼容性好,逐步淘汰
NetavarkPodman 4.0+默认后端,功能更强,支持 IPv6、DNS
# 查看当前网络后端
podman info | grep networkBackend
# networkBackend: netavark

# 查看网络工具版本
podman info | grep -A5 networkBackend

架构对比

CNI(旧版):                    Netavark(推荐):
┌──────────┐                   ┌──────────┐
│  podman  │                   │  podman  │
│          │                   │          │
│  ── CNI plugins (二进制)      │  ── Netavark (Rust 二进制)
│  ├── bridge                  │  ├── bridge
│  ├── flannel                 │  ├── macvlan
│  ├── host-local              │  ├── ipvlan
│  └── ...                     │  ├── firewall
│                              │  └── aardvark-dns (DNS)
└──────────┘                   └──────────┘

7.2 网络模式

7.2.1 Bridge(默认)

# 默认使用 bridge 网络(Podman 创建默认 bridge 网络 podman)
podman run -d --name web nginx:1.27-alpine

# 容器获得独立 IP(Rootless: 10.88.x.x, Root: 10.88.0.x)
podman inspect web --format '{{.NetworkSettings.IPAddress}}'

7.2.2 端口映射

# 基本端口映射
podman run -d -p 8080:80 --name web nginx:1.27-alpine

# 映射多个端口
podman run -d -p 80:80 -p 443:443 --name web nginx:1.27-alpine

# 映射到指定宿主机 IP
podman run -d -p 127.0.0.1:8080:80 --name web nginx:1.27-alpine

# 随机宿主机端口
podman run -d -p 80 --name web nginx:1.27-alpine
podman port web  # 查看实际映射的端口

# 映射 UDP 端口
podman run -d -p 5353:53/udp --name dns mydns:latest

# 映射端口范围
podman run -d -p 3000-3010:3000-3010 --name app myapp:latest

# 查看所有端口映射
podman port web

7.2.3 Host 网络

# 容器直接使用宿主机网络栈(无隔离)
podman run -d --network host --name web nginx:1.27-alpine

# 注意:不需要 -p 参数,直接绑定宿主机端口
# 适用场景:高性能网络应用、需要大量端口的服务

7.2.4 None(无网络)

# 完全禁用网络
podman run -d --network none --name app myapp:latest

# 适用场景:纯计算任务、安全敏感场景

7.2.5 Container 网络

# 共享另一个容器的网络命名空间
podman run -d --name web nginx:1.27-alpine
podman run -d --network container:web --name sidecar fluentd:latest

# sidecar 与 web 共享 localhost(类似 Pod)

7.3 自定义网络

7.3.1 创建自定义网络

# 创建桥接网络
podman network create mynet

# 指定子网
podman network create --subnet 10.89.0.0/24 mynet

# 指定网关
podman network create --subnet 10.89.0.0/24 --gateway 10.89.0.1 mynet

# 创建 IPv6 网络
podman network create --subnet fd00:dead:beef::/48 --ipv6 mynet

# 创建 macvlan 网络(容器获得局域网 IP)
podman network create -d macvlan \
    --subnet 192.168.1.0/24 \
    --gateway 192.168.1.1 \
    -o parent=eth0 \
    my-macvlan

# 查看网络列表
podman network ls

# 查看网络详情
podman network inspect mynet

7.3.2 使用自定义网络

# 容器加入自定义网络
podman run -d --name web --network mynet nginx:1.27-alpine
podman run -d --name app --network mynet myapp:latest

# 自定义网络自带 DNS 解析
podman exec app ping web    # ✅ 可以通过容器名解析
# PING web (10.89.0.2): 56 data bytes
# 64 bytes from 10.89.0.2: seq=0 ttl=42 time=0.123 ms

7.3.3 网络管理命令

# 将运行中的容器连接到网络
podman network connect mynet web

# 断开网络连接
podman network disconnect mynet web

# 删除网络
podman network rm mynet

# 清理未使用的网络
podman network prune

# 重新加载网络配置
podman network reload web

7.4 DNS 解析

7.4.1 自定义网络的 DNS

在自定义网络中,Podman 通过 Aardvark DNS 提供自动 DNS 解析:

# 同一网络中的容器可以互相通过名称解析
podman network create appnet

podman run -d --name db --network appnet postgres:16-alpine
podman run -d --name app --network appnet myapp:latest

# app 容器中可以直接使用 db 作为主机名
podman exec app nslookup db
# Name:      db
# Address:   10.89.0.2

7.4.2 自定义 DNS

# 指定 DNS 服务器
podman run -d --dns 8.8.8.8 --name web nginx:1.27-alpine

# 添加自定义 host 映射
podman run -d \
    --add-host db:10.0.0.5 \
    --add-host cache:10.0.0.6 \
    --name app myapp:latest

# 添加额外 DNS 搜索域
podman run -d --dns-search example.com --name app myapp:latest

# 网络级别配置 DNS
podman network create --dns 10.0.0.53 customnet

7.5 网络配置文件

编辑 /etc/containers/networks/ 或使用 podman network create

{
  "name": "production",
  "id": "a1b2c3d4...",
  "driver": "bridge",
  "network_interface": "podman1",
  "created": "2026-05-10T08:00:00.000000000+08:00",
  "subnets": [
    {
      "subnet": "10.89.1.0/24",
      "gateway": "10.89.1.1"
    }
  ],
  "ipv6_enabled": false,
  "internal": false,
  "dns_enabled": true,
  "ipam_options": {
    "driver": "host-local"
  },
  "options": {
    "mtu": "1500",
    "vlan": "100"
  },
  "labels": {
    "env": "production"
  }
}

7.6 高级网络配置

7.6.1 内部网络(无外部访问)

# 创建内部网络(容器间可通信,但不连接外部网络)
podman network create --internal internal-net

# 数据库等后端服务使用内部网络
podman run -d --name db --network internal-net postgres:16-alpine

# 应用容器同时连接两个网络
podman network connect mynet app-container

7.6.2 macvlan 网络(独立 IP)

# macvlan 让容器获得与宿主机同网段的独立 IP
podman network create -d macvlan \
    --subnet 192.168.1.0/24 \
    --gateway 192.168.1.1 \
    -o parent=eth0 \
    lan-net

podman run -d --name db --network lan-net postgres:16-alpine
# 容器获得 192.168.1.x 的 IP,局域网内可直接访问

7.6.3 流量控制

# 限制容器网络带宽(使用 tc 命令)
# 需要 root 权限或适当的 sysctl 配置

# 查看容器的网络接口
pid=$(podman inspect --format '{{.State.Pid}}' web)
ls -la /proc/$pid/ns/net

# 使用 pasta 网络后端时的流量限制
podman run -d --network pasta:--mtu,1400 --name app myapp:latest

7.7 生产场景

场景一:多层网络隔离

#!/bin/bash
# 三层网络架构

# 前端网络(暴露给外部)
podman network create frontend

# 中间层网络(应用层)
podman network create middle

# 后端网络(数据库,不暴露)
podman network create --internal backend

# Nginx 前端(连接前端和中间层)
podman run -d --name nginx \
    --network frontend \
    -p 80:80 -p 443:443 \
    nginx:1.27-alpine
podman network connect middle nginx

# 应用服务器(连接中间层和后端)
podman run -d --name app \
    --network middle \
    myapp:latest
podman network connect backend app

# 数据库(仅后端网络)
podman run -d --name db \
    --network backend \
    -e POSTGRES_PASSWORD=secret \
    -v pgdata:/var/lib/postgresql/data:Z \
    postgres:16-alpine

# 结果:
# nginx → app → db(单向通信)
# db 无法直接访问 nginx(网络隔离)

场景二:容器对外提供独立 IP

# 使用 macvlan 为每个容器分配局域网 IP
podman network create -d macvlan \
    --subnet 192.168.1.0/24 \
    --gateway 192.168.1.1 \
    -o parent=eth0 \
    lan

# 数据库服务器
podman run -d --name db --network lan postgres:16-alpine
# 获得 IP: 192.168.1.100

# 应用服务器
podman run -d --name app --network lan myapp:latest
# 获得 IP: 192.168.1.101

# 局域网内任何机器可直接访问
ping 192.168.1.100

7.8 常见问题排查

问题 1:容器间无法通信

# 检查是否在同一网络
podman network inspect mynet | grep -A5 "containers"

# 检查 DNS 解析
podman exec app nslookup db

# 检查防火墙
sudo iptables -L -n
sudo firewall-cmd --list-all

问题 2:端口映射不生效

# 检查端口映射
podman port web

# 检查监听端口
ss -tlnp | grep 8080

# Rootless 检查 slirp4netns/pasta 状态
podman inspect web | grep -A10 NetworkSettings

问题 3:DNS 解析失败

# 检查 Aardvark DNS 进程
ps aux | grep aardvark

# 重新加载网络配置
podman network reload --all

# 检查 resolv.conf
podman exec web cat /etc/resolv.conf

7.9 本章小结

知识点要点
网络后端Netavark(Podman 4.0+ 默认)
默认网络bridge,容器获得独立 IP
自定义网络podman network create,自带 DNS
端口映射-p hostPort:containerPort
macvlan容器获得独立局域网 IP
内部网络--internal,无外部连接
DNSAardvark DNS,自定义网络自动解析
最佳实践多层网络隔离保护后端服务

下一步


扩展阅读