Kustomize实战:从0到1实现K8s多环境配置管理与资源部署

Kustomize实战:从0到1实现K8s多环境配置管理与资源部署

在Kubernetes日常运维与开发中,多环境配置复用、差异化管理一直是核心痛点------重复编写资源配置易导致冗余,手动修改配置易引发环境不一致,而Kustomize作为K8s原生内置的配置管理工具,无需模板引擎,通过纯YAML实现「基础配置+环境覆盖」的分层管理,完美解决这一问题。

一、Kustomize核心概念铺垫

  1. Base(基础层):存储所有环境(开发、测试、生产)共用的通用资源配置(如Deployment、Service、通用Secret),一次定义,多环境复用,是配置的「底座」;

  2. Overlay(覆盖层):基于Base层,通过「补丁机制」实现特定环境的差异化配置(如调整副本数、添加环境标签、生成专属配置/密钥),不修改Base原始配置,实现「按需定制」;

  3. 核心优势 :原生集成于kubectl,无需额外安装;纯YAML操作,无学习成本;多环境配置解耦,维护成本大幅降低。

二、环境说明

  • K8s集群版本:1.14+(兼容Kustomize v1beta1)

  • 操作节点:K8s Master节点(或已配置kubectl权限的节点)

  • 目标:搭建Base基础配置,基于Overlay实现开发环境(ml-devops)差异化部署,包含MySQL部署、Service暴露、配置/密钥管理等能力。

三、Step 1:搭建Base基础层,定义通用资源

Base层的核心是定义所有环境共用的基础资源 ,本次实验包含Secret(存储MySQL根密码)、Deployment(MySQL部署)、Service(NodePort暴露服务),并通过kustomization.yaml编排所有资源。

3.1 创建Base目录并编写通用资源

bash 复制代码
# 创建base目录并进入(路径优化,便于后续管理)
mkdir -p /k8s/kustomize-demo/base
cd /k8s/kustomize-demo/base
1. 编写Secret配置(存储MySQL根密码,已base64加密)

新建mysql-secret.yaml,注意:data字段值需为base64加密字符串(本文中MTIzNDU2Nzg5对应明文123456789),添加类型声明增强规范性:

yaml 复制代码
apiVersion: v1
data:
  root-password: MTIzNDU2Nzg5  # base64加密,明文:123456789
kind: Secret
metadata:
  name: mysql-root-secret
type: Opaque  # 通用密钥类型,适用于存储任意敏感信息
2. 编写Deployment配置(MySQL核心部署,3副本通用配置)

新建mysql-deployment.yaml,引用上述Secret中的密码,添加资源限制、端口声明,优化配置健壮性:

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql-deployment
  labels:
    app: mysql
    component: database  # 新增组件标签,便于资源分类
spec:
  replicas: 3  # 通用副本数,多环境可通过补丁修改
  selector:
    matchLabels:
      app: mysql  # 匹配Pod标签,确保Deployment管理正确Pod
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:8.0  # 固定镜像版本,避免版本漂移
        imagePullPolicy: IfNotPresent  # 本地有镜像则不重新拉取,提升部署效率
        ports:
        - containerPort: 3306
          name: mysql-port  # 命名端口,增强可读性
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-root-secret  # 引用Base层定义的Secret
              key: root-password
        resources:
          # 资源限制,避免单个Pod占用过多集群资源
          limits:
            cpu: 1000m  # 最大CPU占用:1核
            memory: 1Gi  # 最大内存占用:1GB
          requests:
            cpu: 500m  # 请求CPU:500毫核
            memory: 512Mi  # 请求内存:512MB
3. 编写Service配置(NodePort暴露,通用端口配置)

新建mysql-service.yaml,通过NodePort类型暴露MySQL服务,端口选择30000-32767范围内的可用端口:

yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  name: mysql-nodeport-service
  labels:
    app: mysql
spec:
  type: NodePort  # 节点端口类型,便于集群外部访问
  selector:
    app: mysql  # 匹配MySQL Pod标签,实现流量转发
  ports:
  - protocol: TCP
    port: 3306        # Service内部端口,集群内可通过该端口访问
    targetPort: 3306  # 容器端口,与MySQL容器暴露端口一致
    nodePort: 30306   # 集群节点端口(固定,便于外部访问,需确保未被占用)

3.2 编写Base层kustomization.yaml,编排所有通用资源

新建kustomization.yaml(Kustomize核心配置文件,必选),声明API版本并引用上述所有资源,作为基础配置的入口:

