zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    SharePoint 2013 APP 开发示例 (六)服务端跨域访问 Web Service (REST API)
    麦咖啡导致电脑不能上网
    SharePoint 2013 Central Admin 不能打开
    SharePoint 2013 APP 开发示例 (五)跨域访问 Web Service (REST API)
    SharePoint 2013 APP 开发示例 系列
    synthesize(合成) keyword in IOS
    Git Cmd
    简单的正则匹配
    Dropbox
    SQL Server Replication
  • 原文地址:https://www.cnblogs.com/Mr-Axin/p/14756500.html
Copyright © 2011-2022 走看看