昆明呈贡教练 發表於 2019-7-5 07:57:00

kubernetes实战篇之helm完整示例

<blockquote>
<p>系列目录</p>
</blockquote>
<h2 id="构建一个-helm-chart">构建一个 Helm Chart</h2>
<p>下面我们通过一个完整的示例来学习如何使用 Helm 创建、打包、分发、安装、升级及回退Kubernetes应用。</p>
<p>创建一个名为 mychart 的 Chart</p>
<pre><code class="language-bash">$ helm create mychart
</code></pre>
<p>该命令创建了一个 mychart 目录,该目录结构如下所示。这里我们主要关注目录中的 Chart.yaml、values.yaml、NOTES.txt 和 Templates 目录。</p>
<pre><code class="language-bash">$ tree mychart
mychart
├── charts
├── Chart.yaml
├── templates
│&nbsp;&nbsp; ├── deployment.yaml
│&nbsp;&nbsp; ├── _helpers.tpl
│&nbsp;&nbsp; ├── ingress.yaml
│&nbsp;&nbsp; ├── NOTES.txt
│&nbsp;&nbsp; ├── service.yaml
│&nbsp;&nbsp; └── tests
│&nbsp;&nbsp;   └── test-connection.yaml
└── values.yaml
</code></pre>
<ul>
<li>Chart.yaml 用于描述这个 Chart的相关信息,包括名字、描述信息以及版本等。</li>
</ul>
<p>仅仅是一些简单的文本描述</p>
<ul>
<li>
<p>values.yaml 用于存储 templates 目录中模板文件中用到变量的值。</p>
</li>
<li>
<p>NOTES.txt 用于介绍 Chart 部署后的一些信息,例如:如何使用这个 Chart、列出缺省的设置等。</p>
</li>
<li>
<p>Templates 目录下是 YAML 文件的模板,该模板文件遵循 Go template 语法。</p>
</li>
</ul>
<p>Templates 目录下 YAML 文件模板的值默认都是在 values.yaml 里定义的,比如在 deployment.yaml 中定义的容器镜像。</p>
<p>image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"</p>
<p>其中的 <code>.Values.image.repository</code> 的值就是在 <code>values.yaml</code> 里定义的 <code>nginx</code>,<code>.Values.image.tag</code> 的值就是 <code>stable</code>。</p>
<p>以上两个变量值是在 create chart 的时候就自动生成的默认值,你可以根据实际情况进行修改。实际上都是静态文本,只在是执行的时候才被解析.</p>
<blockquote>
<p>如果你需要了解更多关于 Go 模板的相关信息,可以查看 Hugo 的一个关于 Go 模板 的介绍</p>
</blockquote>
<h3 id="编写应用的介绍信息">编写应用的介绍信息</h3>
<p>打开 Chart.yaml,可以看到内容如下</p>
<pre><code class="language-bash">$ cat mychart/Chart.yaml
apiVersion: v1
appVersion: "1.0"
description: A Helm chart for Kubernetes
name: mychart
version: 0.1.0
</code></pre>
<h3 id="编写具体应用部署信息">编写具体应用部署信息</h3>
<p>编辑 values.yaml,它默认会在 Kubernetes 部署一个 Nginx。下面是 mychart 应用的 values.yaml 文件的内容:</p>
<pre><code class="language-yml">$ cat mychart/values.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:
type: ClusterIP
port: 80

ingress:
enabled: false
annotations: {}
    # kubernetes.io/ingress.class: nginx
    # kubernetes.io/tls-acme: "true"
path: /
hosts:
    - chart-example.local
tls: []
#- secretName: chart-example-tls
#    hosts:
#      - chart-example.local

resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
#cpu: 100m
#memory: 128Mi
# requests:
#cpu: 100m
#memory: 128Mi

nodeSelector: {}

tolerations: []

affinity: {}
</code></pre>
<p>检查依赖和模板配置是否正确</p>
<pre><code>$ helm lint mychart/
==&gt; Linting .
Chart.yaml: icon is recommended

