#はじめに
これまで、PodやDeploymentなどのWorkloadリソースの動作を確認してきました。
Kubernetesは各ノード間で内部ネットワークを構成していますので、Pod間の通信はPodをデプロイするだけで可能です。しかし、「Service」を利用することで、ロードバランシングやDNSが利用できるようになりますので、「Service」を利用するのが一般的だと思います。
そこで今回はServiceの一つである「ClusterIP」の動作を確認したいと思います。
#ClusterIPの概要
ClusterIPは、クラスタ内でのみ利用可能な仮想IPを持つロードバランサです。
Pod間の通信をロードバランシングします。クラスタの外部に出ることはできません。
##設定
ClusterIPの設定を見ていきます。今回は以下のマニフェストを作成しました。
ClusterIPとDeploymentを合わせて記載しています。
apiVersion: v1
kind: Service
metadata:
name: cluster-ip
spec:
type: ClusterIP
ports:
- name: cluster-port
port: 8080
targetPort: 80
selector:
app: nginx-dep
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx-dep
template:
metadata:
labels:
app: nginx-dep
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
上下が逆になりますが、まずはDeploymentの設定から見ていきます。
ReplicaSetは2つです。各Podには「app: nginx-dep」のラベルが付与されており、コンテナが使用するポートは「80」です。
次にClusterIPの設定を見てみます。
「8080」のポートからのトラフィックを「80」のポートに転送します。そして、SelectorとしてPodのラベルである「app: nginx-dep」を指定しています。指定したラベルを持つPodにバランシングする動作になります。
#動作確認
##ClusterIPとDeploymentの作成
このマニフェストをapplyします。
$ kubectl apply -f sampleClusterIP.yaml
service/cluster-ip created
deployment.apps/nginx created
$ kubectl get service/cluster-ip
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
cluster-ip ClusterIP 10.103.135.178 <none> 8080/TCP 44s
$ $ kubectl get pod -L app -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES APP
nginx-6c4975c9f5-m8cv9 1/1 Running 0 3m46s 192.168.79.75 k8s-worker01 <none> <none> nginx-dep
nginx-6c4975c9f5-xwlzj 1/1 Running 0 3m46s 192.168.69.238 k8s-worker02 <none> <none> nginx-dep
ClusterIPの詳細を確認します。
$ kubectl describe service/cluster-ip
Name: cluster-ip
Namespace: default
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"cluster-ip","namespace":"default"},"spec":{"ports":[{"name":"clus...
Selector: app=nginx-dep
Type: ClusterIP
IP: 10.103.135.178
Port: cluster-port 8080/TCP
TargetPort: 80/TCP
Endpoints: 192.168.69.238:80,192.168.79.75:80
Session Affinity: None
Events: <none>
「IP」の値として「10.103.135.178」が表示されています。これは自動で設定されたClusterIPのIPアドレスです。
次に「Endpoints」に各PodのIPアドレスが表示されていることを確認します。Selectorで設定した値と同じラベルを持つPodのIPアドレスが表示されます。
もし別サービスで同じラベルを持つPodがクラスタ内に存在する場合、そのPodにもバランシングされてしまいますので、ラベル名のつけ方に統一したルールを決めておく必要があります。そのため、意図したPodのIPアドレスが「Endpoints」に表示されていることの他に、意図しないPodのIPアドレスが表示されていないことも確認する必要があります。
##動作確認
設定は問題なさそうですが、実際の動作も確認したいと思います。
方法としては、動作確認用のPodをクラスタ内にデプロイして、そのPodからClusterIPに対してHTTPのリクエストを送ることで確認してみたいと思います。
###下準備
2つのPodに対してどちらにバランシングされたかを確認するために、nginxのindex.htmlに何か目印をつけておきたいと思います。
各Podにログインして、index.htmlを編集します。
$ kubectl exec -it nginx-6c4975c9f5-m8cv9 /bin/bash
root@nginx-6c4975c9f5-m8cv9:/# cd /usr/share/nginx/html/
root@nginx-6c4975c9f5-m8cv9:/usr/share/nginx/html# vi index.html
bash: vi: command not found
root@nginx-6c4975c9f5-m8cv9:/usr/share/nginx/html# echo pod1 >> index.html
root@nginx-6c4975c9f5-m8cv9:/usr/share/nginx/html# exit
exit
viで編集しようと思いましたが、入ってないんですね。。。インストールしても良かったんですが、目印をつけたいだけですので、最後の行に追記しました。雑なやり方ですが、まあわかるでしょう。
もう一つのPodには同様に「pod2」と目印を付けました。
###動作確認用Podのデプロイと確認
動作確認用のPodとして、以下のマニフェストを作成しました。
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
containers:
- name: centos
image: centos:latest
command:
- sh
- -c
args:
- for i in 1 2 3 4 5 ; do curl -s http://10.103.135.178:8080 ; sleep 5; done ;exit 0
5秒間隔で5回HTTPのリクエストを送信します。
このマニフェストをapplyして、30秒ほど待ってからログを確認します。
$ kubectl apply -f test_pod.yaml
pod/test-pod created
$ kubectl logs test-pod | grep pod
pod2
pod1
pod2
pod2
pod1
ちゃんと2つのPodにバランシングされてますね。
#まとめ
今回はServiceの1つであるClusterIPの動作を確認しました。
クラスタ内ではありますがPod間で通信することによって、マイクロサービスっぽくなってきましたね。
バランシングのポリシー(ラウンドロビンとか)設定ができるのかなど、ほかにどのような設定ができるのか調べてみたいと思います。