Kubernetes中Ingress-Nginx后部署Grafana遇503错误求助
环境信息
- 操作系统:Debian 12 (bookworm)
- Kubernetes版本:
kubectl version Client Version: v1.28.2 Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3 Server Version: v1.28.4
- 容器运行时:containerd
- 网络插件:Calico
Ingress-Nginx 安装与验证
通过以下命令安装Ingress-Nginx:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.2/deploy/static/provider/baremetal/deploy.yaml
创建测试Deployment验证Ingress功能正常:
kubectl create deployment demo --image=httpd --port=80 kubectl expose deployment demo
测试访问返回it works,Ingress功能正常。
Grafana 部署配置
在grafana目录下创建以下文件并执行kubectl apply -f grafana完成部署:
0-secret.yaml(存储登录凭证)
(注:需确保文件包含admin-user和admin-password密钥)
1-deployment.yaml
--- apiVersion: apps/v1 kind: Deployment metadata: namespace: ingress-nginx name: grafana spec: replicas: 1 selector: matchLabels: app: grafana strategy: type: Recreate template: metadata: labels: app: grafana spec: containers: - name: grafana image: grafana/grafana:8.1.1 imagePullPolicy: IfNotPresent ports: - name: grafana containerPort: 3000 protocol: TCP env: - name: GF_SECURITY_ADMIN_USER valueFrom: secretKeyRef: name: grafana key: admin-user - name: GF_SECURITY_ADMIN_PASSWORD valueFrom: secretKeyRef: name: grafana key: admin-password livenessProbe: failureThreshold: 10 httpGet: path: /api/health port: grafana initialDelaySeconds: 30 timeoutSeconds: 15 readinessProbe: httpGet: path: /api/health port: grafana
2-service.yaml
--- apiVersion: v1 kind: Service metadata: namespace: ingress-nginx name: grafana spec: type: ClusterIP ports: - name: grafana port: 3000 selector: app: grafana
Ingress 配置
--- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: grafana namespace: ingress-nginx spec: ingressClassName: external-nginx rules: - http: paths: - path: /login pathType: Prefix backend: service: name: grafana port: number: 3000
集群服务信息
kubectl get services -A NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE default kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 18h ingress-nginx grafana ClusterIP 10.104.10.21 <none> 3000/TCP 43m ingress-nginx ingress-nginx-controller NodePort 10.98.208.172 <none> 80:32445/TCP,443:32416/TCP 18h ingress-nginx ingress-nginx-controller-admission ClusterIP 10.106.44.218 <none> 443/TCP 18h kube-system kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 18h
问题现象
访问<节点IP>:32445/login时,浏览器返回503 Service Temporarily Unavailable错误。尝试将Grafana部署到其他命名空间、修改端口等操作,问题依旧。
排查与解决步骤
1. 验证IngressClass匹配性
默认安装的Ingress-Nginx对应的ingressClassName是nginx,而非external-nginx。执行以下命令确认集群中的IngressClass:
kubectl get ingressclasses
如果没有external-nginx,需修改Ingress配置的ingressClassName为nginx,或创建对应的IngressClass资源。
2. 检查Grafana Pod状态与探针
确认Grafana Pod是否正常运行,且探针通过:
kubectl get pods -n ingress-nginx
若Pod状态异常,查看日志排查启动问题:
kubectl logs <grafana-pod-name> -n ingress-nginx
同时检查Secret是否正确配置,确保Pod能读取到admin-user和admin-password。
3. 确认Service与Pod的关联
检查Grafana Service的Endpoints是否包含Pod IP:
kubectl describe service grafana -n ingress-nginx
若Endpoints为空,需确认Deployment的labels与Service的selector是否完全匹配(当前配置为app: grafana,需确保Pod标签正确)。
4. 修复Grafana路径转发问题
当前Ingress路径为/login(Prefix类型),转发请求到Grafana时,Grafana的内部路径会出现不匹配问题。可通过以下两种方式解决:
方法一:添加Ingress重写注解
修改Ingress配置,添加路径重写注解:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: grafana namespace: ingress-nginx annotations: nginx.ingress.kubernetes.io/rewrite-target: /$2 spec: ingressClassName: nginx rules: - http: paths: - path: /login(/|$)(.*) pathType: Prefix backend: service: name: grafana port: number: 3000
方法二:配置Grafana根URL
在Deployment的env中添加GF_SERVER_ROOT_URL变量,指定Ingress访问路径:
env: - name: GF_SERVER_ROOT_URL value: "http://<节点IP>:32445/login"
5. 测试Pod与Service的连通性
进入Ingress-Nginx控制器Pod,测试能否访问Grafana Service:
kubectl exec -it <ingress-controller-pod-name> -n ingress-nginx -- curl 10.104.10.21:3000/api/health
若返回非200状态码,需检查Calico网络插件是否允许同命名空间Pod间通信,或排查节点防火墙规则。
内容的提问来源于stack exchange,提问作者Druzill

