本文将从头构建一个前后端分离的微服务 chart,前端 Vue,后端 Spring Boot。需要提前了解 Helm3Chart相关知识。
相关文章:

一、创建

1.1 创建父Chart

创建一个前端Vue作为父Chart

helm create vue

当前的 Chart 结构如下:

vue/
├── charts
├── Chart.yaml
├── templates
│   ├── deployment.yaml
│   ├── _helpers.tpl
│   ├── hpa.yaml
│   ├── ingress.yaml
│   ├── NOTES.txt
│   ├── serviceaccount.yaml
│   ├── service.yaml
│   └── tests
│       └── test-connection.yaml
└── values.yaml
  • charts:目录用于存放其他依赖的chart(我们称之为子chart)。
  • Chart.yaml:文件包含chart的说明。
  • templates:目录用于放置模板文件。是所有资源的位置,我们可以看到很多kubernetes的资源文件都在这里存放。
  • values.yaml:文件对模板也很重要。该文件包含 chart 默认值。这些值可能在用户在 helm installhelm upgrade 期间被覆盖。

templates目录中的文件:

  • deployment.yaml:创建Kubernetes工作负载的基本文件。
  • _helpers.tpl:放置模板的地方,该文件中定义模版可以在整个chart中重复使用。
  • hpa.yamlHPA配置文件。
  • ingress.yaml:负载均衡配置文件。
  • NOTES.txtchart的 “帮助文本”。这会在用户运行helm install时显示给用户。
  • serviceaccount.yamlserviceaccount配置文件。
  • service.yaml:服务发现的配置文件。
  • tests/test-connection.yaml:用于测试chart安装后的测试pod

1.2 创建子Chart

创建eureka注册中心、oauth2鉴权中心和一个MS微服务,作为子Chart

helm create eureka \
&& helm create oauth2 \
&& helm create ms \
&& helm create ws

现在当前目录我们一共有五个待调试的Chart

vue          ---父chart
eureka       ---子chart 
oauth2       ---子chart
ms           ---子chart
ws           ---子chart

二、调试

2.1 调试父Chart

首先删除Chart中无用的文件,所有文件根据自己需求创建。

