|
|
|
|
# 50 | 服务编排(下):基于Helm的服务编排部署实战
|
|
|
|
|
|
|
|
|
|
你好,我是孔令飞。
|
|
|
|
|
|
|
|
|
|
上一讲,我介绍了 Helm 的基础知识,并带着你部署了一个简单的应用。掌握Helm的基础知识之后,今天我们就来实战下,一起通过Helm部署一个IAM应用。
|
|
|
|
|
|
|
|
|
|
通过Helm部署IAM应用,首先需要制作IAM Chart包,然后通过Chart包来一键部署IAM应用。在实际开发中,我们需要将应用部署在不同的环境中,所以我也会给你演示下如何在多环境中部署IAM应用。
|
|
|
|
|
|
|
|
|
|
## 制作IAM Chart包
|
|
|
|
|
|
|
|
|
|
在部署IAM应用之前,我们首先需要制作一个IAM Chart包。
|
|
|
|
|
|
|
|
|
|
我们假设IAM项目源码根目录为`${IAM_ROOT}`,进入 `${IAM_ROOT}/deployments`目录,在该目录下创建Chart包。具体创建流程分为四个步骤,下面我来详细介绍下。
|
|
|
|
|
|
|
|
|
|
**第一步,**创建一个模板Chart。
|
|
|
|
|
|
|
|
|
|
Chart是一个组织在文件目录中的集合,目录名称就是Chart名称(没有版本信息)。你可以看看这个 [Chart 开发指南](https://helm.sh/zh/docs/topics/charts) ,它介绍了如何开发你自己的Chart。
|
|
|
|
|
|
|
|
|
|
不过,这里你也可以使用 `helm create` 命令来快速创建一个模板Chart,并基于该Chart进行修改,得到你自己的Chart。创建命令如下:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
$ helm create iam
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
`helm create iam`会在当前目录下生成一个`iam`目录,里面存放的就是Chart文件。Chart目录结构及文件如下:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
$ tree -FC iam/
|
|
|
|
|
├── charts/ # [可选]: 该目录中放置当前Chart依赖的其他Chart
|
|
|
|
|
├── Chart.yaml # YAML文件,用于描述Chart的基本信息,包括名称版本等
|
|
|
|
|
├── templates/ # [可选]: 部署文件模版目录,模版使用的值来自values.yaml和由Tiller提供的值
|
|
|
|
|
│ ├── deployment.yaml # Kubernetes Deployment object
|
|
|
|
|
│ ├── _helpers.tpl # 用于修改Kubernetes objcet配置的模板
|
|
|
|
|
│ ├── hpa.yaml # Kubernetes HPA object
|
|
|
|
|
│ ├── ingress.yaml # Kubernetes Ingress object
|
|
|
|
|
│ ├── NOTES.txt # [可选]: 放置Chart的使用指南
|
|
|
|
|
│ ├── serviceaccount.yaml
|
|
|
|
|
│ ├── service.yaml
|
|
|
|
|
│ └── tests/ # 定义了一些测试资源
|
|
|
|
|
│ └── test-connection.yaml
|
|
|
|
|
└── values.yaml # Chart的默认配置文件
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
上面的目录中,有两个比较重要的文件:
|
|
|
|
|
|
|
|
|
|
* Chart.yaml 文件
|
|
|
|
|
* templates目录
|
|
|
|
|
|
|
|
|
|
下面我来详细介绍下这两个文件。**我们先来看Chart.yaml 文件。**
|
|
|
|
|
|
|
|
|
|
Chart.yaml用来描述Chart的基本信息,包括名称、版本等,内容如下:
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
apiVersion: Chart API 版本 (必需)
|
|
|
|
|
name: Chart名称 (必需)
|
|
|
|
|
version: 语义化版本(必需)
|
|
|
|
|
kubeVersion: 兼容Kubernetes版本的语义化版本(可选)
|
|
|
|
|
description: 对这个项目的一句话描述(可选)
|
|
|
|
|
type: Chart类型 (可选)
|
|
|
|
|
keywords:
|
|
|
|
|
- 关于项目的一组关键字(可选)
|
|
|
|
|
home: 项目home页面的URL (可选)
|
|
|
|
|
sources:
|
|
|
|
|
- 项目源码的URL列表(可选)
|
|
|
|
|
dependencies: # chart 必要条件列表 (可选)
|
|
|
|
|
- name: Chart名称 (nginx)
|
|
|
|
|
version: Chart版本 ("1.2.3")
|
|
|
|
|
repository: (可选)仓库URL ("https://example.com/charts") 或别名 ("@repo-name")
|
|
|
|
|
condition: (可选) 解析为布尔值的YAML路径,用于启用/禁用Chart(e.g. subchart1.enabled )
|
|
|
|
|
tags: # (可选)
|
|
|
|
|
- 用于一次启用/禁用 一组Chart的tag
|
|
|
|
|
import-values: # (可选)
|
|
|
|
|
- ImportValue 保存源值到导入父键的映射。每项可以是字符串或者一对子/父列表项
|
|
|
|
|
alias: (可选) Chart中使用的别名。当你要多次添加相同的Chart时会很有用
|
|
|
|
|
maintainers: # (可选)
|
|
|
|
|
- name: 维护者名字 (每个维护者都需要)
|
|
|
|
|
email: 维护者邮箱 (每个维护者可选)
|
|
|
|
|
url: 维护者URL (每个维护者可选)
|
|
|
|
|
icon: 用作icon的SVG或PNG图片URL (可选)
|
|
|
|
|
appVersion: 包含的应用版本(可选)。不需要是语义化,建议使用引号
|
|
|
|
|
deprecated: 不被推荐的Chart(可选,布尔值)
|
|
|
|
|
annotations:
|
|
|
|
|
example: 按名称输入的批注列表 (可选).
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**我们再来看下****templates目录****这个文件。**
|
|
|
|
|
|
|
|
|
|
templates目录中包含了应用中各个Kubernetes资源的YAML格式资源定义模板,例如:
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
apiVersion: v1
|
|
|
|
|
kind: Service
|
|
|
|
|
metadata:
|
|
|
|
|
labels:
|
|
|
|
|
app: {{ .Values.pump.name }}
|
|
|
|
|
name: {{ .Values.pump.name }}
|
|
|
|
|
spec:
|
|
|
|
|
ports:
|
|
|
|
|
- name: http
|
|
|
|
|
protocol: TCP
|
|
|
|
|
{{- toYaml .Values.pump.service.http| nindent 4 }}
|
|
|
|
|
selector:
|
|
|
|
|
app: {{ .Values.pump.name }}
|
|
|
|
|
sessionAffinity: None
|
|
|
|
|
type: {{ .Values.serviceType }}
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
`{{ .Values.pump.name }}`会被`deployments/iam/values.yaml`文件中`pump.name`的值替换。上面的模版语法扩展了 Go `text/template`包的语法:
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
# 这种方式定义的模版,会去除test模版尾部所有的空行
|
|
|
|
|
{{- define "test"}}
|
|
|
|
|
模版内容
|
|
|
|
|
{{- end}}
|
|
|
|
|
|
|
|
|
|
# 去除test模版头部的第一个空行
|
|
|
|
|
{{- template "test" }}
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
下面是用于YAML文件前置空格的语法:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
# 这种方式定义的模版,会去除test模版头部和尾部所有的空行
|
|
|
|
|
{{- define "test" -}}
|
|
|
|
|
模版内容
|
|
|
|
|
{{- end -}}
|
|
|
|
|
|
|
|
|
|
# 可以在test模版每一行的头部增加4个空格,用于YAML文件的对齐
|
|
|
|
|
{{ include "test" | indent 4}}
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
最后,这里有三点需要你注意:
|
|
|
|
|
|
|
|
|
|
* Chart名称必须是小写字母和数字,单词之间可以使用横杠`-`分隔,Chart名称中不能用大写字母,也不能用下划线,`.`号也不行。
|
|
|
|
|
* 尽可能使用[SemVer 2](https://semver.org/)来表示版本号。
|
|
|
|
|
* YAML 文件应该按照双空格的形式缩进(一定不要使用tab键)。
|
|
|
|
|
|
|
|
|
|
**第二步,**编辑 `iam` 目录下的Chart文件。
|
|
|
|
|
|
|
|
|
|
我们可以基于`helm create`生成的模板Chart来构建自己的Chart包。这里我们添加了创建iam-apiserver、iam-authz-server、iam-pump、iamctl服务需要的YAML格式的Kubernetes资源文件模板:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
$ ls -1 iam/templates/*.yaml
|
|
|
|
|
iam/templates/hpa.yaml # Kubernetes HPA模板文件
|
|
|
|
|
iam/templates/iam-apiserver-deployment.yaml # iam-apiserver服务deployment模板文件
|
|
|
|
|
iam/templates/iam-apiserver-service.yaml # iam-apiserver服务service模板文件
|
|
|
|
|
iam/templates/iam-authz-server-deployment.yaml # iam-authz-server服务deployment模板文件
|
|
|
|
|
iam/templates/iam-authz-server-service.yaml # iam-authz-server服务service模板文件
|
|
|
|
|
iam/templates/iamctl-deployment.yaml # iamctl服务deployment模板文件
|
|
|
|
|
iam/templates/iam-pump-deployment.yaml # iam-pump服务deployment模板文件
|
|
|
|
|
iam/templates/iam-pump-service.yaml # iam-pump服务service模板文件
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
模板的具体内容,你可以查看[deployments/iam/templates/](https://github.com/marmotedu/iam/tree/v1.1.0/deployments/iam/templates)。
|
|
|
|
|
|
|
|
|
|
在编辑 Chart 时,我们可以通过 `helm lint` 验证格式是否正确,例如:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
$ helm lint iam
|
|
|
|
|
==> Linting iam
|
|
|
|
|
|
|
|
|
|
1 chart(s) linted, 0 chart(s) failed
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
`0 chart(s) failed` 说明当前Iam Chart包是通过校验的。
|
|
|
|
|
|
|
|
|
|
**第三步,**修改Chart的配置文件,添加自定义配置。
|
|
|
|
|
|
|
|
|
|
我们可以编辑`deployments/iam/values.yaml`文件,定制自己的配置。具体配置你可以参考[deployments/iam/values.yaml](https://github.com/marmotedu/iam/blob/v1.1.0/deployments/iam/values.yaml)。
|
|
|
|
|
|
|
|
|
|
在修改 `values.yaml` 文件时,你可以参考下面这些最佳实践。
|
|
|
|
|
|
|
|
|
|
* 变量名称以小写字母开头,单词按驼峰区分,例如`chickenNoodleSoup`。
|
|
|
|
|
* 给所有字符串类型的值加上引号。
|
|
|
|
|
* 为了避免整数转换问题,将整型存储为字符串更好,并用 `{{ int $value }}` 在模板中将字符串转回整型。
|
|
|
|
|
* `values.yaml`中定义的每个属性都应该文档化。文档字符串应该以它要描述的属性开头,并至少给出一句描述。例如:
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
# serverHost is the host name for the webserver
|
|
|
|
|
serverHost: example
|
|
|
|
|
# serverPort is the HTTP listener port for the webserver
|
|
|
|
|
serverPort: 9191
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
这里需要注意,所有的Helm内置变量都以大写字母开头,以便与用户定义的value进行区分,例如`.Release.Name`、`.Capabilities.KubeVersion`。
|
|
|
|
|
|
|
|
|
|
为了安全,values.yaml中只配置Kubernetes资源相关的配置项,例如Deployment副本数、Service端口等。至于iam-apiserver、iam-authz-server、iam-pump、iamctl组件的配置文件,我们创建单独的ConfigMap,并在Deployment中引用。
|
|
|
|
|
|
|
|
|
|
**第四步,**打包Chart,并上传到Chart仓库中。
|
|
|
|
|
|
|
|
|
|
这是一个可选步骤,可以根据你的实际需要来选择。如果想了解具体操作,你可以查看 [Helm chart 仓库](https://helm.sh/zh/docs/topics/chart_repository)获取更多信息。
|
|
|
|
|
|
|
|
|
|
最后,IAM应用的Chart包见[deployments/iam](https://github.com/marmotedu/iam/tree/v1.1.0/deployments/iam)。
|
|
|
|
|
|
|
|
|
|
## IAM Chart部署
|
|
|
|
|
|
|
|
|
|
上面,我们制作了IAM应用的Chart包,接下来我们就使用这个Chart包来一键创建IAM应用。IAM Chart部署一共分为10个步骤,你可以跟着我一步步操作下。
|
|
|
|
|
|
|
|
|
|
**第一步,**配置`scripts/install/environment.sh`。
|
|
|
|
|
|
|
|
|
|
`scripts/install/environment.sh`文件中包含了各类自定义配置,你主要配置下面这些跟数据库相关的就可以,其他配置使用默认值。
|
|
|
|
|
|
|
|
|
|
* MariaDB配置:environment.sh文件中以`MARIADB_`开头的变量。
|
|
|
|
|
* Redis配置:environment.sh文件中以`REDIS_`开头的变量。
|
|
|
|
|
* MongoDB配置:environment.sh文件中以`MONGO_`开头的变量。
|
|
|
|
|
|
|
|
|
|
**第二步,**创建IAM应用的配置文件。
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
$ cd ${IAM_ROOT}
|
|
|
|
|
$ make gen.defaultconfigs # 生成iam-apiserver、iam-authz-server、iam-pump、iamctl组件的默认配置文件
|
|
|
|
|
$ make gen.ca # 生成 CA 证书
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
上面的命令会将IAM的配置文件存放在目录`${IAM_ROOT}/_output/configs/`下。
|
|
|
|
|
|
|
|
|
|
**第三步,**创建 `iam` 命名空间。
|
|
|
|
|
|
|
|
|
|
我们将IAM应用涉及到的各类资源都创建在`iam`命名空间中。将IAM资源创建在独立的命名空间中,不仅方便维护,还可以有效避免影响其他Kubernetes资源。
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
$ kubectl create namespace iam
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**第四步,**将IAM各服务的配置文件,以ConfigMap资源的形式保存在Kubernetes集群中。
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
$ kubectl -n iam create configmap iam --from-file=${IAM_ROOT}/_output/configs/
|
|
|
|
|
$ kubectl -n iam get configmap iam
|
|
|
|
|
NAME DATA AGE
|
|
|
|
|
iam 4 13s
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**第五步,**将IAM各服务使用的证书文件,以ConfigMap资源的形式保存在Kubernetes集群中。
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
$ kubectl -n iam create configmap iam-cert --from-file=${IAM_ROOT}/_output/cert
|
|
|
|
|
$ kubectl -n iam get configmap iam-cert
|
|
|
|
|
NAME DATA AGE
|
|
|
|
|
iam-cert 14 12s
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**第六步,**创建镜像仓库访问密钥。
|
|
|
|
|
|
|
|
|
|
在准备阶段,我们开通了[腾讯云镜像仓库服务](http://ccr.ccs.tencentyun.com),并创建了用户`10000099``xxxx`,密码为`iam59!z$`。
|
|
|
|
|
|
|
|
|
|
接下来,我们就可以创建docker-registry secret了。Kubernetes在下载Docker镜像时,需要docker-registry secret来进行认证。创建命令如下:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
$ kubectl -n iam create secret docker-registry ccr-registry --docker-server=ccr.ccs.tencentyun.com --docker-username=10000099xxxx --docker-password='iam59!z$'
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**第七步,**创建Docker镜像,并Push到镜像仓库。
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
$ make push REGISTRY_PREFIX=ccr.ccs.tencentyun.com/marmotedu VERSION=v1.1.0
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**第八步,**安装IAM Chart包。
|
|
|
|
|
|
|
|
|
|
在[49讲](https://time.geekbang.org/column/article/420940)里,我介绍了4种安装Chart包的方法。这里,我们通过未打包的IAM Chart路径来安装,安装方法如下:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
$ cd ${IAM_ROOT}
|
|
|
|
|
$ helm -n iam install iam deployments/iam
|
|
|
|
|
NAME: iam
|
|
|
|
|
LAST DEPLOYED: Sat Aug 21 17:46:56 2021
|
|
|
|
|
NAMESPACE: iam
|
|
|
|
|
STATUS: deployed
|
|
|
|
|
REVISION: 1
|
|
|
|
|
TEST SUITE: None
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
执行 `helm install` 后,Kubernetes会自动部署应用,等到IAM应用的Pod都处在 `Running` 状态时,说明IAM应用已经成功安装:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
$ kubectl -n iam get pods|grep iam
|
|
|
|
|
iam-apiserver-cb4ff955-hs827 1/1 Running 0 66s
|
|
|
|
|
iam-authz-server-7fccc7db8d-chwnn 1/1 Running 0 66s
|
|
|
|
|
iam-pump-78b57b4464-rrlbf 1/1 Running 0 66s
|
|
|
|
|
iamctl-59fdc4995-xrzhn 1/1 Running 0 66s
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**第九步,**测试IAM应用。
|
|
|
|
|
|
|
|
|
|
我们通过`helm install`在`iam`命令空间下创建了一个测试Deployment `iamctl`。你可以登陆`iamctl` Deployment所创建出来的Pod,执行一些运维操作和冒烟测试。登陆命令如下:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
$ kubectl -n iam exec -it `kubectl -n iam get pods -l app=iamctl | awk '/iamctl/{print $1}'` -- bash
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
登陆到`iamctl-xxxxxxxxxx-xxxxx` Pod中后,你就可以执行运维操作和冒烟测试了。
|
|
|
|
|
|
|
|
|
|
**先来看运维操作。**iamctl工具以子命令的方式对外提供功能,你可以使用它提供的各类功能,如下图所示:
|
|
|
|
|
|
|
|
|
|
![图片](https://static001.geekbang.org/resource/image/69/y2/693f608aa571cbfd6e06c8cfdb242yy2.png?wh=1920x337)
|
|
|
|
|
|
|
|
|
|
**再来看冒烟测试:**
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
# cd /opt/iam/scripts/install
|
|
|
|
|
# ./test.sh iam::test::smoke
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
如果`./test.sh iam::test::smoke`命令打印的输出中,最后一行为`congratulations, smoke test passed!`字符串,就说明IAM应用安装成功。如下图所示:
|
|
|
|
|
|
|
|
|
|
![图片](https://static001.geekbang.org/resource/image/9d/8c/9dcc557952b3586f7b37b065bf2bd58c.png?wh=1920x314)
|
|
|
|
|
|
|
|
|
|
**第十步,**销毁EKS集群的资源。
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
$ kubectl delete namespace iam
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
你可以根据需要选择是否删除EKS集群,如果不需要了就可以选择删除。
|
|
|
|
|
|
|
|
|
|
## IAM应用多环境部署
|
|
|
|
|
|
|
|
|
|
在实际的项目开发中,我们需要将IAM应用部署到不同的环境中,不同环境的配置文件是不同的,那么IAM项目是如何进行多环境部署的呢?
|
|
|
|
|
|
|
|
|
|
IAM项目在configs目录下创建了多个Helm values文件(格式为`values-{envName}-env.yaml`):
|
|
|
|
|
|
|
|
|
|
* values-test-env.yaml,测试环境Helm values文件。
|
|
|
|
|
* values-pre-env.yaml,预发环境Helm values文件。
|
|
|
|
|
* values-prod-env.yaml,生产环境Helm values文件。
|
|
|
|
|
|
|
|
|
|
在部署IAM应用时,我们在命令行指定`-f`参数,例如:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
$ helm -n iam install -f configs/values-test-env.yaml iam deployments/iam # 安装到测试环境。
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## 总结
|
|
|
|
|
|
|
|
|
|
这一讲,我们通过 `helm create iam` 创建了一个模板Chart,并基于这个模板Chart包进行了二次开发,最终创建了IAM应用的Helm Chart包:[deployments/iam](https://github.com/marmotedu/iam/tree/v1.1.0/deployments/iam)。
|
|
|
|
|
|
|
|
|
|
有了Helm Chart包,我们就可以通过 `helm -n iam install iam deployments/iam` 命令来一键部署好整个IAM应用。当IAM应用中的所有Pod都处在 `Running` 状态后,说明IAM应用被成功部署。
|
|
|
|
|
|
|
|
|
|
最后,我们可以登录iamctl容器,执行 `test.sh iam::test::smoke` 命令,来对IAM应用进行冒烟测试。
|
|
|
|
|
|
|
|
|
|
## 课后练习
|
|
|
|
|
|
|
|
|
|
1. 试着在Helm Chart中加入MariaDB、MongoDB、Redis模板,通过Helm一键部署好整个IAM应用。
|
|
|
|
|
2. 试着通过 `helm` 命令升级、回滚和删除IAM应用。
|
|
|
|
|
|
|
|
|
|
欢迎你在留言区与我交流讨论,我们下一讲见。
|
|
|
|
|
|