使用Helm3管理复杂应用的部署

认识Helm
  1. 为什么有helm?

  2. Helm是什么?

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

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

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

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

  3. Helm的版本

    • helm2

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

    • helm3

      • 从安全性和易用性方面考虑,移除了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 server本地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 https://charts.bitnami.com/bitnami
# 同步最新charts信息到本地
$ helm repo update

快速入门实践:

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

# helm 搜索chart包
$ helm search repo wordpress $ kubectl create namespace wordpress
# 从仓库安装
$ helm -n wordpress install wordpress stable/wordpress --set mariadb.primary.persistence.enabled=false --set service.type=ClusterIP --set ingress.enabled=true --set persistence.enabled=false --set ingress.hostname=wordpress.luffy.com $ helm -n wordpress ls
$ kubectl -n wordpress get all # 从chart仓库中把chart包下载到本地
$ helm pull stable/wordpress
$ tree mysql

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

$ helm create nginx

# 从本地安装
$ helm install nginx ./nginx # 安装到别的命名空间luffy
$ helm -n luffy install nginx ./nginx --set replicaCount=2 --set image.tag=alpine # 查看
$ helm ls
$ helm -n luffy ls #
$ 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环境中。

$ helm install debug-nginx ./ --dry-run --set replicaCount=2 --debug

分析模板文件的实现:

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

    {{ include "nginx.fullname" . }}

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

  • 内置对象

    .Values
    .Release.Name
    .Chart
    • Release:该对象描述了 release 本身的相关信息,它内部有几个对象:

      • Release.Name:release 名称
      • Release.Namespace:release 安装到的命名空间
      • Release.IsUpgrade:如果当前操作是升级或回滚,则该值为 true
      • Release.IsInstall:如果当前操作是安装,则将其设置为 true
      • Release.Revision:release 的 revision 版本号,在安装的时候,值为1,每次升级或回滚都会增加
      • Release.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 }}"

Helm template

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 }}
创建Release的时候赋值
  • 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

使用helm template查看渲染模板

$ helm -n luffy template nginx ./nginx --set replicaCount=2 --set image.tag=alpine --set autoscaling.enabled=true

更多语法参考:

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

实战:使用Helm部署Harbor镜像及chart仓库
harbor部署

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

  • 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

创建pvc

$ kubectl create namespace harbor
$ cat harbor-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: harbor-data
namespace: harbor
spec:
accessModes:
- ReadWriteMany
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持久化数据目录权限导致无法登录
  • registry组件的镜像存储目录权限导致镜像推送失败
  • chartmuseum存储目录权限,导致chart推送失败

解决:

$ mount -t ceph 172.21.51.55:6789:/ /mnt/cephfs -o name=admin,secret=AQBPTstgc078NBAA78D1/KABglIZHKh7+G2X8w==

$ chown -R 999:999 database
$ chown -R 999:999 redis
$ chown -R 10000:10000 chartmuseum
$ chown -R 10000:10000 registry
$ chown -R 10000:10000 jobservice
推送镜像到Harbor仓库

配置hosts及docker非安全仓库:

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

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

安装插件:

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

离线安装:

$ mkdir helm-push
$ wget https://github.com/chartmuseum/helm-push/releases/download/v0.8.1/helm-push_0.8.1_linux_amd64.tar.gz
$ tar zxf helm-push_0.8.1_linux_amd64.tar.gz -C helm-push
$ helm plugin install ./helm-push

添加repo

$ helm repo add myharbor https://harbor.luffy.com/chartrepo/luffy
# x509错误 # 添加证书信任,根证书为配置给ingress使用的证书
$ kubectl get secret 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 luffy https://harbor.luffy.com/chartrepo/luffy --ca-file=harbor.ca.crt --username admin --password Harbor12345 $ helm repo ls

推送chart到仓库:

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

