Loading

Helm

十二、Helm

在没使用 helm 之前,向 kubernetes 部署应用,我们要依次部署 deployment、svc 等,步骤较繁琐。况且随着很多项目微服务化,复杂的应用在容器中部署以及管理显得较为复杂,helm通过打包的方式,支持发布的版本管理和控制,很大程度上简化了 Kubernetes 应用的部署和管理。

Helm 本质就是让 K8s 的应用管理(Deployment,Service 等 ) 可配置,能动态生成。通过动态生成 K8s 资源清单文件(deployment.yamlservice.yaml)。然后调用Kubectl自动执行K8s资源部署。

Helm 是官方提供的类似于 YUM 的包管理器,是部署环境的流程封装。Helm 有两个重要的概念:chart和release:

  • chart 是创建一个应用的信息集合,包括各种 Kubernetes 对象的配置模板、参数定义、依赖关系、文档说明等。chart 是应用部署的自包含逻辑单元。可以将 chart 想象成 apt、yum 中的软件安装包。
  • release 是 chart 的运行实例,代表了一个正在运行的应用。当 chart 被安装到 Kubernetes 集群,就生成一个 release。chart 能够多次安装到同一个集群,每次安装都是一个 release。

Helm 包含两个组件:Helm 客户端和 Tiller 服务器,如下图所示:
image

Helm 客户端负责 chart 和 release 的创建和管理以及和 Tiller 的交互。

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

可以前往Helm的官方网站了解更多。

1 Helm部署

越来越多的公司和团队开始使用 Helm 这个 Kubernetes 的包管理器,我们也将使用 Helm 安装 Kubernetes 的常用组件。Helm由Helm客户端命令行工具和服务端tiller组成,Helm的安装十分简单。下载helm命令行工具到master的/usr/local/bin下,这里下载的2.13.1版本:

ntpdate ntp1.aliyun.com
wget https://get.helm.sh/helm-v2.13.1-linux-amd64.tar.gz
tar -zxvf helm-v2.13.1-linux-amd64.tar.gz 
cd linux-amd64/ 
cp helm /usr/local/bin/
chmod a+x /usr/local/bin/helm

要获取其它版本,前往github官方发布页面下载。

查看Helm和对应支持的Kubernetes版本,可以参考 Helm 版本支持策略

因为 Kubernetes API服务器开启了RBAC访问控制,所以需要创建tiller使用的service account:tiller并分配合适的角色给它。这里简单起见直接分配cluster-admin这个集群内置的 ClusterRole 给它。创建 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

创建这个SA:

kubectl create -f rbac-config.yaml 

安装tiller客户端

helm init --service-account=tiller --skip-refresh

如下:
image

tiller默认被部署在集群中的kube-system名称空间下,查看一下:

kubectl get pod -n kube-system -l app=helm

如果遇到ImagePullBackOff,可能是镜像下载错误,自行开启魔法,或者配置一个国内镜像,也可以从本地文件导入镜像。

查看Helm的版本:

helm version

如下图
image

2 Helm仓库

查看官方的Helm仓库:https://artifacthub.io/

Helm 的软件仓库Repository本质上是一个 Web 服务器,该服务器保存了一系列的 Chart 软件包以供用户下载,并且提供了一个该 Repository 的 Chart 包的清单文件以供查询。Helm 可以同时管理多个不同的 Repository。
image

和docker hub类似,比如搜索mysql
image

按照提示安装Helm源,然后通过命令就可以安装需要的应用。

3 Helm自定义模板

除了官方仓库,还可以自定义应用模版。下面的示例创建了一个自定义的Helm模版:

创建文件夹

mkdir ./hello-world
cd ./hello-world

创建自描述文件Chart.yaml , 这个文件必须由 name 和 version 定义

cat <<'EOF' > ./Chart.yaml 
name: hello-world 
version: 1.0.0 
EOF

创建模板文件,用于生成Kubernetes资源清单(manifests)

mkdir ./templates  #必须是这个目录名
# deployment的清单
cat <<'EOF' > ./templates/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: ibmcom/helloworld
          ports: 
            - containerPort: 8080
              protocol: TCP 
EOF

# svc的清单
cat <<'EOF' > ./templates/service.yaml 
apiVersion: v1 
kind: Service 
metadata: 
  name: hello-world 
spec: 
  type: NodePort 
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP 
  selector: 
    app: hello-world 
EOF

然后,使用命令创建Release

helm install .

