14
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Kubernetes (Azure AKS)とローカルネットワークをOpenVPN(443/tcp)で接続する

Last updated at Posted at 2018-04-17

はじめに

皆さんKubernetes使ってますか?サーバーサイドのインフラやネットワーク構成を斟酌せず、システムを構成するために必要なコンテナ群を宣言的に記述するだけで、ナンカイイカンジにサーバーサイドを組み立ててくれるカワイイヤツです。

一方そのKubernetes自体を構築し維持管理するのは大変なので、Kubernetes自体はクラウドに面倒を見てもらいたくなるのは世の常です。

しかし世の中は全てクラウドだけで完結するわけではなく、ローカルシステムと生のパケットをやり取りせざるを得ないことも、ままあります。ローカルネットワークとクラウドの仮想ネットワークをVPN接続するソリューションは、大体どのクラウドでも提供されていますが、要件によってはうまくハマらない場合があります。

例えばAzureのポイント対サイトVPNはクライアントOSがWindowsとMacしかダメとか・・・

そこで今回は、Kubernetes (Azure AKS)上にOpenVPNサーバを構築し、ローカルネットワーク(を模した別サイトの仮想ネットワーク)と接続してみます。最終的には、次のような構成になります。

kubernetes-openvpn.png

検証した環境

Kubernetesクラスタ バージョン
AKS Microsoft AKS 米国中部
Kubernetes 1.8.10
ローカルシステム バージョン
クラウド Microsoft Azure 東日本
OS Ubuntu 16.04 LTS
kubectl端末 バージョン
azure cli 2.0.31
kubectl 1.10.0
OS macOS Sierra 10.12.6

AKSの起動

Azure CLIを使って、米国中央リージョンにAKSを起動します。

注意) AKSを起動するためには、Service Principalを作成できる権限が必要です。もし403エラーが発生するようでしたら、Azureアカウントの管理者に相談してください。

Azure CLIのログイン

login_cli
mac:~$ az login

oauth2で認証するためのキーコードが表示されますので、 https://microsoft.com/devicelogin にブラウザでアクセスしてキーコードを入力し、Azure CLIを認証してください。

AKS用のリソースグループを作成

create_aks_resourcegroup
mac:~$ az group create --name aks --location centralus

米国中央リージョンにAKS用のリソースグループを作ります。

AKS起動

start_aks
mac:~$ az aks create --resource-group aks --name aksCluster --node-count 1 --ssh-key-value $HOME/.ssh/azure.pub

米国中央リージョンにAKSを起動します。

kubectlを設定

configure_kubectl
mac:~$ az aks get-credentials --resource-group aks --name aksCluster

起動したAKSに接続するように、kubectlを設定します。

get_nodes
mac:~$ kubectl get nodes
NAME                       STATUS    ROLES     AGE       VERSION
aks-nodepool1-37708792-0   Ready     agent     16m       v1.8.10

上記のように、aks-...というnodeがリストされていれば、AKSに接続しています。

(オプション)Kubernetes dashboardの表示

open_dashboard
mac:~$ az aks browse --resource-group aks --name aksCluster --disable-browser

別のコンソールからaz aks browseコマンドを実行すると、AKSのManagerとのトンネルを開設します。トンネルが開設されている状態で http://127.0.0.1:8001/ にアクセスすると、Kubernetes dashboardを参照することができます。

Kubernetes上にOpenVPNサーバを構築

AKSの準備ができたので、AKSのKubernetes上に443/tcpでlistenするOpenVPNサーバを構築します。

スクリプト類の取得

mac:~$ git clone https://github.com/nmatsui/kubernetes-openvpn.git
mac:~$ cd kubernetes-openvpn

Kubernetes上にOpenVPNサーバを構築するためのスクリプト類を取得します。

cloneしたnmatsui/kubernetes-openvpnのスクリプトやyamlは、kube-openvpnをベースに443/tcpでVPNをlistenするようにアレンジしたものです。

PKI鍵生成

