3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

NSX環境におけるTanzu Kubernetes GridのRoutable Pod

Last updated at Posted at 2021-12-18

本記事はvExperts Advent Calendar 2021の12月18日分の投稿です。

はじめに

NSX-Tで構成されるvSphere環境のTanzu Kubernetes GridのワークロードクラスターではAntrea CNIを利用して、Podに対してルーティング可能なIPアドレスを構成し、NATを利用せずにPodにアクセスする(Routable Pod)ことが可能になります。Tanzu Kubernetes Grid環境、vSphere with Tanzu環境ともRoutable Podを利用することが可能です。以下のドキュメント設定方法が記載されています。

Tanzu Kubernetes Gridで構成してみる

マニュアルの「Deploy Pods with Routable, No-NAT IP Addresses (NSX-T)」を参考にTanzu Kubernetes Grid環境のワークロードクラスターでRoutable Podを利用してみます。

NSX-Tの要件

NSX-T側では予めワークロードクラスターを接続するネットワーク(NSX-Tのセグメント)を作成し、Tier1 Gateway配下にぶら下げておく必要があります。

  • Tier0 Gatewayを既存ネットワークに対して接続
  • Tanzu Kubernetes Clusterを接続するTier1 Gatewayの作成
    • Tier0 Gatewayに接続
    • ルートアドバタイズとして「すべてのスタティックルート」と「接続されている全てのセグメントおよびサービスポート」を有効化する
  • Tanzu Kubernetes Gridを接続するセグメントの作成
    • ゲートウェイアドレスの指定
    • 上記で作成したTier1 Gatewayに接続
    • Tanzu Kubernernets Clusterのノードが利用するDHCPサーバーの構成

ネットワーク構成

Routable Podを有効化すると、NSX-TのTier1 Gateway配下にワークロードクラスターが作成され、Tier1 GatewayにPod CIDR向けのStatic Routeが追加されます。T1 Gatewayに追加されたStatic Routeは上位のTier0 Gatewayにアドバタイズされ、外部のネットワークからPodのIPアドレスに対して直接通信することが可能になります。

Kobito.rBvlU7.png

マネジメントクラスターの作成

今回はロードバランサーとしてNSX-ALBを利用するため、以下のようにAVI_パラメータを指定してマネジメントクラスターを作成します。マネジメントクラスターはRoutable Podを利用しないため、CLUSTER_CIDRとして100.96.0.0/11を指定しています。

AVI_CA_DATA_B64: XXXXXXXX...
AVI_CLOUD_NAME: Default-Cloud
AVI_CONTROL_PLANE_HA_PROVIDER: "false"
AVI_CONTROLLER: 192.168.30.250
AVI_DATA_NETWORK: tanzu-overlay
AVI_DATA_NETWORK_CIDR: 172.16.128.0/21
AVI_ENABLE: "true"
AVI_LABELS: ""
AVI_PASSWORD: <encoded:XXXXXXXXXXXX>
AVI_SERVICE_ENGINE_GROUP: Default-Group
AVI_USERNAME: admin
CLUSTER_CIDR: 100.96.0.0/11
CLUSTER_NAME: mgmt
CLUSTER_PLAN: dev
ENABLE_CEIP_PARTICIPATION: "true"
ENABLE_MHC: "true"
IDENTITY_MANAGEMENT_TYPE: none
INFRASTRUCTURE_PROVIDER: vsphere
SERVICE_CIDR: 100.64.0.0/13
TKG_HTTP_PROXY_ENABLED: "false"
VSPHERE_CONTROL_PLANE_ENDPOINT: 172.16.135.240
VSPHERE_DATACENTER: /DC
VSPHERE_DATASTORE: /DC/datastore/NFS
VSPHERE_FOLDER: /DC/vm
VSPHERE_NETWORK: tanzu-overlay
VSPHERE_PASSWORD: <encoded:XXXXXXXXXXXX>
VSPHERE_RESOURCE_POOL: /DC/host/CL/Resources/Tanzu
VSPHERE_SERVER: 10.44.55.100
VSPHERE_SSH_AUTHORIZED_KEY: ssh-rsa AAAAB...
VSPHERE_INSECURE: true
VSPHERE_USERNAME: administrator@vsphere.local

