部署metrics-serverMetrics Server 是 Kubernetes 的“实时仪表盘采集器”它的核心作用是收集集群内 Pod 和 Node 的实时资源使用率CPU 和内存并供外部工具如 HPA 或 kubectl top读取有两种部署方式这里笔者选择yaml文件部署helm方式激活metrics-servervim kubernetes-dashboard/values.yamlmetrics-server:enabled: true修改镜像位置vim kubernetes-dashboard/charts/metrics-server/values.yamlimage:repository: reg.westos.org/metrics-server/metrics-servertag: v0.8.0使用helm更新部署helm upgrade kubernetesui kubernetes-dashboard --namespace kubernetes-dashboard查看资源kubectl -n kubernetes-dashboard get all查看资源使用量kubectl top nodekubectl top podyaml文件部署下载部署文件https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml跳过证书验证修改镜像源拉取所需镜像打标签并上传应用查看部署HPA应用apiVersion: apps/v1kind: Deploymentmetadata:name: phpspec:replicas: 1selector:matchLabels:app: phptemplate:metadata:labels:app: phpspec:containers:- name: phpappimage: reg.westos.org/metrics-server/hpa-exampleports:- containerPort: 80resources:requests:cpu: 200m# memory: 256Mi---apiVersion: v1kind: Servicemetadata:name: phpspec:ports:- name: httpprotocol: TCPport: 80selector:app: php---apiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: phpspec:ingressClassName: nginxrules:- host: php.example.comhttp:paths:- path: /backend:service:name: phpport:name: httppathType: ImplementationSpecificHelmchart包管理Helm Chart 核心作用1. 打包整套复杂应用告别零散 yaml一个完整应用往往包含Deployment、Service、Ingress、ConfigMap、Secret、RBAC、CRD、StorageClass、StatefulSet 等几十份 yaml。原生方式手动维护一堆 yaml依次kubectl apply顺序容易错、漏资源Helm Chart全部打包成一个包一条命令完成整套安装2. 模板化 配置分离一套模板多环境复用资源模板写死在templates变量抽离到 values.yaml。 不同环境可以写多套 valuesvalues-dev.yaml、values-prod.yaml3. 版本管理安装、升级、回滚Helm 引入Release版本实例每一次在集群安装 Chart生成一个 Release。helm install新建 Releasehelm upgrade升级 Release修改 values / 换新版 charthelm rollback release名 revision一键回滚到上一个版本helm list查看集群中所有已部署的 Releasehelm uninstall卸载整套应用清理所有相关 K8s 资源原生 kubectl 没有应用级别的版本记录改 yaml 出错很难一键回滚整套资源。4. 依赖管理子 ChartChart 可以声明依赖在 Chart.yaml 或 requirements.yaml自动拉取依赖包。 例业务 Chart 依赖一个存储 Chart自动部署 CSIStorageClass安装业务包时会自动安装存储组件。5. 仓库机制RepoChart 可以存放在 Chart 仓库类似 yum 源公开仓库Bitnami、Longhorn、Rook 等。6. 可复用、标准化、便于 CI/CD团队统一 Chart 规范所有环境部署逻辑一致减少人为操作差异CI 流水线可以直接调用 helm 命令做部署适合 GitOps。官网 https://helm.sh/zh/docs/intro/quickstart/https://github.com/helm/helm/releases配置helm命令补齐使用helm管理应用查询官方应用中心# helm search hub nginx添加第三方repo源查询chart拉取chart部署chartglobal:imageRegistry: reg.westos.orgsecurity:allowInsecureImages: true上传所需镜像查询资源helm list-n redishelm -n redis status redishelm-n redisget manifestredis| kubectl get -f -更新chartglobal:imageRegistry: reg.westos.orgsecurity:allowInsecureImages: trueredis:password: westossentinel:enabled: true封装chart包修改chart检测语法打包部署应用访问回收上传chart到OCI仓库使用harbor存储和管理chart复制仓库证书登录仓库查看默认缓存信息提前在harbor仓库创建charts项目这个仓库专门存放chart包上传chart下载chart默认下载最新版本安装chart测试再次打包上传chart需要先修改下chart信息Chart.yamlappversion也要改为v2value.yaml升级测试部署历史回滚测试查看历史多了一条回滚的历史回收helm部署storageclassHelm 一键部署 CSI 存储插件并自动生成 StorageClass开启 K8s 集群动态持久化存储业务 PVC 自动分配存储卷不用人工维护 PV删除原有的部署添加repo寻找所需chart包将该文件放在部署了helm的主机image:repository: reg.westos.org/sig-storage/nfs-subdir-external-provisionernfs:server: 192.168.154.201path: /nfsdatastorageClass:defaultClass: truereclaimPolicy: DeletearchiveOnDelete: false #这里填写了false之后的实验中不会自动恢复删除的pvc创建ns测试注意创建时间为28s的条目没有生成新的datahelm部署ingress-nginxingress-nginx 本质是 K8s 的 Ingress 控制器Helm 是用来一键安装它的包管理工具Ingress 资源只是规则ingress-nginx 才是真正的负载 / 反向代理程序K8s 原生 Ingress 只是路由规则对象没有控制器不会生效ingress-nginx 以 Nginx 为内核监听集群 Ingress 规则动态更新 Nginx 配置。对外暴露集群内服务统一入口用域名 / 路径区分后端不同 Pod 服务不用为每个业务单独建 LoadBalancer/NodePort Service节约端口和公网 IP。支持 HTTP/HTTPS、域名路由、路径路由、SSL 证书、限流、重写、会话保持等 Nginx 能力。Helm 的价值ingress-nginx 组件多Deployment、ConfigMap、RBAC、Service、IngressClass 等Helm Chart 打包全套资源通过 values.yaml 灵活配置外部访问类型、资源配额、ssl、日志、参数调优实现一键安装、升级、回滚、卸载便于多环境统一管理。回收原有部署添加repo源寻找ingress-nginx的chart包注意镜像私有仓库中是否具备global:image:registry: reg.westos.orgcontroller:image:image: ingress-nginx/controllertag: v1.13.3digest: digestChroot: ingressClassResource:name: nginxdefault: trueservice:type: LoadBalancer # 需要metallb的支持admissionWebhooks:patch:image:registry: reg.westos.orgimage: ingress-nginx/kube-webhook-certgentag: v1.6.3digest: defaultBackend:enabled: truename: defaultbackendimage:registry: reg.westos.orgimage: ingress-nginx/defaultbackend-amd64tag: 1.5测试回收k8s调度nodename强制固定节点跳过调度器apiVersion: v1kind: Podmetadata:name: nginxlabels:app: nginxspec:containers:- name: nginximage: reg.westos.org/library/nginx:latestnodeName: k8s3 #找不到节点pod会出现pending优先级最高回收nodeselector最简单标签匹配Pod 写标签 KV只会调度到拥有对应标签的节点硬约束不满足就 PendingKey键 名字Value值 对应的数据。一一对应的key: value结构就是 KV 对apiVersion: v1kind: Podmetadata:name: nginxspec:containers:- name: nginximage: reg.westos.org/library/nginx:latestimagePullPolicy: IfNotPresentnodeSelector:disktype: ssd为目标节点打上标签后应用yaml文件查看回收这里去除k8s2的标签重新应用发现部署在k8s3上nodeaffinity两种规则requiredDuringSchedulingIgnoredDuringExecution硬约束必须满足不满足不调度preferredDuringSchedulingIgnoredDuringExecution软约束优先选找不到也可以放其他节点apiVersion: v1kind: Podmetadata:name: node-affinityspec:containers:- name: nginximage: reg.westos.org/library/nginx:latestaffinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:- matchExpressions:- key: disktypeoperator: Invalues:- ssd- fcpreferredDuringSchedulingIgnoredDuringExecution:- weight: 1preference:matchExpressions:- key: kubernetes.io/hostnameoperator: NotInvalues:- k8s3最后的event里可以看到选择了k8s3由于没有符合的标签回收podaffinity吸引尽量把 Pod 调度到和指定 Pod同一个拓扑域同节点 / 同机架 / 同可用区适合服务之间高频通信apiVersion: apps/v1kind: Deploymentmetadata:name: nginx-deploymentlabels:app: nginxspec:replicas: 3selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: reg.westos.org/library/nginx:latestaffinity:podAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- key: appoperator: Invalues:- nginxtopologyKey: kubernetes.io/hostname回收podantiaffinity排斥避免多个同业务 Pod 落在同一节点实现高可用比如多副本分散在不同 nodeapiVersion: apps/v1kind: Deploymentmetadata:name: nginx-deploymentlabels:app: nginxspec:replicas: 3selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: reg.westos.org/library/nginx:latestaffinity:podAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- key: appoperator: Invalues:- nginxtopologyKey: kubernetes.io/hostname由于这里笔者只有两个node所以第三个副本是pending状态回收pod反亲和倾向满足倾向满足指 Kubernetes 调度器会尽量遵守反亲和规则但若集群中没有其他符合条件的节点仍会将 Pod 调度到不满足规则的节点上属于软约束不会导致 Pod 调度失败apiVersion: apps/v1kind: Deploymentmetadata:name: node-affinityspec:replicas: 3selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:tolerations:- effect: NoScheduleoperator: Exists- effect: NoExecuteoperator: Existscontainers:- name: nginximage: nginxaffinity:podAntiAffinity:preferredDuringSchedulingIgnoredDuringExecution:- weight: 100podAffinityTerm:labelSelector:matchExpressions:- key: appoperator: Invalues:- nginxtopologyKey: kubernetes.io/hostnamenodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:- matchExpressions:- key: disktypeoperator: Invalues:- ssd- sataTaintsTaint 污点打在 Node 上节点拒绝不带容忍的 Pod。3 种效应NoSchedule新 Pod 不能调度上去已有 Pod 继续跑PreferNoSchedule尽量不调度非强制NoExecute不仅不调度还驱逐节点上不匹配的老 PodTolerations 容忍打在 Pod 上Pod 声明可以接受节点的污点才能调度到该节点apiVersion: apps/v1kind: Deploymentmetadata:labels:app: webname: webspec:replicas: 3selector:matchLabels:app: webtemplate:metadata:labels:app: webspec:containers:- image: reg.westos.org/library/nginx:latestname: nginx设置taint增加副本新增的pod都在k8s2上更改污点类型所有的pod转移到k8s2上回收设置 tolerations这里笔者的内存不足理想情况下应用后pod会被调度到没有污点的node上回收kubectl delete -f taint.yaml容忍所有taints应用之后可以看到pod被调度到了有污点的k8s3上回收回收污点cordon、drain、deletecordon禁止新 Pod 调度到该节点已经在节点上运行的 Pod 不受影响继续正常跑drain自动执行 cordon 驱逐节点上所有业务 Poddelete把这个 Node 对象从 k8s APIServer 中删掉新建的都在k8s3上测试draink8s3节点重启kubelet服务重新加入集群