create_pki
mac:kubernetes-openvpn$ docker run --user=$(id -u) -e OVPN_SERVER_URL=tcp://vpn.example.com:443 -v $PWD:/etc/openvpn:z -ti ptlange/openvpn ovpn_initpki
mac:kubernetes-openvpn$ docker run --user=$(id -u) -e EASYRSA_CRL_DAYS=180 -v $PWD:/etc/openvpn:z -ti ptlange/openvpn easyrsa gen-crl

kube-openvpnのコンテナを用いて、VPN接続で用いるPKI鍵を生成します。FQDNとして vpn.example.com という存在しないドメインを指定していますが、このFQDNは最終的にはOpenVPNクライアントの /etc/hosts で名前解決します。

ここで指定するFQDNは、Kubernetes上に構築されるOpenVPN PODのラベル名にも用いられます。 vpn.example.com 以外のFQDNを使用する場合、 testproxy-1.yamltestproxy-2.yaml のSelectorも合わせて変更してください。

KubernetesのService用ネットワークとPod用ネットワークのCIDR取得

get_service_cidr
mac:kubernetes-openvpn$ kubectl cluster-info dump | grep "service-cluster-ip-range"
get_pod_cidr
mac:kubernetes-openvpn$ kubectl cluster-info dump | grep "cluster-cidr"

OpenVPNはクライアントのルーティングテーブルにOpenVPNサーバへのルーティングをpushすることができます。そのために、KubernetesのServiceとPodのCIDRを取得します。

ただしAzure AKSでは、ServiceのCIDRがうまく取れません(もしかしたら、az aksとかで取れるのかも??)
見る限りAzure AKSは 10.0.0.0/16 でServiceのIPを振っているようですので、ローカルシステム側の仮想ネットワークのCIDRをかぶらないようにしておけば、とりあえず 10.0.0.0/8 を全部Kubernetesにまわしてしまえば問題なさげな感じです。

OpenVPNサーバ起動

start_openvpn_server
mac:kubernetes-openvpn$ ./kube-openvpn/deploy.sh default tcp://vpn.example.com:443 10.0.0.0/8 10.244.0.0/16

./kube-openvpn/deploy.sh を用いて、Kubernetes上にOpenVPNサーバを起動します。内部的にはざっくり次のようなことをしています。

  • namespaceやFQDN、ポート、指定されたCIDRを元にOpenVPNの各種設定値を生成してconfigmapに設定
  • 生成したPKI鍵をsecretに登録
  • ./kube-openvpn/deployment.yamlを用いてOpenVPN PODとServiceを起動

OpenVPNクライアント用の設定ファイルを生成

create_ovpn
mac:kubernetes-openvpn$ docker run --user=$(id -u) -v $PWD:/etc/openvpn:z -ti ptlange/openvpn easyrsa build-client-full client nopass
mac:kubernetes-openvpn$ docker run --user=$(id -u) -e OVPN_SERVER_URL=tcp://vpn.example.com:443 -v $PWD:/etc/openvpn:z --rm ptlange/openvpn ovpn_getclient client > client.ovpn

OpenVPNクライアントがOpenVPNサーバに接続する際の設定ファイルを生成しておきます(後で検証用のVMにscpします)。

接続検証用のローカルシステムの起動

米国中央のAKS上にOpenVPNサーバが起動しましたので、次はローカルシステムを模した仮想ネットワークとクライアントVM(2台)を東日本リージョンに起動します。

ローカルシステム用のリソースグループを作成

create_client_resourcegroup
mac:~$ az group create --name client --location japaneast

東日本リージョンにローカルシステム用のリソースグループを作ります。