1 chart(s) linted, no failures
</code></pre>
<p>如果文件格式错误,可以根据提示进行修改。</p>
<h3 id="将应用打包">将应用打包</h3>
<pre><code class="language-bash">$ helm package mychart
Successfully packaged chart and saved it to: /home/k8s/mychart-0.1.0.tgz
</code></pre>
<p>mychart 目录会被打包为一个 mychart-0.1.0.tgz 格式的压缩包,该压缩包会被放到当前目录下,并同时被保存到了 Helm 的本地缺省仓库目录中。</p>
<p>如果你想看到更详细的输出,可以加上 --debug 参数来查看打包的输出,输出内容应该类似如下:</p>
<pre><code class="language-bash">$ helm package mychart --debug
Successfully packaged chart and saved it to: /home/k8s/mychart-0.1.0.tgz
Successfully saved /home/k8s/mychart-0.1.0.tgz to /home/k8s/.helm/repository/local
</code></pre>
<h3 id="将应用发布到-repository">将应用发布到 Repository</h3>
<p>虽然我们已经打包了 Chart 并发布到了 Helm 的本地目录中,但通过 helm search 命令查找,并不能找不到刚才生成的 mychart包。</p>
<pre><code>$ helm search mychart
No results found
</code></pre>
<p>这是因为 Repository 目录中的 Chart 包还没有被 Helm 管理。通过 helm repo list 命令可以看到目前 Helm 中已配置的 Repository 的信息。</p>
<blockquote>
<p>注:新版本中执行 helm init 命令后默认会配置一个名为 local 的本地仓库。如果大家通过helm repo list 可以看到local选项,则为默认添加了,下面的有配置不用管,当然如果你不太明白仍然按照下面的操作执行了,也是没有问题的</p>
</blockquote>
<p>我们可以在本地启动一个 Repository Server,并将其加入到 Helm Repo 列表中。Helm Repository 必须以 Web 服务的方式提供,这里我们就使用 helm serve 命令启动一个 Repository Server,该 Server 缺省使用 <code>$HOME/.helm/repository/local</code> 目录作为 Chart 存储,并在 8879 端口上提供服务。</p>
<pre><code class="language-bash">$ helm serve &amp;
Now serving you on 127.0.0.1:8879
</code></pre>
<p>默认情况下该服务只监听 127.0.0.1,如果你要绑定到其它网络接口,可使用以下命令:</p>
<p>helm serve --address 192.168.100.211:8879 &amp;</p>
<p>如果你想使用指定目录来做为 Helm Repository 的存储目录,可以加上 --repo-path 参数</p>
<pre><code class="language-bash">helm serve --address 192.168.124.59:8879 --repo-path /data/helm/repository/ --url http://192.168.124.59:8879/charts/
</code></pre>
<p>通过 helm repo index 命令将 Chart 的 Metadata 记录更新在 index.yaml 文件中:</p>
<pre><code class="language-bash"> 更新 Helm Repository 的索引文件
$ cd /home/k8s/.helm/repository/local
$ helm repo index --url=http://192.168.100.211:8879 .
</code></pre>
<p>完成启动本地 Helm Repository Server 后,就可以将本地 Repository 加入 Helm 的 Repo 列表</p>
<pre><code class="language-bash">$ helm repo add local http://127.0.0.1:8879
"local" has been added to your repositories
</code></pre>
<p>现在再次查找 mychart 包,就可以搜索到了。</p>
<pre><code class="language-bash">$ helm repo update
$ helm search mychart
NAME                 CHART VERSION        APP VERSION        DESCRIPTION
local/mychart        0.1.0              1.0              A Helm chart for Kubernetes
</code></pre>
<h2 id="在-kubernetes-中部署应用">在 Kubernetes 中部署应用</h2>
<h3 id="部署一个应用">部署一个应用</h3>
<p>Chart 被发布到仓储后,就可以通过 helm install 命令部署该 Chart。</p>
<ul>
<li>检查配置和模板是否有效</li>
</ul>
<p>当使用 <code>helm install</code> 命令部署应用时,实际上就是将 templates 目录下的模板文件渲染成 Kubernetes 能够识别的 YAML 格式。</p>
<p>在部署前我们可以使用 helm install --dry-run --debug &lt;chart_dir&gt; --name &lt;release_name&gt;命令来验证 Chart 的配置。该输出中包含了模板的变量配置与最终渲染的 YAML 文件。</p>
<pre><code class="language-yml">$ helm install --dry-run --debug local/mychart --name mike-test
Created tunnel using local port: '46649'

