• Kubernetes下的服务发现
    • Kubernetes的访问授权
    • 服务发现

    Kubernetes下的服务发现

    目前为止,我们已经能够在Kubernetes下部署一个简单的Prometheus实例,不过当前来说它并不能发挥其监控系统的作用,除了Prometheus,暂时没有任何的监控采集目标。在第7章中,我们介绍了Prometheus的服务发现能力,它能够与通过与“中间代理人“的交互,从而动态的获取需要监控的目标实例。而在Kubernetes下Prometheus就是需要与Kubernetes的API进行交互,从而能够动态的发现Kubernetes中部署的所有可监控的目标资源。

    Kubernetes的访问授权

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

    1. apiVersion: rbac.authorization.k8s.io/v1beta1
    2. kind: ClusterRole
    3. metadata:
    4. name: prometheus
    5. rules:
    6. - apiGroups: [""]
    7. resources:
    8. - nodes
    9. - nodes/proxy
    10. - services
    11. - endpoints
    12. - pods
    13. verbs: ["get", "list", "watch"]
    14. - apiGroups:
    15. - extensions
    16. resources:
    17. - ingresses
    18. verbs: ["get", "list", "watch"]
    19. - nonResourceURLs: ["/metrics"]
    20. verbs: ["get"]
    21. ---
    22. apiVersion: v1
    23. kind: ServiceAccount
    24. metadata:
    25. name: prometheus
    26. namespace: default
    27. ---
    28. apiVersion: rbac.authorization.k8s.io/v1beta1
    29. kind: ClusterRoleBinding
    30. metadata:
    31. name: prometheus
    32. roleRef:
    33. apiGroup: rbac.authorization.k8s.io
    34. kind: ClusterRole
    35. name: prometheus
    36. subjects:
    37. - kind: ServiceAccount
    38. name: prometheus
    39. namespace: default

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

    1. $ kubectl create -f prometheus-rbac-setup.yml
    2. clusterrole "prometheus" created
    3. serviceaccount "prometheus" created
    4. 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进行变更升级:

    1. $ kubectl apply -f prometheus-deployment.yml
    2. service "prometheus" configured
    3. deployment "prometheus" configured
    4. $ kubectl get pods
    5. NAME READY STATUS RESTARTS AGE
    6. prometheus-55f655696d-wjqcl 0/1 Terminating 0 38m
    7. prometheus-69f9ddb588-czn2c 1/1 Running 0 6s

    指定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

    服务发现

    在Kubernetes下,Promethues通过与Kubernetes API集成目前主要支持5种服务发现模式,分别是:Node、Service、Pod、Endpoints、Ingress。

    通过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配置:

    1. - job_name: 'kubernetes-nodes'
    2. tls_config:
    3. ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
    4. bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
    5. kubernetes_sd_configs:
    6. - role: node

    通过指定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. evaluation_interval: 15s
    7. scrape_configs:
    8. - job_name: 'kubernetes-nodes'
    9. tls_config:
    10. ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
    11. bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
    12. kubernetes_sd_configs:
    13. - role: node
    14. - job_name: 'kubernetes-service'
    15. tls_config:
    16. ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
    17. bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
    18. kubernetes_sd_configs:
    19. - role: service
    20. - job_name: 'kubernetes-endpoints'
    21. tls_config:
    22. ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
    23. bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
    24. kubernetes_sd_configs:
    25. - role: endpoints
    26. - job_name: 'kubernetes-ingress'
    27. tls_config:
    28. ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
    29. bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
    30. kubernetes_sd_configs:
    31. - role: ingress
    32. - job_name: 'kubernetes-pods'
    33. tls_config:
    34. ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
    35. bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
    36. kubernetes_sd_configs:
    37. - role: pod
    38. kind: ConfigMap
    39. metadata:
    40. 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
    9. prometheus-69f9ddb588-wtlsn 1/1 Running 0 14s

    Prometheus使用新的配置文件重建之后,打开Prometheus UI,通过Service Discovery页面可以查看到当前Prometheus通过Kubernetes发现的所有资源对象了:

    Service Discovery发现的实例

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

    1. __address__="192.168.99.100:10250"
    2. __meta_kubernetes_node_address_Hostname="minikube"
    3. __meta_kubernetes_node_address_InternalIP="192.168.99.100"
    4. __meta_kubernetes_node_annotation_alpha_kubernetes_io_provided_node_ip="192.168.99.100"
    5. __meta_kubernetes_node_annotation_node_alpha_kubernetes_io_ttl="0"
    6. __meta_kubernetes_node_annotation_volumes_kubernetes_io_controller_managed_attach_detach="true"
    7. __meta_kubernetes_node_label_beta_kubernetes_io_arch="amd64"
    8. __meta_kubernetes_node_label_beta_kubernetes_io_os="linux"
    9. __meta_kubernetes_node_label_kubernetes_io_hostname="minikube"
    10. __meta_kubernetes_node_name="minikube"
    11. __metrics_path__="/metrics"
    12. __scheme__="https"
    13. instance="minikube"
    14. job="kubernetes-nodes"

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

    Target页面状态

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

    接下来,我们将利用Promtheus的服务发现能力,实现对Kubernetes集群的全面监控。