Helm 部署 K8s 集群完整笔记

Helm 部署 K8s 集群完整笔记

一、整体架构图

plain

复制代码
┌─────────────────────────────────────────────────────────────────┐
│                         用户层                                   │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────────┐  │
│  │  Docker CLI │  │  kubectl    │  │  helm                   │  │
│  │  (构建镜像)  │  │  (管理K8s)  │  │  (包管理器)              │  │
│  └──────┬──────┘  └──────┬──────┘  └───────────┬─────────────┘  │
└─────────┼────────────────┼─────────────────────┼────────────────┘
          │                │                     │
          ▼                ▼                     ▼
┌─────────────────────────────────────────────────────────────────┐
│                      minikube 层                                 │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │              Docker Desktop (宿主机)                      │    │
│  │  ┌─────────────────────────────────────────────────────┐  │    │
│  │  │           minikube 容器 (K8s 控制平面)                │  │    │
│  │  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  │  │    │
│  │  │  │  kube-apiserver │  │  kube-scheduler │  │  kube-controller │  │  │    │
│  │  │  └─────────────┘  └─────────────┘  └─────────────┘  │  │    │
│  │  │  ┌─────────────┐  ┌─────────────┐                    │  │    │
│  │  │  │  etcd (数据库) │  │  kubelet      │                    │  │    │
│  │  │  └─────────────┘  └─────────────┘                    │  │    │
│  │  └─────────────────────────────────────────────────────┘  │    │
│  └─────────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────────┘
          │
          ▼
┌─────────────────────────────────────────────────────────────────┐
│                      应用层 (Pod)                                │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────────┐  │
│  │ camp-auth   │  │ camp-web    │  │ camp-backend            │  │
│  │ (Nginx)     │  │ (Nginx)     │  │ (FastAPI + SQLite)      │  │
│  └─────────────┘  └─────────────┘  └─────────────────────────┘  │
└─────────────────────────────────────────────────────────────────┘

二、文件结构与调用关系

2.1 项目目录结构

plain

复制代码
kubernetes-microservices/
│
├── docker-compose.yml              # Docker Compose 配置(本地开发)
├── docker-compose.ghcr.yml         # 使用预构建镜像的 Compose 配置
│
├── helm/                           # Helm Chart 目录
│   ├── deploy-helm.sh              # Helm 部署脚本(Shell)
│   ├── values-dev.yaml             # 开发环境配置
│   ├── values-prod.yaml            # 生产环境配置
│   ├── values-local.yaml           # 本地自定义配置(我们创建的)
│   │
│   └── camp/                       # Helm Chart 包
│       ├── Chart.yaml              # Chart 元数据(名称、版本、依赖)
│       ├── values.yaml             # 默认配置值
│       │
│       └── templates/              # K8s 资源模板目录
│           ├── _helpers.tpl        # 辅助模板函数(镜像名、标签生成)
│           ├── deployment.yaml     # Deployment 资源模板
│           ├── service.yaml        # Service 资源模板
│           ├── ingress.yaml        # Ingress 资源模板
│           ├── configmap.yaml      # ConfigMap 资源模板
│           ├── secret.yaml         # Secret 资源模板
│           ├── pvc.yaml            # PVC 资源模板
│           ├── hpa.yaml            # HPA 资源模板
│           ├── resourcequota.yaml  # ResourceQuota 资源模板
│           ├── networkpolicy.yaml  # NetworkPolicy 资源模板
│           ├── monitoring.yaml     # 监控资源模板
│           ├── serviceaccount.yaml # ServiceAccount 资源模板
│           └── notes.txt           # 部署后提示信息
│
├── k8s/                            # 原生 K8s YAML(手动部署用)
│   ├── deploy.sh                   # AKS 部署脚本
│   ├── cleanup.sh                  # AKS 清理脚本
│   ├── namespace.yaml
│   ├── configmap.yaml
│   ├── secret.yaml
│   ├── persistent-volumes.yaml
│   ├── backend-deployment.yaml
│   ├── web-frontend-deployment.yaml
│   ├── auth-frontend-deployment.yaml
│   ├── ingress.yaml
│   ├── horizontal-pod-autoscaler.yaml
│   ├── resource-quota.yaml
│   ├── network-policy.yaml
│   ├── monitoring.yaml
│   └── kustomization.yaml          # Kustomize 配置
│
└── .github/workflows/              # CI/CD
    └── build-and-deploy.yml        # GitHub Actions 工作流