yaml 复制代码
apiVersion: kustomize.config.k8s.io/v1beta1  # 稳定版API,兼容性最广
kind: Kustomization
metadata:
  name: mysql-base-config  # Base层配置名称,便于识别
# 引用Base层所有通用资源,Kustomize会自动解析这些YAML文件
resources:
- mysql-secret.yaml
- mysql-deployment.yaml
- mysql-service.yaml

3.3 验证Base层目录结构

安装tree工具并查看目录结构,确保所有配置文件正确放置,避免路径错误:

bash 复制代码
# 安装tree(Debian/Ubuntu系列,CentOS可使用yum install tree)
apt update && apt install tree -y
# 查看当前目录(Base层)结构
tree .

预期输出(确保目录结构与以下一致):

text 复制代码
.
├── kustomization.yaml
├── mysql-deployment.yaml
├── mysql-secret.yaml
└── mysql-service.yaml

0 directories, 4 files

至此,Base层通用配置搭建完成,所有环境均可直接引用该层配置,无需重复编写通用资源。

四、Step 2:搭建Overlay覆盖层,实现开发环境差异化配置

基于Base层,我们在overlays/development目录下搭建开发环境的专属配置,核心实现:

  1. 指定开发环境专属命名空间ml-devops,实现环境隔离;

  2. 通过策略合并补丁将MySQL副本数从3改为4(开发环境需更多测试实例);

  3. 通过JSON 6902补丁为Pod添加开发环境专属标签;

  4. 生成开发环境专属ConfigMap(存储配置参数)和Secret(存储专属密钥);

  5. 为所有资源添加通用环境标签env: dev

  6. 引用Base层配置,实现配置复用。

4.1 创建Overlay开发环境目录

回到上级目录,递归创建Overlay开发环境目录,路径与Base层对应,便于管理:

bash 复制代码
# 回到kustomize-demo根目录
cd /k8s/kustomize-demo
# 递归创建overlay开发环境目录(overlays/development)
mkdir -p overlays/development
# 进入开发环境Overlay目录
cd overlays/development

4.2 编写开发环境核心配置:kustomization.yaml

新建kustomization.yaml,这是Overlay层的核心,集成「资源引用、补丁修改、配置/密钥生成、环境隔离」等所有能力,代码优化后注释清晰,便于后续维护:

yaml 复制代码
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
# 开发环境专属命名空间,实现与测试/生产环境的资源隔离,避免冲突
namespace: ml-devops
# 引用Base层基础配置(相对路径,../../base指向上级目录的base文件夹)
resources:
- ../../base
# 为所有资源添加通用标签,方便按环境、版本筛选资源,便于运维管理
commonLabels:
  env: dev  # 环境标签:开发环境
  version: v1.0  # 版本标签,便于版本追溯
  project: ml-devops  # 项目标签,关联项目归属
# 生成器配置:关闭ConfigMap/Secret名称的哈希后缀(默认开启,关闭后便于记忆和引用)
generatorOptions:
  disableNameSuffixHash: true
# 补丁列表:修改Base层的Deployment配置,实现开发环境差异化
patches:
  # 补丁1:策略合并补丁(Strategic Merge)
  # 适用场景:简单字段修改(如副本数、镜像版本、标签等),无需完整资源结构
  - path: deploy-strategic-merge-patch.yaml
    target:
      # 指定补丁作用的目标资源:Base层的mysql-deployment(Deployment类型)
      kind: Deployment
      name: mysql-deployment
    options:
      allowNameChange: false  # 不允许修改资源名称,保证Base与Overlay资源名称一致
  # 补丁2:JSON 6902补丁
  # 适用场景:复杂嵌套字段操作(如添加/删除标签、修改嵌套配置等)
  - path: deploy-json6902-patch.yaml
    target:
      kind: Deployment
      name: mysql-deployment
    options:
      allowNameChange: false
# 生成开发环境专属ConfigMap(两种方式:文件式、字面量式,按需选择)
configMapGenerator:
- name: dev-mysql-config
  files:
    - config/mysql-config.properties  # 从文件加载MySQL配置,便于批量修改
- name: dev-env-config
  literals:  # 直接写字面量配置,适用于简单键值对
    - MYSQL_DATABASE=ml_dev_db  # 开发环境专属数据库名称
    - MYSQL_CHARSET=utf8mb4     # 数据库字符集
    - MYSQL_COLLATION=utf8mb4_unicode_ci  # 数据库排序规则
# 生成开发环境专属Secret(两种方式:文件式、字面量式,存储敏感信息)
secretGenerator:
- name: dev-mysql-account
  files:
    - secret/account-info.yaml  # 从文件加载业务账号密码,便于维护
  type: Opaque
