• Helm


    认识Helm
    1. 为什么有helm?

    2. Helm是什么?

      kubernetes的包管理器,“可以将Helm看作Linux系统下的apt-get/yum”。

      • 对于应用发布者而言,可以通过Helm打包应用,管理应用依赖关系,管理应用版本并发布应用到软件仓库。

      • 对于使用者而言,使用Helm后不用需要了解Kubernetes的Yaml语法并编写应用部署文件,可以通过Helm下载并在kubernetes上安装需要的应用。

      除此以外,Helm还提供了kubernetes上的软件部署,删除,升级,回滚应用的强大功能。

    3. Helm的版本

      • helm2
        image
        C/S架构,helm通过Tiller与k8s交互

      • helm3
        image

        • 从安全性和易用性方面考虑,移除了Tiller服务端,helm3直接使用kubeconfig文件鉴权访问APIServer服务器

        • 由二路合并升级成为三路合并补丁策略( 旧的配置,线上状态,新的配置 )

          helm install very_important_app ./very_important_app
          

          这个应用的副本数量设置为 3 。现在,如果有人不小心执行了 kubectl edit 或:

          kubectl scale -replicas=0 deployment/very_important_app
          

          然后,团队中的某个人发现 very_important_app 莫名其妙宕机了,尝试执行命令:

          helm rollback very_important_app
          

          在 Helm 2 中,这个操作将比较旧的配置与新的配置,然后生成一个更新补丁。由于,误操作的人仅修改了应用的线上状态(旧的配置并未更新)。Helm 在回滚时,什么事情也不会做。因为旧的配置与新的配置没有差别(都是 3 个副本)。然后,Helm 不执行回滚,副本数继续保持为 0

        • 移除了helm serve本地repo仓库

        • 创建应用时必须指定名字(或者--generate-name随机生成)

    4. Helm的重要概念

      • chart,应用的信息集合,包括各种对象的配置模板、参数定义、依赖关系、文档说明等
      • Repoistory,chart仓库,存储chart的地方,并且提供了一个该 Repository 的 Chart 包的清单文件以供查询。Helm 可以同时管理多个不同的 Repository。
      • release, 当 chart 被安装到 kubernetes 集群,就生成了一个 release , 是 chart 的运行实例,代表了一个正在运行的应用

    helm 是包管理工具,包就是指 chart,helm 能够:

    • 从零创建chart
    • 与仓库交互,拉取、保存、更新 chart
    • 在kubernetes集群中安装、卸载 release
    • 更新、回滚、测试 release
    安装与快速入门实践

    下载最新的稳定版本:https://get.helm.sh/helm-v3.2.4-linux-amd64.tar.gz

    更多版本可以参考: https://github.com/helm/helm/releases

    # k8s-master节点
    $ wget https://get.helm.sh/helm-v3.2.4-linux-amd64.tar.gz
    $ tar -zxf helm-v3.2.4-linux-amd64.tar.gz
    
    $ cp linux-amd64/helm /usr/local/bin/
    
    # 验证安装
    $ helm version
    version.BuildInfo{Version:"v3.2.4", GitCommit:"0ad800ef43d3b826f31a5ad8dfbb4fe05d143688", GitTreeState:"clean", GoVersion:"go1.13.12"}
    $ helm env
    
    # 添加仓库
    $ helm repo add stable http://mirror.azure.cn/kubernetes/charts/
    # 同步最新charts信息到本地
    $ helm repo update
    
    
    

    快速入门实践:

    示例一:使用helm安装mysql应用

    # helm 搜索chart包
    $ helm search repo mysql
    
    # 从仓库安装
    $ helm install mysql stable/mysql
    
    $ helm ls
    $ kubectl get all 
    
    # 从chart仓库中把chart包下载到本地
    $ helm pull stable/mysql
    $ tree mysql
    

    示例二:新建nginx的chart并安装

    $ helm create nginx
    
    # 从本地安装
    $ helm install nginx ./nginx
    
    # 安装到别的命名空间luffy
    $ helm -n luffy install ./nginx
    
    # 查看
    $ helm ls
    $ helm -n luffy ls
    
    #
    $ kubectl get all 
    $ kubectl -n luffy get all
    
    Chart的模板语法及开发
    nginx的chart实现分析

    格式:

    $ tree nginx/
    nginx/
    ├── charts						# 存放子chart
    ├── Chart.yaml					# 该chart的全局定义信息
    ├── templates					# chart运行所需的资源清单模板,用于和values做渲染
    │   ├── deployment.yaml
    │   ├── _helpers.tpl			# 定义全局的命名模板,方便在其他模板中引入使用
    │   ├── hpa.yaml
    │   ├── ingress.yaml
    │   ├── NOTES.txt				# helm安装完成后终端的提示信息
    │   ├── serviceaccount.yaml
    │   ├── service.yaml
    │   └── tests
    │       └── test-connection.yaml
    └── values.yaml					# 模板使用的默认值信息
    

    很明显,资源清单都在templates中,数据来源于values.yaml,安装的过程就是将模板与数据融合成k8s可识别的资源清单,然后部署到k8s环境中。

    分析模板文件的实现:

    • 引用命名模板并传递作用域

      {{ include "nginx.fullname" . }}
      

      include从_helpers.tpl中引用命名模板,并传递顶级作用域.

    • 内置对象

      .Values
      .Release.Name
      
      
      • Release:该对象描述了 release 本身的相关信息,它内部有几个对象:
        • Release.Name:release 名称
        • Release.Namespace:release 安装到的命名空间
        • Release.IsUpgrade:如果当前操作是升级或回滚,则该值为 true
        • Release.IsInstall:如果当前操作是安装,则将其设置为 true
        • Release.Revision:release 的 revision 版本号,在安装的时候,值为1,每次升级或回滚都会增加
        • Reelase.Service:渲染当前模板的服务,在 Helm 上,实际上该值始终为 Helm
      • Values:从 values.yaml 文件和用户提供的 values 文件传递到模板的 Values 值
      • Chart:获取 Chart.yaml 文件的内容,该文件中的任何数据都可以访问,例如 {{ .Chart.Name }}-{{ .Chart.Version}} 可以渲染成 mychart-0.1.0
    • 模板定义

      {{- define "nginx.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 }}
      
      • {{- 去掉左边的空格及换行,-}} 去掉右侧的空格及换行

      • 示例

        apiVersion: v1
        kind: ConfigMap
        metadata:
          name: {{ .Release.Name }}-configmap
        data:
          myvalue: "Hello World"
          drink: {{ .Values.favorite.drink | default "tea" | quote }}
          food: {{ .Values.favorite.food | upper | quote }}
          {{ if eq .Values.favorite.drink "coffee" }}
          mug: true
          {{ end }}
        

        渲染完后是:

        apiVersion: v1
        kind: ConfigMap
        metadata:
          name: mychart-1575971172-configmap
        data:
          myvalue: "Hello World"
          drink: "coffee"
          food: "PIZZA"
        
          mug: true
        
    • 管道及方法

      • trunc表示字符串截取,63作为参数传递给trunc方法,trimSuffix表示去掉-后缀

        {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
        
      • nindent表示前面的空格数

          selector:
            matchLabels:
              {{- include "nginx.selectorLabels" . | nindent 6 }}
        
      • lower表示将内容小写,quote表示用双引号引起来

        value: {{ include "mytpl" . | lower | quote }}
        
    • 条件判断语句每个if对应一个end

      {{- if .Values.fullnameOverride }}
      ...
      {{- else }}
      ...
      {{- end }}
      

      通常用来根据values.yaml中定义的开关来控制模板中的显示:

      {{- if not .Values.autoscaling.enabled }}
        replicas: {{ .Values.replicaCount }}
      {{- end }}
      
    • 定义变量,模板中可以通过变量名字去引用

      {{- $name := default .Chart.Name .Values.nameOverride }}
      
    • 遍历values的数据

            {{- with .Values.nodeSelector }}
            nodeSelector:
              {{- toYaml . | nindent 8 }}
            {{- end }}
      

      toYaml处理值中的转义及特殊字符, "kubernetes.io/role"=master , name="value1,value2" 类似的情况

    • default设置默认值

      image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
      

    hpa.yaml

    {{- if .Values.autoscaling.enabled }}
    apiVersion: autoscaling/v2beta1
    kind: HorizontalPodAutoscaler
    metadata:
      name: {{ include "nginx.fullname" . }}
      labels:
        {{- include "nginx.labels" . | nindent 4 }}
    spec:
      scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: {{ include "nginx.fullname" . }}
      minReplicas: {{ .Values.autoscaling.minReplicas }}
      maxReplicas: {{ .Values.autoscaling.maxReplicas }}
      metrics:
      {{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
        - type: Resource
          resource:
            name: cpu
            targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
      {{- end }}
      {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
        - type: Resource
          resource:
            name: memory
            targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
      {{- end }}
    {{- end }}
    
    创建应用的时候赋值
    • set的方式
    # 改变副本数和resource值
    $ helm install nginx-2 ./nginx --set replicaCount=2 --set resources.limits.cpu=200m --set resources.limits.memory=256Mi
    
    
    • value文件的方式

      $ cat nginx-values.yaml
      resources:
        limits:
          cpu: 100m
          memory: 128Mi
        requests:
          cpu: 100m
          memory: 128Mi
      autoscaling:
        enabled: true
        minReplicas: 1
        maxReplicas: 3
        targetCPUUtilizationPercentage: 80
      ingress:
        enabled: true
        hosts:
          - host: chart-example.luffy.com
            paths:
            - /
      
      $ helm install -f nginx-values.yaml nginx-3 ./nginx
      

    更多语法参考:

    https://helm.sh/docs/topics/charts/

    部署mysql失败的问题

    使用Helm部署Harbor镜像及chart仓库
    harbor踩坑部署

    架构 https://github.com/goharbor/harbor/wiki/Architecture-Overview-of-Harbor
    image

    • Core,核心组件
      • API Server,接收处理用户请求
      • Config Manager :所有系统的配置,比如认证、邮件、证书配置等
      • Project Manager:项目管理
      • Quota Manager :配额管理
      • Chart Controller:chart管理
      • Replication Controller :镜像副本控制器,可以与不同类型的仓库实现镜像同步
      • Distribution (docker registry)
      • Docker Hub
      • ...
      • Scan Manager :扫描管理,引入第三方组件,进行镜像安全扫描
      • Registry Driver :镜像仓库驱动,目前使用docker registry
    • Job Service,执行异步任务,如同步镜像信息
    • Log Collector,统一日志收集器,收集各模块日志
    • GC Controller
    • Chart Museum,chart仓库服务,第三方
    • Docker Registry,镜像仓库服务
    • kv-storage,redis缓存服务,job service使用,存储job metadata
    • local/remote storage,存储服务,比较镜像存储
    • SQL Database,postgresl,存储用户、项目等元数据

    通常用作企业级镜像仓库服务,实际功能强大很多。

    组件众多,因此使用helm部署

    # 添加harbor chart仓库
    $ helm repo add harbor https://helm.goharbor.io
    
    # 搜索harbor的chart
    $ helm search repo harbor
    
    # 不知道如何部署,因此拉到本地
    $ helm pull harbor/harbor --version 1.4.1
    

    创建pvc

    $ kubectl create namespace harbor
    $ cat harbor-pvc.yaml
    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: harbor-pvc
      namespace: harbor
    spec:
      accessModes:     
        - ReadWriteOnce
      storageClassName: dynamic-cephfs
      resources:
        requests:
          storage: 20Gi
    

    修改harbor配置:

    • 开启ingress访问
    • externalURL,web访问入口,和ingress的域名相同
    • 持久化,使用PVC对接的cephfs
    • harborAdminPassword: "Harbor12345",管理员默认账户 admin/Harbor12345
    • 开启chartmuseum
    • clair和trivy漏洞扫描组件,暂不启用

    helm创建:

    # 使用本地chart安装
    $ helm install harbor ./harbor -n harbor 
    

    踩坑一:redis持久化数据目录权限导致无法登录

    redis数据目录,/var/lib/redis,需要设置redis的用户及用户组权限

          initContainers:
          - name: "change-permission-of-directory"
            image: {{ .Values.database.internal.initContainerImage.repository }}:{{ .Values.database.internal.initContainerImage.tag }}
            imagePullPolicy: {{ .Values.imagePullPolicy }}
            command: ["/bin/sh"]
            args: ["-c", "chown -R 999:999 /var/lib/redis"]
            volumeMounts:
            - name: data
              mountPath: /var/lib/redis
              subPath: {{ $redis.subPath }}
    

    踩坑二:registry组件的镜像存储目录权限导致镜像推送失败

    registry的镜像存储目录,需要设置registry用户的用户及用户组,不然镜像推送失败

          initContainers:
          - name: "change-permission-of-directory"
            image: {{ .Values.database.internal.initContainerImage.repository }}:{{ .Values.database.internal.initContainerImage.tag }}
            imagePullPolicy: {{ .Values.imagePullPolicy }}
            command: ["/bin/sh"]
            args: ["-c", "chown -R 10000:10000 {{ .Values.persistence.imageChartStorage.filesystem.rootdirectory }}"]
            volumeMounts:
            - name: registry-data
              mountPath: {{ .Values.persistence.imageChartStorage.filesystem.rootdirectory }}
              subPath: {{ .Values.persistence.persistentVolumeClaim.registry.subPath }}
    

    踩坑三:chartmuseum存储目录权限,导致chart推送失败

          initContainers:
          - name: "change-permission-of-directory"
            image: {{ .Values.database.internal.initContainerImage.repository }}:{{ .Values.database.internal.initContainerImage.tag }}
            imagePullPolicy: {{ .Values.imagePullPolicy }}
            command: ["/bin/sh"]
            args: ["-c", "chown -R 10000:10000 /chart_storage"]
            volumeMounts:
            - name: chartmuseum-data
              mountPath: /chart_storage
              subPath: {{ .Values.persistence.persistentVolumeClaim.chartmuseum.subPath }}
    

    更新内容后,执行更新release

    $ helm upgrade harbor -n harbor ./
    
    推送镜像到Harbor仓库

    配置hosts及docker非安全仓库:

    $ cat /etc/hosts
    ...
    192.168.136.10 k8s-master core.harbor.domain
    ...
    
    $ cat /etc/docker/daemon.json
    {                                            
      "insecure-registries": [                   
        "192.168.136.10:5000",                   
        "core.harbor.domain"                     
      ],                                         
      "registry-mirrors" : [                     
        "https://8xpk5wnt.mirror.aliyuncs.com"   
      ]                                          
    }                           
    
    #
    $ systemctl restart docker
    
    # 使用账户密码登录admin/Harbor12345
    $ docker login core.harbor.domain
    
    $ docker tag nginx:alpine core.harbor.domain/library/nginx:alpine
    $ docker push core.harbor.domain/library/nginx:alpine
    
    推送chart到Harbor仓库

    helm3默认没有安装helm push插件,需要手动安装。插件地址 https://github.com/chartmuseum/helm-push

    安装插件:

    $ helm plugin install https://github.com/chartmuseum/helm-push
    

    离线安装:

    $ helm plugin install ./helm-push
    

    添加repo

    $ helm repo add myharbor https://core.harbor.domain/chartrepo/library 
    # x509错误
    
    # 添加证书信任,根证书为配置给ingress使用的证书
    $ kubectl get secret harbor-harbor-ingress -n harbor -o jsonpath="{.data.ca.crt}" | base64 -d >harbor.ca.crt
    
    $ cp harbor.ca.crt /etc/pki/ca-trust/source/anchors
    $ update-ca-trust enable; update-ca-trust extract
    
    # 再次添加
    $ helm repo add myharbor https://core.harbor.domain/chartrepo/library --ca-file=harbor.ca.crt
    
    $ helm repo ls
    
    

    推送chart到仓库:

    $ helm push harbor myharbor --ca-file=harbor.ca.crt -u admin -p Harbor12345
    

    查看harbor仓库的chart

  • 相关阅读:
    熟悉常用的HDFS操作
    爬虫爬取小说网站
    数据结构化与保存
    使用正则表达式,取得点击次数,函数抽离
    爬取校园新闻首页的新闻
    网络爬虫基础练习
    综合练习:词频统计
    最近在学习多元分析,有空放上来分享
    机器学习基石作业一15-20题(Python实现)
    2018十月份
  • 原文地址:https://www.cnblogs.com/Mr-Axin/p/14756500.html
Copyright © 2020-2023  润新知