以下のコマンドでマネジメントクラスターを作成します。

$ tanzu management-cluster create -f management.yaml

ワークロードクラスターの作成

マネジメントクラスターの作成が完了したら、マネジメントクラスターを利用してRoutable Podが利用可能なワークロードクラスターを作成します。ワークロードクラスターの作成には以下の構成ファイルを利用します。

CLUSTER_NAME: cl1
CLUSTER_PLAN: dev
INFRASTRUCTURE_PROVIDER: vsphere
ENABLE_CEIP_PARTICIPATION: true
ENABLE_AUDIT_LOGGING: true
SERVICE_CIDR: 100.64.0.0/13
AVI_CONTROL_PLANE_HA_PROVIDER: false
DEPLOY_TKG_ON_VSPHERE7: true
ENABLE_TKGS_ON_VSPHERE7: false
VSPHERE_CONTROL_PLANE_ENDPOINT: 172.16.135.250
VSPHERE_DATACENTER: /DC
VSPHERE_DATASTORE: /DC/datastore/NFS
VSPHERE_FOLDER: /DC/vm
VSPHERE_NETWORK: tanzu-overlay
VSPHERE_PASSWORD: <encoded:xxxxxxxxxxxx>
VSPHERE_RESOURCE_POOL: /DC/host/CL/Resources/Tanzu
VSPHERE_SERVER: 10.44.55.100
VSPHERE_SSH_AUTHORIZED_KEY: ssh-rsa AAAA...
VSPHERE_INSECURE: true
VSPHERE_USERNAME: administrator@vsphere.local
VSPHERE_STORAGE_POLICY_ID: "tkg"
CONTROLPLANE_SIZE: large
WORKER_SIZE: large
WORKER_MACHINE_COUNT: 2
OS_NAME: "photon"
ENABLE_MHC: true
MHC_UNKNOWN_STATUS_TIMEOUT: 5m
MHC_FALSE_STATUS_TIMEOUT: 12m
CLUSTER_CIDR: 172.16.136.0/21
NSXT_POD_ROUTING_ENABLED: "true"
NSXT_MANAGER_HOST: 10.44.55.101
NSXT_ROUTER_PATH: /infra/tier-1s/tanzu-cl1
NSXT_USERNAME: admin
NSXT_PASSWORD: NSXTPASSWORD
NSXT_ALLOW_UNVERIFIED_SSL: "true"

ポイントは、NSXT_パラメータの指定とCLUSTER_CIDRの指定です。CLUSTER_CIDRには/24以上のCIDRを指定します。作成するクラスターの各ノードにはCLUSTER_CIDRから/24単位でpodCIDRが割り当てられます。作成するノード数に注意してCLUSTER_CIDRを指定する必要があります。

以下のコマンドでマネジメントクラスターを作成します。

$ tanzu cluster create cl1 -f clsuter01.yaml

Podの作成と動作確認

作成されたクラスターに接続して確認するとノードのIPアドレスはDHCPから払い出されています。

$ tanzu cluster kubeconfig get cl1 --admin
$ kubectl config use-context cl1-admin@cl1
$ kubectl get node -o wide
NAME                        STATUS   ROLES                  AGE   VERSION            INTERNAL-IP      EXTERNAL-IP      OS-IMAGE                 KERNEL-VERSION   CONTAINER-RUNTIME
cl1-control-plane-nh9n7     Ready    control-plane,master   20m   v1.21.2+vmware.1   172.16.128.63    172.16.128.63    VMware Photon OS/Linux   4.19.198-1.ph3   containerd://1.4.6
cl1-md-0-5789bbcb76-hbnqz   Ready    <none>                 17m   v1.21.2+vmware.1   172.16.128.126   172.16.128.126   VMware Photon OS/Linux   4.19.198-1.ph3   containerd://1.4.6
cl1-md-0-5789bbcb76-vvrjv   Ready    <none>                 14m   v1.21.2+vmware.1   172.16.128.35    172.16.128.35    VMware Photon OS/Linux   4.19.198-1.ph3   containerd://1.4.6

