zoukankan      html  css  js  c++  java
  • ASP.NET Core on K8S深入学习(10)K8S包管理器Helm

    本篇已加入《.NET Core on K8S学习实践系列文章索引》,可以点击查看更多容器化技术相关系列文章。

    一、关于Helm

    1.1 为何需要Helm?

      虽然K8S能够很好地组织和编排容器,但是缺少一个更高层次的应用打包工具,而Helm就是专门干这个事的。

      通过Helm能够帮助开发者定义、安装和升级Kubernetes中的容器云应用。同时,也可以通过Helm进行容器云应用的分享。

    1.2 Helm的架构

      Helm的整体架构如下图(图片来源-Kubernetes中文社区)所示:

      

      Helm架构由Helm客户端、Tiller服务器端和Chart仓库所组成;

    两个重要概念:

    (1)Chart是创建一个应用的信息集合,包括各种K8S对象的配置模板、参数定义等,可以理解为是apt、yum中的软件安装包;

    (2)Release是Chart的运行实例,代表了一个正在运行的应用。

      Tiller部署在Kubernetes中,Helm客户端从Chart仓库中获取Chart安装包,并通过与Tiller服务器的交互将其安装部署到Kubernetes集群中。

      简单说来,Helm客户端负责管理Chart,而 Tiller服务器则负责管理Release。 

    二、Helm的安装和使用

    2.1 Helm客户端的安装

      执行以下命令将Helm客户端安装在能够执行kubectl命令的节点上,这里假设我们安装在k8s-master节点上进行示例演示:

    curl https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get | bash

      也可以通过下面的方式安装:

    wget https://storage.googleapis.com/kubernetes-helm/helm-v2.11.0-linux-amd64.tar.gz
    tar -zxvf helm-v2.11.0-linux-amd64.tar.gz
    cd linux-amd64/
    cp helm /usr/local/bin/

      验证:查看helm版本

    helm version

      

      补充:为了提高使用命令行的效率,建议安装helm命令补全脚本,命令如下:

    cd ~ && helm completion bash > .helmrc echo "source .helmrc" >> .bashrc

      重新登录后,就可以方便地通过tab键来补全helm子命令和参数了,如下图所示,当我们输入helm install --之后按下Tab键,就会给我们参数提示了:

      

    2.2 Tiller服务器的安装

      Tiller服务器本身也是作为容器化的一个应用运行在K8S集群中,这里我们简单执行下面的命令即可安装Tiller服务:

    helm init

      执行以上命令,会如下图所示:

      

       看到上图中的提示信息,代表Helm服务端已经安装成功。

       这时,我们可以看看Tiller的Service、Deployment和Pod有没有启动起来:

      (1)Service & Deployment

      

       (2)Pod

      

      如果看到其Status不是Running,那么很有可能是镜像没有拉取下来,可以曲线救国:即下载可访问的镜像然后修改Tag!

    docker pull fishead/gcr.io.kubernetes-helm.tiller:v2.11.0
    docker tag fishead/gcr.io.kubernetes-helm.tiller:v2.11.0 gcr.io/kubernetes-helm/tiller:v2.11.0

       这时再次通过helm version命令验证一下:

      

       可以看到,我们已经可以成功看到客户端和服务端的版本信息了,证明客户端和服务端(Pod)都已经安装成功了!

    2.3 Helm的使用准备

      Helm安装好后,我们可以通过以下helm search来查看当前可安装的Chart:

      

    Note:Helm安装时会为我们配置好两个仓库,一个是stable官方仓库,另一个是local本地仓库,上图中显示的都是stable官方仓库中的Chart。  

       为了能够执行install安装,我们还需要事先为Tiller服务器添加集群权限,防止因Tiller服务器的权限不足而无法install。

    # 创建serviceaccount资源tiller,属于kube-system命名空间
    kubectl create serviceaccount -n kube-system tiller
    # 创建 clusterrolebinding资源tiller-cluster-rule,集群角色为cluster-admin,用户为kube-system:tiller
    kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
    # 修改deployment tiller-deploy的配置,增加字段spec.template.spec.serviceAccount
    kubectl patch deploy -n kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}'

      

       至此,使用Helm的准备工作就到此结束,后面我们就可以开始实践安装Chart了!

    三、MySQL Chart实践

    3.1 初步安装MySQL Chart

      这里我们通过以下命令来通过官方仓库安装mysql:

    helm install stable/mysql -n=edc-mysql --namespace=edc-charts

      其中,-n 代表 release的名字,--namespace 指定了其所在namespace。

      执行成功之后,会显示一屏幕的提示信息,其中Notes部分包含了release的使用方法,可以重点关注一下。

      这里我们通过以下命令来看看已经部署的release:

    helm list

      

       可以看到,该release的状态已经是DEPLOYED,也可以看到其版本号是5.7.27。

      下面再看看service、deployment、pod以及pvc的情况:

      

      

       从上图可以看到,由于还没有位mysql准备PV(PersistentVolume,不了解此概念的童鞋可以参考这一篇《K8S数据管理》),导致当前release不可用,处于Pending状态。接下来我们就要先解决PV的问题,让release能够正常运行起来!在此之前,为了后续方便演示,这里现将此chart删除:

    helm delete edc-mysql

    3.2 为MySQL Chart准备PV

      首先,按照约定准备一个edc-mysql-pv.yml,如下所示:

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: edc-mysql-pv
    spec:
      capacity:
        storage: 8Gi
      accessModes:
        - ReadWriteOnce
      persistentVolumeReclaimPolicy: Retain
      #storageClassName: nfs
      nfs:
        path: /edc/k8s/nfsdata/edc-mysql-pv
        server: k8s-master

      这里申请了一个8G的PV,用于适配mysql chart的默认配置要求,当然我们也可以通过修改自定义values.yaml来修改。

    3.3 定制化安装MySQL Chart

      Helm有两种方式传递配置参数实现定制化安装,一种是指定自定义的values文件,另一种是通过--set直接传入参数值。这里我们演示通过第二种,这里我们重新安装mysql chart:

    helm install stable/mysql -namespace=edc-charts --set mysqlRootPassword=edc123456 -n edison

      验证结果如下图所示:

      

    3.4 升级和回滚Release

      这里假设我安装的版本是5.7.14,这里我将其先升级为5.7.26来演示:

    helm upgrade --set imageTag=5.7.26 edison stable/mysql

      通过查看可以看到image已经换为了5.7.26:

      

       通过helm history可以查看release的所有历史版本:

      

       Note:这里Revision 1是5.7.14版本,Revision 2是5.7.26版本,Revision 3是5.7.27版本。

       这里我们通过helm rollback回退到Revision 1版本(即5.7.14版本),可以看到已经成功回退到了5.7.14版本:

       

    四、自定义Chart实践

    4.1 创建Chart

      首先,通过以下命令创建一个chart命名为mychart:

    helm create mychart

      Helm会帮我们创建目录mychart,并生成各种chart文件。

      

      这里我们需要关注的是values.yaml,修改其中的内容为我们之前演示的ASP.NET Core WebAPI应用镜像:

    # Default values for mychart.
    # This is a YAML-formatted file.
    # Declare variables to be passed into your templates.
    
    replicaCount: 1
    
    image:
      repository: edisonsaonian/k8s-demo
      tag: latest
      pullPolicy: IfNotPresent
    
    service:
      type: NodePort
      port: 80
      nodePort: 31000
    
    ingress:
      enabled: false
    
    resources:
      limits:
        cpu: 1
        memory: 228Mi
      requests:
        cpu: 100m
        memory: 128Mi

      这里我们选择NodePort的方式让外部可以通过31000端口访问到API,也设置了资源限制。

      此外,我们再修改一下Templates目录下的deployment和service两个模板文件:

      (1)deployment模板:重点关注两个探针的配置

    apiVersion: apps/v1beta2
    kind: Deployment
    metadata:
      name: {{ include "mychart.fullname" . }}
      labels:
        app.kubernetes.io/name: {{ include "mychart.name" . }}
        helm.sh/chart: {{ include "mychart.chart" . }}
        app.kubernetes.io/instance: {{ .Release.Name }}
        app.kubernetes.io/managed-by: {{ .Release.Service }}
    spec:
      replicas: {{ .Values.replicaCount }}
      selector:
        matchLabels:
          app.kubernetes.io/name: {{ include "mychart.name" . }}
          app.kubernetes.io/instance: {{ .Release.Name }}
      template:
        metadata:
          labels:
            app.kubernetes.io/name: {{ include "mychart.name" . }}
            app.kubernetes.io/instance: {{ .Release.Name }}
        spec:
          containers:
            - name: {{ .Chart.Name }}
              image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
              imagePullPolicy: {{ .Values.image.pullPolicy }}
              ports:
                - name: http
                  containerPort: 80
                  protocol: TCP
              # 探针  检测项目是否存活
              livenessProbe:
                httpGet:
                  path: /api/values
                  port: http
              # 探针  检测项目是否启动成功
              readinessProbe:
                httpGet:
                  path: /api/values
                  port: http
                initialDelaySeconds: 30
                periodSeconds: 60
              resources:
    {{ toYaml .Values.resources | indent 12 }}
        {{- with .Values.nodeSelector }}
          nodeSelector:
    {{ toYaml . | indent 8 }}
        {{- end }}
        {{- with .Values.affinity }}
          affinity:
    {{ toYaml . | indent 8 }}
        {{- end }}
        {{- with .Values.tolerations }}
          tolerations:
    {{ toYaml . | indent 8 }}
        {{- end }}

      (2)service模板:重点关注NodePort的配置

    apiVersion: v1
    kind: Service
    metadata:
      name: {{ include "mychart.fullname" . }}
      labels:
        app.kubernetes.io/name: {{ include "mychart.name" . }}
        helm.sh/chart: {{ include "mychart.chart" . }}
        app.kubernetes.io/instance: {{ .Release.Name }}
        app.kubernetes.io/managed-by: {{ .Release.Service }}
    spec:
      type: {{ .Values.service.type }}
      ports:
        - port: {{ .Values.service.port }}
          targetPort: http
          # 添加nodePort
          nodePort: {{ .Values.service.nodePort }}
          protocol: TCP
          name: http
      selector:
        app.kubernetes.io/name: {{ include "mychart.name" . }}
        app.kubernetes.io/instance: {{ .Release.Name }}

       编写完成后,通过 helm lint 可以帮助我们快速验证是否有语法错误:

      

    4.2 安装Chart

      没有语法错误检测之后,便可以开始安装Chart了,正式安装之前我们可以通过以下命令来模拟安装,它会输出每个模板生成的yaml内容,帮助你检查生成的yaml内容是否是你想要的或者正确的。

    helm install --dry-run --debug

      然后,这里我们选择本地安装Chart:

    helm install mychart -n edc-api-release --namespace=aspnetcore

      只需要简单的一句话,就可以将chart部署到K8S集群中了,下面我们通过在外部访问NodePort 31000端口来验证一下是否部署成功:

      (1)Node 1

      

      (2)Node 2

       

       两个Node节点都可以访问到,证明部署成功!

    4.3 添加Chart到仓库

      通过测试之后,我们的Chart就可以发布到仓库中供团队成员使用了,像阿里云、腾讯云等云服务商都已经提供了完善的Helm远程仓库,我们也可以自己搭建一个仓库,任何的Web Server其实都可以作为一个chart仓库。

      下面我们在k8s-master上启动给一个httpd容器,让它来作为我们的本地chart仓库。

    docker run -d -p 8080:80 -v /var/www:/usr/local/apache2/htdocs/ httpd

      然后,我们将mychart进行打包,helm会将其打包为一个tgz包:

    helm package mychart

      然后,我们为mychart包生成仓库的index文件,并将其推送到本地chart仓库中:

    mkdir myrepo
    mv mychart-0.1.0.tgz myrepo/
    helm repo index myrepo/ --url http://192.168.2.100:8080/charts

      这里我们将httpd容器中的charts目录作为chart仓库,因此需要提前创建charts目录,并将打好的包和index.yaml文件也上传到该目录中:

      

      最后,我们将新仓库添加到helm:

    helm repo add edc-repo http://192.168.2.100:8080/charts
    helm repo list

      

       可以看到,edc-repo已经添加到了helm中,代表可以从新的本地仓库中下载和安装mychart了!

    4.4 使用自定义Chart

      现在我们来从本地的新仓库中下载和安装mychart:

    helm install edc-repo/mychart -n mychart-release --namespace=aspnetcore

      安装完成后再次验证:

      (1)Node 1

      

      (2)Node 2

       

      如果以后仓库添加了新的chart,需要使用以下命令来更新本地的index文件:

    helm repo update

    五、小结

       本文介绍了K8S的包管理器Helm的基本概念与安装和使用,Helm能够帮助我们像使用apt或yum那样管理安装、部署、升级和删除容器化应用,最后演示了如何为我们的ASP.NET Core API应用开发自己的chart,并在团队中共享chart。当然,关于Helm,笔者也是初学,还有很多地方没有研究,希望此文能给初学者一点帮助,谢谢!

    参考资料

    (1)CloudMan,《每天5分钟玩转Kubernetes

    (2)李振良,《一天入门Kubernets教程

    (3)马哥(马永亮),《Kubernetes快速入门

    (4)潘猛,《Kubernetes笔记之Helm

    (5)雪雁(心莱科技),《利用Helm简化Kubernetes应用部署(二)

    (6)周国通,《Kubernetes实战篇之Helm填坑与基本命令

  • 相关阅读:
    第三十一篇 玩转数据结构——并查集(Union Find)
    第三十篇 玩转数据结构——字典树(Trie)
    开发Electron可能用到的工具
    最新NetMonitor代码
    用C++/CLI搭建C++和C#之间的桥梁
    xaml实现无边框窗口
    用xaml画的带阴影3D感的圆球
    创作了一个xml的替代格式
    域名投资入门和技巧
    Compaq Visual Fortran生成静态库的方法及使用
  • 原文地址:https://www.cnblogs.com/edisonchou/p/aspnet_core_on_k8s_deepstudy_part10.html
Copyright © 2011-2022 走看看