2.2 Helm 文件调用关系

plain

复制代码
values-local.yaml (用户自定义配置)
        │
        ▼
┌─────────────────┐
│  helm install   │ ──► 读取 Chart.yaml(Chart 元数据)
│  helm upgrade   │
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│  values.yaml    │ ──► 默认值(被 values-local.yaml 覆盖)
│  (默认值)        │
└────────┬────────┘
         │
         ▼
┌─────────────────────────────────────────┐
│           templates/ 目录                │
│  ┌─────────────────────────────────────┐ │
│  │  _helpers.tpl                       │ │
│  │  ├─ camp.fullname                   │ │
│  │  ├─ camp.backend.image             │ │
│  │  ├─ camp.web.image                 │ │
│  │  └─ camp.auth.image                │ │
│  └─────────────────────────────────────┘ │
│              │                          │
│              ▼                          │
│  ┌─────────────────────────────────────┐ │
│  │  deployment.yaml                    │ │
│  │  ├─ 引用 _helpers.tpl 中的函数       │ │
│  │  ├─ 引用 .Values.backend.resources  │ │
│  │  └─ 引用 .Values.config.databaseUrl  │ │
│  └─────────────────────────────────────┘ │
│  ┌─────────────────────────────────────┐ │
│  │  service.yaml                       │ │
│  │  ├─ 引用 .Values.backend.service    │ │
│  │  └─ 引用 selectorLabels             │ │
│  └─────────────────────────────────────┘ │
│  ┌─────────────────────────────────────┐ │
│  │  configmap.yaml                     │ │
│  │  └─ 引用 .Values.config.*           │ │
│  └─────────────────────────────────────┘ │
│  ┌─────────────────────────────────────┐ │
│  │  secret.yaml                        │ │
│  │  └─ 引用 .Values.secrets.*          │ │
│  └─────────────────────────────────────┘ │
│  ┌─────────────────────────────────────┐ │
│  │  ... 其他模板文件                    │ │
│  └─────────────────────────────────────┘ │
└─────────────────────────────────────────┘
         │
         ▼
┌─────────────────┐
│  渲染后的 YAML   │ ──► 提交给 kubectl → kube-apiserver
│  (K8s 资源清单)  │
└─────────────────┘

2.3 关键文件详解

Chart.yaml --- Chart 元数据

yaml

复制代码
apiVersion: v2           # Helm 3 使用 v2
name: camp               # Chart 名称
description: CAMP Helm Chart
type: application        # 应用类型(application/library)
version: 0.1.0           # Chart 版本
appVersion: "1.0"        # 应用版本
values.yaml --- 默认值

yaml

复制代码
# 全局配置
global:
  imageRegistry: ""

# 镜像配置
image:
  registry: docker.io
  repository: nginx
  pullPolicy: IfNotPresent
  tag: ""

# 副本数
replicaCount:
  backend: 2
  web: 2
  auth: 2

# 后端配置
backend:
  name: backend
  service:
    port: 8000
    targetPort: 8000
  resources:
    limits:
      cpu: 500m
      memory: 512Mi
    requests:
      cpu: 250m
      memory: 256Mi
  livenessProbe:
    httpGet:
      path: /test
      port: http
  readinessProbe:
    httpGet:
      path: /health
      port: http
  autoscaling:
    enabled: false
  persistence:
    uploads:
      enabled: true
      storageClass: ""
      accessMode: ReadWriteOnce
      size: 1Gi
      mountPath: /app/uploads
    database:
      enabled: true
      storageClass: ""
      accessMode: ReadWriteOnce
      size: 1Gi
      mountPath: /app/camp.db
      subPath: camp.db

# 前端配置(web/auth 类似)
web:
  name: web
  service:
    port: 80
    targetPort: 80
  resources:
    limits:
      cpu: 200m
      memory: 256Mi
    requests:
      cpu: 100m
      memory: 128Mi

# 应用配置
config:
  databaseUrl: "sqlite:///app/camp.db"
  debug: false
  logLevel: info

# 密钥
secrets:
  secretKey: ""
  jwtSecret: ""
  defaultPassword: "admin123"

# 安全上下文
securityContext:
  capabilities:
    drop:
    - ALL
  readOnlyRootFilesystem: true
  runAsNonRoot: true
  runAsUser: 1000