各ノードのpodCIDRを確認すると、クラスター作成時に指定したCLUSTER_CIDR: 172.16.136.0/21から各ノードに対して/24単位で割り当てられています。

$ kubectl get node -o=jsonpath='{range .items[*]}{.spec.podCIDR}{"\n"}{end}'
172.16.136.0/24
172.16.137.0/24
172.16.138.0/24

T1 GatewayのStatic Routeを確認すると、各podCIDRのNextHopとしてワークロードクラスターのノードが追加されています。複数のワークロードクラスターを構成する場合、各ワークロードクラスターのCLUSTER_CIDRとして重複しないアドレス範囲を指定する必要があります。以下の例はワークロードクラスターとしてcl1とcl2を作成し、それぞれのCLUSTER_CIDRとして172.16.136.0/21172.16.144.0/21を割り当てた場合の状態です。

Kobito.CEujUn.png

Podを作成し、確認すると各PodのIPアドレスはpodCIDRから払い出されています。

$ kubectl create deploy nginx --image=nginxdemos/hello:plain-text
$ kubectl scale deploy nginx --replicas=4
$ kubectl get pod -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP              NODE                        NOMINATED NODE   READINESS GATES
nginx-6bbf47444b-9p4lx   1/1     Running   0          24s   172.16.138.5    cl1-md-0-5789bbcb76-vvrjv   <none>           <none>
nginx-6bbf47444b-j2wsf   1/1     Running   0          20s   172.16.137.9    cl1-md-0-5789bbcb76-hbnqz   <none>           <none>
nginx-6bbf47444b-ws4z7   1/1     Running   0          20s   172.16.138.6    cl1-md-0-5789bbcb76-vvrjv   <none>           <none>
nginx-6bbf47444b-x5mkc   1/1     Running   0          20s   172.16.137.10   cl1-md-0-5789bbcb76-hbnqz   <none>           <none>

各PodのIPアドレスに直接curlを実行すると、Podに対してアクセスすることができました。

$ for i in $(kubectl get pod -o=jsonpath='{.items[*].status.podIP}'); do curl -s $i; done | grep 'Server address'
Server address: 172.16.139.5:80
Server address: 172.16.137.9:80
Server address: 172.16.139.6:80
Server address: 172.16.137.10:80

Antrea CNIの設定確認

ワークロードクラスターのantreaの設定を確認してみます。kube-systemネームスペースにConfigMapとしてantrea-configが作成されています。内容を確認すると、antrea-agent.conftrafficEncapMode: noEncapnoSNAT: trueが指定されています。

$ kubectl get configmap -n kube-system antrea-config-ctb8mftc58
NAME                       DATA   AGE
antrea-config-ctb8mftc58   3      73m

$ kubectl get configmap antrea-config-ctb8mftc58 -oyaml
apiVersion: v1
data:
  antrea-agent.conf: |
    featureGates:
      AntreaProxy: true
      EndpointSlice: false
      Traceflow: true
      NodePortLocal: false
      AntreaPolicy: true
      FlowExporter: false
      NetworkPolicyStats: false
    trafficEncapMode: noEncap
    noSNAT: true

LoadBalancerの利用

LoadBalancer Serviceを作成し、NSX-ALBにVirtual Serviceが構成されてアクセスできることを確認します。

$ kubectl expose deploy nginx --port=80 --type=LoadBalancer

$ kubectl get service
NAME         TYPE           CLUSTER-IP       EXTERNAL-IP    PORT(S)        AGE
kubernetes   ClusterIP      100.64.0.1       <none>         443/TCP        5h15m
nginx        LoadBalancer   100.69.231.126   172.16.129.2   80:30858/TCP   15s

$ while true; do curl -s 172.16.129.2|grep address; sleep 1; done
Server address: 172.16.138.6:80
Server address: 172.16.137.9:80
Server address: 172.16.138.5:80
Server address: 172.16.137.9:80
Server address: 172.16.137.10:80