使用 helm install 命令在 Kubernetes 集群中部署的 Chart 称为 Release。

单个chart可以在同一个集群中安装多次,并能创建多个不同的版本,类似于docker镜像和容器的关系。
image

查看当前helm运行列表信息,使用命令:

helm list

也可以通过kubectl查看:

kubectl get po
NAME                          READY   STATUS    RESTARTS   AGE
hello-world-5b696b88b-wj6tg   1/1     Running   0          4m29s

查看Release的状态信息:

helm status [Release名称]

结果如下:

LAST DEPLOYED: Thu Jan  6 08:24:16 2022
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/Pod(related)
NAME                         READY  STATUS   RESTARTS  AGE
hello-world-5b696b88b-wj6tg  1/1    Running  0         <invalid>

==> v1/Service
NAME         TYPE      CLUSTER-IP    EXTERNAL-IP  PORT(S)       AGE
hello-world  NodePort  10.97.96.155  <none>       80:31325/TCP  <invalid>

==> v1beta1/Deployment
NAME         READY  UP-TO-DATE  AVAILABLE  AGE
hello-world  1/1    1           1          <invalid>

看到服务的端口为31325,可以通过浏览器访问http://192.168.142.20:31325/获取到如下内容:
image

使用Helm的好处是,可以通过values.yaml来进行更新:

新建配置文件values.yaml,内容为:

cat <<'EOF' > ./values.yaml 
image: 
  repository: ibmcom/helloworld
  tag: 'v2' 
EOF 

这个文件中定义的值,在模板文件中可以通过.Values对象访问到:

cat <<'EOF' > ./templates/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: {{ .Values.image.repository }}:{{ .Values.image.tag }} 
          ports: 
            - containerPort: 80
              protocol: TCP 
EOF

这样后续直接修改values.yaml就能直接修改镜像和tag,现在我们只需要更新配置:

helm upgrade [Release名称] .

就可以实现更新。

4 常用命令

可以通过helm help获取帮助,查看一些常用的命令。

# 列出已经部署的 Release 
helm list 

# 查询一个特定的 Release 的状态 
helm status RELEASE_NAME 

# 移除所有与这个 Release 相关的 Kubernetes 资源(还有回滚余地) 
helm delete cautious-shrimp 

# 更新Release
helm upgrade RELEASE名称 CHART路径

# 回滚 helm rollback RELEASE_NAME REVISION_NUMBER 
helm rollback cautious-shrimp 1 

# 使用 helm delete --purge RELEASE_NAME 移除所有与指定 Release 相关的 Kubernetes 资源和所有这个 Release 的记录(彻底删除,无法回滚) 
helm delete --purge cautious-shrimp 

# 查看删除但还保留的记录
helm list --deleted

# 使用模板动态生成K8s资源清单时,提前预览生成的结果:使用--dry-run 
helm install --dry-run .  # 尝试部署,但不真正执行部署
helm install . --dry-run --debug  # --debug选项来打印出生成的清单文件内容

5 使用Helm部署dashboard

Dashboard 是基于网页的 Kubernetes 用户界面。 你可以使用 Dashboard 将容器应用部署到 Kubernetes 集群中,也可以对容器应用排错,还能管理集群资源。 你可以使用 Dashboard 获取运行在集群中的应用的概览信息,也可以创建或者修改 Kubernetes 资源 (如 Deployment,Job,DaemonSet 等等)。 例如,你可以对 Deployment 实现弹性伸缩、发起滚动升级、重启 Pod 或者使用向导创建新的应用。

Dashboard 同时展示了 Kubernetes 集群中的资源状态信息和所有报错信息。
image

你可以手动部署:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.2.0/aio/deploy/recommended.yaml

这里介绍使用Helm部署方式:

把Chart的压缩包下载到本地使用:

helm fetch stable/kubernetes-dashboard --version 1.8.0  # 下载1.8.0版本

如果提示Error: no cached repo found. (try 'helm repo update'). open /root/.helm/repository/cache/stable-index.yaml: no such file or directory,尝试更新仓库

helm repo update

如果还是失败,更换仓库:

# 先移除原先的仓库
helm repo remove stable
# 添加新的仓库地址
helm repo add stable https://charts.helm.sh/stable/
# 更新仓库
helm repo update

下载到本地之后,解压:

tar -xzf kubernetes-dashboard-1.8.0.tgz
cd kubernetes-dashboard

image

和我们自定义的Helm模版目录结构一样。

创建kubernetes-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

创建这个Release:

helm install . \
-n kubernetes-dashboard \  #指定名称
--namespace kube-system \  #指定名称空间
-f kubernetes-dashboard.yaml  #指定创建的yaml文件

查看服务:

kubectl get svc -n kube-system
NAME                   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                  AGE
kube-dns               ClusterIP   10.96.0.10      <none>        53/UDP,53/TCP,9153/TCP   46h
kubernetes-dashboard   ClusterIP   10.98.252.152   <none>        443/TCP                  97s
tiller-deploy          ClusterIP   10.110.29.137   <none>        44134/TCP                6h5m

这里将TYPE修改为NodePort方式(Ingress也可以),暴露服务给外界访问:

kubectl edit svc kubernetes-dashboard -n kube-system

修改完成后再次查看:

[root@k8s-master kubernetes-dashboard]# kubectl get svc -n kube-system
NAME                   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                  AGE
kube-dns               ClusterIP   10.96.0.10      <none>        53/UDP,53/TCP,9153/TCP   46h
kubernetes-dashboard   NodePort    10.98.252.152   <none>        443:30332/TCP            5m17s
tiller-deploy          ClusterIP   10.110.29.137   <none>        44134/TCP                6h9m

端口为30332,我们打开浏览器访问一下https://192.168.142.20:30332/

使用HTTPS,Chrome浏览器可能无法访问。
image

有以下三种解决方案:

  1. 下载证书sz /etc/kubernetes/pki/ca.crt,将证书导入到浏览器:打开浏览器右上角三个点设置--安全和隐私设置--安全--管理证书点击导入证书。
  2. 在不受信任的页面空白处输入thisisunsafe绕过Chrome证书验证(仅用于学习用途,不要滥用)
  3. 使用其它浏览器(火狐等)

最后你会看到如下页面:
image

可以通过指定kubeconfig文件访问,也可以通过令牌token的方式访问

查看token:

kubectl -n kube-system get secret | grep kubernetes-dashboard-token

kubernetes-dashboard-token-5bg6x                 kubernetes.io/service-account-token   3      44m

使用describe查看:

kubectl describe secret kubernetes-dashboard-token-5bg6x -n kube-system

token:      eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJrdWJlcm5ldGVzLWRhc2hib2FyZC10b2tlbi01Ymc2eCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjdmM2RjZWQ1LWFlYjEtNGQ0NS1iYWEzLWU4MWRjNGRkYmMwNiIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlLXN5c3RlbTprdWJlcm5ldGVzLWRhc2hib2FyZCJ9.hwmS2AvHQ5mjeIbBYbw95fVvj_IxvJgmQ0YoDjIdrlwhtpzJpaLSTjgC7PoNDOoFfb1_hPqjclcOIwSxv_fI3v4kfQRkA-BuPyMc-_waLZrw1hP_fe9bM9PxnvHSpCWyOZrrOWTum9MKY9SqfcvKUDsS2iaks-ynAJHP7occnr_gMJ8YNMtNDkNdd0Ry1pzRIEJhr-kX-81eJ2DhsjLyVFHHb2o0jkbDDOenJnNmODy5za7d7xOaguPuXCqsH2tu7MUbIoHDF78Sqg19qP4aprJYQO5t26wpA8_RArr5vf_iO64lrGgOZKIwY2uFi0v9iOklkCRY6vYeRBiBU9SIfg

复制token,使用令牌登录
image

然后就可以在管理页面可视化地创建应用了。

6 Prometheus

6.1 介绍

Prometheus(普罗米修斯)是一个最初在SoundCloud上构建的监控系统。自2012年成为社区开源项目,拥 有非常活跃的开发人员和用户社区。为强调开源及独立维护,Prometheus于2016年加入云原生云计算基金会 (CNCF),成为继Kubernetes之后的第二个托管项目。github官网地址

普罗米修斯的架构图:
image

  • Prometheus Server:收集指标和存储时间序列数据,并提供查询接口
  • ClientLibrary:客户端库
  • Push Gateway:短期存储指标数据。主要用于临时性的任务
  • Exporters:采集已有的第三方服务监控指标并暴露metrics
  • Alertmanager:告警
  • Web UI:简单的Web控制台,展示功能较弱一般用来调试监控函数PromSQL,一般用grafana替代展示
  • TSDB:时序数据库,用来存储监控数据。

普罗米修斯的监控内容:
image

