Envoy Proxyを使ったファイルベースの動的コンフィグレーション (EKS)

メリークリスマス !

こんにちは、ed (edward) です。

この記事は、みらい翻訳のカレンダー | Advent Calendar 2022 - Qiita の25日目です。

前回17日目はローカルPC上の Kubernetes を使ったファイルベースの動的コンフィグレーションを説明しました。

今回のこの記事では、Amazon Elastic Kubernetes Service (EKS) を使って説明します。

IaC ツールは、Terraform を使用します。コードは、GitHub リポジトリ にあります。

最終的に実現されるルーティングは前回と同じです。

なお、プロダクション環境で利用する場合は「Envoy Proxyを使ったファイルベースの動的コンフィグレーションとk8sのライフサイクル」を参照することをおすすめします。

EKS クラスタの構築

git clone した後、spring-boot/eks/terraform ディレクトリに移動してください。そして、次の3つのコマンドを順に実行します。

terraform init
terraform plan
terraform apply

この terraform により、永続ボリュームに EBS を使う aws-ebs-csi-driverクラスタ add on に導入されます。

構築された EKS クラスタkubectl のデフォルトコンテキストに設定します。

aws eks update-kubeconfig --name envoyproxy-examples

EBS ボリュームの作成

クラスタで生成されたノードのアベイラビリティゾーンを確認します。

kubectl get node -L topology.ebs.csi.aws.com/zone

EBS ボリュームは管理コンソールまたは AWS CLI で作成します。今回使用する EBS ボリュームは最小の 1G で作成します。

aws ec2 create-volume --availability-zone ap-northeast-1d --size 1

永続ボリュームの作成 (PersistentVolume と PersistentVolumeClaim)

spring-boot/eks ディレクトリに移動します。

pv.yaml ファイルを編集して、作成した EBS ボリュームの ID を volumeHandle に設定します。

kubectl apply -f pv.yaml
kubectl apply -f pvc.yaml

EnvoyProxy の構成ファイルのコピー

ここまでの手順では EBS ボリュームは空の状態です。Envoy Proxy の初期の構成ファイルを BusyBox のイメージを使ってコピーします。

次のコマンドを実行する前に、deployment.yamltopology.ebs.csi.aws.com/zone を EBS ボリュームを作成したアベイラビリティゾーンに合わせてください。

kubectl apply -f deployment.yaml
export POD_NAME=$(kubectl get pod -o jsonpath='{.items[0].metadata.name}' -l app=app)
kubectl cp ../config $POD_NAME:/app/data/jp/config/
kubectl cp ../config $POD_NAME:/app/data/spring-boot-demo/config/
kubectl exec $POD_NAME -- ls -lR /app/data
kubectl delete -f deployment.yaml

メモ: 構成ファイルのコピーが完了した EBS ボリュームのスナップショットをここで取得しておくと、異なるアベイラビリティゾーンで同じデータが必要になった時にスナップショットから EBS ボリュームを作成できるようになるので便利です。

Helm を使ってインストール

spring-boot ディレクトリに移動します。

レガシーアプリケーションを想定したサービスのインストール

helm install spring-boot-demo --values=eks-us-values.yaml ./spring-boot-demo

kubectl get svc を実行すると、次のような出力が得られます。

NAME                     TYPE           CLUSTER-IP      EXTERNAL-IP                                                                    PORT(S)        AGE
kubernetes               ClusterIP      172.20.0.1      <none>                                                                         443/TCP        57m
spring-boot-demo         LoadBalancer   172.20.187.23   a461f11bac2c4475c80f679b35ee1457-1810793654.ap-northeast-1.elb.amazonaws.com   80:31938/TCP   2m27s
spring-boot-demo-admin   LoadBalancer   172.20.190.77   a6db6b07a227c46b8b12a7e4b4861348-1598948861.ap-northeast-1.elb.amazonaws.com   80:30818/TCP   2m27s

spring-boot-demoEXTERNAL-IP にあるドメイン名を使ってアクセスすると、Hello World が返ります。

curl http://a461f11bac2c4475c80f679b35ee1457-1810793654.ap-northeast-1.elb.amazonaws.com
Hello World

新しいサービスを想定したサービスのインストール

helm install jp --values=eks-jp-values.yaml ./spring-boot-demo

kubectl get svc を実行すると、次のような出力が得られます。

