每天5分钟玩转Kubernetes | chart详解

书籍来源:cloudman《每天5分钟玩转Kubernetes》

一边学习一边整理老师的课程内容及试验笔记,并与大家分享,侵权即删,谢谢支持!

附上汇总贴:每天5分钟玩转Kubernetes | 汇总_COCOgsta的博客-CSDN博客


chart是Helm的应用打包格式。chart由一系列文件组成,这些文件描述了Kubernetes部署应用时所需要的资源,比如Service、Deployment、PersistentVolumeClaim、Secret、ConfigMap等。

单个的chart可以非常简单,只用于部署一个服务,比如Memcached。chart也可以很复杂,部署整个应用,比如包含HTTP Servers、Database、消息中间件、Cache等。

chart将这些文件放置在预定义的目录结构中,通常整个chart被打成tar包,而且标注上版本信息,便于Helm部署。

下面我们将详细讨论chart的目录结构以及包含的各类文件。

11.5.1 chart目录结构

以前面MySQL chart为例。一旦安装了某个chart,我们就可以在~/.helm/cache/archive中找到chart的tar包,如图所示。

解压后,MySQL chart目录结构如图所示。

目录名就是chart的名字(不带版本信息),这里是mysql,包含如下内容。

(1)Chart.yaml

YAML文件,描述chart的概要信息,如图所示。

name和version是必填项,其他都是可选项。

(2)README.md

Markdown格式的README文件,相当于chart的使用文档,此文件为可选,如图所示。

(3)LICENSE

文本文件,描述chart的许可信息,此文件为可选。

(4)requirements.yaml

chart可能依赖其他的chart,这些依赖关系可通过requirements.yaml指定,如图所示(实验环境中没有dependencies)。

在安装过程中,依赖的chart也会被一起安装。

(5)values.yaml

chart支持在安装时根据参数进行定制化配置,而values.yaml则提供了这些配置参数的默认值,如图所示。

(6)templates目录

各类Kubernetes资源的配置模板都放置在这里。Helm会将values.yaml中的参数值注入模板中,生成标准的YAML配置文件。

模板是chart最重要的部分,也是Helm最强大的地方。模板增加了应用部署的灵活性,能够适用不同的环境,我们后面会详细讨论。

(7)templates/NOTES.txt

chart的简易使用文档,chart安装成功后会显示此文档内容,如图所示。

与模板一样,可以在NOTE.txt中插入配置参数,Helm会动态注入参数值。

11.5.2 chart模板

Helm通过模板创建Kubernetes能够理解的YAML格式的资源配置文件,我们将通过例子来学习如何使用模板。

以templates/secrets.yaml为例,如图所示。

从结构上看,文件的内容非常像Secret配置,只是大部分属性值变成了{ { xxx }}。这些{ { xxx }}实际上是模板的语法。Helm采用了Go语言的模板来编写chart。Go模板非常强大,支持变量、对象、函数、流控制等功能。下面我们通过解析templates/secrets.yaml快速学习模板。

① { { template "mysql.fullname" . }}定义Secret的name。关键字 template的作用是引用一个子模板mysql.fullname。这个子模板是在 templates/_helpers.tpl文件中定义的,如图所示。

这个定义还是很复杂的,因为它用到了模板语言中的对象、函数、流控制等概念。现在看不懂没关系,这里我们学习的重点是:如果存在一些信息多个模板都会用到,则可在templates/_helpers.tpl中将其定义为子模板,然后通过templates函数引用。

这里mysql.fullname是由release与chart二者名字拼接组成的。

根据chart的最佳实践,所有资源的名称都应该保持一致。对于我们这个chart,无论Secret还是Deployment、PersistentVolumeClaim、Service,它们的名字都是子模板mysql.fullname的值。

② Chart和Release是Helm预定义的对象,每个对象都有自己的属 性,可以在模板中使用。如果使用下面的命令安装chart:

helm install stable/mysql -n my

那么:

  • { { .Chart.Name }}的值为mysql。
  • { { .Chart.Version }}的值为0.3.0。
  • { { .Release.Name }}的值为my。
  • { { .Release.Service }}始终取值为Tiller。
  • { { template "mysql.fullname" . }}计算结果为my-mysql。

③ 这里指定mysql-root-password的值,不过使用了if-else的流控制,其逻辑为:如果.Values.mysqlRootPassword有值,就对其进行base64编码,否则随机生成一个10位的字符串并编码。

Values也是预定义的对象,代表的是values.yaml文件。.Values.mysqlRootPassword则是values.yaml中定义的 mysqlRootPassword参数,如图所示。

因为mysqlRootPassword被注释掉了,没有赋值,所以逻辑判断会走else,即随机生成密码。

