目录
在没使用 helm 之前,向 kubernetes 部署应用,我们要依次部署 deployment、svc 等,步骤较繁琐。 况且随着很多项目微服务化,复杂的应用在容器中部署以及管理显得较为复杂,helm 通过打包的方式,支持发布的版本管理和控制, 很大程度上简化了 Kubernetes 应用的部署和管理。
Helm 本质就是让 K8s 的应用管理(Deployment、Service 等)可配置,可以通过类似于传递环境变量的方式能动态生成。通过动态生成 K8s 资源清单文件(deployment.yaml、service.yaml)。然后调用 Kubectl 自动执行 K8s 资源部署。
Helm 是官方提供的类似于 YUM 的包管理器,是部署环境的流程封装。Helm 有三个重要的概念:Chart 、Repository 和 Release
●Chart:Helm 的软件包,采用 TAR 格式。类似于 APT 的 DEB 包或者 YUM 的 RPM 包,其包含了一组定义 Kubernetes 资源相关的 YAML 文件。
●Repository(仓库):Helm 的软件仓库,Repository 本质上是一个 Web 服务器,该服务器保存了一系列的 Chart 软件包以供用户下载,并且提供了一个该 Repository 的 Chart 包的清单文件以供查询。Helm 可以同时管理多个不同的 Repository。
●Release:使用 helm install 命令在 Kubernetes 集群中部署的 Chart 称为 Release。可以理解为 Helm 使用 Chart 包部署的一个应用实例。一个 chart 通常可以在同一个集群中安装多次。每一次安装都会创建一个新的 release。
以 MySQL chart 为例,如果你想在你的集群中运行两个数据库,你可以安装该 chart 两次。每一个数据库都会拥有它自己的 release 和 release name。可以将 release 想象成应用程序发布的版本号。
总结:Helm 安装 charts 到 Kubernetes 集群中,每次安装都会创建一个新的 release。你可以在 Helm 的 chart repositories 中寻找新的 chart。
//Helm3 与 Helm2 的区别:
Helm2 是 C/S 架构,主要分为客户端 helm 和服务端 Tiller。在 Helm 2 中,Tiller 是作为一个 Deployment 部署在 kube-system 命名空间中,很多情况下,我们会为 Tiller 准备一个 ServiceAccount ,这个 ServiceAccount 通常拥有集群的所有权限。
用户可以使用本地 Helm 命令,自由地连接到 Tiller 中并通过 Tiller 创建、修改、删除任意命名空间下的任意资源。
在 Helm 3 中,Tiller 被移除了。新的 Helm 客户端会像 kubectl 命令一样,读取本地的 kubeconfig 文件,使用我们在 kubeconfig 中预先定义好的权限来进行一系列操作。
Helm 的官方网站 https://helm.sh/
1、安装 helm?
//下载二进制 Helm client 安装包
https://github.com/helm/helm/tags
tar -zxvf helm-v3.6.0-linux-amd64.tar.gz
mv linux-amd64/helm /usr/local/bin/helm
helm version
//命令补全
source <(helm completion bash)
2、使用 helm 安装 Chart
//添加常用的 chart 仓库,
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo add stable http://mirror.azure.cn/kubernetes/charts
helm repo add aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
helm repo add incubator https://charts.helm.sh/incubator
//更新 charts 列表
helm repo update ? ? ? ? ?
helm repo list
//查看 stable 仓库可用的 charts 列表
helm search repo stable
//删除 incubator 仓库
helm repo remove incubator
//查看 chart 信息
helm show chart stable/mysql ? ? #查看指定 chart 的基本信息
helm show all stable/mysql?? ??? ? #获取指定 chart 的所有信息
//安装 chart
helm install my-redis bitnami/redis [-n default] ? #指定 release 的名字为 my-redis,-n 指定部署到 k8s 的 namespace
helm install bitnami/redis --generate-name ? ?#不指定 release 的名字时,需使用 –generate-name 随机生成一个名字
//查看所有 release
helm ls?
helm list
//查看指定的 release 状态
helm status my-redis ? ? ? ? ? ? ??
//删除指定的 release
helm uninstall my-redis?
charts 除了可以在 repo 中下载,还可以自己自定义,创建完成后通过 helm 部署到 k8s。
//拉取 chart
mkdir /opt/helm
cd /opt/helm
helm pull stable/mysql
ls
mysql-1.6.9.tgz
tar xf mysql-1.6.9.tgz
yum install -y tree
tree mysql
mysql
├── Chart.yaml
├── README.md
├── templates
│???├── configurationFiles-configmap.yaml
│???├── deployment.yaml
│???├── _helpers.tpl
│???├── initializationFiles-configmap.yaml
│???├── NOTES.txt
│???├── pvc.yaml
│???├── secrets.yaml
│???├── serviceaccount.yaml
│???├── servicemonitor.yaml
│???├── service.yaml
│???├── ingress.yaml
│???└── tests
│??? ? ?├── test-configmap.yaml
│??? ? ?└── test.yaml
└── values.yaml
可以看到,一个 chart 包就是一个文件夹的集合,文件夹名称就是 chart 包的名称。
#chart 是包含至少两项内容的helm软件包:
(1)软件包自描述文件 Chart.yaml,这个文件必须有 name 和 version(chart版本) 的定义
(2)一个或多个模板,其中包含 Kubernetes 清单文件:
●NOTES.txt:chart 的“帮助文本”,在用户运行 helm install 时显示给用户
●deployment.yaml:创建 deployment 的资源清单文件
●service.yaml:为 deployment 创建 service 的资源清单文件
●ingress.yaml: 创建 ingress 对象的资源清单文件
●_helpers.tpl:放置模板助手的地方,可以在整个 chart 中重复使用
//创建自定义的 chart
helm create nginx
tree nginx
nginx
├── charts
├── Chart.yaml
├── templates
│???├── deployment.yaml
│???├── _helpers.tpl
│???├── hpa.yaml
│???├── ingress.yaml
│???├── NOTES.txt
│???├── serviceaccount.yaml
│???├── service.yaml
│???└── tests
│??? ? ?└── test-connection.yaml
└── values.yaml
cat nginx/templates/deployment.yaml
#在 templates 目录下 yaml 文件模板中的变量(go template语法)的值默认是在 nginx/values.yaml 中定义的,只需要修改 nginx/values.yaml 的内容,也就完成了 templates 目录下 yaml 文件的配置。
比如在 deployment.yaml 中定义的容器镜像:
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
cat nginx/values.yaml | grep repository
? repository: nginx
#以上变量值是在 create chart 的时候就自动生成的默认值,你可以根据实际情况进行修改。
//修改 chart
vim nginx/Chart.yaml
apiVersion: v2
name: nginx ? ? ? ? ? ? ? ? ? ? #chart名字
description: A Helm chart for Kubernetes
type: application ? ? ? ? ? ? ? #chart类型,application或library
version: 0.1.0 ? ? ? ? ? ? ? ? ?#chart版本
appVersion: 1.16.0 ? ? ? ? ? ? ?#application部署版本
vim nginx/values.yaml
replicaCount: 1
image:
? repository: nginx
? pullPolicy: IfNotPresent
? tag: "latest" ? ? ? ? ? ? ? ?#设置镜像标签
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
? create: true
? annotations: {}
? name: ""
podAnnotations: {}
podSecurityContext: {}
? # fsGroup: 2000
securityContext: {}
? # capabilities:
? # ? drop:
? # ? - ALL
? # readOnlyRootFilesystem: true
? # runAsNonRoot: true
? # runAsUser: 1000
service:
? type: ClusterIP
? port: 80
ingress:
? enabled: true ? ? ? ? ? ? ? ? #开启 ingress
? className: ""
? annotations: {}
? ? # kubernetes.io/ingress.class: nginx
? ? # kubernetes.io/tls-acme: "true"
? hosts:
? ? - host: www.kgc.com ? ? ? ? #指定ingress域名
? ? ? paths:
? ? ? ? - path: /
? ? ? ? ? pathType: Prefix ? ? ?#指定ingress路径类型
? tls: []
? # ?- secretName: chart-example-tls
? # ? ?hosts:
? # ? ? ?- chart-example.local
resources:
? limits:
? ? cpu: 100m
? ? memory: 128Mi
? requests:
? ? cpu: 100m
? ? memory: 128Mi
autoscaling:
? enabled: false
? minReplicas: 1
? maxReplicas: 100
? targetCPUUtilizationPercentage: 80
? # targetMemoryUtilizationPercentage: 80
nodeSelector: {}
tolerations: []
affinity: {}
//打包 chart
helm lint nginx ? ? ? ?#检查依赖和模版配置是否正确
helm package nginx ? ? #打包 chart,会在当前目录下生成压缩包 nginx-0.1.0.tgz
//部署 chart
helm install nginx ./nginx --dry-run --debug ? ?#使用 --dry-run 参数验证 Chart 的配置,并不执行安装
helm install nginx ./nginx -n default ? ? ? ? ? #部署 chart,release 版本默认为 1
或者
helm install nginx ./nginx-0.1.0.tgz
#可根据不同的配置来 install,默认是 values.yaml
helm install nginx ./nginx -f ./nginx/values-prod.yaml
helm ls
NAME ?? ?NAMESPACE?? ?REVISION?? ?UPDATED ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??? ?STATUS ??? ?CHART ? ? ??? ?APP VERSION
nginx?? ?default ??? ?1 ? ? ? ?? ?2022-01-18 23:43:06.170248683 +0800 CST?? ?deployed?? ?nginx-0.1.0?? ?1.16.0 ? ??
kubectl get pod,svc
NAME ? ? ? ? ? ? ? ? ? ? ? ? READY ? STATUS ? ?RESTARTS ? AGE
pod/nginx-67779bd969-kq2fm ? 1/1 ? ? Running ? 0 ? ? ? ? ?58m
NAME ? ? ? ? ? ? ? ? ? ?TYPE ? ? ? ?CLUSTER-IP ? ? ?EXTERNAL-IP ? PORT(S) ? AGE
service/kubernetes ? ? ?ClusterIP ? 10.96.0.1 ? ? ? <none> ? ? ? ?443/TCP ? 37h
service/nginx ? ? ? ? ? ClusterIP ? 10.100.0.171 ? ?<none> ? ? ? ?80/TCP ? ?58s
#部署 ingress
wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/mandatory.yaml
wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml
kubectl apply -f mandatory.yaml
kubectl apply -f service-nodeport.yaml
kubectl get pod,svc -n ingress-nginx
NAME ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?READY ? STATUS ? ?RESTARTS ? AGE
pod/nginx-ingress-controller-54b86f8f7b-jjlnj ? 1/1 ? ? Running ? 0 ? ? ? ? ?79s
NAME ? ? ? ? ? ? ? ? ? ?TYPE ? ? ? CLUSTER-IP ? ? EXTERNAL-IP ? PORT(S) ? ? ? ? ? ? ? ? ? ? ?AGE
service/ingress-nginx ? NodePort ? 10.101.36.34 ? <none> ? ? ? ?80:30665/TCP,443:30363/TCP ? 6s
kubectl get ingress
NAME ? ? ? ? ? ? ? ?CLASS ? ?HOSTS ? ? ? ? ?ADDRESS ? ? ? ?PORTS ? AGE
nginx ? ? ? ? ? ? ? <none> ? www.kgc.com ? ?10.101.36.34 ? 80 ? ? ?58m
vim /etc/hosts
.....
192.168.10.21 node02 www.kgc.com
curl http://www.kgc.com:30665
//修改为 NodePort 访问后,升级
vim nginx/values.yaml
service:
? type: NodePort
? port: 80
? nodePort: 30080
ingress:
? enabled: false
vim nginx/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
? name: {{ include "nginx.fullname" . }}
? labels:
? ? {{- include "nginx.labels" . | nindent 4 }}
spec:
? type: {{ .Values.service.type }}
? ports:
? ? - port: {{ .Values.service.port }}
? ? ? targetPort: http
? ? ? protocol: TCP
? ? ? name: http
? ? ? nodePort: {{ .Values.service.nodePort }} ? ? ? ? ? ? ?#指定 nodePort
? selector:
? ? {{- include "nginx.selectorLabels" . | nindent 4 }}
升级 release,release 版本加 1
helm upgrade nginx nginx?
kubectl get svc
NAME ? ? ? ? ? ?TYPE ? ? ? ?CLUSTER-IP ? ? ?EXTERNAL-IP ? PORT(S) ? ? ? ?AGE
kubernetes ? ? ?ClusterIP ? 10.96.0.1 ? ? ? <none> ? ? ? ?443/TCP ? ? ? ?38h
nginx ? ? ? ? ? NodePort ? ?10.100.0.171 ? ?<none> ? ? ? ?80:30080/TCP ? 79m
curl 192.168.80.14:30080
//回滚
#根据 release 版本回滚
helm history nginx ? ? ? ? ? ? ?#查看 release 版本历史
helm rollback nginx 1 ? ? ? ? ? #回滚 release 到版本1
helm history nginx ? ? ? ? ? #nginx release 已经回滚到版本 1
REVISION?? ?UPDATED ? ? ? ? ? ? ? ? ?? ?STATUS ? ??? ?CHART ? ? ??? ?APP VERSION?? ?DESCRIPTION ? ??
1 ? ? ? ?? ?Tue Jan 18 23:43:06 2022?? ?superseded?? ?nginx-0.1.0?? ?1.16.0 ? ? ?? ?Install complete
2 ? ? ? ?? ?Wed Jan 19 01:02:42 2022?? ?superseded?? ?nginx-0.1.0?? ?1.16.0 ? ? ?? ?Upgrade complete
3 ? ? ? ?? ?Wed Jan 19 01:04:52 2022?? ?deployed ??? ?nginx-0.1.0?? ?1.16.0 ? ? ?? ?Rollback to 1
#通常情况下,在配置好 templates 目录下的 kubernetes 清单文件后,后续维护一般只需要修改 Chart.yaml 和 values.yaml 即可。
//在命令行使用 --set 指定参数来部署(install,upgrade)release
#注:此参数值会覆盖掉在 values.yaml 中的值,如需了解其它的预定义变量参数,可查看 helm 官方文档。
helm upgrade nginx nginx --set image.tag='1.15'
helm 可以使用 harbor 作为本地仓库,将自定义的 chart 推送至 harbor 仓库。
//安装 harbor
#上传 harbor-offline-installer-v1.9.1.tgz 和 docker-compose 文件到 /opt 目录
cd /opt
cp docker-compose /usr/local/bin/
chmod +x /usr/local/bin/docker-compose
tar zxf harbor-offline-installer-v1.9.1.tgz
cd harbor/
vim harbor.yml
hostname: 192.168.10.19
harbor_admin_password: Harbor12345 ? ? #admin用户初始密码
data_volume: /data ? ? ? ? ? ? ? ? ? ? #数据存储路径,自动创建
chart:
? absolute_url: enabled ? ? ? ? ? ? ? ?#在chart中启用绝对url
log:
? level: info
? local:
? ? rotate_count: 50
? ? rotate_size: 200M
? ? location: /var/log/harbor ? ? ? ? ?#日志路径
#安装带有 Clair service 和 chart 仓库服务的 Harbor
./install.sh --with-clair --with-chartmuseum
//安装 push 插件
#在线安装
helm plugin install https://github.com/chartmuseum/helm-push
#离线安装
wget https://github.com/chartmuseum/helm-push/releases/download/v0.8.1/helm-push_0.8.1_linux_amd64.tar.gz
mkdir ~/.local/share/helm/plugins/helm-push
tar -zxvf helm-push_0.8.1_linux_amd64.tar.gz -C ~/.local/share/helm/plugins/helm-push
helm repo ls
#登录 Harbor WEB UI 界面,创建一个新项目
浏览器访问:http://192.168.10.19 ,默认的管理员用户名和密码是 admin/Harbor12345
点击 “+新建项目” 按钮
填写项目名称为 “chart_repo”,访问级别勾选 “公开”,点击 “确定” 按钮,创建新项目
#添加仓库
helm repo add harbor http://192.168.10.19/chartrepo/chart_repo --username=admin --password=Harbor12345
#注:这里的 repo 的地址是<Harbor URL>/chartrepo/<项目名称>,Harbor 中每个项目是分开的 repo。如果不提供项目名称, 则默认使用 library 这个项目。
#推送 chart 到 harbor 中
cd /opt/helm
helm push nginx harbor
#查看 chart_repo 项目中的 Helm Charts
HPA(Horizontal Pod Autoscaling)Pod 水平自动伸缩,Kubernetes 有一个 HPA 的资源,HPA 可以根据 CPU 利用率自动伸缩一个 Replication Controller、Deployment 或者Replica Set 中的 Pod 数量。
(1)HPA 基于 Master 上的 kube-controller-manager 服务启动参数 horizontal-pod-autoscaler-sync-period 定义的时长(默认为30秒),周期性的检测 Pod 的 CPU 使用率。
(2)HPA 与之前的 RC、Deployment 一样,也属于一种 Kubernetes 资源对象。通过追踪分析 RC 控制的所有目标 Pod 的负载变化情况,来确定是否需要针对性地调整目标Pod的副本数,这是HPA的实现原理。
(3)metrics-server 也需要部署到集群中, 它可以通过 resource metrics API 对外提供度量数据。
●metrics-server:是kubernetes集群资源使用情况的聚合器,收集数据给kubernetes集群内使用,如kubectl、hpa、scheduler等。
//在所有 Node 节点上传 metrics-server.tar 镜像包到 /opt 目录
cd /opt/
docker load -i metrics-server.tar
//使用 helm install 安装 metrics-server
mkdir /opt/metrics
cd /opt/metrics
helm repo remove stable
helm repo add stable https://charts.helm.sh/stable
或
helm repo add stable http://mirror.azure.cn/kubernetes/charts
helm repo update
helm pull stable/metrics-server
vim metrics-server.yaml
args:
- --logtostderr
- --kubelet-insecure-tls
- --kubelet-preferred-address-types=InternalIP
image:
? repository: k8s.gcr.io/metrics-server-amd64
? tag: v0.3.2
??
??
//使用 helm install 安装 metrics-server
helm install metrics-server stable/metrics-server -n kube-system -f metrics-server.yaml
kubectl get pods -n kube-system | grep metrics-server
#需要多等一会儿
kubectl top node
kubectl top pods --all-namespaces
--------------- 部署 HPA ---------------
//在所有节点上传 hpa-example.tar 镜像文件到 /opt 目录
hpa-example.tar 是谷歌基于 PHP 语言开发的用于测试 HPA 的镜像,其中包含了一些可以运行 CPU 密集计算任务的代码。
cd /opt
docker load -i hpa-example.tar
docker images | grep hpa-example
gcr.io/google_containers/hpa-example ? ? ? ? ?latest ? ? ? ? ?4ca4c13a6d7c ? 5 years ago ? ? 481MB
//创建用于测试的 Pod 资源,并设置请求资源为 cpu=200m
vim hpa-pod.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
? labels:
? ? run: php-apache
? name: php-apache
spec:
? replicas: 1
? selector:
? ? matchLabels:
? ? ? run: php-apache
? template:
? ? metadata:
? ? ? labels:
? ? ? ? run: php-apache
? ? spec:
? ? ? containers:
? ? ? - image: gcr.io/google_containers/hpa-example
? ? ? ? name: php-apache
? ? ? ? imagePullPolicy: IfNotPresent
? ? ? ? ports:
? ? ? ? - containerPort: 80
? ? ? ? resources:
? ? ? ? ? requests:
? ? ? ? ? ? cpu: 200m
---
apiVersion: v1
kind: Service
metadata:
? name: php-apache
spec:
? ports:
? - port: 80
? ? protocol: TCP
? ? targetPort: 80
? selector:
? ? run: php-apache
?? ?
?? ?
kubectl apply -f hpa-pod.yaml
kubectl get pods
NAME ? ? ? ? ? ? ? ? ? ? ? ? ?READY ? STATUS ? ?RESTARTS ? AGE
php-apache-799f99c985-5j5b4 ? 1/1 ? ? Running ? 0 ? ? ? ? ?26s
?? ??? ?
//使用 kubectl autoscale 命令创建 HPA 控制器,设置 cpu 负载阈值为请求资源的 50%,指定最少负载节点数量为 1 个,最大负载节点数量为 10 个
kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=10
//需要等一会儿,才能获取到指标信息 TARGETS
kubectl get hpa
NAME ? ? ? ? REFERENCE ? ? ? ? ? ? ? TARGETS ? MINPODS ? MAXPODS ? REPLICAS ? AGE
php-apache ? Deployment/php-apache ? 0%/50% ? ?1 ? ? ? ? 10 ? ? ? ?1 ? ? ? ? ?8m27s
kubectl top pods
NAME ? ? ? ? ? ? ? ? ? ? ? ? ?CPU(cores) ? MEMORY(bytes) ??
php-apache-799f99c985-5j5b4 ? 0m ? ? ? ? ? 11Mi ? ? ? ? ? ?
//创建一个测试客户端容器
kubectl run -it load-generator --image=busybox /bin/sh
//增加负载
# while true; do wget -q -O- http://php-apache.default.svc.cluster.local; done
//打开一个新的窗口,查看负载节点数目
kubectl get hpa -w
NAME ? ? ? ? REFERENCE ? ? ? ? ? ? ? TARGETS ? MINPODS ? MAXPODS ? REPLICAS ? AGE
php-apache ? Deployment/php-apache ? 39%/50% ? 1 ? ? ? ? 10 ? ? ? ?1 ? ? ? ? ?13m
php-apache ? Deployment/php-apache ? 54%/50% ? 1 ? ? ? ? 10 ? ? ? ?1 ? ? ? ? ?13m
php-apache ? Deployment/php-apache ? 342%/50% ? 1 ? ? ? ? 10 ? ? ? ?1 ? ? ? ? ?14m
php-apache ? Deployment/php-apache ? 315%/50% ? 1 ? ? ? ? 10 ? ? ? ?4 ? ? ? ? ?14m
php-apache ? Deployment/php-apache ? 315%/50% ? 1 ? ? ? ? 10 ? ? ? ?7 ? ? ? ? ?14m
php-apache ? Deployment/php-apache ? 315%/50% ? 1 ? ? ? ? 10 ? ? ? ?7 ? ? ? ? ?14m
php-apache ? Deployment/php-apache ? 68%/50% ? ?1 ? ? ? ? 10 ? ? ? ?7 ? ? ? ? ?15m
php-apache ? Deployment/php-apache ? 62%/50% ? ?1 ? ? ? ? 10 ? ? ? ?7 ? ? ? ? ?15m
php-apache ? Deployment/php-apache ? 67%/50% ? ?1 ? ? ? ? 10 ? ? ? ?7 ? ? ? ? ?15m
php-apache ? Deployment/php-apache ? 67%/50% ? ?1 ? ? ? ? 10 ? ? ? ?10 ? ? ? ? 15m
php-apache ? Deployment/php-apache ? 56%/50% ? ?1 ? ? ? ? 10 ? ? ? ?10 ? ? ? ? 16m
php-apache ? Deployment/php-apache ? 52%/50% ? ?1 ? ? ? ? 10 ? ? ? ?10 ? ? ? ? 16m
php-apache ? Deployment/php-apache ? 45%/50% ? ?1 ? ? ? ? 10 ? ? ? ?10 ? ? ? ? 16m
php-apache ? Deployment/php-apache ? 34%/50% ? ?1 ? ? ? ? 10 ? ? ? ?10 ? ? ? ? 16m
#以上可以看到经过压测,负载节点数量最大上升到 10 个,并且 cpu 负载也随之下降。
//如果 cpu 性能较好导致负载节点上升不到 10 个,可再创建一个测试客户端同时测试:
kubectl run -i --tty load-generator1 --image=busybox /bin/sh
# while true; do wget -q -O- http://php-apache.default.svc.cluster.local; done
//查看 Pod 状态,也发现已经创建了 10 个 Pod 资源
kubectl get pods
NAME ? ? ? ? ? ? ? ? ? ? ? ? ? ? READY ? STATUS ? ?RESTARTS ? AGE
load-generator-7d549cd44-xq5rv ? 1/1 ? ? Running ? 0 ? ? ? ? ?6m34s
php-apache-799f99c985-5j5b4 ? ? ?1/1 ? ? Running ? 0 ? ? ? ? ?20m
php-apache-799f99c985-6zn9n ? ? ?1/1 ? ? Running ? 0 ? ? ? ? ?3m12s
php-apache-799f99c985-8rnqz ? ? ?1/1 ? ? Running ? 0 ? ? ? ? ?101s
php-apache-799f99c985-lgth4 ? ? ?1/1 ? ? Running ? 0 ? ? ? ? ?2m57s
php-apache-799f99c985-nhtzv ? ? ?1/1 ? ? Running ? 0 ? ? ? ? ?101s
php-apache-799f99c985-nssrp ? ? ?1/1 ? ? Running ? 0 ? ? ? ? ?2m57s
php-apache-799f99c985-nx4hn ? ? ?1/1 ? ? Running ? 0 ? ? ? ? ?3m12s
php-apache-799f99c985-p7h4w ? ? ?1/1 ? ? Running ? 0 ? ? ? ? ?2m57s
php-apache-799f99c985-rmb9t ? ? ?1/1 ? ? Running ? 0 ? ? ? ? ?3m12s
php-apache-799f99c985-xwj5p ? ? ?1/1 ? ? Running ? 0 ? ? ? ? ?101s
#HPA 扩容的时候,负载节点数量上升速度会比较快;但回收的时候,负载节点数量下降速度会比较慢。
原因是防止在业务高峰期时因为网络波动等原因的场景下,如果回收策略比较积极的话,K8S集群可能会认为访问流量变小而快速收缩负载节点数量,而仅剩的负载节点又承受不了高负载的压力导致崩溃,从而影响业务。
扩展
//资源限制 - Pod
Kubernetes对资源的限制实际上是通过cgroup来控制的,cgroup是容器的一组用来控制内核如何运行进程的相关属性集合。针对内存、CPU 和各种设备都有对应的 cgroup。
默认情况下,Pod 运行没有 CPU 和内存的限额。这意味着系统中的任何 Pod 将能够像执行该 Pod 所在的节点一样, 消耗足够多的 CPU 和内存。一般会针对某些应用的 pod 资源进行资源限制,这个资源限制是通过 resources 的 requests 和 limits 来实现。requests 为创建 Pod 时初始要分配的资源,limits 为 Pod 最高请求的资源值。
示例:
spec:
? containers:
? - image: xxxx
? ? imagePullPolicy: IfNotPresent
? ? name: auth
? ? ports:
? ? - containerPort: 8080
? ? ? protocol: TCP
? ? resources:
? ? ? limits:
? ? ? ? cpu: "2"
? ? ? ? memory: 1Gi
? ? ? requests:
? ? ? ? cpu: 250m
? ? ? ? memory: 250Mi
//资源限制 - 命名空间
1.计算资源配额
apiVersion: v1
kind: ResourceQuota ? ? ? ?#使用 ResourceQuota 资源类型
metadata:
? name: compute-resources
? namespace: spark-cluster ?#指定命令空间
spec:
? hard:
? ? pods: "20" ? ?#设置 Pod 数量最大值
? ? requests.cpu: "2"
? ? requests.memory: 1Gi
? ? limits.cpu: "4"
? ? limits.memory: 2Gi
2.配置对象数量配额限制
apiVersion: v1
kind: ResourceQuota
metadata:
? name: object-counts
? namespace: spark-cluster
spec:
? hard:
? ? configmaps: "10"
? ? persistentvolumeclaims: "4"?? ??? ?#设置 pvc 数量最大值
? ? replicationcontrollers: "20" ? ?#设置 rc 数量最大值
? ? secrets: "10"
? ? services: "10"
? ? services.loadbalancers: "2"
#如果Pod没有设置requests和limits,则会使用当前命名空间的最大资源;如果命名空间也没设置,则会使用集群的最大资源。
K8S 会根据 limits 限制 Pod 使用资源,当内存超过 limits 时 cgruops 会触发 OOM。
这里就需要创建 LimitRange 资源来设置 Pod 或其中的 Container 能够使用资源的最大默认值
apiVersion: v1
kind: LimitRange ? ? #使用 LimitRange 资源类型
metadata:
? name: mem-limit-range
? namespace: test ? ?#可以给指定的 namespace 增加一个资源限制
spec:
? limits:
? - default: ? ? ? ? #default 即 limit 的值
? ? ? memory: 512Mi
? ? ? cpu: 500m
? ? defaultRequest: ? #defaultRequest 即 request 的值
? ? ? memory: 256Mi
? ? ? cpu: 100m
? ? type: Container ?#类型支持 Container、Pod、PVC
//Rancher 简介 ? ? k3s
Rancher 是一个开源的企业级多集群 Kubernetes 管理平台,实现了 Kubernetes 集群在混合云+本地数据中心的集中部署与管理, 以确保集群的安全性,加速企业数字化转型。超过 40000 家企业每天使用 Rancher 快速创新。
官网:https://docs.rancher.cn/
//Rancher 和 k8s 的区别
Rancher 和 k8s 都是用来作为容器的调度与编排系统。但是 rancher 不仅能够管理应用容器,更重要的一点是能够管理 k8s 集群。 Rancher2.x 底层基于 k8s 调度引擎,通过 Rancher 的封装,用户可以在不熟悉 k8s 概念的情况下轻松的通过 Rancher 来部署容器到k8s集群当中。
//实验环境
控制节点/master01?? ??? ?192.168.10.19
工作节点/node01?? ??? ??? ?192.168.10.20
工作节点/node02?? ??? ??? ?192.168.10.21
Rancher节点/rancher?? ? ? ?192.168.10.23
1、安装 rancher
#在 master01 节点下载 rancher-agent 镜像
docker pull rancher/rancher-agent:v2.5.7
#在 rancher 节点下载 rancher 镜像
docker pull rancher/rancher:v2.5.7
docker run -d --restart=unless-stopped -p 80:80 -p 443:443 --privileged --name rancher rancher/rancher:v2.5.7
#--restart=unless-stopped 表示在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器
docker ps -a|grep rancher
1326da432b17 ? rancher/rancher:v2.5.7 ? "entrypoint.sh" ? 13 seconds ago ? Up 13 seconds ? 0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp ? rancher
2、登录 Rancher 平台
需要先等一会儿,再浏览器访问 http://192.168.10.23 ,由于未使用授信证书,会有报警,忽略即可
登录后如是英文页面,可点击右下角语言选项选择中文
3、Rancher 管理已存在的 k8s 集群
选择【添加集群】,点击【导入】
【集群名称】设置为 k8s-cluster,点击【创建】
选择复制第三条命令绕过证书检查导入 k8s 集群
#在 k8s 控制节点 master01 上执行刚才复制的命令,如第一次执行报错,再执行一次即可
curl --insecure -sfL https://192.168.10.23/v3/import/ltlhl7vggnwz8knbjncgbxqlrf6krpbfbxtzh4qlpnqxrq5559k6gf_c-jf5bx.yaml | kubectl apply -f -
kubectl get ns
NAME ? ? ? ? ? ? ?STATUS ? AGE
cattle-system ? ? Active ? 3m24s
default ? ? ? ? ? Active ? 27d
fleet-system ? ? ?Active ? 2m14s
kube-node-lease ? Active ? 27d
kube-public ? ? ? Active ? 27d
kube-system ? ? ? Active ? 27d
kubectl get pods -n cattle-system -o wide
NAME ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?READY ? STATUS ? ?RESTARTS ? AGE ? ?IP ? ? ? ? ? NODE ? ? NOMINATED NODE ? READINESS GATES
cattle-cluster-agent-78647b4ff8-fbqdp ? 1/1 ? ? Running ? 0 ? ? ? ? ?2m1s ? 10.244.1.4 ? node01 ? <none> ? ? ? ? ? <none>
kubectl get pods -n fleet-system -o wide
NAME ? ? ? ? ? ? ? ? ? ? ? ? ? READY ? STATUS ? ?RESTARTS ? AGE ? ?IP ? ? ? ? ? NODE ? ? NOMINATED NODE ? READINESS GATES
fleet-agent-55bfc495bd-m9qjt ? 1/1 ? ? Running ? 0 ? ? ? ? ?6m8s ? 10.244.1.3 ? node01 ? <none> ? ? ? ? ? <none>
4、Rancher 部署监控系统
点击【启用监控以查看实时监控】
【监控组件版本】选择 0.2.1,其他的默认即可
点击【启用监控】,启动监控时间可能比较长,需要等待10分钟左右
5、使用 Rancher 仪表盘管理 k8s 集群
//以创建 nginx 服务为例
点击【仪表盘】进入 k8s 集群仪表盘界面
#创建名称空间 namespace
点击左侧菜单【Namespaces】,再点击右侧【Create】
【Name】输入 dev,【Description】选填可自定义
点击右下角【Create】
#创建 Deployment 资源
点击左侧菜单【Deployments】,再点击右侧【Create】
【Namespace】下拉选择 dev,【Name】输入 nginx-dev,【Replicas】输入 3
点击中间选项【Container】,【Container Image】输入 nginx:1.14,【Pull Policy】选择 IfNotPresent
在【Pod Labels】下点击【Add Lable】,【Key】输入 app,【Value】输入 nginx
点击中间选项【Labels and Annotations】,点击【Add Label】,【Key】输入 app,【Value】输入 nginx
点击右下角【Create】
#创建 service
点击左侧菜单【Services】,再点击右侧【Create】
点击【Node Port】
【Namespace】下拉选择 dev,【Name】输入 nginx-dev
【Port Name】输入 nginx,【Listening Port】输入 80,【Target Port】输入 80,【Node Port】输入 30180
点击中间选项【Selectors】,【Key】输入 app,【Value】输入 nginx
点击右下角【Create】
点击【nginx-dev】查看 service 是否已关联上 Pod
#点击 service 资源的节点端口 30180/TCP,可以访问内部的 nginx 页面了