docker与物理网络互通

微服务的流行推动着容器技术的发展,伴随着新技术的应用产生了新的问题。比如开发人员本机无法运行诸多的微服务,如何保障开发正常进行。本文将介绍如何打通开发环境网与docker环境之间的网络。

网络互通配置

由于Kubernetes集群会使用CNI插件创建Pod/Service内部子网,外面一般无法访问内部IP和域名,给开发、测试、 联调带来了很大的麻烦,因此打通开发测试环境Kubernetes集群内部子网和办公室的局域网、实现互联互通是经常遇到的问题。

通过路由跳转打通容器网络

选一台docker节点做路由转发,连接办公室网络和 docker 集群服务

  • 节点 IP 地址 192.168.1.90
  • 容器网段 10.42.0.0/16
  • 办公网段 192.168.0.0/24

image-20210303144129408

我的网络整体结构本身不复杂,所以相对来说配置简单。

节点,做snat:

开启转发

1
2
3
vim /etc/sysctl.d/k8s.conf
net.ipv4.ip_forward = 1
sysctl -p

来自办公室访问dockerservice snat

1
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -d 10.42.0.0/16 -j MASQUERADE

在办公室的出口路由器上,设置静态路由,将docker的网段,路由到节点上

1
ip route 10.42.0.0 255.255.255.0 192.168.1.90

以上步骤操作后,我们就可以在本地电脑通过访问docker ip去访问服务。

image-20210303135329788

通过VPN打通容器网络

生成服务端配置文件和证书

生成服配置文件

1
2
3
4
5
6
7
8
9
10
OVPN_DATA=/data/openvpn
SERVER_PUBLIC_URL=172.30.4.195
DNS_SERVER=180.168.255.118
SERVER_SUBNET=10.4.0.0/24

docker run \
-v ${OVPN_DATA}:/etc/openvpn \
--rm \
kylemanna/openvpn:2.4 \
ovpn_genconfig -u udp://${SERVER_PUBLIC_URL} -n ${DNS_SERVER} -p "route 10.42.0.0 255.255.0.0" -s ${SERVER_SUBNET}

参数说明

-u SERVER_PUBLIC_URL # vpn所在服务器的公网ip
-n DNS_SERVER # dns服务器地址
-p PUSH # 推送路由
-s SERVER_SUBNET # vpn内网范围,一定要注意,不要和已有物理网络、Kubernetes网络冲突。

image-20210731141857240

修改配置

注释push "block-outside-dns"一行,我这里不注释 dns 解析异常

生成密钥文件

1
2
3
4
5
6
7
OVPN_DATA=/data/openvpn

docker run \
-v ${OVPN_DATA}:/etc/openvpn \
--rm -it \
kylemanna/openvpn:2.4 \
ovpn_initpki

在此要输入ca的密码,需要输入两次。

1
2
Enter New CA Key Passphrase:
Re-Enter New CA Key Passphrase:

image-20210723095326974

此处要输入组织,可直接回车跳过。

1
Common Name (eg: your user, host, or server name) [Easy-RSA CA]:

输入之前设置的私钥密码,需要输入两次

1
Enter pass phrase for /etc/openvpn/pki/private/ca.key:

image-20210723095711430

启动OpenVPN服务

1
2
3
4
5
6
7
8
OVPN_DATA=/data/openvpn

docker run -d \
--name openvpn \
-v ${OVPN_DATA}:/etc/openvpn \
-p 1194:1194/udp \
--cap-add=NET_ADMIN \
kylemanna/openvpn:2.4

生成客户端配置和证书

生成客户端证书

CLIENTNAME可以是你想要的名字

1
2
3
4
5
6
7
8
OVPN_DATA=/data/openvpn
CLIENTNAME=docker

docker run \
-v ${OVPN_DATA}:/etc/openvpn \
--rm -it \
kylemanna/openvpn:2.4 \
easyrsa build-client-full ${CLIENTNAME} nopass

输入之前设置的密码

1
Enter pass phrase for /etc/openvpn/pki/private/ca.key:

image-20210723100324352

导出客户端配置

1
2
3
4
5
6
7
8
9
OVPN_DATA=/data/openvpn
CLIENTNAME=docker

mkdir -p /data/openvpn/conf
docker run \
-v ${OVPN_DATA}:/etc/openvpn \
--rm \
kylemanna/openvpn:2.4 \
ovpn_getclient ${CLIENTNAME} > /data/openvpn/conf/${CLIENTNAME}.ovpn

基于用户密码方式认证

参考之前的Cenos7搭建OpenVPN

最终配置

服务端配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
server 10.4.0.0 255.255.255.0
verb 3
key /etc/openvpn/pki/private/192.168.1.91.key
ca /etc/openvpn/pki/ca.crt
cert /etc/openvpn/pki/issued/192.168.1.91.crt
dh /etc/openvpn/pki/dh.pem
#tls-auth /etc/openvpn/pki/ta.key
key-direction 0
keepalive 10 60
persist-key
persist-tun

proto udp
# Rely on Docker to do port mapping, internally always 1194
port 1194
dev tun0
status /tmp/openvpn-status.log

user nobody
group nogroup
comp-lzo no

### Route Configurations Below
route 192.168.254.0 255.255.255.0

### Push Configurations Below
#push "block-outside-dns"
push "dhcp-option DNS 180.168.255.118"
push "comp-lzo no"
push "route 10.42.0.0 255.255.0.0"

client-cert-not-required
auth-user-pass-verify /etc/openvpn/checkpsw.sh via-env
username-as-common-name
script-security 3

客户端配置文件

1
2
3
4
5
6
7
8
9
10
11
12
client
nobind
dev tun
auth-user-pass
remote-cert-tls server
remote 192.168.1.91 1194 udp

<ca>
-----BEGIN CERTIFICATE-----

-----END CERTIFICATE-----
</ca>

参考链接:

打通Kubernetes内网与局域网的N种方法

办公环境下 Kubernetes 网络互通方案

OpenVPN访问Kubernetes集群内网