使用Kustomize管理K8S的YAML清单

简介: 使用Kustomize管理K8S的YAML清单

将应用部署到Kubernetes中的方式有很多,目前主流是就是使用kubectlHelm,不过其先决条件都需要YAML清单文件。


不同由于部署环境的多样化,比如有开发环境、测试环境、预生产环境、生产环境,我们就会针对不同的环境定制各种YAML文件,但是在很多情况下同一个应用在不同的环境可能只做了简单的更改,这样就会导致YAML泛滥。


而**Kustomize 就是用于帮助解决这些问题的开源配置管理工具。**从 Kubernetes v1.14 开始,kubectl 就完全支持 Kustomize 和 kustomization 文件。


kustomize是什么?


kustomize lets you customize raw, template-free YAML files for multiple purposes, leaving the original YAML untouched and usable as is.


上面是官方对于kustomize的定义。大致是说:kustomize允许您自定义无模板的原始YAML文件来用于多种目的,而原始的YAML则保持不变并可以使用。


kustomize的作用


当我们在K8S中有多套环境的时候,就会面临如下问题:


  • 多环境多团队多个YAML资源清单
  • 不同环境差异微小,但是不得不copy and change
  • helm稍显复杂,需要额外的学习投入


而kustomize可以很好的解决这些问题:


  • kustomize 通过 Base & Overlays 方式方式维护不同环境的应用配置
  • kustomize 使用 patch 方式复用 Base 配置,并在 Overlay 描述与 Base 应用配置的差异部分来实现资源复用
  • kustomize 管理的都是 Kubernetes 原生 YAML 文件,不需要学习额外的 DSL 语法


安装


在kubernetes 1.14版本以上,已经集成到kubectl中了,你可以通过kubectl --help来进行查看命令。


如果需要额外安装,直接到https://github.com/kubernetes-sigs/kustomize/releases里进行下载对应的版本。


比如:


wget https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize%2Fv3.8.7/kustomize_v3.8.7_linux_amd64.tar.gz
tar xf kustomize_v3.8.7_linux_amd64.tar.gz
cp kustomize/kustomize /usr/local/bin


这样就完成了简单的安装了。


实践测试


背景


  • 版本信息

  • kubernetes:1.17.9
  • 集群信息,由于在一个环境中进行测试,所以采用不同的namespace进行分开

  • 开发环境:dev
  • 预发环境:stag
  • 生产环境:prod
  • 测试用例:一个简单的hello world示例


创建基础模板


首先创建一个helloworld目录,表示应用,然后在里面创建一个base目录,如下:


mkdir helloworld/base -p


然后在base目录下创建以下配置清单:


base/
├── configMap.yaml
├── deployment.yaml
├── ingress.yaml
├── kustomization.yaml
└── service.yaml


他们的清单内容分别如下:


configMap.yaml


apiVersion: v1
kind: ConfigMap
metadata:
  name: the-map
  namespace: default
data:
  altGreeting: "Hello World!"
  enableRisky: "false"


deployment.yaml


apiVersion: apps/v1
kind: Deployment
metadata:
  name: the-deployment
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      deployment: hello
  template:
    metadata:
      labels:
        deployment: hello
    spec:
      containers:
      - name: the-container
        image: monopole/hello:1
        command: ["/hello",
                  "--port=8080",
                  "--enableRiskyFeature=$(ENABLE_RISKY)"]
        ports:
        - containerPort: 8080
        env:
        - name: ALT_GREETING
          valueFrom:
            configMapKeyRef:
              name: the-map
              key: altGreeting
        - name: ENABLE_RISKY
          valueFrom:
            configMapKeyRef:
              name: the-map
              key: enableRisky


service.yaml


kind: Service
apiVersion: v1
metadata:
  name: the-service
  namespace: default
spec:
  selector:
    deployment: hello
  type: NodePort
  ports:
  - protocol: TCP
    port: 8080
    targetPort: 8080


ingress.yaml


apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: the-ingress 
  namespace: default
