作者:SRE運維博客
博客地址:https://www.cnsre.cn/
文章地址:https://www.cnsre.cn/posts/211217431135/
相關話題:https://www.cnsre.cn/tags/aws/
最近在AWS 平台創建了EKS 用於測試環境項目,EKS 創建完以后我打算使用 Ingress 控制器 來暴露服務,ingress 前在添加一個ALB 負載均衡器,這樣就可以實現完全的高可用了。但是在創建好 ingress 卻發現無法調通服務,查看 aws 官方文檔 Amazon EKS 上的應用程序負載均衡 發現需要使用 aws-load-balancer-controller.
本文檔的目標:
-
創建 EKS ALB 所需要的角色。
-
創建 EKS aws-load-balancer-controller
-
創建 EKS pod 服務
-
使用 ALB 將 pod 服務暴露出去
AWS Load Balancer Controller 介紹
AWS Load Balancer Controller 的工作原理
AWS Load Balancer Controller 是幫助管理 Kubernetes 集群的彈性負載均衡器的控制器。
- 它通過供應應用程序負載均衡器來滿足 Kubernetes Ingress 資源。
- 它通過提供 網絡負載均衡器來滿足 Kubernetes Service 資源。
下圖詳細說明了此控制器創建的 AWS 組件。它還演示了從 ALB 到 Kubernetes 集群的路由入口流量。
[1]:控制器監視來自 API 服務器的入口事件。當它找到滿足其要求的入口資源時,它開始創建 AWS 資源。
[2]:在 AWS 中為新的入口資源創建了一個 ALB (ELBv2)。此 ALB 可以面向 Internet 或內部。您還可以使用注釋指定它在其中創建的子網。
[3]:在 AWS 中為入口資源中描述的每個獨特的 Kubernetes 服務創建目標組。
[4]:為入口資源注釋中詳述的每個端口創建偵聽器。如果未指定端口,則使用合理的默認值 (80
或443
)。證書也可以通過注釋附加。
[5]:為入口資源中指定的每個路徑創建規則。這可確保將特定路徑的流量路由到正確的 Kubernetes 服務。
安裝前的准備
- EKS 已經創建完畢
- 准備 兩個 Public 子網
- 能夠創建 IAM 策略 的賬戶
關於子網的說明:
根據EKS 最佳實踐。EKS 的 worker node,它們只需要接收來自 alb ingress(通過內網轉發)的流量,安全起見就需要把他們放在私有子網。但是它們又需要去公網上拉一些鏡像,所以它們本身也需要放問公網的能力,這個時候它們的子網里配置個 nat,訪問外網的時候由 NAT 做一個出向的轉發,就可以實現了,但是因為 nat 是單向的,外界是無法通過NAT訪問到eks的節點的,所以我就需要將ALB 放在 public 子網里。最后就是 ALB 放在 public 來接受流量,worker node 在私有子網處理業務。
創建AWS Load Balancer Controller 的 IAM 策略
打開 策略 點擊 創建策略
打開 IAM_Policy.json 復制內容粘貼到 json
點擊下一步:標簽
然后一直下一步 在下圖中名稱填寫 AWSLoadBalancerControllerIAMPolicy
你也可以自定義名稱。然后創建策略。
{{< notice info "注意:" >}}
如果以官方提供的 IAM_Policy.json 保存有錯的話你可以使用一下策略(權限會大一些)
{{< /notice >}}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iam:CreateServiceLinkedRole",
"ec2:DescribeAccountAttributes",
"ec2:DescribeAddresses",
"ec2:DescribeAvailabilityZones",
"ec2:DescribeInternetGateways",
"ec2:DescribeVpcs",
"ec2:DescribeSubnets",
"ec2:DescribeSecurityGroups",
"ec2:DescribeInstances",
"ec2:DescribeNetworkInterfaces",
"ec2:DescribeTags",
"ec2:GetCoipPoolUsage",
"ec2:DescribeCoipPools",
"elasticloadbalancing:DescribeLoadBalancers",
"elasticloadbalancing:DescribeLoadBalancerAttributes",
"elasticloadbalancing:DescribeListeners",
"elasticloadbalancing:DescribeListenerCertificates",
"elasticloadbalancing:DescribeSSLPolicies",
"elasticloadbalancing:DescribeRules",
"elasticloadbalancing:DescribeTargetGroups",
"elasticloadbalancing:DescribeTargetGroupAttributes",
"elasticloadbalancing:DescribeTargetHealth",
"elasticloadbalancing:DescribeTags"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"cognito-idp:DescribeUserPoolClient",
"acm:ListCertificates",
"acm:DescribeCertificate",
"iam:ListServerCertificates",
"iam:GetServerCertificate",
"waf-regional:GetWebACL",
"waf-regional:GetWebACLForResource",
"waf-regional:AssociateWebACL",
"waf-regional:DisassociateWebACL",
"wafv2:GetWebACL",
"wafv2:GetWebACLForResource",
"wafv2:AssociateWebACL",
"wafv2:DisassociateWebACL",
"shield:GetSubscriptionState",
"shield:DescribeProtection",
"shield:CreateProtection",
"shield:DeleteProtection"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ec2:AuthorizeSecurityGroupIngress",
"ec2:RevokeSecurityGroupIngress"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ec2:CreateSecurityGroup"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ec2:CreateTags"
],
"Resource": "arn:aws-cn:ec2:*:*:security-group/*",
"Condition": {
"StringEquals": {
"ec2:CreateAction": "CreateSecurityGroup"
},
"Null": {
"aws:RequestTag/elbv2.k8s.aws/cluster": "false"
}
}
},
{
"Effect": "Allow",
"Action": [
"ec2:CreateTags",
"ec2:DeleteTags"
],
"Resource": "arn:aws-cn:ec2:*:*:security-group/*",
"Condition": {
"Null": {
"aws:RequestTag/elbv2.k8s.aws/cluster": "true",
"aws:ResourceTag/elbv2.k8s.aws/cluster": "false"
}
}
},
{
"Effect": "Allow",
"Action": [
"ec2:AuthorizeSecurityGroupIngress",
"ec2:RevokeSecurityGroupIngress",
"ec2:DeleteSecurityGroup"
],
"Resource": "*",
"Condition": {
"Null": {
"aws:ResourceTag/elbv2.k8s.aws/cluster": "false"
}
}
},
{
"Effect": "Allow",
"Action": [
"elasticloadbalancing:CreateLoadBalancer",
"elasticloadbalancing:CreateTargetGroup"
],
"Resource": "*",
"Condition": {
"Null": {
"aws:RequestTag/elbv2.k8s.aws/cluster": "false"
}
}
},
{
"Effect": "Allow",
"Action": [
"elasticloadbalancing:CreateListener",
"elasticloadbalancing:DeleteListener",
"elasticloadbalancing:CreateRule",
"elasticloadbalancing:DeleteRule"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"elasticloadbalancing:AddTags",
"elasticloadbalancing:RemoveTags"
],
"Resource": [
"arn:aws-cn:elasticloadbalancing:*:*:targetgroup/*/*",
"arn:aws-cn:elasticloadbalancing:*:*:loadbalancer/net/*/*",
"arn:aws-cn:elasticloadbalancing:*:*:loadbalancer/app/*/*"
],
"Condition": {
"Null": {
"aws:RequestTag/elbv2.k8s.aws/cluster": "true",
"aws:ResourceTag/elbv2.k8s.aws/cluster": "false"
}
}
},
{
"Effect": "Allow",
"Action": [
"elasticloadbalancing:AddTags",
"elasticloadbalancing:RemoveTags"
],
"Resource": [
"arn:aws-cn:elasticloadbalancing:*:*:listener/net/*/*/*",
"arn:aws-cn:elasticloadbalancing:*:*:listener/app/*/*/*",
"arn:aws-cn:elasticloadbalancing:*:*:listener-rule/net/*/*/*",
"arn:aws-cn:elasticloadbalancing:*:*:listener-rule/app/*/*/*"
]
},
{
"Effect": "Allow",
"Action": [
"elasticloadbalancing:ModifyLoadBalancerAttributes",
"elasticloadbalancing:SetIpAddressType",
"elasticloadbalancing:SetSecurityGroups",
"elasticloadbalancing:SetSubnets",
"elasticloadbalancing:DeleteLoadBalancer",
"elasticloadbalancing:ModifyTargetGroup",
"elasticloadbalancing:ModifyTargetGroupAttributes",
"elasticloadbalancing:DeleteTargetGroup"
],
"Resource": "*",
"Condition": {
"Null": {
"aws:ResourceTag/elbv2.k8s.aws/cluster": "false"
}
}
},
{
"Effect": "Allow",
"Action": [
"elasticloadbalancing:RegisterTargets",
"elasticloadbalancing:DeregisterTargets"
],
"Resource": "arn:aws-cn:elasticloadbalancing:*:*:targetgroup/*/*"
},
{
"Effect": "Allow",
"Action": [
"elasticloadbalancing:SetWebAcl",
"elasticloadbalancing:ModifyListener",
"elasticloadbalancing:AddListenerCertificates",
"elasticloadbalancing:RemoveListenerCertificates",
"elasticloadbalancing:ModifyRule"
],
"Resource": "*"
}
]
}
賦予 EKS node 權限
在 角色 中搜索 nodegrou-NodeInstanceRole
找到你對應的 EKS 集群 如下圖
然后點擊該角色-- 點擊附加策略
在搜索框內 輸入剛才創建的策略名稱 然后選中,點擊最下邊的附加策略。
我的策略名稱為:AWSLoadBalancerControllerIAMPolicy
在 EKS 中安裝 AWS Load Balancer Controller
安裝證書管理器
kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v1.5.3/cert-manager.yaml
部署 YAML
下載負載平衡器控制器的規范。
wget https://github.com/kubernetes-sigs/aws-load-balancer-controller/releases/download/v2.3.1/v2_3_1_full.yaml
編輯保存的 yaml 文件,轉到部署規范,並將控制器 --cluster-name arg 值設置為您的 EKS 集群名稱
apiVersion: apps/v1
kind: Deployment
. . .
name: aws-load-balancer-controller
namespace: kube-system
spec:
. . .
template:
spec:
containers:
- args:
- --cluster-name=<INSERT_CLUSTER_NAME>
如果您為服務賬戶使用 IAM 角色,我們建議您從 yaml 規范中刪除 ServiceAccount。如果您從 yaml 規范中刪除安裝部分,這將保留 eksctl 創建的 iamserviceaccount。
apiVersion: v1
kind: ServiceAccount
應用 yaml 文件
kubectl apply -f v2_3_1_full.yaml
部署示例應用程序
將游戲 2048 部署為示例應用程序,以確認作為入口對象的結果,Amazon負載均衡器控制器是否會創建 Amazon ALB。
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.2.0/docs/examples/2048/2048_full.yaml
幾分鍾后,驗證是否已使用以下命令創建入口資源。
kubectl get ingress/ingress-2048 -n game-2048
輸出:
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress-2048 <none> * k8s-game2048-ingress2-xxxxxxxxxx-yyyyyyyyyy.cn-north-1.elb.amazonaws.com.cn 80 3h42m
{{< notice info "注意:" >}}
如果在幾分鍾后尚未創建入口,請運行以下命令以查看負載均衡器控制器日志。這些日志包含可幫助您診斷部署中任何問題的錯誤消息。
{{< /notice >}}
kubectl logs -n kube-system deployment.apps/aws-load-balancer-controller
打開瀏覽器並從上一命令輸出導航到 ADDRESS
URL 以查看示例應用程序。如果您沒有看到任何內容,請等待幾分鍾,並刷新您的瀏覽器。
作者:SRE運維博客
博客地址:https://www.cnsre.cn/
文章地址:https://www.cnsre.cn/posts/211217431135/
相關話題:https://www.cnsre.cn/tags/aws/