randAlphaNum、b64enc、quote都是Go模板语言支持的函数,函数之间可以通过管道|连接。{ { randAlphaNum 10 | b64enc | quote }}的作用是首先随机产生一个长度为10的字符串,然后将其base64编码, 最后两边加上双引号。

templates/secrets.yaml这个例子展示了chart模板主要的功能,我们最大的收获应该是:模板将chart参数化了,通过values.yaml可以灵活定制应用。

无论多复杂的应用,用户都可以用Go模板语言编写出chart。无非是使用到更多的函数、对象和流控制。对于初学者,建议尽量参考 官方的chart。根据二八定律,这些chart已经覆盖了绝大部分情况,而 且采用了最佳实践。如何遇到不懂的函数、对象和其他语法,可参考 官网文档https://docs.helm.sh。

11.5.3 再次实践MySQL chart

学习了chart结构和模板的知识后,现在重新实践一次MySQL chart,相信会有更多收获。

  1. chart安装前的准备

作为准备工作,安装之前需要先清楚chart的使用方法。这些信息通常记录在values.yaml和README.md中。除了下载源文件查看,执行helm inspect values可能是更方便的方法,如图所示。

输出的实际上是values.yaml的内容。阅读注释就可以知道MySQL chart支持哪些参数,安装之前需要做哪些准备。其中有一部分是关于存储的,如图所示。

chart定义了一个PersistentVolumeClaim,申请8GB的PersistentVolume。由于我们的实验环境不支持动态供给,因此要预先创建好相应的PV,其配置文件mysql-pv.yml的内容如下所示。

[root@k8s-master ~]# cat mysql-pv.yml 
apiVersion: v1
kind: PersistentVolume
metadata:
  name: mysql-pv
spec:
  accessModes:
    - ReadWriteOnce
  capacity:
    storage: 8Gi
  persistentVolumeReclaimPolicy: Retain
#  storageClassName: nfs
  nfs:
    path: /nfsdata/mysql-pv
    server: 192.168.1.146
[root@k8s-master ~]# 

创建PV mysql-pv,如图所示。

接下来就可以安装chart了。

  1. 定制化安装chart

除了接受values.yaml的默认值,我们还可以定制化chart,比如设置mysqlRootPassword。

Helm有两种方式传递配置参数:

(1)指定自己的values文件。通常的做法是首先通过helm inspect values mysql >myvalues.yaml生成values文件,然后设置 mysqlRootPassword,最后执行helm install--values=myvalues.yaml mysql。

(2)通过--set直接传入参数值,如图所示。

mysqlRootPassword设置为abc123。另外,-n设置release为my,各类资源的名称即为my-mysql。

通过helm list和helm status可以查看chart的最新状态,如图所示。

PVC已经Bound,Deployment也变为AVAILABLE。

11.5.4 升级和回滚release

release发布后可以执行helm upgrade对其进行升级,通过--values或--set应用新的配置。比如将当前的MySQL版本升级到5.7.15,如图所示。

等待一些时间,升级成功,如图所示。

helm history可以查看release所有的版本。通过helm rollback可以回滚到任何版本,如图所示。

回滚成功,MySQL恢复到5.7.30,如图所示。

11.5.5 开发自己的chart

Kubernetes给我们提供了大量官方chart,不过要部署微服务应用,还是需要开发自己的chart,下面就来实践这个主题。

  1. 创建chart

执行helm create mychart命令,创建chart mychart,如图所示。

Helm会帮我们创建目录mychart,并生成各类chart文件。这样我们就可以在此基础上开发自己的chart了。

新建的chart默认包含一个nginx应用示例,values.yaml内容如图所示。

开发时建议大家参考官方chart中的模板values.yaml、Chart.yaml,里面包含了大量最佳实践和最常用的函数、流控制,这里就不一一展开了。

  1. 调试chart

只要是程序就会有bug,chart也不例外。Helm提供了debug的工具:helm lint和helm install --dry-run --debug。

helm lint会检测chart的语法,报告错误以及给出建议。

比如我们故意在values.yaml的第8行漏掉了行尾的那个冒号,如图所示。

helm lint mychart会指出这个语法错误,如图所示。

mychart目录被作为参数传递给helm lint。错误修复后则能通过检测,如图所示。

helm install --dry-run --debug会模拟安装chart,并输出每个模板生成的YAML内容,如下所示。

[root@k8s-master ~]# helm install --dry-run mychart --debug
[debug] Created tunnel using local port: '37535'

[debug] SERVER: "127.0.0.1:37535"

[debug] Original chart version: ""
[debug] CHART PATH: /root/mychart

NAME:   filled-bison
REVISION: 1
RELEASED: Wed Jun  8 02:46:26 2022
CHART: mychart-0.1.0
USER-SUPPLIED VALUES:
{}

COMPUTED VALUES:
affinity: {}
fullnameOverride: ""
image:
  pullPolicy: IfNotPresent
  repository: nginx
  tag: stable
