Posted at

Azure Kubernetes Service(AKS) におけるインターネット向けトラフィックの送信元グローバル IP アドレスについて


はじめに

以下のドキュメントを図解してみたり検証してみただけです

https://docs.microsoft.com/ja-jp/azure/aks/egress#egress-traffic-overview


結論

AKS の Pod が Internet へアクセスする際は、Azure Load Balancer を経由する

image.png

Azure Load Balancer に Public IP が複数ある場合は、最初に付与された Public IP を送信元のアドレスに用いる

=> Kubernetes としては、最初に作成された LoadBalancer 型 Service の External-IP に相当する

image.png

固定したい場合は、静的 IP アドレスで LoadBalancer 型 Service を作成しておいて、消さないこと。

(参考) https://docs.microsoft.com/ja-jp/azure/aks/egress


検証

まずは Service がない状態。なお、送信元 IP アドレスは http://inet-ip.info/ へcurl することで確認している。

# kubectl get service --all-namespaces

NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 35d
kube-system heapster ClusterIP 10.0.169.238 <none> 80/TCP 35d
kube-system kube-dns ClusterIP 10.0.0.10 <none> 53/UDP,53/TCP 35d
kube-system kubernetes-dashboard ClusterIP 10.0.176.74 <none> 80/TCP 35d
kube-system metrics-server ClusterIP 10.0.94.33 <none> 443/TCP 35d
kube-system tiller-deploy ClusterIP 10.0.97.17 <none> 44134/TCP 2h
#
#
# kubectl run tmp-shell --generator=run-pod/v1 --rm -i --tty --image centos -- /bin/bash
If you don't see a command prompt, try pressing enter.
[root@tmp-shell /]# curl inet-ip.info
104.46.222.180

上記の IP アドレスが何者かは謎だが、少なくとも毎回このアドレスが使われることは保証されないように見える。

次に、LoadBalancer型 Service を作成して検証してみる。送信元 IP アドレスは唯一の EXTERNAL-IP と合致している。

~# kubectl create service loadbalancer testlb-1 --tcp=80

service/testlb-1 created
# kubectl get service --all-namespaces
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 35d
default testlb-1 LoadBalancer 10.0.225.173 104.46.222.111 80:31929/TCP 1m
kube-system heapster ClusterIP 10.0.169.238 <none> 80/TCP 35d
kube-system kube-dns ClusterIP 10.0.0.10 <none> 53/UDP,53/TCP 35d
kube-system kubernetes-dashboard ClusterIP 10.0.176.74 <none> 80/TCP 35d
kube-system metrics-server ClusterIP 10.0.94.33 <none> 443/TCP 35d
kube-system tiller-deploy ClusterIP 10.0.97.17 <none> 44134/TCP 2h
# kubectl run tmp-shell --generator=run-pod/v1 --rm -i --tty --image centos -- /bin/bash
If you don't see a command prompt, try pressing enter.
[root@tmp-shell /]# curl inet-ip.info
104.46.222.111

別のLoadBalancer型 Service を作成して検証してみる。すべての試行を載せてはいないが、毎回、初回に作成した LoadBalancer 型 Service の External-IP が送信元となった。

# kubectl create service loadbalancer testlb-2 --tcp=80

service/testlb-2 created
# kubectl create service loadbalancer testlb-3 --tcp=80
service/testlb-3 created
# kubectl get service --all-namespaces
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 35d
default testlb-1 LoadBalancer 10.0.225.173 104.46.222.111 80:31929/TCP 5m
default testlb-2 LoadBalancer 10.0.106.135 104.46.223.63 80:31985/TCP 2m
default testlb-3 LoadBalancer 10.0.116.64 20.43.83.172 80:32544/TCP 2m
kube-system heapster ClusterIP 10.0.169.238 <none> 80/TCP 35d
kube-system kube-dns ClusterIP 10.0.0.10 <none> 53/UDP,53/TCP 35d
kube-system kubernetes-dashboard ClusterIP 10.0.176.74 <none> 80/TCP 35d
kube-system metrics-server ClusterIP 10.0.94.33 <none> 443/TCP 35d
kube-system tiller-deploy ClusterIP 10.0.97.17 <none> 44134/TCP 2h
# kubectl run tmp-shell --generator=run-pod/v1 --rm -i --tty --image centos -- /bin/bash
If you don't see a command prompt, try pressing enter.
[root@tmp-shell /]# curl inet-ip.info
104.46.222.111

最後に、初回に作成した LoadBalancer 型 Service (test-lb1) を削除して検証してみる。結果、二番目に作成された test-lb2 の EXTERNAL-IP が送信元アドレスとなった。

# kubectl delete service testlb-1

service "testlb-1" deleted
# kubectl get service --all-namespaces
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 35d
default testlb-2 LoadBalancer 10.0.106.135 104.46.223.63 80:31985/TCP 3m
default testlb-3 LoadBalancer 10.0.116.64 20.43.83.172 80:32544/TCP 3m
kube-system heapster ClusterIP 10.0.169.238 <none> 80/TCP 35d
kube-system kube-dns ClusterIP 10.0.0.10 <none> 53/UDP,53/TCP 35d
kube-system kubernetes-dashboard ClusterIP 10.0.176.74 <none> 80/TCP 35d
kube-system metrics-server ClusterIP 10.0.94.33 <none> 443/TCP 35d
kube-system tiller-deploy ClusterIP 10.0.97.17 <none> 44134/TCP 2h
# kubectl run tmp-shell --generator=run-pod/v1 --rm -i --tty --image centos -- /bin/bash
If you don't see a command prompt, try pressing enter.
[root@tmp-shell /]# curl inet-ip.info
104.46.223.63