【Kubernetes 企业项目实战】10、掌握 Kubernetes Kustomize 技术从入门到企业实战(上)

目录

一、Kustomize 概述

1.1 Kustomize 简介 

1.2 Kustomize 与 Helm 技术详细对比

1.2.1 区别

1.2.2 优缺点

1.2.3 适用场景

1.3 总结

二、Kustomize 入门

2.1 安装 Kustomize

2.2 Kustomize 项目目录结构及介绍

2.2.1 Kustomize 基本概念

2.2.2 personal-web 项目结构详细介绍

2.3 创建基础资源

2.3.1 deploy.yaml 

2.3.2 service.yaml

2.3.3 ingress.yaml

2.4 创建 kustomization.yaml

2.5 生成定制资源


一、Kustomize 概述

1.1 Kustomize 简介 

        Kustomize 是一款 Kubernetes 原生的配置管理工具,其核心理念是允许用户自定义 Kubernetes 资源配置,而无需直接修改原始的 YAML 文件。这在很大程度上提高了配置的可维护性和可重用性。Kustomize 使用声明式的方式来定制资源,通过一系列预定义的指令和规则,用户可以对基础资源进行修改、添加或删除。Kustomize 与其他模板技术相比,具有以下优势:

  1. 易于理解:Kustomize 使用简单的 YAML 语法,与 Kubernetes 资源本身的定义方式保持一致,易于学习和理解。

  2. 原子性:Kustomize 的覆盖策略允许用户精确地修改特定部分的配置,而不会影响其他部分。这样可以确保修改的原子性,避免出现意外的副作用。

  3. 可组合性:Kustomize 支持将多个覆盖层叠加在一起,从而形成一个完整的定制资源。这使得用户可以在多个环境和场景之间复用同一套基础配置,降低了维护成本。

  4. 集成 Kubernetes:Kustomize 自 Kubernetes v1.14 起已经被集成在 kubectl 中,用户无需安装额外的工具即可使用 Kustomize。

        总之,Kustomize 提供了一种更为灵活且高效的方式来管理 Kubernetes 资源配置。通过使用 Kustomize,开发者和运维人员可以轻松地为不同环境和场景创建定制的配置,提高了工作效率和配置的可维护性。

Kustomize 官方文档:配置定制(Bespoke configuration) | SIG CLI 

Kustomize 在 k8s 中的介绍:使用 Kustomize 对 Kubernetes 对象进行声明式管理 | Kubernetes 

1.2 Kustomize 与 Helm 技术详细对比

        Kustomize 和 Helm 都是 Kubernetes 生态中流行的配置管理工具,虽然它们有许多相似之处,但在实现方式和适用场景上有所不同。接下来,我们将从区别、优缺点和适用场景等方面详细对比 Kustomize 和 Helm。

Helm 的教程:【Kubernetes 企业项目实战】08、简化 K8s 应用部署工具 Helm V3 入门到企业实战_Stars.Sky的博客-CSDN博客

1.2.1 区别

  1. 实现方式:Kustomize 采用基于覆盖的策略,通过在原始资源上应用一系列覆盖来实现资源定制。而 Helm 使用 Go 模板语言,将变量嵌入到 YAML 文件中,通过替换变量的方式生成定制资源。

  2. 配置管理:Kustomize 使用 kustomization.yaml 文件进行配置管理,而 Helm 使用名为 Chart.yamlvalues.yaml 的文件。

  3. 依赖管理:Helm 支持依赖管理,允许用户将一个 Helm Chart 依赖于其他 Helm Chart。而 Kustomize 不具备依赖管理功能。

  4. 发布管理:Helm 支持版本控制和回滚功能,可以管理应用的发布历史。Kustomize 不具备类似功能。

  5. 安装方式:Kustomize 自 Kubernetes v1.14 起已经集成在 kubectl 中,而 Helm 需要单独安装。

1.2.2 优缺点

Kustomize

优点:

  • 易于学习和理解,与 Kubernetes 资源本身的定义方式保持一致。
  • 使用声明式方式进行资源定制,避免了模板语言带来的复杂性。
  • 支持多层覆盖,有利于组织和管理复杂的配置。
  • 无需安装额外工具,与 kubectl 无缝集成。

