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

KDDI Engineer&DesignerAdvent Calendar 2021

Day 4

【初心者】AWS Wavelengthを使ってみる #5 (Amazon EKS + F5 BIG-IP によるコンテナ負荷分散)

Last updated at Posted at 2021-12-04

#1. 目的

  • AWS Wavelength では、2021/11現在ではELB(CLB/ALB/NLB全て)が未提供。そのため、Wavelength Zoneにてインスタンスやコンテナの負荷分散を行う場合、自分で仕組みを用意する必要がある。例えば、北米でAWS Wavelengthに接続可能な回線を提供するVerizon社の、Wavelengthに関するQAサイトにも、ELBの代替例としてHAProxyが推奨されている。

What can I use in place of AWS Elastic Load Balancing to automatically distribute incoming application traffic across multiple targets, such as Amazon EC2 instances?
Consider using Amazon EC2 as a proxy server and configuring HAProxy, a free, open source software implementation of a high availability load balancer. To learn more about HAProxy, visit the HAProxy configuration manual here.

  • 今回は、ELBの代替として、商用プロダクトであり信頼性も高い、F5社のBIG-IP Virtual Edition(AWSなどのクラウドで動作するロードバランサ)を用いて、コンテナの負荷分散が実現可能なことを確認する。

#2. やったこと

  • Wavelength上にEKS環境を構築し、コンテナを起動する。
  • Wavelength上にBIG-IPをデプロイし、コンテナの負荷分散が可能なことを確認する。以下の2方式で確認する。
    • Ingress
    • Service type LoadBalancer
  • BIG-IPには、EKS環境にデプロイするコントローラ(CIS: F5 Container Ingress Services) から動的に設定を投入する。
  • なお今回、Wavelength環境での検証を行っているが、Wavelengthに依存する設定はないため、同様の内容を東京リージョンなどのEKS環境で実現することも可能。

#3. 構成
##全体の構成

  • Wavelength上にEKSのノードグループを用意し、コントローラ(CIS)、サンプルアプリをデプロイする。
  • ノードグループと同じサブネットにBIG-IPをデプロイし、外部からBIG-IP経由でサンプルアプリにアクセスできるようにする。

f5構成図1.png

##Ingress の場合

  • EKS上ではIngressリソースを作成する(BIG-IPがそれに合わせて自動設定される)。
  • BIG-IP経由でサンプルアプリのPodまでアクセスできることを確認する。

f5構成図2.png

##Service type LoadBalancerの場合

  • EKS上ではService type Loadbalancer リソースを作成する(BIG-IPがそれに合わせて自動設定される)。
  • BIG-IP経由でサンプルアプリのPodまでアクセスできることを確認する。

f5構成図3.png

#4. 手順
##4.1 環境の準備

EKS環境の構築

  • 以前の記事「【初心者】AWS Wavelengthを使ってみる #2 (Amazon EKSの利用)」を参考に、Wavelength上にEKS環境を構築する。
    • Kubernetesのバージョンはv1.21(2021/11時点のEKSでの最新バージョン)
    • 通常時のワーカーノード数は2(Wavelength Zoneに t3.mediumのインスタンスが2個ある状態)
  • ワーカーノードへキャリアIPを付与する(今回は直接外部にコンテナイメージを取得に行かせるため)。
  • ワーカーノードはサブネット内(10.0.10.0/24)からのアクセスを許可する(後で同一サブネットに作成するF5 BIG-IPからコンテナへのアクセスを許可するため)。

テスト用ウェブサービスの作成

  • 後でF5 BIG-IPを用いてインターネットへ公開する用の、テスト用のウェブサービスを作成する。(httpアクセスすると、ノード名、pod名が返されるだけのシンプルなサービス)
[ec2-user@ip-10-0-0-151 ~]$ kubectl get deployment
NAME     READY   UP-TO-DATE   AVAILABLE   AGE
coffee   2/2     2            2           26h
tea      3/3     3            3           26h
[ec2-user@ip-10-0-0-151 ~]$ kubectl get pods
NAME                      READY   STATUS    RESTARTS   AGE
coffee-6f4b79b975-b7tch   1/1     Running   0          26h
coffee-6f4b79b975-n422v   1/1     Running   0          26h
tea-6fb46d899f-5vqlx      1/1     Running   0          26h
tea-6fb46d899f-f98zc      1/1     Running   0          26h
tea-6fb46d899f-x7wkv      1/1     Running   0          26h
[ec2-user@ip-10-0-0-151 ~]$ kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
coffee-svc   ClusterIP   172.20.73.10    <none>        80/TCP    26h
kubernetes   ClusterIP   172.20.0.1      <none>        443/TCP   2d6h
tea-svc      ClusterIP   172.20.179.79   <none>        80/TCP    26h
  • このcoffee-svc/tea-svcについて、BIG-IPを用いて外部からのアクセスを可能にするよう設定していく。

