Hsn*_*edi 24 amazon-web-services amazon-iam kubernetes terraform amazon-eks
AWS 支持服务账户的 IAM 角色 (IRSA),允许集群操作员将 AWS IAM 角色映射到 Kubernetes 服务账户。
为此,必须在 EKS 集群中创建一个iamserviceaccount :
eksctl create iamserviceaccount \
--name <AUTOSCALER_NAME> \
--namespace kube-system \
--cluster <CLUSTER_NAME> \
--attach-policy-arn <POLICY_ARN> \
--approve \
--override-existing-serviceaccounts
Run Code Online (Sandbox Code Playgroud)
问题是我不想使用上面的eksctl命令,因为我想使用terraform.
eksctl 命令除了创建服务帐户之外还执行其他操作吗?如果它只创建一个服务帐户,那么YAML它的代表是什么?
coo*_*ool 40
我在这里添加我的答案是因为我偶然发现了同样的问题,并且接受了答案(以及上面的其他答案),但没有提供问题的完整解决方案 - 没有代码示例。它们只是我必须用来进行更深入研究的指导方针。有一些问题确实很容易被忽略 - 如果没有代码示例,很难得出正在发生的事情的结论(特别是在创建 IAM 角色时与 Conditions/StringEquals 相关的部分)
创建与角色绑定的服务帐户的全部目的是可以从集群内创建 aws 资源(最常见的情况是负载均衡器,或将日志推送到 cloudwatch 的角色)。
所以,问题是我们如何使用 terraform 而不是使用 eks 命令来做到这一点。
我们需要做的是:
完成此设置后,我们的 k8s 服务帐户将具有 k8s 集群角色和 k8s 集群角色绑定(这将允许该服务帐户在 k8s 内执行操作),并且我们的 k8s 服务帐户将附加 IAM 角色,这将允许在集群外部执行操作(例如创建 aws 资源)
那么让我们从它开始吧。下面的假设是您的 eks 集群已经使用 terraform 创建,并且我们专注于在 eks 集群周围创建工作服务帐户所需的资源。
创建 eks_oidc
### First we need to create tls certificate
data "tls_certificate" "eks-cluster-tls-certificate" {
url = aws_eks_cluster.eks-cluster.identity[0].oidc[0].issuer
}
# After that create oidc
resource "aws_iam_openid_connect_provider" "eks-cluster-oidc" {
client_id_list = ["sts.amazonaws.com"]
thumbprint_list = [data.tls_certificate.eks-cluster-tls-certificate.certificates[0].sha1_fingerprint]
url = aws_eks_cluster.eks-cluster.identity[0].oidc[0].issuer
}
Run Code Online (Sandbox Code Playgroud)
现在,让我们使用所有必要的策略创建 AWS IAM 角色。
下面的 Terraform 声明性代码将:
请注意,我在这里使用后缀作为 alb 入口控制器,因为这是我在集群内角色的主要用途。您可以更改角色的策略名称,也可以更改策略的权限访问,具体取决于您计划使用它执行的操作。
data "aws_caller_identity" "current" {}
locals {
account_id = data.aws_caller_identity.current.account_id
eks_oidc = replace(replace(aws_eks_cluster.eks-cluster.endpoint, "https://", ""), "/\\..*$/", "")
}
# Policy which will allow us to create application load balancer from inside of cluster
resource "aws_iam_policy" "ALBIngressControllerIAMPolicy" {
name = "ALBIngressControllerIAMPolicy"
description = "Policy which will be used by role for service - for creating alb from within cluster by issuing declarative kube commands"
policy = jsonencode({
Version = "2012-10-17",
Statement = [
{
Effect = "Allow",
Action = [
"elasticloadbalancing:ModifyListener",
"wafv2:AssociateWebACL",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:DescribeInstances",
"wafv2:GetWebACLForResource",
"elasticloadbalancing:RegisterTargets",
"iam:ListServerCertificates",
"wafv2:GetWebACL",
"elasticloadbalancing:SetIpAddressType",
"elasticloadbalancing:DeleteLoadBalancer",
"elasticloadbalancing:SetWebAcl",
"ec2:DescribeInternetGateways",
"elasticloadbalancing:DescribeLoadBalancers",
"waf-regional:GetWebACLForResource",
"acm:GetCertificate",
"shield:DescribeSubscription",
"waf-regional:GetWebACL",
"elasticloadbalancing:CreateRule",
"ec2:DescribeAccountAttributes",
"elasticloadbalancing:AddListenerCertificates",
"elasticloadbalancing:ModifyTargetGroupAttributes",
"waf:GetWebACL",
"iam:GetServerCertificate",
"wafv2:DisassociateWebACL",
"shield:GetSubscriptionState",
"ec2:CreateTags",
"elasticloadbalancing:CreateTargetGroup",
"ec2:ModifyNetworkInterfaceAttribute",
"elasticloadbalancing:DeregisterTargets",
"elasticloadbalancing:DescribeLoadBalancerAttributes",
"ec2:RevokeSecurityGroupIngress",
"elasticloadbalancing:DescribeTargetGroupAttributes",
"shield:CreateProtection",
"acm:DescribeCertificate",
"elasticloadbalancing:ModifyRule",
"elasticloadbalancing:AddTags",
"elasticloadbalancing:DescribeRules",
"ec2:DescribeSubnets",
"elasticloadbalancing:ModifyLoadBalancerAttributes",
"waf-regional:AssociateWebACL",
"tag:GetResources",
"ec2:DescribeAddresses",
"ec2:DeleteTags",
"shield:DescribeProtection",
"shield:DeleteProtection",
"elasticloadbalancing:RemoveListenerCertificates",
"tag:TagResources",
"elasticloadbalancing:RemoveTags",
"elasticloadbalancing:CreateListener",
"elasticloadbalancing:DescribeListeners",
"ec2:DescribeNetworkInterfaces",
"ec2:CreateSecurityGroup",
"acm:ListCertificates",
"elasticloadbalancing:DescribeListenerCertificates",
"ec2:ModifyInstanceAttribute",
"elasticloadbalancing:DeleteRule",
"cognito-idp:DescribeUserPoolClient",
"ec2:DescribeInstanceStatus",
"elasticloadbalancing:DescribeSSLPolicies",
"elasticloadbalancing:CreateLoadBalancer",
"waf-regional:DisassociateWebACL",
"elasticloadbalancing:DescribeTags",
"ec2:DescribeTags",
"elasticloadbalancing:*",
"elasticloadbalancing:SetSubnets",
"elasticloadbalancing:DeleteTargetGroup",
"ec2:DescribeSecurityGroups",
"iam:CreateServiceLinkedRole",
"ec2:DescribeVpcs",
"ec2:DeleteSecurityGroup",
"elasticloadbalancing:DescribeTargetHealth",
"elasticloadbalancing:SetSecurityGroups",
"elasticloadbalancing:DescribeTargetGroups",
"shield:ListProtections",
"elasticloadbalancing:ModifyTargetGroup",
"elasticloadbalancing:DeleteListener"
],
Resource = "*"
}
]
})
}
# Create IAM role
resource "aws_iam_role" "alb-ingress-controller-role" {
name = "alb-ingress-controller"
assume_role_policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Federated": "${aws_iam_openid_connect_provider.eks-cluster-oidc.arn}"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"${replace(aws_iam_openid_connect_provider.eks-cluster-oidc.url, "https://", "")}:sub": "system:serviceaccount:kube-system:alb-ingress-controller",
"${replace(aws_iam_openid_connect_provider.eks-cluster-oidc.url, "https://", "")}:aud": "sts.amazonaws.com"
}
}
}
]
}
POLICY
depends_on = [aws_iam_openid_connect_provider.eks-cluster-oidc]
tags = {
"ServiceAccountName" = "alb-ingress-controller"
"ServiceAccountNameSpace" = "kube-system"
}
}
# Attach policies to IAM role
resource "aws_iam_role_policy_attachment" "alb-ingress-controller-role-ALBIngressControllerIAMPolicy" {
policy_arn = aws_iam_policy.ALBIngressControllerIAMPolicy.arn
role = aws_iam_role.alb-ingress-controller-role.name
depends_on = [aws_iam_role.alb-ingress-controller-role]
}
resource "aws_iam_role_policy_attachment" "alb-ingress-controller-role-AmazonEKS_CNI_Policy" {
role = aws_iam_role.alb-ingress-controller-role.name
policy_arn = "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy"
depends_on = [aws_iam_role.alb-ingress-controller-role]
}
Run Code Online (Sandbox Code Playgroud)
执行完上面的terraform后,就成功创建了terraform部分资源。现在我们需要创建一个 k8s 服务帐户并将 IAM 角色与该服务帐户绑定。
创建集群角色、集群角色绑定和服务帐户
您可以使用
直接(从 master 分支),但考虑到我们需要注释 iam arn,我倾向于下载此文件,更新它并将其存储在我的 kubectl 配置文件中。
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
app.kubernetes.io/name: alb-ingress-controller
name: alb-ingress-controller
rules:
- apiGroups:
- ""
- extensions
resources:
- configmaps
- endpoints
- events
- ingresses
- ingresses/status
- services
- pods/status
verbs:
- create
- get
- list
- update
- watch
- patch
- apiGroups:
- ""
- extensions
resources:
- nodes
- pods
- secrets
- services
- namespaces
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
app.kubernetes.io/name: alb-ingress-controller
name: alb-ingress-controller
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: alb-ingress-controller
subjects:
- kind: ServiceAccount
name: alb-ingress-controller
namespace: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
app.kubernetes.io/name: alb-ingress-controller
name: alb-ingress-controller
namespace: kube-system
annotations:
eks.amazonaws.com/role-arn: <ARN OF YOUR ROLE HERE>
...
Run Code Online (Sandbox Code Playgroud)
在此文件的底部,您会注意到需要放置 ANR 角色的注释。
再检查一遍
就这样了。之后您就有了一个与 iam 角色连接的 k8s 服务帐户。
检查:
kubectl get sa -n kube-system
kubectl describe sa alb-ingress-controller -n kube-system
Run Code Online (Sandbox Code Playgroud)
您应该得到与此类似的输出(注释是最重要的部分,因为它确认了 iam 角色的附件):
Name: alb-ingress-controller
Namespace: kube-system
Labels: app.kubernetes.io/managed-by=Helm
app.kubernetes.io/name=alb-ingress-controller
Annotations: eks.amazonaws.com/role-arn: <YOUR ANR WILL BE HERE>
meta.helm.sh/release-name: testrelease
meta.helm.sh/release-namespace: default
Image pull secrets: <none>
Mountable secrets: alb-ingress-controller-token-l4pd8
Tokens: alb-ingress-controller-token-l4pd8
Events: <none>
Run Code Online (Sandbox Code Playgroud)
从现在开始,您可以使用此服务来管理您附加的策略允许的内部 k8s 资源和外部资源。
就我而言,如前所述,我使用它(除了其他东西)来创建 alb 入口控制器和负载均衡器,因此所有前缀都带有“alb-ingress”
首先,您应该在 Terraform 中定义 IAM 角色。
其次,您应该在 Kubernetes 中配置aws-auth configmap以将 IAM 角色映射到 Kubernetes 用户或服务帐户。您可以使用Kubernetes提供程序在 Terraform 中执行此操作。
已经有一个 Terraform 模块terraform-aws-eks来管理 EKS 集群的各个方面。你可能会从中得到一些想法。
经过Vasili Angapov的帮助,现在我可以回答这个问题了:
是的,它的作用不仅仅是创建服务帐户。它做了三件事:
现在,在 terraform 中使用 kubernetes 和 aws 提供程序可以轻松声明上述步骤。
| 归档时间: |
|
| 查看次数: |
13158 次 |
| 最近记录: |