Skip to content

Helm

Helm 是 Kubernetes 的包管理器,用来打包、配置、部署应用到 K8s 集群。

  • Helm Chart 就像 Linux 里的 apt、yum 的安装包(.deb/.rpm)
  • 把一套 K8s 的 Deployment、Service、Ingress、ConfigMap 等 YAML 封装成一个 Chart
  • 部署的时候用 helm install,传不同的 values.yaml,就能部署出不同的环境版本
  • 结合 GitOps,把 Helm Chart 放到 Git 仓库,CI/CD pipeline 可以自动部署

核心价值

能力说明举例
模板化部署把多个 YAML 文件抽象成变量注入image.tag={ { .Values.image.tag } }
一键部署/升级/回滚管理部署历史helm rollback
多环境配置使用不同的 values 文件values-dev.yaml / values-prod.yaml
依赖管理Chart 可以嵌套依赖子 Chart主服务引入 Redis/MySQL 子 Chart
版本发布标准化每个服务都以 Chart 管理版本v1.2.3 标签即部署版本

常见的仓库

shell
helm repo add nvdp https://nvidia.github.io/k8s-device-plugin
helm repo add harbor https://helm.goharbor.io
helm repo add nvidia https://nvidia.github.io/gpu-operator
helm repo add metrics-server https://kubernetes-sigs.github.io/metrics-server/
helm repo add hami-charts https://project-hami.github.io/HAMi/
helm repo add hami-webui https://project-hami.github.io/HAMi-WebUI
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo add kyverno https://kyverno.github.io/kyverno/
helm repo update

Harbor

配置

shell
helm repo add harbor https://helm.goharbor.io
helm repo update

helm install harbor harbor/harbor -f harbor-values.yaml --namespace harbor --create-namespace
yaml
expose:
  # 同一台机器部署情况下,可以用 nginx 代理这个
  type: clusterIP
  tls:
    enabled: false
    auto:
      enabled: false
      commonName: "placeholder"

# 注意这里,必须要和 docker login 用的地址一样
# 或 http://your-domain.com
externalURL: http://172.29.101.173:8888  

harborAdminPassword: "123456"

persistence:
  enabled: true
  persistentVolumeClaim:
    registry:
      storageClass: "local-path"
      accessMode: ReadWriteOnce
      size: 5Gi
    jobservice:
      jobLog:
        storageClass: "local-path"
        accessMode: ReadWriteOnce
        size: 1Gi
    database:
      storageClass: "local-path"
      accessMode: ReadWriteOnce
      size: 1Gi
    redis:
      storageClass: "local-path"
      accessMode: ReadWriteOnce
      size: 1Gi
    trivy:
      storageClass: "local-path"
      accessMode: ReadWriteOnce
      size: 1Gi
  • 有时候会有权限问题
yaml
privileged: true
allowPrivilegeEscalation: true
  • 建立 harbor-sercet 授信私服
shell
kubectl create secret docker-registry harbor-secret \
  --docker-server=http://localhost:8888 \
  --docker-username=admin \
  --docker-password=123456 \
  --namespace=harbor-test \
  --dry-run=client -o yaml

Metrics

shell
helm repo add metrics-server https://kubernetes-sigs.github.io/metrics-server/
helm repo update

helm install metrics-server metrics-server/metrics-server \
  --namespace kube-system \
  --create-namespace \
  --set args="{--kubelet-insecure-tls}"

GPU Operator

官方文档

参考教程

安装

  1. GPU 节点必须运行相同的操作系统,
  • 如果提前手动在节点上安装驱动的话,该节点可以使用不同的操作系统
  • CPU 节点操作系统没要求,因为 gpu-operator 只会在 GPU 节点上运行
  1. GPU 节点必须配置相同容器引擎,例如都是 containerd 或者都是 docker
  2. 如果使用了 Pod Security Admission (PSA) ,需要为 gpu-operator 标记特权模式