rm -rf vue/values.yaml vue/templates/*

2.1.1 创建命名空间namespace模版文件

values.yaml文件中定义如下(每个值后续都会用到,这里统一写完):

vim vue/values.yaml
nameSpace: microservice
secretsName: mysecret
imageCredentials:
  registry: http://192.168.1.40
  username: admin
  password: Yidongjituan123
replicaCount: 1
image:
  repository: 192.168.1.40/xzzyy/vue-saas
  tag: 95e740c61bd7f9b4b3be62f819d00f90fe10ac24
service:
  port: 40099

创建namespace模版文件。

vim vue/templates/namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: {{ .Values.nameSpace }}
  labels:
    name: {{ .Values.nameSpace }}

2.1.2 创建镜像仓库secrets模版文件

镜像拉的secrets实质上是注册,用户名和密码的组合。在正在部署的应用程序中可能需要它们,但要创建它们需要多次运行 base64。我们可以编写一个模板来组合Docker配置文件,以用作Secret的有效载体。这里是一个例子:

我们定义我们的帮助模板如下:

vim vue/templates/_helpers.tpl
{{- define "imagePullSecret"}}
{{- printf "{\"auths\": {\"%s\": {\"auth\": \"%s\"}}}" .Values.imageCredentials.registry (printf "%s:%s" .Values.imageCredentials.username .Values.imageCredentials.password | b64enc) | b64enc }}
{{- end}}

创建secrets模版文件。

vim vue/templates/secrets.yaml
apiVersion: v1
kind: Secret
metadata:
  name: {{ .Values.secretsName }}
  namespace: {{ .Values.nameSpace }}
type: kubernetes.io/dockerconfigjson
data:
  .dockerconfigjson: {{ template "imagePullSecret" . }}

2.1.2 创建工作负载deployment模版文件

vim vue/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Chart.Name }}
  namespace: {{ .Values.nameSpace }}
spec:
  replicas: {{ .Values.replicaCount }}
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: {{ .Chart.Name }}
  template:
    metadata:
      labels:
        app: {{ .Chart.Name }}
    spec:
      restartPolicy: Always
      imagePullSecrets:
      - name: {{ .Values.secretsName }}
      containers:
      - name: {{ .Chart.Name }}
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
        imagePullPolicy: Always
        ports:
        - name: http
          containerPort: {{ .Values.service.port }}
          protocol: TCP
        startupProbe:
          httpGet:
            path: /
            port: 8080
          failureThreshold: 10
          periodSeconds: 5
        livenessProbe:
          httpGet:
            path: /
            port: 8080
          initialDelaySeconds: 10
          failureThreshold: 1
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /
            port: 8080
          initialDelaySeconds: 10
          failureThreshold: 3
          periodSeconds: 5

2.1.3 创建服务发现service模版文件

vim vue/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: {{ .Chart.Name }}
  namespace: {{ .Values.nameSpace }}
  labels:
    name: {{ .Chart.Name }}
spec:
  type: NodePort
  ports:
  - port: {{ .Values.service.port }}
    targetPort: 8080
    nodePort: {{ .Values.service.port }}
    protocol: TCP
  selector:
    app: {{ .Chart.Name }}

使用helm install --dry-run demo vue/可对模版进行渲染预览,如渲染不成功,根据提示修改即可。

渲染后的样式:

NAME: demo
LAST DEPLOYED: Thu Jul 23 16:06:25 2020
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
---
# Source: vue/templates/namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: microservice
  labels:
    name: microservice
---
# Source: vue/templates/secrets.yaml
apiVersion: v1
kind: Secret
metadata:
  name: mysecret
  namespace: microservice
type: kubernetes.io/dockerconfigjson
data:
  .dockerconfigjson: eyJhdXRocyI6IHsiaHR0cDovLzE5Mi4xNjguMS40MCI6IHsiYXV0aCI6ICJZV1J0YVc0NldXbGtiMjVuYW1sMGRXRnVNVEl6In19fQ==
---
# Source: vue/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: vue
  namespace: microservice
spec:
  replicas: 1
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: vue
  template:
    metadata:
      labels:
        app: vue
    spec:
      restartPolicy: Always
      imagePullSecrets:
      - name: mysecret
      containers:
      - name: vue
        image: "192.168.1.40/xzzyy/vue-saas:95e740c61bd7f9b4b3be62f819d00f90fe10ac24"
        imagePullPolicy: Always
        ports:
        - name: http
          containerPort: 40099
          protocol: TCP
        startupProbe:
          httpGet:
            path: /
            port: 8080
          failureThreshold: 10
          periodSeconds: 5
        livenessProbe:
          httpGet:
            path: /
            port: 8080
          initialDelaySeconds: 10
          failureThreshold: 1
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /
            port: 8080
          initialDelaySeconds: 10
          failureThreshold: 3
          periodSeconds: 5

2.2 调试子Chart

由于父Chart已经创建完成namespacesecrets,子Chart无需再次创建。删除无用文件。

rm -rf eureka/values.yaml eureka/templates/* \
&& rm -rf oauth2/values.yaml oauth2/templates/* \
&&  rm -rf ms/values.yaml ms/templates/* \
&&  rm -rf ws/values.yaml ws/templates/* 

2.1.1 创建配置映射configmap模版文件

使用configmap统一管理Spring Boot的配置文件。只需要创建一个configmap,然后将四个配置文件以键值对的方式存入该configmap,以便引用。

values.yaml文件中定义如下(每个值后续都会用到,这里统一写完):

vim eureka/values.yaml
configmapName: demo-config
nameSpace: microservice
secretsName: mysecret
replicaCount: 1
image:
  repository: 192.168.1.40/xzzyy/eureka
  tag: bff976dda6786a2b593ccf5a76bd2e1cf670e615
service:
  port: 40000

创建configmap模版文件。

vim eureka/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Values.configmapName }}
  namespace: {{ .Values.nameSpace }}
data:
{{ (.Files.Glob "config/*").AsConfig | indent 2 }}

使用引用静态文件的方式,直接引入配置文件内容,经过这种方式会创建四个键值对,键为配置名称,值为配置文件内容。不过需要提前将配置文件放入Chart的根目录,如下:

eureka/
├── charts
├── Chart.yaml
├── config
│   ├── eureka.yml
│   ├── ms.yml
│   ├── oauth2.yml
│   └── ws.yml
├── templates
│   ├── configmap.yaml
│   ├── deployment.yaml
│   └── service.yaml
└── values.yaml

编写完之后可以通过helm install --dry-run confimap eureka/验证模版正确性。

2.1.2 创建工作负载deployment模版文件

  • eureka
vim eureka/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Chart.Name }}
  namespace: {{ .Values.nameSpace }}
spec:
  replicas: {{ .Values.replicaCount }}
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: {{ .Chart.Name }}
  template:
    metadata:
      labels:
        app: {{ .Chart.Name }}
    spec:
      restartPolicy: Always
      imagePullSecrets:
      - name: {{ .Values.secretsName }}
      containers:
      - name: {{ .Chart.Name }}
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
        imagePullPolicy: Always
        ports:
        - name: http
          containerPort: {{ .Values.service.port }}
          protocol: TCP
        startupProbe:
          tcpSocket:
            port: http
          initialDelaySeconds: 5
          failureThreshold: 10
          periodSeconds: 5
        readinessProbe:
          tcpSocket:
            port: http
          failureThreshold: 3
          periodSeconds: 5
        livenessProbe:
          tcpSocket:
            port: http
          failureThreshold: 1
          periodSeconds: 10
        resources:
          limits:
            cpu: 2
            memory: 2Gi
          requests:
            cpu: 1
            memory: 1Gi
        volumeMounts:
          - name: config-volume
            mountPath: /config
      volumes:
      - name: config-volume
        configMap:
          name: {{ .Values.configmapName }}
          items:
          - key: {{ .Chart.Name }}.yml
            path: bootstrap.yml
  • oauth2

values.yaml内容。

vim oauth2/values.yaml
secretsName: mysecret
configmapName: demo-config
nameSpace: microservice
replicaCount: 1
image:
  repository: 192.168.1.40/xzzyy/oauth2
  tag: bff976dda6786a2b593ccf5a76bd2e1cf670e615
service:
  port: 40001

deployment.yaml内容

vim oauth2/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Chart.Name }}
  namespace: {{ .Values.nameSpace }}
spec:
  replicas: {{ .Values.replicaCount }}
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: {{ .Chart.Name }}
  template:
    metadata:
      labels:
        app: {{ .Chart.Name }}
    spec:
      restartPolicy: Always
      imagePullSecrets:
      - name: {{ .Values.secretsName }}
      containers:
      - name: {{ .Chart.Name }}
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
        imagePullPolicy: Always
        ports:
        - name: http
          containerPort: {{ .Values.service.port }}
          protocol: TCP
        startupProbe:
          tcpSocket:
            port: http
          initialDelaySeconds: 5
          failureThreshold: 10
          periodSeconds: 5
        readinessProbe:
          tcpSocket:
            port: http
          failureThreshold: 3
          periodSeconds: 5
        livenessProbe:
          tcpSocket:
            port: http
          failureThreshold: 1
          periodSeconds: 10
        resources:
          limits:
            cpu: 2
            memory: 2Gi
          requests:
            cpu: 1
            memory: 1Gi
        volumeMounts:
          - name: config-volume
            mountPath: /config
      volumes:
      - name: config-volume
        configMap:
          name: {{ .Values.configmapName }}
          items:
          - key: {{ .Chart.Name }}.yml
            path: bootstrap.yml
  • ws

values.yaml内容

vim ws/values.yaml
secretsName: mysecret
configmapName: demo-config
nameSpace: microservice
replicaCount: 1
image:
  repository: 192.168.1.40/xzzyy/doctor-ws
  tag: bff976dda6786a2b593ccf5a76bd2e1cf670e615
service:
  port: 40002

deployment.yaml内容

vim ws/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Chart.Name }}
  namespace: {{ .Values.nameSpace }}
spec:
  replicas: {{ .Values.replicaCount }}
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: {{ .Chart.Name }}
  template:
    metadata:
      labels:
        app: {{ .Chart.Name }}
    spec:
      restartPolicy: Always
      imagePullSecrets:
      - name: {{ .Values.secretsName }}
      containers:
      - name: {{ .Chart.Name }}
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
        imagePullPolicy: Always
        ports:
        - name: http
          containerPort: {{ .Values.service.port }}
          protocol: TCP
        startupProbe:
          httpGet:
            path: /doc.html
            port: http
          initialDelaySeconds: 5
          failureThreshold: 10
          periodSeconds: 5
        livenessProbe:
          httpGet:
            path: /doc.html
            port: http
          failureThreshold: 1
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /doc.html
            port: http
          failureThreshold: 3
          periodSeconds: 5
        resources:
          limits:
            cpu: 2
            memory: 2Gi
          requests:
            cpu: 1
            memory: 1Gi
        volumeMounts:
        - name: config-volume
          mountPath: /config
      volumes:
      - name: config-volume
        configMap:
          name: {{ .Values.configmapName }}
          items:
          - key: {{ .Chart.Name }}.yml
            path: bootstrap.yml
  • ms

values.yaml内容

vim ms/values.yaml
secretsName: mysecret
configmapName: demo-config
nameSpace: microservice
replicaCount: 1
image:
  repository: 192.168.1.40/xzzyy/online-registration-ms
  tag: bff976dda6786a2b593ccf5a76bd2e1cf670e615
service:
  port: 40003

deployment.yaml内容

vim ms/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Chart.Name }}
  namespace: {{ .Values.nameSpace }}
spec:
  replicas: {{ .Values.replicaCount }}
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: {{ .Chart.Name }}
  template:
    metadata:
      labels:
        app: {{ .Chart.Name }}
    spec:
      restartPolicy: Always
      imagePullSecrets:
      - name: {{ .Values.secretsName }}
      containers:
      - name: {{ .Chart.Name }}
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
        imagePullPolicy: Always
        ports:
        - name: http
          containerPort: {{ .Values.service.port }}
          protocol: TCP
        startupProbe:
          httpGet:
            path: /doc.html
            port: http
          initialDelaySeconds: 5
          failureThreshold: 10
          periodSeconds: 5
        livenessProbe:
          httpGet:
            path: /doc.html
            port: http
          failureThreshold: 1
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /doc.html
            port: http
          failureThreshold: 3
          periodSeconds: 5
        resources:
          limits:
            cpu: 2
            memory: 2Gi
          requests:
            cpu: 1
            memory: 1Gi
        volumeMounts:
        - name: config-volume
          mountPath: /config
      volumes:
      - name: config-volume
        configMap:
          name: {{ .Values.configmapName }}
          items:
          - key: {{ .Chart.Name }}.yml
            path: bootstrap.yml

2.1.3 创建服务发现service模版文件

  • eureka
vim eureka/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: {{ .Chart.Name }}
  namespace: {{ .Values.nameSpace }}
  labels:
    name: {{ .Chart.Name }}
spec:
  type: NodePort
  ports:
  - port: {{ .Values.service.port }}
    targetPort: {{ .Values.service.port }}
    nodePort: {{ .Values.service.port }}
    protocol: TCP
  selector:
    app: {{ .Chart.Name }}
  • oauth2
vim oauth2/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: {{ .Chart.Name }}
  namespace: {{ .Values.nameSpace }}
  labels:
    name: {{ .Chart.Name }}
spec:
  type: NodePort
  ports:
  - port: {{ .Values.service.port }}
    targetPort: {{ .Values.service.port }}
    nodePort: {{ .Values.service.port }}
    protocol: TCP
  selector:
    app: {{ .Chart.Name }}
  • ws
vim ws/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: {{ .Chart.Name }}
  namespace: {{ .Values.nameSpace }}
  labels:
    name: {{ .Chart.Name }}
spec:
  type: NodePort
  ports:
  - port: {{ .Values.service.port }}
    targetPort: {{ .Values.service.port }}
    nodePort: {{ .Values.service.port }}
    protocol: TCP
  selector:
    app: {{ .Chart.Name }}
  • ms
vim ms/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: {{ .Chart.Name }}
  namespace: {{ .Values.nameSpace }}
  labels:
    name: {{ .Chart.Name }}
spec:
  type: NodePort
  ports:
  - port: {{ .Values.service.port }}
    targetPort: {{ .Values.service.port }}
    nodePort: {{ .Values.service.port }}
    protocol: TCP
  selector:
    app: {{ .Chart.Name }}

通过helm install --dry-run demo xxxx/验证每个Chart的正确性。

2.3 联合调试父子Chart

保证每个Chart都可以--dry-run渲染成功,然后就可以开始进行联调试

首先修改父ChartChart.yaml文件,添加依赖关系。

vim vue/Chart.yaml

追加如下内容,file://是针对Chart.yaml的相对路径,也可以写远程repo库的地址,这里是本地调试没有用到。

dependencies:
  - name: eureka
    repository: file://../eureka/
    version: 0.1.0
  - name: oauth2
    repository: file://../oauth2/
    version: 0.1.0
  - name: ws
    repository: file://../ws/
    version: 0.1.0
  - name: ms
    repository: file://../ms/
    version: 0.1.0

然后使用dependency update参数,构建chart依赖。

[root@harbor ~]# helm dependency update vue/
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "myrepo" chart repository
Update Complete. ⎈Happy Helming!⎈
Saving 4 charts
Deleting outdated charts

最终父Chart目录结构

vue/
├── Chart.lock
├── charts
│   ├── eureka-0.1.0.tgz
│   ├── ms-0.1.0.tgz
│   ├── oauth2-0.1.0.tgz
│   └── ws-0.1.0.tgz
├── Chart.yaml
├── templates
│   ├── deployment.yaml
│   ├── _helpers.tpl
│   ├── namespace.yaml
│   ├── secrets.yaml
│   └── service.yaml
└── values.yaml

三、安装

直接使用helm本地安装父Chart即可

helm install demo vue/

查看安装的chart

[root@harbor ~]# helm list 
NAME                       	NAMESPACE	REVISION	UPDATED                                	STATUS  	CHART          	APP VERSION
demo                       	default  	1       	2020-07-23 17:18:14.746382646 +0800 CST	deployed	vue-0.1.0      	1.16.0     

查看部署的deployment

[root@harbor ~]# kubectl get deployments.apps -n microservice 
NAME     READY   UP-TO-DATE   AVAILABLE   AGE
eureka   1/1     1            1           43s
ms       1/1     1            1           43s
oauth2   1/1     1            1           43s
vue      1/1     1            1           43s
ws       1/1     1            1           43s

四、优化

上述步骤完成的多依赖构建,已经满足一键部署多个服务的需求了,但是通过实际操作下来,会发现一些问题:

  • 每个子chart中都有相同的values值。例如:secretsNameconfigmapNamenameSpace
  • 有很多模版都是相同的。例如:deployment.yamlservice.yaml

如果有二三十个微服务后端的话,会有一大部分时间在做重复工作。所以我们就在想能不能复用这些常量和模版。

4.1 全局常量

可以修改父Chartvalues.yaml,追加一个global值,将所有子Chart会用到的值设置为全局常量。

imageCredentials:
  registry: http://192.168.1.40
  username: admin
  password: Yidongjituan123
replicaCount: 1
image:
  repository: 192.168.1.40/xzzyy/vue-saas
  tag: 95e740c61bd7f9b4b3be62f819d00f90fe10ac24
service:
  port: 40099
  
global:
  nameSpace: microservice
  secretsName: mysecret
  configmapName: demo-config

此值可供所有chart使用,使用方式:.Values.global.nameSpace.Values.global.secretsName等等。
这样我们就无需在每个子Chartvalues.yaml中重复定义这些值了,只需修改一下模版中的使用方式即可。

4.2 共享常量

Chartvalues.yaml,增加以下内容,注意节点的名字必须是子chart名。

imageCredentials:
  registry: http://192.168.1.40
  username: admin
  password: Yidongjituan123
replicaCount: 1
image:
  repository: 192.168.1.40/xzzyy/vue-saas
  tag: 95e740c61bd7f9b4b3be62f819d00f90fe10ac24
service:
  port: 40099
global:
  nameSpace: microservice
  secretsName: mysecret
  configmapName: demo-config

eureka:
  replicaCount: 1
  image:
    repository: 192.168.1.40/xzzyy/eureka
    tag: bff976dda6786a2b593ccf5a76bd2e1cf670e615
  service:
    port: 40000

oauth2:
  replicaCount: 1
  image:
    repository: 192.168.1.40/xzzyy/oauth2
    tag: bff976dda6786a2b593ccf5a76bd2e1cf670e615
  service:
    port: 40001

ws:
  replicaCount: 1
  image:
    repository: 192.168.1.40/xzzyy/doctor-ws
    tag: bff976dda6786a2b593ccf5a76bd2e1cf670e615
  service:
    port: 40002

ms:
  replicaCount: 1
  image:
    repository: 192.168.1.40/xzzyy/online-registration-ms
    tag: bff976dda6786a2b593ccf5a76bd2e1cf670e615
  service:
    port: 40003

eureka的模板里就可以通过{{ .Values.replicaCount }} 来引用。当Helm发现节点名是子chart名时,它会自动引用这个常量到子chartvalues.yaml中。
因此,在oauth2中,你也可以通过{{ .Values.image.repository }} 来访问这个常量。


如果出现父Chart子Chart中都定义了相同的values值,那么helm会以父Chart为准,覆盖子Chart中相同的值。

4.3 if-else

如何复用我们的模版呢,这就需要在编写模版文件时候加入复杂的判断条件,来完成一个模版的多个chart复用。

if-else语法

{{if PIPELINE}}
  # Do something
{{else if OTHER PIPELINE}}
  # Do something else
{{else}}
  # Default case
{{end}}
  • 一个布尔型的假
  • 一个数字零
  • 一个空的字符串
  • 一个 nil(空或 null)
  • 一个空的集合(map,slice,tuple,dict,array)

在其他情况下, 条件值为 true 此管道被执行。

if-else使用案例

values.yaml内容:

favorite:
  drink: coffee
  food: pizza

configmap.yaml内容:

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{.Release.Name }}-configmap
data:
  myvalue: "Hello World"
  drink: {{.Values.favorite.drink }}
  food: {{.Values.favorite.food }}
  {{- if eq .Values.favorite.drink "coffee" }}
  mug: true
  {{- end}}

渲染后的模版:

# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: clunky-cat-configmap
data:
  myvalue: "Hello World"
  drink: "coffee"
  food: "PIZZA"
  mug: true
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