#はじめに
今回はServiceの一つであるNodePortの動作を確認したいと思います。
前回はExternalIPの動作を確認しました。動作的にはNodePortとExternalIPはよく似ていますので、違いを中心に確認したいと思います。
#NodePortの設定と概要
以下のマニフェストを作成しました。
apiVersion: v1
kind: Service
metadata:
name: node-port
spec:
type: NodePort
ports:
- name: node-port
protocol: TCP
port: 8080
targetPort: 80
nodePort: 30001
selector:
app: nginx-dep
NodePortは、全てのworkerノードを入口として外部と通信をします。そのため、ExternalIPでは外部と通信するためのノードのIPアドレスをマニフェストに記載しましたが、NodePortにはその項目がありません。
その代わりに通信を受け付けるためのポート(nodePort)を指定します。マニフェストで指定しなかった場合は、デフォルトの「30000-32767」の範囲で自動で割り当てられます。マニフェストで設定する場合にも、この範囲で指定します。
「port」「targetPort」はClusterIPと同様です。NodePortは内部にClusterIPを包含しているようなイメージです。
#NodePortの作成
このマニフェストをapplyします。
$ kubectl apply -f sampleNodePort.yaml
service/node-port created
$ kubectl get svc -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
cluster-ip ClusterIP 10.101.47.213 <none> 8080/TCP 3d6h app=nginx-dep
external-ip ClusterIP 10.98.225.181 10.20.30.20 8080/TCP 47h app=nginx-dep
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 41d <none>
node-port NodePort 10.101.179.255 <none> 8080:30001/TCP 13s app=nginx-dep
$ kubectl describe svc node-port
Name: node-port
Namespace: default
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"node-port","namespace":"default"},"spec":{"ports":[{"name":"node-...
Selector: app=nginx-dep
Type: NodePort
IP: 10.101.179.255
Port: node-port 8080/TCP
TargetPort: 80/TCP
NodePort: node-port 30001/TCP
Endpoints: 192.168.69.246:80,192.168.79.106:80
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
#動作確認
##外部との疎通
外部(gateway)から疎通できることを確認します。
[gateway ~]$ for i in 1 2 3 4 5 ;do curl -s http://k8s-worker01:30001 | grep pod; sleep 5;done
pod1
pod1
pod1
pod2
pod2
[gateway ~]$ for i in 1 2 3 4 5 ;do curl -s http://k8s-worker02:30001 | grep pod; sleep 5;done
pod1
pod1
pod2
pod1
pod2
2つのworkerノード(worker01/worker02)のどちらからでも疎通できることと、バランシングされていることが確認できますね。
##内部での疎通
NodePortのClusterIPとしての動作も確認してみます。
テスト用の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://node-port.default.svc.cluster.local:8080 ; sleep 5; done ;exit 0
FQDNで指定していますが、ClusterIPと同じ規則です。また、ポート番号は「nodePort」ではなく「port」を指定します。
このマニフェストをapplyして、30秒ほど待ってlogを確認します。
$ kubectl apply -f test_pod.yaml
pod/test-pod created
$ kubectl logs test-pod | grep pod
pod2
pod1
pod2
pod2
pod1
ClusterIPとしてもちゃんと動作していますね。
#まとめ
今回はNodePortの動作を確認しました。
ExternalIPとの違いは、外部との通信の入口となるノードがマニフェストで指定したノードのみ(ExternalIP)か、全ノード(NodePort)かの違いでしょうか。
動作的にはよく似ていますが、ExternalIPはClusterIPそのものを外部と通信できるようにしたもので、NodePortはClusterIPに1つレイヤーを被せた感じですね。その効果のほどまではわからないので、2つの違いを意識しながらこれからも検証したいと思います。