目录
- 插叙
- 前言
- 一、思考和原理
- 二、实现步骤
- 0. 资料包
- 1. TLS证书签发
- 2. 使用 certmanager 生成签发证书
- 3. 获取secret的内容 并替换CA_BUNDLE
- 4.部署svc + deploy
- 三、测试验证
- 1. 观察pod情况
- 2. 给node 打上不需要超售的标签【可以让master节点资源不超卖】
- 3. 资源实现超卖
- 4. 删除还原
- 四、总结
插叙
友友们好久不见,插播一个最近get的证书,完成了第一步,一起努力鸭~
前言
小涛运维时遇到一个问题,发现:容器在Kubernetes中,使用率要远低于申请率
比如:申请了1G内存,实际只用了200M左右,
就会产生这种情况:node上还有资源,但是不能调度了(Why?因为k8s默认调度器是 按allocate算的,并不是真实剩余的)
那么怎么办呢?
- 用scheduler extender写一个调度器 ,用usage调度pod
- 按照namespace 把业务分开,在每个ns上设置resourceQuota -->相对最容易实现【yaml文件限制】
- 把pod的request降低
- 基于MutatingWebhook 把node的 allocatable 调高
今天,小涛讲解的方法,是第四种----基于MutatingWebhook 把node的 allocatable 调高
下面和小涛看看吧~
一、思考和原理
思想:基于MutatingWebhook将allocatable调高
,实现node资源超卖
#查看某个node节点当前资源情况
kubectl get nodes node2 -o yaml |grep allocatable: -A6
核心点:动态修改节点Node对象的allocatable字段值
- 而我们看到allocatable字段属于Status字段
- 显然不能直接通过kubectl edit命令来直接修改。
- 因为Status字段和Spec字段不同,Spec是用户设置的期望数据
- 而Status是实际数据(Node节点通过不断向apiServer发送心跳来更新自己的实时状态,最终存在etcd中)。那么怎么去修改Stauts字段呢?
二、实现步骤
0. 资料包
链接:https://pan.baidu.com/s/12AmYn5h_c_XrlH6iS-gSDQ
提取码:sell
- 实现的核心步骤
- 证书和签名:tls双向认证需要
- 编写go项目代码,实现webhook服务器,对node status字段更改
- 部署webhook服务,编写MutatingWebhookConfiguration 测试【把node 的status推送到中间件服务中】
1. TLS证书签发
借助certmanager 签发证书
#安装部署
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.8.2/cert-manager.yaml
#================================================================
#如果是内网环境,将yaml文件 wget后,再docker pull 对应的镜像后,再导入到离线环境的镜像仓库【资料包里有相关镜像资料】
wget https://github.com/cert-manager/cert-manager/releases/download/v1.8.2/cert-manager.yaml
docker pull quay.io/jetstack/cert-manager-cainjector:v1.8.2
docker pull quay.io/jetstack/cert-manager-controller:v1.8.2
docker pull quay.io/jetstack/cert-manager-webhook:v1.8.2
docker pull registry.cn-beijing.aliyuncs.com/dbatao/k8s-node-oversell:v1
检查certmanager服务是否正常
$ kubectl apply -f cert-manager.yaml
$ kubectl get pod -n cert-manager
2. 使用 certmanager 生成签发证书
# cat cert.yaml
---
apiVersion: v1
kind: Namespace
metadata:
name: node-oversell-webhook
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: selfsigned-issuer
namespace: node-oversell-webhook
spec:
selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: serving-cert
namespace: node-oversell-webhook
spec:
dnsNames:
- node-oversell-webhook.node-oversell-webhook.svc
- node-oversell-webhook.node-oversell-webhook.svc.cluster.local
issuerRef:
kind: Issuer
name: selfsigned-issuer
secretName: webhook-server-cert
---
# kubectl apply -f cert.yaml
查看证书是否已签发完成
$ kubectl get certificate -n node-oversell-webhook
3. 获取secret的内容 并替换CA_BUNDLE
CA_BUNDLE=$(kubectl -n node-oversell-webhook get secrets webhook-server-cert -o jsonpath="{.data.ca\.crt}")
echo ${CA_BUNDLE}
sed -i "s|\${CA_BUNDLE}|${CA_BUNDLE}|g" mutating_webhook.yaml
cat mutating_webhook.yaml
kubectl apply -f mutating_webhook.yaml
4.部署svc + deploy
kubectl apply -f webhook_deployment.yaml
kubectl apply -f svc.yaml
curl -k https://svc_ip:443/readyz #预期---返回ok
三、测试验证
1. 观察pod情况
kubectl logs -n node-oversell-webhook node-oversell-webhook-7b75dd467b-hs9m9 --tail 10
2. 给node 打上不需要超售的标签【可以让master节点资源不超卖】
#将<node_name>更换为不用超卖节点的名称,非常智能!!
$ kubectl label node <node_name> node-oversell/disable=true
#例如
kubectl label node master01 node-oversell/disable=true
#如果需要这个节点超卖,将标签去掉即可
kubectl label node master01 node-oversell/disable-
3. 资源实现超卖
$ kubectl get nodes node2 -o yaml |grep allocatable: -A6
#在Prometheus里用PromeQL也能查看到
kube_node_status_allocatable{} #QL查询语句
4. 删除还原
$ kubectl delete deploy -n node-oversell-webhook node-oversell-webhook
$ kubectl delete mutatingwebhookconfigurations node-oversell-webhook
四、总结
-
我们再来回顾一下大致步骤
-
API-Server支持准入控制器中,准入控制器中有一个“修改性质的控制器”
- 监听node status的服务资源,牵引到某个服务上【这个服务中,把10G改成20G,再推送API-Server中】
- Admission controller是拦截(经过身份验证)API Server请求的网关,并且可以修改请求对象或拒绝请求。
- k8s在Api-Server中就提供Admission Controller(准入控制器)的机制,包括MutatingAdmissionWebhook,通过这个webhook,所有在集群中和Api-Sever交互的请求都被发送到一个指定的接口中,我们只要提供一个这样的接口,就可以获取到Node往ApiServer发送心跳的Staus数据了。然后将这个数据进行我们的自定义修改,再往后传给etcd,就能让etcd以为我们修改过的Status数据就是节点的真实Status,最终实现资源的超卖。
- MutatingAdmissionWebhook 作为kubernetes的 ApiServer中Admission Controller的一部分,提供了非常灵活的扩展机制,通过配置MutatingWebhookConfiguration对象,理论上可以监听并修改任何经过ApiServer处理的请求。
-
形象的通俗理解:古代时,大臣(node资源汇报)想汇报情况给皇帝(ETCD),需要通过太监进行传达,那么太监可以修改奏本(allocatable)再传给皇帝,以达到以假乱真的情形。
- 而 k8s在Api-Server中就提供Admission Controller(准入控制器)的机制(可以修改性质的控制器)
今天也是充实的一天呢,有问题欢迎大家评论区交流,咱们下篇文章再见了~ 😉