shell
kubectl create ns gpu-operator
kubectl label --overwrite ns gpu-operator pod-security.kubernetes.io/enforce=privileged
  1. 集群中不要安装 NFD,如果已经安装了需要再安装 gpu-operator 时禁用 NFD 部署。
shell
kubectl get nodes -o json | jq '.items[].metadata.labels | keys | any(startswith("feature.node.kubernetes.io"))'
  1. helm部署
shell
# 添加 nvidia helm 仓库并更新
helm repo add nvidia https://helm.ngc.nvidia.com/nvidia \
    && helm repo update
# 以默认配置安装
helm install --wait --generate-name \
    -n gpu-operator --create-namespace \
    nvidia/gpu-operator

# 如果提前手动安装了 gpu 驱动,operator 中要禁止 gpu 安装
# 目前测试兼容性没问题的版本gpu-operator-v24.9.2
helm install --wait --generate-name \
     -n gpu-operator --create-namespace \
     nvidia/gpu-operator \
     --set driver.enabled=false

helm list -A
shell
kubectl -n gpu-operator get all
NAME                                                           READY   STATUS      RESTARTS      AGE
gpu-feature-discovery-jdqpb                                    1/1     Running     0             35d
gpu-operator-67f8b59c9b-k989m                                  1/1     Running     6 (35d ago)   35d
nfd-node-feature-discovery-gc-5644575d55-957rp                 1/1     Running     6 (35d ago)   35d
nfd-node-feature-discovery-master-5bd568cf5c-c6t9s             1/1     Running     6 (35d ago)   35d
nfd-node-feature-discovery-worker-sqb7x                        1/1     Running     6 (35d ago)   35d
nvidia-container-toolkit-daemonset-rqgtv                       1/1     Running     0             35d
nvidia-cuda-validator-9kqnf                                    0/1     Completed   0             35d
nvidia-dcgm-exporter-8mb6v                                     1/1     Running     0             35d
nvidia-device-plugin-daemonset-7nkjw                           1/1     Running     0             35d
nvidia-driver-daemonset-5.15.0-105-generic-ubuntu22.04-g5dgx   1/1     Running     5 (35d ago)   35d
nvidia-operator-validator-6mqlm                                1/1     Running     0             35d
  1. 验证
bash
kubectl -n gpu-operator exec -it nvidia-driver-daemonset-5.15.0-105-generic-ubuntu22.04-g5dgx -- nvidia-smi
Defaulted container "nvidia-device-plugin" out of: nvidia-device-plugin, config-manager, toolkit-validation (init), config-manager-init (init)
Wed Jul 17 01:49:35 2024
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 525.147.05   Driver Version: 525.147.05   CUDA Version: 12.0     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  NVIDIA A40          Off  | 00000000:00:07.0 Off |                    0 |
|  0%   46C    P0    88W / 300W |    484MiB / 46068MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
|   1  NVIDIA A40          Off  | 00000000:00:08.0 Off |                    0 |
|  0%   48C    P0    92W / 300W |  40916MiB / 46068MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
+-----------------------------------------------------------------------------+
  1. 查看node资源、标签
yaml
$ kubectl get node xxx -oyaml
status:
  addresses:
  - address: 172.18.187.224
    type: InternalIP
  - address: izj6c5dnq07p1ic04ei9vwz
    type: Hostname
  allocatable:
    cpu: "4"
    ephemeral-storage: "189889991571"
    hugepages-1Gi: "0"
    hugepages-2Mi: "0"
    memory: 15246720Ki
    nvidia.com/gpu: "1"  # gpu
    pods: "110"
  capacity:
    cpu: "4"
    ephemeral-storage: 206043828Ki
    hugepages-1Gi: "0"
    hugepages-2Mi: "0"
    memory: 15349120Ki
    nvidia.com/gpu: "1"
    pods: "110"

测试

  1. 开启TimeSlicing
