今回やること
前回はterraformを使って、EKSとその他AWSリソースを作成するところまで実施しました。
今回はEKSのリソースを作成しつつ、AWS Load Balancer Controllerを使ってALBを作成し、外部から通信を受け付け可能な状態にするところまで試してみます。
このシリーズの記事
Terraformを使ってArgo CDによるGitOpsなリリースができるEKS環境を構築してみる(前編~TerraformでAWSリソースを構築してみた~)
Terraformを使ってArgo CDによるGitOpsなリリースができるEKS環境を構築してみる(中編~AWS Load Balancer Controller使ってみた~) ←今回はこちら
Terraformを使ってArgo CDによるGitOpsなリリースができるEKS環境を構築してみる(後編~Argo CDでGitOpsなデプロイやってみた~))
Kubernetesにおけるインターネットアクセス
Kubernetesでは、インターネットから通信を受け付ける方法として、大きく以下の2つの方法があります。
- Serviceのサービスタイプの1つであるLoad Balancerを使う
- Ingressを使う
2つとも外部のロードバランサーと連携してKubernetesクラスタへの外部アクセスを可能にするリソースです。大きな違いはロードバランシングがL4かL7のどちらで提供されるかという点。
今回は、Ingressを使った方式を試してみます。
AWS Load Balancer Controllerとは
Ingressを使用する場合、Ingressリソースと、Ingress Controllerと呼ばれるリソースの一式を用意する必要があります。ざっくり言うと、
- Ingress:ロードバランサーの設定を定義する
- Ingress Controller:Ingressリソースの内容に基づいて、ロードバランサーを作成する
という役割がそれぞれにあります。AWS Load Balancer Controllerは、AWSにおける「Ingress Controllerと呼ばれるリソースの一式」に相当します。
今回は以下の通り、Private Subnet内のKubernetesの各リソースと、ALBを作成し、アプリに疎通するところまで確認したいと思います。上記の通り、Ingress Controller(AWS Load Balancer Controller)がIngressを検知してALBを作ってくれます。
作ってみる
というわけで、AWS Load Balancer ControllerとIngressを作成して、ALBが作られていく様子を確認してみたいと思います。AWS Load Balancer Controllerの作成手順は以下のAWSの公式ガイドに書かれています。
IAMロールとServiceAccountの作成
まず初めにIAMロールとServiceAccountを作成します。いずれもAWSからテンプレートが提供されています。
該当のIAMロールにアタッチするポリシー「AWSLoadBalancerControllerIAMPolicy」を見る限り、これはKubernetesリソースであるAWS Load Balancer ControllerがAWSリソースであるALBを作成したりその他もろもろの権限を許可するためのロールとみなしてよさそうです。
なお、ロールの信頼関係は、リージョン、AWSアカウントIDおよび、EKSのOIDC部分(以下XXX…)を使用しているものに書き換えておく必要があります。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::111122223333:oidc-provider/oidc.eks.region-code.amazonaws.com/id/XXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.region-code.amazonaws.com/id/XXXXXXXXXXXXXXXXXXXXXXXXXXXXX:aud": "sts.amazonaws.com",
"oidc.eks.region-code.amazonaws.com/id/XXXXXXXXXXXXXXXXXXXXXXXXXXXXX:sub": "system:serviceaccount:kube-system:aws-load-balancer-controller"
}
}
}
]
}
AWS Load Balancer Controllerのインストール
AWS Load Balancer Controllerをインストールします。こちらも、必要なマニフェストファイルがAWSより提供されていますので、順番にapplyしていけばOKです。
$ kubectl apply -f cert-manager.yaml
namespace/cert-manager created
customresourcedefinition.apiextensions.k8s.io/certificaterequests.cert-manager.io created
customresourcedefinition.apiextensions.k8s.io/certificates.cert-manager.io created
customresourcedefinition.apiextensions.k8s.io/challenges.acme.cert-manager.io created
customresourcedefinition.apiextensions.k8s.io/clusterissuers.cert-manager.io created
customresourcedefinition.apiextensions.k8s.io/issuers.cert-manager.io created
customresourcedefinition.apiextensions.k8s.io/orders.acme.cert-manager.io created
…(以下省略)
$ kubectl apply -f v2_4_4_full.yaml
customresourcedefinition.apiextensions.k8s.io/ingressclassparams.elbv2.k8s.aws created
customresourcedefinition.apiextensions.k8s.io/targetgroupbindings.elbv2.k8s.aws created
role.rbac.authorization.k8s.io/aws-load-balancer-controller-leader-election-role created
clusterrole.rbac.authorization.k8s.io/aws-load-balancer-controller-role created
rolebinding.rbac.authorization.k8s.io/aws-load-balancer-controller-leader-election-rolebinding created
clusterrolebinding.rbac.authorization.k8s.io/aws-load-balancer-controller-rolebinding created
service/aws-load-balancer-webhook-service created
deployment.apps/aws-load-balancer-controller created
certificate.cert-manager.io/aws-load-balancer-serving-cert created
issuer.cert-manager.io/aws-load-balancer-selfsigned-issuer created
mutatingwebhookconfiguration.admissionregistration.k8s.io/aws-load-balancer-webhook created
validatingwebhookconfiguration.admissionregistration.k8s.io/aws-load-balancer-webhook created
ingressclass.networking.k8s.io/alb created
加えて、IngressClassおよびIngressClassParams作成のマニフェストを実行します。
これが、IngressとAWS Load Balancer Controllerを関連付けます。
$ kubectl apply -f v2_4_4_ingclass.yaml
ingressclassparams.elbv2.k8s.aws/alb created
ingressclass.networking.k8s.io/alb configured
最後に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 1/1 1 1 5m43s
Ingressの作成
AWS Load Balancer Controllerが用意できたので、後はIngressを作成すれば、ALBが作られます。
その前に、ALBから通信を受け付けるアプリ群を作っておかないといけないので、以下のマニフェストを実行しておきます。
# NameSpace
apiVersion: v1
kind: Namespace
metadata:
name: dev-ap
---
# Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: dev-ap
name: dev-ap-deployment
spec:
replicas: 3
selector:
matchLabels:
app: dev-ap-deployment
template:
metadata:
labels:
app: dev-ap-deployment
spec:
#今回は予めECRリポジトリに格納しておいたNginxコンテナのイメージを使用
containers:
- image: 111122223333.dkr.ecr.ap-northeast-1.amazonaws.com/otameshi-ecr:latest
name: dev-ap-pod
---
# NodePort
apiVersion: v1
kind: Service
metadata:
namespace: dev-ap
name: dev-ap-nodeport
labels:
app: dev-ap-nodeport
spec:
type: NodePort
selector:
app: dev-ap-deployment
ports:
- port: 80
protocol: TCP
targetPort: 8080
$ kubectl apply -f dev-ap.yaml
namespace/dev-ap created
deployment.apps/dev-ap-deployment created
service/dev-ap-nodeport created
いよいよIngressを作成します。アノテーション部分でALBの設定ができるのがポイントです。
今回はinternet-facingにしつつ、あらかじめ作ったSecurityGroupをアタッチしています。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: dev-ap
name: alb-ingress
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/security-groups: dev-sg
spec:
ingressClassName: alb
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: dev-ap-nodeport
port:
number: 8080
$ kubectl apply -f ingress.yaml
ingress.networking.k8s.io/alb-ingress created
動作確認
AWSコンソールにて、LoadBalancerのリソースを覗いてみると、、、
ALBが作成されています!
アノテーションで設定したSecurityGroupも反映されています。
ALBのDNSにアクセスすると、アプリ(シンプルなNginxの画面ですが)が表示されました。
Ingress Controller(AWS Load Balancer Controller)によってALBが作成され、ALB⇒NodePort⇒Podsの経路で問題なく通信することが確認できました。
ここまでのまとめ
前回からかなり間が空いてしまいましたが、ようやくKubernetesがアプリケーションサービスを提供する状態となりました。
外部通信の方法は冒頭に示した通りいくつかの方式があるようですが、各クラウドサービスが提供するIngress Controllerを使用するのが比較的シンプルな構成になるのではという個人的な所感です。(AWSで言えば今回試したAWS Load Balancer Controller、GCPの場合、GKE Ingress controllerというものがある模様)
次回、ようやく本題のArgo CD君が登場します。