【Amazon EKS】第二回 ALBを利用してNginx Podに負荷分散設定をしてみた!
投稿者:内堀 雄真
はじめに
こんにちは! ハイブリッドクラウド部の内堀です。
ハイブリッドクラウド部では、Amazon EKSについてのテックブログを投稿しています!
前回記事では「Amazon EKSのクラスターとノードグループの作成を行い、踏み台サーバからクラスターへの接続が出来るようになる」までを実装しました。
今回は「Nginxが起動するPodを作成し、AWS ALBを利用した負荷分散が出来るようになる」までを実装していきます。
目次
OIDCプロバイダーの作成
OIDCプロバイダーは、身元を確認したり認証情報を提供したりする役割を持っています。
今回はAWS Load Balancer Controller サービスアカウントでIAMロールを使用するため、作成が必要となります。
公式ドキュメント「クラスター用の IAM OIDC プロバイダーの作成」を参考に、OIDCプロバイダーを作成していきます。
前提条件
- AWS CLIの有効なバージョンがインストールされていること。
- kubectlの有効なバージョンがインストールされていること。
二つの有効なバージョンについては、上記の公式ドキュメントを参照してください。
今回はAWS CLI ver2.13.7、kubectl ver1.27.1がインストールされた環境で作成していきます。
作成
EKSコンソール > クラスター
該当のクラスター名をクリックし、
概要 > 詳細 にある「OpenID Connect プロバイダー URL」の値をコピーしておきます。
IAMコンソール > IDプロバイダ
「プロバイダを追加」をクリックします。
「プロバイダのタイプ」はOpenID Connectを選択し、
「プロバイダのURL」では先ほどコピーしたURLを貼り付けて「サムプリントを取得」を押します。
「対象者」では「sts.amazonaws.com」と入力します。
上記の入力が終わったら「プロバイダを追加」をクリックし、プロバイダを作成します。
AWS Load Balancer Controllerのインストール
AWS Load Balancer ControllerはEKS上で稼働するPodに対してAmazon Elastic Load Balancer(ELB)の設定・管理を自動化するツールです。
IngressリソースをデプロイすることでALBを作成し、Serviceリソースのtype: LoadBalancerとすることでNLBを作成します。
以前はAWS ALB Ingress Controller と呼ばれていました。
公式ドキュメント「AWS Load Balancer Controller アドオンのインストール」を参考にインストールを行います。
1. IAMポリシーの作成
IAM ポリシーを作成します。
# IAMポリシーの内容をダウンロード
$ curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.4.7/docs/install/iam_policy.json
# IAMポリシーの作成
$ aws iam create-policy \
--policy-name AWSLoadBalancerControllerIAMPolicy \
--policy-document file://iam_policy.json
2. IAMロールの作成
IAMロールを作成し、先ほど作成したIAMポリシーをアタッチしておきます。
日本語の箇所は環境に合わせて書き換えてください。
# クラスターのOIDCプロバイダーIDを取得して変数に格納する
$ oidc_id=$(aws eks describe-cluster --name (クラスター名) --query "cluster.identity.oidc.issuer" --output text | cut -d '/' -f 5)
# IDを確認する
# 出力されたIDは次コマンド内で入力する
$ aws iam list-open-id-connect-providers | grep $oidc_id | cut -d "/" -f4
# 日本語箇所を書き換え、jsonファイルを作成する
$ cat >load-balancer-role-trust-policy.json <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::(アカウントID):oidc-provider/oidc.eks.(リージョンコード).amazonaws.com/id/(二つ目のコマンドで取得したID)"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.(リージョン).amazonaws.com/id/(二つ目のコマンドで取得したID):aud": "sts.amazonaws.com",
"oidc.eks.(リージョン).amazonaws.com/id/(二つ目のコマンドで取得したID):sub": "system:serviceaccount:kube-system:aws-load-balancer-controller"
}
}
}
]
}
EOF
# IAMロールを作成する
$ aws iam create-role \
--role-name AmazonEKSLoadBalancerControllerRole \
--assume-role-policy-document file://"load-balancer-role-trust-policy.json"
# IAMロールに先ほど作成したEKS管理のIAMポリシーをアタッチする
$ aws iam attach-role-policy \
--policy-arn arn:aws:iam::(アカウントID):policy/AWSLoadBalancerControllerIAMPolicy \
--role-name AmazonEKSLoadBalancerControllerRole
3. サービスアカウントの作成
サービスアカウント「aws-load-balancer-controller」を作成します。
名前空間はkube-systemを指定してください。
# 日本語箇所を書き換え、yamlファイルを作成する
$ cat >aws-load-balancer-controller-service-account.yaml <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/name: aws-load-balancer-controller
name: aws-load-balancer-controller
namespace: kube-system
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::(アカウントID):role/AmazonEKSLoadBalancerControllerRole
EOF
#サービスアカウントを作成する
$ kubectl apply -f aws-load-balancer-controller-service-account.yaml
4. AWS Load Balancer Controllerのインストール
Helmを使用してインストールを行います。
Helmの導入はこちらを参考にしてください。
# Helmのインストール
$ curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 > get_helm.sh
$ chmod 700 get_helm.sh
$ ./get_helm.sh
# インストール確認
$ helm version --short | cut -d + -f 1
v3.12.2
# eks-chartsリポジトリを追加する
$ helm repo add eks https://aws.github.io/eks-charts
# ローカルリポジトリの更新
$ helm repo update eks
# AWS Load Balancer Controller のインストール
$ helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
-n kube-system \
--set clusterName=(クラスター名) \
--set serviceAccount.create=false \
--set serviceAccount.name=aws-load-balancer-controller
5. インストール確認
AWS Load Balancer Controllerがインストールされていることを確認します。
$ kubectl get deployment -n kube-system aws-load-balancer-controller
NAME READY UP-TO-DATE AVAILABLE AGE
aws-load-balancer-controller 2/2 2 2 26d
アプリケーション・ALBのデプロイ
NginxのPodを起動し、ALB経由でアクセスするためのDeployment,Service,Ingressを作成します。
今回はAWS ECRのパブリックリポジトリにあるnginxイメージを使用して作成していきます。
1. Deploymentファイルの作成
Podのスケーリング設定や情報を定義します。
Deploymentを使用することで、稼働するPod数の保証や、ローリングアップデートを自動で行ってくれます。
次の内容をdeployment.yamlとして保存します。
# Deploymentリソースの定義に使用されるKubernetes APIのバージョンとグループ
apiVersion: apps/v1
# 作成するリソースの種類
kind: Deployment
# メタデータ
metadata:
name: nlb-sample-app # 作成するリソースの名前
namespace: nginx # リソースを作成する名前空間
# リソースの仕様
spec:
replicas: 2 # Deploymentが管理するPodのレプリカ数
selector: # 適用するリソースの選択
matchLabels: # ラベルの一致を条件とする
app: nginx
template: # 作成するpodの定義
metadata:
labels:
app: nginx
spec:
containers: # pod内のコンテナの仕様
- name: nginx # コンテナの名前
image: public.ecr.aws/nginx/nginx:1.23 # コンテナイメージ
ports: # コンテナが公開するポート(内部向け)
- name: tcp
containerPort: 80
2. Serviceファイルの作成
クラスタ内のPodへのネットワーク接続設定を定義します。
NginxのPodにアクセスするためのSerivceを作成します。
次の内容をservice.yamlとして保存します。
apiVersion: v1
kind: Service
metadata:
name: alb-sample-service
namespace: nginx
spec:
ports: # Podへのアクセスに使用するport
- port: 80
targetPort: 80
protocol: TCP
type: ClusterIP # クラスター内Pod通信
selector:
app: nginx
3. Ingressファイルの作成
NginxにアクセスするためのIngressを作成します。
Ingressが作成されるとIngressコントローラーによりALBが自動作成され、Nginxへのアクセスが可能となります。
次の内容をingress.yamlとして保存します。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing # 外部からのトラフィックを許可
alb.ingress.kubernetes.io/target-type: ip # Ipをターゲットに設定
name: test-ingress
namespace: nginx
spec:
ingressClassName: alb # ingressのクラス名を定義
rules:
- http: # httpルール
paths:
- path: /
pathType: Prefix
backend:
service:
name: alb-sample-service # 接続するService
port:
number: 80
4. マニフェストファイルの適用・デプロイ確認
作成した3つのマニフェストファイル(deployment.yaml, service.yaml, ingress.yaml)を、クラスターに適用します。
$ kubectl apply -f deployment.yaml, service.yaml, ingress.yaml
適用後、リソースが正常にデプロイされているか確認します。
以下のような出力となっていれば、問題なくデプロイが完了しています。
$ kubectl get all -n nginx
NAME READY STATUS RESTARTS AGE
pod/nlb-sample-app-78ddc8bc75-dll7f 1/1 Running 0 3h39m
pod/nlb-sample-app-78ddc8bc75-zxkdv 1/1 Running 0 3h39m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/alb-sample-service ClusterIP 172.20.90.135 <none> 80/TCP 131m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nlb-sample-app 2/2 2 2 3h39m
NAME DESIRED CURRENT READY AGE
replicaset.apps/nlb-sample-app-78ddc8bc75 2 2 2 3h39m
$ kubectl get ingress -n nginx
NAME CLASS HOSTS ADDRESS PORTS AGE
test-ingress alb * k8s-nginx-testingr-bda49c23c3-672405439.ap-northeast-1.elb.amazonaws.com 80 125m
AWS コンソールに移動し、ALBが作成されていることも確認してください。
EC2コンソール > ロードバランサー
アプリケーションへの接続
早速作成したNginxに接続してみます。
ALBの詳細情報からDNS名を取得し、ブラウザでアクセスしてみます。
http://k8s-nginx-testingr-bda49c23c3-672405439.ap-northeast-1.elb.amazonaws.com
以下のような画面が出力されれば成功です。
負荷分散の確認
ALBからのアクセスが2つのNginxのPodに負荷分散されていることを各Podのログで確認します
まずは起動しているPodの名前を調べます。
$ kubectl get pods -n nginx
NAME READY STATUS RESTARTS AGE
nlb-sample-app-78ddc8bc75-2wd9l 1/1 Running 0 20h
nlb-sample-app-78ddc8bc75-skwcq 1/1 Running 0 20h
一つ目のPod、”nlb-sample-app-78ddc8bc75-2wd9l” のログを確認します。
$ kubectl logs nlb-sample-app-78ddc8bc75-2wd9l -n nginx
...
10.0.0.21 - - [31/Aug/2023:09:13:32 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36" "xxx.xxx.xxx.xxx, xxx.xxx.xxx.xxx"
...
クライアントから一つ目のPodへのアクセスログを確認出来ました。
続いて二つ目のPod、”nlb-sample-app-78ddc8bc75-skwcq” のログを確認してみます。
$ kubectl logs nlb-sample-app-78ddc8bc75-skwcq -n nginx
...
10.0.12.7 - - [31/Aug/2023:09:11:34 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36" "xxx.xxx.xxx.xxx, "xxx.xxx.xxx.xxx"
...
同じく、クライアントから二つ目のPodへのアクセスログを確認出来ました。
ALB経由で2つのPodに負荷分散されていることが確認できました。
まとめ
今回のブログ記事では、EKSを用いたPodにおける負荷分散設定の詳細な手順をご紹介しました。
- OIDCプロバイダーの作成
- AWS Load Balancer Controller のインストール
- Nginxが起動するPodとALBのデプロイ
これらのステップにより、目標とするアプリケーションに接続した際に、負荷が複数のPodに分散されるようになりました。この記事が皆さまのEKSや負荷分散の設定に役立つ一助となれば幸いです。この機会に、皆さまもぜひEKSを触ってみてください!
第3回では、CI/CDを用いてコンテナイメージの作成からEKS上への自動デプロイに関して記事にする予定です。次回も楽しみにお待ちください!
AWS社とのAWSソリューションプロバイダープログラム契約を結び、AWSのアカウントの手配から設計、環境構築、システム運用までワンストップのソリューションを提供いたします。
コンテナ技術には特に力を入れており、Amazon EKSだけでなく、Red Hat OpenShiftのソリューションもございます。
OpenShiftのソリューションページや、運用ソリューションであるNI+C Multicloud MSPの紹介ページもありますので、一読していただけますと幸いです。