SERVER: "127.0.0.1:46649"

Original chart version: ""
Fetched local/mychart to /home/k8s/.helm/cache/archive/mychart-0.1.0.tgz

CHART PATH: /home/k8s/.helm/cache/archive/mychart-0.1.0.tgz

NAME:   tylertest
REVISION: 1
RELEASED: Mon Jul 23 10:39:49 2018
CHART: mychart-0.1.0
USER-SUPPLIED VALUES:
{}

COMPUTED VALUES:
affinity: {}
image:
pullPolicy: IfNotPresent
repository: nginx
tag: stable
ingress:
annotations: {}
enabled: false
hosts:
- chart-example.local
path: /
tls: []
nodeSelector: {}
replicaCount: 1
resources: {}
service:
port: 80
type: ClusterIP
tolerations: []

HOOKS:
MANIFEST:

---
# Source: mychart/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: tylertest-mychart
labels:
    app: mychart
    chart: mychart-0.1.0
    release: tyler-test
    heritage: Tiller
spec:
type: ClusterIP
ports:
    - port: 80
      targetPort: http
      protocol: TCP
      name: http
selector:
    app: mychart
    release: mike-test
---
# Source: mychart/templates/deployment.yaml
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: tylertest-mychart
labels:
    app: mychart
    chart: mychart-0.1.0
    release: tyler-test
    heritage: Tiller
spec:
replicas: 1
selector:
    matchLabels:
      app: mychart
      release: tyler-test
template:
    metadata:
      labels:
      app: mychart
      release: tyler-test
    spec:
      containers:
      - name: mychart
          image: "nginx:stable"
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
            containerPort: 80
            protocol: TCP
          livenessProbe:
            httpGet:
            path: /
            port: http
          readinessProbe:
            httpGet:
            path: /
            port: http
          resources:
            {}
</code></pre>
<p>验证完成没有问题后,我们就可以使用以下命令将其部署到 Kubernetes 上了。</p>
<pre><code class="language-bash"># 部署时需指定 Chart 名及 Release(部署的实例)名。
$ helm install local/mychart --name mike-test
NAME:   mike-test
LAST DEPLOYED: Mon Jul 23 10:41:20 2018
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==&gt; v1/Service
NAME               TYPE       CLUSTER-IP      EXTERNAL-IPPORT(S)AGE
mike-test-mychartClusterIP10.254.120.177&lt;none&gt;       80/TCP   1s

==&gt; v1beta2/Deployment
NAME               DESIREDCURRENTUP-TO-DATEAVAILABLEAGE
mike-test-mychart1      0      0         0          0s

==&gt; v1/Pod(related)
NAME                              READYSTATUS   RESTARTSAGE
mike-test-mychart-6d56f8c8c9-d685v0/1    Pending0         0s


NOTES:
1. Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace default -l "app=mychart,release=mike-test" -o jsonpath="{.items.metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl port-forward $POD_NAME 8080:80
</code></pre>
<blockquote>
<p>注:helm install 默认会用到 socat,需要在所有节点上安装 socat 软件包。</p>
</blockquote>
<p>关于访问的部分这里就不再介绍了,后面会讲解一个完整项目对外暴露访问</p>
<p>使用下面的命令列出的所有已部署的 Release 以及其对应的 Chart。</p>
<pre><code>$ helm list
NAME           REVISION        UPDATED                       STATUS        CHART              NAMESPACE
tylertest        1               Mon Jul 23 10:41:20 2018        DEPLOYED        mychart-0.1.0        default
</code></pre>
<p>你还可以使用 <code>helm status</code> 查询一个特定的 Release 的状态。</p>
<pre><code class="language-bash">$ helm status tylertest
LAST DEPLOYED: Mon Jul 23 10:41:20 2018
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==&gt; v1/Pod(related)
NAME                              READYSTATUS   RESTARTSAGE
tylertest-mychart-6d56f8c8c9-d685v1/1    Running0         1m

