Linux学习33-HPA动态扩缩容及k8s调度策略

部署metrics-server

Metrics Server 是 Kubernetes 的"实时仪表盘采集器",它的核心作用是收集集群内 Pod 和 Node 的实时资源使用率(CPU 和内存),并供外部工具(如 HPA 或 kubectl top)读取

有两种部署方式,这里笔者选择yaml文件部署

helm方式

激活metrics-server

vim kubernetes-dashboard/values.yaml

metrics-server:

enabled: true

修改镜像位置

vim kubernetes-dashboard/charts/metrics-server/values.yaml

image:

repository: reg.westos.org/metrics-server/metrics-server

tag: "v0.8.0"

使用helm更新部署

helm upgrade kubernetesui kubernetes-dashboard --namespace kubernetes-dashboard

查看资源

kubectl -n kubernetes-dashboard get all

查看资源使用量

kubectl top node

kubectl top pod

yaml文件部署

下载部署文件

https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

跳过证书验证,修改镜像源

拉取所需镜像,打标签并上传

应用,查看

部署HPA应用

apiVersion: "apps/v1"

kind: "Deployment"

metadata:

name: "php"

spec:

replicas: 1

selector:

matchLabels:

app: "php"

template:

metadata:

labels:

app: "php"

spec:

containers:

  • name: "phpapp"

image: "reg.westos.org/metrics-server/hpa-example"

ports:

  • containerPort: 80

resources:

requests:

cpu: 200m

memory: 256Mi


apiVersion: "v1"

kind: "Service"

metadata:

name: "php"

spec:

ports:

  • name: "http"

protocol: "TCP"

port: 80

selector:

app: "php"


apiVersion: networking.k8s.io/v1

kind: Ingress

metadata:

name: php

spec:

ingressClassName: nginx

rules:

http:

paths:

  • path: /

backend:

service:

name: php

port:

name: http

pathType: ImplementationSpecific

H elm chart包管理

Helm Chart 核心作用

1. 打包整套复杂应用,告别零散 yaml

一个完整应用往往包含:Deployment、Service、Ingress、ConfigMap、Secret、RBAC、CRD、StorageClass、StatefulSet 等几十份 yaml。

  • 原生方式:手动维护一堆 yaml,依次kubectl apply,顺序容易错、漏资源;
  • Helm Chart:全部打包成一个包,一条命令完成整套安装

2. 模板化 + 配置分离,一套模板多环境复用

资源模板写死在templates,变量抽离到 values.yaml 。 不同环境可以写多套 values:values-dev.yaml、values-prod.yaml

3. 版本管理:安装、升级、回滚

Helm 引入Release(版本实例):每一次在集群安装 Chart,生成一个 Release。

  • helm install:新建 Release
  • helm upgrade:升级 Release(修改 values / 换新版 chart)
  • helm rollback <release名> <revision>:一键回滚到上一个版本
  • helm list:查看集群中所有已部署的 Release
  • helm uninstall:卸载整套应用,清理所有相关 K8s 资源

原生 kubectl 没有应用级别的版本记录,改 yaml 出错很难一键回滚整套资源。

4. 依赖管理(子 Chart)

Chart 可以声明依赖(在 Chart.yaml 或 requirements.yaml),自动拉取依赖包。 例:业务 Chart 依赖一个存储 Chart(自动部署 CSI+StorageClass),安装业务包时会自动安装存储组件。

5. 仓库机制(Repo)

Chart 可以存放在 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


部署chart

global:

imageRegistry: "reg.westos.org"

security:

allowInsecureImages: true

上传所需镜像

查询资源
helm list -n redis

helm -n redis status redis

helm -n redis get manifest redis | kubectl get -f -


更新chart

global:
imageRegistry: "reg.westos.org"
security:
allowInsecureImages: true
redis:
password: "westos"
sentinel:
enabled: true

封装chart包


修改chart


检测语法

打包


部署应用


访问


回收

上传chart到OCI仓库

使用harbor存储和管理chart

复制仓库证书


登录仓库


查看默认缓存信息