ローカルシステム用の仮想ネットワークを作成

  1. vnetとsubnetを作成

    create_vnet
    mac:~$ az network vnet create --resource-group client --name client-vnet --address-prefix 192.168.0.0/16 --subnet-name public --subnet-prefix 192.168.0.0/24
    
  2. 2台のクライアント用にpublic ipを二つ作成

    create_publicip_1
    mac:~$ az network public-ip create --resource-group client --name client-publicip-1 --dns-name client-1
    
    create_publicip_2
    mac:~$ az network public-ip create --resource-group client --name client-publicip-2 --dns-name client-2
    
  3. セキュリティグループを作成

    create_nsg
    mac:~$ az network nsg create --resource-group client --name client-nsg
    
  4. kubectl端末からのSSHを許可

    add_ingress_rule
    mac:~$ az network nsg rule create --resource-group client --nsg-name client-nsg --name AllowSSHInBound --protocol tcp --destination-port-range 22 --source-address-prefixes WWW.XXX.YYY.ZZZ/32 --access allow --priority 1000
    
  5. セキュリティグループとpublic ipを割り当てた仮想NICを二つ作成

    create_nic_1
    mac:~$ az network nic create --resource-group client --name client-nic-1 --vnet-name client-vnet --subnet public --public-ip-address client-publicip-1 --network-security-group client-nsg
    
    create_nic_2
    mac:~$ az network nic create --resource-group client --name client-nic-2 --vnet-name client-vnet --subnet public --public-ip-address client-publicip-2 --network-security-group client-nsg
    

KubernetesにルーティングするCIDR(10.0.0.0/8)とかぶらないように、 192.168.0.0/16 の仮想ネットワーク上に 192.168.0.0/24 のサブネットを構築します。
またInternetからSSHの受信を許可したセキュリティグループを作成し(デフォルトルールにより、仮想ネットワーク内の送受信、及び仮想ネットワークからInternetへの送信は許可されます)、セキュリティグループとpublic ipを割り当てた仮想NICを作成します。

ローカルシステム用の可用性セットを作成

create_as
mac:~$ az vm availability-set create --resource-group client --name client-as

今回は検証なので不要ではありますが、とりあえず可用性セットも作っておきます。

クライアントVMを2台起動

start_vm_1
mac:~$ az vm create --resource-group client --name ubuntu-1 --location japaneast --availability-set client-as --nics client-nic-1 --image UbuntuLTS --size Standard_A1 --admin-username ubuntu --ssh-key-value $HOME/.ssh/azure.pub
start_vm_2
mac:~$ az vm create --resource-group client --name ubuntu-2 --location japaneast --availability-set client-as --nics client-nic-2 --image UbuntuLTS --size Standard_A1 --admin-username ubuntu --ssh-key-value $HOME/.ssh/azure.pub

作成した仮想NICを指定して、Ubuntu 16.04 LTSのVMを2台起動します。

ローカルシステムからKubernetesへVPNで接続

では準備ができましたので、ローカルシステム上の検証用VM(ubuntu-1)からKubernetesへ443/tcpでVPN接続してみます。

OpenVPNクライアント用の設定ファイルをubuntu-1にSCP

OpenVPNクライアント用の設定ファイルを生成で作成された client.ovpn をubuntu-1にSCPします。

OpenVPN ServiceのExternal IP確認と名前解決

get_externalip
mac:kubernetes-openvpn$ kubectl get service -l openvpn=vpn.example.com
NAME      TYPE           CLUSTER-IP    EXTERNAL-IP    PORT(S)         AGE
openvpn   LoadBalancer   10.0.206.64   WW.XX.YY.ZZ    443:32041/TCP   8m

Kubernetes上に起動したOpenVPN Serviceのexternal ipを確認し、OpenVPNサーバ構築時に指定した vpn.example.com で名前解決できるようにします。とりあえず今回は、ubuntu-1の /etc/hosts に設定しておきます。

/etc/hosts
ubuntu-1:~$ cat /etc/hosts
127.0.0.1 localhost
WW.XX.YY.ZZ vpn.example.com

# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts

ubuntu-1からKubernetesへVPN接続の確認

  1. OpenVPNパッケージをインストール

    install_openvpn_on_ubuntu-1
    ubuntu-1:~$ sudo apt update && sudo apt install openvpn -y
    
  2. KubernetesのOpenVPNサーバへ接続

    connect_openvpn
    ubuntu-1:~$ sudo openvpn ./client.ovpn
    ...
    Tue Apr 17 04:01:24 2018 Initialization Sequence Completed
    

