0
0

More than 1 year has passed since last update.

AWS 上で Tanzu Community Edition をデプロイ、Contour と AWS Load Balancer Controller による Ingress の実現

Last updated at Posted at 2022-01-05

Chapter I: AWS 上で Tanzu Community Edition のデプロイ

 デプロイ方法はこちら VMware JP Blog に記載があるため、詳細を省きます。
TKG 1.4.0 on AWS の構築

 Management Cluster と Workload Cluster 構成後の AWS アーキテクチャは下記の図になります。
TUNA01.jpg

 2つの ELB(Classic)は自動的に作られ、Control Plane の API サーバアクセスとして構成されます。

Chapter I.5 TKG on AWS の LB Service の検証

 Ingress を検証する前に、Default の LB Service を検証します。
下記シンプルな LB Service を Workload Cluster でデプロイします。

lb-test.yaml
apiVersion: v1
kind: Service
metadata:
  name: lb-svc-1
spec:
  type: LoadBalancer
  selector:
    app: lb-svc-1
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

結果として

$ k get service -n default
NAME         TYPE           CLUSTER-IP       EXTERNAL-IP                                                              PORT(S)        AGE
kubernetes   ClusterIP      100.64.0.1       <none>                                                                   443/TCP        5d5h
lb-svc-1     LoadBalancer   100.68.125.217   aebc093baba6d43e18262210da62530b-296707719.us-east-2.elb.amazonaws.com   80:30904/TCP   29s

 ELB(Classic) が自動的に作成されます。Instance に Workload Cluster の Worker Node が設定されています。
TUNA03.jpg
 結論として、TCE on AWS をデプロイしたら、ELB が LB Service のバックエンドとして自動的にインテグレートされます。

Chapter II: Contour を使った Ingress の実現

 Contour のインストールはこちらの記事を参照します。

 Contour は VMware が管理する Open Source Ingress Controller です。データープレーンは Envoy Proxy を使います。
 TCE での Contour デプロイは tanzu package の仕組みを利用すれば容易にデプロイできます。

Step 1: リポジトリを追加
tanzu package repository add tce-repo --url projects.registry.vmware.com/tce/main:0.9.1 --namespace tanzu-package-repo-global
Step 2: 使用可能な package を確認
$ tanzu package available list
- Retrieving available packages...
  NAME                                           DISPLAY-NAME        SHORT-DESCRIPTION                         
  cert-manager.community.tanzu.vmware.com        cert-manager        Certificate management                    
  contour.community.tanzu.vmware.com             Contour             An ingress controller                     
  external-dns.community.tanzu.vmware.com        external-dns        This package provides DNS synchronization functionality.

正しい Package を利用するためには TCE を最新版にアップグレードした方がいいです。

Step 3: Contour をデプロイします。
tanzu package install contour --package-name contour.community.tanzu.vmware.com --version 1.19.1

 これで Contour と Envoy がデプロイされます。

$ k get pods -n projectcontour
NAME                            READY   STATUS      RESTARTS   AGE
contour-649bdcf7fd-6ttd4        1/1     Running     0          66m
contour-649bdcf7fd-zblx5        1/1     Running     0          66m
contour-certgen-v1.18.1-m5q8h   0/1     Completed   0          66m
envoy-8hf85                     2/2     Running     0          66m
Step 4: Ingress をデプロイしてみます。
contour-ingress-test.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: lb-svc-nginx
  labels:
    app: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: lb-svc-1
  template:
    metadata:
      labels:
        app: lb-svc-1
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - name: storage
          mountPath: /usr/share/nginx/html
    volumes:
    - name: storage
      hostPath:
        path: "/data/html"
        type: Directory
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: lb-svc-nginx-old
  labels:
    app: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: lb-svc-2
  template:
    metadata:
      labels:
        app: lb-svc-2
    spec:
      containers:
      - name: nginx
        image: nginx:1.20.1
        ports:
        - containerPort: 80
        volumeMounts:
        - name: storage
          mountPath: /usr/share/nginx/html/old
    volumes:
    - name: storage
      hostPath:
        path: "/data/html/old"
        type: Directory
---
apiVersion: v1
kind: Service
metadata:
  name: lb-svc-1
spec:
  type: NodePort
  selector:
    app: lb-svc-1
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: lb-svc-2
spec:
  type: NodePort
  selector:
    app: lb-svc-2
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: contour-test-ingress
  annotations:
    kubernetes.io/ingress.class: contour
spec:
  rules:
  - host:
    http:
      paths:
      - path: /old
        pathType: Prefix
        backend:
          service:
            name: lb-svc-2
            port:
              number: 80
      - path: /
        pathType: Prefix
        backend:
          service:
            name: lb-svc-1
            port:
              number: 80

 上記は2つバージョン(Latest & 1.20.1)の Nginx をデプロイし、それぞれの deployment に対して NodePort を作り、さらに、URL path (/ & /old)で区別するように Ingress を構成します。
 見た目上分けるために、host path volume を使って、簡易な html ファイルをマウントしています。

 host path volume を使うので、workload cluster の worker node にアクセスし、/data/html ディレクトリと index.html ファイルを作る必要があります。

 worker node にアクセスするのには、踏み台の workload-cluster-bastion インスタンスを経由してアクセスします。

 デプロイ後、Ingress と Service を確認します。

