9 Kubernetes-Helm应用
在 Kubernetes 中,将集群环境部署简单化。让 Kubernetes 中的应用,能动态生成
一、概念
核心概念:
chart:类似 docker-compose 的 yaml 文件
release:部署的项目(实例)
chart,可动态化运行为,release
Helm 包含两个组件:
Helm 客户端和 Tiller 服务器,如下图所示
Helm 客户端负责 chart 和 release 的创建和管理以及和 Tiller 的交互。Tiller 服务器运行在 Kubernetes 集群中,它会处理 Helm 客户端的请求,与 Kubernetes API Server 交互
HELM 版本
V2版本(现存)、V3版本(未来)区别:
V3版本更稳定
二、HELM 部署
注意:HELM 对时间同步要求高
1、下载 或上传 helm
直接下载:
$ ntpdate ntp1.aliyun.com
$ wget https://storage.googleapis.com/kubernetes-helm/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/
本地上传压缩包:
[root@k8s-master01 helm]# tar -xf helm-v2.13.1-linux-amd64.tar.gz
[root@k8s-master01 helm]# cp -a linux-amd64/helm /usr/local/bin/
2、每个节点导入 创建 tiller 所需镜像
[root@k8s-master01 helm]# scp helm-tiller.tar root@n1:/root/
root@n1's password:
helm-tiller.tar 100% 81MB 41.9MB/s 00:01
[root@k8s-master01 helm]# scp helm-tiller.tar root@n2:/root/
[root@k8s-master01 helm]# docker load -i helm-tiller.tar
[root@k8s-node01 ~]# docker load -i helm-tiller.tar
[root@k8s-node02 ~]# docker load -i helm-tiller.tar
3、创建 tiller,并进行集群角色绑定
[root@k8s-master01 helm]# vim rbac.yaml
[root@k8s-master01 helm]# cat rbac.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@k8s-master01 helm]# kubectl apply -f rbac.yaml
[root@k8s-master01 helm]# helm init --service-account tiller --skip-refresh
# 检查tiller运行
[root@k8s-master01 helm]# kubectl get pod -A |grep tiller
kube-system tiller-deploy-58565b5464-tsdpf 1/1 Running 0 135m
# 查看helm版本
[root@k8s-master01 ~]# 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 常用命令
$ helm install . # 基于当前目录部署应用
$ helm ls # 列出helm
$ helm delte helm名 # 删除helm
$ helm upgrade -f 文件名 helm名 . # 基于文件升级应用
$ helm upgrade -f 文件名 helm名 --set image,tag=v3 . # 命令升级
$ helm repo list # 查看本地 helm 使用的仓库地址
# 列出已经部署的 Release
$ helm ls
# 查询一个特定的 Release 的状态
$ helm status RELEASE_NAME
# 移除所有与这个 Release 相关的 Kubernetes 资源
$ helm delete cautious-shrimp
# 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 ls --deleted
0)部署一个简单环境:
1、创建文件夹
2、创建自描述文件 Chart.yaml (这个文件必须有 name 和 version 定义)
3、创建模板文件, 用于生成 Kubernetes 资源清单(manifests)
$ mkdir ./templates
$ 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: wangyanglinux/myapp:v1
ports:
- containerPort: 80
protocol: TCP
EOF
$ cat <<'EOF' > ./templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: hello-world
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
app: hello-world
EOF
4、 部署环境
使用命令 helm install RELATIVE_PATH_TO_CHART 创建一次Release
5、浏览器测试访问
部署成功
6、配置体现在配置文件 values.yaml
$ cat <<'EOF' > ./values.yaml
image:
repository: wangyanglinux/myapp
tag: v1
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 中的值可以被部署 release 时用到的参数 --values YAML_FILE_PATH 或 --set key1=value1, key2=value2 覆盖掉
$ helm install --set image.tag='latest' .
# 升级版本
helm upgrade -f values.yaml helm名 .
7、Debug
# 使用模板动态生成K8s资源清单,非常需要能提前预览生成的结果。
# 使用--dry-run --debug 选项来打印出生成的清单文件内容,而不执行部署
helm install . --dry-run --debug --set image.tag=latest
四、HELM 部署 dashboard
GUI 管理 Kubernetes 集群
1、找到镜像,chart包
Ⅰ、上传镜像到私有仓库:
# 导入dashboard镜像
[root@k8s-master01 ~]# docker load -i dashboard.tar
fbdfe08b001c: Loading layer 122.3MB/122.3MB
Loaded image: k8s.gcr.io/kubernetes-dashboard-amd64:v1.10.1
# 修改标签
[root@k8s-master01 ~]# docker tag k8s.gcr.io/kubernetes-dashboard-amd64:v1.10.1 harbor.yq.com/library/kubernetes-dashboard-amd64:v1.10.1
# 登录私有仓库
[root@k8s-master01 ~]# docker login harbor.yq.com -u admin -p Harbor12345
...
Login Succeeded
# 上传镜像
[root@k8s-master01 ~]# docker push harbor.yq.com/library/kubernetes-dashboard-amd64:v1.10.1
Ⅱ、上传chart包
2、HELM 安装 dashboard
Ⅰ、解压 dashboard 的 chart 包到指定位置
[root@k8s-master01 dashboard]# pwd
/usr/local/kubernetes/helm/dashboard
[root@k8s-master01 dashboard]# tar -xf kubernetes-dashboard-1.8.0.tgz
[root@k8s-master01 dashboard]# cd kubernetes-dashboard
[root@k8s-master01 kubernetes-dashboard]#
Ⅱ、编写新的 yaml 文件
修改镜像地址为私有仓库
关闭ingress
[root@k8s-master01 kubernetes-dashboard]# vim dashboard.yaml
[root@k8s-master01 kubernetes-dashboard]# cat dashboard.yaml
image:
repository: harbor.yq.com/library/kubernetes-dashboard-amd64
tag: v1.10.1
ingress:
enabled: false
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
Ⅲ、helm 部署
Ⅳ、修改 service 为NodePort,将服务暴露出去
也可以部署 ingress实现
[root@k8s-master01 kubernetes-dashboard]# kubectl get svc -n kube-system |grep dashboard
kubernetes-dashboard NodePort 10.107.63.76 <none> 443:31782/TCP 4m29s
3、证书相关配置
Ⅰ、创建证书
$ pwd
/usr/local/kubernetes/helm/dashboard
$ mkdir cert;cd cert
$ openssl genrsa -des3 -out server.key 2048
$ openssl req -new -key server.key -out server.csr
$ cp server.key server.key.org
$ openssl rsa -in server.key.org -out server.key
$ openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
Ⅱ、替换 dashboard 默认证书
$ kubectl delete secret kubernetes-dashboard -n kube-system
$ pwd
/usr/local/kubernetes/helm/dashboard/cert
$ mv server.key tls.key
$ mv server.crt tls.crt
$ kubectl create secret generic kubernetes-dashboard --from-file=tls.key --from-file=tls.crt -n kube-system
Ⅲ、修改 dashboard 的 deployment 控制器,识别证书文件
$ kubectl edit deployment kubernetes-dashboard -n kube-system
- --tls-key-file=tls.key
- --tls-cert-file=tls.crt
# dashboard的pod运行成功
$ kubectl get pod -n kube-system |grep dashboard
kubernetes-dashboard-5b99fb7b49-k6f87 1/1 Running 0 31s
# 获取svc的地址
$ kubectl get svc -n kube-system |grep dashboard
kubernetes-dashboard NodePort 10.100.101.159 <none> 443:30301/TCP 2m58s
4、浏览器登录
Ⅰ、浏览器输入地址登录
Ⅱ、获取 token(令牌)
如果选择kubeconfig文件认证,将 ~/.kube/config 文件上传。本次采用令牌认证
$ kubectl get secret -n kube-system |grep dashboard-token
kubernetes-dashboard-token-kfmvk kubernetes.io/service-account-token 3 6m32s
$ kubectl describe secret kubernetes-dashboard-token-kfmvk -n kube-system
Name: kubernetes-dashboard-token-kfmvk
Namespace: kube-system
Labels: <none>
Annotations: kubernetes.io/service-account.name: kubernetes-dashboard
kubernetes.io/service-account.uid: 13b5b878-fd84-4ae2-b511-555a7027f30b
Type: kubernetes.io/service-account-token
Data
====
ca.crt: 1025 bytes
namespace: 11 bytes
token: eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJrdWJlcm5ldGVzLWRhc2hib2FyZC10b2tlbi1rZm12ayIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjEzYjViODc4LWZkODQtNGFlMi1iNTExLTU1NWE3MDI3ZjMwYiIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlLXN5c3RlbTprdWJlcm5ldGVzLWRhc2hib2FyZCJ9.pJuNoplIrp6MT6BGLZEC-UzkdbZ6ytpuSl48ShPLF7jozpSIpLE4J51QfwNZX9bN0CP6zDpKGeX_KkyN10I2bzAJsDFQe83XGPLI3jNZGoO0jS3Row73z09IfczcTmw6fnZX2Ar1JoJ8wf5NqTJDdkLECrFyReacjZL5JjzzYH91ZGn2UJpLKYoedgLVY_5VfhZI_7xH8bDgDWJ6juMsb4nfwpxcLvey3VVr8ajrRK6y6uFBw05tAHhS-1G8B1IUFmYpWOCAOEbbcNQWxH7cz7T0eNEUtv1bPluzCKh7QngIXUJ-9rhTKdJWDP3ZYjDm07mQp7J0YB5e3P7BNKpBIw
Ⅲ、将令牌输入
5、使用 dashboard 部署应用
详细步骤请点击👉 使用 dashboard 部署应用.md
五、HELM 部署 EFK
0、相关概念:
-
EFK:CDN(内容分发网络)中的核心技术。分布式日志收集工具
-
由 ELK ---》 EFK
E:(Elasticsearch)搜索引擎,数据索引、切片数据、数据存储
L:(Logstash)日志收集,数据收集端
K:(Kibana)图形化展示
L:(Fluent)日志收集端,资源消耗比 Logstash 低。(使用 HostPath volume ,将 /var/log/containers 进行挂载)
- EFK 工作原理图
- 注意:K8S 中,在不同的名字空间中,网络可互相访问,但是资源不可同用
实验步骤:
注意:在实验环境中,需要物理机内存 >= 16G
1、导入所需镜像到私有仓库
先将进行导入到一个节点:
$ docker load -i elasticsearch-oss.tar
$ docker load -i fluentd-elasticsearch.tar
$ docker load -i kibanaoss.tar
再更改标签,导入私有仓库:
# 更改标签
$ docker tag docker.elastic.co/elasticsearch/elasticsearch-oss:6.4.2 harbor.yq.com/library/elasticsearch-oss:6.4.2
$ docker tag gcr.io/google-containers/fluentd-elasticsearch:v2.3.2 harbor.yq.com/library/fluentd-elasticsearch:v2.3.2
$ docker tag docker.elastic.co/kibana/kibana-oss:6.4.2 harbor.yq.com/library/kibana/kibana-oss:6.4.2
# 登录
$ docker login harbor.yq.com -u admin -p Harbor1234
# 导入镜像到私有仓库
$ docker push harbor.yq.com/library/elasticsearch-oss:6.4.2
$ docker push harbor.yq.com/library/fluentd-elasticsearch:v2.3.2
$ docker push harbor.yq.com/library/kibana/kibana-oss:6.4.2
2、导入 chart 包,配置部署 Elasticsearch
Ⅰ、实验环境中,避免内存不够用,将 master 节点的污点设置为 PreferNoSchedule
生产环境中,一般不会设置(一般默认的 NoSchedule)
# 查看master01节点的污点
$ kubectl describe node k8s-master01 |grep -i taint
Taints: node-role.kubernetes.io/master:NoSchedule
# 删除master01的污点
[root@k8s-master01 ~]# kubectl taint node k8s-master01 node-role.kubernetes.io/master=:NoSchedule-
# 设置master01的污点为 PreferNoSchedule
[root@k8s-master01 ~]# kubectl taint node k8s-master01 node-role.kubernetes.io/master=:PreferNoSchedule
# 查看master01节点的污点
[root@k8s-master01 ~]# kubectl describe node k8s-master01 |grep -i taint
Taints: node-role.kubernetes.io/master:PreferNoSchedule
Ⅱ、导入 chart 包,配置部署 Elasticsearch
导入 chart 包:
value.yaml 文件需要修改的地方:
部署 Elasticsearch:
$ pwd
/usr/local/kubernetes/helm/efk/elasticsearch
$ kubectl create ns efk
$ helm install --name els1 --namespace=efk -f values.yaml .
# 等待一段时间查看运行状态
$ kubectl get pod -n efk
NAME READY STATUS RESTARTS AGE
els1-elasticsearch-client-9c5cd87c4-fjdhp 1/1 Running 5 18m
els1-elasticsearch-client-9c5cd87c4-lft6l 1/1 Running 0 10m
els1-elasticsearch-data-0 0/1 Running 1 6m41s
els1-elasticsearch-data-1 1/1 Running 0 5m15s
els1-elasticsearch-master-0 1/1 Running 0 7m15s
els1-elasticsearch-master-1 1/1 Running 1 17m
els1-elasticsearch-master-2 1/1 Running 0 4m30s
测试 Elasticsearch 组件中的角色:
$ kubectl run cirror-$RANDOM --rm -it --image=cirros -- /bin/sh
/ #
/ # curl 10.97.149.187:9200/_cat/nodes
/ #
172.100.1.158 17 66 16 5.09 10.52 7.50 i - els1-elasticsearch-client-9c5cd87c4-fjdhp
172.100.0.54 21 99 24 1.58 3.52 2.48 i - els1-elasticsearch-client-9c5cd87c4-lft6l
172.100.2.47 17 87 10 0.79 12.51 19.84 mi - els1-elasticsearch-master-2
172.100.0.56 6 99 16 1.58 3.52 2.48 di - els1-elasticsearch-data-1
172.100.2.46 6 87 14 0.79 12.51 19.84 di - els1-elasticsearch-data-0
172.100.1.159 20 66 53 5.09 10.52 7.50 mi * els1-elasticsearch-master-1
172.100.0.55 16 99 24 1.58 3.52 2.48 mi - els1-elasticsearch-master-0
/ #
/ #
3、部署 Fluent
Ⅰ、解压 chart 包,修改 value.yaml 文件:
$ pwd
/usr/local/kubernetes/helm/efk
$ tar -xf fluentd-elasticsearch-2.0.7.tgz
$ cd fluentd-elasticsearch
# 获取efk的service地址
$ kubectl get svc -n efk
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
els1-elasticsearch-client ClusterIP 10.103.238.205 <none> 9200/TCP 2m56s
els1-elasticsearch-discovery ClusterIP None <none> 9300/TCP 2m56s
$ vim value.yaml
value.yaml 文件需要修改的部分:
Ⅱ、部署 Fluentd:
$ helm install --name flu1 --namespace=efk -f values.yaml .
[root@k8s-master01 fluentd-elasticsearch]# pwd
/usr/local/kubernetes/helm/efk/fluentd-elasticsearch
[root@k8s-master01 fluentd-elasticsearch]# helm install --name flu1 --namespace=efk -f values.yaml .
4、部署 Kibana
Ⅰ、解压 chart 包,修改 value.yaml 文件:
$ pwd
/usr/local/kubernetes/helm/efk
$ tar -xf kibana-0.14.8.tgz
$ cd kibana
$ kubectl get svc -n efk
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
els1-elasticsearch-client ClusterIP 10.97.149.187 <none> 9200/TCP 22m
els1-elasticsearch-discovery ClusterIP None <none> 9300/TCP 22m
$ vim values.yaml
value.yaml 文件修改的部分:
Ⅱ、部署 Kibana:
Ⅲ、修改 Kibana 的 service 类型为 NodePort 暴露出去
$ kubectl get svc -n efk
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
els1-elasticsearch-client ClusterIP 10.97.149.187 <none> 9200/TCP 31m
els1-elasticsearch-discovery ClusterIP None <none> 9300/TCP 31m
kib1-kibana ClusterIP 10.104.196.171 <none> 443/TCP 4m35s
$ kubectl edit svc kib1-kibana -n efk
5、浏览器访问测试
Ⅰ、先运行一个控制器,访问,产生日志
$ kubectl create deployment myapp --image=wangyanglinux/myapp:v1
$ kubectl scale deployment myapp --replicas=5
$ kubectl create svc clusterip myapp --tcp=80:80
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 29d
myapp ClusterIP 10.103.114.252 <none> 80/TCP 5s
$ while true;do curl 10.103.114.252/hostname.html ;sleep 1;done
Ⅱ、浏览器访问测试
先查询 Kibana 的 service 地址:
[root@k8s-master01 elasticsearch]# kubectl get svc -n efk |grep kib
kib1-kibana NodePort 10.104.196.171 <none> 443:31355/TCP 19m
浏览器访问:
六、HELM 部署Prometheus
0、相关概念
Prometheus:开源的报警系统和监控工具包,一种时序数据库,按照时间序列记录数据( PQL 语句)
- 监控服务器对比:
- Operator 开发框架
CRD+自定义控制器,组成新的开发方向
- Prometheus-Operator 的一些组件
1.MetricServer:对接 Prometheus ,从其中获取数据,再给集群内使用( 如:kubectl、hpa、schedule)
2.PrometheusOperator:系统监测,警报工具箱,用于存储监控数据
3.NodeExporter:存在于每个节点,对接猫头鹰监控。用于各节点关键度量指标状态数据
4.KubernetesMetics:收集集群内资源对象数据,指定报警规则
5.Prometheus:采用 pull 方式收集 ApiServer、Schedule、Controller Manager、kubelet组件的数据,通过http传输
6.Grafana:图形化展示工具
- Prometheus 的工作原理图
-
猫头鹰监控:(谷歌开发的),部署在物理节点追踪,实现对容器的资源使用量进行监控,每个节点的 Kubelet 自带了猫头鹰监控的功能
-
Prometheus 能够实现动态发现(Consul)
Operator部署:
1、导入镜像
# 解压镜像压缩包,导入镜像,导入私有仓库
$ pwd
/usr/local/kubernetes/prometheus
$ tar -xf prometheus.tar.gz
$ cd prometheus
$ docker load -i addon-resizer.tar
Loaded image: k8s.gcr.io/addon-resizer:1.8.4
$ docker tag k8s.gcr.io/addon-resizer:1.8.4 harbor.yq.com/library/addon-resizer:1.8.4
$ docker push harbor.yq.com/library/addon-resizer:1.8.4
$ docker load -i alertmanager.tar
Loaded image: quay.io/prometheus/alertmanager:v0.18.0
$ docker tag quay.io/prometheus/alertmanager:v0.18.0 harbor.yq.com/library/alertmanager:v0.18.0
$ docker push harbor.yq.com/library/alertmanager:v0.18.0
$ docker load -i configmap-reload.tar
Loaded image: quay.io/coreos/configmap-reload:v0.0.1
$ docker tag quay.io/coreos/configmap-reload:v0.0.1 harbor.yq.com/library/configmap-reload:v0.0.1
$ docker push harbor.yq.com/library/configmap-reload:v0.0.1
$ docker load -i grafana.tar
Loaded image: grafana/grafana:6.2.2
$ docker tag grafana/grafana:6.2.2 harbor.yq.com/library/grafana:6.2.2
$ docker push harbor.yq.com/library/grafana:6.2.2
$ docker load -i k8s-prometheus-adapter-amd64.tar
Loaded image: quay.io/coreos/k8s-prometheus-adapter-amd64:v0.4.1
$ docker tag quay.io/coreos/k8s-prometheus-adapter-amd64:v0.4.1 harbor.yq.com/library/k8s-prometheus-adapter-amd64:v0.4.1
$ docker push harbor.yq.com/library/k8s-prometheus-adapter-amd64:v0.4.1The push refers to repository
$ docker load -i kube-rbac-proxy.tar
Loaded image: quay.io/coreos/kube-rbac-proxy:v0.4.1
$ docker tag quay.io/coreos/kube-rbac-proxy:v0.4.1 harbor.yq.com/library/kube-rbac-proxy:v0.4.1
$ docker push harbor.yq.com/library/kube-rbac-proxy:v0.4.1
$ docker load -i kube-state-metrics.tar
Loaded image: quay.io/coreos/kube-state-metrics:v1.7.1
$ docker tag quay.io/coreos/kube-state-metrics:v1.7.1 harbor.yq.com/library/kube-state-metrics:v1.7.1
$ docker push harbor.yq.com/library/kube-state-metrics:v1.7.1
$ docker load -i node-exporter.tar
Loaded image: quay.io/prometheus/node-exporter:v0.18.1
$ docker tag quay.io/prometheus/node-exporter:v0.18.1 harbor.yq.com/library/node-exporter:v0.18.1
$ docker push harbor.yq.com/library/node-exporter:v0.18.1
$ docker load -i prometheus-config-reloader.tar
Loaded image: quay.io/coreos/prometheus-config-reloader:v0.31.1
$ docker tag quay.io/coreos/prometheus-config-reloader:v0.31.1 harbor.yq.com/library/prometheus-config-reloader:v0.31.1
$ docker push harbor.yq.com/library/prometheus-config-reloader:v0.31.1
$ docker load -i prometheus-operator.tar
Loaded image: quay.io/coreos/prometheus-operator:v0.31.1
$ docker tag quay.io/coreos/prometheus-operator:v0.31.1 harbor.yq.com/library/prometheus-operator:v0.31.1
$ docker push harbor.yq.com/library/prometheus-operator:v0.31.1
$ docker load -i prometheus.tar
Loaded image: quay.io/prometheus/prometheus:v2.11.0
$ docker tag quay.io/prometheus/prometheus:v2.11.0 harbor.yq.com/library/prometheus:v2.11.0
$ docker push harbor.yq.com/library/prometheus:v2.11.0
2、导入 Operator 框架部署的压缩包
$ tar -xf kube-prometheus.git.tar.gz
$ cd kube-prometheus/manifests/
$ pwd
/usr/local/kubernetes/prometheus/kube-prometheus/manifests
# 修改 yaml 文件中镜像下载位置,指向私有仓库
# (由于 yaml 文件很多,写个脚本筛选,再对应修改)
$ vim /usr/local/bin/check
$ cat /usr/local/bin/check
#!/bin/bash
for i in $(ls)
do
cat $i|grep "image" > /dev/null
[ $? -eq 0 ] && echo $i || echo "" > /dev/null
done
$ chmod a+x /usr/local/bin/check
$ check
0prometheus-operator-0alertmanagerCustomResourceDefinition.yaml
0prometheus-operator-0prometheusCustomResourceDefinition.yaml
0prometheus-operator-deployment.yaml
grafana-dashboardDefinitions.yaml
grafana-deployment.yaml
kube-state-metrics-deployment.yaml
node-exporter-daemonset.yaml
prometheus-adapter-deployment.yaml
prometheus-rules.yaml
$ vim 0prometheus-operator-deployment.yaml
$ cat 0prometheus-operator-deployment.yaml |grep image
- --config-reloader-image=harbor.yq.com/library/configmap-reload:v0.0.1
image: harbor.yq.com/library/prometheus-operator:v0.31.1
$ vim grafana-deployment.yaml
$ cat grafana-deployment.yaml|grep image
- image: harbor.yq.com/library/grafana:6.2.2
$ vim kube-state-metrics-deployment.yaml
$ cat kube-state-metrics-deployment.yaml |grep image
image: harbor.yq.com/library/kube-rbac-proxy:v0.4.1
image: harbor.yq.com/library/kube-rbac-proxy:v0.4.1
image: harbor.yq.com/library/kube-state-metrics:v1.7.1
image: harbor.yq.com/library/addon-resizer:1.8.4
$ vim node-exporter-daemonset.yaml
$ cat node-exporter-daemonset.yaml |grep image
image: harbor.yq.com/library/node-exporter:v0.18.1
image: harbor.yq.com/library/kube-rbac-proxy:v0.4.1
$ vim prometheus-adapter-deployment.yaml
$ cat prometheus-adapter-deployment.yaml |grep image
image: harbor.yq.com/library/k8s-prometheus-adapter-amd64:v0.4.1
3、修改 yaml 文件
修改 grafana-service.yaml 文件,使用 nodepode 方式访问 grafana:
$ 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,改为 nodepode
$ 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,改为 nodepode
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
4、部署:
多次执行命令,基于所有 yaml 文件运行资源对象
5、查看资源对象运行状态:
$ kubectl get pod -n monitoring
NAME READY STATUS RESTARTS AGE
alertmanager-main-0 2/2 Running 0 110s
alertmanager-main-1 1/2 Running 0 31s
grafana-58c655bb57-8nfzx 1/1 Running 0 2m
kube-state-metrics-698b8547bc-zpht5 4/4 Running 0 104s
node-exporter-bjgk2 2/2 Running 0 118s
node-exporter-ddrq6 2/2 Running 0 118s
node-exporter-vrmh7 2/2 Running 0 118s
prometheus-adapter-5cf4f7d66f-gtdsd 1/1 Running 0 119s
prometheus-k8s-0 3/3 Running 1 99s
prometheus-k8s-1 3/3 Running 1 99s
prometheus-operator-97fc48778-crbhh 1/1 Running 0 2m
$ kubectl get svc -n monitoring
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
alertmanager-main NodePort 10.100.148.232 <none> 9093:30300/TCP 105s
alertmanager-operated ClusterIP None <none> 9093/TCP,6783/TCP 2m6s
grafana NodePort 10.101.181.149 <none> 3000:30100/TCP 2m16s
kube-state-metrics ClusterIP None <none> 8443/TCP,9443/TCP 2m16s
node-exporter ClusterIP None <none> 9100/TCP 2m16s
prometheus-adapter ClusterIP 10.110.84.17 <none> 443/TCP 2m15s
prometheus-k8s NodePort 10.100.189.1 <none> 9090:30200/TCP 2m14s
prometheus-operated ClusterIP None <none> 9090/TCP 116s
prometheus-operator ClusterIP None <none> 8080/TCP
6、浏览器访问
7、Grafana 监控
登录导入
监控
七、自动扩容缩
MeticServer 对接 Prometheus ,获取资源消耗信息
结合资源消耗信息,hpa控制器,实现自动扩容缩
注意:扩容相应迅速、但是收缩很慢
# MeticServer 对接 Prometheus 后,kubectl top 命令可用
$ kubectl top node # 查看node资源消耗
$ kubectl top pod # 查看pod资源消耗
1、上传导入镜像
hpa镜像是专门对hpa自动扩容缩,进行测试的镜像
# 导入镜像到本地
$ docker load -i hpa.tar
Loaded image: wangyanglinux/hpa:latest
# 登录私有仓库
$ docker login harbor.yq.com -u admin -p Harbor12345
# 修改镜像标签,导入私有镜像仓库
$ docker tag wangyanglinux/hpa:latest harbor.yq.com/library/hpa:v1
$ docker push harbor.yq.com/library/hpa:v1
2、创建 deployment 控制器,和对应的 service
HPA 可以根据 CPU 利用率自动伸缩 RC、Deployment、RS 中的 Pod 数量
# 方法一:用命令创建deployment控制器,service
$ kubectl run php-apache --image=harbor.yq.com/library/hpa:v1 --requests=cpu=200m --expose --port=80
# 方法二:也可以通过干跑,导出 yaml 文件,基于 yaml 文件启动
$ mkdir 10;cd 10
$ kubectl run php-apache --image=harbor.yq.com/library/hpa:v1 --requests=cpu=200m --expose --port=80 --dry-run -o yaml > 3.hpa.yaml
$ cat 3.hpa.yaml
apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
name: php-apache
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
run: php-apache
status:
loadBalancer: {}
---
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
run: php-apache
name: php-apache
spec:
replicas: 1
selector:
matchLabels:
run: php-apache
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
run: php-apache
spec:
containers:
- image: harbor.yq.com/library/hpa:v1
name: php-apache
ports:
- containerPort: 80
resources:
requests:
cpu: 200m
status: {}
$ kubectl apply -f 3.hpa.
# 创建完成后,查看运行状态
$ kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
php-apache 1/1 1 1 56s
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 30d
php-apache ClusterIP 10.110.178.169 <none> 80/TCP 58s
3、创建 HPA 控制器
$ kubectl autoscale deployment php-apache --cpu-percent=50 --min=2 --max=10
# 等待一会后,hpa控制器对资源使用,进行查看
$ kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache 0%/50% 2 10 2 117s
4、增加负载,查看负载节点数目
$ kubectl run -i --tty work --rm --image=busybox /bin/sh
while true; do wget -q -O- http://php-apache.default.svc.cluster.local; done
# 等待一段时间后,自动扩容了(扩容迅速)
$ kubectl get pod |grep php-apache|wc -l
10
$ kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache 65%/50% 2 10 10 9m59s
# 退出测试的pod以后,需要等待一段时间才会缩容(缩容缓慢)
八、资源限制
MeticServer 有了获取资源消耗情况的能力,可以对资源对象,使用的资源,进行限制
1、资源限制 - Pod
使用 cgroup 实现资源限制(控制组,内核技术):Kubernetes 对资源的限制实际上是通过 CGROUP 来控制的,CGROUP 是容器的一组用来控制内核如果运行进程的相关属性集合。针对内存、CPU、和各种设备都有对应的 CGROUP
若不对pod进行资源限制,默认情况下,pod能使用集群中所有的资源
spec.containers.resources.limits 最高请求值(硬限制)
spec.containers.resouces.requests 分配值(软限制)
spec:
containers:
- image: wangyanglinux/myapp:v1
name: auth
resources:
limits:
cpu: "4"
memory: 2Gi
requests:
cpu: 250m
memory: 250Mi
requests 要分配的资源,limits 为最高请求的资源,可以理解为初始值和最大值
注意:若limits 和 requests 的值设置为相同,那么在资源请求中,优先分配
资源分配优先级: limits 与 requests 值设置为相同 > request 与limits 存在 > 无资源限制
一般情况下的 limits 值与 requests 值的设置:使用工具进行压测后,获取的值设置为 requests,requests 值 / 0.8 为 limits 的值
2、资源限制 - 名称空间
一、计算资源配额
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-resources
namespace: spark-cluster
spec:
hard:
requests.cpu: "20"
requests.memory: 100Gi
limits.cpu: "40"
limits.memory: 200Gi
二、配置对象数量配额限制
apiVersion: v1
kind: ResourceQuota
metadata:
name: object-counts
namespace: spark-cluster
spec:
hard:
pods: "20"
configmaps: "10"
persistentvolumeclaims: "4"
replicationcontrollers: "20"
secrets: "10"
services: "10"
services.loadbalancers: "2"
三、配置 CPU 和 内存 limitrange
apiVersion: v1
kind: LimitRange
metadata:
name: mem-limit-range
namespace: example
spec:
limits:
- default: # 默认限制值
memory: 512Mi
cpu: 2
defaultRequest: # 默认请求值
memory: 256Mi
cpu: 0.5
max: # 最大的资源限制
memory: 800Mi
cpu: 3
min: # 最小限制
memory: 100Mi
cpu: 0.3
maxLimitRequestRatio: # 超售值(提升资源使用率)(值越大,使用率越高;但是稳定性越低)
memory: 2
cpu: 2
type: Container # Container / Pod / PersistentVolumeClaim
3、在 dev 名字空间中测试 pod 限制
dev名字空间是在集群安全中,创建的名字空间,管理员为 devuser
1)创建 resourcequota 资源对象
对 dev名字空间中的pod个数,进行限制
[root@k8s-master01 10]# vim 4.rq.yaml
[root@k8s-master01 10]# cat 4.rq.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: object-counts
namespace: dev
spec:
hard:
pods: "4"
[root@k8s-master01 10]# kubectl apply -f 4.rq.yaml
2)进入 devuser 用户,测试限制
[root@k8s-master01 10]# su - devuser
[devuser@k8s-master01 ~]$ kubectl get pod
No resources found.
# 创建deployment控制器
[devuser@k8s-master01 ~]$ kubectl create deployment myapp --image=harbor.yq.com/library/myapp:v1
deployment.apps/myapp created
# 修改副本数为10个
[devuser@k8s-master01 ~]$ kubectl scale deployment myapp --replicas=10
deployment.extensions/myapp scaled
# 一段时间后,副本数仍然为4个,pods限制生效
[devuser@k8s-master01 ~]$ kubectl get pod
NAME READY STATUS RESTARTS AGE
myapp-65d7d4c559-5qp5c 1/1 Running 0 3m4s
myapp-65d7d4c559-6mmpf 1/1 Running 0 3m20s
myapp-65d7d4c559-b9zth 1/1 Running 0 3m4s
myapp-65d7d4c559-wrlrr 1/1 Running 0 3m4s









