Kubernetes上のOpenVPNサーバへ接続します。 Initialization Sequence Completed と表示されれば、接続成功です。

eth0とtun0のIPアドレス確認

eth0
ubuntu-1:~$ ip addr show dev eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0d:3a:50:85:26 brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.4/24 brd 192.168.0.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::20d:3aff:fe50:8526/64 scope link
       valid_lft forever preferred_lft forever
tun0
ubuntu-1:~$ ip addr show dev tun0
3: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 100
    link/none
    inet 10.140.0.2/24 brd 10.140.0.255 scope global tun0
       valid_lft forever preferred_lft forever
    inet6 fe80::7821:bd24:7fde:a992/64 scope link flags 800
       valid_lft forever preferred_lft forever

VPN接続をしているコンソールとは別のコンソールを開き、ubuntu-1のeth0(ローカルシステムの仮想ネットワークに接続したデバイス)のIPアドレスと、tun0(OpenVPNによって開設されたVPNトンネルに接続したデバイス)のIPアドレスを確認します。

今回は、eth0に 192.168.0.4 tun0に 10.140.0.2 が割り当てられました。

ルーティングテーブル確認

show_route
ubuntu-1:~$ ip route show
default via 192.168.0.1 dev eth0
10.0.0.0/8 via 10.140.0.1 dev tun0
10.140.0.0/24 dev tun0  proto kernel  scope link  src 10.140.0.2
10.244.0.0/16 via 10.140.0.1 dev tun0
168.63.129.16 via 192.168.0.1 dev eth0
169.254.169.254 via 192.168.0.1 dev eth0
192.168.0.0/24 dev eth0  proto kernel  scope link  src 192.168.0.4

ついでにルーティングテーブルも確認しておきます。OpenVPNサーバ起動時に指定した10.0.0.0/810.244.0.0/16が、tun0経由で10.140.0.1にルーティングされることがわかります(10.140.0.1は、Kubernetes上のOpenVPNサーバのVPNトンネル出口のIPアドレスです)。

VPN接続を停止

openvpnクライアントからの接続をCtrl-Cで停止し、一旦VPN接続を解除しておきます。

接続検証

ここまでで、Kubernetes上のOpenVPNサーバとローカルシステムがOpenVPNによってネットワーク的に繋がったことがわかりました。ただしこれだけだとつまらないので、実際にローカルシステムからKubernetesのHTTPサービスを、逆にKubernetes上のPODからローカルシステムのHTTPデーモンに接続してみましょう。

Kubernetes側に検証用のPODやServiceを起動しVPN再接続

OpenVPNサーバにローカルシステムへのNAT設定を追加

  1. OpenVPNクライアントの設定

    add_ccd
    mac:kubernetes-openvpn$ kubectl edit configmap openvpn-ccd
    
    diff
    --- /tmp/openvpn-ccd.org	2018-04-17 13:23:32.000000000 +0900
    +++ /tmp/openvpn-ccd	2018-04-17 13:24:14.000000000 +0900
    @@ -5,6 +5,7 @@
     apiVersion: v1
     data:
       example: ifconfig-push 10.140.0.5 255.255.255.0
    +  ubuntu-1: ifconfig-push 10.140.0.2 255.255.255.0
     kind: ConfigMap
     metadata:
       annotations:
    
  2. OpenVPNクライアントに対するPort mappingの設定

    add_portmapping
    mac:kubernetes-openvpn$ kubectl edit configmap openvpn-portmapping
    
    diff
    --- /tmp/openvpn-portmapping.org	2018-04-17 13:28:40.000000000 +0900
    +++ /tmp/openvpn-portmapping	2018-04-17 13:29:10.000000000 +0900
    @@ -5,6 +5,8 @@
     apiVersion: v1
     data:
       "20080": example:80
    +  "8081": ubuntu-1:8081
    +  "8082": ubuntu-1:8082
     kind: ConfigMap
     metadata:
       annotations:
    

