[Kubernetes]ExternalIPの動作を確認する


はじめに

「ClusterIPの動作を確認する」では、ClusterIPはクラスタ内でのみ通信するServiceだとしました。しかし、ClusterIPにはExteralIPを設定することができ、これを設定することで、クラスタ外のノードと通信することができます。
今回はこのExternalIPの動作を確認したいと思います。

設定

ExternalIPはマニフェストのtypeに設定するのではありません。typeはClusterIPです。ややこしいですね。
作成したマニフェストは以下になります。ClusterIPのマニフェストに「spec.externalIPs」を追加します。

sampleExternalIP.yaml
apiVersion: v1
kind: Service
metadata:
  name: external-ip
spec:
  type: ClusterIP
  externalIPs:
    - 10.20.30.20
  ports:
    - name: cluster-port
      protocol: TCP
      port: 8080
      targetPort: 80
  selector:
    app: nginx-dep

設定するIPアドレスは、クラスタを構成するノードのIPアドレスです。全てを指定する必要はありません。ここでは、worker01のみを指定しています。

$ kubectl get node -o wide
NAME           STATUS   ROLES    AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE                KERNEL-VERSION                CONTAINER-RUNTIME
k8s-master     Ready    master   39d   v1.17.3   10.20.30.10   <none>        CentOS Linux 7 (Core)   3.10.0-1062.12.1.el7.x86_64   docker://19.3.6
k8s-worker01   Ready    <none>   39d   v1.17.3   10.20.30.20   <none>        CentOS Linux 7 (Core)   3.10.0-1062.12.1.el7.x86_64   docker://19.3.6
k8s-worker02   Ready    <none>   39d   v1.17.3   10.20.30.30   <none>        CentOS Linux 7 (Core)   3.10.0-1062.12.1.el7.x86_64   docker://19.3.6

ExternalIPの作成

このマニフェストをapplyして、作成したServiceを確認します。

$ kubectl apply -f sampleExternalIP.yaml
service/external-ip created
$ kubectl get svc
NAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
cluster-ip    ClusterIP   10.101.47.213   <none>        8080/TCP   31h
external-ip   ClusterIP   10.98.225.181   10.20.30.20   8080/TCP   7s
kubernetes    ClusterIP   10.96.0.1       <none>        443/TCP    39d
$ kubectl describe svc external-ip
Name:              external-ip
Namespace:         default
Labels:            <none>
Annotations:       kubectl.kubernetes.io/last-applied-configuration:
                     {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"external-ip","namespace":"default"},"spec":{"externalIPs":["10.20...
Selector:          app=nginx-dep
Type:              ClusterIP
IP:                10.98.225.181
External IPs:      10.20.30.20
Port:              cluster-port  8080/TCP
TargetPort:        80/TCP
Endpoints:         192.168.69.236:80,192.168.79.92:80
Session Affinity:  None
Events:            <none>

動作確認

クラスタには以前作成したPod(Deployment)があります。このPodに対して、外部からの疎通を確認します。

$ kubectl get pod -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP               NODE           NOMINATED NODE   READINESS GATES
nginx-6c4975c9f5-v5ljf   1/1     Running   1          31h   192.168.69.236   k8s-worker02   <none>           <none>
nginx-6c4975c9f5-x4bwq   1/1     Running   1          31h   192.168.79.92    k8s-worker01   <none>           <none>

検証で使用しているクラスタは、PC上のVertualBOXで構築しています。クラスタを構成するVMの他に、GatewayとなるVMもありますので、ここからHTTPのリクエストを送信して疎通を確認します。
検証環境はこちらを参照してください。

[gateway ~]$ for i in 1 2 3 4 5 ;do curl -s http://10.20.30.20:8080 | grep pod; sleep 5; done
pod1
pod1
pod1
pod2
pod2

疎通の確認と、バランシングされていることがわかりますね。
また、ExternalIPを設定したノードはworker01(10.20.30.20)のみですが、worker02にデプロイされているPod1にもバランシングされていることがわかります。

ExternalIPに設定して”いない”worker02(10.20.30.30)からは疎通できないことも確認しておきます。

[gateway ~]$ for i in 1 2 3 4 5 ;do curl -s http://10.20.30.30:8080 | grep pod; sleep 5; done
[gateway ~]$

Errorが出るわけではないのでわかりづらいですが、何も応答がなくプロンプトが返ってきます。

まとめ

今回はExternalIPの動作を確認しました。これだけだとNodePortと同じように思えるのですが、NodePortの動作を確認するときに違いを確かめてみたいと思います。