yaml
# kubectl create -n gpu-operator -f nvidia-time-slicing.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: time-slicing-config-all
data:
  any: |-
    version: v1
    flags:
      migStrategy: none
    sharing:
      timeSlicing:
        renameByDefault: false
        failRequestsGreaterThanOne: false
        resources:
          - name: nvidia.com/gpu
            replicas: 4
  1. 修改集群策略
bash
kubectl patch clusterpolicies.nvidia.com/cluster-policy \
    -n gpu-operator --type merge \
    -p '{"spec": {"devicePlugin": {"config": {"name": "time-slicing-config-all", "default": "any"}}}}'

# 查看修改重启过程
kubectl get events -n gpu-operator --sort-by='.lastTimestamp'
  1. 再次运行 node -oyaml,查看GPU是不是超分配了
  2. 启动pod
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: time-slicing-verification
  labels:
    app: time-slicing-verification
spec:
  replicas: 2
  selector:
    matchLabels:
      app: time-slicing-verification
  template:
    metadata:
      labels:
        app: time-slicing-verification
    spec:
      tolerations:
        - key: nvidia.com/gpu
          operator: Exists
          effect: NoSchedule
      hostPID: true
      containers:
        - name: cuda-sample-vector-add
          image: "nvcr.io/nvidia/k8s/cuda-sample:vectoradd-cuda11.7.1-ubuntu20.04"
          command: ["/bin/bash", "-c", "--"]
          args:
            - while true; do /cuda-samples/vectorAdd; done
          resources:
           limits:
             nvidia.com/gpu: 1

HAMi

官方文档

前置需要安装 GPU Operator

shell

helm repo add hami-charts https://project-hami.github.io/HAMi/

# 注意指定镜像版本
helm install hami hami-charts/hami --set scheduler.kubeScheduler.imageTag=v1.23.6 -n gpu-operator

HAMi WebUI

HAMi WebUI

yaml
kube-prometheus-stack:
  enabled: false

externalPrometheus:
  enabled: true

externalPrometheus:
  address: http://kube-prometheus-kube-prometheus.monitoring.svc.cluster.local:9090
shell
helm repo add hami-webui https://project-hami.github.io/HAMi-WebUI

helm install hami-webui -n gpu-operator  hami-webui/hami-webui -f hami-webui-values.yaml

kubectl port-forward service/hami-webui 3000:3000 --namespace=kube-system

GPU分配问题

  1. 如果您在使用设备插件时不请求 GPU,则插件会在容器内公开机器上的所有 GPU。
  2. 如果想分配GPU使用MIG(Multi-Instance GPU)参考链接:NVIDIA.comCSDN.com
    1. A100 支持最高分配7个
  3. 同一Pod里面,可以有多个容器,多个容器可以共享Pod的资源

kyverno

Kyverno 是一个专为 Kubernetes 设计的 策略引擎(Policy Engine) ,它让你可以用 Kubernetes 原生的 YAML 资源定义安全、合规和配置管理规则 ,而不需要写复杂的代码。

它的定位有点像 Kubernetes 世界里的“守门员”和“自动化修复工”,常见功能包括:

  1. 验证(Validate)
    • 检查 Pod、Deployment 等资源是否符合你的规则,比如镜像必须来自私有仓库、必须加特定标签等。
  2. 变更(Mutate)
    • 自动为资源补充配置,比如自动加 label、加资源限制、加安全上下文。
  3. 生成(Generate)
    • 自动创建额外的 Kubernetes 资源,比如创建命名空间时自动生成 NetworkPolicy、ResourceQuota 等。

常见使用场景

  • 安全合规 :阻止使用 latest tag 的镜像;要求开启 readOnlyRootFilesystem
  • 配置标准化 :自动加标准标签(如 app.kubernetes.io/name)。
  • 多租户隔离 :不同命名空间自动生成隔离网络策略。
  • 资源保护 :确保 Pod 有 CPU 和内存限制。

安装

shell
helm repo add kyverno https://kyverno.github.io/kyverno/
helm repo update
helm install kyverno kyverno/kyverno --namespace kyverno --create-namespace

替换镜像源

如何构建自己的 Helm Chart