##4.2 BIG-IPの設定

インスタンスの起動

  • BIG-IP VEをWavelength上のサブネット(EKSのワーカーノード2個が起動しているのと同じサブネット)にデプロイする。
  • イメージ名: F5 BIG-IP VE - ALL (BYOL, 2 Boot Locations) ※ライセンス込みのタイプ(PAYG)もあるが、今回はライセンスはBYOLとし、別途F5社より検証用ライセンスを発行頂いたものを用いる。
  • インスタンスタイプ: t3.medium
  • バージョン: 16.1.1 Build 0.0.16
  • キャリアIPを付与し、外部からのアクセスを可能にする。
  • 同一サブネット(10.0.10.0/24)からのアクセスを許可する。(ワーカーノード上に配置されるF5のコントローラからのアクセスを受けるため)

管理画面用パスワード設定

  • ssh(user: admin, 秘密鍵) で接続し、管理画面用のパスワードを設定、保存する。
admin@(ip-10-0-10-63)(cfg-sync Standalone)(NO LICENSE)(/Common)(tmos)# modify auth user admin password PASSWORD
admin@(ip-10-0-10-63)(cfg-sync Standalone)(NO LICENSE)(/Common)(tmos)# save sys config

 

ライセンスの設定

  • 管理画面 ( https://BIG-IPインスタンスのキャリアIP:8443 )にアクセスし、user: admin, password: 上記で設定したパスワードで、ログインする。

f501.png

  • F5社から発行頂いた検証用ライセンスを設定する。

f502.png

Partition作成

  • 専用のPartition(BIG-IP内の管理領域のようなもの)を作成する。 System -> Users: Partition List -> New Partition で、新規に「k8s]というPartitionを作成する。

f503.png

f504.png

AS3の追加

  • 「AS3(Application Services 3 Extension)」は、BIG-IPを外部から操作することを可能とする拡張モジュールのようなもの。
  • F5社のGitHubから、rpmファイル(f5-appsvcs-3.28.0-3.noarch.rpm)を作業用PCなどにダウンロードする。今回は v3.28.0 を使用する。
  • BIG-IPの管理画面で、iApps -> Package Management LX から、rpmファイルをインポートする。

f505.png

f506.png

##4.3 Ingress での設定

CIS 用権限などの作成

  • CISは、k8sなどのコンテナ環境とF5 BIG-IPを連携させるような仕組み。
  • まずはEKS上でCISのコントローラ(k8s-bigip-ctlr)を動作させるための権限などを用意する。(もう少し細かく権限付与も可能だが、今回は検証のためざっくりclusteradmin権限を付与)
[ec2-user@ip-10-0-0-151 ~]$ kubectl create secret generic bigip-login -n kube-system --from-literal=username=admin --from-literal=password=PASSWORD
secret/bigip-login created
[ec2-user@ip-10-0-0-151 ~]$ kubectl create serviceaccount k8s-bigip-ctlr -n kube-system
serviceaccount/k8s-bigip-ctlr created
[ec2-user@ip-10-0-0-151 ~]$ kubectl create clusterrolebinding k8s-bigip-ctlr-clusteradmin --clusterrole=cluster-admin --serviceaccount=kube-system:k8s-bigip-ctlr
clusterrolebinding.rbac.authorization.k8s.io/k8s-bigip-ctlr-clusteradmin created

CIS (k8s-bigip-ctlr) の作成

  • EKS環境でIngressリソースを作成した時に、BIG-IPに適切な設定が自動投入されるようにするため、CIS (k8s-bigip-ctlr) を作成する。これがIngress Controllerとして動作する。
  • 以下のマニフェストを用いる。「--bigip-url=https://10.0.10.63:8443」のところは、BIG-IPのインスタンスのローカルIPアドレスを指定する。
  • 今回は他環境で動作実績のあるバージョン(v2.5.1)を使用している。