缺点:

  • 不支持依赖管理和发布管理。
  • 在处理复杂逻辑和动态生成内容时,相较于 Helm 的模板语言,Kustomize 的能力有限。

Helm

优点:

  • 支持依赖管理和发布管理,提供了完整的应用生命周期管理功能。
  • 使用 Go 模板语言,可以处理复杂的逻辑和动态生成内容。
  • 拥有丰富的社区资源,如 Helm Chart 仓库等。

缺点:

  • 需要单独安装,并学习 Go 模板语言。
  • 模板语言可能导致配置的复杂性增加。

1.2.3 适用场景

Kustomize

  • 适用于简单到中等复杂度的 Kubernetes 资源配置管理。
  • 更适合那些需要在多个环境和场景下复用基础配置的场景。
  • 当对模板语言的需求较低时,Kustomize 是一个更简洁的选择。

Helm

  • 适用于具有复杂依赖关系和发布管理需求的应用。
  • 当需要处理复杂逻辑和动态生成内容时,Helm 的模板语言更具优势。
  • 如果需要使用丰富的社区资源,例如 Helm Chart 仓库,Helm 是一个更好的选择。

1.3 总结

        Kustomize 和 Helm 都是优秀的 Kubernetes 配置管理工具,它们各自具有独特的优势和不同的适用场景。在选择 Kustomize 还是 Helm 时,需要根据实际需求和场景来权衡。

        Kustomize 以其简单易用、声明式的方式在 Kubernetes 生态中脱颖而出,特别适合那些需要在多个环境和场景下复用基础配置的场景。

        而 Helm 则作为一个功能更为完善的应用生命周期管理工具,更适合具有复杂依赖关系和发布管理需求的应用。在处理复杂逻辑和动态生成内容时,Helm 的模板语言具有显著优势。同时,Helm 也拥有丰富的社区资源,如 Helm Chart 仓库等,为用户提供了更多的便利。

        最终,你可以根据实际项目需求、团队技能和个人喜好来选择 Kustomize 或 Helm。无论选择哪种工具,都能在 Kubernetes 配置管理方面为你带来很大的帮助。

二、Kustomize 入门

kustomize API 介绍:kustomization.yaml | SIG CLI

2.1 安装 Kustomize

        Kustomize 自 Kubernetes v1.14 起已经被集成在 kubectl 中,因此无需额外安装。只需确保你的 kubectl 版本在 v1.14 以上即可使用 Kustomize。

root@jenkins:/data/kustomize# kubectl version

root@jenkins:/data/kustomize# kubectl kustomize 

2.2 Kustomize 项目目录结构及介绍

此次教程以 personal-web 前端项目作为讲解例子:

root@jenkins:/data/kustomize# tree personal-web
personal-web
├── base
│   ├── deploy.yaml
│   ├── ingress.yaml
│   ├── kustomization.yaml
│   ├── nginx.conf
│   └── service.yaml
└── overlays
    ├── pre
    │   ├── deploy-patch.yaml
    │   ├── ing-patch.yaml
    │   └── kustomization.yaml
    ├── prod
    │   ├── deploy-patch.yaml
    │   ├── ing-patch.yaml
    │   ├── kustomization.yaml
    │   └── set_volumeMounts.yaml
    ├── test1
    │   ├── deploy-patch.yaml
    │   ├── ing-patch.yaml
    │   └── kustomization.yaml
    └── test2
        ├── deploy-patch.yaml
        ├── ing-patch.yaml
        └── kustomization.yaml

2.2.1 Kustomize 基本概念

  1. 基础资源(Base):基础资源是原始的 Kubernetes YAML 文件,用于描述 Kubernetes 对象。

  2. 覆盖(Overlay):覆盖是对基础资源的定制,用于为特定环境或场景提供额外的配置信息。

  3. kustomization.yaml:Kustomize 的配置文件,用于描述如何生成定制的资源。

