はじめに
VMware vSphere環境ではTanzu Kubernetes Grid(通称: TKG)を使用することで簡単にKubernetes環境を構築することができます。本記事で紹介するTKGはStandalone版であり、マルチクラウドに対応可能なTKGmです。また、NSX ALBはEssentialsライセンスを使用していきます。本記事ではEnterprise Editionの機能である、DNS ProviderとAKOを使用したL7 Ingressを構築する方法を紹介します。
前回
これまで構築した環境を元に本記事を記述しております。
https://www.munenick.me/blog/tkg-nsx-alb-04
環境
| 環境 |
|---|
| VMware ESXi 8 |
| VMware vCenter 8 |
| Tanzu Kubernetes Grid 2.1.1 |
| NSX Advanced Load Balancer 22.1.3 |
前提条件
- VMware ESXiの構築及びvCenterを使用してDatacenterの管理ができていること
- 2つ以上のVLAN環境が構築できていること
- 本環境ではマネジメントネットワーク:VM Network(VLAN0)とKubernetes用ネットワーク:VLAN100(VLAN100)を用意しています。
- 十分なリソースのあるサーバ、ストレージ
- NSX ALBでCPU:8, RAM:24GB, ROM:128GB使用します。
- 要件によりますが、デプロイするKubernetesノードでもCPU:2, RAM:8GB, ROM:40GBの仮想マシンが4~12個デプロイされます。
Enterprise Editionへの変更
本記事で紹介するDNS ProviderとAKO IngressはEssentialsライセンスでは構築することはできません。なので、まずEssentialsライセンスからEnterpriseライセンスに変更します。
-
NSX ALBにadminユーザでログインしてください。

-
上部タブの「管理」→「ライセンス」にある設定ボタン(歯車マーク)をクリックしてください。

-
「エンタープライズ階層」を選択し、右下の「保存」ボタンをクリックしてください。