==&gt; v1/Service
NAME               TYPE       CLUSTER-IP      EXTERNAL-IPPORT(S)AGE
tylertest-mychartClusterIP10.254.120.177&lt;none&gt;       80/TCP   1m

==&gt; v1beta2/Deployment
NAME               DESIREDCURRENTUP-TO-DATEAVAILABLEAGE
tylertest-mychart1      1      1         1          1m


NOTES:
1. Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace default -l "app=mychart,release=tyler-test" -o jsonpath="{.items.metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl port-forward $POD_NAME 8080:80
</code></pre>
<h3 id="升级和回退一个应用">升级和回退一个应用</h3>
<p>从上面 helm list 输出的结果中我们可以看到有一个 Revision(更改历史)字段,该字段用于表示某一个 Release 被更新的次数,我们可以用该特性对已部署的 Release 进行回滚。</p>
<ul>
<li>修改 Chart.yaml 文件</li>
</ul>
<p>将版本号从 0.1.0 修改为 0.2.0, 然后使用 <code>helm package</code> 命令打包并发布到本地仓库。</p>
<pre><code class="language-bash">$ cat mychart/Chart.yaml
apiVersion: v1
appVersion: "1.0"
description: A Helm chart for Kubernetes
name: mychart
version: 0.2.0

$ helm package mychart
Successfully packaged chart and saved it to: /home/k8s/mychart-0.2.0.tgz
</code></pre>
<p>查询本地仓库中的 Chart 信息</p>
<p>我们可以看到在本地仓库中 mychart 有两个版本</p>
<pre><code class="language-bash">$ helm search mychart -l
NAME            CHART VERSION   APP VERSION   DESCRIPTION
local/mychart   0.2.0         1.0             A Helm chart for Kubernetes
local/mychart   0.1.0         1.0             A Helm chart for Kubernetes
</code></pre>
<ul>
<li>升级一个应用</li>
</ul>
<p>现在用 helm upgrade 命令将已部署的 tylertest 升级到新版本。你可以通过 --version 参数指定需要升级的版本号,如果没有指定版本号,则缺省使用最新版本。</p>
<pre><code class="language-bash">
$ helm upgrade tylertest mychart
Release "tylertest" has been upgraded. Happy Helming!
LAST DEPLOYED: Thu Apr 25 09:19:53 2019
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==&gt; v1/Deployment
NAME               READYUP-TO-DATEAVAILABLEAGE
tylertest-mychart1/1    1         1          25m

==&gt; v1/Pod(related)
NAME                              READYSTATUS   RESTARTSAGE
tylertest-mychart-545479dd4b-hj9ml1/1    Running0         25m

==&gt; v1/Service
NAME               TYPE       CLUSTER-IP    EXTERNAL-IPPORT(S)AGE
tylertest-mychartClusterIP10.103.51.57&lt;none&gt;       80/TCP   25m