Kubernetes上のOpenVPNに、NAT設定を追加します(configmap経由で設定できるようになっています)。

OpenVPNサーバの 8081 及び 8082 ポートに到達したパケットは、VPNトンネルを通って 10.140.0.2(ローカルシステムのubuntu-1のtun0のIPアドレス)の対応するポートに転送されます。

OpenVPNサーバのProxyServiceをKubernetes上に起動

start_testproxy
mac:kubernetes-openvpn$ kubectl apply -f testproxy-1.yaml
mac:kubernetes-openvpn$ kubectl apply -f testproxy-2.yaml

Kubernetesの仕組み上、OpenVPNサーバのPODと他のPODが直接通信するのではなく、OpenVPNサーバにつながるServiceと他のPODが通信する形になります。そのため、8081(や8082)をlistenするServiceを起動してOpenVPNサーバのPODと接続します。

testproxy-1.yaml
apiVersion: v1
kind: Service
metadata:
  name: testproxy-1
  labels:
    app: testproxy-1
spec:
  type: ClusterIP
  selector:
    openvpn: vpn.example.com
  ports:
  - port: 8081
    targetPort: 8081

検証用のHTTPサービスをKubernetes上に起動

start_testservice
mac:kubernetes-openvpn$ kubectl apply -f testservice.yaml

ローカルシステム側からKuberntesへの到達検証用に、どのようなパスにアクセスしても {"message":"hello world!"} というjsonを返す検証用のServiceをポート3000でKubernetes上に起動します。

testservice.yaml
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: testserver
spec:
  replicas: 1
  selector:
    matchLabels:
      app: testserver
  template:
    metadata:
      labels:
        app: testserver
    spec:
      containers:
      - name: testserver
        image: nmatsui/hello-world-api:latest
        ports:
        - containerPort: 3000
          name: testserver
---
apiVersion: v1
kind: Service
metadata:
  name: testservice
  labels:
    app: testservice
spec:
  type: ClusterIP
  selector:
    app: testserver
  ports:
  - port: 3000

このtestserviceのKubernetes内部IPアドレスを確認しておきます。

get_testservice
mac:kubernetes-openvpn$ kubectl get services -l app=testservice

NAME          TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
testservice   ClusterIP   10.0.19.96   <none>        3000/TCP   24m

今回は10.0.19.96が割り当てられました。

ubuntu-1でVPN接続を再開

reconnect_openvpn
ubuntu-1:~$ sudo openvpn ./client.ovpn

ubuntu-1でVPN接続を再開します。再接続することにより、configmapで設定したportmappingが有効になります。

ubuntu-1とKuberntesの接続検証

それでは、ubuntu-1とKuberntesが双方向に接続できることを確認します。

ubuntu-1 ⇒ Kubernetes上のtestserviceの疎通確認

from_ubuntu-1_to_testservice
ubuntu-1:~$ curl -i http://10.0.19.96:3000/
HTTP/1.1 200 OK
Content-Type: application/json
Date: Tue, 17 Apr 2018 04:47:19 GMT
Connection: keep-alive
Transfer-Encoding: chunked

{"message":"hello world!"}

ローカルシステムのubuntu-1からKubernetesのtestserviceのIPアドレスへ、VPNトンネルを通ってHTTP接続できることが確認できました。

ubuntu-1=>testservice.png

