基于Kubernetes搭建Openvpn Server

什么是OpenVPN

OpenVPN是一个用于创建虚拟专用网络加密通道的软件包,最早由James Yonan编写。OpenVPN允许创建的VPN使用公开密钥、电子证书、或者用户名/密码来进行身份验证。它大量使用了OpenSSL加密库中的SSLv3/TLSv1协议函数库。当前OpenVPN能在Solaris、Linux、OpenBSD、FreeBSD、NetBSD、Mac OS X与Microsoft Windows以及Android和iOS上运行,并包含了许多安全性的功能。它并不是一个基于Web的VPN软件,也不与IPsec及其他VPN软件包兼容。

部署文件

主要包括PersistentVolume、PersistentVolumeClaim、Deployment、Service,参考如下:

PersistentVolume

PV一般情况需要绑定一个nfs服务来持久化数据到磁盘,请替换下边配置中的地址和路径。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: v1
kind: PersistentVolume
metadata:
name: openvpn
labels:
app: openvpn
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
nfs:
server: YOUR_NFS_SERVER_ADDRESS
path: "YOUR_NFS_PATH"

PersistentVolumeClaim

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: openvpn
labels:
app: openvpn
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
selector:
matchLabels:
app: openvpn

Service

Service需要使用externalIP将端口绑定到某个节点的ip上,请将下边<SERVICE_EXTERNAL_IP>替换为某个节点的ip:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apiVersion: v1
kind: Service
metadata:
name: openvpn
labels:
name: openvpn
spec:
ports:
- protocol: TCP
port: 1194
targetPort: 1194
selector:
name: openvpn
type: ClusterIP
externalIPs:
- <SERVICE_EXTERNAL_IP>

Deployment

  • 关于openvpn详细参数配置如下,请跟据实际情况替换(这里默认使用的公司的ldap进行授权认证):
    • <SERVICE_EXTERNAL_IP>: 与Service中设置的externalIP相同。
    • <YOUR_NODE_DNS_IP>: 为你机器的DNS服务器地址,可以通过cat /etc/resolv.conf查看。
    • <YOUR_CLUSTER_SERVICE_CIDR>: 为kubernetes集群的service的ip段和子网掩码。假如,我的Service的ip段为10.233.0.0/18,那么这里的值就填写10.233.0.0 255.255.192.0。关于子网掩码计算可以百度。
    • <YOUR_CLUSTER_DNS_SERVER>: 为kubernetes集群的kube-dns的service的CLuster IP。kubectl get svc -n kube-system | grep kube-dns
    • <YOUR_CLUSTER_POD_SUBNET>: 为kubernetes集群的pod的网络地址。假如,我的pod的ip段为10.233.64.0/18,那么这里的值就是10.233.64.0
    • <YOUR_CLUSTER_POD_MASK>: 为kubernetes集群的pod网段的掩码地址。假如,我的pod的ip段为10.233.64.0/18,那么掩码地址为:255.255.192.0。关于子网掩码计算可以百度。
    • <YOUR_CLUSTER_DOMAIN>: 集群的域,如果在安装集群的时候没有特别配置,默认是cluster.local
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: openvpn
labels:
name: openvpn
spec:
replicas: 1
selector:
matchLabels:
name: openvpn
template:
metadata:
labels:
name: openvpn
spec:
containers:
- name: openvpn
image: 'registry.saas.hand-china.com/tools/rancher-openvpn:latest'
ports:
- containerPort: 1194
protocol: TCP
env:
- name: REMOTE_IP
value: <SERVICE_EXTERNAL_IP>
- name: REMOTE_PORT
value: '1194'
- name: CERT_COUNTRY
value: FR
- name: CERT_PROVINCE
value: PACA
- name: CERT_CITY
value: Marseille
- name: CERT_ORG
value: MDNS
- name: CERT_EMAIL
value: none@example.com
- name: CERT_OU
value: IT
- name: VPNPOOL_NETWORK
value: 10.8.0.0
- name: VPNPOOL_CIDR
value: '16'
- name: OPENVPN_EXTRACONF
value: 'push "dhcp-option DNS <YOUR_NODE_DNS_IP>"\npush "route <YOUR_CLUSTER_SERVICE_CIDR>"'
- name: AUTH_METHOD
value: ldap
- name: AUTH_LDAP_URL
value: 'ldap://ac.hand-china.com'
- name: AUTH_LDAP_SEARCH
value: (employeeNumber=$username)
- name: AUTH_LDAP_BASEDN
value: 'ou=employee,dc=hand-china,dc=com'
- name: PUSHDNS
value: <YOUR_CLUSTER_DNS_SERVER>
- name: PUSHSEARCH
value: <YOUR_CLUSTER_DOMAIN>
- name: ROUTE_NETWORK
value: <YOUR_CLUSTER_POD_SUBNET>
- name: ROUTE_NETMASK
value: <YOUR_CLUSTER_POD_MASK>
resources:
limits:
memory: 100Mi
requests:
memory: 100Mi
volumeMounts:
- name: vpn-openshift
mountPath: /etc/openvpn
terminationMessagePath: /dev/termination-log
imagePullPolicy: Always
securityContext:
privileged: true
volumes:
- name: vpn-openshift
persistentVolumeClaim:
claimName: openvpn
restartPolicy: Always
terminationGracePeriodSeconds: 30
dnsPolicy: ClusterFirst
securityContext: {}
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
revisionHistoryLimit: 2

客户端配置

  • 部署完成之后,你可以通过dashboard界面或者kubectl命令查看到该openvpn对应的pod的日志。在日志中会输出vpn的连接信息和证书。
  • 将证书内容复制下来,保存到一个文件中,并且以.ovpn命名后缀。
  • 接下来就可以使用客户端进行连接了。windows可以下载官方的openvpn客户端,mac用户使用shimo。
  • 更多关于vpn的环境变量配置请参考GITHUB

使用openvpn访问集群

  • 使用vpn客户端连接上集群openvpn后,我们可以在本地直接访问集群里的POD IP和SERVICE。
  • 如果想要用service的dns名称进行访问,需要将dns的名称写全。规则是:<SERVICE_NAME>.<NAMESPACE>.svc.<CLUSTER_DOMAIN>
  • <SERVICE_NAME>: 服务的名称
  • <NAMESPACE>: 命名空间名称
  • <CLUSTER_DOMAIN>: 集群的域,默认是cluster.local
  • 假如,我在test的命名空间下部署可一个nginx应用,并且service的名称叫做nginx1,那么我本地机器可以直接访问http://nginx1.test.svc.cluster.local来访问nginx应用。
setzero wechat