imagePullSecrets: []
ingress:
  annotations: {}
  enabled: false
  hosts:
  - host: chart-example.local
    paths: []
  tls: []
nameOverride: ""
nodeSelector: {}
podSecurityContext: {}
replicaCount: 1
resources: {}
securityContext: {}
service:
  port: 80
  type: ClusterIP
serviceAccount:
  create: true
  name: ""
tolerations: []

HOOKS:
---
# filled-bison-mychart-test-connection
apiVersion: v1
kind: Pod
metadata:
  name: "filled-bison-mychart-test-connection"
  labels:
    app.kubernetes.io/name: mychart
    helm.sh/chart: mychart-0.1.0
    app.kubernetes.io/instance: filled-bison
    app.kubernetes.io/version: "1.0"
    app.kubernetes.io/managed-by: Tiller
  annotations:
    "helm.sh/hook": test-success
spec:
  containers:
    - name: wget
      image: busybox
      command: ['wget']
      args:  ['filled-bison-mychart:80']
  restartPolicy: Never
MANIFEST:

---
# Source: mychart/templates/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: filled-bison-mychart
  labels:
    app.kubernetes.io/name: mychart
    helm.sh/chart: mychart-0.1.0
    app.kubernetes.io/instance: filled-bison
    app.kubernetes.io/version: "1.0"
    app.kubernetes.io/managed-by: Tiller
---
# Source: mychart/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: filled-bison-mychart
  labels:
    app.kubernetes.io/name: mychart
    helm.sh/chart: mychart-0.1.0
    app.kubernetes.io/instance: filled-bison
    app.kubernetes.io/version: "1.0"
    app.kubernetes.io/managed-by: Tiller
spec:
  type: ClusterIP
  ports:
    - port: 80
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app.kubernetes.io/name: mychart
    app.kubernetes.io/instance: filled-bison
---
# Source: mychart/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: filled-bison-mychart
  labels:
    app.kubernetes.io/name: mychart
    helm.sh/chart: mychart-0.1.0
    app.kubernetes.io/instance: filled-bison
    app.kubernetes.io/version: "1.0"
    app.kubernetes.io/managed-by: Tiller
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: mychart
      app.kubernetes.io/instance: filled-bison
  template:
    metadata:
      labels:
        app.kubernetes.io/name: mychart
        app.kubernetes.io/instance: filled-bison
    spec:
      serviceAccountName: filled-bison-mychart
      securityContext:
        {}
        
      containers:
        - name: mychart
          securityContext:
            {}
            
          image: "nginx:stable"
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /
              port: http
          readinessProbe:
            httpGet:
              path: /
              port: http
          resources:
            {}
[root@k8s-master ~]# 

我们可以检测这些输出,判断是否与预期相符。

同样,mychart目录作为参数传递给helm install --dry-run -- debug。

  1. 安装chart

当我们准备就绪,就可以安装chart了。Helm支持四种安装方法:

(1)安装仓库中的chart,例如helm install stable/nginx。

(2)通过tar包安装,例如helm install ./nginx-1.2.3.tgz。

(3)通过chart本地目录安装,例如helm install ./nginx。

(4)通过URL安装,例如helm install
https://example.com/charts/nginx-1.2.3.tgz。

这里我们使用本地目录安装,如图所示。

当chart部署到Kubernetes集群后,便可以对其进行更为全面的测试了。

  1. 将chart添加到仓库

chart通过测试后可以添加到仓库中,团队其他成员就能够使用了。任何HTTP Server都可以用作chart仓库。下面演示在k8s-node1 192.168.1.145上搭建仓库。

(1)在k8s-node1上启动一个httpd容器,如图所示。

(2)通过helm package将mychart打包,如图所示。

(3)执行helm repo index生成仓库的index文件,如图所示。

Helm会扫描myrepo目录中的所有tgz包并生成index.yaml。--url指定的是新仓库的访问路径。新生成的index.yaml记录了当前仓库中所有chart的信息,如图所示。

当前只有mychart这一个chart。

(4)将mychart-0.1.0.tgz和index.yaml上传到k8s-node1的/var/www/charts目录,如图所示。

(5)通过helm repo add将新仓库添加到Helm,如图所示。

仓库命名为newrepo,Helm会从仓库下载index.yaml。

(6)现在已经可以repo search到mychart了,如图所示。

除了newrepo/mychart,这里还有一个local/mychart。这是因为在执行第2步打包操作的同时,mychart也被同步到了local的仓库。

(7)已经可以直接从新仓库安装mychart了,如图所示。

(8)若以后仓库添加了新的chart,则需要用helm repo update更新本地的index,如图所示。

这个操作相当于Ubutun的apt-get update。

猜你喜欢

转载自blog.csdn.net/guolianggsta/article/details/125267941