AKO Ingressの構築
KubernetesにはIngressという機能があり、NGINX Ingress ControllerやVMwareが管理しているContour Ingress Controllerがあります。これらはNSX ALBのL4ロードバランサと組み合わせることで使用することができます。しかし、NSX ALBではL7 Ingressという機能を提供しており、上記のIngress Controllerを使用しなくても高性能なIngressを構築することができます。今回はそのL7 Ingressの構築方法を紹介します。
Managementクラスタでの設定
-
クラスタ管理マシンに接続してください。
-
以下のコマンドを実行し、Managementクラスタ用コンテキストを選択してください。
MuNeNiCK [ ~ ]$ kubectl config use-context tkg21mc01-admin@tkg21mc01
Switched to context "tkg21mc01-admin@tkg21mc01".
- 以下のコマンドを実行し、Managementクラスタのコンテキストが選択されていることを確認してください。
MuNeNiCK [ ~ ]$ kubectl config current-context
tkg21mc01-admin@tkg21mc01
- 任意の場所に以下のyamlファイルを作成してください。ただし、以下の項を自身の環境に合わせて書き換えてください。
- spec.controlPlaneNetwork: Kubernetesのcontrol-planeノードが接続するネットワークアドレスを「cidr」に、ネットワークグループを「name」に指定してください。
- spec.controller: NSX ALB ControllerのIPアドレスを指定してください。
- spec.dataNetwork: Kubernetes のデータプレーンのネットワークを指定します。これは「spec.controlPlaneNetwork」と同様になる場合が多いです。
- spec.extraConfigs.ingress.nodeNetworkList: Ingress として利用するネットワークを指定します。これは「spec.controlPlaneNetwork」と同様になる場合が多いです。
- shardVSSize: : LARGE, MEDIUM, SMALL, DEDICATEDから選択することができます。SMALLを指定した場合、作成される仮想サービスおよび割り当てられるVIPアドレスが1つとなります。この場合、DNS Providerを必ずしも作成しなくて良くなります。
apiVersion: networking.tkg.tanzu.vmware.com/v1alpha1
kind: AKODeploymentConfig
metadata:
name: ako-deploy
spec:
adminCredentialRef:
name: avi-controller-credentials
namespace: tkg-system-networking
certificateAuthorityRef:
name: avi-controller-ca
namespace: tkg-system-networking
cloudName: Default-Cloud
clusterSelector:
matchLabels:
ako-deploy: "true"
controlPlaneNetwork:
cidr: 192.168.100.0/24
name: VLAN100
controller: 192.168.0.241
dataNetwork:
cidr: 192.168.100.0/24
name: VLAN100
extraConfigs:
cniPlugin: antrea
disableStaticRouteSync: false
ingress:
disableIngressClass: false
nodeNetworkList:
- cidrs:
- 192.168.100.0/24
networkName: VLAN100
serviceType: NodePortLocal
shardVSSize: SMALL
serviceEngineGroup: Default-Group
- 以下のコマンドを実行し、yamlファイルを適用してください。
MuNeNiCK [ ~/kubernetes/management/ako ]$ kubectl apply -f ako-deploy.yaml
akodeploymentconfig.networking.tkg.tanzu.vmware.com/ako-deploy created
- 以下のコマンドを実行し、Workloadクラスタにラベルを付与してください。
uNeNiCK [ ~/kubernetes/management/ako ]$ kubectl label cluster tkg21wc01 ako-deploy="true"
cluster.cluster.x-k8s.io/tkg21wc01 labeled
Workloadクラスタでの設定
- 以下のコマンドを実行し、Workloadコンテキストに切り替えてください。
MuNeNiCK [ ~/kubernetes/management/ako ]$ kubectl config use-context tkg21wc01-admin@tkg21wc01
Switched to context "tkg21wc01-admin@tkg21wc01".
- 以下のコマンドを実行し、Workloadコンテキストが選択されていることを確認してください。
MuNeNiCK [ ~/kubernetes/management/ako ]$ kubectl config current-context
tkg21wc01-admin@tkg21wc01
- 以下のコマンドを実行し、AKOのPodを再起動してください。
MuNeNiCK [ ~/kubernetes/management/ako ]$ kubectl delete pod ako-0 -n avi-system
pod "ako-0" deleted
- 以下のコマンドを実行してIngressClassが作成されたことを確認してください。
MuNeNiCK [ ~/kubernetes/workload/caddy-ingress ]$ kubectl get ingressclass
NAME CONTROLLER PARAMETERS AGE
avi-lb ako.vmware.com/avi-lb <none> 42m
テストリソースの作成
今回はIngressの検証としてnginxを動作させたいと思います。
- 任意の場所に以下のyamlファイルを作成してください。ただし、「host」を自身のFQDNに書き換えてください。
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-ingress-deployment
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21.1
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: test-ingress-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-ingress
spec:
ingressClassName: avi-lb
rules:
- host: test-ingress.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: test-ingress-service
port:
number: 80
- 以下のコマンドを実行し、yamlを適用してください。
MuNeNiCK [ ~/kubernetes/workload/test-ako-ingress ]$ kubectl apply -f test-ingress.yaml
deployment.apps/test-ingress-deployment created
service/test-ingress-service created
ingress.networking.k8s.io/test-ingress created
- 以下のコマンドを実行してIngressリソースの作成を確認してください。ここでIngressコントローラに割り当てられたIPアドレスを確認することができます。
MuNeNiCK [ ~/kubernetes/workload ]$ kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
test-ingress avi-lb test-ingress.example.com 192.168.100.108 80 2m22s
DNSレコードの登録
Ingressコントローラに割り当てられたVIPアドレスをDNSのレコードとして登録する必要があります。後述するDNS Providerを構築する場合はこの手順は必要ありません。 今回はWindows Server DNSでレコード登録をします。
-
DNSマネージャを起動し、DNSレコードを追加したいゾーンを右クリックしてください。そして、「新しいホスト(AまたはAAAA)」をクリックしてください。

-
任意の名前を入力し、IPアドレスにIngressコントローラのIPアドレスを指定してください。私はワイルドカードを指定しています。これにより、Windows Server DNSで解決できなかったレコードをIngressコントローラに転送してくれます。

Ingressの確認
- ブラウザから、指定したFQDNにアクセスできたら成功です。

DNS Providerの構築(オプション)
AKO Ingressを使用する際に、「shardVSSize」を「SMALL」以外に設定すると、複数の仮想サービスが構築されます。そこで、その仮想サービスに割り当てられたアドレス(VIPアドレス)にアクセスする形になります。しかし、通常のDNSサーバでは複数のアドレスからホストを解決させることは容易ではありません。そこで、NSX ALBのDNS Providerを使用することで、動的にレコードを更新し、複数のIPアドレスからホストの解決を行うことができます。
DNS Profileの設定
-
「テンプレート」→「プロファイル」→「IPアドレス管理/DNSプロファイル」の「作成」ボタンをクリックし、「DNSプロファイル」をクリックしてください。

-
以下の項目を設定してください。
- 名前: 任意の名前を設定してください。今回は「k8s-dns」としています。

- DNSサービスドメイン: 「追加」ボタンをクリックし、自身のドメイン名を入力してください。

