k8s 包管理器

| 标签 kubernetes  helm  浏览次数: -

Why Helm

Helm 到底解决了什么问题?为什么 Kubernetes 需要 Helm?

答案是: Kubernetes 能够很好地组织和编排容器,但它缺少一个更高层次的应用打包工具,而 Helm 就是来干这件事的。

部署 MySQL

  • 1.Service,让外界能够访问到 MySQL

service.yaml

apiVersion: v1
kind: Service
metadata:
  name: my-mysql
  labels:
    app: my-mysql
spec:
  ports:
    - name: mysql
      port: 3306
      targetPort: mysql
  selector:
    app: my-mysql
  • 2.Secret,定义 MySQL 的密码

secret.yaml

apiVersion: v1
kind: Secret
metadata:
  name: my-mysql
  labels:
    app: my-mysql
type: Opaque
data:
  mysql-root-password: "cm9vdA==" # root
  mysql-password: "bXlzcWw=" # mysql
  • 3.PersistentVolumeClaim,为 MySQL 申请持久化存储空间

pv.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-mysql
  labels:
    app: my-mysql
spec:
  capacity:
    storage: 4Gi
  accessModes:
    * ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: nfs
  nfs:
    path: /nfsdata/my-mysql
    server: 192.168.1.6

pvc.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-mysql
  labels:
    app: my-mysql
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 4Gi
  storageClassName: nfs
  • 4.Deployment,部署 MySQL Pod,并使用上面的这些支持对象

pod.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-mysql
  labels:
    app: my-mysql
spec:
  selector:
    matchLabels:
      app: my-mysql
  template:
    metadata:
      labels:
        app: my-mysql
    spec:
      containers:
        - name: my-mysql
          image: "mysql:5.7.14"
          env:
            - name: MYSQL_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: my-mysql
                  key: mysql-root-password
            - name: MYSQL_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: my-mysql
                  key: mysql-password
            - name: MYSQL_USER
              value: ""
            - name: MYSQL_DATABASE
              value: ""
          ports:
            - name: mysql
              containerPort: 3306
          volumeMounts:
            - name: data
              mountPath: /var/lib/mysql
      volumes:
        - name: data
          persistentVolumeClaim:
            claimName: my-mysql
  • 执行部署操作
kubectl apply -f service.yaml -f secret.yaml -f pv.yaml -f pvc.yaml -f pod.yaml
  • 查看资源
kubectl get svc,secret,pv,pvc,deployment
  • 验证 MySQL
kubectl run -it --rm --image=mysql:5.7.14 --restart=Never mysql-client -- mysql -h my-mysql -u root -proot -e "show databases"

小结

由上可以发现部署 MySQL 的文件就已经很多了,如果应用只由一个或几个这样的服务组成,上面的部署方式完全足够了。

缺点

  • 1.很难管理、编辑和维护如此多的服务。每个服务都有若干配置,缺乏一个更高层次的工具将这些配置组织起来。
  • 2.不容易将这些服务作为一个整体统一发布。部署人员需要首先理解应用都包含哪些服务,然后按照逻辑顺序依次执行 kubectl apply。即缺少一种工具来定义应用与服务,以及服务与服务之间的依赖关系。
  • 3.不能高效地共享和重用服务。比如两个应用都要用到 MySQL 服务,但配置的参数不一样,这两个应用只能分别拷贝一套标准的 MySQL 配置文件,修改后通过 kubectl apply 部署。也就是说不支持参数化配置和多环境部署。
  • 4.不支持应用级别的版本管理。虽然可以通过 kubectl rollout undo 进行回滚,但这只能针对单个 Deployment,不支持整个应用的回滚。
  • 5.不支持对部署的应用状态进行验证。比如是否能通过预定义的账号访问 MySQL。虽然 Kubernetes 有健康检查,但那是针对单个容器,我们需要应用(服务)级别的健康检查。

Helm

chart

chart 是创建一个应用的信息集合,包括各种 Kubernetes 对象的配置模板、参数定义、依赖关系、文档说明等。chart 是应用部署的自包含逻辑单元。可以将 chart 想象成 apt、yum 中的软件安装包。

release

release 是 chart 的运行实例,代表了一个正在运行的应用。当 chart 被安装到 Kubernetes 集群,就生成一个 release。chart 能够多次安装到同一个集群,每次安装都是一个 release。

helm 功能

  • 1.从零创建新 chart
  • 2.与存储 chart 的仓库交互,拉取、保存和更新 chart
  • 3.在 Kubernetes 集群中安装和卸载 release
  • 4.更新、回滚和测试 release

架构

Helm架构

Helm 客户端是终端用户使用的命令行工具,用户可以:

  • 1.在本地开发 chart
  • 2.管理 chart 仓库
  • 3.与 Tiller 服务器交互
  • 4.在远程 Kubernetes 集群上安装 chart
  • 5.查看 release 信息
  • 6.升级或卸载已有的 release