spec:
  rules:
    - host: test.coolops.cn 
      http:
        paths:
          - backend:
              serviceName: the-service 
              servicePort: 8080 
            path: /


kustomization.yaml


# Example configuration for the webserver
# at https://github.com/monopole/hello
commonLabels:
  app: hello
resources:
- deployment.yaml
- service.yaml
- configMap.yaml
- ingress.yaml


这样基础模板就创建好了,我们可以使用如下命令将所有文件连在一起。


kustomize build ../base


然后如果想创建应用可以用以下方式。


# 直接使用kubectl apply -k (集群版本要高于1.14)
kubectl apply -k ../base/
# 还可以通过kustomize命令
kustomize build ../base | kubectl apply -f -


删除应用命令类似,可以自行尝试。


根据不同环境创建overlays


上面的是基础模板,所有的配置都是基于它,现在我们根据不同的环境进行定制。


首先创建如下目录结构


.
├── base
│   ├── configMap.yaml
│   ├── deployment.yaml
│   ├── ingress.yaml
│   ├── kustomization.yaml
│   └── service.yaml
└── overlays
    ├── dev
    ├── prod
    └── stag


其中:


  • dev目录下存放开发环境定制清单
  • stag目录下存放预发环境定制清单
  • prod目录下存放生产环境定制清单


配置开发环境


在dev目录下创建以下文件:


../dev/
├── ingress.yaml
├── kustomization.yaml
└── map.yaml


其中ingress.yaml如下:


apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: the-ingress 
  namespace: default
spec:
  rules:
    - host: hello-dev.coolops.cn 
      http:
        paths:
          - backend:
              serviceName: the-service 
              servicePort: 8080 
            path: /


map.yaml


apiVersion: v1
kind: ConfigMap
metadata:
  name: the-map
data:
  altGreeting: "Hello,This is Dev!"
  enableRisky: "true"


kustomization.yaml


namePrefix: dev-
commonLabels:
  org: acmeCorporation
  variant: dev
commonAnnotations:
  note: Hello, This is dev!
patchesStrategicMerge:
- map.yaml
- ingress.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
namespace: dev


开发环境更改了configmap的内容、ingress的host,还有namespace。

然后可以通过kustomize build .测试配置是否正确。


配置预发环境


在stag目录下创建以下文件:


../stag/
├── kustomization.yaml
└── map.yaml


其中map.yaml内容如下:


apiVersion: v1
kind: ConfigMap
metadata:
  name: the-map
data:
  altGreeting: "Hello,This is Stag!"
  enableRisky: "true"


kustomization.yaml


namePrefix: stag-
commonLabels:
  org: acmeCorporation
  variant: stag
commonAnnotations:
  note: Hello, This is stag!
patchesStrategicMerge:
- map.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
namespace: stag


预发环境更改了configmap和namespace。


配置生产环境


在prod目录下创建以下文件:


../prod/
├── deployment.yaml
├── kustomization.yaml
└── map.yaml


其中deployment.yaml配置如下:


apiVersion: apps/v1
kind: Deployment
metadata:
  name: the-deployment
spec:
  replicas: 3


map.yaml


apiVersion: v1
kind: ConfigMap
metadata:
  name: the-map
data:
  altGreeting: "Hello,This is prod!"
  enableRisky: "true"


kustomization.yaml


namePrefix: prod-
commonLabels:
  org: acmeCorporation
  variant: prod
commonAnnotations:
  note: Hello, This is prod!
patchesStrategicMerge:
- deployment.yaml
- map.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
namespace: prod


生产环境更改了configmap、deploy副本数、namspace。


发布使用


上面我们已经将整个需要的配置定制好了。现在就可以进行发布了。


如果要发布开发环境,则使用:


cd helloworld/
kustomize build overlays/dev/ | kubectl apply -f -


然后我们可以看到发布完成,如下:


# kubectl get all -n dev
NAME                                      READY   STATUS    RESTARTS   AGE
pod/dev-the-deployment-6cdcbbc878-27n5g   1/1     Running   0          50s
pod/dev-the-deployment-6cdcbbc878-fgx89   1/1     Running   0          50s
pod/dev-the-deployment-6cdcbbc878-xz5q2   1/1     Running   0          50s
NAME                      TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
service/dev-the-service   NodePort   10.103.77.190   <none>        8080:32414/TCP   50s
NAME                                 READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/dev-the-deployment   3/3     3            3           50s
NAME                                            DESIRED   CURRENT   READY   AGE
replicaset.apps/dev-the-deployment-6cdcbbc878   3         3         3       50s


然后通过域名访问如下:


640.png


其他环境是类似的操作,这里不再赘述。


结合CD使用


在进行持续部署的时候每次都需要修改镜像地址为最新的版本,使用kustomize也可以简单的实现。


加入我们要修改dev环境下的镜像地址为nginx,命令如下


cd overlays/dev
kustomize edit set image monopole/hello=nginx:latest


说明:


  • monopole/hello是原来的镜像名字
  • nginx:latest是新的镜像+标签


然后可以看到kustomization.yaml下的镜像地址已经变成了nginx,如下:


namePrefix: dev-
commonLabels:
  org: acmeCorporation
  variant: dev
commonAnnotations:
  note: Hello, This is dev!
patchesStrategicMerge:
- map.yaml
- ingress.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
namespace: dev
images:
- name: monopole/hello
  newName: nginx
  newTag: latest


我们这时候再发布,就是nginx的镜像了。


# kustomize build . | kubectl apply -f -
configmap/dev-the-map unchanged
service/dev-the-service unchanged
deployment.apps/dev-the-deployment configured
ingress.extensions/dev-the-ingress unchanged


同样,修改namespace可以使用如下命令。


kustomize edit set namespace test


更多操作可以查看官方文档:https://kubernetes-sigs.github.io/kustomize/zh/guides/


写在最后


使用 Kustomize 简化了针对不同环境的应用程序配置的管理。我们将一组几乎重复的 YAML 文件重组为一个分层模型,这将减少错误,减少手动配置,并使代码更易于识别和维护。

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
4月前
|
JSON Kubernetes API
深入理解Kubernetes配置:编写高效的YAML文件
深入理解Kubernetes配置:编写高效的YAML文件
|
3月前
|
Kubernetes 应用服务中间件 nginx
k8s学习--YAML资源清单文件托管服务nginx
k8s学习--YAML资源清单文件托管服务nginx
k8s学习--YAML资源清单文件托管服务nginx
|
3月前
|
Kubernetes Cloud Native 流计算
Flink-12 Flink Java 3分钟上手 Kubernetes云原生下的Flink集群 Rancher Stateful Set yaml详细 扩容缩容部署 Docker容器编排
Flink-12 Flink Java 3分钟上手 Kubernetes云原生下的Flink集群 Rancher Stateful Set yaml详细 扩容缩容部署 Docker容器编排
118 3
|
3月前
|
Kubernetes Docker Perl
k8s常见故障--yaml文件检查没有问题 pod起不来(一直处于创建中)
k8s常见故障--yaml文件检查没有问题 pod起不来(一直处于创建中)
143 1
|
5月前
|
JSON Kubernetes 数据格式
k8s集群yaml文件方式迁移
k8s集群yaml文件方式迁移
|
5月前
|
Kubernetes API 容器
在K8S中,deployment的yaml文件如何编写呢?
在K8S中,deployment的yaml文件如何编写呢?
|
7月前
|
存储 运维 Serverless
函数计算产品使用问题之在YAML文件中配置了环境变量,但在PHP代码中无法读取到这些环境变量,是什么原因
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
100 1
|
3月前
ingress相关yaml文件报错且相关资源一切正常解决方法
ingress相关yaml文件报错且相关资源一切正常解决方法
ingress相关yaml文件报错且相关资源一切正常解决方法
|
6月前
|
运维 Kubernetes Serverless
Serverless 应用引擎使用问题之s.yaml文件中如何使用外部环境变量
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
|
6月前
|
存储 缓存 运维
函数计算产品使用问题之如何将外部环境变量放到s.yaml文件中使用
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。

热门文章

最新文章