2.2.2 personal-web 项目结构详细介绍

        上面是一个使用 Kustomize 的项目目录结构,用于管理一个名为 personal-web 的 Kubernetes 应用。该项目包含一个基础配置目录(base)和一个覆盖层配置目录(overlays)。我们来详细了解这个项目结构:

  • base 目录:包含该应用的基本 Kubernetes 资源配置文件,如 deploy.yaml(Deployment 配置)、ingress.yaml(Ingress 配置)和 service.yaml(Service 配置)。此外,还包含一个名为 nginx.conf 的 Nginx 配置文件。这些文件定义了应用的基本架构和行为。

    • kustomization.yaml:这是 Kustomize 的核心配置文件,用于声明基本资源,以及如何修改这些资源。在这个例子中,kustomization.yaml 将其他 YAML 文件(如 deploy.yamlingress.yamlservice.yaml)视为基础资源。
  • overlays 目录:包含用于不同环境(如预生产、生产和两个测试环境)的覆盖层配置。每个子目录(preprodtest1test2)代表一个环境,包含针对该环境的特定修改。

    • 每个子目录中的 kustomization.yaml 文件指定了要应用的基础配置(在本例中为 base 目录)以及覆盖层资源(如 deploy-patch.yamling-patch.yaml),这些资源用于修改基本配置以满足特定环境的需求。

    • deploy-patch.yamling-patch.yaml 文件包含针对 Deployment 和 Ingress 的定制修改。例如,可以更改副本数量、镜像标签或 Ingress 的主机名。

    • prod 目录下的 set_volumeMounts.yaml 文件是一个专门针对生产环境的额外配置,用于设置特定的 VolumeMounts。这表明生产环境与其他环境可能有不同的存储配置。

        总之,这个 Kustomize 项目目录结构允许您在不同环境之间复用基础配置,同时提供了覆盖层来实现针对特定环境的定制修改。这有助于提高配置的可维护性和可重用性。

2.3 创建基础资源

2.3.1 deploy.yaml 

        首先,我们创建一个项目目录(personal-web),在该项目下创建 base 目录用于存放基础资源。例如,创建一个名为 deploy.yaml 的文件,内容如下:

root@jenkins:/data/kustomize# cat personal-web/base/deploy.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: -app 
spec:
  replicas: 1
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: 
  template:
    metadata:
      labels:
        app: 
    spec:
      imagePullSecrets:
      - name: registry
      containers:
      - name: personal-web
        image: 
        imagePullPolicy: Always
        env:
        - name: CONTAINER_APP_NAME
          value: personal-web
        - name: CONTAINER_PODIP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        - name: CONTAINER_PODPORT
          value: "80"
        - name: CONTAINER_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        ports:
        - name: http
          containerPort: 80
        readinessProbe:
          httpGet:
            path: /
            scheme: HTTP
            port: 80
          initialDelaySeconds: 3
          periodSeconds: 3
          timeoutSeconds: 2
          successThreshold: 2
          failureThreshold: 3
        resources:
          limits:
            cpu: 500m
            memory: 2000Mi
          requests:
            cpu: 200m
            memory: 500Mi
        volumeMounts:
        - name: conf
          mountPath: /etc/nginx/nginx.conf
          subPath: nginx.conf
      volumes:
      - name: conf
        configMap:
          name: -cm

        这个 deploy.yaml 文件定义了一个 Kubernetes Deployment 资源。Deployment 资源用于描述应用程序的部署,确保特定数量的副本始终处于运行状态。以下是详细的字段解释:

  • apiVersion: apps/v1:指定 Kubernetes API 的版本,本例中使用的是 apps/v1

  • kind: Deployment:指定资源类型为 Deployment。

  • metadata:资源元数据,包括资源名称等信息。

    • name: -app:Deployment 资源的名称。这里的是个伏笔,后面会介绍,会自动生成 name: personal-web-app
  • spec:Deployment 资源的详细规格。

    • replicas: 1:指定运行的副本数量为 1。

    • strategy:定义升级策略。

      • rollingUpdate:指定滚动更新策略。

        • maxSurge: 1:在更新过程中允许的最大超出副本数。

        • maxUnavailable: 0:在更新过程中允许的最大不可用副本数。

    • selector:定义用于匹配 Pod 的标签选择器。

      • matchLabels:指定要匹配的标签。这里的值缺失,应该添加一个键值对,例如 app: personal-web
    • template:定义 Pod 模板。

      • metadata:Pod 元数据。

        • labels:指定 Pod 标签。这里的值缺失,应该添加一个键值对,例如 app: personal-web
      • spec:Pod 详细规格。

        • imagePullSecrets:指定用于拉取镜像的 Secret。在这个例子中,Secret 名称为 registry

        • containers:定义容器列表。

          • name: personal-web:容器名称。

          • image:容器使用的镜像。这里的值缺失,应该添加一个有效的镜像,例如 image: myrepo/personal-web:latest

          • imagePullPolicy: Always:镜像拉取策略,始终拉取新的镜像。

          • env:定义容器的环境变量。

          • ports:定义容器的端口映射。

          • readinessProbe:定义容器的就绪探针,用于检查容器是否已经准备好接收流量。

          • resources:定义容器的资源限制和请求。

          • volumeMounts:定义容器的卷挂载。

        • volumes:定义 Pod 的卷。

          • name: conf:卷的名称。

          • configMap:使用 ConfigMap 作为卷的数据来源。

            • name: -cm:指定 ConfigMap 的名称。后续会自动生成,例如 name: personal-web-cm

        这个 deploy.yaml 文件定义了一个名为 personal-web 的容器,它会使用指定的镜像并将其部署为一个 Kubernetes Deployment。这个 Deployment 包含了一个 Pod,其中包括环境变量、端口映射、就绪探针和资源限制等配置信息。

        容器将使用名为 registry 的 Secret 来拉取镜像,并始终拉取最新的镜像。容器的环境变量包括 CONTAINER_APP_NAMECONTAINER_PODIPCONTAINER_PODPORTCONTAINER_NAMESPACE,它们分别表示应用名称、Pod IP 地址、Pod 端口和命名空间。

        容器的端口映射将内部的 80 端口映射为名称为 http 的端口。就绪探针将检查容器的根路径(/),使用 HTTP 协议和 80 端口,以确保容器已经准备好接收流量。容器的资源限制和请求分别定义了 CPU 和内存的最大使用量以及基本需求。

        卷挂载部分将名为 conf 的卷挂载到容器的 /etc/nginx/nginx.conf 路径上。此卷使用名为 personal-web-cm 的 ConfigMap 作为数据来源。这样,您可以在 ConfigMap 中存储和管理 Nginx 配置,并自动将其应用到容器中。

        这个 deploy.yaml 文件为 personal-web 应用提供了一个基础的 Kubernetes Deployment 配置。通过 Kustomize 的覆盖层,您可以根据不同环境的需求对其进行修改。

