利用 NGINX Ingress 实现 Kubernetes 服务间访问与高可用设计实践

404 阅读2分钟

🎯 背景

在 Kubernetes 微服务架构中,Ingress 是暴露 HTTP 服务的标准方式,通常由 Ingress Controller(如 NGINX Ingress)负责实际转发。本文通过一个 A 服务调用 B 服务的实际案例,讲解:

  • 如何部署 nginx-ingress
  • 如何配置 Ingress 实现服务间调用
  • 服务挂掉如何处理
  • 如何结合 Probe / Service 实现高可用
  • 如何部署 Kubernetes Dashboard 并使用 token 登录

📌 一、架构总览

graph TD
  User[外部用户] -->|访问 ingress IP| IngressController[nginx-ingress controller]
  IngressController -->|根据规则转发| ServiceB[Service B]
  IngressController -->|根据规则转发| ServiceA[Service A]
  ServiceA -->|通过 ClusterIP 或域名| ServiceB
  ServiceB --> PodB1[Pod B #1]
  ServiceB --> PodB2[Pod B #2]
  ServiceA --> PodA1[Pod A #1]

🚀 二、部署 nginx-ingress 控制器

2.1 添加 Helm 仓库并安装

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update

kubectl create namespace ingress-nginx

helm install nginx-ingress ingress-nginx/ingress-nginx \
  --set controller.publishService.enabled=false \
  --set controller.service.type=NodePort \
  -n ingress-nginx

2.2 查看访问地址

export HTTP_NODE_PORT=$(kubectl get svc -n ingress-nginx nginx-ingress-ingress-nginx-controller -o jsonpath="{.spec.ports[0].nodePort}")
export NODE_IP=$(kubectl get nodes -o jsonpath="{.items[0].status.addresses[1].address}")
echo "Access via: http://${NODE_IP}:${HTTP_NODE_PORT}"

🧩 三、部署服务 A / B

3.1 Service B(被调用)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: service-b
spec:
  replicas: 2
  selector:
    matchLabels:
      app: service-b
  template:
    metadata:
      labels:
        app: service-b
    spec:
      containers:
      - name: service-b
        image: your-repo/service-b:latest
        ports:
        - containerPort: 8080
        readinessProbe:
          httpGet:
            path: /healthz
            port: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: service-b
spec:
  selector:
    app: service-b
  ports:
  - port: 80
    targetPort: 8080

3.2 Service A 通过域名访问 B

// 示例:使用 Ingress 域名访问
http.Get("http://b.example.com/api/hello")

// 或使用内部服务 DNS
http.Get("http://service-b.default.svc.cluster.local/api/hello")

📡 四、配置 Ingress

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: service-b-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
  - host: b.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: service-b
            port:
              number: 80
curl -H "Host: b.example.com" http://$NODE_IP:$HTTP_NODE_PORT

🔄 五、服务故障处理机制

5.1 健康检查与剔除

readinessProbe:
  httpGet:
    path: /healthz
    port: 8080
  initialDelaySeconds: 5
  periodSeconds: 10
  • 探针失败 => Pod 从 Service 中剔除

  • 所有 Pod 失败 => Ingress 返回 502

5.2 应用侧容错逻辑

// Go 中简单的重试机制
for i := 0; i < 3; i++ {
  resp, err := http.Get("http://b.example.com/api/hello")
  if err == nil && resp.StatusCode < 500 {
    break
  }
  time.Sleep(time.Second)
}

📊 六、部署 Kubernetes Dashboard(含 token)

6.1 安装 Dashboard

kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml

6.2 创建管理员账户

# dashboard-admin.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: dashboard-admin-sa
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: dashboard-admin-sa
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: dashboard-admin-sa
  namespace: kube-system
kubectl apply -f dashboard-admin.yaml

6.3 获取登录 token

kubectl -n kube-system get secret | grep dashboard-admin-sa
kubectl -n kube-system describe secret dashboard-admin-sa-token-xxxxx | grep 'token:'

6.4 本地访问 Dashboard

kubectl proxy

访问地址:

http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/

📘 附图:Dashboard 权限关系图


graph TD
  User --> Dashboard[Dashboard Web UI]
  Dashboard --> ServiceAccount[dashboard-admin-sa]
  ServiceAccount --> ClusterRoleBinding
  ClusterRoleBinding --> ClusterRole[cluster-admin]
  ClusterRole --> API[API Server 权限]

✅ 总结

  • 使用 Ingress 实现跨服务访问和服务发现
  • readinessProbe + Service + Ingress 实现服务的高可用
  • 业务逻辑中应处理服务故障(熔断/重试)
  • Dashboard 提供 Web 界面管理能力,需通过 SA + token 登录