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 文件:

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 文件已经添加好):

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。

ini 复制代码
--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。

yaml 复制代码
 - 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

vbnet 复制代码
wget https://static.guance.com/datakit-operator/datakit-operator.yaml

执行安装指令。

arduino 复制代码
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。

csharp 复制代码
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 采集器

ini 复制代码
# 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 端口。

yaml 复制代码
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 控制器的稳定性和性能。通过链路追踪,可以了解请求的完整路径和延迟,定位瓶颈;指标监控(如请求速率、错误率、响应时间)有助于评估系统健康状况,及时发现异常。

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

相关推荐
Arya_aa11 小时前
四:部署前端和后端
nginx
Java面试题总结12 小时前
一文搞定 Linux Nginx 从安装、启动到 nginx.conf 全配置详解(新手也能看懂)
linux·运维·nginx
MiNG MENS1 天前
nginx 代理 redis
运维·redis·nginx
珊瑚怪人1 天前
一个域名问题
nginx
dxdz1 天前
一文搞定 Linux Nginx 从安装、启动到 nginx.conf 全配置详解(新手也能看懂)
nginx
遇见火星1 天前
Nginx 负载均衡配置模板:轮询、权重、IP哈希、最少连接
tcp/ip·nginx·负载均衡
untE EADO1 天前
Nginx代理到https地址忽略证书验证配置
运维·nginx·https
Treh UNFO1 天前
nginx的重定向
大数据·数据库·nginx
理人综艺好会1 天前
nginx了解
运维·nginx
likeGhee1 天前
docker创建nginx+keepalived+nacos集群(仅测试环境)
nginx·docker