如何使用 Terraform 配置 EKS ALB
Posted
技术标签:
【中文标题】如何使用 Terraform 配置 EKS ALB【英文标题】:How to configure EKS ALB with Terraform 【发布时间】:2021-06-16 00:05:46 【问题描述】:我很难让 EKS 向公共互联网公开 IP 地址。我需要自己设置 ALB,还是作为 EKS 集群的一部分免费获得?如果必须自己做,是需要在terraform模板文件中定义还是在kubernetes对象yaml中定义?
这是我在 Terraform 中定义的 EKS 集群以及我认为所需的权限。
// eks.tf
resource "aws_iam_role" "eks_cluster_role"
name = "$local.env_name-eks-cluster-role"
assume_role_policy = jsonencode(
Version = "2012-10-17",
Statement = [
Effect = "Allow",
Principal =
Service = "eks.amazonaws.com"
,
Action = "sts:AssumeRole"
]
)
resource "aws_iam_role_policy_attachment" "eks-AmazonEKSClusterPolicy"
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"
role = aws_iam_role.eks_cluster_role.name
resource "aws_iam_role_policy_attachment" "eks-AmazonEKSVPCResourceController"
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSVPCResourceController"
role = aws_iam_role.eks_cluster_role.name
resource "aws_kms_key" "eks_key"
description = "EKS KMS Key"
deletion_window_in_days = 7
enable_key_rotation = true
tags =
Environment = local.env_name
Service = "EKS"
resource "aws_kms_alias" "eks_key_alias"
target_key_id = aws_kms_key.eks_key.id
name = "alias/eks-kms-key-$local.env_name"
resource "aws_eks_cluster" "eks_cluster"
name = "$local.env_name-eks-cluster"
role_arn = aws_iam_role.eks_cluster_role.arn
enabled_cluster_log_types = ["api", "audit", "authenticator", "controllerManager", "scheduler"]
vpc_config
subnet_ids = [aws_subnet.private_a.id, aws_subnet.private_b.id]
encryption_config
resources = ["secrets"]
provider
key_arn = aws_kms_key.eks_key.arn
tags =
Environment = local.env_name
resource "aws_iam_role" "eks_node_group_role"
name = "$local.env_name-eks-node-group"
assume_role_policy = jsonencode(
Version = "2012-10-17",
Statement = [
Effect = "Allow",
Principal =
Service = "ec2.amazonaws.com"
,
Action = "sts:AssumeRole"
]
)
resource "aws_iam_role_policy_attachment" "eks-node-group-AmazonEKSWorkerNodePolicy"
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy"
role = aws_iam_role.eks_node_group_role.name
resource "aws_iam_role_policy_attachment" "eks-node-group-AmazonEKS_CNI_Policy"
policy_arn = "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy"
role = aws_iam_role.eks_node_group_role.name
resource "aws_iam_role_policy_attachment" "eks-node-group-AmazonEC2ContainerRegistryReadOnly"
policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
role = aws_iam_role.eks_node_group_role.name
resource "aws_eks_node_group" "eks_node_group"
instance_types = var.node_group_instance_types
node_group_name = "$local.env_name-eks-node-group"
node_role_arn = aws_iam_role.eks_node_group_role.arn
cluster_name = aws_eks_cluster.eks_cluster.name
subnet_ids = [aws_subnet.private_a.id, aws_subnet.private_b.id]
scaling_config
desired_size = 1
max_size = 1
min_size = 1
// Ensure that IAM Role permissions are created before and deleted after EKS Node Group handling.
// Otherwise, EKS will not be able to properly delete EC2 Instances and Elastic Network Interfaces.
depends_on = [
aws_iam_role_policy_attachment.eks-node-group-AmazonEC2ContainerRegistryReadOnly,
aws_iam_role_policy_attachment.eks-node-group-AmazonEKS_CNI_Policy,
aws_iam_role_policy_attachment.eks-node-group-AmazonEKSWorkerNodePolicy,
]
这是我的 kubernetes 对象 yaml:
# hello-kubernetes.yaml
apiVersion: v1
kind: Service
metadata:
name: hello-kubernetes
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 8080
selector:
app: hello-kubernetes
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-kubernetes
spec:
replicas: 3
selector:
matchLabels:
app: hello-kubernetes
template:
metadata:
labels:
app: hello-kubernetes
spec:
containers:
- name: hello-kubernetes
image: paulbouwer/hello-kubernetes:1.9
ports:
- containerPort: 8080
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: hello-ingress
spec:
backend:
serviceName: hello-kubernetes
servicePort: 80
我已经运行 terraform apply
并且集群已启动并正在运行。我已经安装了eksctl
和kubectl
并运行kubectl apply -f hello-kubernetes.yaml
。 pod、服务和入口似乎运行良好。
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-kubernetes-6cb7cd595b-25bd9 1/1 Running 0 6h13m
hello-kubernetes-6cb7cd595b-lccdj 1/1 Running 0 6h13m
hello-kubernetes-6cb7cd595b-snwvr 1/1 Running 0 6h13m
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-kubernetes LoadBalancer 172.20.102.37 <pending> 80:32086/TCP 6h15m
$ kubectl get ingresses
NAME CLASS HOSTS ADDRESS PORTS AGE
hello-ingress <none> * 80 3h45m
我缺少什么以及它属于哪个文件?
【问题讨论】:
【参考方案1】:通常的方法是放置一个 ALB 并将流量重定向到 EKS 集群,并使用 ALB 入口控制器对其进行管理。这个入口控制器将充当集群和您的 ALB 之间的通信,这是非常直接的 AWS 文档
EKS w/ALB
如果 ALB 不适合您的应用程序需求,其他解决方案可能是使用带有 NLB 的 nginx 入口控制器,如下文所述
NGINX w/NLB
【讨论】:
在哪里定义 ALB 和入口控制器? ALB 是否在 terraform 文件中,而 Ingress Controller 是否在 kubernetes yaml 中?您如何将它们连接在一起? 正如 Jonas 回答的那样,按照文档 docs.aws.amazon.com/eks/latest/userguide/… 中详细说明的说明进行操作,然后在定义 k8s 入口清单时,使用注释kubernetes.io/ingress.class: alb
。这是一个完整的例子:docs.aws.amazon.com/eks/latest/userguide/alb-ingress.html【参考方案2】:
这也发生在我身上,在所有设置之后,我无法看到入口地址。调试此问题的最佳方法是检查入口控制器的日志。你可以这样做:
使用以下命令获取 Ingress 控制器 po 名称:kubectl get po -n kube-system
使用以下命令检查 po 的日志:kubectl logs
如果您没有找到任何以 ingress 名称运行的 po,那么您必须先创建 ingress 控制器。
【讨论】:
谢谢,我在 kube-system 命名空间中没有看到入口 pod。我是在 Terraform 中通过将其添加到 tf 文件中来创建它,还是在 Kubernetes 中通过将其添加到 yaml 文件中来创建它? 我确实在命名空间中看到了这四个 pod,如果有帮助的话:aws-node-4jp4q、coredns、c79dcb98c-96npq、coredns-c79dcb98c-rqkxx 和 kube-proxy-9zdcw。 您需要使用 yaml 文件添加它。点击链接:medium.com/cloudzone/…【参考方案3】:您需要按照installation instructions安装AWS Load Balancer Controller;首先您需要创建 IAM 角色和权限,这可以通过 Terraform 完成;那么你需要应用 Kubernetes Yaml 来将控制器安装到你的集群中,这可以通过 Helm 或 Kubectl 来完成。
您还需要注意 subnet tagging ,例如创建面向公共或私有的负载均衡器。
【讨论】:
以上是关于如何使用 Terraform 配置 EKS ALB的主要内容,如果未能解决你的问题,请参考以下文章
带有 ALB 入口控制器的 Terraform AWS Kubernetes EKS 资源不会创建负载均衡器
如何使用 Terraform 配置 AWS EKS 自动扩缩器?
在 EKS 上,我如何验证我通过 Terraform 配置了 Spot 实例