2.3.2 service.yaml

root@jenkins:/data/kustomize# cat personal-web/base/service.yaml 
apiVersion: v1
kind: Service
metadata:
  name: -svc
spec:
  sessionAffinity: ClientIP
  sessionAffinityConfig:
    clientIP:
      timeoutSeconds: 300
  type: ClusterIP
  ports:
  - name: http-nginx
    port: 80
    targetPort: 80
  selector:
    app:

        这个 service.yaml 文件定义了一个 Kubernetes Service 资源。Service 资源用于为一组运行的 Pod 提供一个稳定的 IP 地址和 DNS 名称,实现负载均衡和网络流量分发。以下是详细的字段解释:

  • apiVersion: v1:指定 Kubernetes API 的版本,本例中使用的是 v1

  • kind: Service:指定资源类型为 Service。

  • metadata:资源元数据,包括资源名称等信息。

    • name: -svc:Service 资源的名称。这里的名称似乎有误,应该是一个有效的名称,例如 name: personal-web-svc
  • spec:Service 资源的详细规格。

    • sessionAffinity: ClientIP:设置会话亲和性(session affinity)为 ClientIP。这意味着来自同一客户端 IP 的请求会被发送到同一个 Pod。

    • sessionAffinityConfig:会话亲和性配置。

      • clientIP:针对客户端 IP 的会话亲和性配置。

        • timeoutSeconds: 300:设置客户端 IP 会话亲和性的超时时间为 300 秒。
    • type: ClusterIP:设置 Service 类型为 ClusterIP。这意味着 Service 会分配一个内部集群 IP 地址,仅在集群内部可访问。

    • ports:定义 Service 的端口映射。

      • name: http-nginx:端口名称。

      • port: 80:Service 的端口。

      • targetPort: 80:Pod 中的目标端口。

    • selector:定义用于匹配 Pod 的标签选择器。

      • app:指定要匹配的标签。这里的值缺失,应该添加一个键值对,例如 app: personal-web

        这个 service.yaml 文件为 personal-web 应用提供了一个基础的 Kubernetes Service 配置。Service 资源将在集群内部将流量分发到具有 app: personal-web 标签的 Pod,并确保来自同一客户端 IP 的请求会被发送到同一个 Pod。通过 Kustomize 的覆盖层,您可以根据不同环境的需求对其进行修改。

