k8s prometheus adapter —— 拓展 k8s 基于 prometheus 实现动态伸缩

一、背景介绍

       截至 k8s 1.10 版本,horizontalpodautoscalers 还只支持基于 CPU 使用率实现动态伸缩

       很多场景下,往往需要更多的监测指标来指导集群的扩缩容,如 HTTP 请求率、内存使用率等

       幸运的是,k8s 提供了 aggregation 来支持用户自定义的 API 拓展,详情请戳 这里

       通过自定义 api,我们就可以借助 prometheus 收集到的集群运行信息,完成自定义的弹性伸缩

       本文就介绍一种基于 prometneus 的自定义集群动态伸缩方案

二、配置步骤

2.1  本文假设用户已经拥有一个正常运行的 k8s 集群,如果您还没有部署,可以参考这里一键完成快速部署

       K8S 集群版本: 1.10.4

       Docker 版本:18.03.0-ce

       操作系统:CentOS Linux release 7.4.1708 (Core)

2.2  配置 K8S 集群,开启  aggregation 功能

       注意:如果您是通过 2.1 中链接部署的 k8s 集群,该步骤已经配置过,可以略过

       调整 apiserver 的启动配置项(追加如下几项,证书自己按需生成):

         --requestheader-client-ca-file=/etc/kubernetes/ssl/ca.pem \
         --requestheader-allowed-names=aggregator \
         --requestheader-extra-headers-prefix=X-Remote-Extra- \
         --requestheader-group-headers=X-Remote-Group \
         --requestheader-username-headers=X-Remote-User \
         --proxy-client-cert-file=/etc/kubernetes/ssl/aggregator-proxy.pem \
         --proxy-client-key-file=/etc/kubernetes/ssl/aggregator-proxy-key.pem \
         --enable-aggregator-routing=true \

       调整 controller-manager 的启动配置项(追加如下内容):

         --master=<apiserver-address>:<port> \
         --horizontal-pod-autoscaler-use-rest-clients=true \

       重启拉起集群

       检查配置是否生效

       执行:kubectl api-versions

       

2.3  部署 prometheus

       安装包 地址:https://github.com/coreos/prometheus-operator

       a.  该 prometheus 使用了 kubelet 进行数据采集,需要确保 kubelet 开启了如下参数配置

            --authentication-token-webhook=true
            --authorization-mode=Webhook

       b.  开启上述参数后,如果 kubectl logs xxx 命令提示     

            Forbidden (user=kubernetes, verb=get, resource=nodes, subresource=proxy

            说明 ApiServer 权限不够了,部署如下 yaml 文件可以解决

           (注意末尾的 user name 使用你集群的实际用户)

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: kube-apiserver
  namespace: kube-system
rules:
- apiGroups:
  - ""
  resources:
  - nodes/proxy
  - nodes/metrics
  verbs:
  - get
  - create
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: kube-apiserver
  namespace: kube-system
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: kube-apiserver
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: kubernetes

        c.   部署 prometheus

cd <PROMETHEUS-OPERATOR-ROOT>/contrib/kube-prometheus
kubectl create -f manifests/

        d.   配置 prometheus 拥有必须的权限

              默认 prometheus 不能访问所有命名空间

              拷贝 <PROMETHEUS-OPERATOR-ROOT>/contrib/kube-prometheus/manifests/prometheus-clusterRole.yaml

              编辑该文件,末尾追加如下内容:

- apiGroups: [""]
   resources:
   - nodes
   - services
   - endpoints
   - pods
   verbs: ["get", "list", "watch"]

              kubectl apply -f prometheus-clusterRole.yaml

         e.  默认部署的 prometheus 没有开放 NodePort

             prometheus-nodeport.yaml

kind: Service
apiVersion: v1
metadata:
  name: prometheus-nodeport
  namespace: monitoring
spec:
  type: NodePort
  ports:
    - port: 9090
      targetPort: 9090
      nodePort: 39000 
  selector:
    app: prometheus
    prometheus: k8s

              grafana-nodeport.yaml

kind: Service
apiVersion: v1
metadata:
  name: grafana-nodeport
  namespace: monitoring
spec:
  type: NodePort
  ports:
    - port: 3000
      targetPort: 3000
      nodePort: 39002 
  selector:
    app: grafana

            执行创建命令: kubectl apply -f  grafana-nodeport.yaml prometheus-nodeport.yaml

            查看 Grafana

              

2.4   部署 custom metrics

        首先确认下 metrics 默认 prometheus url 是否正确,文件路径为:

        contrib/kube-prometheus/experimental/custom-metrics-api/custom-metrics-apiserver-deployment.yaml

        本例,应该将 prometheus-url 配置为:http://prometheus-k8s.monitoring:9090,如下图所示:

        

cd <PROMETHEUS-OPERATOR-ROOT>/contrib/kube-prometheus/experimental/custom-metrics-api
chmod +x *.sh
./gencerts.sh
./deploy.sh

        查看 custom metrics 是否正常

        kubectl api-versions

        

        出来红框标注的 api 即代表成功

2.5   增加 target 监测对象

        prometheus 引入了 ServiceMonitor 对象,通过创建该对象,能动态告知 prometheus 监控哪些服务

        一个例子,(endpoint 的 port 即为要监测的服务开放的 port 名称,path 为 metrics 请求路径)

        其中,labels 必须包含 k8s-app,默认地 prometheus 使用该标签识别 ServiceMonitor

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: msapi-app-monitor
  namespace: monitoring
  labels:
    k8s-app: ctsi-backend
spec:
  selector:
    matchLabels:
      app: msapi-app
  endpoints:
  - port: msapi-app
    interval: 30s
    path: /actuator/prometheus
  namespaceSelector:
    matchNames:
    - ctsi 

        查看一下目前有哪些 ServiceMonitor

        kubectl get servicemonitor --all-namespaces

        

        可以看到,我们新加入的 ServiceMonitor 已经成功创建了

        去 Prometheus 界面看下

        

       

        可以看到,配置文件已经更新,添加了我们想要监测的目标了

2.6   实现动态伸缩

        通过 prometheus 监测的内容,我们可以实现动态伸缩集群,举个简单例子

kind: HorizontalPodAutoscaler
apiVersion: autoscaling/v2beta1
metadata:
  name: msapi-deployment-custom-autoscaler
  namespace: ctsi
spec:
  scaleTargetRef:
    # point the HPA at the sample application
    # you created above
    apiVersion: apps/v1
    kind: Deployment
    name: msapi-deployment 
  # autoscale between 1 and 10 replicas
  minReplicas: 1
  maxReplicas: 5
  metrics:
  # use a "Pods" metric, which takes the average of the
  # given metric across all pods controlled by the autoscaling target
  - type: Pods
    pods:
      # use the metric that you used above: pods/http_requests
      metricName: http_server_requests_seconds_count
      # target 500 milli-requests per second,
      # which is 1 request every two seconds
      targetAverageValue: 100

       查看 hpa

       kubectl get hpa --all-namespaces

       

       验证,动态伸缩正常!!!

猜你喜欢

转载自blog.csdn.net/shida_csdn/article/details/81077972