提前在harbor仓库创建charts项目,这个仓库专门存放chart包


上传chart


下载chart,默认下载最新版本


安装chart

测试


再次打包上传chart

需要先修改下chart信息,Chart.yaml,appversion也要改为v2

value.yaml

升级

测试


部署历史


回滚

测试

查看历史,多了一条回滚的历史

回收

helm部署storageclass

Helm 一键部署 CSI 存储插件,并自动生成 StorageClass,开启 K8s 集群动态持久化存储,业务 PVC 自动分配存储卷,不用人工维护 PV

删除原有的部署

添加repo

寻找所需chart包

将该文件放在部署了helm的主机

image:

repository: reg.westos.org/sig-storage/nfs-subdir-external-provisioner

nfs:

server: 192.168.154.201

path: /nfsdata

storageClass:

defaultClass: true

reclaimPolicy: Delete

archiveOnDelete: false #这里填写了false,之后的实验中不会自动恢复删除的pvc

创建ns


测试

注意创建时间为28s的条目

没有生成新的data

helm部署ingress-nginx

ingress-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.org

controller:

image:

image: ingress-nginx/controller

tag: "v1.13.3"

digest: ""

digestChroot: ""

ingressClassResource:

name: nginx

default: true

service:

type: LoadBalancer # 需要metallb的支持

admissionWebhooks:

patch:

image:

registry: reg.westos.org

image: ingress-nginx/kube-webhook-certgen

tag: v1.6.3

digest: ""

defaultBackend:

enabled: true

name: defaultbackend

image:

registry: reg.westos.org

image: ingress-nginx/defaultbackend-amd64

tag: "1.5"

测试

回收

k8s调度

nodename

强制固定节点,跳过调度器


apiVersion: v1

kind: Pod

metadata:

name: nginx

labels:

app: nginx

spec:

containers:

  • name: nginx

image: reg.westos.org/library/nginx:latest

nodeName: k8s3 #找不到节点pod会出现pending,优先级最高

回收

nodeselector

最简单标签匹配;Pod 写标签 KV,只会调度到拥有对应标签的节点;硬约束,不满足就 Pending

Key(键)= 名字;Value(值)= 对应的数据。一一对应的 key: value 结构,就是 KV 对

apiVersion: v1

kind: Pod

metadata:

name: nginx

spec:

containers:

  • name: nginx

image: reg.westos.org/library/nginx:latest

imagePullPolicy: IfNotPresent

nodeSelector:

disktype: ssd

为目标节点打上标签后应用yaml文件

查看

回收

这里去除k8s2的标签,重新应用,发现部署在k8s3上

nodeaffinity

两种规则:
requiredDuringSchedulingIgnoredDuringExecution:硬约束,必须满足,不满足不调度
preferredDuringSchedulingIgnoredDuringExecution:软约束,优先选,找不到也可以放其他节点

apiVersion: v1

kind: Pod

metadata:

name: node-affinity

spec:

containers:

  • name: nginx

image: reg.westos.org/library/nginx:latest

affinity:

nodeAffinity:

requiredDuringSchedulingIgnoredDuringExecution:

nodeSelectorTerms:

  • matchExpressions:

  • key: disktype

operator: In

values:

  • ssd

  • fc

preferredDuringSchedulingIgnoredDuringExecution:

  • weight: 1

preference:

matchExpressions:

operator: NotIn

values:

  • k8s3

最后的event里可以看到选择了k8s3(由于没有符合的标签)

回收

podaffinity

吸引,尽量把 Pod 调度到和指定 Pod同一个拓扑域(同节点 / 同机架 / 同可用区),适合服务之间高频通信

apiVersion: apps/v1

kind: Deployment

metadata:

name: nginx-deployment

labels:

app: nginx

spec:

replicas: 3

selector:

matchLabels:

app: nginx

template:

metadata:

labels:

app: nginx

spec:

containers:

  • name: nginx

image: reg.westos.org/library/nginx:latest

affinity:

podAffinity:

requiredDuringSchedulingIgnoredDuringExecution:

  • labelSelector:

matchExpressions:

  • key: app

operator: In

values:

  • nginx

topologyKey: "kubernetes.io/hostname"


回收

podantiaffinity

排斥,避免多个同业务 Pod 落在同一节点,实现高可用(比如多副本分散在不同 node)


apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:



由于这里笔者只有两个node,所以第三个副本是pending状态

回收


pod反亲和倾向满足

"倾向满足"指 Kubernetes 调度器会尽量遵守反亲和规则,但若集群中没有其他符合条件的节点,仍会将 Pod 调度到不满足规则的节点上,属于软约束,不会导致 Pod 调度失败

apiVersion: apps/v1
kind: Deployment
metadata:
name: node-affinity
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
tolerations:

  • effect: NoSchedule
    operator: Exists
  • effect: NoExecute
    operator: Exists
    containers:
  • name: nginx
    image: nginx
    affinity:
    podAntiAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
  • weight: 100
    podAffinityTerm:
    labelSelector:
    matchExpressions:
  • key: app
    operator: In
    values:
  • nginx
    topologyKey: kubernetes.io/hostname

nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:

  • matchExpressions:
  • key: disktype
    operator: In
    values:
  • ssd
  • sata

Taints

Taint 污点:打在 Node 上,节点拒绝不带容忍的 Pod。3 种效应:

NoSchedule:新 Pod 不能调度上去,已有 Pod 继续跑

PreferNoSchedule:尽量不调度,非强制

NoExecute:不仅不调度,还驱逐节点上不匹配的老 Pod

Tolerations 容忍:打在 Pod 上,Pod 声明可以接受节点的污点,才能调度到该节点

apiVersion: apps/v1

kind: Deployment

metadata:

labels:

app: web

name: web

spec:

replicas: 3

selector:

matchLabels:

app: web

template:

metadata:

labels:

app: web

spec:

containers:

name: nginx


设置taint

增加副本

新增的pod都在k8s2上

更改污点类型

所有的pod转移到k8s2上

回收


设置 tolerations

这里笔者的内存不足,理想情况下应用后pod会被调度到没有污点的node上
回收
kubectl delete -f taint.yaml
容忍所有taints

应用之后可以看到pod被调度到了有污点的k8s3上

回收

回收污点

cordon、drain、delete

cordon: 禁止新 Pod 调度到该节点;已经在节点上运行的 Pod 不受影响,继续正常跑

**drain:**自动执行 cordon + 驱逐节点上所有业务 Pod

**delete:**把这个 Node 对象从 k8s APIServer 中删掉

新建的都在k8s3上

测试drain


k8s3节点重启kubelet服务重新加入集群

相关推荐
yi0111 小时前
LeetCode 134 加油站:从 双循环暴力 演变到 贪心
linux·算法·leetcode
知识分享小能手1 小时前
C++ 学习教程,从入门到精通,C++内存模型和名称空间 — 详细知识点总结(9)
开发语言·c++·学习
java_logo1 小时前
Docker 部署 dockurr/windows:轻松搭建浏览器可控 Windows 虚拟机
运维·windows·docker·容器·虚拟机·kvm·轩辕镜像
醇氧1 小时前
CentOS7.9 Yum 安装 Redis6.x(RPM 包,无需编译,推荐 remi 源)
linux·python
怪奇云呼军1 小时前
从 ElevenLabs 看工具调用:闪电智能 Voice Agent 的企业集成验收设计
android·大数据·运维·服务器·网络·人工智能·kotlin
AOI小白新手上路1 小时前
韦东山《ARM 架构与编程》3-2 GPIO 引脚操作方法概述 · 学习笔记
arm开发·学习·架构
傲世仙尊2 小时前
重写的顿悟-lambda类型擦除条件变量的真相与sendto里的bind
linux·网络
zhangrelay2 小时前
ROS2 Lyrical实验5导航Nav2
linux·笔记·学习·ubuntu·机器人
一条破秋裤2 小时前
Linux 线程分离与主动取消:pthread_detach、pthread_cancel
java·linux·jvm