2.3.3 ingress.yaml

root@jenkins:/data/kustomize# cat personal-web/base/ingress.yaml 
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/service-weight: ""
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/ssl-redirect: 'true'
  name: -ingress
spec:
  tls:
  - hosts:
    - 
    secretName: 
  ingressClassName: nginx
  rules:
  - host: 
    http:
      paths:
      - backend:
          service:
            name: 
            port:
              number: 80
        path: /
        pathType: Prefix

        这个 ingress.yaml 文件定义了一个 Kubernetes Ingress 资源。Ingress 资源用于管理外部访问集群内部服务的规则,允许您通过一个或多个 HTTP 或 HTTPS 路径将流量路由到集群内部的 Service。以下是详细的字段解释:

  • apiVersion: networking.k8s.io/v1:指定 Kubernetes API 的版本,本例中使用的是 networking.k8s.io/v1

  • kind: Ingress:指定资源类型为 Ingress。

  • metadata:资源元数据,包括资源名称、注解等信息。

    • annotations:为 Ingress 添加注解,用于配置 Ingress 控制器的行为。本例中使用了 nginx Ingress 控制器。

      • nginx.ingress.kubernetes.io/service-weight:为后端服务设置权重,用于流量分发。这里的值为空,表示使用默认权重。

      • nginx.ingress.kubernetes.io/rewrite-target:重写目标路径,将客户端请求的路径重写为指定值。本例中,所有请求的路径都被重写为 /

      • nginx.ingress.kubernetes.io/ssl-redirect:设置为 'true' 以启用 SSL 重定向。这意味着非 SSL 请求将被重定向到 SSL 端点。

    • name: -ingress:Ingress 资源的名称。这里的名称似乎有误,应该是一个有效的名称,例如 name: personal-web-ingress

  • spec:Ingress 资源的详细规格。

    • tls:配置 Ingress 的 TLS 设置。

      • hosts:指定 TLS 证书适用的域名。这里的值缺失,应该添加一个有效的域名,例如 - example.com

      • secretName:指定包含 TLS 证书和密钥的 Kubernetes Secret。这里的值缺失,应该添加一个有效的 Secret 名称,例如 secretName: example-tls-secret

    • ingressClassName: nginx:指定 Ingress 类名为 nginx,用于选择正确的 Ingress 控制器。

    • rules:定义 Ingress 规则。

      • host:指定规则适用的域名。这里的值缺失,应该添加一个有效的域名,例如 host: example.com

      • http:配置 HTTP 规则。

        • paths:定义 HTTP 路径列表。

          • backend:配置后端服务。

            • service:指定后端服务。

              • name:后端服务的名称。这里的值缺失,应该添加一个有效的名称,例如 name: personal-web-svc

              • port:指定后端服务的端口。

                • number: 80:后端服务的端口号。
          • path: /:指定匹配的路径。

          • pathType: Prefix:指定路径类型为 Prefix,表示匹配请求路径的前缀

2.4 创建 kustomization.yaml

接下来,我们创建一个名为 kustomization.yaml 的文件,内容如下:

root@jenkins:/data/kustomize# cat personal-web/base/kustomization.yaml 
resources:
- deploy.yaml
- service.yaml
- ingress.yaml

