🎯 背景
在 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 登录