本文介绍使用页面点击的方式在AWS中国宁夏区安装AWS EKS的全部流程,并使用Cluster Autoscaler实现底层资源的自动扩缩容。
其中涉及到如下的子部分
安装
网络检查
AWS EKS在中国宁夏区创建前,我们现需要保证自己的VPC网络符合Amazon EKS VPC and subnet requirements and considerations要求,比如VPC中必须要有足够的private ip,必须同时开启DNS hostname
和DNS resolution
,必须为AWS EKS控制面提供2个AZ的子网。
关于网络规划可以参考一文看懂 Amazon EKS 中的网络规划
,
本文我为EKS分配了3个AZ的子网;设计上AWS EKS管理的EC2在container-ec2-subnet
子网,AWS EKS管理的Pod在containers-subnet
子网,这样把EC2的private ip cidr和pod的private ip cidr分开管理;如果你不计划分开EC2和Pod的private ip cidr也完全没问题,这也是默认设置,此外VPC开启DNS hostname
和DNS resolution
权限检查
你在创建AWS EKS的时候,必须有AWS相关的足够的权限,详情请看Getting started with Amazon EKS – Amazon Web Services Management Console and Amazon CLI中的Required IAM permissions
部分
安装AWS EKS控制面
我们创建AWS EKS的时候,实际上只是创建了K8S的控制面(控制面做了自动的跨AZ高可用),后续的EC2/Fargate计算资源的管理、K8S deployment、service的管理、K8S插件的安装也会逐渐涉及。
cluster role设置
AWS EKS可以帮助我们管理资源并和其他AWS服务交互,所以我们必须给AWS EKS合适的role,让AWS EKS可以用这个role去执行相应的动作,详情可以看Amazon EKS cluster IAM role
在AWS IAM控制台中,我们可以创建一个名为AmazonEKSClusterRole
的role
检查AmazonEKSClusterPolicy
是否被正确的选择了
最后检查下详情并创建role
创建成功后我们可以看到相应的role
EKS安装
在AWS EKS控制台,我们可以接着创建AWS EKS
我们在创建EKS的时候选择我们刚才创建的role来给EKS合适的权限,同时也建议选择最新的EKS版本。AWS EKS的发布周期和维护周期和K8S的支持周期基本一致,Amazon EKS Kubernetes versions里面列出了可选的版本,EKS一般每个版本的支持周期大约为12个月,当支持周期结束前建议大家提前安排好版本更新,避免由于结束支持后失去安全和bug修复保证。更多的详情可以看Amazon EKS Kubernetes versions、Amazon EKS platform versions
Secrets encryption是可选的,用于对EKS里面的Kubernetes secrets数据做加密进一步的保证安全
接着我们选择网络,一般我推荐选择3个子网(subnet)跨越3个AZ保证绝对的可靠;然后EKS控制面会在这些子网里面放置网络接口,通过网络接口暴露控制面的API服务,这样我们后面的EC2/Fargate等安装了kubelet的计算资源以及pod就可以和这些网络接口通信,我们可以通过下面的security group做精细的控制)。此外cluster enpoint access我们可以按照自己的需求选择,详情请看Amazon EKS cluster endpoint access control,测试/开发环境建议选择public
+private
(互联网能访问控制面API,也能在VPC内访问控制面API,这样方便运维在本地电脑控制EKS),正式环境建议选择private
(互联网不能访问控制面API,只能在VPC内访问控制面API,这样绝对避免互联网网络访问,就更安全)
一般我放行vpc cidr的全部入栈流量,你可以更加精细化设置
AWS EKS可以选择开启日志,你可以按自己需求选择
AWS EKS默认会安装必要的插件
选择默认版本或者最新的版本即可
检查全部的配置
提交创建,我们需要等几分钟等待AWS EKS创建完成
就绪后就可以使用了
设置计算资源
创建完成后,AWS EKS的控制面就提供给我们了。这时我们其实是没有底层计算资源的,我们有2种选择: ec2 node group和fargate,其中ec2 node group建议优先托管节点组(Managed node groups),它可以帮我们做好ec2的故障恢复,EC2随压力的伸缩
设置托管节点组
ec2 node的角色创建
我们需要给EC2合适的role,这样EC2在创建后会有合适的权限加入EKS集群或者做其他的操作,我们可以参考Amazon EKS node IAM role
我们首先在AWS IAM控制台创建role
选择添加3个必要的policy:AmazonEKSWorkerNodePolicy
,AmazonEC2ContainerRegistryReadOnly
,AmazonEKS_CNI_Policy
确认3个policy选择正确后提交,role名称我填为AmazonEKSNodeRole
创建成功
创建托管节点组
在EKS控制台,我们开始创建托管节点组。
给这个节点组的节点赋予我们刚才创建的role
节点组中我们可以进一步的设置,比如选择操作系统,购买类型,机型,这个节点组的最小,最大节点数和当前期望的节点数
EC2节点的网络保持默认就好,你也可以选择为EC2节点打开SSH访问
检查设置并创建
创建中,需要等待几分钟
创建成功后的效果,我们可以看待节点组创建成功了,并且节点加入了集群
补充说明:
详情请看Managed node groups
比如我可以结合spot/on-demand、x86/arm64、amazon linux/bottlerocket创建多个节点组,多元化使用结合弹性和成本
Cluster Autoscaler实现节点组自动水平扩展
AWS Autoscaling有2种节点组自动扩缩容组件:karpenter和Cluster Autoscaler,本文选择的是Cluster Autoscaler
相关的链接
- AWS EKS Autoscaling
- AWS EKS Cluster Autoscaler
- kubernetes autoscaler
IAM OIDC provider设置
为了让Cluster Autoscaler有权限操作nodegroup,我们需要设置安全策略
在AWS EKS中复制集群的OpenID Connect provider URL
在AWS IAM补充OIDC,我们先创建Identity providers
填入前面复制的OpenID Connect provider URL
,并将Audience设置为sts.amazonaws.com
创建完成
EKS Nodegroup tags管理
为了让Cluster Autoscaler能够发现我们指定的node group,我们可以给node group设置tag
为需要被Cluster Autoscaler管理的node group设置tag
tag有2个:
名称 | 值 |
---|---|
k8s.io/cluster-autoscaler/enabled | true |
k8s.io/cluster-autoscaler/ | owned |
将换为你实际的集群名称
例如我的:
创建IAM Policy
将如下的policy保存为cluster-autoscaler-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"autoscaling:SetDesiredCapacity",
"autoscaling:TerminateInstanceInAutoScalingGroup"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:ResourceTag/k8s.io/cluster-autoscaler/": "owned"
}
}
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"autoscaling:DescribeAutoScalingInstances",
"autoscaling:DescribeAutoScalingGroups",
"ec2:DescribeLaunchTemplateVersions",
"autoscaling:DescribeTags",
"autoscaling:DescribeLaunchConfigurations",
"ec2:DescribeInstanceTypes"
],
"Resource": "*"
}
]
}
比如我的
然后创建ploicy
aws iam create-policy --policy-name AmazonEKSClusterAutoscalerPolicy --policy-document file://cluster-autoscaler-policy.json
创建AmazonEKSClusterAutoscalerRole role
在AWS IAM控制台创建role
policy选择上面新创的AmazonEKSClusterAutoscalerPolicy
检查设置并创建,名称填为AmazonEKSClusterAutoscalerRole
保险起见,创建完成后检查AmazonEKSClusterAutoscalerRole
是否和前面的OIDC签名一致
正式安装autoscaler
下载cluster-autoscaler-autodiscover.yaml
curl -O https://raw.githubusercontent.com/kubernetes/autoscaler/master/cluster-autoscaler/cloudprovider/aws/examples/cluster-autoscaler-autodiscover.yaml
将下载的文件进行修改,调整为你的集群名称
然后部署
kubectl apply -f cluster-autoscaler-autodiscover.yaml
为集群的cluster-autoscaler加上有关role的注解,将arn:aws:iam::ACCOUNT_ID:role/AmazonEKSClusterAutoscalerRole
替换为前面场景的名为AmazonEKSClusterAutoscalerRole
的role的实际的arn
kubectl annotate serviceaccount cluster-autoscaler -n kube-system eks.amazonaws.com/role-arn=arn:aws:iam::ACCOUNT_ID:role/AmazonEKSClusterAutoscalerRole
为cluster-autoscaler deployment打patch,补充注解
kubectl patch deployment cluster-autoscaler -n kube-system -p '{"spec":{"template":{"metadata":{"annotations":{"cluster-autoscaler.kubernetes.io/safe-to-evict": "false"}}}}}'
修改cluster-autoscaler
kubectl -n kube-system edit deployment.apps/cluster-autoscaler
加上如下的内容,加的使用缩进请用空格,不要用tab缩进
--balance-similar-node-groups
--skip-nodes-with-system-pods=false
如下图,位置在
设置cluster-autoscale的image地址和版本,这里中国直接访问registry.k8s.io一定失败,因为被屏蔽了
kubectl set image deployment cluster-autoscaler -n kube-system cluster-autoscaler=registry.k8s.io/autoscaling/cluster-autoscaler:v1.27.3
所以使用proxy替代即可
kubectl set image deployment cluster-autoscaler -n kube-system cluster-autoscaler=registryk8s.azk8s.cn/autoscaling/cluster-autoscaler:v1.27.3
到这里部署就完成了~~~~~~
检查安装效果
通过下面的命令查看log
kubectl -n kube-system logs -f deployment.apps/cluster-autoscaler
出现No candidates for scale down
类的字样,说明工作正常,正在尝试进行扩缩容评估
Horizontal Pod Autoscaler设置
首先安装Metrics Server,参考Installing the Kubernetes Metrics Server
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
这里建议先下载文件然后用registryk8s.azk8s.cn
替换registry.k8s.io
,避免网络问题
继续参考Horizontal Pod Autoscaler进行测试
以一个PHP样例为测试对象
kubectl apply -f https://k8s.io/examples/application/php-apache.yaml
这里建议先下载文件然后用registryk8s.azk8s.cn
替换registry.k8s.io
,避免网络问题
设置一个HPA,规定CPU压力超过50%后扩展
kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=10
查看HPA信息
kubectl get hpa
进行压力测试,通过压力让CPU指标上升
kubectl run -i --tty load-generator --rm --image=busybox --restart=Never -- /bin/sh -c "while sleep 0.01; do wget -q -O- http://php-apache; done"
当施加压力后,我们看到pod数量随着CPU指标的上升而变多了,这时HPA工作正常
更多的pod需要更多的EC2承载,我们看到cluster-autoscaler自动为我们扩展了一个EC2
当我们停止压力测试,过一段时间cluster-autoscaler会自动为我们回收EC2。
清理测试,删除相关的资源
kubectl delete deployment.apps/php-apache service/php-apache horizontalpodautoscaler.autoscaling/php-apache
**到这里我们完成一个高可用,资源自动扩展的EKS部署,这样我们真正的实现了云上按需计算、高性价比、高可靠性的容器化服务搭建。
**
设置Fargate
创建Amazon EKS Pod execution IAM role
fargate正常运行需要有Amazon EKS Pod execution IAM role,详情可以参考Amazon EKS Pod execution IAM role
编辑policy内容,并保存为pod-execution-role-trust-policy.json
,其中region-code
和aws-account
需要填你真实的内容
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Condition": {
"ArnLike": {
"aws:SourceArn": "arn:aws-cn:eks:::fargateprofile/*"
}
},
"Principal": {
"Service": "eks-fargate-pods.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
创建role,名称可以自定义,我设置为AmazonEKSFargatePodExecutionRole
aws iam create-role --role-name AmazonEKSFargatePodExecutionRole --assume-role-policy-document file://"pod-execution-role-trust-policy.json"
将AmazonEKSFargatePodExecutionRole
和AmazonEKSFargatePodExecutionRolePolicy
关联
aws iam attach-role-policy --policy-arn arn:aws-cn:iam::aws:policy/AmazonEKSFargatePodExecutionRolePolicy --role-name AmazonEKSFargatePodExecutionRole
创建fargate profile
填写自己的fargate-profile名称,并选定刚才创建的AmazonEKSFargatePodExecutionRole
为这个profie填入合适的namespace设置,详情见AWS Fargate profile
检查并创建
创建需要几分钟
创建完成
测试fargate的使用
这里是一个简单的nginx deployment样例,请注意它的namesapce必须要和fargate proflie中的namespace设置相匹配,匹配规则为AWS Fargate profile
apiVersion: apps/v1
kind: Deployment
metadata:
name: eks-sample-linux-deployment
# 必须和fargate proflie中的namespace设置相匹配,https://docs.aws.amazon.com/eks/latest/userguide/fargate-profile.html
namespace: prod-fargate
labels:
app: eks-sample-linux-app
spec:
replicas: 3
selector:
matchLabels:
app: eks-sample-linux-app
template:
metadata:
labels:
app: eks-sample-linux-app
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/arch
operator: In
values:
- amd64
- arm64
containers:
- name: nginx
image: public.ecr.aws/nginx/nginx:1.23
ports:
- name: http
containerPort: 80
imagePullPolicy: IfNotPresent
nodeSelector:
kubernetes.io/os: linux
等待片刻我们发现fargate作为底层计算资源已经运行了正确的nginx
fargate和ec2 node group不一样,只需要你设置好pod的HPA后,pod就可以自动的水平扩展并及时获取对应的fargate计算资源,不再需要autosacler等插件。
关于fargate详情请看:
- AWS fargate
- AWS fargate doc
- 聊聊 AWS Fargate 在容器世界中的角色定位