configMapGenerator:
- name: -cm
  files:
  - nginx.conf

   kustomization.yaml 文件是 Kustomize 的核心配置文件,用于描述资源的基本配置和修改。在这个例子中,kustomization.yaml 文件位于 base 目录下,包含以下内容:

  • resources:列出了本层次结构中包含的 Kubernetes 资源文件。在这个例子中,包括 deploy.yaml(Deployment),service.yaml(Service)和 ingress.yaml(Ingress)。

  • configMapGenerator:指定 ConfigMap 生成器,用于从文件或字面值创建 ConfigMap。在这个例子中,生成器用于创建一个名为 -cm 的 ConfigMap。这个名称似乎有误,应该是一个有效的名称,例如 name: personal-web-cm

    • files:指定用于生成 ConfigMap 的文件列表。在这个例子中,生成器将 nginx.conf 文件内容添加到 ConfigMap 中。

        通过 kustomization.yaml 文件,您可以定义和组织 Kubernetes 资源的基本结构。在其他覆盖层中,您可以根据不同环境的需求对这些资源进行修改。这使得您能够更轻松地管理和维护多个环境的 Kubernetes 配置。

    configMapGenerator 是 Kustomize 中的一个功能,用于动态生成 Kubernetes ConfigMap。它允许您将配置数据与应用程序资源分离,从而更好地管理和维护配置信息。下面详细介绍 configMapGenerator 的优势和作用:

  1. 分离配置和应用程序资源:configMapGenerator 允许您将配置信息(如配置文件、属性、参数等)与应用程序资源(如 Deployment、Service 等)分离。这样做有助于提高配置管理的灵活性和可维护性,方便您在不同环境中使用不同的配置。

  2. 简化配置管理:通过使用 configMapGenerator,您可以直接从本地文件或字面值创建 ConfigMap,无需手动创建和更新 YAML 文件。这降低了出错的可能性,同时简化了配置管理过程。

  3. 避免重复和冗余:当您的应用程序需要使用相同的配置数据时,configMapGenerator 可以避免重复和冗余。通过在 Kustomize 层次结构中复用相同的配置文件或字面值,您可以确保配置数据在各个环境中保持一致。

  4. 自动生成名称后缀:configMapGenerator 会自动为生成的 ConfigMap 添加一个唯一的后缀。这确保了当配置数据发生变化时,所有使用这个 ConfigMap 的资源都会得到更新。这样可以避免因为未更新配置导致的应用程序错误或故障。

  5. 支持多种数据来源:configMapGenerator 支持从多种来源生成 ConfigMap,包括文件、目录、字面值、环境变量文件等。这使得您可以根据实际需求选择合适的数据来源,灵活处理不同类型的配置数据。

        总之,按照传统的部署方式,我们需要先提前创建 configmap 资源,再把创建好的资源名称填入 deploy.yaml 文件中才能生效,而 configMapGenerator 的存在则无需提前创建 configmap 资源,直接生成有效的 configmap,大大提高效率。

2.5 生成定制资源

现在,我们可以使用 kubectl kustomize 命令生成定制资源:

root@jenkins:/data/kustomize# kubectl kustomize personal-web/base/

   kubectl kustomize 命令用于处理指定目录下的 Kustomize 配置文件(kustomization.yaml),并生成最终的 Kubernetes 资源清单(manifest)。它根据 kustomization.yaml 文件中定义的基础资源、覆盖层、变量替换等指令,将不同环境的配置进行合并和修改,输出一个最终的资源清单。

这个命令的主要作用如下:

  1. 处理 Kustomize 配置:kubectl kustomize 会根据 kustomization.yaml 文件的指令,处理基础资源和覆盖层,生成一个适用于特定环境的资源清单。

  2. 生成最终资源清单:该命令会生成一个最终的 Kubernetes 资源清单,该清单包含所有经过修改和合并的资源配置,可以直接应用于 Kubernetes 集群。

  3. 方便资源部署和管理:kubectl kustomize 命令简化了在不同环境中部署和管理 Kubernetes 资源的过程。您可以轻松地在开发、测试和生产等不同环境中使用相应的覆盖层,以确保配置正确。

注意:我们前面所介绍的一些资源清单文件的字段值有些是为空的、甚至是一些名称没有填写完整等,这些空缺的部分,就是我们后续手动调整的地方,也叫补丁,大白话就是用于 DIY。 

上一篇文章:【Kubernetes 企业项目实战】09、Rancher 2.6 管理 k8s-v1.23 及以上版本高可用集群_rancher 高可用_Stars.Sky的博客-CSDN博客

下一篇文章:【Kubernetes 企业项目实战】11、掌握 Kubernetes Kustomize 技术从入门到企业实战(下)_Stars.Sky的博客-CSDN博客

猜你喜欢

转载自blog.csdn.net/weixin_46560589/article/details/129982359