NSX-ALB Controllerを確認すると、Service用のVirtual Serivceの負荷分散対象はワークロードクラスターのNodePortが構成されていました。AKO自体はRoutable Podを負荷分散対象として利用することが可能ですが、TKGのオプションとして設定する方法を見つけることができませんでした。

Kobito.D7YdC6.png

ノードの追加・削除

TKGではクラスターのノードを簡単にスケールアウト・スケールインすることが可能です。ノードの追加と削除の際に、T1 GatewayのStatic Routeが追加・削除される様子を確認してみました。Static Routeの追加削除は、各ワークロードクラスターのvsphere-cloud-controller-managerが行っており、以下のログが出力されていました。なお、クラスター削除時は各ノードのStatic Routeは削除されないため手動でStatic Routeエントリを削除する必要があります。

  • ノード追加時
I1216 05:40:06.080046       1 route_controller.go:193] Creating route for node cl1-md-0-5789bbcb76-vvrjv 172.16.139.0/24 with hint 1455b87f-8fbe-4cfd-b43c-fdfb822acfc7, throttled 564ns
I1216 05:40:10.107407       1 route_controller.go:213] Created route for node cl1-md-0-5789bbcb76-vvrjv 172.16.139.0/24 with hint 1455b87f-8fbe-4cfd-b43c-fdfb822acfc7 after 4.027359885s
I1216 05:40:10.107480       1 route_controller.go:303] Patching node status cl1-md-0-5789bbcb76-vvrjv with true previous condition was:nil

hintとして表示されているIDはNSX上に作成されるStatic RouteリソースのIDのPrefixとして利用されるため、IDにより追加されたリソースを検索することが可能です。

image.png

  • ノード削除時

ノードの削除は古いものが優先して削除されるようです。

I1216 05:44:46.046675       1 route_controller.go:246] Deleting route a57a555e-e4eb-49ad-af74-e11a7d7a8ad8_172.16.138.0_24 172.16.138.0/24
I1216 05:44:46.485056       1 route_controller.go:250] Deleted route a57a555e-e4eb-49ad-af74-e11a7d7a8ad8_172.16.138.0_24 172.16.138.0/24 after 438.418613ms

vSpehre with Tanzuで構成してみる

vSphere with Tanzu環境では、Supervisor Cluster有効時にNSX-T側の構成が完了しているため、TKGと比べるとシンプルにRoutable Podクラスターを構成することができます。ネームスペースのオプションで「クラスターネットワーク設定のオーバーライド」を有効にし、NATモードを無効化し、「名前空間ネットワーク」と「名前空間サブネットプリフィックス」を指定します。「名前空間ネットワーク」はワークロードクラスターとそのPod CIDRとして利用されるネットワークとして利用されます。「名前空間サブネットプリフィックス」はワークロードクラスターのノードに割り当てるIPアドレスのプリフィックスとして利用されますが、各ノードのPod CIDRはTKGと同じように/24で割り当てられます。

Kobito.WZEqAW.png

以下のようなマニフェストを利用してワークロードクラスターを作成することで、Routable Podを利用することが可能になります。

apiVersion: run.tanzu.vmware.com/v1alpha2
kind: TanzuKubernetesCluster
metadata:
  name: routablepods
spec:
  topology:
    controlPlane:
      replicas: 3
      vmClass: best-effort-medium
      storageClass: k8s-policy
      tkr:
        reference:
          name: v1.21.2---vmware.1-tkg.1.ee25d55
    nodePools:
    - name: worker-nodepool-a1
      replicas: 3
      vmClass: best-effort-medium
      storageClass: k8s-policy
      tkr:
        reference:
          name: v1.21.2---vmware.1-tkg.1.ee25d55
  settings:
    storage:
      defaultClass: k8s-policy
    network:
      # antrea-nsx-routed is the required CNI for routable pods
      cni:
        name: antrea-nsx-routed
      services:
        cidrBlocks: ["10.97.0.0/24"]
      serviceDomain: tanzukubernetescluster.local
      # pods.cidrBlocks value must be empty when antrea-nsx-routed is the CNI
      pods:
        cidrBlocks:

