Ingress-nginx 接入可观测性最佳实践

    背景

    在大型分布式系统中,服务之间调用复杂,链路追踪可以帮助梳理请求流向,现代系统也需要实时监控来快速响应事件以及故障,让我们了解系统瓶颈和高负载路径,从而可以进行优化。

    Ingress-nginx 是在 Kubernetes 环境中使用的,专门用于管理进入 Kubernetes 集群的外部访问流量。它基于 Nginx,利用其作为反向代理和负载均衡器的能力,但专门配置和优化以适应 Kubernetes 的架构。Ingress Controller 的主要任务是根据预先定义的规则(通过 Kubernetes Ingress 资源设置)将外部请求路由到集群内的特定服务。

    前提条件

    Ingress-nginx(v1.9.0) 协议使用 Opentracing 协议上报链路数据,各个服务中链路使用 ddtrace 串联上报数据。

    本示例的 Ingress-nginx 版本是1.9.6,Service 之间使用 DDtrace sdk 串联上报数据。

    1. 安装 Ingress-nginx-Controller

    创建一个 ingress-nginx.yaml 文件:

    apiVersion: v1
    kind: Namespace
    metadata:
      name: ingress-nginx
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: ingress-nginx
      namespace: ingress-nginx
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: ingress-nginx
    rules:
      - apiGroups:
          - ""
        resources:
          - configmaps
          - endpoints
          - nodes
          - pods
          - secrets
          - services
        verbs:
          - list
          - watch
          - get
      - apiGroups:
          - "discovery.k8s.io"
        resources:
          - endpointslices
        verbs:
          - list
          - watch
      - apiGroups:
          - "coordination.k8s.io"
        resources:
          - leases
        verbs:
          - get
          - watch
          - list
          - create
          - update
      - apiGroups:
          - "networking.k8s.io"
        resources:
          - ingresses
          - ingressclasses
        verbs:
          - get
          - list
          - watch
      - apiGroups:
          - "networking.k8s.io"
        resources:
          - ingresses/status
        verbs:
          - update
      - apiGroups:
          - "extensions"
        resources:
          - ingresses
        verbs:
          - get
          - list
          - watch
      - apiGroups:
          - "extensions"
        resources:
          - ingresses/status
        verbs:
          - update
      - apiGroups:
          - ""
        resources:
          - events
        verbs:
          - create
          - patch
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: ingress-nginx
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: ingress-nginx
    subjects:
      - kind: ServiceAccount
        name: ingress-nginx
        namespace: ingress-nginx
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: ingress-nginx-controller
      namespace: ingress-nginx
    spec:
      selector:
        matchLabels:
          app: ingress-nginx
      template:
        metadata:
          labels:
            app: ingress-nginx
        spec:
          serviceAccountName: ingress-nginx
          containers:
          - name: controller
            image: xxxxxxxxxxxxxxx/controller:v1.9.6
            args:
            - /nginx-ingress-controller
            - --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller
            - --election-id=ingress-controller-leader
            - --controller-class=k8s.io/ingress-nginx
            - --ingress-class=nginx
            - --configmap=ingress-nginx/ingress-nginx-controller
            env:
            - name: HOST_IP
              valueFrom:
                fieldRef:
                  fieldPath: status.hostIP
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
            ports:
            - name: http
              containerPort: 80
            - name: https
              containerPort: 443
            - name: prom
              containerPort: 10254
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: ingress-nginx-controller
      namespace: ingress-nginx
    spec:
      type: NodePort
      ports:
      - name: http
        port: 80
        targetPort: 80
        nodePort: 30796
      - name: https
        port: 443
        targetPort: 443
        nodePort: 30149
      - name: prometheus
        port: 10254
        targetPort: 10254
        nodePort: 30254
      selector:
        app: ingress-nginx
    ---
    
    apiVersion: v1
    data:
      allow-snippet-annotations: "false"
      enable-opentracing: "true"
      opentracing-trust-incoming-span: "true"
      datadog-collector-host: "datakit-service.datakit.svc.cluster.local"
      datadog-collector-port: "9529"
      datadog-service-name: "ingress-nginx"
      datadog-environment: "testing"
      datadog-operation-name-override: "HTTP $request_method $service_name $uri $opentelemetry_trace_id"
      datadog-priority-sampling: "false"
      datadog-sample-rate: "1.0"
    kind: ConfigMap
    metadata:
      labels:
        app.Kubernetes.io/component: controller
        app.Kubernetes.io/instance: ingress-nginx
        app.Kubernetes.io/name: ingress-nginx
        app.Kubernetes.io/part-of: ingress-nginx
        app.Kubernetes.io/version: 1.9.6
      name: ingress-nginx-controller
      namespace: ingress-nginx
    

    应用该配置:

    kubectl apply -f ingress-nginx.yaml
    

    1.1 编辑 Ingress-controller ConfigMap 资源

    配置 Ingress-nginx 服务 ConfigMap(上述步骤中 Ingress-nginx.yaml 文件已经添加好):

    apiVersion: v1
    data:
      allow-snippet-annotations: "false"
      enable-opentracing: "true"
      opentracing-trust-incoming-span: "true"
      datadog-collector-host: "datakit-service.datakit.svc.cluster.local"
      datadog-collector-port: "9529"
      datadog-service-name: "ingress-nginx"
      datadog-environment: "testing"
      datadog-operation-name-override: "HTTP $request_method $service_name $uri $opentelemetry_trace_id"
      datadog-priority-sampling: "false"
      datadog-sample-rate: "1.0"
    kind: ConfigMap
    metadata:
      labels:
        app.Kubernetes.io/component: controller
        app.Kubernetes.io/instance: ingress-nginx
        app.Kubernetes.io/name: ingress-nginx
        app.Kubernetes.io/part-of: ingress-nginx
        app.Kubernetes.io/version: 1.9.6
      name: ingress-nginx-controller
      namespace: ingress-nginx
    

    配置 ConfigMap 后在 Ingress-controller 的 deployment 中增加一行指定 ConfigMap。

    --configmap=ingress-nginx/ingress-nginx-controller
    

    kuebctl apply -f ingress-nginx.yaml
    

    1.2 DataKit-operator 注入 DDTrace SDK

    1.2.1 开启 DDTrace 采集器

    修改 datakit.yaml 文件,在默认开启的采集器配置中,追加 DDtrace。

     - name: ENV_DEFAULT_ENABLED_INPUTS
       value: cpu,disk,diskio,mem,swap,system,hostobject,net,host_processes,container,ddtrace
    

    重启 DataKit。

    kubectl apply -f datakit.yaml
    

    1.2.2 安装 DataKit Operator

    wget https://static.guance.com/datakit-operator/datakit-operator.yaml
    

    执行安装指令。

    kubectl apply -f datakit-operator.yaml
    

    重启业务应用 pod。

    kubectl apply -f xxxxx.yaml
    

    1.2.3 Ingress 访问测试

    因为 Ingress-nginx-controller Service 的类型是 NodePort,将 80 端口映射到 30796 端口。192.168.0.5 是运行 Ingress-nginx Pod 的节点 IP。

    curl -H "Host:service.com" http://192.168.0.5:30796/service-a/api/a
    
    Service-A received: Hello from Service-B
    

    1.2.4 链路展示

    到观测云控制台应用性能检测部分,可以看到 Ingress-nginx 链路数据正常上报。

    2. Ingress-nginx 指标

    Ingress Nginx Controller 集成了 Prometheus 监控功能,使用 10254 作为其 Prometheus 指标端点的默认端口。通过将 service 的 type 改为 NodePort 并映射 10254 端口,集群外部(例如节点 IP)可以通过 http://:10254/metrics 访问这些指标。

    DataKit 使用 Kubernetes Prometheus Discovery 方式采集 Prometheus 暴露的指标。KubernetesPrometheus 是一个只能应用在 Kubernetes 的采集器,它根据自定义配置实现自动发现 Prometheus 服务并进行采集,极大简化了使用过程。

    2.1 DataKit 配置

    DataKit 操作如下:

    1、通过 ConfigMap 方式注入采集器配置来开启采集器开启KubernetesPrometheus 采集器

    # datakit.yaml
    
    volumeMounts: # datakit.yaml 中已有该配置,直接搜索即可定位到
            - mountPath: /usr/local/datakit/conf.d/Kubernetesprometheus/Kubernetesprometheus.conf
              name: datakit-conf
              subPath: Kubernetesprometheus.conf
    
    # 直接在 datakit.yaml 底部追加
    ---
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: datakit-conf
      namespace: datakit
    data:
        Kubernetesprometheus.conf: |-
          [inputs.Kubernetesprometheus]
            [[inputs.Kubernetesprometheus.instances]]
              role       = "pod"
              #namespaces = ["ingress-nginx"]
              scheme     = "http"
              #selector   = "app=ingress-nginx"
              port       = "10254"
              path       = "/metrics"
              node_local = "true"
              [inputs.Kubernetesprometheus.instances.custom]
                measurement = "ingress-nginx"
                [inputs.Kubernetesprometheus.instances.custom.tags]
                  instance         = "__Kubernetes_mate_instance"
                  host             = "__Kubernetes_mate_host"
                  pod_name         = "__Kubernetes_pod_name"
                  pod_namespace    = "__Kubernetes_pod_namespace"
    

    2、 重启 DataKit

    2.2 Ingres-nginx- controller 配置

    Ingress-nginx-controller 的配置文件 Ingress-nginx.yaml 修改内容如下:

    编辑 deploy.yaml 把 service 的 type 设置成 NodePort,并对外暴露 10254 端口。

    spec:
      type: NodePort
    ......
        - name: prometheus
          port: 10254
          targetPort: prometheus
    

    2.3 指标展示

    2.4 仪表板视图

    3. Ingress-nginx 日志

    Ingress-nginx 日志是由控制台输出,DataKit 可以采集输出到 stdout 的容器日志,使用 datakit.yaml 部署 DataKit 后默认已经开启了 container 采集器。此时会在 DataKit 容器中生成 /usr/local/datakit/conf.d/container/container.conf 配置文件,默认配置是采集除了 pubrepo.jiagouyun.com/datakit/logfwd 开头的镜像外的所有 stdout 日志。访问日志页面即可看到 Ingress-nginx-controller 相关日志。

    总结

    监控 Ingress-nginx 的链路、指标和日志的作用在于确保 Kubernetes 集群中 Ingress 控制器的稳定性和性能。通过链路追踪,可以了解请求的完整路径和延迟,定位瓶颈;指标监控(如请求速率、错误率、响应时间)有助于评估系统健康状况,及时发现异常。

    日志分析则提供详细的事件记录,便于排查问题和审计安全。通过这些手段,可以优化流量管理,提升用户体验,同时保障服务的高可用性和安全性,是现代微服务架构中不可或缺的运维实践。

    联系我们

    加入社区

    微信扫码
    加入官方交流群

    立即体验

    在线开通,按量计费,真正的云服务!

    免费开启

    支持私有云环境部署

    代码托管平台