二十八、Helm的更多相关文章

  1. Bootstrap <基础二十八>列表组

    列表组.列表组件用于以列表形式呈现复杂的和自定义的内容.创建一个基本的列表组的步骤如下: 向元素 <ul> 添加 class .list-group. 向 <li> 添加 cl ...

  2. Web 前端开发人员和设计师必读文章推荐【系列二十八】

    <Web 前端开发精华文章推荐>2014年第7期(总第28期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...

  3. Citrix 服务器虚拟化之二十八 XenApp6.5发布文档内容

    Citrix 服务器虚拟化之二十八  XenApp 6.5发布文档内容 XenApp可发布以下类型的资源向用户提供信息访问,这些资源可在服务器或桌面上虚拟化: 1)  服务器桌面:发布场中服务器的整个 ...

  4. WCF技术剖析之二十八:自己动手获取元数据[附源代码下载]

    原文:WCF技术剖析之二十八:自己动手获取元数据[附源代码下载] 元数据的发布方式决定了元数据的获取行为,WCF服务元数据架构体系通过ServiceMetadataBehavior实现了基于WS-ME ...

  5. VMware vSphere 服务器虚拟化之二十八 桌面虚拟化之安装View传输服务器

    VMware vSphere 服务器虚拟化之二十八 桌面虚拟化之安装View传输服务器 View 传输服务器用于管理和简化数据中心与在最终用户本地系统上检出使用的 View 桌面之间的数据传输.必须安 ...

  6. Bootstrap入门(二十八)JS插件5:工具提醒

    Bootstrap入门(二十八)JS插件5:工具提醒 工具提示在使用过程中比较常见,但是实现起来有些麻烦,而bootstrap则很好地解决了这个问题. 我们来写一个简单的实例 先引入CSS文件和JS文 ...

  7. mysql进阶(二十八)MySQL GRANT REVOKE用法

    mysql进阶(二十八)MySQL GRANT REVOKE用法   MySQL的权限系统围绕着两个概念: 认证->确定用户是否允许连接数据库服务器: 授权->确定用户是否拥有足够的权限执 ...

  8. JAVA之旅(二十八)——File概述,创建,删除,判断文件存在,创建文件夹,判断是否为文件/文件夹,获取信息,文件列表,文件过滤

    JAVA之旅(二十八)--File概述,创建,删除,判断文件存在,创建文件夹,判断是否为文件/文件夹,获取信息,文件列表,文件过滤 我们可以继续了,今天说下File 一.File概述 文件的操作是非常 ...

  9. 条目二十八《正确理解由reverse_iterator的base()成员函数所产生的iterator的用法》

    条目二十八<正确理解由reverse_iterator的base()成员函数所产生的iterator的用法> 迭代器的种类一共有四种,上面已经说过了.这里就不再次写出来. 这一个条目主要是 ...

  10. (转载)Android项目实战(二十八):Zxing二维码实现及优化

    Android项目实战(二十八):Zxing二维码实现及优化   前言: 多年之前接触过zxing实现二维码,没想到今日项目中再此使用竟然使用的还是zxing,百度之,竟是如此牛的玩意. 当然,项目中 ...

随机推荐

  1. Spring源码 21 Bean生命周期

    参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...

  2. Spring核心思想Ioc和Aop (面试)

    Spring核心思想Ioc和Aop (面试) 注意: Ioc和Aop并不是Spring提出的,在Spring之前就已经存在,Spring只是在技术层面给这两个思想做了非常好的实现. 1 Ioc 1.1 ...

  3. 微服务性能分析|Pyroscope 集合 Spring Cloud Pig 的实践分享

    随着微服务体系在生产环境落地,也会伴随着一些问题出现,比如流量过大造成某个微服务应用程序的性能瓶颈.CPU利用率高.或内存泄漏等问题.要找到问题的根本原因,我们通常都会通过日志.进程再结合代码去判断根 ...

  4. 275. H 指数 II--Leetcode_暴力

    来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/h-index-ii 著作权归领扣网络所有.商业转载请联系官方授权,非商业转载请注明出处. 题目的大意是 ...

  5. HEXO-admin安装和使用(汉化版)

    hi,大家好,我是KINGWDY,众所周知我用的是hexo,写博文首先要在终端输入hexo n xxxxx,然后打开MWeb PRO开始写md,但是,这很麻烦,就在我一筹莫展之际,我看到了这篇博文-- ...

  6. Paperask一键获取A币

    又到了毕业季,查论文是一件很头疼的事情,网上免费查重检测力度又很一般┑( ̄Д  ̄)┍ 因为一次偶然同学推荐了解到这个网站,只要做新手任务就能得到很多积分,再进行抽奖就可以得到A币或者是至尊券可以免费使 ...

  7. clipboard实现文本复制的方法

    1.下载地址: https://github.com/mo3408/clipboard 2.使用方法: 先引入js: <script src="dist/clipboard.min.j ...

  8. Linux 配置ODBC连接Oracle

    在使用kdb_database_link 扩展插件连接Oracle数据库时,必须先配置ODBC,确保通过ODBC能连接Oracle数据库.以下是配置ODBC的过程. 一.安装ODBC 1.安装 [ro ...

  9. spring的set注入方式流程图解

    spring的set注入方式流程图解 自己学习spring的一些笔记,详细画出了spring的set方式实现依赖注入的流程. 注意:<property name="UserDao&qu ...

  10. 更改elasticsearch中索引的mapping

    文章转载自:https://www.cnblogs.com/uglyliu/p/12331964.html 昨天研发说在kibana中统计userid字段不出图,后来查到该字段显示冲突了,然后再查看了 ...