- 名前: 任意の名前を設定してください。今回は「k8s-dns」としています。
これらを入力し終わったら、右下の「保存」ボタンをクリックしてください。
Default-Cloudへの適用
-
「インフラストラクチャ」→「クラウド」→「Default-Cloud」の編集ボタン(ペンマーク)をクリックしてください。

-
「IPアドレス管理/DNS」の「DNSプロファイル」先程作成したDNSプロファイルを指定してください。

DNS用仮想サービスの作成
-
「ダッシュボード」→「仮想サービスの作成」をクリックし、「詳細設定」をクリックしてください。

-
まず、以下の項目を設定してください。
- 名前: 任意の名前を設定してください。今回は「dns01」としています。
- アプリケーションプロファイル: プルダウンメニューから「System-DNS」を指定してください。

-
次にVIPアドレスの設定を行います。「VS VIP」のプルダウンメニューから「VS VIPの作成」をクリックしてください。

-
「VS VIPの作成」が開いたら「VIP」項目の「追加」ボタンをクリックしてください。

-
「VIPの編集」ではプライベートIPに自身の要件に合わせて設定してください。今回は静的アドレスを設定するために「静的」を選択し、「IPv4アドレス」にIPアドレスを割り当てています。ここで設定したIPアドレスがDNSサーバのアドレスとなります。ただし、ここで設定するIPアドレスはNSX ALBのネットワーク設定にて指定したアドレス範囲の範囲外のアドレスを指定してください。

-
「VIPの編集」にて「配置ネットワーク」の「追加」ボタンをクリックしてください。

-
「配置ネットワークの作成」では「配置ネットワーク」に配置したいネットワーク、「IPv4サブネット」では配置するネットワークのアドレスを指定してください。今回はKubernetes用ネットワークを指定しています。

-
これらの設定を終えたら「VIPの編集」の右下の「保存」をクリックしてください。

-
「VS VIPの作成」の「DNS」欄にある「追加」をクリックしてください。

-
「DNSの作成」では以下の項目を設定してください。
- アプリケーションドメイン名: ネームサーバのドメイン名になります。今回は「dns01」としています。
- TTL: TTLを設定してください。今回は300としています。
-
ここまでの設定を終えたら、「VS VIPの編集」で右下の「保存」をクリックしてください。
-
既存のDNSサーバが存在する場合、そのサーバをフォワーダーとして設定することができます。既存のDNSがない場合はここの手順は飛ばしていただいて構いません。「プール」にある「プールの選択」のプルダウンメニューを開き、「プールの作成」をクリックしてください。

-
ここで以下の項目を入力し、右下の「保存」をクリックしてください。
-
名前: 任意のプール名を入力してください。

-
サーバ: 既存のDNSサーバのIPアドレスを入力し、「追加ボタン」クリックしてください。

-
-
「新しい仮想サービス」に戻ったら右下の「次へ」をクリックしてください。

-
「ステップ2: ポリシー」ではポリシーを指定することができます。今回はデフォルトのまま進みます。設定を終えたら、右下の「次へ」をクリックしてください。

-
「ステップ3: 分析」ではこの仮想サービスに対する分析の設定を行うことができます。今回はデフォルトのまま進みます。設定を終えたら、右下の「次へ」をクリックしてください。

-
「ステップ4: 詳細」では仮想サービスのパフォーマンス制限などを設定することができます。今回は「BGP経由のアドバタイズ」のチェックを外しています。設定を終えたら、右下の「次へ」をクリックしてください。

-
「ステップ5: 静的DNSレコード」では手動でDNSレコードを設定することができます。
システムへの適用
-
「管理」→「システム設定」に進み、「編集」をクリックしてください。

-
一番下にある「DNSサービス」の「追加」ボタンをクリックし、先ほど作成したDNS仮想サービスを選択してください。その後右下の「保存」ボタンをクリックしてください。

DNSの設定
クライアントのDNSの設定をNSX ALBの仮想サービスDNSに指定します。例としてWindowsの設定を紹介します。
-
検索欄から「ncpa.cpl」と検索してください。

-
使用しているイーサネットを右クリックし、「プロパティ」をクリックしてください。

-
「インターネットプロトコルバージョン4」の「プロパティ」をクリックしてください。

-
「優先DNSサーバ」にNSX ALBのDNS ProviderのVIPアドレスを指定してください。

DNSの検証
クライアントPCなどで「nslookup」や「ping」コマンドを使用してDNSの検証をしてください。(静的DNSレコードで設定したAレコードが解決できていることがわかります。)

次回
未定