监控指标 具体实现 举例
Pod性能 cAdvisor 容器CPU,内存利用率
Node性能 node-exporter 节点CPU,内存利用率
K8S资源对象 kube-state-metrics Pod/Deployment/Service

6.2 部署Prometheus

接下来开始构建:

mkdir prometheus && cd prometheus
git clone https://github.com/coreos/kube-prometheus.git 
cd kube-prometheus/manifests

修改grafana-service.yaml文件,使用NodePort方式访问grafana(修改原因是集群IP的方式无法暴露给外部):

vim grafana-service.yaml

apiVersion: v1 
kind: Service 
metadata: 
  name: grafana 
  namespace: monitoring 
spec: 
  type: NodePort #添加内容 
  ports: 
  - name: http 
    port: 3000 
    targetPort: http 
    nodePort: 30100 #添加内容 
  selector: 
    app: grafana

修改prometheus-service.yaml,改为NodePort

vim prometheus-service.yaml

apiVersion: v1 
kind: Service 
metadata: 
  labels: 
    prometheus: k8s
  name: prometheus-k8s 
  namespace: monitoring 
spec: 
  type: NodePort #添加内容
  ports: 
  - name: web 
    port: 9090 
    targetPort: web 
    nodePort: 30200  #添加内容
  selector: 
    app: prometheus 
    prometheus: k8s

修改alertmanager-service.yaml,改为NodePort

vim alertmanager-service.yaml 

apiVersion: v1 
kind: Service 
metadata: 
  labels: 
    alertmanager: main 
  name: alertmanager-main 
  namespace: monitoring 
spec: 
  type: NodePort  #添加内容
  ports: 
  - name: web 
    port: 9093 
    targetPort: web 
    nodePort: 30300  #添加内容
  selector: 
    alertmanager: main 
    app: alertmanager

开始部署:

kubectl apply -f ../manifests/

创建完成后,就可以查看监控信息了

kubectl top node
kubectl top pod

Prometheus对应的访问端口为30200,访问 http://192.168.142.20:30200
image

通过访问 http://192.168.142.20:30200/target 可以看到Prometheus已经成功连接上了 k8s 的API Server

grafana的端口号是30100,浏览器访问 http://192.168.142.20:30100/ 用户名密码默认为admin/admin
image

7 Horizontal Pod Autoscaling

Horizontal Pod Autoscaling(HPA)可以根据 CPU 利用率自动伸缩Replication Controller、Deployment或者Replica Set 中的 Pod 数量。

构建HPA示例:

kubectl run php-apache --image=gcr.io/google_containers/hpa-example --requests=cpu=200m --expose --port=80

#  --requests=cpu=200m:资源限制,初始分配值

创建 HPA 控制器(CPU负载超过50%就扩容,最大扩容数为10,负载小了之后会减小节点数,最少保持1个)

kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=10

增加负载,如果CPU利用率上去了,就会自动扩容增加Pod数量进行减压,最大增加到上面设置的10个上限。

8 部署EFK日志平台

EFK指的是:

  • E:Elasticsearch

  • F:Fluentd

  • K:Kibana

添加 Google incubator 仓库

helm repo add incubator http://storage.googleapis.com/kubernetes-charts-incubator

部署Elasticsearch

kubectl create namespace efk  #创建名称空间
helm fetch incubator/elasticsearch  #提前下载好镜像
tar -xf elasticsearch-xxx.tgz && cd elasticsearch  #如果服务器配置不够,可以修改values.yaml对应的集群节点和PVC设置,生产的也可以不修改

#安装运行
helm install --name els1 --namespace=efk -f values.yaml .

#启动测试
kubectl run cirror-$RANDOM --rm -it --image=cirros -- /bin/sh 
curl Elasticsearch:Port/_cat/nodes

部署Fluentd

helm fetch stable/fluentd-elasticsearch 
# 解压进入修改文件
vim values.yaml 
# 更改其中 Elasticsearch 访问地址 
# 安装运行
helm install --name flu1 --namespace=efk -f values.yaml . 

部署Kibana

部署EFK时,E和K的版本必须一致,否则会报错。

helm fetch stable/kibana --version 0.14.8 
# 同样需要进入values.yaml中Elasticsearch的访问地址
helm install --name kib1 --namespace=efk -f values.yaml . --version 0.14.8

修改svc访问方式为NodePort暴露给外部访问

kubectl edit svc kib1-kibana -n efk
type: NodePort

访问测试:
image

posted @ 2022-01-13 17:29  yyyz  阅读(447)  评论(0编辑  收藏  举报