背景:很久很久以前,在GKE里手动写k8s yaml file部署了Kong,版本是v0.13.x,这个版本太老太旧了,而且Kong现在最新的版本是v1.1.x,不仅仅有一些变动,还提供了许多新功能。因为我们升级Kong的任务不能再等待了。目标,升级Kong到v1.0.3。技术解决方案是选择Kong的helm chart来进行升级操作,由于项目上已经存在的一些限制条件,我们需要定制Kong的helm chart来满足这次升级。
文章分为两部分:
- Kong 升级的一些准备资料
- Customization Helm Chart & Helm Repo
Kong升级资料准备
官方文档升级Kong到v1.0.0里面有个Preliminary Checks,该部分提及到
If your cluster is running a version lower than 0.14, you need to upgrade to 0.14.1 first instead. Upgrading from a pre-0.14 cluster straight to Kong 1.0 is not supported.
所以我们需要先将Kong从0.13.x -> 0.14.1, 然后再从 v0.14.1 -> v1.0.3.
在官方文档升级Kong到v1.0.0里,只有Migration Steps from 0.14的步骤。
在Kong github repo的UPGRADE.md中,记录了不同版本如何升级的步骤。如:upgrade-to-014x.
Kong Upgragde to 0.14.x
Github md文档:upgrade-to-014x
技术方案是会用helm的Kong chart实现0.13.x -> 0.14.1 的升级。但是需要Customization Kong Chart. 因为GKE里的kong链接的GCP Postgres SQL instance,所以需要在Kong所在的pod里面起一个cloudproxy
- Cloud SQL Proxy About Postgres 的介绍
- How to connect using the proxy from GKE 这个是我们需要定制化kong chart用到的参考文章
How to customization Kong chart?
官方文档:
- chart development guide
The Chart File Structure
自定义chart,需要按照Helm期望的文件结构来设计。
Helm保留了一些关键字的使用,如: 保留了 charts/ 和 templates/ 这样的文件夹名字等。
Chart 就是所有文件的集合,文件夹的名字就是chart的名字,文件夹的名字不需要包含版本信息。如下面的wordpress文件夹,就是一个描述wordpress的chart被放在wordpress/ 文件夹下。
wordpress/
Chart.yaml # A YAML file containing information about the chart
LICENSE # OPTIONAL: A plain text file containing the license for the chart
README.md # OPTIONAL: A human-readable README file
requirements.yaml # OPTIONAL: A YAML file listing dependencies for the chart
values.yaml # The default configuration values for this chart
charts/ # A directory containing any charts upon which this chart depends.
templates/ # A directory of templates that, when combined with values,
# will generate valid Kubernetes manifest files.
templates/NOTES.txt # OPTIONAL: A plain text file containing short usage notes
Chart 版本遵循的是SemVer 2 标准,简单的解释是:
版本格式:主版本号.次版本号.修订号,版本号递增规则如下:
- 主版本号:当你做了不兼容的 API 修改,
- 次版本号:当你做了向下兼容的功能性新增,
- 修订号:当你做了向下兼容的问题修正。
先行版本号及版本编译元数据可以加到“主版本号.次版本号.修订号”的后面,作为延伸。
Chart Dependencies
在Helm里,有时候,一个chart可能会依赖一些其他的chart。这些被依赖的charts可以通过配置requirements.yaml 文件动态建立链接,或者可以将被依赖的charts移动到charts/ 目录下,手动的管理。
dependencies:
- name: apache
version: 1.2.3
repository: http://example.com/charts
- name: mysql
version: 3.2.1
repository: http://another.example.com/charts
- The name field => 被依赖的chart的name
- The version field => 被依赖的chart的版本
- The repository field => 被依赖chart所在的repo。注意:你必须使用
helm repo add
将这个repo添加到本地。
当配置了dependency后,可以使用helm dependency update
更新依赖。
依赖这一块还有很多信息,可以查看文档继续学习。
Templates and Values
Templates 是 helm chart里的资源模板,都放在 templates/ 文件夹下。
Values for the templates 有两种方式:
- chart的开发者提供一个 values.yaml . 这个values.yaml 包含默认的values。
- Chart 的使用者可以提供一个YAML file 包含这些 values。提供给helm install命令。
Predefined Values
values.yaml file定义的value可以在模板中用.Values 对象取到。
模板也可以取到预定义的值。
以下值是预定义的,可用于每个模板,并且无法覆盖。与所有值一样,名称区分大小写。
Release.Name: The name of the release (not the chart)
Release.Time: The time the chart release was last updated. This will match the Last Released time on a Release object.
Release.Namespace: The namespace the chart was released to.
Release.Service: The service that conducted the release. Usually this is Tiller.
Release.IsUpgrade: This is set to true if the current operation is an upgrade or rollback.
Release.IsInstall: This is set to true if the current operation is an install.
Release.Revision: The revision number. It begins at 1, and increments with each helm upgrade.
Chart: The contents of the Chart.yaml. Thus, the chart version is obtainable as Chart.Version and the maintainers are in Chart.Maintainers.
Files: A map-like object containing all non-special files in the chart. This will not give you access to templates, but will give you access to additional files that are present (unless they are excluded using .helmignore). Files can be accessed using {{index .Files "file.name"}} or using the {{.Files.Get name}} or {{.Files.GetString name}} functions. You can also access the contents of the file as []byte using {{.Files.GetBytes}}
Capabilities: A map-like object that contains information about the versions of Kubernetes ({{.Capabilities.KubeVersion}}, Tiller ({{.Capabilities.TillerVersion}}, and the supported Kubernetes API versions ({{.Capabilities.APIVersions.Has "batch/v1")
关于Customization Chart 时,如何使用teamplate里面的的value,template,和预定义值,参考资料:
- chart 模板 - 每天5分钟玩转 Docker 容器技术(165)
- the text/template Go package documentation
Demo:
{{ template "mysql.fullname" . }}
关键字 template 的作用是引用一个子模板 mysql.fullname。这个子模板是在templates/_helpers.tpl
文件中定义的
如果存在一些信息多个模板都会用到,则可在templates/_helpers.tpl
中将其定义为子模板,然后通过 templates 函数引用。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。
Using Helm to Manage Charts
- using-helm-to-manage-charts
- creating-your-own-charts
Helm 提供了一些操作chart的命令:
创建一个新的chart:helm create mychart
当你edit好chart后,helm可以讲chart打包:helm package mychart
也可以使用helm帮助你检查chart的格式化或者其他信息:helm lint mychart
安装自己打包好的chart: helm install ./mychart-0.1.0.tgz
Chart Repositories
Chart Repo 是一个HTTP Server,包含一个或者多个打包的chart.
虽然helm可用于管理本地chart目录,但在共享chart时,首选机制是chart repo.
Helm repo 的一个特征是含有一个名为 index.yaml
的文件,里面是该repo存储的chart的列表。可以使用helm repo index
命令,可以根据包含打包的chart的给定本地目录生成索引文件。
如果一个chart repo 没有index.yaml 文件,那么将会不被认为是一个合法的chart repo. (确保 index.yaml 可以在没有认证要求的情况下访问
).
在client 端,repo可以通过helm repo
命令进行管理。然而,helm没有提供上传chart到远端repo 服务器的工具。因为这样做会给repo 服务器的实现增加一些要求,从而提高了建立repo 服务器的障碍。
Hosting Chart Repositories
有好几种方式可以host chart repo:
- ChartMuseum
- JFrog Artifactory
- Github Page
- Ordinary Web Servers
ChartMuseum
我们是选择使用了ChartMuseum方式。
Helm 提供了一个名为chartmuseum的开源helm repo server帮助你host chart repo。
ChartMuseum支持多个云存储后端。将其配置为指向包含chart的目录或bucket,将动态生成index.yaml文件。
部署 chartmuseum:
helm install stable/chartmuseum
add chartmuseum server to repo list:
helm repo add chartmuseum http://localhost:8080
创建public的 GCS bucket(Google Cloud Storage Bucket)
,然后可以通过https://bucket-name.storage.googleapis.com/
去访问你的repo.
Managing Chart Repositories
repo中的chart必须是打包过后的,可以使用 helm package chart-name/
进行打包。
当你有了打包后的chart,创建一个新的文件夹,将打包好的chart移到这个文件里,操作步骤:
-
helm package docs/exampe/alpine
打包chart -
mkdir fantastic-charts
创建新的文件夹 -
mv alpine-0.1.0.tgz fantastic-charts/
将chart包移到fantastic-charts文件下 -
helm repo index fantastic-charts/ --url https://fantastic-charts.storage.googleapis.com
用helm生成一个更新的index.yaml文件,通过传递chart package 所在的文件路径 和 远端repo的地址这两个参数给helm repo index
.然后在chart package 所在的文件夹下面会有一个index.yaml文件.
然后,可以使用同步工具或者手动的上传chart 和 index 文件到远端的chart repo里。
如果使用的是GCS,那么可以使用gsutil client Syncing Your Chart Repository。
Sync your local and remote chart repositories
通过运行helm code base里的scripts/sync-repo.sh文件,将含有chart package和index.yaml的文件夹上传到你的GCS bucket上, 需要传递本地文件夹的路径和GCS bucket的名字
scripts/sync-repo.sh fantastic-charts/ bucket-name
Updating your chart repository
你可以使用gsutil rsync
命令,将远端的repo 复制到本地。
# the -n flag does a dry run
gsutil rsync -d -n gs://bucket-name local-dir/
# performs the copy actions
$ gsutil rsync -d gs://bucket-name local-dir/
参考文档:
- https://whmzsu.github.io/helm-doc-zh-cn/chart/chart_repository-zh_cn.html
- 使用Helm优化Kubernetes下的研发体验:基础设施即代码