Kubernetes上のPOD ⇒ ubuntu-1のHTTPデーモンの疎通確認

  1. ubuntu-1にindex.htmlを準備

    index.html
    <html>
      <head><title>TEST PAGE</title></head>
      <body>ubuntu-1</body>
    </html>
    
  2. ubuntu-1で8081ポートでHTTPデーモン起動

    start_httpd
    ubuntu-1:~$ python -m SimpleHTTPServer 8081
    
  3. Kubernetes上にcurlが使えるPODを起動

    start_pod
    mac:kubernetes-openvpn$ kubectl run testpod --rm -it --image=yauritux/busybox-curl
    
  4. PODからtestproxyの8081ポートへアクセス

    from_pod_to_ubuntu-1
    pod:~$ curl -i http://testproxy-1:8081/
    HTTP/1.0 200 OK
    Server: SimpleHTTP/0.6 Python/2.7.12
    Date: Tue, 17 Apr 2018 05:02:06 GMT
    Content-type: text/html
    Content-Length: 79
    Last-Modified: Tue, 17 Apr 2018 04:57:22 GMT
    
    <html>
      <head><title>TEST PAGE</title></head>
      <body>ubuntu-1</body>
    </html>
    

KubernetesのPODから、OpenVPNサーバのNATを経由して、ubuntu-1のHTTPデーモンにHTTP接続できることが確認できました。

testpod=>ubuntu-1.png

ubuntu-2とKubernetesの接続検証

最後に、Kubernetesとは直接接続されていないubuntu-2とKubernetesが、ubuntu-1でNATすることで双方向に接続できることを確認します。

ubuntu-1にNATを設定

  1. ubuntu-1でパケットのforwardを許可

    enable_ip_forward
    ubuntu-1:~$ sudo sysctl -w net.ipv4.ip_forward=1
    
  2. ubuntu-1のeth0(192.168.0.4)の3000ポート ⇒ Kubernetesのtestserviceの3000ポートへforward

    from_localvnet_to_testservice
    ubuntu-1:~$ sudo iptables -t nat -A PREROUTING -m tcp -p tcp --dst 192.168.0.4 --dport 3000 -j DNAT --to-destination 10.0.19.96:3000
    ubuntu-1:~$ sudo iptables -t nat -A POSTROUTING -m tcp -p tcp --dst 10.0.19.96 --dport 3000 -j SNAT --to-source 10.140.0.2
    
  3. ubuntu-1のtun0(10.140.0.2)の8082ポート ⇒ ubuntu-2の8082ポートへforward

    from_vpn_to_ubuntu-2
    ubuntu-1:~$ sudo iptables -t nat -A PREROUTING -m tcp -p tcp --dst 10.140.0.2 --dport 8082 -j DNAT --to-destination 192.168.0.5:8082
    ubuntu-1:~$ sudo iptables -t nat -A POSTROUTING -m tcp -p tcp --dst 192.168.0.5 --dport 8082 -j SNAT --to-source 192.168.0.4
    
  4. NATテーブルを確認

    show_nat
    ubuntu-1:~$ sudo iptables -L -t nat
    Chain PREROUTING (policy ACCEPT)
    target     prot opt source               destination
    DNAT       tcp  --  anywhere             192.168.0.4          tcp dpt:3000 to:10.0.19.96:3000
    DNAT       tcp  --  anywhere             10.140.0.2           tcp dpt:8082 to:192.168.0.5:8082
    
    Chain INPUT (policy ACCEPT)
    target     prot opt source               destination
    
    Chain OUTPUT (policy ACCEPT)
    target     prot opt source               destination
    
    Chain POSTROUTING (policy ACCEPT)
    target     prot opt source               destination
    SNAT       tcp  --  anywhere             10.0.19.96           tcp dpt:3000 to:10.140.0.2
    SNAT       tcp  --  anywhere             192.168.0.5          tcp dpt:8082 to:192.168.0.4
    
  5. filterテーブルを確認

    • 本来はFORWARDフィルタも設定しなければなりませんが、AzureのVMはデフォルトのフィルタルールが全てACCEPTなので割愛します。
    show_filter
    ubuntu-1:~$ sudo iptables -L -t filter
    Chain INPUT (policy ACCEPT)
    target     prot opt source               destination
    
    Chain FORWARD (policy ACCEPT)
    target     prot opt source               destination
    
    Chain OUTPUT (policy ACCEPT)
    target     prot opt source               destination
    
  6. (option)FORWARDフィルタを追加

    • もしFORWARDをデフォルトでDROPするように設定している場合は、次のようにFORWARDフィルタを追加してください。
    forward_rule
    ubuntu-1:~$ sudo iptables -A FORWARD -m tcp -p tcp --dst 10.0.19.96 --dport 3000 -j ACCEPT
    ubuntu-1:~$ sudo iptables -A FORWARD -m tcp -p tcp --dst 192.168.0.5 --dport 8082 -j ACCEPT
    ubuntu-1:~$ sudo iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
    
    show_forward_filter
    ubuntu-1:~$ sudo iptables -nL FORWARD
    Chain FORWARD (policy DROP)
    target     prot opt source               destination
    ACCEPT     tcp  --  0.0.0.0/0            10.0.19.96           tcp dpt:3000
    ACCEPT     tcp  --  0.0.0.0/0            192.168.0.5          tcp dpt:8082
    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
    