Tiller 服务器运行在 Kubernetes 集群中,它会处理 Helm 客户端的请求,与 Kubernetes API Server 交互。Tiller 服务器负责:

  • 1.监听来自 Helm 客户端的请求
  • 2.通过 chart 构建 release
  • 3.在 Kubernetes 中安装 chart,并跟踪 release 的状态
  • 4.通过 API Server 升级或卸载已有的 release

Helm 客户端负责管理 chart;Tiller 服务器负责管理 release。

安装 helm 客户端

curl https://raw.githubusercontent.com/helm/helm/v2.16.2/scripts/get | bash

若一直安装失败,可以换下方手动安装方式

wget -O ~/helm-v2.16.2-linux-amd64.tar.gz https://get.helm.sh/helm-v2.16.2-linux-amd64.tar.gz
tar zxvf ~/helm-v2.16.2-linux-amd64.tar.gz

wget -O ~/helm-v2.6.2-linux-amd64.tar.gz https://get.helm.sh/helm-v2.6.2-linux-amd64.tar.gz
tar zxvf ~/helm-v2.6.2-linux-amd64.tar.gz

mv linux-amd64/helm /usr/local/bin/
chmod +x /usr/local/bin/helm
  • 查看版本
helm version
  • 配置补全脚本
echo -n 'source <(helm completion zsh)' >> ~/.zshrc

安装 Tiller 服务器

  • 配置 RBAC 授权

rbac-config.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: tiller
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: tiller
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
  - kind: ServiceAccount
    name: tiller
    namespace: kube-system

tiller 版本和 helm client 对应的版本一样

kubectl apply -f rbac-config.yaml  # kubectl 版本1.16.0之后才需要执行

helm init --upgrade --service-account tiller --tiller-image registry.cn-hangzhou.aliyuncs.com/google_containers/tiller:v2.16.2 --stable-repo-url http://mirror.azure.cn/kubernetes/charts

tiller 指定 v2.6.2 版本一直报 Error: error validating "": error validating data: the server could not find the requested resource 错误,故修改版本

  • 查看 Tiller
kubectl get --namespace=kube-system svc,deployment,pv,pod tiller-deploy
  • 再次查看版本
helm version
  • 查看 Helm 仓库地址
helm repo list

比如可以通过 helm repo add stable http://mirror.azure.cn/kubernetes/charts 添加国内仓库

  • 关键字搜索
helm search mysql
  • 安装 MySQL
ubuntu2@root helm install --name mysql --set mysqlRootPassword=root,mysqlUser=test,mysqlPassword=test,mysqlDatabase=test stable/mysql
Error: no available release name found

以上报错,通常是因为 Tiller 服务器的权限不足。

解决报错

  • 创建 Kubernetes 的服务帐号和绑定角色
kubectl create serviceaccount --namespace kube-system tiller

kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
  • 为 Tiller 设置帐号
kubectl patch deploy --namespace kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}'
  • 查看授权是否成功
kubectl get deploy --namespace kube-system tiller-deploy --output yaml | grep serviceAccount
  • 卸载 Helm 服务器端 Tiller
kubectl delete --namespace=kube-system svc tiller-deploy
kubectl delete deployment -n kube-system tiller-deploy
helm reset --force; trash ~/.helm

重新安装MySQL

  • 重新执行上面执行过的 安装MySQL 操作
  • 查看组成 release 的各个对象
kubectl get service mysql
kubectl get deployment mysql
kubectl get pod `kubectl get pod | grep mysql | awk '{print $1}'`
kubectl get pvc mysql

Chart 目录结构

chart 是 Helm 的应用打包格式。chart 由一系列文件组成,这些文件描述了 Kubernetes 部署应用时所需要的资源,比如 Service、Deployment、PersistentVolumeClaim、Secret、ConfigMap 等。

单个的 chart 可以非常简单,只用于部署一个服务,比如 Memcached;chart 也可以很复杂,部署整个应用,比如包含 HTTP Servers、 Database、消息中间件、cache 等。

chart 将这些文件放置在预定义的目录结构中,通常整个 chart 被打成 tar 包,而且标注上版本信息,便于 Helm 部署。

MySQL chart

一旦安装了某个 chart,就可以在 ~/.helm/cache/archive 中找到 chart 的 tar 包。

  • 解压 tar 包
