在没使用
Helm
之前,向K8S
部署应用,我们要依次部署deployment
、svc
等,步骤较繁琐。况且随着很多项目微服务化,复杂的应用在容器中部署以及管理显得较为复杂,Helm
通过打包的方式,支持发布的版本管理和控制,很大程度上简化了K8S
应用的部署和管理
一、Helm 简介
Helm
本质就是让K8S
的应用管理(Deployment
、Service
等 ) 可配置,能动态生成。通过动态生成K8S
资源清单文件(deployment.yaml
,service.yaml
)。然后调用Kubectl
自动执行K8S
资源部署。
Helm
是官方提供的类似于YUM
的包管理器,是部署环境的流程封装。Helm
有两个重要的概念:chart
和release
:
chart
是创建一个应用的信息集合,包括各种Kubernetes
对象的配置模板、参数定义、依赖关系、文档说明等。chart
是应用部署的自包含逻辑单元。可以将chart
想象成apt
、yum
中的软件安装包release
是chart
的运行实例,代表了一个正在运行的应用。当chart
被安装到Kubernetes
集群,就生成一个release
。chart
能够多次安装到同一个集群,每次安装都是一个release
。
Helm
包含两个组件:Helm
客户端和Tiller
服务器,如下图所示:
Helm
客户端负责chart
和release
的创建和管理以及和Tiller
的交互。Tiller
服务器运行在 K8S
集群中,它会处理Helm
客户端的请求,与Kubernetes API Server
交互
二、Helm 部署
下载helm
客户端:
[root@master helm]# wget https://source-82722.oss-cn-beijing.aliyuncs.com/helm/helm-v2.13.1-linux-amd64.tar.gz
[root@master helm]# tar -zxvf helm-v2.13.1-linux-amd64.tar.gz && cp linux-amd64/helm /usr/local/bin/
由于api server
开启了RBAC
访问控制,所以需要创建tiller
使用的service account
,并分配合适的角色给它,这样才能访问api server
,详细内容可以查看helm
文档中的Role-based Access Control
。这里简单起见直接分配cluster- admin
这个集群内置的ClusterRole
给它,创建rbac-config.yaml
文件:
[root@master helm]# cat 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
[root@master helm]# kubectl create -f rbac-config.yaml
# gcr.io/kubernetes-helm/tiller 由于无法下载,所以我们直接加载镜像
# 工作节点均需要这个镜像
[root@worker1 ~]# docker load --input helm-tiller.tar
# helm初始化
[root@master helm]# helm init --service-account tiller --skip-refresh
[root@master helm]# kubectl get pod -n kube-system | grep tiller
tiller-deploy-6d47785b7c-jbdv7 1/1 Running 0 1h
#查看helm的版本
[root@master helm]# helm version
Client: &version.Version{SemVer:"v2.13.1", GitCommit:"618447cbf203d147601b4b9bd7f8c37a5d39fbb4", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.13.1", GitCommit:"618447cbf203d147601b4b9bd7f8c37a5d39fbb4", GitTreeState:"clean"}
三、Helm 自定义模板
[root@master helm]# mkdir hello-world && cd hello-world
#创建自描述文件 Chart.yaml,这个文件必须有name和version定义
[root@master hello-world]# vim Chart.yaml
name: hello-world
version: 1.0.0
#创建模板文件,用于生成Kubernetes资源清单(manifests)
[root@master templates]# mkdir templates && cd templates
[root@master templates]# vim deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: hello-world
spec:
replicas: 1
template:
metadata:
labels:
app: hello-world
spec:
containers:
- name: hello-world
image: hub.hc.com/library/myapp:v1
ports:
- containerPort: 80
protocol: TCP
[root@master templates]# vim service.yaml
apiVersion: v1
kind: Service
metadata:
name: hello-world
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
app: hello-world
# 使用命令 helm install RELATIVE_PATH_TO_CHART 创建一次Release
[root@master hello-world]# helm install .
# 列出已经部署的 Release
[root@master hello-world]# helm list
NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
dunking-manta 2 Tue Aug 18 10:04:27 2020 DEPLOYED hello-world-1.0.0 default
#查询一个特定的Release的状态
[root@master templates]# helm status dunking-manta
#移除所有与这个Release相关的Kubernetes资源
[root@master templates]# helm delete dunking-manta
#查看被删除的release
[root@master templates]# helm ls --deleted
NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
dunking-manta 2 Tue Aug 18 10:04:27 2020 DELETED hello-world-1.0.0 default
[root@master templates]# helm history dunking-manta
REVISION UPDATED STATUS CHART DESCRIPTION
1 Tue Aug 18 09:49:45 2020 SUPERSEDED hello-world-1.0.0 Install complete
2 Tue Aug 18 10:04:27 2020 SUPERSEDED hello-world-1.0.0 Deletion complete
#回滚
[root@master templates]# helm rollback dunking-manta 2
#彻底删除release
[root@master templates]# helm delete --purge dunking-manta
动态切换版本:
[root@master hello-world]# vim values.yaml
image:
repository: wangyanglinux/myapp
tag: 'v2'
#修改image标签
[root@master ~]# curl master:32218
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
# 修改
[root@master hello-world]# helm upgrade dunking-manta .
[root@master ~]# curl master:32218
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
#通过添加set image.tag=''参数修改版本
[root@master ~]# helm upgrade dunking-manta --set image.tag='v1' .
[root@master ~]# curl master:32218
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
Debug
# 使用模板动态生成K8s资源清单,非常需要能提前预览生成的结果
# 使用--dry-run --debug 选项来打印出生成的清单文件内容,而不执行部署
[root@master ~]# helm install . --dry-run --debug --set image.tag=latest
四、使用Helm部署dashboard
# 工作节点加载dashboard镜像
[root@worker1 ~]# docker load -i dashboard.tar
fbdfe08b001c: Loading layer 122.3MB/122.3MB
Loaded image: k8s.gcr.io/kubernetes-dashboard-amd64:v1.10.1
# 更换helm stable源
[root@master Dashboard]# helm repo remove stable
[root@master Dashboard]# helm repo add stable https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
[root@master Dashboard]# helm repo update
[root@master Dashboard]# helm repo list
NAME URL
local http://127.0.0.1:8879/charts
stable https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
#下载dashboard helm配置文件
[root@master Dashboard]# helm fetch stable/kubernetes-dashboard
[root@master Dashboard]# tar -zxvf kubernetes-dashboard-0.6.0.tgz
[root@master kubernetes-dashboard]# vim k8s-dashboard.yaml
image:
repository: k8s.gcr.io/kubernetes-dashboard-amd64
tag: v1.10.1
ingress:
enabled: true
hosts:
- k8s.frognew.com
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
tls:
- secretName: frognew-com-tls-secret
hosts:
- k8s.frognew.com
rbac:
clusterAdminRole: true
[root@master kubernetes-dashboard]# helm install stable/kubernetes-dashboard \
> -n kubernetes-dashboard \
> --namespace kube-system \
> -f k8s-dashboard.yaml
[root@master kubernetes-dashboard]# kubectl get svc -n kube-system | grep kubernetes-dashboard
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes-dashboard ClusterIP 10.105.124.175 <none> 443/TCP 3m39s
#修改svc的type ClusterIP为NodePort
[root@master kubernetes-dashboard]# kubectl edit svc kubernetes-dashboard -n kube-system
[root@master kubernetes-dashboard]# kubectl get svc -n kube-system | grep kubernetes-dashboard
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes-dashboard NodePort 10.105.124.175 <none> 443:30186/TCP 9m5s
五、使用dashboard部署应用
使用火狐浏览器访问https://192.168.182.100:30186
,选择令牌并输入下方查到的token
:
查询dashboard-token
[root@master kubernetes-dashboard]# kubectl -n kube-system get secret | grep kubernetes-dashboard-token
kubernetes-dashboard-token-5lgp8 kubernetes.io/service-account-token 3 27m
# 查看token
[root@master kubernetes-dashboard]# kubectl describe secret kubernetes-dashboard-token-5lgp8 -n kube-system
进入到dashboard
面板后,点击创建应用:
创建应用的参数如下,点击部署
容器部署成功: