update helm to v3

pull/399/head
Jimmy song 2020-05-24 21:47:32 +08:00
parent e830e68f4e
commit 194f1b835d
5 changed files with 126 additions and 653 deletions

View File

@ -78,7 +78,7 @@ Kubernetes Handbook开源于2017年3月并在其后不断完善是第一本
## 云原生社区
云原生社区是一个有技术、有温度、有情怀的开源社区,由 [Jimmy 和他的伙伴们](https://cloudnative.to/team)成立于 2020 年 5 月 12 日,秉持“共识、共治、共建、共享”的原则。立足中国,面向世界,企业中立,旨在借助开源打破企业的边界,关注技术人的成长,面向全球华人,促进中国云原生开源的发展。欢迎[加入我们](https://cloudnative.to/contact/)
云原生社区是一个有技术、有温度、有情怀的开源社区,由 [Jimmy 和他的伙伴们](https://cloudnative.to/team)成立于 2020 年 5 月 12 日,秉持“共识、共治、共建、共享”的原则。立足中国,面向世界,企业中立,旨在借助开源打破企业的边界,关注技术人的成长,面向全球华人,促进中国云原生开源的发展。云原生官方网站 <https://cloudnative.to>,关注社区微信公众号,获取加入方式。
<p align="center">
<img src="images/cloud-native-wechat.jpg" alt="云原生社区微信公众号" title="云原生社区微信公众号"/>

View File

@ -6,7 +6,8 @@
"links": {
"sidebar": {
"回到主页": "https://jimmysong.io",
"Awesome Cloud Native": "https://jimmysong.io/awesome-cloud-native"
"Awesome Cloud Native": "https://jimmysong.io/awesome-cloud-native",
"云原生社区": "https://cloudnative.to"
}
},
"plugins": [
@ -50,7 +51,7 @@
"size": "small"
},
"tbfed-pagefooter": {
"copyright": "<p><a href=https://time.geekbang.org/column/intro/292?code=EhFrzVKvIro8U06UyaeLCCdmbpk7g010iXprzDxW17I%3D&utm_term=SPoster>给开发者和架构师的云计算指南 - 极客时间专栏《深入浅出云计算》</a> | <a href=https://jimmysong.io/contact/>加入云原生社区</a></p>Copyright © 2017-2020 | Distributed under <a href=https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh>CC BY 4.0</a> | <a href=https://jimmysong.io>jimmysong.io</a>",
"copyright": "<a href=https://jimmysong.io/contact/>加入中国最大的有技术、有温度、有情怀的云原生社区</a></p>Copyright © 2017-2020 | Distributed under <a href=https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh>CC BY 4.0</a> | <a href=https://jimmysong.io>jimmysong.io</a>",
"modify_label": " Updated at ",
"modify_format": "YYYY-MM-DD HH:mm:ss"
},

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

View File

@ -1,713 +1,185 @@
# 使用Helm管理kubernetes应用
**本文基于 Helm v2待更新 Helm v3 的说明。**
[Helm](http://helm.sh) 是一个 Kubernetes 应用的包管理工具,用来管理 [chart](https://github.com/helm/charts)——预先配置好的安装包资源,有点类似于 Ubuntu 的 APT 和 CentOS 中的 YUM。2019 年 11 月 13 日,[Helm 3 发布](https://helm.sh/blog/helm-3-released/)2020 年 4 月 30 日,从 CNCF 中[毕业](https://helm.sh/blog/celebrating-helms-cncf-graduation/)。本文基于 Helm 3。
读完本文后您应该可以自己创建chart并创建自己的私有chart仓库
Helm chart 是用来封装 Kubernetes 原生应用程序的 YAML 文件,可以在你部署应用的时候自定义应用程序的一些 metadata便与应用程序的分发
[Helm](http://helm.sh)是一个kubernetes应用的包管理工具用来管理[charts](https://github.com/kubernetes/charts)——预先配置好的安装包资源有点类似于Ubuntu的APT和CentOS中的yum。
Helm chart是用来封装kubernetes原生应用程序的yaml文件可以在你部署应用的时候自定义应用程序的一些metadata便与应用程序的分发。
Helm和charts的主要作用
Helm 和 chart 的主要作用是:
- 应用程序封装
- 版本管理
- 依赖检查
- 便于应用程序分发
## 安装Helm
下面是 Helm 的架构图。
![Helm 架构图(来自 IBM Developer Blog](../images/helm-chart.png)
Helm 可以安装本地或者远程的 chart当 chart 安装到 Kubernetes 中后就会创建一个 release每次更新该 chart 的配置并执行 `helm upgrade` release 的版本数就会加 1。同一个 chart 可以部署多次。
## 安装 Helm
**前提要求**
- Kubernetes1.5以上版本
- 集群可访问到的镜像仓库
- 执行helm命令的主机可以访问到kubernetes集群
- Kubernetes 1.5 以上版本
- 执行 helm 命令的主机可以访问到 Kubernetes 集群
**安装步骤**
请参考 [Helm 官方文档](https://helm.sh/docs/intro/install/)安装,对于 Mac 用户可以直接运行 `brew install helm` 安装即可。
首先需要安装helm客户端
## Chart 说明
下面我们将一步步创建一个 chart 来说明其组织结构。
首先使用 `helm create mychart` 创建一个名为 `mychart` 的示例,我们再使用 `tree mychart` 命令看一下 chart 的目录结构。
```bash
curl https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get > get_helm.sh
chmod 700 get_helm.sh
./get_helm.sh
mychart
├── Chart.yaml
├── charts # 该目录保存其他依赖的 chart子 chart
├── templates # chart 配置模板,用于渲染最终的 Kubernetes YAML 文件
│   ├── NOTES.txt # 用户运行 helm install 时候的提示信息
│   ├── _helpers.tpl # 用于创建模板时的帮助类
│   ├── deployment.yaml # Kubernetes deployment 配置
│   ├── ingress.yaml # Kubernetes ingress 配置
│   ├── service.yaml # Kubernetes service 配置
│   ├── serviceaccount.yaml # Kubernetes serviceaccount 配置
│   └── tests
│   └── test-connection.yaml
└── values.yaml # 定义 chart 模板中的自定义配置的默认值,可以在执行 helm install 或 helm update 的时候覆盖
```
创建tiller的`serviceaccount`和`clusterrolebinding`
以上仅为 helm 为我们自动创建的目录结构,我们还可以在 `templates` 目录加其他 Kubernetes 对象的配置,比如 `ConfigMap`、`DaemonSet` 等。
```bash
kubectl create serviceaccount --namespace kube-system tiller
kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
```
然后安装helm服务端tiller目前最新版 v2.14.2,若无法访问 `gcr.io`,可以使用阿里云镜像,如:
```bash
helm init --upgrade -i registry.cn-hangzhou.aliyuncs.com/google_containers/tiller:v2.12.2 --stable-repo-url https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
```
我们使用`-i`指定自己的镜像,因为官方的镜像因为某些原因无法拉取,官方镜像地址是:`gcr.io/kubernetes-helm/tiller:v2.14.2`,使用`helm version`可查看helm客户端版本。
为应用程序设置`serviceAccount`
```bash
kubectl patch deploy --namespace kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}'
```
检查是否安装成功:
```bash
$ kubectl -n kube-system get pods|grep tiller
tiller-deploy-2372561459-f6p0z 1/1 Running 0 1h
$ helm version
Client: &version.Version{SemVer:"v2.14.2", GitCommit:"a8b13cc5ab6a7dbef0a58f5061bcc7c0c61598e7", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.12.2", GitCommit:"7d2b0c73d734f6586ed222a567c5d103fed435be", GitTreeState:"clean"}
```
## 创建自己的chart
我们创建一个名为`mychart`的chart看一看chart的文件结构。
```bash
$ helm create mongodb
$ tree mongodb
mongodb
├── Chart.yaml #Chart本身的版本和配置信息
├── charts #依赖的chart
├── templates #配置模板目录
│   ├── NOTES.txt #helm提示信息
│   ├── _helpers.tpl #用于修改kubernetes objcet配置的模板
│   ├── deployment.yaml #kubernetes Deployment object
│   └── service.yaml #kubernetes Serivce
└── values.yaml #kubernetes object configuration
2 directories, 6 files
```
### 模板
`Templates`目录下是yaml文件的模板遵循[Go template](https://golang.org/pkg/text/template/)语法。使用过[Hugo](https://gohugo.io)的静态网站生成工具的人应该对此很熟悉。
我们查看下`deployment.yaml`文件的内容。
我们查看下使用 `helm create` 命令自动生成的 `templates/service.yaml` 文件。
```yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: {{ template "fullname" . }}
labels:
chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}"
spec:
replicas: {{ .Values.replicaCount }}
template:
metadata:
labels:
app: {{ template "fullname" . }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- containerPort: {{ .Values.service.internalPort }}
livenessProbe:
httpGet:
path: /
port: {{ .Values.service.internalPort }}
readinessProbe:
httpGet:
path: /
port: {{ .Values.service.internalPort }}
resources:
{{ toyaml .Values.resources | indent 12 }}
```
这是该应用的Deployment的yaml配置文件其中的双大括号包扩起来的部分是Go template其中的Values是在`values.yaml`文件中定义的:
```yaml
# Default values for mychart.
# This is a yaml-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
image:
repository: nginx
tag: stable
pullPolicy: IfNotPresent
service:
name: nginx
type: ClusterIP
externalPort: 80
internalPort: 80
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi
```
比如在`Deployment.yaml`中定义的容器镜像`image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"`其中的:
- `.Values.image.repository`就是nginx
- `.Values.image.tag`就是stable
以上两个变量值是在create chart的时候自动生成的默认值。
我们将默认的镜像地址和tag改成我们自己的镜像`harbor-001.jimmysong.io/library/nginx:1.9`。
### 检查配置和模板是否有效
当使用kubernetes部署应用的时候实际上讲templates渲染成最终的kubernetes能够识别的yaml格式。
使用`helm install --dry-run --debug <chart_dir>`命令来验证chart配置。该输出中包含了模板的变量配置与最终渲染的yaml文件。
```bash
$ helm install --dry-run --debug mychart
Created tunnel using local port: '58406'
SERVER: "localhost:58406"
CHART PATH: /Users/jimmy/Workspace/github/bitnami/charts/incubator/mean/charts/mychart
NAME: filled-seahorse
REVISION: 1
RELEASED: Tue Oct 24 18:57:13 2017
CHART: mychart-0.1.0
USER-SUPPLIED VALUES:
{}
COMPUTED VALUES:
image:
pullPolicy: IfNotPresent
repository: harbor-001.jimmysong.io/library/nginx
tag: 1.9
replicaCount: 1
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi
service:
externalPort: 80
internalPort: 80
name: nginx
type: ClusterIP
HOOKS:
MANIFEST:
---
# Source: mychart/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: filled-seahorse-mychart
name: {{ include "mychart.fullname" . }}
labels:
chart: "mychart-0.1.0"
{{- include "mychart.labels" . | nindent 4 }}
spec:
type: ClusterIP
type: {{ .Values.service.type }}
ports:
- port: 80
targetPort: 80
protocol: TCP
name: nginx
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
selector:
app: filled-seahorse-mychart
---
# Source: mychart/templates/deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: filled-seahorse-mychart
labels:
chart: "mychart-0.1.0"
spec:
replicas: 1
template:
metadata:
labels:
app: filled-seahorse-mychart
spec:
containers:
- name: mychart
image: "harbor-001.jimmysong.io/library/nginx:1.9"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
livenessProbe:
httpGet:
path: /
port: 80
readinessProbe:
httpGet:
path: /
port: 80
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi
{{- include "mychart.selectorLabels" . | nindent 4 }}
```
我们可以看到Deployment和Service的名字前半截由两个随机的单词组成最后才是我们在`values.yaml`中配置的值
可以看到其中有很多`{{ }}` 包围的字段,这是使用的 [Go template](https://golang.org/pkg/text/template/) 创建的自定义字段,其中 `mychart` 开头的都是在 `_helpers.tpl` 中生成的定义。
### 部署到kubernetes
例如 `_helpers.tpl` 中对 `chart.fullname` 的定义:
在`mychart`目录下执行下面的命令将nginx部署到kubernetes集群上。
```bash
helm install .
NAME: eating-hound
LAST DEPLOYED: Wed Oct 25 14:58:15 2017
NAMESPACE: default
STATUS: DEPLOYED
RESOURCES:
==> v1/Service
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
eating-hound-mychart 10.254.135.68 <none> 80/TCP 0s
==> extensions/v1beta1/Deployment
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
eating-hound-mychart 1 1 1 0 0s
NOTES:
1. Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace default -l "app=eating-hound-mychart" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl port-forward $POD_NAME 8080:80
```go
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "mychart.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}
```
现在nginx已经部署到kubernetes集群上本地执行提示中的命令在本地主机上访问到nginx实例。
```bash
export POD_NAME=$(kubectl get pods --namespace default -l "app=eating-hound-mychart" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl port-forward $POD_NAME 8080:80
```
在本地访问`http://127.0.0.1:8080`即可访问到nginx。
**查看部署的relaese**
```bash
$ helm list
NAME REVISION UPDATED STATUS CHART NAMESPACE
eating-hound 1 Wed Oct 25 14:58:15 2017 DEPLOYED mychart-0.1.0 default
```
**删除部署的release**
```bash
$ helm delete eating-hound
release "eating-hound" deleted
```
### 打包分享
我们可以修改`Chart.yaml`中的helm chart配置信息然后使用下列命令将chart打包成一个压缩文件。
```bash
helm package .
```
打包出`mychart-0.1.0.tgz`文件。
### 依赖
我们可以在`requirements.yaml`中定义应用所依赖的chart例如定义对`mariadb`的依赖:
我们再看下 `values.yaml` 文件中有这样的一段配置:
```yaml
dependencies:
- name: mariadb
version: 0.6.0
repository: https://kubernetes-charts.storage.googleapis.com
service:
type: ClusterIP
port: 80
```
使用`helm lint . `命令可以检查依赖和模板配置是否正确
在使用 `helm install``helm update` 时,会渲染 `templates/service.yaml` 文件中的 `{{ .Values.service.type }}``{{ .Values.service.port }}` 的值。
### 安装源
## 使用 Helm
使用第三方chat库
Helm 常用命令如下:
- 添加fabric8库
- `helm create`:在本地创建新的 chart
- `helm dependency`:管理 chart 依赖;
- `helm intall`:安装 chart
- `helm lint`:检查 chart 配置是否有误;
- `helm list`:列出所有 release
- `helm package`:打包本地 chart
- `helm repo`:列出、增加、更新、删除 chart 仓库;
- `helm rollback`:回滚 release 到历史版本;
- `helm pull`:拉取远程 chart 到本地;
- `helm search`:使用关键词搜索 chart
- `helm uninstall`:卸载 release
- `helm upgrade`:升级 release
使用 `helm -h` 可以查看 Helm 命令行使用详情,请参考 [Helm 文档](https://helm.sh/docs/helm/helm/)。
### 安装 chart
安装 chart 的命令格式为:
```bash
$ helm repo add fabric8 https://fabric8.io/helm
helm install [NAME] [CHART] [flags]
```
- 搜索fabric8提供的工具主要就是fabric8-platform工具包包含了CI、CD的全套工具
示例:
```bash
$ helm search fabric8
# 安装本地 chart
helm install -f myvalues.yaml myredis ./redis
# 指定变量
helm install --set name=prod myredis ./redis
# 指定变量的值为 string 类型
helm install --set-string long_int=1234567890 myredis ./redis
# 指定引用的文件地址
helm install --set-file my_script=dothings.sh myredis ./redis
# 同时指定多个变量
helm install --set foo=bar --set foo=newbar myredis ./redis
```
我们在前面安装chart可以通过HTTP server的方式提供。
其中:
- `myvalues.yaml`:自定义变量配置文件;
- `myredis`release 名称;
- `./redis`:本地的 chart 目录;
Helm chart 安装后会转化成 Kubernetes 中的资源对象,生成一个 chart release可以使用 `helm list` 命令查看。
关于 `helm intsall` 详细用法见:<https://helm.sh/docs/helm/helm_install/>
## 升级和回滚 chart
要想升级 chart 可以修改本地的 chart 配置并执行:
```bash
$ helm serve
Regenerating index. This may take a moment.
Now serving you on 127.0.0.1:8879
helm upgrade [RELEASE] [CHART] [flags]
```
访问`http://localhost:8879`可以看到刚刚安装的chart。
![Helm chart源](../images/helm-charts-repository.jpg)
点击链接即可以下载chart的压缩包。
## 注意事项
下面列举一些常见问题,和在解决这些问题时候的注意事项。
### 服务依赖管理
所有使用helm部署的应用中如果没有特别指定chart的名字都会生成一个随机的`Release name`,例如`romping-frog`、`sexy-newton`等跟启动docker容器时候容器名字的命名规则相同而真正的资源对象的名字是在YAML文件中定义的名字我们成为`App name`,两者连接起来才是资源对象的实际名字:`Release name`-`App name`。
而使用helm chart部署的包含依赖关系的应用都会使用同一套`Release name`在配置YAML文件的时候一定要注意在做服务发现时需要配置的服务地址如果使用环境变量的话需要像下面这样配置。
```yaml
env:
- name: SERVICE_NAME
value: "{{ .Release.Name }}-{{ .Values.image.env.SERVICE_NAME }}"
```
这是使用了Go template的语法。至于`{{ .Values.image.env.SERVICE_NAME }}`的值是从`values.yaml`文件中获取的,所以需要在`values.yaml`中增加如下配置:
```yaml
image:
env:
SERVICE_NAME: k8s-app-monitor-test
```
### 解决本地chart依赖
在本地当前chart配置的目录下启动helm server我们不指定任何参数直接使用默认端口启动。
使用 `helm ls` 的命令查看当前运行的 chart 的 release 版本,并使用下面的命令回滚到历史版本:
```bash
helm serve
helm rollback <RELEASE> [REVISION] [flags]
```
将该repo加入到repo list中。
### 卸载 chart
要想卸载 chart 可以使用下面的命令。
```bash
helm repo add local http://localhost:8879
helm uninstall RELEASE_NAME [...] [flags]
```
在浏览器中访问<http://localhost:8879>可以看到所有本地的chart。
然后下载依赖到本地。
```bash
helm dependency update
```
这样所有的chart都会下载到本地的`charts`目录下。
### 设置helm命令自动补全
为了方便helm命令的使用helm提供了自动补全功能如果使用zsh请执行
```bash
source <(helm completion zsh)
```
如果使用bash请执行
```bash
source <(helm completion bash)
```
## 部署MEAN测试案例
MEAN是用来构建网站和web应用的免费开源的JavaScript软件栈该软件栈包括MongoDB、Express.js、Angular和Node.js。
**下载charts**
```bash
$ git clone https://github.com/bitnami/charts.git
$ cd charts/incubator/mean
$ helm dep list
NAME VERSION REPOSITORY STATUS
mongodb 0.4.x https://kubernetes-charts.storage.googleapis.com/ missing
```
缺少mongodb的依赖需要更新一下chart。
**注**`https://kubernetes-charts.storage.googleapis.com/`是Google维护的chart库访问该地址可以看到所有的chart列表。
```bash
$ helm dep update
Hang tight while we grab the latest from your chart repositories...
...Unable to get an update from the "local" chart repository (http://127.0.0.1:8879/charts):
Get http://127.0.0.1:8879/charts/index.yaml: dial tcp 127.0.0.1:8879: getsockopt: connection refused
...Successfully got an update from the "stable" chart repository
Update Complete. ⎈Happy Helming!⎈
Saving 1 charts
Downloading mongodb from repo https://kubernetes-charts.storage.googleapis.com/
```
所有的image都在 `values.yaml` 文件中配置。
下载缺失的chart。
```bash
$ helm dep build
Hang tight while we grab the latest from your chart repositories...
...Unable to get an update from the "local" chart repository (http://127.0.0.1:8879/charts):
Get http://127.0.0.1:8879/charts/index.yaml: dial tcp 127.0.0.1:8879: getsockopt: connection refused
...Successfully got an update from the "stable" chart repository
Update Complete. ⎈Happy Helming!⎈
Saving 1 charts
Downloading mongodb from repo https://kubernetes-charts.storage.googleapis.com/
```
**修改mongodb chart配置**
将刚才下载的`charts/mongodb-0.4.17.tgz`给解压后,修改其中的配置:
- 将`persistence`下的`enabled`设置为false
- 将image修改为我们的私有镜像harbor-001.jimmysong.io/library/bitnami-mongodb:3.4.9-r1
执行`helm install --dry-run --debug .`确定模板无误。
将修改后的mongodb chart打包在mongodb的目录下执行
```bash
helm package .
```
现在再访问前面启动的helm server `http://localhost:8879`将可以在页面上看到mongodb-0.4.17这个chart。
我们对官方chart配置做了如下修改后推送到了自己的chart仓库
- `requirements.yaml`和`requirements.lock`文件中的`repository`为`http://localhost:8879`
- 将`values.yaml`中的`storageClass`设置为`null`
- 将`values.yaml`中的`Image`都改为私有镜像
- `repositroy`都设置为`http://localhost:8879`
**注**因为我们没有使用PVC所以将所有的关于持久化存储的配置都设置为false了。
**部署MEAN**
在`mean`目录下执行:
```bash
helm install .
NAME: orbiting-platypus
LAST DEPLOYED: Wed Oct 25 16:21:48 2017
NAMESPACE: default
STATUS: DEPLOYED
RESOURCES:
==> v1/Secret
NAME TYPE DATA AGE
orbiting-platypus-mongodb Opaque 2 2s
==> v1/ConfigMap
NAME DATA AGE
orbiting-platypus-mean 1 2s
==> v1/Service
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
orbiting-platypus-mongodb 10.254.144.208 <none> 27017/TCP 2s
orbiting-platypus-mean 10.254.165.23 <none> 80/TCP 2s
==> extensions/v1beta1/Deployment
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
orbiting-platypus-mean 1 1 1 0 2s
orbiting-platypus-mongodb 1 1 1 0 2s
NOTES:
Get the URL of your Node app by running:
export POD_NAME=$(kubectl get pods --namespace default -l "app=orbiting-platypus-mean" -o jsonpath="{.items[0].metadata.name}")
echo http://127.0.0.1:8080/
kubectl port-forward $POD_NAME 8080:80
```
这样MEAN软件栈就部署到你的kuberentes集群里面了默认是在default namespace下
**验证检查**
为了验证MEAN是否安装成功过可以使用`kubectl get pods`查看pod是否启动完成会先启动mongodb的pod然后启动MEAN中的4步init。
**访问Web UI**
在Ingress中增加如下配置
```yaml
- host: mean.jimmysong.io
http:
paths:
- backend:
serviceName: orbiting-platypus-mean
servicePort: 80
path: /
```
然后在页面中更新ingress:
```bash
kubectl repalce -f ingress.yaml
```
关于Ingress配置请参考[边缘节点配置](../practice/edge-node-configuration.md)
然后在本地的`/etc/hosts`文件中增加一条配置:
```ini
172.20.0.119 mean.jimmysong.io
```
**注**172.20.0.119即边缘节点的VIP。
因为该页面需要加载google的angularjs、还有两个css在国内无法访问可以使用curl测试
```bash
curl mean.jimmysong.io
```
将会返回HTML内容
```html
<!doctype html>
<!-- ASSIGN OUR ANGULAR MODULE -->
<html ng-app="scotchTodo">
<head>
<!-- META -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Optimize mobile viewport -->
<title>Node/Angular Todo App</title>
<!-- SCROLLS -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">
<!-- load bootstrap -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css">
<style>
html {
overflow-y: scroll;
}
body {
padding-top: 50px;
}
#todo-list {
margin-bottom: 30px;
}
#todo-form {
margin-bottom: 50px;
}
</style>
<!-- SPELLS -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
<!-- load angular -->
<script src="js/controllers/main.js"></script>
<!-- load up our controller -->
<script src="js/services/todos.js"></script>
<!-- load our todo service -->
<script src="js/core.js"></script>
<!-- load our main application -->
</head>
<!-- SET THE CONTROLLER -->
<body ng-controller="mainController">
<div class="container">
<!-- HEADER AND TODO COUNT -->
<div class="jumbotron text-center">
<h1>I'm a Todo-aholic <span class="label label-info">{{ todos.length }}</span></h1>
</div>
<!-- TODO LIST -->
<div id="todo-list" class="row">
<div class="col-sm-4 col-sm-offset-4">
<!-- LOOP OVER THE TODOS IN $scope.todos -->
<div class="checkbox" ng-repeat="todo in todos">
<label>
<input type="checkbox" ng-click="deleteTodo(todo._id)"> {{ todo.text }}
</label>
</div>
<p class="text-center" ng-show="loading">
<span class="fa fa-spinner fa-spin fa-3x"></span>
</p>
</div>
</div>
<!-- FORM TO CREATE TODOS -->
<div id="todo-form" class="row">
<div class="col-sm-8 col-sm-offset-2 text-center">
<form>
<div class="form-group">
<!-- BIND THIS VALUE TO formData.text IN ANGULAR -->
<input type="text" class="form-control input-lg text-center" placeholder="I want to buy a puppy that will love me forever" ng-model="formData.text">
</div>
<!-- createToDo() WILL CREATE NEW TODOS -->
<button type="submit" class="btn btn-primary btn-lg" ng-click="createTodo()">Add</button>
</form>
</div>
</div>
<div class="text-center text-muted">
<p>A demo by <a href="http://scotch.io">Scotch</a>.</p>
<p>Read the <a href="http://scotch.io/tutorials/javascript/creating-a-single-page-todo-app-with-node-and-angular">tutorial</a>.</p>
</div>
</div>
</body>
</html>
```
访问 http://mean.jimmysong.io 可以看到如下界面我在其中添加几条todo
![TODO应用的Web页面](../images/helm-mean-todo-aholic.jpg)
**注**Todo中的文字来自*What does the fox say*
测试完成后可以使用下面的命令将mean chart推送的本地chart仓库中。
在mean目录下执行
```bash
helm package .
```
再次刷新`http://localhost:8879`将可以看到如下三个chart
- mean
- mean-0.1.3
- mongodb
- mongodb-0.4.17
- mychart
- mychart-0.1.0
## 参考
- [Deploy, Scale And Upgrade An Application On Kubernetes With Helm](https://docs.bitnami.com/kubernetes/how-to/deploy-application-kubernetes-helm/)
- [Go template](https://golang.org/pkg/text/template/)
- [How To Create Your First Helm Chart](https://docs.bitnami.com/kubernetes/how-to/create-your-first-helm-chart/)
- [Speed deployment on Kubernetes with Helm Chart Quick yaml example from scratch](https://www.ibm.com/blogs/bluemix/2017/10/quick-example-helm-chart-for-kubernetes/)
- [Go template - golang.org](https://golang.org/pkg/text/template/)
- [Getting Started - helm.sh](https://helm.sh/docs/chart_template_guide/getting_started/)
- [Helm 用户指南 - whmzsu.github.io](https://whmzsu.github.io/helm-doc-zh-cn/)

View File

@ -2,4 +2,4 @@
Kubernetes虽然提供了多种容器编排对象例如Deployment、StatefulSet、DeamonSet、Job等还有多种基础资源封装例如ConfigMap、Secret、Serivce等但是一个应用往往有多个服务有的可能还要依赖持久化存储当这些服务之间直接互相依赖需要有一定的组合的情况下使用YAML文件的方式配置应用往往十分繁琐还容易出错这时候就需要服务编排工具。
服务编排管理工具就是构建在kubernetes的基础[object](../concepts/objects.md)之上,统筹各个服务之间的关系和依赖的。目前常用到的工具是 [Helm](https://github.com/kubernetes/helm)。
服务编排管理工具就是构建在kubernetes的基础[object](../concepts/objects.md)之上,统筹各个服务之间的关系和依赖的。目前常用到的工具是 [Helm](https://github.com/heml/helm)。