NAME                        TYPE           CLUSTER-IP      EXTERNAL-IP                                                                    PORT(S)        AGE
jp-spring-boot-demo         LoadBalancer   172.20.247.84   af7999c557c184403ab89c1c594f74af-1198057548.ap-northeast-1.elb.amazonaws.com   80:31249/TCP   55s
jp-spring-boot-demo-admin   LoadBalancer   172.20.91.61    a6566724d98db49a69605d8be2e278bb-326792365.ap-northeast-1.elb.amazonaws.com    80:32010/TCP   55s
kubernetes                  ClusterIP      172.20.0.1      <none>                                                                         443/TCP        64m
spring-boot-demo            LoadBalancer   172.20.187.23   a461f11bac2c4475c80f679b35ee1457-1810793654.ap-northeast-1.elb.amazonaws.com   80:31938/TCP   9m12s
spring-boot-demo-admin      LoadBalancer   172.20.190.77   a6db6b07a227c46b8b12a7e4b4861348-1598948861.ap-northeast-1.elb.amazonaws.com   80:30818/TCP   9m12s

jp-spring-boot-demoEXTERNAL-IP にあるドメイン名を使ってアクセスすると、Hello Japan が返ります。

curl http://af7999c557c184403ab89c1c594f74af-1198057548.ap-northeast-1.elb.amazonaws.com
Hello Japan

ルーティングの追加

ルーティングを追加する前に、spring-boot-demojp パスを確認します。

curl http://a461f11bac2c4475c80f679b35ee1457-1810793654.ap-northeast-1.elb.amazonaws.com/jp
{"timestamp":"2022-12-25T12:20:06.818+00:00","path":"/jp","status":404,"error":"Not Found","message":null,"requestId":"a705bb12-3"}

上の通り 404 エラーが返されます。

kubectl get podspring-boot-demo のポッド名を調べます。

export POD_NAME=spring-boot-demo-ccc77d49b-b6zb7
kubectl exec $POD_NAME -c envoy -- cat /var/lib/envoy/spring-boot-demo/config/cds/cds.yaml
resources:
  - "@type": type.googleapis.com/envoy.config.cluster.v3.Cluster
    name: us
    load_assignment:
      cluster_name: us
      endpoints:
        - lb_endpoints:
            - endpoint:
                address:
                  socket_address:
                    address: 127.0.0.1
                    port_value: 8081

クラスタの更新

jp-spring-boot-demo サービスを Envoy Proxy のクラスタに追加する設定ファイルをコピーします。

kubectl exec $POD_NAME -c envoy -- mv -f /var/lib/envoy/spring-boot-demo/config/cds/cds2.yaml /var/lib/envoy/spring-boot-demo/config/cds/cds.yaml

リスナーの更新

kubectl exec $POD_NAME -c envoy -- mv -f /var/lib/envoy/spring-boot-demo/config/lds/lds2.yaml /var/lib/envoy/spring-boot-demo/config/lds/lds.yaml
curl http://a461f11bac2c4475c80f679b35ee1457-1810793654.ap-northeast-1.elb.amazonaws.com/jp
Hello Japan

リソースの削除

最後に、使用したリソースを削除して課金されないようにします。

cd spring-boot
helm uninstall jp
helm uninstall spring-boot-demo
cd eks
kubectl delete -f pvc.yaml
kubectl delete -f pv.yaml
cd terraform
terraform destroy

上記コマンドを実行した後、手動で作成した EBS ボリュームを削除します。

まとめ

この記事では永続ボリュームに EBS を使用しました。Envoy Proxy の構成変更はファイルの中身の変化ではなく移動 (mv) を検出するものであるためです。

EBS の場合、同じアベイラビリティゾーンのノードにデプロイされた Pod でなければ利用できないという制約があります。この制約のない永続ボリュームとして利用できる他のサービスに Amazon Elastic File System (EFS)Amazon FSx for LustreAmazon FSx for NetApp ONTAP があります。

ところで、デジタルバッジといえば、AWS 認定資格のものが有名ですが、今年は、AWS Skill Builder のラーニングプランにあるバッジアセスメントで 80% 以上の正答率で得られるバッジがいくつか発表されています。

この記事の EBS についてのラーニングプランもあります。

以下の3つのラーニングプランそれぞれでデジタルバッジを獲得でき、3つとも取得すると、Storage Core バッジも取得できます。

最後まで読んでいただきありがとうございます。

それでは皆さん、よいお年をお迎えください。

We're hiring!

みらい翻訳では、アーキテクチャに興味のある方や技術ブログを盛り上げていただけるエンジニアを募集しています! ご興味のある方は、ぜひ下記リンクよりご応募・お問い合わせをお待ちしております。

参考