- name: dev-api-secret
  literals:  # 直接写字面量密钥,适用于简单敏感信息
    - api_key=dev_8s9f7d6a5b4c3e2f1
    - token=dev_mlops_2025_token
  type: Opaque

4.3 编写补丁文件,实现Deployment差异化修改

根据上述kustomization.yaml的配置,编写两个补丁文件,分别实现副本数调整和标签添加。

1. 策略合并补丁(deploy-strategic-merge-patch.yaml)

适合简单字段修改,只需编写要修改的字段,无需完整资源结构,本次将副本数从3改为4:

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql-deployment  # 必须与Base层Deployment名称一致,否则无法匹配
spec:
  replicas: 4  # 开发环境副本数调整为4,满足测试需求
2. JSON 6902补丁(deploy-json6902-patch.yaml)

适合复杂嵌套字段操作,通过op指定操作类型(add/delete/replace),path指定字段路径,value指定值:

json 复制代码
[
  {
    "op": "add",  # 操作类型:添加字段
    "path": "/spec/template/metadata/labels/dev",  # 字段路径:Pod标签下添加dev键
    "value": "release-v1.0"  # 标签值:开发环境版本标识
  },
  {
    "op": "add",
    "path": "/spec/template/metadata/labels/team",
    "value": "ml-dev-team"  # 新增团队标签,便于团队归属管理
  }
]

4.4 编写ConfigMap和Secret的配套文件

根据kustomization.yaml中的配置,创建对应的配置文件和密钥文件目录及内容,确保路径一致:

bash 复制代码
# 创建config(存储ConfigMap配套文件)和secret(存储Secret配套文件)目录
mkdir -p config secret
1. ConfigMap配套文件:config/mysql-config.properties

存储开发环境MySQL专属配置参数,便于集中管理和修改:

properties 复制代码
# 开发环境MySQL专属配置(优化数据库性能,适配开发场景)
mysql_max_connections=100  # 最大连接数,开发环境无需过高
mysql_wait_timeout=86400   # 连接超时时间(24小时)
mysql_interactive_timeout=86400  # 交互式连接超时时间
mysql_query_cache_size=0   # 关闭查询缓存,适配MySQL 8.0+版本
character_set_server=utf8mb4  # 服务器字符集
collation_server=utf8mb4_unicode_ci  # 服务器排序规则
2. Secret配套文件:secret/account-info.yaml

存储开发环境MySQL业务账号密码,敏感信息单独存放,便于维护:

yaml 复制代码
# 开发环境MySQL业务账号(非root账号,降低权限风险)
app_user=ml_dev_user  # 业务账号名称
app_password=dev_ml@2025  # 业务账号密码,复杂度适中,适配开发环境

4.5 验证Overlay开发环境目录结构

执行tree命令,查看Overlay开发环境目录结构,确保所有文件正确放置:

bash 复制代码
tree .

预期输出

text 复制代码
.
├── config
│   └── mysql-config.properties
├── deploy-json6902-patch.yaml
├── deploy-strategic-merge-patch.yaml
├── kustomization.yaml
└── secret
    └── account-info.yaml

2 directories, 6 files

4.6 预览Overlay配置效果(关键步骤)

在部署到集群前,通过kubectl kustomize预览最终生成的K8s资源清单,验证配置是否正确,避免部署出错(核心校验:副本数、标签、命名空间等):

bash 复制代码
kubectl kustomize ./

预览说明:命令会自动合并Base层配置与Overlay层的补丁、配置/密钥生成规则,输出最终的YAML资源清单。可重点检查以下内容:

  • Deployment副本数是否为4;

  • Pod标签是否包含env: devdev: release-v1.0等;

  • 命名空间是否为ml-devops

  • ConfigMap/Secret是否包含开发环境专属配置。

五、Step 3:部署到K8s集群并验证所有资源

完成配置预览且确认无误后,开始将配置部署到K8s集群,并通过kubectl命令逐步验证所有资源的创建状态,确保部署成功。

5.1 创建开发环境专属命名空间

先创建开发环境专属命名空间ml-devops,实现环境隔离,避免与其他环境资源冲突:

bash 复制代码
kubectl create namespace ml-devops

预期输出namespace/ml-devops created

5.2 基于Kustomize部署所有资源

使用kubectl apply -k .命令,Kustomize会自动合并Base和Overlay层配置,一次性部署所有资源到指定命名空间(ml-devops),无需手动逐个部署YAML文件:

bash 复制代码
kubectl apply -k .

预期输出(所有资源创建成功):

text 复制代码
configmap/dev-env-config created
configmap/dev-mysql-config created
secret/dev-api-secret created
secret/dev-mysql-account created
secret/mysql-root-secret created
service/mysql-nodeport-service created
deployment.apps/mysql-deployment created

5.3 验证所有资源部署状态

部署完成后,通过以下kubectl命令,逐步验证所有资源的状态,确保符合预期。所有命令均指定命名空间ml-devops,避免查询到其他环境资源。

1. 验证ConfigMap(开发环境专属)

查看开发环境下所有ConfigMap,确认两个专属ConfigMap均已创建:

bash 复制代码
kubectl get configmaps -n ml-devops

预期输出(包含dev-env-config、dev-mysql-config):

text 复制代码
NAME                DATA   AGE
dev-env-config      3      1m
dev-mysql-config    5      1m
2. 验证Secret(通用+开发环境专属)

查看开发环境下所有Secret,确认Base层的通用Secret和Overlay层的专属Secret均已创建:

bash 复制代码
kubectl get secrets -n ml-devops

预期输出(包含mysql-root-secret、dev-mysql-account、dev-api-secret):

text 复制代码
NAME                  TYPE     DATA   AGE
dev-api-secret        Opaque   2      1m
dev-mysql-account     Opaque   2      1m
mysql-root-secret     Opaque   1      1m
3. 验证Service(NodePort暴露)

查看开发环境下的Service,确认NodePort服务已创建,端口与配置一致(nodePort: 30306):

bash 复制代码
kubectl get service -n ml-devops

预期输出

text 复制代码
NAME                     TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
mysql-nodeport-service   NodePort   10.96.xxx.xxx   <none>        3306:30306/TCP   1m
4. 验证Deployment(副本数是否为4)

查看开发环境下的Deployment,确认副本数已通过补丁修改为4,且就绪副本数与总副本数一致:

bash 复制代码
kubectl get deployments.apps -n ml-devops

预期输出(replicas: 4,READY: 4/4):

text 复制代码
NAME                READY   UP-TO-DATE   AVAILABLE   AGE
mysql-deployment    4/4     4            4           1m
5. 验证Pod(是否正常运行、标签是否正确)

查看开发环境下的Pod,确认所有Pod均为Running状态,且包含开发环境专属标签:

bash 复制代码
kubectl get pods --show-labels -n ml-devops

关键验证点

  • Pod状态均为Running,数量为4个(与Deployment副本数一致);

  • Labels列包含env=devdev=release-v1.0team=ml-dev-teamapp=mysql等标签;

  • Pod名称以mysql-deployment-xxx开头,与Deployment名称一致。

6. 验证MySQL服务可访问性(可选,确保服务正常可用)

通过kubectl exec进入Pod,验证MySQL服务是否正常启动,可正常登录:

bash 复制代码
# 替换<pod-name>为上述命令查询到的任意Pod名称(如mysql-deployment-7f89dxxx)
# 替换<node-ip>为你的K8s节点IP(Master或Worker节点均可)
kubectl exec -it <pod-name> -n ml-devops -- mysql -h <node-ip> -P 30306 -u root -p

执行命令后,输入Base层配置的MySQL根密码123456789,若能成功进入MySQL命令行(如下所示),说明服务部署正常:

text 复制代码
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.xx MySQL Community Server - GPL

Copyright (c) 2000, 2025, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>
相关推荐
张小凡vip7 小时前
Kubernetes--k8s中部署redis数据库服务
redis·kubernetes
Hello.Reader8 小时前
Flink Kubernetes HA(高可用)实战原理、前置条件、配置项与数据保留机制
贪心算法·flink·kubernetes
ShiLiu_mtx9 小时前
k8s - 7
云原生·容器·kubernetes
MonkeyKing_sunyuhua12 小时前
docker compose up -d --build 完全使用新代码打包的方法
docker·容器·eureka
醇氧13 小时前
【docker】mysql 8 的健康检查(Health Check)
mysql·docker·容器
匀泪16 小时前
云原生(LVS NAT模式集群实验)
服务器·云原生·lvs
70asunflower16 小时前
用Docker创建不同的容器类型
运维·docker·容器
CodeGolang17 小时前
Docker容器化部署Zabbix监控系统完整指南
docker·容器·zabbix
DolitD17 小时前
云流技术深度剖析:国内云渲染主流技术与开源和海外厂商技术实测对比
功能测试·云原生·开源·云计算·实时云渲染