NOTES:
1. Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=mychart,app.kubernetes.io/instance=tylertest" -o jsonpath="{.items.metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl port-forward $POD_NAME 8080:80

</code></pre>
<p>完成后,可以看到已部署的 tylertest 被升级到 0.2.0 版本。</p>
<pre><code class="language-bash">NAME                  REVISION      UPDATED                         STATUS          CHART                           APP VERSION   NAMESPACE
kubernetes-dashboard    1               Thu Mar 14 09:06:25 2019      DEPLOYED      kubernetes-dashboard-1.2.0      1.10.1          kube-system
tylertest               2               Thu Apr 25 09:19:53 2019      DEPLOYED      mychart-0.2.0                   1.0             default
</code></pre>
<ul>
<li>回退一个应用</li>
</ul>
<p>如果更新后的程序由于某些原因运行有问题,需要回退到旧版本的应用。首先我们可以使用 <code>helm history</code> 命令查看一个 Release 的所有变更记录。</p>
<pre><code class="language-bash">
$ helm list tylertest
NAME            REVISION      UPDATED                         STATUS          CHART         APP VERSION   NAMESPACE
tylertest       2               Thu Apr 25 09:19:53 2019      DEPLOYED      mychart-0.2.0   1.0             default
</code></pre>
<p>其次,我们可以使用下面的命令对指定的应用进行回退。</p>
<pre><code class="language-bash">
$ helm rollback tylertest 1
Rollback was a success! Happy Helming!
</code></pre>
<blockquote>
<p>注:其中的参数 1 是 helm history 查看到 Release 的历史记录中 REVISION 对应的值。</p>
</blockquote>
<ul>
<li>最后,我们使用 helm list 和 helm history 命令都可以看到 mychart 的版本已经回退到 0.1.0 版本。</li>
</ul>
<pre><code class="language-bash">$ helm list
NAME                  REVISION      UPDATED                         STATUS          CHART                           APP VERSION   NAMESPACE
kubernetes-dashboard    1               Thu Mar 14 09:06:25 2019      DEPLOYED      kubernetes-dashboard-1.2.0      1.10.1          kube-system
tylertest               3               Thu Apr 25 09:22:19 2019      DEPLOYED      mychart-0.1.0                   1.0             default
$ helm history tylertest
REVISION      UPDATED                         STATUS          CHART         DESCRIPTION
1               Thu Apr 25 08:54:49 2019      SUPERSEDED      mychart-0.1.0   Install complete
2               Thu Apr 25 09:19:53 2019      SUPERSEDED      mychart-0.2.0   Upgrade complete
3               Thu Apr 25 09:22:19 2019      DEPLOYED      mychart-0.1.0   Rollback to 1
</code></pre>
<h3 id="删除一个应用">删除一个应用</h3>
<p>如果需要删除一个已部署的 Release,可以利用 helm delete 命令来完成删除。</p>
<pre><code class="language-bash">$ helm delete tylertest
release "tylertest" deleted
</code></pre>
<p>确认应用是否删除,该应用已被标记为 DELETED 状态</p>
<pre><code class="language-bash">
$ helm ls --deleted
NAME                  REVISION      UPDATED                         STATUSCHART                   APP VERSION   NAMESPACE
intentional-chinchilla1               Wed Apr 24 18:37:29 2019      DELETED mychart-0.1.0         1.0             default
invisible-turkey      1               Mon Apr 22 17:39:14 2019      DELETED nginx-ingress-0.21.1    0.14.0          jx
punk-condor             1               Wed Apr 24 18:38:09 2019      DELETED mychart-0.1.0         1.0             default
tylerchart            1               Wed Apr 24 18:40:01 2019      DELETED mychart-0.1.0         1.0             default
tylertest               3               Thu Apr 25 09:22:19 2019      DELETED mychart-0.1.0         1.0             default
vigilant-bat            1               Wed Apr 24 17:40:02 2019      DELETED xray-0.4.2            2.3.0         default

</code></pre>
<p>从上面的结果也可以看出,默认情况下已经删除的 Release 只是将状态标识为 DELETED 了 ,但该 Release 的历史信息还是继续被保存的。</p>
<pre><code class="language-bash">
$ helm history tylertest
REVISION      UPDATED                         STATUS          CHART         DESCRIPTION
1               Thu Apr 25 08:54:49 2019      SUPERSEDED      mychart-0.1.0   Install complete
2               Thu Apr 25 09:19:53 2019      SUPERSEDED      mychart-0.2.0   Upgrade complete
3               Thu Apr 25 09:22:19 2019      DELETED         mychart-0.1.0   Deletion complete
</code></pre>
<p>如果要移除指定 Release 所有相关的 Kubernetes 资源和 Release 的历史记录,可以用如下命令:</p>
<pre><code class="language-bash">$ helm delete --purge tylertest
release "tylertest" deleted
</code></pre>
<p>再次查看已删除的 Release,已经无法找到相关信息。</p>
<pre><code class="language-bash">$ helm hist tylertest
Error: release: "tyertest" not found

# helm ls 命令也已均无查询记录。
$ helm ls --deleted
$ helm ls -a tylertest
</code></pre><br><br>
来源:https://www.cnblogs.com/tylerzhou/p/11136107.html
頁: [1]
查看完整版本: kubernetes实战篇之helm完整示例