tjtjtjのメモ

自分のためのメモです

kubernetes 学習 NodePort

前回は、クラスタ内部間の通信を調べた。 クラスタ外部 -> サービス -> pod の経路を調べたい。

確認

kb2 に pod:29pkt, pod:nrj9j。kb3 に pod:n9t8t。

$ kubectl get pod -o wide
NAME                                  READY   STATUS    RESTARTS   AGE   IP            NODE   NOMINATED NODE   READINESS GATES
kbhello-deployment-664dd576d4-29pkt   1/1     Running   0          24h   10.244.1.90   kb2    <none>           <none>
kbhello-deployment-664dd576d4-n9t8t   1/1     Running   0          24h   10.244.2.37   kb3    <none>           <none>
kbhello-deployment-664dd576d4-nrj9j   1/1     Running   0          24h   10.244.1.91   kb2    <none>           <none>

EXTERNAL-IP にip設定すればいいのかな?

$ kubectl get service
NAME                  TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
kbhello-service-cip   ClusterIP   10.104.228.167   <none>        8080/TCP   3d22h
kubernetes            ClusterIP   10.96.0.1        <none>        443/TCP    43d

LoadBalancer を試す

apiVersion: v1
kind: Service
metadata:
  name: kbhello-service-lb
spec:
  selector:
    app: kbhello
  type: LoadBalancer
  ports:
  - port: 8080
  loadBalancerIP: 192.168.0.111

やっぱり失敗。EXTERNAL-IP:pending。LoadBalancer にipを渡す人が必要なのか。

$ kubectl get service
NAME                  TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
kbhello-service-cip   ClusterIP      10.104.228.167   <none>        8080/TCP         3d23h
kbhello-service-lb    LoadBalancer   10.111.236.45    <pending>     8080:30202/TCP   97s
kubernetes            ClusterIP      10.96.0.1        <none>        443/TCP          43d

CLUSTER-IP のcurl はOK

$ curl 10.111.236.45:8080
Hello Docker World kbhello-deployment-664dd576d4-n9t8t
Hello Docker World kbhello-deployment-664dd576d4-29pkt
Hello Docker World kbhello-deployment-664dd576d4-nrj9j

NodePort を試す

NodePort。ノードポート。node内のpodには行けても、別nodeのpodには行けない感。

NodePortは、全てのKubernetes NodeのIP:Portで受けたトラフィックをコンテナに転送する形で、外部疎通性を確立します。 https://thinkit.co.jp/article/13738?page=0%2C1

NodePortは各NodeのIPでポートを公開します。これにより、クラスタの外からServiceにアクセスできるようになります。 https://codezine.jp/article/detail/10523

試してみる。

$ kubectl expose deployment kbhello-deployment --type=NodePort --port 8080
service/kbhello-deployment exposed
$ kubectl get service
NAME                  TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
kbhello-deployment    NodePort    10.110.104.66    <none>        8080:30199/TCP   18s
kbhello-service-cip   ClusterIP   10.104.228.167   <none>        8080/TCP         3d23h
kubernetes            ClusterIP   10.96.0.1        <none>        443/TCP          44d

node:kb2 にcurl。node3のレスポンスもあった。

$ curl 192.168.0.102:8080
curl: (7) Failed to connect to 192.168.0.102 port 8080: Connection refused

$ curl 192.168.0.102:30199
Hello Docker World kbhello-deployment-664dd576d4-29pkt
Hello Docker World kbhello-deployment-664dd576d4-nrj9j
Hello Docker World kbhello-deployment-664dd576d4-29pkt
Hello Docker World kbhello-deployment-664dd576d4-n9t8t <--- node:kb3
Hello Docker World kbhello-deployment-664dd576d4-nrj9j

node:kb3 にcurl。node2のレスポンスもあった。

$ curl 192.168.0.103:8080
curl: (7) Failed to connect to 192.168.0.103 port 8080: Connection refused

$ curl 192.168.0.103:30199
Hello Docker World kbhello-deployment-664dd576d4-n9t8t
Hello Docker World kbhello-deployment-664dd576d4-29pkt <--- node:kb2
Hello Docker World kbhello-deployment-664dd576d4-29pkt <--- node:kb2
Hello Docker World kbhello-deployment-664dd576d4-29pkt <--- node:kb2
Hello Docker World kbhello-deployment-664dd576d4-nrj9j <--- node:kb2

pod を1個にしてcurl してみる。

podがないnodeを作ったらどうなる?

$ kubectl edit deployment kbhello-deployment
:
 replicas: 3
↓ 
 replicas: 1

node:kb2 だけになったことを確認。

$ kubectl get pod -o wide
NAME                                  READY   STATUS    RESTARTS   AGE   IP            NODE   NOMINATED NODE   READINESS GATES
kbhello-deployment-664dd576d4-29pkt   1/1     Running   0          24h   10.244.1.90   kb2    <none>           <none>

curl。podがない kb3(103) の port からもレスポンスがある。なるほど、欲しかったのはNodePortだったのか。

core@kb1 ~ $ curl 192.168.0.102:30199
Hello Docker World kbhello-deployment-664dd576d4-29pkt

core@kb1 ~ $ curl 192.168.0.103:30199
Hello Docker World kbhello-deployment-664dd576d4-29pkt

NodePortだと別nodeのpodには行けない、は勘違いでした。

NodePortを指定する

さっきのやり方ではNodePort の番号を指定できないようなのでマニフェストにしてみた。

kbhello-service-np.yaml

apiVersion: v1
kind: Service
metadata:
  name: kbhello-service-np
spec:
  selector:
    app: kbhello
  type: NodePort
  ports:
  - port: 8080
    nodePort: 30080

マニフェスト適用。

$ kubectl apply -f kbhello-service-np.yaml
service/kbhello-service-np created

$ kubectl get svc
NAME                  TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
kbhello-deployment    NodePort    10.110.104.66    <none>        8080:30199/TCP   28m
kbhello-service-cip   ClusterIP   10.104.228.167   <none>        8080/TCP         4d
kbhello-service-np    NodePort    10.99.42.155     <none>        8080:30080/TCP   8s
kubernetes            ClusterIP   10.96.0.1        <none>        443/TCP          44d

curlで確認。podが1コしかないけど想定通りの結果が得られた。

$ curl 192.168.0.102:30080
Hello Docker World kbhello-deployment-664dd576d4-29pkt
Hello Docker World kbhello-deployment-664dd576d4-29pkt

$ curl 192.168.0.103:30080
Hello Docker World kbhello-deployment-664dd576d4-29pkt
Hello Docker World kbhello-deployment-664dd576d4-29pkt