背景
一般情况下prometheus+grafana是监控kubernetes的最佳实践方式,但是大部分会将prometheus和grafana部署在集群内,方便直接调用集群内的cert和url进行监控;但是当有多个集群的时候不方便统一查看,所以本文章是将prometheus和grafana部署在集群外,方便数据统一存储和grafana统一页面展示,
无论是集群内还是集群外,收集集群信息的工具基本都是一致的,但是在集群外部署需要自行构建url路径
收集信息 | 工具 | 监控url | |
node性能 | node-exporter | /api/v1/nodes/nodename:9100/proxy/metrics | node节点信息 |
pod性能 | cadvisor |
/api/v1/nodes/nodename:9100/proxy/metrics/cadvisor | pod容器信息 |
k8s资源 | kube-state-metrics | deployment、ingress、daemonset等信息 |
当部署在集群内时,Prometheus有的监控使用的是集群私有ip,而集群外Prometheus使用默认自动拼接的监控url是无法访问的,此时需要自行构造apiserver proxy URLs,可以参考apiserver proxy URLs。通过proxy url集群外Prometheus就可以访问监控url来拉取监控指标了。
上表中Pod性能和Node性能的监控url其实都是自行构造的proxy url,而K8S资源使用默认的监控url,就会发现其endpoint都是K8S集群内部的私有ip,因此所有的状态都是down的。但是如果构建url,所有的状态都会是up。
一、集群内部署prometheus
要访问K8S apiserver需要先进行授权,而集群内部Prometheus可以使用集群内默认配置进行访问,而集群外访问需要使用token+客户端cert进行认证,因此需要先进行RBAC授权。
因此我们要首先创建service-account,cluster-role,clusterrolebinding,步骤如下
#创建namespace #kubectl create namespace prometheus #创建名为prometheus的serviceaccount #kubectl create sa prometheus #每次创建一个命名空间都会自动创建一个default的sa #kubectl get sa NAME SECRETS AGE arms-prom-operator 1 169d default 1 169d
创建clusterrole 或者直接用集群自带的cluster-admin
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: labels: addonmanager.kubernetes.io/mode: Reconcile kubernetes.io/cluster-service: "true" name: prometheus resourceVersion: "2351123657" selfLink: /apis/rbac.authorization.k8s.io/v1/clusterroles/prometheus uid: 809fe89e-3ac5-4901-afca-08b988324f34 rules: - apiGroups: - "" resources: - nodes - nodes/metrics - services - endpoints - pods verbs: - get - list - watch - apiGroups: - "" resources: - configmaps verbs: - get - nonResourceURLs: - /metrics verbs: - get
将sa和cluster-role进行绑定
#kubectl create clusterrolebinding prometheus --clusterrole cluster-admin --serviceaccount=prometheus:prometheus
查看sa对应的token
#kubectl get sa prometheus -o yaml apiVersion: v1 kind: ServiceAccount metadata: creationTimestamp: "2021-11-09T09:36:31Z" name: prometheus namespace: prometheus resourceVersion: "2351125959" selfLink: /api/v1/namespaces/prometheus/serviceaccounts/prometheus uid: 8f8f8e88-4d2c-40c5-abe7-c61615f7cf27 secrets: - name: prometheus-token-rt59g
查看sa里secrets里对应的token,将此处得到token保存好,后期连接k8s获取数据时会用到
#kubectl describe secrets prometheus-token-rt59g Name: prometheus-token-rt59g Namespace: prometheus Labels: <none> Annotations: kubernetes.io/service-account.name: prometheus kubernetes.io/service-account.uid: 8f8f8e88-4d2c-40c5-abe7-c61615f7cf27 Type: kubernetes.io/service-account-token Data ==== token: eyJhbGciOiJSUzI******************* ca.crt: 1135 bytes namespace: 10 bytes
开始在集群内部署收集信息工具
通过node-exporter采集集群node节点的数据,如cpu、内存、磁盘、网络流量等,建议用daemonset的方式部署node-exporter#vim node-exporter.y
apiVersion: extensions/v1beta1 kind: DaemonSet metadata: labels: app: node-exporter name: node-exporter spec: selector: matchLabels: app: node-exporter template: metadata: labels: app: node-exporter spec: containers: - image: quay.io/prometheus/node-exporter imagePullPolicy: Always name: node-exporter resources: limits: cpu: 102m memory: 180Mi requests: cpu: 102m memory: 180Mi ports: - containerPort: 9100 hostPort: 9100 name: node-exporter hostNetwork: true hostPID: true nodeSelector: beta.kubernetes.io/os: linux restartPolicy: Always tolerations: - key: "node-role.kubernetes.io/master" operator: "Exists" effect: "NoSchedule"
#kubectl apply -f node-exporter.yaml
# kubectl get pods
NAME READY STATUS RESTARTS AGE
node-exporter-496dj 1/1 Running 0 9d
node-exporter-628wq 1/1 Running 0 9d
node-exporter-v96rt 1/1 Running 0 9d
pod信息收集
pod信息收集不用单独部署工具,可直接在node收集信息的url后加cadvisor即可
k8s资源对象收集工具 kube-state-metrics部署
下载部署文件 #wget https://github.com/kubernetes/kube-state-metrics/tree/master/examples #kubectl apply deployment.yaml
此时部署kube-state-metrics时容易由于镜像下载失败导致pod处于pending状态,建议在电脑上自己下载后tag打标签上传到自己的镜像仓库后在修改deploymen里的image就可以下载下来。
至此,集群内收集node、集群和pod的信息就部署完成。
2、集群外通过docker-compose部署prometheus. prometheus 版本为2.31
version: '3'
services: prometheus: image: 'prom/prometheus' container_name: prometheus ports: - "9090:9090" volumes: - /work/prometheus/etc/prometheus.yml:/etc/prometheus/prometheus.yml - /work/prometheus/etc:/etc/prometheus - /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime #修改集群时间为中国标准时间 command: - '--config.file=/etc/prometheus/prometheus.yml' - '--storage.tsdb.path=/prometheus' - '--web.enable-admin-api' - '--web.enable-lifecycle' #mkdir /work/prometheus/etc #docker-compose up -d #vim /work/prometheus/etc/prometheus.yml global: # scrape_interval: 15s scrape_timeout: 30s # evaluation_interval: 10s scrape_configs: - job_name: "k8s" scheme: https tls_config: #此4行也要添加,如果不添加容易报错,提示error:x509 certificate signed by unknown authority insecure_skip_verify: true authorization: credentials_file: /etc/prometheus/k8s.token #之前具有权限secret中的token kubernetes_sd_configs: - role: node api_server: https://123.56.65.107:6443 tls_config: # insecure_skip_verify: true ca_file: /etc/prometheus/ca.crt #可以通过config文件内容,将certificate-authority-data内容进行解密 authorization: credentials_file: /etc/prometheus/k8s.token
此处可以看到已经收集到了k8s的信息
获取node-exporter信息
修改node-exporter的url为https://aoi-server:6443/api/v1/nodes/NODES-HOSTNAME:9100/proxy/metrics
如果不确定url,可以先用本地8002端口进行映射,kubectl proxy --port=8002,通过本地8002端口http://localhost:8001/来确定url的具体位置和内容是否正确
- job_name: "dev-bj-node-exporter" scheme: https tls_config: insecure_skip_verify: true authorization: credentials_file: /etc/prometheus/k8s.token kubernetes_sd_configs: - role: node api_server: https://api-server:6443 tls_config: # insecure_skip_verify: true #跳过证书校验认证 ca_file: /etc/prometheus/ca.crt authorization: credentials_file: /etc/prometheus/k8s.token relabel_configs: - target_label: __address__ replacement: api-server:6443 - source_labels: [__meta_kubernetes_node_name] regex: (.+) target_label: __metrics_path__ replacement: /api/v1/nodes/$1:9100/proxy/metrics - action: labelmap regex: __meta_kubernetes_node_label_(.+) - source_labels: [__meta_kubernetes_namespace__] target_label: kubernetes_namespace action: replace - source_labels: [__meta_kubernetes_service_name] action: replace target_label: service_name
建议收集多个 k8s集群数据的时候,开启多个docker容器,映射到主机不同的端口,这样方便在grafana根据不同端口收集不同集群数据,方便查看
参考链接:https://blog.csdn.net/yanggd1987/article/details/108807171、
https://www.yxingxing.net/archives/prometheus-20191203-k8s#1-pod%E6%80%A7%E8%83%BD
grafana安装和数据永久存储
#mkdir /work/grafana #cd /work/grafana #vim grafana.sh docker stop -t 10 grafana docker rm grafana docker run -itd --name grafana \ -p 3000:3000 \ -e "GF_SERVER_ADMIN_PASSWORD=PASSWORD" \ -v "/work/grafana/data:/var/lib/grafana" \ #数据永久存储在 --user "root" \ --log-opt max-size=500m --log-opt max-file=3 \ -d grafana/grafana
bash grafana.sh
默认登陆账号和密码是admin
选择prometheus数据源
tips:
grafana添加的dashboards模板后,部分内容显示不出数据,是因为promQL的语法中的关键字与prometheus那边的内容不相符,导致搜索不到,因此可以通过prometheus的9100端口下/metrics查看其关键字内容进行更改后可查看。
可以在dashboard的设置页面variables页面进行添加变量,添加变量时也需要参考prometheus的/metrics页面内容查看。
注意url即使是部署在本机,也要写明本机的ip地址,最好不要用localhost,如果出现网关错误,可能是prometheus机器的安全组端口没开。
不同的数据可以选择不同的模板,建议在grafana的官网进行搜索合适的dashboard模板 https://grafana.com/grafana/dashboards/
推荐模板ID:
node性能:8919、9276
pod性能:8588
k8s资源:3119、6417