cluster-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: k8s-bigip-ctlr
  namespace: kube-system
spec:
  replicas: 1
  selector:
    matchLabels:
      app: k8s-bigip-ctlr
  template:
    metadata:
      name: k8s-bigip-ctlr
      labels:
        app: k8s-bigip-ctlr
    spec:
      serviceAccountName: k8s-bigip-ctlr
      containers:
        - name: k8s-bigip-ctlr
          image: "f5networks/k8s-bigip-ctlr:2.5.1"
          imagePullPolicy: IfNotPresent
          env:
            - name: BIGIP_USERNAME
              valueFrom:
                secretKeyRef:
                  name: bigip-login
                  key: username
            - name: BIGIP_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: bigip-login
                  key: password
          command: ["/app/bin/k8s-bigip-ctlr"]
          args: [
            "--bigip-username=$(BIGIP_USERNAME)",
            "--bigip-password=$(BIGIP_PASSWORD)",
            "--bigip-url=https://10.0.10.63:8443",
            "--insecure=true",
            "--bigip-partition=k8s",
            "--pool-member-type=cluster"
          ]
[ec2-user@ip-10-0-0-151 ~]$ kubectl apply -f cluster-deployment.yaml
deployment.apps/k8s-bigip-ctlr created
[ec2-user@ip-10-0-0-151 ~]$ kubectl get pods -n kube-system			
NAME                              READY   STATUS    RESTARTS   AGE			
aws-node-8jlzx                    1/1     Running   0          55m			
aws-node-tb5kn                    1/1     Running   0          15h			
coredns-76f4967988-5wvjr          1/1     Running   0          14h			
coredns-76f4967988-vfxsv          1/1     Running   0          27h			
k8s-bigip-ctlr-6989b8bf6c-z9jc9   1/1     Running   0          25s			
kube-proxy-85tgh                  1/1     Running   0          15h			
kube-proxy-qkkbk                  1/1     Running   0          55m	
  • 成功すると、k8s-bigip-ctlrのpodがRunningになる。(BIG-IPのアクセスURLやポートが間違っていたり、BIG-IPへのアクセスがsecuritygroupで拒否されていたりして、BIG-IPにアクセスできない場合、podの作成に失敗する。)

IngressClassの作成

  • CISで使用するIngressClassを作成する。
[ec2-user@ip-10-0-0-151 ~]$ kubectl apply -f https://raw.githubusercontent.com/F5Networks/k8s-bigip-ctlr/master/docs/config_examples/ingress/networkingV1/example-default-ingress-class.yaml
ingressclass.networking.k8s.io/f5 created	

Ingress リソースの作成

  • 以下のマニフェストを用いて、Ingress リソースを作成する。「https://BIG-IPのキャリアIP/tea」 の場合はteaのサービスに、「https://BIG-IPのキャリアIP/coffee」の場合はcoffeeのサービスに転送するような設定としている)
ingress-cafe.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: cafe-ingress
  annotations:
    virtual-server.f5.com/partition: "k8s"
    virtual-server.f5.com/ip: 10.0.10.63
    virtual-server.f5.com/http-port: "80"
    virtual-server.f5.com/ssl-redirect: "false"
    virtual-server.f5.com/balance: "round-robin"
spec:
  ingressClassName: f5
  rules:
  - http:
      paths:
      - path: /tea
        backend:
          serviceName: tea-svc
          servicePort: 80
      - path: /coffee
        backend:
          serviceName: coffee-svc
          servicePort: 80
[ec2-user@ip-10-0-0-151 ~]$ kubectl apply -f ingress-cafe.yaml
Warning: networking.k8s.io/v1beta1 Ingress is deprecated in v1.19+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
ingress.networking.k8s.io/cafe-ingress created
[ec2-user@ip-10-0-0-151 ~]$ kubectl get ingress
NAME           CLASS   HOSTS   ADDRESS      PORTS   AGE
cafe-ingress   f5      *       10.0.10.63   80      7s

BIG-IPの自動設定投入確認

  • Ingress リソース作成後、BIG-IPに必要な設定が入ることを確認する。

  • Virtual Server (待ち受けするアドレス・ポート、転送先のPoolなどの設定のセット)が作成される。

