Kubernetes下的服务发现

    为了能够让Prometheus能够访问收到认证保护的Kubernetes API,我们首先需要做的是,对Prometheus进行访问授权。在Kubernetes中主要使用基于角色的访问控制模型(Role-Based Access Control),用于管理Kubernetes下资源访问权限。首先我们需要在Kubernetes下定义角色(ClusterRole),并且为该角色赋予相应的访问权限。同时创建Prometheus所使用的账号(ServiceAccount),最后则是将该账号与角色进行绑定(ClusterRoleBinding)。这些所有的操作在Kubernetes同样被视为是一系列的资源,可以通过YAML文件进行描述并创建,这里创建prometheus-rbac-setup.yml文件,并写入以下内容:

    其中需要注意的是ClusterRole是全局的,不需要指定命名空间。而ServiceAccount是属于特定命名空间的资源。通过kubectl命令创建RBAC对应的各个资源:

    1. clusterrole "prometheus" created
    2. serviceaccount "prometheus" created
    3. clusterrolebinding "prometheus" created

    在完成角色权限以及用户的绑定之后,就可以指定Prometheus使用特定的ServiceAccount创建Pod实例。修改prometheus-deployment.yml文件,并添加serviceAccountName和serviceAccount定义:

    1. spec:
    2. replicas: 1
    3. template:
    4. metadata:
    5. labels:
    6. app: prometheus
    7. spec:
    8. serviceAccountName: prometheus
    9. serviceAccount: prometheus

    通过kubectl apply对Deployment进行变更升级:

    指定ServiceAccount创建的Pod实例中,会自动将用于访问Kubernetes API的CA证书以及当前账户对应的访问令牌文件挂载到Pod实例的/var/run/secrets/kubernetes.io/serviceaccount/目录下,可以通过以下命令进行查看:

    1. kubectl exec -it prometheus-69f9ddb588-czn2c ls /var/run/secrets/kubernetes.io/serviceaccount/
    2. ca.crt namespace token

    服务发现

    通过kubectl命令行,可以方便的获取到当前集群中的所有节点信息:

    1. $ kubectl get nodes -o wide
    2. NAME STATUS ROLES AGE VERSION EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
    3. minikube Ready <none> 164d v1.8.0 <none> Buildroot 2017.02 4.9.13 docker://Unknown

    为了能够让Prometheus能够获取到当前集群中所有节点的信息,在Promtheus的配置文件中,我们添加如下Job配置:

    通过指定kubernetes_sd_config的模式为node,Prometheus会自动从Kubernetes中发现到所有的node节点并作为当前Job监控的Target实例。如下所示,这里需要指定用于访问Kubernetes API的ca以及token文件路径。

    对于Ingress,Service,Endpoints, Pod的使用方式也是类似的,下面给出了一个完整Prometheus配置的示例:

    1. apiVersion: v1
    2. data:
    3. prometheus.yml: |-
    4. global:
    5. scrape_interval: 15s
    6. scrape_configs:
    7. - job_name: 'kubernetes-nodes'
    8. tls_config:
    9. ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
    10. bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
    11. kubernetes_sd_configs:
    12. - role: node
    13. - job_name: 'kubernetes-service'
    14. tls_config:
    15. ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
    16. bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
    17. kubernetes_sd_configs:
    18. - role: service
    19. - job_name: 'kubernetes-endpoints'
    20. tls_config:
    21. ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
    22. bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
    23. kubernetes_sd_configs:
    24. - role: endpoints
    25. - job_name: 'kubernetes-ingress'
    26. tls_config:
    27. kubernetes_sd_configs:
    28. - role: ingress
    29. - job_name: 'kubernetes-pods'
    30. tls_config:
    31. ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
    32. bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
    33. kubernetes_sd_configs:
    34. - role: pod
    35. kind: ConfigMap
    36. metadata:
    37. name: prometheus-config

    更新Prometheus配置文件,并重建Prometheus实例:

    1. $ kubectl apply -f prometheus-config.yml
    2. configmap "prometheus-config" configured
    3. $ kubectl get pods
    4. prometheus-69f9ddb588-rbrs2 1/1 Running 0 4m
    5. $ kubectl delete pods prometheus-69f9ddb588-rbrs2
    6. pod "prometheus-69f9ddb588-rbrs2" deleted
    7. $ kubectl get pods
    8. prometheus-69f9ddb588-rbrs2 0/1 Terminating 0 4m

    同时Prometheus会自动将该资源的所有信息,并通过标签的形式体现在Target对象上。如下所示,是Promthues获取到的Node节点的标签信息:

    目前为止,我们已经能够通过Prometheus自动发现Kubernetes集群中的各类资源以及其基本信息。不过,如果现在查看Promtheus的Target状态页面,结果可能会让人不太满意:

    Target页面状态

    虽然Prometheus能够自动发现所有的资源对象,并且将其作为Target对象进行数据采集。 但并不是所有的资源对象都是支持Promethues的,并且不同类型资源对象的采集方式可能是不同的。因此,在实际的操作中,我们需要有明确的监控目标,并且针对不同类型的监控目标设置不同的数据采集方式。