
# 使用Prometheus监控CCI实例
#### 场景描述
本章节介绍如何在CCI命名空间中，通过手动部署Prometheus，实现对Pod实例的指标监控。Prometheus概念及详细配置请参阅[Prometheus 官方文档](https://prometheus.io/docs/introduction/overview/)。
您将在CCI命名空间中部署一个集成了cci-iam-authenticator插件的Prometheus实例，该插件使Prometheus能够通过IAM认证机制安全地访问CCI的API Server，从而利用Kubernetes服务发现机制对Pod进行实时监控。
#### 前提条件
- 已创建CCI命名空间（本示例以test命名空间为例）。
- 已在SWR（容器镜像服务）创建组织，用于存储自定义镜像。
- 已获取华为云账号的**AK/SK**（访问密钥），用于后续配置kubectl客户端认证。
- 本地环境已安装Docker和Kubectl工具。
 
#### 步骤一：构建并推送Prometheus镜像
本文以Prometheus官方社区镜像**v2.43.0** 为例进行构建。为了确保配置文件的兼容性以及本实践的一次性通过率，建议您使用与本文档一致的镜像版本。
![](https://support.huaweicloud.com/bestpractice-cci/public_sys-resources/note_3.0-zh-cn.png)
- **镜像来源**：本实践使用Quay.io托管的官方镜像。
- **版本选择** ：如需使用其他版本，请访问 [Prometheus官方Tags列表](https://hub.docker.com/r/prom/prometheus/tags) (Docker Hub)。更高版本的Prometheus配置文件格式可能发生变化，请根据实际情况调整 prometheus.yml配置。
 
1. 下载对应版本的prometheus镜像和cci-iam-authenticator二进制文件，操作命令如下：
   ```
   docker pull quay.io/prometheus/prometheus:v2.43.0
   mkdir prome && cd prome && wget https://cci-iam-authenticator.obs.cn-north-4.myhuaweicloud.com/latest/linux-amd64/cci-iam-authenticator && chmod +x cci-iam-authenticator
   ```
   
2. 创建Dockerfile执行以下命令，自动在当前目录生成 Dockerfile文件：
   ```
   cat > Dockerfile <<EOF
   FROM quay.io/prometheus/prometheus:v2.43.0
   COPY cci-iam-authenticator /usr/bin/
   EOF
   ```
   
3. 构建集成cci-iam-authenticator命令的镜像，并推送到swr镜像仓库，推送镜像需要先登录仓库，详情请参见[推动镜像到镜像仓库](https://support.huaweicloud.com/usermanual-swr/swr_01_0011.html)。请将*\<org-name\>* 替换为实际swr镜像仓库名称。
   ```
   docker build -t swr.cn-north-4.myhuaweicloud.com/<org-name>/prometheus:v2.43.0-cci-iam-authenticator .
   docker push swr.cn-north-4.myhuaweicloud.com/<org-name>/prometheus:v2.43.0-cci-iam-authenticator
   ```
   
 
#### 步骤二：使用ConfigMap配置Prometheus访问CCI
1. 使用cci-iam-authenticator作为k8s client端的认证插件，通过用户名/密码的方式或ak/sk方式配置IAM认证信息。详情可参考[安装并设置kubectl](https://support.huaweicloud.com/devg-cci/cci_kubectl_02.html#section2)进行配置。
   ```
   wget https://cci-iam-authenticator.obs.cn-north-4.myhuaweicloud.com/latest/linux-amd64/cci-iam-authenticator 
   chmod +x cci-iam-authenticator && mv cci-iam-authenticator /usr/bin/
   ```
   
2. 获取各个区域cci-endpoint地址，具体请参见[地区和终端节点列表](https://console.huaweicloud.com/apiexplorer/#/endpoint/CCI)。请将根据实际情况替换ci-endpoint地址和AK/SK密钥值。
   ```
   cci-iam-authenticator generate-kubeconfig --cci-endpoint=https://cci.xxx.myhuaweicloud.com --ak=*** --sk=***
   kubectl get ns
   ```
   
3. 配置完成后，执行如下命令，获取$HOME/.kube/config路径下的kubeconfig文件。
   ```
   kubectl config view
   ```
   图1kubeconfig文件   
   ![](https://support.huaweicloud.com/bestpractice-cci/zh-cn_image_0000002497897140.png "点击放大")
   以下示例是为Prometheus访问CCI所做的配置。使用此配置文件构造Prometheus连接API Server的信息。您只需将获取到的kubeconfig配置文件内容写入ConfigMap。
   ```
   kind: ConfigMap
   apiVersion: v1
   metadata:
     name: kubeconfig
   data:
     kubeconfig: |-
       apiVersion: v1 # cci-iam-authenticator生成的kubeconfig配置文件
       clusters:
       - cluster:
           insecure-skip-tls-verify: true
           server: https://cci.cn-north-4.myhuaweicloud.com
         name: cci-cluster-cn-north-4
       contexts:
       - context:
           cluster: cci-cluster-cn-north-4
           user: cci-user-cn-north-4-xxx
         name: cci-context-cn-north-4-xxx
       current-context: cci-context-cn-north-4-xxx
       kind: Config
       preferences: {}
       users:
       - name: cci-user-cn-north-4-xxx
         user:
           exec:
             apiVersion: client.authentication.k8s.io/v1beta1
             args: # iam-endpoint对应的值由iam.myhuaweicloud.com改为iam.cn-north-4.myhuaweicloud.com走内网认证 cn-north-4为服务所在的region
             - token
             - --iam-endpoint=https://iam.cn-north-4.myhuaweicloud.com
             - --insecure-skip-tls-verify=true
             - --cache=true
             - --token-only=false
             - --project-name=cn-north-4
             - --ak=xxx
             - --sk=xxx
             command: cci-iam-authenticator
             env: []
             interactiveMode: IfAvailable
             provideClusterInfo: false
   ```
   
 
#### 步骤三：使用ConfigMap管理Prometheus配置
为了能够方便地管理配置文件，本文示例中将 prometheus.yml 文件用 ConfigMap 的形式进行管理。通过ConfigMap可以方便地做到配置解耦，使得不同环境有不同的配置。相比环境变量，Pod中引用ConfigMap可以做到实时更新，当您更新ConfigMap的数据后，Pod中引用的ConfigMap会同步刷新。
创建prometheus-config.yml文件，并写入以下内容：
```
kind: ConfigMap
apiVersion: v1
metadata:
  name: prometheus-config
  labels:
    name: prometheus-config
data:
  prometheus.yml: |-
    global:
      scrape_interval: 15s
      evaluation_interval: 15s
    scrape_configs:
      - job_name: 'kubernetes-pods'
        kubernetes_sd_configs:
        - role: pod
          kubeconfig_file: /etc/kube/kubeconfig # 指定deployment挂载kubeconfig的路径
          namespaces:
            names:
            - test # 要监控的命名空间列表
        relabel_configs:
        - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
          action: keep
          regex: true
        - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
          action: replace
          target_label: __metrics_path__
          regex: (.+)
        - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
          action: replace
          regex: ([^:]+)(?::\d+)?;(\d+)
          replacement: $1:$2
          target_label: __address__
        - action: labelmap
          regex: __meta_kubernetes_pod_label_(.+)
        - source_labels: [__meta_kubernetes_namespace]
          action: replace
          target_label: kubernetes_namespace
        - source_labels: [__meta_kubernetes_pod_name]
          action: replace
          target_label: kubernetes_pod_name
      - job_name: cci-monitor
        kubernetes_sd_configs:
        - role: pod
          kubeconfig_file: /etc/kube/kubeconfig # 指定deployment挂载kubeconfig的路径
          namespaces:
            names:
            - test # 要监控的命名空间列表
        relabel_configs:
        - source_labels: [__meta_kubernetes_pod_annotation_monitoring_cci_io_enable_pod_metrics] 
          action: drop     
          regex: false
        - action: replace
          regex: ([^:]+)(?::\d+)?
          replacement: $1:19100
          source_labels: [__meta_kubernetes_pod_ip]
          target_label: __address__
        - action: replace
          regex: ([^:]+)(?::\d+)?;(\d+) 
          replacement: $1:$2
          source_labels: [__meta_kubernetes_pod_ip, __meta_kubernetes_pod_annotation_monitoring_cci_io_metrics_port]
          target_label: __address__
```
**global模块** ：控制Prometheus Server的全局配置。
- scrape_interval：表示拉取targets的默认时间间隔。
- evaluation_interval：表示执行rules的时间间隔。
 
**scrape_configs模块**：用于控制prometheus监控具体资源内容。利用Pod服务自动发现机制，在Prometheus主配置文件（prometheus.yml）中，配置监控任务（job），对工作负载进行自定义监控和基础指标监控。
- **自定义监控：** 对接开源Prometheus监控指标，为pod中的应用提供prometheus的监控功能，利用Pod服务自动发现机制，在Prometheus主配置文件（prometheus.yml）中，配置port和path指定要采集的端口和路径。
  - prometheus.io/scrape为true，则会将pod作为监控目标。
  
  - prometheus.io/path，默认为/metrics
  
  - prometheus.io/port , 端口
   
- **基础指标监控**：CCI为了让Prometheus能获取Kubernetes集群的pod基础监控数据，利用Pod服务自动发现机制，在Prometheus主配置文件（prometheus.yml）中，配置一个单独的监控任务（job），在kubernetes_sd_configs项下，指定模式为Pod，列出需要被监控的命名空间列表。
 
Configmap创建完后显示如图所示：
![](https://support.huaweicloud.com/bestpractice-cci/zh-cn_image_0000002524370451.png "点击放大")
#### 步骤四：使用Deployment部署Prometheus
创建prometheus的工作负载，将配置项挂载到工作负载中。使用Deployment部署Prometheus所用的镜像，相比于官方镜像额外打包了cci-iam-authenticator二进制。
示例中创建一个名为prometheus-config的Volume，Volume引用名为"prometheus-config"、"kubeconfig"、"prometheus-storage"的ConfigMap，再将Volume挂载到容器的"/tmp"路径下。
```
kind: Deployment
apiVersion: apps/v1 
metadata:   
  name: prometheus   
  labels:     
    app.kubernetes.io/component: prometheus     
    app.kubernetes.io/instance: k8s     
    app.kubernetes.io/name: prometheus     
    app.kubernetes.io/part-of: kube-prometheus 
spec:   
  replicas: 1
  selector:
     matchLabels:
       app.kubernetes.io/component: prometheus      # 架构中的组件
       app.kubernetes.io/instance: k8s              # 标识应用程序实例的唯一名称
       app.kubernetes.io/name: prometheus           # 应用程序的名称
       app.kubernetes.io/part-of: kube-prometheus   # 这是一个更高级别应用程序的名称
  template:
    metadata:
      labels:
        app.kubernetes.io/component: prometheus
        app.kubernetes.io/instance: k8s
        app.kubernetes.io/name: prometheus
        app.kubernetes.io/part-of: kube-prometheus
    spec:
      volumes:      # 在Volume中引用ConfigMap
        - name: prometheus-config
          configMap:
            name: prometheus-config
            defaultMode: 420        # ConfigMap卷中的所有文件默认设置为420
        - name: kubeconfig
          configMap:
            name: kubeconfig
            defaultMode: 420
        - name: prometheus-storage
          emptyDir:
            medium: LocalAuto
            sizeLimit: 10Gi
      containers:
        - name: prometheus
          image: 'swr.cn-north-4.myhuaweicloud.com/xxx/prometheus:v2.43.0-cci-iam-authenticator' # 替换为自己构建的普罗镜像             '
          args:         # 传给可执行文件的参数（启动参数）
            - '--storage.tsdb.retention.time=12h'              # 监控数据保留的时间
            - '--config.file=/etc/prometheus/prometheus.yml'   # 配置文件
            - '--storage.tsdb.path=/prometheus/'               # Prometheus写入数据库的地方
          ports:
            - containerPort: 9090
              protocol: TCP 
          resources:
            limits:
              cpu: 500m
              memory: 1Gi
            requests:
              cpu: 500m
              memory: 1Gi
          volumeMounts:
            - name: prometheus-config
              mountPath: /etc/prometheus/
            - name: kubeconfig
              mountPath: /etc/kube/
            - name: prometheus-storage
              mountPath: /prometheus/
          terminationMessagePath: /dev/termination-log       # 表示容器的异常终止消息的路径
          terminationMessagePolicy: File                     # 仅从终止消息文件中检索终止消息。
          imagePullPolicy: Always
      restartPolicy: Always
      imagePullSecrets:           # 拉取镜像使用的证书，必须为imagepull-secret
      - name: imagepull-secret
      terminationGracePeriodSeconds: 30      # 优雅关闭的宽限期，即在收到停止请求后，有多少时间来进行资源释放或者做其它操作，如果到了最大时间还没有停止，会被强制结束。
      dnsPolicy: ClusterFirst   
      securityContext: {} 
      schedulerName: default-scheduler 
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 25%
      maxSurge: 25%
  revisionHistoryLimit: 10
  progressDeadlineSeconds: 600
```
#### 步骤五：配置公网访问Prometheus平台
为了在浏览器中访问Prometheus，您可以给负载绑定ELB实例，通过公网访问Prometheus平台，查看监控数据。
1. 登录云容器实例管理控制台，在左侧导航栏中选择"网络管理 \> 服务（Service）"，在右侧页面单击"添加服务"。
2. 在"添加服务"页面，访问类型选择"负载均衡 LoadBalancer"。
3. 设置弹性负载均衡访问参数。 
   - 服务名称：服务名称即Service的名称，Service是用于管理Pod访问的对象。
   
   - 命名空间：工作负载所在命名空间。
   
   - 关联工作负载：要添加Service的工作负载。
   
   - 负载均衡：选择公网ELB实例。如没有ELB实例可以单击"创建ELB实例"新建后再选择。
     ![](https://support.huaweicloud.com/bestpractice-cci/public_sys-resources/notice_3.0-zh-cn.png)
     此处创建的ELB需要与负载所在命名空间在同一个VPC内。
     CCI暂时不支持独享型负载均衡，建议您创建共享型ELB实例。
     
   
   - 负载端口配置
     - 协议：访问负载的通信协议，可选择TCP或UDP。
     
     - 访问端口：负载提供的访问端口，即为服务端口，可自定义。
     
     - 容器端口：容器监听的端口，负载访问端口映射到容器端口，Prometheus的默认端口号为9090。
      
   
   
   图2添加服务   
   ![](https://support.huaweicloud.com/bestpractice-cci/zh-cn_image_0000002524607615.png "点击放大")
   
   
4. 单击"提交"。 
   工作负载已添加"负载均衡 LoadBalancer"的服务。
   
   
5. 创建完成后在浏览器通过访问"负载均衡公网IP地址:服务端口"来访问Prometheus。 
   ![](https://support.huaweicloud.com/bestpractice-cci/zh-cn_image_0000002492328630.png "点击放大")
   
   
 
