Terraformを使って、AWS EKS(Kubernetes)クラスターを構築しALB経由でアクセスする
内容
Terraformを使って、AWS EKSのKubernetesクラスターを作成します。
また、そのEKSクラスター内で実行されているPodにALB経由でアクセスできるようにします。
準備
Terraformでネットワークを作成する
まずはKubernetesクラスターが動作するネットワークをTerraformで作成していきます。
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
name = "eks-vpc"
cidr = "10.0.0.0/16"
enable_dns_hostnames = true
azs = ["ap-northeast-1a", "ap-northeast-1c", "ap-northeast-1d"]
public_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
private_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]
enable_nat_gateway = true
single_nat_gateway = true
# これがないと後ほど作成するALBが自動で作成されません。
public_subnet_tags = {
"kubernetes.io/role/elb" = 1
}
tags = {
Terraform = "true",
Environment = terraform.workspace
}
}
PublicサブネットとPrivateサブネットを持つ、VPCを作成しました。
EKSクラスターを立ち上げる
今回はFargate Profileを使ったEKSクラスターを作成していきます。
※( https://github.com/terraform-aws-modules/terraform-aws-eks/tree/master/examples/fargate_profile )こちらの公式モジュールのexampleを元に必要な箇所だけ修正しました。
module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "~> 19.0"
cluster_name = "main-eks"
cluster_version = "1.25"
cluster_endpoint_public_access = true
cluster_addons = {
kube-proxy = {}
vpc-cni = {}
coredns = {
configuration_values = jsonencode({
computeType = "Fargate"
})
}
}
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnets
control_plane_subnet_ids = module.vpc.intra_subnets
create_cluster_security_group = false
create_node_security_group = false
fargate_profile_defaults = {
iam_role_additional_policies = {
additional = aws_iam_policy.additional.arn
}
}
fargate_profiles = merge(
{
apps = {
name = "apps"
selectors = [
{
namespace = "apps"
},
]
subnet_ids = module.vpc.private_subnets
}
},
{ for i in range(3) :
"kube-system-${i}" => {
selectors = [
{ namespace = "kube-system" }
]
subnet_ids = [element(module.vpc.private_subnets, i)]
}
}
)
}
resource "aws_iam_policy" "additional" {
name = "iam-eks-additional"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = [
"ec2:Describe*",
]
Effect = "Allow"
Resource = "*"
},
]
})
}
これで、Kubernetesクラスターとそのクラスターが動作するVPCネットワークが完成しました。
EKSクラスターにNginxポッドを作成する
Contextを設定する
EKSクラスターが立ち上がったので、ローカルのターミナルからそのクラスターを操作できるように、Contextの設定を行います。
$ aws eks --region ap-northeast-1 update-kubeconfig --name "main-eks"
Namespaceを作成する
Fargate Profileによって、apps namespaceにPod等を配置するように設定しています。そのため、apps namespaceを作成します。
$ kubectl create ns apps
kubenamespace/apps created
Nginx Podを作成し、exposeする
次に、apps namespaceに対して、nginx Podを作成し、そのPodをexposeします。
$ kubectl run test-pod -n apps --image=nginx:latest
pod/test-pod created
$ kubectl expose pod test-pod --port=80 --target-port=80 -n apps
service/test-pod exposed
$ kubectl get all -n apps
NAME READY STATUS RESTARTS AGE
pod/test-pod 1/1 Running 0 3m7s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/test-pod ClusterIP 172.20.38.47 <none> 80/TCP 38s
ALB経由でアクセスする
ネットワークとKubernetesクラスターが立ち上がり、そのクラスター内にPodを立てることもできたのでs、そのPodに対して、ALB経由でアクセスできるようにします。
※( https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/aws-load-balancer-controller.html )公式チュートリアルを参考にしています。
ALB IngressをKubernetesクラスターから作成できるように、ServiceAccountを作成する
まずは、ALBをKubernetesクラスターから作成できるように、ServiceAccountを作成します。
Policyの作成
AWS APIを呼び出すことが出来るALB用のIAMポリシーを作成します。
$ curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.4.4/docs/install/iam_policy.json
$ aws iam create-policy --policy-name AWSLoadBalancerControllerIAMPolicy --policy-document file://iam_policy.json
ClusterにServiceAccountを作成する
次に、今作成したPolicyをアタッチしたKubernetes Service Accountを作成します。
$ eksctl create iamserviceaccount \
--cluster=main-eks \
--namespace=kube-system \
--name=aws-load-balancer-controller \
--role-name AmazonEKSLoadBalancerControllerRole \
--attach-policy-arn=arn:aws:iam::<AWS Account ID>:policy/AWSLoadBalancerControllerIAMPolicy \
--approve
※AWS Account ID
の部分はご自分のAWSアカウントのIDに変更してください。
$ kubectl describe sa aws-load-balancer-controller -n kube-system
Name: aws-load-balancer-controller
Namespace: kube-system
Labels: app.kubernetes.io/managed-by=eksctl
Annotations: eks.amazonaws.com/role-arn: arn:aws:iam::1111111111:role/AmazonEKSLoadBalancerControllerRole
Image pull secrets: <none>
Mountable secrets: <none>
Tokens: <none>
Events: <none>
正常にServiceAccountがクラスター内に作成されました。
HELMを使ってALBをデプロイする
HELMを使って、AWS Load Balancer Controllerをインストールする
$ helm repo add eks https://aws.github.io/eks-charts
$ helm repo update
$ helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
-n kube-system \
--set clusterName=main-eks \
--set region=ap-northeast-1 \
--set serviceAccount.create=false \
--set vpcId=<VPC ID> \
--set serviceAccount.name=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 4m49s
※VPC ID
の部分はご自分のAWSVPCのIDに変更してください。
これで、 ALBを作成するためのAnnotationを付与したIngressを作成すれば、KubernetesがALBを自動でセットアップしてくれる準備が整いました。最後に、Ingressを作成し、NginxPodにトラフィックを流します。
Ingressを作成し、nginx Podに接続する
最後に、Ingressを作成し、ALBを作成します。以下のyamlファイルを kubectl apply ingress.yaml
して、Kubernetesクラスターに適用します。
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: apps
name: ingress
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
spec:
ingressClassName: alb
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: test-pod
port:
number: 80
しばらくすると、
$ kubectl apply ingress.yaml
$ kubectl get ingress -n apps
NAMESPACE NAME CLASS HOSTS ADDRESS PORTS AGE
apps ingress alb * ....ap-northeast-1.elb.amazonaws.com 80 4m12s
といった具合に自動付与されたDNS名が表示されるので、そのDNSにアクセスするとnginxの初期画面が表示されます!
$ curl ....ap-northeast-1.elb.amazonaws.com
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
これで、EKSクラスターをTerraformで作成して、ALBを使ってクラスター内で動作するPodにアクセスすることができました!
note
勉強法やキャリア構築法など、エンジニアに役立つ記事をnoteで配信しています。
Discussion