podSecurityContext:
  fsGroup: 2000

# 资源配额
resourceQuota:
  enabled: true

# 网络策略
networkPolicy:
  enabled: true

# 监控
monitoring:
  enabled: false
_helpers.tpl --- 辅助函数

yaml

复制代码
{{/*
生成完整名称
*/}}
{{- define "camp.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}

{{/*
生成后端镜像名
*/}}
{{- define "camp.backend.image" -}}
{{- $registry := .Values.global.imageRegistry | default .Values.image.registry }}
{{- $repository := .Values.backend.image.repository }}
{{- $tag := .Values.image.tag | default .Chart.AppVersion }}
{{- printf "%s/%s:%s" $registry $repository $tag }}
{{- end }}

三、工具链调用关系

3.1 完整工具链

plain

复制代码
用户操作
    │
    ├─► docker build ──► 本地镜像
    │       │
    │       ▼
    │   docker images
    │       │
    │       ▼
    │   minikube image load ──► 加载到 minikube
    │       │
    │       ▼
    └─► helm install/upgrade ──► 渲染模板
            │
            ├─► 读取 values.yaml
            ├─► 读取 values-local.yaml(覆盖)
            ├─► 渲染 templates/*.yaml
            │       │
            │       ├─► _helpers.tpl(函数调用)
            │       ├─► deployment.yaml
            │       ├─► service.yaml
            │       └─► ...
            │
            ▼
        kubectl apply ──► 提交到 kube-apiserver
                │
                ▼
            kube-apiserver ──► 写入 etcd
                │
                ├─► kube-scheduler ──► 选择节点
                │
                ▼
            kubelet ──► 创建 Pod
                │
                ▼
            containerd/docker ──► 拉取/运行镜像

3.2 各工具职责

Table

工具 职责 类比
Docker 构建、管理容器镜像 工厂(生产产品)
minikube 本地运行 K8s 集群 迷你数据中心
kubectl 与 K8s 集群交互 遥控器
helm K8s 包管理器 apt/yum(软件包管理)
kube-apiserver K8s 控制平面入口 前台接待
kube-scheduler 调度 Pod 到节点 调度员
kubelet 节点上的代理 车间主任
etcd K8s 数据存储 数据库

四、部署流程详解

4.1 标准部署流程

powershell

复制代码
# 1. 启动 minikube
minikube start --driver=docker --memory=4096 --cpus=2

# 2. 构建/准备镜像
docker compose build

# 3. 加载镜像到 minikube
minikube image load <image-name>

# 4. 创建命名空间
kubectl create namespace camp

# 5. Helm 部署
helm upgrade --install camp ./camp --values values-local.yaml -n camp

# 6. 验证
kubectl get pods -n camp
helm status camp -n camp

# 7. 端口转发访问
kubectl port-forward svc/camp-auth-service 3000:80 -n camp

4.2 配置覆盖优先级

plain

复制代码
values.yaml (最低优先级)
    │
    ▼
values-dev.yaml / values-prod.yaml
    │
    ▼
values-local.yaml (最高优先级)
    │
    ▼
--set 命令行参数 (临时最高)

五、所有错误及解决方案

5.1 Helm 安装问题

Table

错误 原因 解决
helm : 无法将"helm"项识别 Helm 未安装或未加入 PATH 下载安装并添加到 PATH,或使用完整路径 C:\tools\helm\windows-amd64\helm.exe

5.2 Chart 语法错误

Table

错误 原因 解决
unexpected <.> in operand 动态 key 语法不支持 $.Values.(.service).service.port 改为固定值 number: 80
undefined variable "$Values" 变量名错误,应为 $.Values 修改为 $.Values
failed to find unique target for patch patch 未指定 namespace 添加 namespace: camp
yaml: line 27: mapping values are not allowed YAML 缩进错误 检查空格/Tab 混用,确保正确缩进

5.3 模板渲染错误

Table

错误 原因 解决
nil pointer evaluating interface {}.Namespace 循环内部 . 上下文改变 使用 $ 引用根上下文:$.Release.Namespace
error converting YAML to JSON 模板渲染后 YAML 格式错误 检查条件渲染的缩进和结构
duplicate "Container" type LimitRange 中重复定义 合并为单个 type: Container

5.4 镜像问题

Table

错误 原因 解决
ImagePullBackOff 镜像不存在或无法拉取 确认镜像名正确,使用 minikube image load 加载本地镜像
ErrImagePull 镜像拉取失败 检查网络、镜像仓库权限
ErrImageNeverPull imagePullPolicy: Never 但镜像不存在 确保镜像已加载到 minikube
镜像名重复路径 _helpers.tplprintf 格式错误 修复为 printf "%s/%s:%s" $registry $repository $tag

5.5 运行时错误

Table

错误 原因 解决
mkdir() failed (13: Permission denied) Nginx 无写入权限 禁用 securityContext:securityContext: null
sqlite3.OperationalError: unable to open database file 数据库路径错误或权限不足 使用默认路径 sqlite:///app/camp.db,禁用 PVC
container's runAsUser breaks non-root policy securityContext 冲突 完全禁用 securityContext 和 podSecurityContext
CreateContainerConfigError 容器配置错误 检查 securityContext、镜像名、环境变量
CrashLoopBackOff 应用启动失败 查看日志 kubectl logs,检查健康检查路径
Pending 资源不足或 PVC 未绑定 检查节点资源、StorageClass、PVC 状态

5.6 存储问题

Table

错误 原因 解决
storageclass.storage.k8s.io "default" not found StorageClass 不存在 创建 default StorageClass 或使用 standard
pod has unbound immediate PersistentVolumeClaims PVC 未绑定 检查 StorageClass、手动创建 PV、或禁用 PVC
not a directory: Are you trying to mount a directory onto a file subPath 挂载文件到目录 去掉 subPath,改为挂载目录

六、关键配置文件

6.1 最终可用的 values-local.yaml

yaml

复制代码
# ============================================
# Helm Values - 本地 minikube 部署配置
# ============================================

# 全局配置
global:
  imageRegistry: ghcr.io

# 镜像配置
image:
  registry: ghcr.io
  repository: kubernetes-microservices    # 镜像仓库路径
  pullPolicy: Never                      # 使用本地镜像,不拉取
  tag: "latest"

# 副本数配置
replicaCount:
  backend: 2
  web: 2
  auth: 2

# Ingress 配置
ingress:
  enabled: false                         # 禁用 Ingress(本地用端口转发)

# 后端服务配置
backend:
  name: backend
  service:
    port: 8000
    targetPort: 8000
  resources:
    limits:
      cpu: 500m
      memory: 512Mi
    requests:
      cpu: 250m
      memory: 256Mi
  livenessProbe:
    httpGet:
      path: /test
      port: http
  readinessProbe:
    httpGet:
      path: /health
      port: http
  autoscaling:
    enabled: false                       # 禁用 HPA(需要 Metrics Server)
  persistence:
    uploads:
      enabled: false                     # 禁用 PVC,使用 emptyDir
    database:
      enabled: false                     # 禁用 PVC,使用 emptyDir

# Web 前端配置
web:
  name: web
  service:
    port: 80
    targetPort: 80
  resources:
    limits:
      cpu: 200m
      memory: 256Mi
    requests:
      cpu: 100m
      memory: 128Mi
  livenessProbe:
    httpGet:
      path: /
      port: http
  readinessProbe:
    httpGet:
      path: /
      port: http
  autoscaling:
    enabled: false

# Auth 前端配置
auth:
  name: auth
  service:
    port: 80
    targetPort: 80
  resources:
    limits:
      cpu: 200m
      memory: 256Mi
    requests:
      cpu: 100m
      memory: 128Mi
  livenessProbe:
    httpGet:
      path: /
      port: http
  readinessProbe:
    httpGet:
      path: /
      port: http
  autoscaling:
    enabled: false

# 应用配置
config:
  databaseUrl: "sqlite:///app/camp.db"    # 默认数据库路径
  debug: true
  logLevel: info
  apiV1Prefix: "/api/v1"
  appName: "Cloud Asset Management Platform"
  appVersion: "1.0.0"
  storageType: local
  localStoragePath: "/app/uploads"
  maxFileSize: "52428800"
  corsOrigins: "http://localhost:3004,http://localhost:3000"
  pythonUnbuffered: "1"
  pythonpath: "/app"

# 密钥配置
secrets:
  secretKey: "dev-secret-key"
  jwtSecret: "dev-jwt-secret"
  defaultPassword: "admin123"

# 安全上下文(本地学习禁用)
securityContext: null
podSecurityContext: null

# 资源配额
resourceQuota:
  enabled: false

# 限制范围
limitRange:
  enabled: false

# 网络策略
networkPolicy:
  enabled: false

# 监控
monitoring:
  enabled: false

# 节点选择
nodeSelector: {}

# 容忍
tolerations: []

# 亲和性
affinity: {}

七、常用命令速查

7.1 minikube 管理

bash

复制代码
# 启动
minikube start --driver=docker --memory=4096 --cpus=2

# 停止
minikube stop

# 删除
minikube delete

# 查看状态
minikube status

# 获取 IP
minikube ip

# 加载镜像
minikube image load <image-name>

# 查看 minikube 中的镜像
minikube ssh -- docker images

# 启用插件
minikube addons enable ingress
minikube addons enable metrics-server
minikube addons enable storage-provisioner

7.2 Helm 管理

bash

复制代码
# 安装/升级
helm upgrade --install <release-name> ./<chart-path> --values <values-file> -n <namespace>

# 卸载
helm uninstall <release-name> -n <namespace>

# 查看状态
helm status <release-name> -n <namespace>

# 查看历史
helm history <release-name> -n <namespace>

# 回滚
helm rollback <release-name> <revision> -n <namespace>

# 预览渲染
helm template <release-name> ./<chart-path> --values <values-file>

# 检查语法
helm lint ./<chart-path>

7.3 kubectl 管理

bash

复制代码
# 查看资源
kubectl get pods -n <namespace>
kubectl get deployment -n <namespace>
kubectl get svc -n <namespace>
kubectl get pvc -n <namespace>
kubectl get hpa -n <namespace>
kubectl get all -n <namespace>

# 查看详情
kubectl describe pod <pod-name> -n <namespace>
kubectl describe deployment <deployment-name> -n <namespace>

# 查看日志
kubectl logs <pod-name> -n <namespace>
kubectl logs -f deployment/<deployment-name> -n <namespace>

# 进入容器
kubectl exec -it <pod-name> -n <namespace> -- sh

# 端口转发
kubectl port-forward svc/<service-name> <local-port>:<service-port> -n <namespace>

# 扩缩容
kubectl scale deployment <deployment-name> --replicas=<count> -n <namespace>

# 删除资源
kubectl delete pod <pod-name> -n <namespace>
kubectl delete deployment <deployment-name> -n <namespace>
kubectl delete namespace <namespace>

八、学习路径建议

plain

复制代码
第一阶段:Docker 基础
    ├─ Docker 镜像构建
    ├─ Docker Compose 编排
    └─ 容器网络与存储

第二阶段:K8s 核心概念
    ├─ Pod、Deployment、Service
    ├─ ConfigMap、Secret
    ├─ PVC、StorageClass
    └─ Ingress、HPA

第三阶段:Helm 包管理
    ├─ Chart 结构与模板语法
    ├─ Values 配置与覆盖
    ├─ 模板函数与管道
    └─ Helm 安装、升级、回滚

第四阶段:生产级部署
    ├─ GitOps (ArgoCD/Flux)
    ├─ CI/CD (GitHub Actions/GitLab CI)
    ├─ 多集群管理
    └─ 监控与告警 (Prometheus/Grafana)
相关推荐
海清河晏1111 小时前
Qt实战:从零构建美化登录界面
开发语言·c++·qt
祐樹1 小时前
1987年5月23日下午15-17点出生性格、运势和命运
java
zhangjw341 小时前
第35篇:Spring Boot入门:自动配置+快速搭建,简化企业开发
java·spring boot·后端
一只小灿灿1 小时前
C++ 各类特殊符号、运算符
开发语言·c++
Fu_Lin_1 小时前
《Qt嵌入式从零基础到精通》前言与阅读指南
开发语言·qt
名字还没想好☜1 小时前
Go 的 select 实战:超时、非阻塞收发与优雅退出的三个套路
开发语言·数据库·golang·go·并发
geovindu1 小时前
java: Backtracking Algorithm
java·开发语言·windows·后端·算法·回溯算法
NWU_LK1 小时前
【WebFlux】第六篇 —— 全链路响应式与数据库交互
java·数据库
一只小菜鸡..1 小时前
南京大学 操作系统 (JYY) 学习笔记:Hello, OS World! (程序的机器视角)
java·笔记·学习