nginx 配置 安全组 集群 Image 弹性伸缩 控制台 aliyun ESS kubernetes autoscaler
摘要: 阿里云 Kubernetes 服务简化了 K8S 集群的创建,升级和手动扩缩容.然而使用 Kubernetes 集群经常问到的一个问题是,我应该保持多大的节点规模来满足应用需求呢? Autoscaler 的出现解决了这个问题,它可以自动的根据部署的应用所请求的资源量来动态的伸缩集群.
阿里云 Kubernetes 服务简化了 K8S 集群的创建,升级和手动扩缩容.然而使用 Kubernetes 集群经常问到的一个问题是,我应该保持多大的节点规模来满足应用需求呢? Autoscaler 的出现解决了这个问题,它可以自动的根据部署的应用所请求的资源量来动态的伸缩集群.
tips: 一个好的实践是显示的为你的每个应用指定资源请求的值 request.
前置条件
为了实现集群规模的自动扩展,需要完成以下工作.
使用阿里云 Kubernete 服务在阿里云某个 Region 创建一个 kubernetes 集群,这里以杭州 Region 为例.创建集群请 参考 .
在相应的 Region(示例杭州) 创建 ESS 弹性伸缩实例,并配置.
获取 kubernetes 集群的添加节点命令
为了使得 ESS 实例节点可以动态加入 Kubernetes 集群,我们需要获取 Kubernetes 集群添加节点命令作为,ESS 伸缩组的 userdata 数据.
进入上一步创建好的 Kubernetes 集群的管理 控制台 , 选择刚刚创建的集群,点击 [更多]->[添加已有节点]:
拷贝黑框中的内容备用:
curl http://aliacs-k8s-cn-hangzhou.oss-cn-hangzhou.aliyuncs.com/public/pkg/run/attach/attach_node.sh | bash -s -- --docker-version 17.06.2-ce-1 --token 9e3606.1de6xxxxxxxx9a9 --endpoint 192.168.223.87:6443 --cluster-dns 172.19.0.10
ESS 需要这段脚本来初始化新扩展出来的节点.
创建 ESS 实例.
自动扩展 kubernetes 集群需要阿里云 ESS(弹性伸缩组)的支持,因此需要先创建一个 ESS.
进入 ESS 控制台 . 选择杭州 Region(和 kubernetes 集群所在 region 保持一致),点击[创建伸缩组] ,在弹出的对话框中填写相应信息,注意网络类型选择专有网络,并且专有网络选择前置条件 1 中的 Kubernetes 集群的 vpc 网络名,然后选择一个 vswitch,然后提交.如下图:
注意:
这里的 VPC 网络的选择一定要是前面创建的 kubernetes 集群所使用的 VPC 网络,可以进入容器服务 kubernetes 集群 [控制台](), 选择该集群,点击管理,查看该 VPC 信息,如下图:
最后记录刚刚创建的伸缩组的名字,格式为 regionid.ess_group_name, eg.
cn-hangzhou.kubernetes-hangzhou-group
, 这个名字在配置 autoscaler 的时候会用上.
创建伸缩配置项
选择刚才创建的伸缩组,点击添加 [伸缩配置], 选择实例规格,安全组(和 kubernetes 集群同属于一个安全组),带宽峰值选择 0(不分配公网 IP),公共镜像选择 centos 7.4,设置云盘大小, 最后设置用户数据.
注意用户数据选择[使用文本形式] ,同时将获取 kubernetes 集群的添加节点命令粘贴到该文本框中,并在之前添加 #!/bin/bash 和 yum clean all. 下面是一个用户数据的示例,替换成你自己的:
#!/bin/bash
yum clean all
curl http://aliacs-k8s-cn-hangzhou.oss-cn-hangzhou.aliyuncs.com/public/pkg/run/attach/attach_node.sh | bash -s -- --docker-version 17.06.2-ce-1 --token 9e3606.1de6xxxxxxxx9a9 --endpoint 192.168.223.87:6443 --cluster-dns 172.19.0.10
然后完成创建,启用配置.
部署 Autoscaler 到 kubernetes 集群中
由于 autoscaler 会调用阿里云 ESS api 来触发集群规模调整,因此需要配置 api 访问的 accesskey . 同时需要手动指定上面刚刚创建伸缩组,格式为
regionid.ess_group_name
, 上面示例:
cn-hangzhou.kubernetes-hangzhou-group
创建 AutoScaler kubernetes deployment. 所有命令均在其中一台 master 上面执行.
[root@iZbuZ autoscale]# export ACCESS_KEY=<replace with your own key> \
ACCESS_SECRET=<replace with your own>
[root@iZbuZ autoscale]# export AUTO_SCALER_GROUP=<replace with above group name>
[root@iZbuZ autoscale]# kubectl create secret generic cloud-config \
-n kube-system \
--from-literal=access-key-id="${ACCESS_KEY}" \
--from-literal=access-key-secret="${ACCESS_SECRET}"
[root@iZbuZ autoscale]#
[root@iZbuZ autoscale]# cat <<EOF | kubectl apply -f -
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: cluster-autoscaler
namespace: kube-system
labels:
app: cluster-autoscaler
spec:
replicas: 1
selector:
matchLabels:
app: cluster-autoscaler
template:
metadata:
labels:
app: cluster-autoscaler
spec:
serviceAccountName: admin
containers:
- image: registry.cn-hangzhou.aliyuncs.com/google-containers/cluster-autoscaler:v1.1.0
name: cluster-autoscaler
resources:
limits:
cpu: 100m
memory: 300Mi
requests:
cpu: 100m
memory: 300Mi
command:
- ./cluster-autoscaler
- --v=4
- --stderrthreshold=info
- --cloud-provider=alicloud
- --skip-nodes-with-local-storage=false
- --nodes=1:100:${AUTO_SCALER_GROUP}
env:
- name: ACCESS_KEY_ID
valueFrom:
secretKeyRef:
name: cloud-config
key: access-key-id
- name: ACCESS_KEY_SECRET
valueFrom:
secretKeyRef:
name: cloud-config
key: access-key-secret
imagePullPolicy: "Always"
EOF
[root@iZbuZ autoscale]# kubectl get deploy -n kube-system cluster-autoscaler
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
cluster-autoscaler 1 1 1 1 17h
完成创建.
测试自动扩展节点效果
Autoscaler 根据用户应用的资源静态请求量来决定是否扩展集群大小,因此请设置好应用的资源请求量.
测试前节点数量如下,配置均为 2 核 4G ECS,其中两个节点可调度.
[root@iZbuZ ~]# kubectl get no
NAME STATUS ROLES AGE VERSION
cn-hangzhou.i-bp12xhp8qv06m48u6j6q Ready <none> 1d v1.8.4
cn-hangzhou.i-bp13sdsyk6zszfotf49x Ready master 1d v1.8.4
cn-hangzhou.i-bp16808sbruko78l8j96 Ready <none> 1d v1.8.4
cn-hangzhou.i-bp1bb7xjnbyxmxska58u Ready master 1d v1.8.4
cn-hangzhou.i-bp1bhan5nqzh8vfk08qb Ready master 1d v1.8.4
接下来我们创建一个副本 nginx deployment, 指定每个 nginx 副本需要消耗 1 核 1G 内存.
[root@iZbuZ ~]# cat <<EOF | kubectl apply -f -
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
run: nginx
name: nginx
spec:
replicas: 1
template:
labels:
run: nginx
spec:
containers:
- image: nginx
imagePullPolicy: Always
name: nginx
resources:
requests:
cpu: "1"
memory: 1Gi
EOF
[root@iZbuZ ~]# kubectl get po
NAME READY STATUS RESTARTS AGE
http-svc-wpxgj 1/1 Running 0 1d
http-svc-z9hjv 1/1 Running 0 1d
nginx-9d9b56898-xvkkm 1/1 Running 0 18h
看到由于有足够的 cpu 内存资源,所以 pod 能够正常调度.接下来我们使用 kubectl scale 命令来扩展副本数量到 4 个.
[root@iZbuZ ~]# kubectl scale deploy nginx --replicas 4
[root@iZbuZ ~]# kubectl get po
NAME READY STATUS RESTARTS AGE
http-svc-wpxgj 1/1 Running 0 1d
http-svc-z9hjv 1/1 Running 0 1d
nginx-9d9b56898-jphgw 1/1 Running 0 18h
nginx-9d9b56898-p92lk 1/1 pending 0 20s
nginx-9d9b56898-sbrp6 1/1 pending 0 20s
nginx-9d9b56898-xvkkm 1/1 Running 0 18h
[root@iZbuZ ~]# kubectl describe po nginx-9d9b56898-p92lk |grep -A 4 Event
发现由于没有足够的 cpu 内存资源,该 pod 无法被调度(pod 处于 pending 状态).这时候 autoscaler 会介入,尝试创建一个新的节点来让 pod 可以被调度.接下来我们执行一个
watch kubectl get no
的命令来监视 node 的添加.大约几分钟后,就有新的节点添加进来了
[root@iZbuZ ~]# watch kubectl get no
Every 2.0s: kubectl get no
NAME STATUS ROLES AGE VERSION
cn-hangzhou.i-bp12xhp8qv06m48u6j6q Ready <none> 1d v1.8.4
cn-hangzhou.i-bp13sdsyk6zszfotf49x Ready master 1d v1.8.4
cn-hangzhou.i-bp16808sbruko78l8j96 Ready <none> 1d v1.8.4
cn-hangzhou.i-bp17cnn1s5fxh5aeujii Ready <none> 1m v1.8.4
cn-hangzhou.i-bp1bb7xjnbyxmxska58u Ready master 1d v1.8.4
cn-hangzhou.i-bp1bhan5nqzh8vfk08qb Ready master 1d v1.8.4
[root@iZbuZ ~]# kubectl get po
NAME READY STATUS RESTARTS AGE
http-svc-wpxgj 1/1 Running 0 1d
http-svc-z9hjv 1/1 Running 0 1d
nginx-9d9b56898-jphgw 1/1 Running 0 18h
nginx-9d9b56898-p92lk 1/1 Running 0 2m
nginx-9d9b56898-sbrp6 1/1 Running 0 2m
nginx-9d9b56898-xvkkm 1/1 Running 0 18h
可以观察到比测试前新增了一个节点,并且 pod 也正常调度了.
测试自动收缩节点数量
当 Autoscaler 发现通过调整 Pod 分布时可以空闲出多余的 node 的时候,会执行节点移除操作.这个操作不会立即执行,通常设置了一个冷却时间,300s 左右才会执行 scale down.
通过 kubectl scale 来调整 nginx 副本数量到 1 个,观察集群节点的变化.
[root@iZbuZ ~]# kubectl scale deploy nginx --replicas 1
[root@iZbuZ ~]# watch kubectl get no
Every 2.0s: kubectl get no
NAME STATUS ROLES AGE VERSION
cn-hangzhou.i-bp12xhp8qv06m48u6j6q Ready <none> 1d v1.8.4
cn-hangzhou.i-bp13sdsyk6zszfotf49x Ready master 1d v1.8.4
cn-hangzhou.i-bp16808sbruko78l8j96 Ready <none> 1d v1.8.4
cn-hangzhou.i-bp1bb7xjnbyxmxska58u Ready master 1d v1.8.4
cn-hangzhou.i-bp1bhan5nqzh8vfk08qb Ready master 1d v1.8.4
总结
Autoscaler 会作为一个开源工具独立使用,阿里云 Kubernetes 服务也将进一步简化弹性伸缩的用户体验,将弹性计算和 Kubernetes 集群管理完美结合在一起.也欢迎您的意见和建议,帮助我们迭代产品能力.
阿里云 Kubernetes 服务 全球首批通过 Kubernetes 一致性认证,简化了 Kubernetes 集群生命周期管理,内置了与阿里云产品集成,也将进一步简化 Kubernetes 的开发者体验,帮助用户关注云端应用价值创新.
来源: https://yq.aliyun.com/articles/392170