f507.png

  • Virtual Server に紐づくPolicy(URIの部分(tea もしくは coffee)を見てそれぞれ別のPoolに転送する)が設定される。

f508.png

動作確認

  • 手元のPC(auスマホでテザリング)のブラウザ(FirefoxとEdge)から、「http://BIG-IPのキャリアIP/coffee」 にアクセスする。coffeeサービス用の2つのPodのどちらかで処理されることを確認する。(アクセス時、以下のように処理を行ったホストのIPアドレスやPod名が表示されることで判別可能)

f510.png

f509.png

  • 同様に 「http://BIG-IPのキャリアIP/tea」 にアクセスすると、tea サービスを処理するPod(3つのどれか)へアクセス可能。URIに応じて別々のサービスにアクセスできていることが確認できる。

f511.png

  • BIG-IPのStatisticsの画面で、/coffee にアクセスした場合、coffeeサービス用の2つのPodに処理が分散されていることが確認できる。

f512.png

##4.4 Service Type LoadBalancer での設定

FIC(F5 IPAM Controller)の作成

  • Service Type LoadBalancerでの設定の場合、IPアドレスの割り当て管理管理が必要となるため、「FIS(IPAM Controller)」を追加で作成する。
  • 以下のマニフェストを使用する。
    • 今回はv0.1.4(2021/11時点の最新版はv0.1.5)を使用している。v0.1.5から信頼性の向上のためか、PVの使用が必要となっており検証用としては煩雑だったため。
    • 「--ip-range」として、この環境のサブネットの中から、配布したいIPアドレスのレンジを指定する。
ipam-controller.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    name: ipam-controller
  name: ipam-controller
  namespace: kube-system
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ipam-controller
  template:
    metadata:
      labels:
        app: ipam-controller
    spec:
      containers:
      - args:
        - --orchestration
        - kubernetes
        - --ip-range
        - '{"test" : "10.0.10.101-10.0.10.105","prod" : "10.0.10.111-10.0.10.115"}'
        - --log-level
        - DEBUG
        command:
        - /app/bin/f5-ipam-controller
        image: f5networks/f5-ipam-controller:0.1.4
        imagePullPolicy: IfNotPresent
        name: ipam-controller
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      serviceAccount: k8s-bigip-ctlr
      serviceAccountName: k8s-bigip-ctlr
      terminationGracePeriodSeconds: 30
[ec2-user@ip-10-0-0-151 ~]$ kubectl apply -f ipam-controller.yaml
deployment.apps/ipam-controller created
[ec2-user@ip-10-0-0-151 ~]$ kubectl get pod -n kube-system
NAME                               READY   STATUS    RESTARTS   AGE
aws-node-8jlzx                     1/1     Running   0          3d10h
aws-node-tb5kn                     1/1     Running   0          4d1h
coredns-76f4967988-5wvjr           1/1     Running   0          3d23h
coredns-76f4967988-vfxsv           1/1     Running   0          4d12h
ipam-controller-5f5cd96b54-4gd2r   1/1     Running   0          8s
k8s-bigip-ctlr-6989b8bf6c-z9jc9    1/1     Running   0          3d9h
kube-proxy-85tgh                   1/1     Running   0          4d1h
kube-proxy-qkkbk                   1/1     Running   0          3d10h

CRD作成

  • BIG-IPの設定値をk8s側で管理するためのCRDを作成する。
  • F5社のGitHubの「customresourcedefinitions.yml」 を以下の2行を修正して使用する。(長いのでyamlファイルの全体の転記は省略)
    • name: externaldnses.cis.f5.com -> externaldnss.cis.f5.com
    • plural: externaldnses -> externaldnss
  • 現在(2021/11)時点で、CIS(このCRDの利用側)と、CRDを作成するyamlで、externaldnsに関する名称の不一致(externaldnss/externaldnses)が発生している。そのうち修正されるのではと想定。
customresourcedefinitions-fixed.yaml
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: externaldnss.cis.f5.com
spec:
  group: cis.f5.com
  names:
    kind: ExternalDNS
    plural: externaldnss
    shortNames:
      - edns
    singular: externaldns