ubuntu-1のiptablesへ、ローカルシステムの仮想ネットワークからtestservice(10.0.19.96)へポート3000を転送するNAT定義と、VPNネットワークからubuntu-2(192.168.0.5)へポート8082を転送するNAT定義を設定します。

ubuntu-2 ⇒ Kubernetes上のtestserviceの疎通確認

from_ubuntu-2_to_testservice
ubuntu-2:~$ curl -i http://192.168.0.4:3000
HTTP/1.1 200 OK
Content-Type: application/json
Date: Tue, 17 Apr 2018 05:28:33 GMT
Connection: keep-alive
Transfer-Encoding: chunked

{"message":"hello world!"}

ubuntu-2はKubernetesと接続されておらず、特段のルーティング設定もしていないため、ubuntu-2からtestserviceのIPアドレス 10.0.19.96 へ直接パケットを投げることはできません。しかしubuntu-1(192.168.0.4)がポート3000をtestservice(10.0.19.96)へNATするため、ubuntu-1経由でKubernetesのtestserviceへHTTP接続できます。

ubuntu-2=>testservice.png

Kubernetes上のPOD ⇒ ubuntu-2のHTTPデーモンの疎通確認

  1. ubuntu-2にindex.htmlを準備

    index.html
    <html>
      <head><title>TEST PAGE</title></head>
      <body>ubuntu-2</body>
    </html>
    
  2. ubuntu-2で8082ポートでHTTPデーモンを起動

    start_httpd
    ubuntu-2:~$ python -m SimpleHTTPServer 8082
    
  3. Kubernetes上にcurlが使えるPODを起動

    start_pod
    mac:kubernetes-openvpn$ kubectl run testpod --rm -it --image=yauritux/busybox-curl
    
  4. PODからtestproxyの8082ポートへアクセス

    from_pod_to_ubuntu-2
    pod:~$ curl -i http://testproxy-2:8082/
    HTTP/1.0 200 OK
    Server: SimpleHTTP/0.6 Python/2.7.12
    Date: Tue, 17 Apr 2018 05:45:23 GMT
    Content-type: text/html
    Content-Length: 79
    Last-Modified: Tue, 17 Apr 2018 05:35:00 GMT
    
    <html>
      <head><title>TEST PAGE</title></head>
      <body>ubuntu-2</body>
    </html>
    

KubernetesのPODから、OpenVPNサーバのNATとubuntu-1のNATを経由して、ubuntu-2のHTTPデーモンにHTTP接続できることが確認できました。

testpod=>ubuntu-2.png

さいごに

ということで、Kubernetes上に構築したOpenVPNサーバを経由してKubernetesとローカルシステムの仮想ネットワークを接続することができました(現時点では、OpenVPN Podがspofですが・・・)。
OpenVPNクライアントVMのNAT周りの設定が面倒ですが、ローカルシステム側の他のVMは特段の設定をせずともKubernetesと連携できるようになるため、ここは我慢のしどころということで。
上手く活用して、幸せなKubernetesライフを過ごしましょう!

14
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?