記録。

めも。

kubernetesの個人的メモ(Discovery&LBリソース)

エントリーのリソースの違いがあやふやになってしまったので、整理した。

Discovery&LBリソース

デプロイされているPod(コンテナ)に外部からアクセスできるようにするリソース。

エンドポイントの提供などをしれくれる。

大きく、SerivceとIngress に分かれる。

両者の違いは、SerivceリソースはL4のロードバランシングを提供するのに対して、 IngressリソースはL7のロードバランシングまで提供してくれる。

つまり、Ingressはパスルーティングを実現できたりする。

Serviceリソース

細かくは7つに分かれる。

  • ClusterIP
  • ExternalIP
  • NodePort
  • LoadBalancer
  • Headless(None)
  • ExternalName
  • None-Selector

下から3つについては、今回は省略する。

Cluster IP

クラスタ内部ネットワークのみで疎通できる仮装IPが割り当てられる。 指定した Podに対してロードバランシングを行う。

例えば、クラスタで動くPodAから 3台動いているPodBにアクセスしたいとき、PodAからはCluster IPで割り当てられたIPにアクセスすると、 いい感じにロードバランシングしてくれて、PodBにアクセスすることができる。

構成ファイル例

kind: Service
apiVersion: v1
metadata:
  namespace: wakashiyo-development
  name: wakashiyo-dev-clusterip
spec:
  selector:
    app: nginx
  type: ClusterIP
  ports:
  - name: "http-port"
    port:  8080
    targetPort:  80

selectorにはdeployment等でデプロイしているPodのラベルを設定している。

portでCluster IPが受け付けるポート番号を指定し、

targetPort で転送先のコンテナのポート番号を指定する。

External IP

前述のCluster IPは内部疎通だけだったが、これはクラスタ外からも疎通できる。

指定したクラスタIPアドレスを指定することで、そのNodeへのアクセスを指定したコンテナにロードバランシングする。

ロードバランシングされるのは、指定したIPのNodeにあるコンテナだけでなく、デプロイされているコンテナ全てにロードバランシングされる。

kind: Service
apiVersion: v1
metadata:
  namespace: wakashiyo-development
  name: wakashiyo-dev-clusterip
spec:
  selector:
    app: nginx
  type: ClusterIP
  # kubectl get nodes -o custom-columns="NAME:{metadata.name},IP:{status.addresses[].address}"
  externalIPs:
    - 10.146.0.16
  ports:
  - name: "http-port"
    port:  8080
    targetPort:  80
# It did not work

先ほどのCluster IPと異なるのは、externalIPs という項目が増えている。 これは、GKEであれば、GCEインスタンスの外部IPではなく、OSなどから確認できる内部のIPを使用することができるらしい。

NodePort

こちらは、external IPが外部疎通性のあるノードを指定したのに対して、 こちらは、全てのNodeの外部疎通性を提供する。

(厳密には、0.0.0.0:portnumberでListenし、Node全てのIPにBindする形でロードバランシングされる)

なので、3台のノードが存在した場合、いずれかのIPアドレスにアクセスすると、NodePortからロードバランシングされ、 コンテナにアクセスができる。

構成ファイル例

kind: Service
apiVersion: v1
metadata:
  namespace: wakashiyo-development
  name: wakashiyo-dev-nodeport
spec:
  selector:
    app: nginx
  type: NodePort
  ports:
  - name: http-port
    port: 8080
    targetPort: 80
    nodePort: 30080
# It did not work when use not ingress

ports.nodePort という項目が増えている。

これは、NodePort -> ClusterIP -> Pod(container)

のようにクラスタ内部ではClustert IP のようにトラフィックが流れる。

port はCluster IPで受け付けるポート番号に対して、nodePortはクラスタのnodeで受け付けるポート番号になる。

LoadBalancer

今までは外部疎通性を提供するのに、node自身のIPを外部疎通できるように設定していたのに対して、

これは完全にクラスタ外に作成されるイメージになる。

その名の通り、クラスタ外のロードバランサが指定したコンテナに対してロードバランシングしてくれる。(L4レベルで)

とあるNodeが障害の場合、そのNodeへのトラフィックは流れないようにしてくれる。

GKEだと内部的にはロードバランサのサービスが使用されているらしい。

構成ファイル例

kind: Service
apiVersion: v1
metadata:
  namespace: wakashiyo-development
  name: wakashiyo-dev-lb
spec:
  selector:
    app: nginx
  type: LoadBalancer
  ports:
    - name: "http-port"
      port: 8080
      targetPort: 80
      nodePort: 30082
  # firewall rule (default: 0.0.0.0/0)
  loadBalancerSourceRanges:
    - 10.0.0.0/8

こちらのnodePortはロードバランサで受け付けるポート番号のことを指す。

NodePortと同様にクラスタ内部ではCluster IPが存在して、Cluster IP経由でコンテナまで疎通することができる。

loadBalancerSourceRangesを使用することで、指定したIPレンジからの送信しか受け付けないようにすることができる。

冷やっとしたのは、GKEの場合、Load Balancerを作成した時点で、GCPのロードバランサが作成され、静的IPが払い出される。

これは、クラスタを削除したりしても消えないので注意した方がいい。

Ingress

LoadBalancerと違って、L7のロードバランシングまで提供してくれる。

こちらも内部的には、GCPのロードバランサが使用されている。

構成ファイル例

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  namespace: wakashiyo-development
  name: w-d-ig
spec:
  rules:
    - http:
        paths:
          - path: /path1/*
            backend:
                serviceName: w-d-np1
                servicePort: 8080
          - path: /path2/*
            backend:
                serviceName: w-d-np2
                servicePort: 8080
          - path: /path3/*
            backend:
                serviceName: w-d-np3
                servicePort: 8080

backendには転送したいserviceを指定する。

ここでは、3つのNodePortをあらかじめ用意してからingressをデプロイしている。

というのも、Ingressはserviceをバックエンドとして転送する仕組みになっているため、

Serivceをbackendとして指定している。

ingressを通して公開されるコンテナはロードバランサからのヘルスチェックに応答できるようにしなければならない。

ヘルスチェックで何が行われるかというと、ルートパスへのGETリクエストが来るので、そのリクエストに対して200を返すようにしなければならない。

このことを最初知らずに、いつまで経ってもデプロイが失敗して1時間ほど溶かしてしまった。

Ingress を使用した HTTP(S) 負荷分散  |  Kubernetes Engine のドキュメント  |  Google Cloud