[ec2-user@ip-10-0-0-151 ~]$ kubectl apply -f customresourcedefinitions-fixed.yaml
customresourcedefinition.apiextensions.k8s.io/virtualservers.cis.f5.com created
customresourcedefinition.apiextensions.k8s.io/tlsprofiles.cis.f5.com created
customresourcedefinition.apiextensions.k8s.io/transportservers.cis.f5.com created
customresourcedefinition.apiextensions.k8s.io/externaldnss.cis.f5.com created
customresourcedefinition.apiextensions.k8s.io/ingresslinks.cis.f5.com created
customresourcedefinition.apiextensions.k8s.io/policies.cis.f5.com created

CIS(k8s-bigip-ctlr)の修正

  • Ingressの実施手順の際に作成したCIS(k8s-bigip-ctlr)の設定を修正して、podを再作成する。修正点は、「"--custom-resource-mode=true","--ipam=true"」の2行の追加。
cluster-deployment.yaml
          args: [
            "--bigip-username=$(BIGIP_USERNAME)",
            "--bigip-password=$(BIGIP_PASSWORD)",
            "--bigip-url=https://10.0.10.63:8443",
            "--insecure=true",
            "--bigip-partition=k8s",
            "--pool-member-type=cluster",
            "--custom-resource-mode=true",
            "--ipam=true"
          ]

BIG-IP インスタンスへのセカンダリIPの追加

  • IPAM ControllerのIPレンジで定義したIPアドレスがBIG-IPに紐づくように、BIG-IPのインスタンスの設定でセカンダリIPとしての設定を行う。
  • マネージメントコンソールのEC2の画面にて、BIG-IPのインスタンスを選択し、アクション -> ネットワーキング -> IPアドレスの管理 を選択する。
  • 指定したIPレンジをセカンダリIPとして追加する。

f513.png

Service type LoadBalancerリソース作成

  • coffee-svcのほうを外部公開するようなLoadBalancerリソースを作成する。
  • 現時点(2021/11)で、EKS環境で何もannotationsを付けずにLoadBalancerリソースを作成するとCLBが作成される。「service.beta.kubernetes.io/aws-load-balancer-type: "external"」を記載することで、CLBが作成されなくなる。
  • 「cis.f5.com/ipamLabel: test」を記載することで、「test」ラベルに紐づくIPレンジの中のIPアドレスが使用される。
typelb.yaml
apiVersion: v1
kind: Service
metadata:
  name: coffee-typelb
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: "external"
    cis.f5.com/ipamLabel: test
spec:
  ports:
  - port: 8080
    protocol: TCP
  selector:
    app: coffee
  type: LoadBalancer
[ec2-user@ip-10-0-0-151 ~]$ kubectl apply -f typelb.yaml
service/coffee-typelb created
[ec2-user@ip-10-0-0-151 ~]$ kubectl get svc
NAME            TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
coffee-svc      ClusterIP      172.20.73.10    <none>        80/TCP           5d8h
coffee-typelb   LoadBalancer   172.20.172.14   10.0.10.101   8080:30304/TCP   4s
kubernetes      ClusterIP      172.20.0.1      <none>        443/TCP          6d12h
tea-svc         ClusterIP      172.20.179.79   <none>        80/TCP           5d8h

キャリアIP付与

  • 今回はIPレンジの中から 10.0.10.101 が 使用されたため、このプライベートアドレスに対してキャリアIPを付与する。(BIG-IPへの管理用アクセスに用いているキャリアIPとは別のものとなる。)
  • キャリアIPをインスタンスに関連付けする際、プライベートIPアドレスは先の手順でセカンダリIPとして登録したものの中から選択可能。今回はLoadBalancer用に設定された10.0.10.101を選択する。

f514a.png

BIG-IPの自動設定投入確認

  • LoadBalancerのリソース作成後、BIG-IP側でVirtual Server、Poolなどが自動設定されることを確認する。

f515.png

f516.png

動作確認

  • ブラウザで「https://キャリアIP:8080/」にアクセスし、coffee-svcに接続できることを確認する。

f517.png

  • 2つのpodに負荷分散されていることを確認する。

f518.png

#5. 所感

  • Wavelength環境においても、F5社が提供するCISの仕組みを用いることにより、BIG-IPをk8s環境にうまく組み込む形で、ELBの代替として利用可能なことが確認できた。BIG-IPには今回検証した内容以外にも様々な機能があり、機会があればより深堀してみたい。

#6. 参考URL

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