4. 第一个Kustomize项目:目录结构设计、编写基础Deployment与Service、创建kustomization.yaml

本章将带领你从零搭建第一个Kustomize项目。我们将聚焦于三个核心动作:设计符合Kustomize惯例的目录结构、编写标准的Kubernetes Deployment与Service资源、创建项目核心的kustomization.yaml文件。完成本章后,你将拥有一个可被Kustomize直接渲染并部署到集群的基础项目骨架。

4.1 标准Kustomize目录结构设计

Kustomize推荐使用基于目录的布局来组织环境与基础配置。一个典型的项目结构遵循“基础(base) + 覆盖(overlays)”模式,确保不同环境(如开发、测试、生产)共享同一份基础资源定义,并通过覆盖层进行差异化调整。

设计原则: 基础目录(base)存放所有环境通用的资源定义;覆盖目录(overlays)按环境名称(dev/staging/prod)创建子目录,每个子目录包含针对该环境的补丁(patches)和配置映射(configMapGenerator)等。

以下是我们第一个项目的推荐目录结构:

my-kustomize-app/
├── base/                    # 基础配置目录
│   ├── deployment.yaml      # Deployment 定义
│   ├── service.yaml         # Service 定义
│   └── kustomization.yaml   # 基础 kustomization
├── overlays/                # 环境覆盖目录
│   ├── dev/                 # 开发环境
│   │   ├── kustomization.yaml
│   │   └── patch-replicas.yaml
│   ├── staging/             # 预发布环境
│   │   ├── kustomization.yaml
│   │   └── patch-resources.yaml
│   └── prod/                # 生产环境
│       ├── kustomization.yaml
│       └── patch-ingress.yaml
└── README.md

目录结构说明:

  • base/:包含所有环境共享的原始YAML资源文件(如Deployment、Service)以及一个kustomization.yaml,用于声明这些资源。
  • overlays/:按环境名称划分子目录。每个子目录拥有独立的kustomization.yaml,通过resources字段引用base目录,并通过patches或images等字段进行定制。
  • README.md:项目说明文档,记录项目用途、环境差异及部署命令。
Kustomize 标准项目目录结构 my-kustomize-app/ base/ overlays/ deployment.yaml service.yaml kustomization.yaml dev/ staging/ prod/ 目录结构说明 base/ 存放通用资源;overlays/ 按环境隔离差异配置。 每个环境目录拥有独立的 kustomization.yaml,通过 resources 引用 base。

4.2 编写基础Deployment与Service

在base/目录下,我们创建两个核心资源文件:deployment.yaml和service.yaml。这些文件使用标准的Kubernetes API,不包含任何环境特定的变量或补丁标记。

4.2.1 创建 Deployment

以下是一个简单的Nginx Deployment示例,它定义了2个副本、容器镜像以及资源限制:

# base/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  labels:
    app: my-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: nginx
        image: nginx:1.25-alpine
        ports:
        - containerPort: 80
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"

4.2.2 创建 Service

Service 将流量路由到上述 Deployment 的 Pod。我们使用 ClusterIP 类型,暴露 80 端口:

# base/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: my-app-service
  labels:
    app: my-app
spec:
  type: ClusterIP
  selector:
    app: my-app
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
关键点: 基础资源中的 metadata.name 和 selector 应保持一致性。Kustomize 的 namePrefix 和 nameSuffix 可以在覆盖层中修改名称,但基础层的标签(labels)通常作为匹配依据,建议保持稳定。

4.3 创建核心文件:kustomization.yaml

kustomization.yaml 是Kustomize项目的入口文件。它告诉Kustomize需要处理哪些资源、应用哪些补丁、生成哪些ConfigMap等。在base/目录下,我们创建一个最简单的kustomization.yaml,仅声明资源列表:

# base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
  - deployment.yaml
  - service.yaml

这个文件的核心字段说明:

字段 说明 示例值
apiVersion Kustomize API版本,固定为 kustomize.config.k8s.io/v1beta1 kustomize.config.k8s.io/v1beta1
kind 资源类型,固定为 Kustomization Kustomization
resources 需要包含的YAML资源文件列表,路径相对于kustomization.yaml所在目录 ["deployment.yaml", "service.yaml"]

4.4 验证项目:使用kubectl kustomize渲染

完成上述文件创建后,你可以使用以下命令验证Kustomize是否正确解析并渲染资源:

# 在项目根目录 my-kustomize-app/ 下执行
kubectl kustomize base/

预期输出将是合并后的完整YAML,包含Deployment和Service两个资源,以---分隔:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: my-app
  name: my-app
spec:
  replicas: 2
  ...
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: my-app
  name: my-app-service
spec:
  ...
常见错误: 如果 kubectl kustomize base/ 报错“no matches for kind”,请检查 kustomization.yaml 中的 apiVersion 和 kind 是否拼写正确,以及 resources 列表中的文件名是否与实际文件完全匹配(包括大小写和扩展名)。

4.5 本章小结

通过本章实践,你已经完成了第一个Kustomize项目的搭建:

  • 设计了符合Kustomize惯例的 base/overlays 目录结构。
  • 编写了标准的 Deployment 和 Service 资源文件。
  • 创建了核心的 kustomization.yaml 文件,并成功使用 kubectl kustomize 命令验证了渲染结果。