作成したワークロードクラスターの動作を確認すると、ワークロードクラスターのAPI用のロードバランサーや、LoadBalancer Serivceは入力方向(Ingress)から払い出されています。

$ kubectl config get-clusters
NAME
10.44.186.2
172.16.90.2
supervisor-10.44.186.2

$ kubectl get node -o wide
NAME                                                    STATUS   ROLES                  AGE   VERSION            INTERNAL-IP    EXTERNAL-IP   OS-IMAGE                 KERNEL-VERSION       CONTAINER-RUNTIME
routablepods-control-plane-87fvv                        Ready    control-plane,master   32h   v1.21.2+vmware.1   172.16.96.38   <none>        VMware Photon OS/Linux   4.19.191-4.ph3-esx   containerd://1.4.6
routablepods-control-plane-s8wq4                        Ready    control-plane,master   32h   v1.21.2+vmware.1   172.16.96.34   <none>        VMware Photon OS/Linux   4.19.191-4.ph3-esx   containerd://1.4.6
routablepods-control-plane-t6htb                        Ready    control-plane,master   32h   v1.21.2+vmware.1   172.16.96.39   <none>        VMware Photon OS/Linux   4.19.191-4.ph3-esx   containerd://1.4.6
routablepods-worker-nodepool-a1-s6bsw-b89cf564b-jbs56   Ready    <none>                 32h   v1.21.2+vmware.1   172.16.96.36   <none>        VMware Photon OS/Linux   4.19.191-4.ph3-esx   containerd://1.4.6
routablepods-worker-nodepool-a1-s6bsw-b89cf564b-n5jh4   Ready    <none>                 32h   v1.21.2+vmware.1   172.16.96.35   <none>        VMware Photon OS/Linux   4.19.191-4.ph3-esx   containerd://1.4.6
routablepods-worker-nodepool-a1-s6bsw-b89cf564b-zs2nw   Ready    <none>                 32h   v1.21.2+vmware.1   172.16.96.37   <none>        VMware Photon OS/Linux   4.19.191-4.ph3-esx   containerd://1.4.6

$ kubectl get node -o=jsonpath='{range .items[*]}{.spec.podCIDR}{"\n"}{end}'
172.16.101.0/24
172.16.97.0/24
172.16.102.0/24
172.16.98.0/24
172.16.99.0/24
172.16.100.0/24

$ kubectl get pod -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP             NODE                                                    NOMINATED NODE   READINESS GATES
nginx-6bbf47444b-2b7gx   1/1     Running   0          54s   172.16.98.6    routablepods-worker-nodepool-a1-s6bsw-b89cf564b-jbs56   <none>           <none>
nginx-6bbf47444b-dhbxn   1/1     Running   0          54s   172.16.100.8   routablepods-worker-nodepool-a1-s6bsw-b89cf564b-zs2nw   <none>           <none>
nginx-6bbf47444b-lj2pb   1/1     Running   0          54s   172.16.100.9   routablepods-worker-nodepool-a1-s6bsw-b89cf564b-zs2nw   <none>           <none>
nginx-6bbf47444b-mtg7z   1/1     Running   0          58s   172.16.99.7    routablepods-worker-nodepool-a1-s6bsw-b89cf564b-n5jh4   <none>           <none>

$ kubectl get svc
NAME         TYPE           CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP      10.97.0.1    <none>        443/TCP        32h
nginx        LoadBalancer   10.97.0.31   172.16.90.3   80:30966/TCP   15s
supervisor   ClusterIP      None         <none>        6443/TCP       32h

まとめ

vSphere環境でNSX-Tを利用すると、vSphere with TanzuやTanzu Kubernetes GridのワークロードクラスターでRoutable Podを利用することが可能になります。Routable Podを利用すると従来のVMと同じようにPodに対して直接通信することが可能になり、NATのオーバーヘッドを削減し、多様なアプリケーションの要件に対応することが可能になります。

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?