在macOS上使用Podman运行容器时,涉及设置一个Linux虚拟机(VM)来处理容器。然而,当你使用一个bridge网络的Docker Compose配置时,可能会遇到无法直接从macOS访问容器的问题。本篇博客将指导您如何通过使用WireGuard在Podman虚拟机和macOS之间设置桥接网络,从而实现对容器的直接访问。
问题概述
假设您有如下的Docker Compose配置,它在自定义网络上定义了一个Redis主节点和副本:
services:
redis-leader:
image: redis:6.2.6-alpine
networks:
my-net:
ipv4_address: 10.2.2.100
redis-replica:
image: redis:6.2.6-alpine
command: redis-server --replicaof redis-leader 6379
depends_on:
- redis-leader
networks:
my-net:
ipv4_address: 10.2.2.101
networks:
my-net:
driver: bridge
ipam:
config:
- subnet: 10.2.2.0/24
在这个设置中,您将无法直接从macOS访问Redis容器,因为桥接网络仅连接Podman虚拟机内部的容器,使它们与macOS主机隔离。
解决方案:使用WireGuard桥接网络
为了解决这个问题,我们将设置一个WireGuard连接,使Podman虚拟机和macOS之间的通信变得可能。这一设置允许macOS与运行在虚拟机中的容器进行通信。
第一步:在macOS上安装WireGuard
首先,使用Homebrew在macOS上安装WireGuard工具:
brew install wireguard-tools
第二步:为WireGuard生成密钥
接下来,您需要为Podman虚拟机和macOS分别生成两对公钥和私钥。运行以下命令两次以生成密钥:
wg genkey | tee /dev/stderr | wg pubkey
输出的第一行是私钥,第二行是公钥。请确保运行两次命令以生成两组密钥。
第三步:在macOS上配置WireGuard
生成密钥后,在macOS上配置WireGuard。首先,创建所需的目录:
sudo mkdir -p /opt/homebrew/etc/wireguard/
Then, create the configuration file /opt/homebrew/etc/wireguard/wg0.conf:
cat <<EOF > /opt/homebrew/etc/wireguard/wg0.conf
[Interface]
PrivateKey = <private key A> # macOS的私钥
Address = 10.0.0.2/24 # macOS的WireGuard IP
ListenPort = 51820 # WireGuard监听端口
PostUp = ifconfig lo0 inet 100.64.64.64/30 100.64.64.64 alias
PostDown = ifconfig lo0 inet 100.64.64.64/30 100.64.64.64 delete
[Peer]
PublicKey = <public key B> # Podman虚拟机的公钥
AllowedIPs = 10.2.0.0/16, 10.0.0.1/32 # 桥接网络的范围
PersistentKeepalive = 25
EOF
AllowedIPs字段应与您的Docker桥接网络范围匹配。使用以下命令启动macOS上的WireGuard:
sudo wg-quick up wg0
通过运行以下命令检查WireGuard的状态:
sudo wg
请注意,重启后您需要再次运行sudo wg-quick up wg0来重新启动WireGuard。
第四步:在Podman虚拟机上设置WireGuard
接下来,通过SSH登录到Podman虚拟机:
podman machine ssh
创建WireGuard配置文件 /etc/wireguard/wg0.conf:
cat << EOF > /etc/wireguard/wg0.conf
[Interface]
PrivateKey = <private key B> # Podman虚拟机的私钥
Address = 10.0.0.1/24 # Podman虚拟机的WireGuard IP
PostUp = iptables -A FORWARD -i %i -j ACCEPT
PostDown = iptables -D FORWARD -i %i -j ACCEPT
[Peer]
PublicKey = <public key A> # macOS的公钥
AllowedIPs = 10.0.0.2/32 # macOS的WireGuard IP
Endpoint = 100.64.64.64:51820
PersistentKeepalive = 25
EOF
在Podman虚拟机上启动WireGuard:
wg-quick up wg0
为了确保每次Podman虚拟机启动时WireGuard也自动启动,运行以下命令启用它:
systemctl enable wg-quick@wg0
第五步:从macOS访问容器
一旦macOS and Podman虚拟机上的WireGuard都运行起来,您就可以从macOS直接访问容器了。例如,要ping Redis副本:
ping 10.2.2.101
您应该收到如下响应:
PING 10.2.2.101 (10.2.2.101): 56 data bytes
64 bytes from 10.2.2.101: icmp_seq=0 ttl=63 time=5.992 ms
结论
通过在Podman虚拟机和macOS之间配置WireGuard连接,您可以成功地桥接网络并直接从macOS主机访问容器。这一设置在使用Podman在macOS上处理隔离的bridge网络中的容器时特别有用。