tar zxvf ~/.helm/cache/archive/mysql-1.6.2.tgz -C .
tree -L 3 mysql
mysql
├── Chart.yaml    # YAML文件,描述chart的概要信息,`name` 和 `version` 是必填项,其他都是可选
├── LICENSE   # 文本文件,描述 chart 的许可信息,此文件为可选。
├── README.md   # Markdown 格式的 README 文件,相当于 chart 的使用文档,此文件为可选
├── requirements.yaml   # chart 可能依赖其他的 chart,此文件为可选。
├── templates   # 各类 Kubernetes 资源的配置模板,Helm 会将 values.yaml 中的参数值注入到模板中生成标准的 YAML 配置文件。
│   ├── configurationFiles-configmap.yaml
│   ├── deployment.yaml
│   ├── _helpers.tpl
│   ├── initializationFiles-configmap.yaml
│   ├── NOTES.txt   # chart 的简易使用文档,chart 安装成功后会显示此文档内容。
│   ├── pvc.yaml
│   ├── secrets.yaml
│   ├── serviceaccount.yaml
│   ├── servicemonitor.yaml
│   ├── svc.yaml
│   └── tests
│       ├── test-configmap.yaml
│       └── test.yaml
└── values.yaml   # 配置参数的默认值。

Chart模板

  • 查看chart中的内容
helm inspect values stable/mysql

chart 定义了一个 PersistentVolumeClaim,申请 8G 的 PersistentVolume。由于我们的实验环境不支持动态供给,所以得预先创建好相应的 PV,其配置文件 mysql-pv.yml 内容为:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: mysql-pd
spec:
  accessModes:
    - ReadWriteOnce
  capacity:
    storage: 4Gi
  persistentVolumeReclaimPolicy: Retain
  nfs:
    path: /nfsdata/mysql-pv
    server: 192.168.1.6

创建PV

kubectl apply -f mysql-pv.yaml

定制化安装chart

Helm 有两种方式传递配置参数:

  • 1.指定自己的 values 文件。

通常的做法是首先通过 helm inspect values stable/mysql > myvalues.yaml 生成 values 文件,然后设置 mysqlRootPassword,之后执行 helm install --values=myvalues.yaml mysql

  • 2.通过 –set 直接传入参数值,比如
helm install stable/mysql --set mysqlRootPassword=root -n my

升级和回滚

release 发布后可以执行 helm upgrade 对其升级,通过 –values 或 –set应用新的配置。

将当前的 MySQL 版本升级到 5.7.15:

helm upgrade --set imageTag=5.7.15 my stable/mysql
  • 查看升级结果
kubectl get deployment my-mysql -o wide
  • 查看历史版本
helm history my
  • 回滚
helm rollback my 1
  • 查看回滚结果
kubectl get deployment my-mysql -o wide

开发自己的chart

创建chart

helm create mychart

调试

Helm 提供了 debug 的工具:helm lint <chart>helm install --dry-run --debug <chart>

helm lint 会检测 chart 的语法,报告错误以及给出建议。

helm install –dry-run –debug 会模拟安装 chart,并输出每个模板生成的 YAML 内容。

安装方式

  • 1.安装仓库中的 chart,例如:helm install stable/nginx
  • 2.通过 tar 包安装,例如:helm install ./nginx-1.2.3.tgz
  • 3.通过 chart 本地目录安装,例如:helm install ./nginx
  • 4.通过 URL 安装,例如:helm install https://example.com/charts/nginx-1.2.3.tgz

安装chart

helm install mychart

将 chart 添加到仓库

chart 通过测试后可以将其添加到仓库,团队其他成员就能够使用。任何 HTTP Server 都可以用作 chart 仓库

环境信息: ubuntu1 是k8s的node节点, IP为 192.168.1.5

  • 1.在 ubuntu1 上启动 httpd 容器
mkdir -p /tmp/var/www/charts
docker run -d -p 8080:80 --name httpd -v /tmp/var/www:/usr/local/apache2/htdocs httpd
  • 2.在 ubuntu2 上将 mychart 打包
helm package mychart
  • 3.在 ubuntu2 上生成仓库的 index 文件
mkdir ~/myrepo
mv ./mychart-0.1.0.tgz ~/myrepo

helm repo index ~/myrepo --url http://192.168.1.5:8080/charts
ls ~/myrepo

Helm 会扫描 myrepo 目录中的所有 tgz 包并生成 index.yaml。–url指定的是新仓库的访问路径。新生成的 index.yaml 记录了当前仓库中所有 chart 的信息:

  • 4.将 mychart的tar包index.yaml 拷贝到 ubuntu1
scp ~/myrepo/index.yaml ~/myrepo/mychart-0.1.0.tgz ubuntu1:/tmp/var/www/charts
  • 5.将新仓库加到Helm
helm repo add newrepo http://192.168.1.5:8080/charts

helm repo list
  • 6.在仓库中搜索mychart
helm search mychart
  • 7.从新仓库安装 mychart
helm install newrepo/mychart
  • 8.果以后仓库添加了新的 chart,需要更新本地的 index
helm repo update

上一篇 k8s 普通配置     下一篇 k8s 网络模型
目录导航