$ k get ingress
NAME                   CLASS    HOSTS   ADDRESS                                                                  PORTS   AGE
contour-test-ingress   <none>   *       xxxx.us-east-2.elb.amazonaws.com   80      50m
$ k get service
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   100.64.0.1      <none>        443/TCP        19h
lb-svc-1     NodePort    100.66.23.98    <none>        80:32549/TCP   50m
lb-svc-2     NodePort    100.65.103.44   <none>        80:31707/TCP   50m

 Ingress に ELB のアドレスが関連されていることが分かりました。
さらに AWS コンソルで確認します。
TUNA04.jpg
 ELB(classic) は確かに払い出されています。
 ELB の DNS 名を使ってアクセスしてみますと
TUNA05.jpg
 確かに、想定通りに振り分けています。

Chapter III: AWS ALB を使って Ingress を実現

 Contour の代わりに AWS ALB と AWS Load Balancer Controller の組み合わせで Ingress を実現してみます。

 AWS Load Balancer Controller のデプロイおよびユーザガイドを参照します。

Step 1: IAM の設定

 Ingress Controller が ALB/NLB を操作できるようにするためには IAM role を設定してあげる必要があります。
 EKS を使用するなら、Controller 用 Service Account と IAM role を作り、eksctl コマンドで関連付けますが、TCE などの 3rd Party K8s を使用する場合、手動で追加する必要があります。
 Service Account を使用するためには OIDC provider が必要になるので、今回の検証は Service Account を使わず、直接 Workload Cluster の Worker Node に IAM Role を付与します。
 Controller に必要な IAM Policy をダウンロードし、Policy を作成します。

 専用の IAM Role を作成してもいいですが、今回は TCE デプロイ時に worker node に付与された nodes.tkg.cloud.vmware.com Role に上記 Policy を追加します。

"nodes.tkg.cloud.vmware.com" Role は management cluster の worker node にも適用されています。

 既存の policy に controller 用の policy もアタッチします。
 TUNA06.jpg

Step 2: Subnet Discovery の設定

 AWS load balancer ingress controller は ALB を利用して Ingress を実現します。AWS ALB をデプロイするためには最低限2つ異なるAZにそれぞれSubenetを用意する必要があります。(AWS ALB Doc)

 ただ、マルチAZ をコンフィグしない限り、TCE のデプロイは基本1つのAZ内で完結します。ALB を利用するためには、手動でもう1つのAZ用のSubenet を手動で作成します。
 TUNA07.jpg
 既存の public subnet と private subnet にまねして、2つ目のAZのsubnetを作ります。
 Ingress Controller に Subnet を識別させるために、Subnet に下記のタグをつける必要があります。

Subnet 種別 Key Value
Public subnets kubernetes.io/role/elb 1 or ``
Private subnets kubernetes.io/role/internal-elb 1 or ``

TCE デプロイ時に自動で作られた Subnet にすでに上記タグは設定済み

 本来であれば、新規作成される Subnet に igw や nat も設定すべきですが、TCE worker node はマルチAZ構成していないので、こちら設定しなくてもALBは問題なく動きます。

Step 3: AWS Load Balancer Ingress Controller のデプロイ

 helm に EKS の repo を追加します。

helm repo add eks https://aws.github.io/eks-charts

 helm chart をインストールします。

helm install aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system --set clusterName=<cluster-name>

 インストールされたcontroller を確認します。

$ k get all -n kube-system | grep aws
pod/aws-load-balancer-controller-6bc577994f-r842f                       1/1     Running   0          21h
pod/aws-load-balancer-controller-6bc577994f-snb77                       1/1     Running   0          21h
service/aws-load-balancer-webhook-service   ClusterIP   100.69.91.239    <none>        443/TCP                  21h
deployment.apps/aws-load-balancer-controller   2/2     2            2           21h
replicaset.apps/aws-load-balancer-controller-6bc577994f   2         2         2       21h
Step 4: AWS Load Balancer Ingress Controller のテスト

 Contour のテストで作られた Nginx Pod と Nodeport Service を流用します。
 Ingress は下記の yaml をデプロイします。

aws-lb-ingress-test.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: aws-alb-test-ingress
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/scheme: internet-facing
spec:
  rules:
  - host:
    http:
      paths:
      - path: /old
        pathType: Prefix
        backend:
          service:
            name: lb-svc-2
            port:
              number: 80
      - path: /
        pathType: Prefix
        backend:
          service:
            name: lb-svc-1
            port:
              number: 80

テストのために、alb.ingress.kubernetes.io/scheme: internet-facing の Annotation を追加し、インターネットからALBへのアクセスを許可します。

 デプロイ後の Ingress を確認すると、ALB の DNS 名が紐付けられています。

 NAME                   CLASS    HOSTS   ADDRESS                                                                  PORTS   AGE
aws-alb-test-ingress   <none>   *       k8s-default-awsalbte-xxxxx.us-east-2.elb.amazonaws.com   80      91m

 早速 ALB の public DNS 名でアクセスしてみます。
TUNA08.jpg
 想定通り、振り分けくれています。
 AWS Load Balancer の詳細設定等はUser Guideを参照してください。

Chapter Last

 今回はデプロイと極シンプルのテストをやってみただけですが、ContourとALBにはそれぞれの特性(Contour の HTTP Proxy や ALB の TargetGroup および AWS WAFなど)があるので、それらの比較、そしてTCEとEKSの比較等にも興味がありますので、今後ちょっとずつ書いてみたいです。

0
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
0
0