Service与Ingress配置完全指南
Service与Ingress配置完全指南
前言
在Kubernetes集群中,Service和Ingress是实现服务发现、负载均衡和外部访问的核心资源。正确配置这些资源对于构建可靠的应用架构至关重要。本文将深入讲解Service的各种类型、Ingress配置以及最佳实践。
一、Service核心概念
1.1 什么是Service
Service是Kubernetes的一种资源,用于将运行在一组Pod上的应用程序暴露为网络服务。Service提供稳定的IP地址和DNS名称,屏蔽了后端Pod的动态变化。
1.2 Service的工作原理
apiVersion: v1 kind: Service metadata: name: my-app-service labels: app: my-app spec: type: ClusterIP selector: app: my-app ports: - protocol: TCP port: 80 # Service端口 targetPort: 8080 # Pod端口1.3 Service类型
Kubernetes支持四种Service类型:
- ClusterIP:集群内部IP(默认)
- NodePort:在每个Node上暴露端口
- LoadBalancer:云提供商的负载均衡器
- ExternalName:CNAME记录
二、ClusterIP Service详解
2.1 基本配置
apiVersion: v1 kind: Service metadata: name: backend-service namespace: production labels: app: backend tier: backend spec: type: ClusterIP selector: app: backend tier: backend ports: - name: http protocol: TCP port: 80 targetPort: 8080 - name: grpc protocol: TCP port: 50051 targetPort: 50051 sessionAffinity: None2.2 Headless Service
无头Service返回所有Pod的IP地址,常用于有状态应用。
apiVersion: v1 kind: Service metadata: name: mysql-headless labels: app: mysql spec: type: ClusterIP clusterIP: None # 关键:设置为None即为Headless Service selector: app: mysql ports: - name: mysql port: 3306 targetPort: 33062.3 多端口Service
apiVersion: v1 kind: Service metadata: name: multi-port-service spec: type: ClusterIP selector: app: my-app ports: - name: http protocol: TCP port: 80 targetPort: 8080 - name: https protocol: TCP port: 443 targetPort: 8443 - name: metrics protocol: TCP port: 9090 targetPort: 9090三、NodePort Service
3.1 基本配置
apiVersion: v1 kind: Service metadata: name: my-app-nodeport labels: app: my-app spec: type: NodePort selector: app: my-app ports: - name: http protocol: TCP port: 80 targetPort: 8080 nodePort: 30080 # 可选:指定NodePort范围30000-327673.2 高级配置
apiVersion: v1 kind: Service metadata: name: production-service spec: type: NodePort selector: app: production-app ports: - name: http port: 80 targetPort: 8080 nodePort: 30080 - name: https port: 443 targetPort: 8443 nodePort: 30443 externalTrafficPolicy: Local # 保持客户端IP healthCheckNodePort: 32222四、LoadBalancer Service
4.1 云厂商配置
apiVersion: v1 kind: Service metadata: name: my-app-lb labels: app: my-app annotations: # AWS service.beta.kubernetes.io/aws-load-balancer-type: "nlb" service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "tcp" service.beta.kubernetes.io/aws-load-balancer-ssl-cert: "arn:aws:acm:us-west-2:123456789:certificate/abc123" # GCP cloud.google.com/backend-config: '{"default": "backend-config"}' # Azure service.beta.kubernetes.io/azure-load-balancer-resource-group: "my-resource-group" spec: type: LoadBalancer selector: app: my-app ports: - name: https port: 443 targetPort: 8443 - name: http port: 80 targetPort: 8080 loadBalancerIP: "203.0.113.10" loadBalancerSourceRanges: - "10.0.0.0/8" - "203.0.113.0/24"五、Ingress详解
5.1 Ingress基础配置
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: minimal-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - host: myapp.example.com http: paths: - path: / pathType: Prefix backend: service: name: my-app-service port: number: 805.2 完整Ingress配置
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: production-ingress namespace: production annotations: # Nginx Ingress Controller配置 nginx.ingress.kubernetes.io/ssl-redirect: "true" nginx.ingress.kubernetes.io/proxy-body-size: "50m" nginx.ingress.kubernetes.io/proxy-connect-timeout: "30" nginx.ingress.kubernetes.io/proxy-read-timeout: "60" nginx.ingress.kubernetes.io/proxy-send-timeout: "60" nginx.ingress.kubernetes.io/limit-rps: "100" nginx.ingress.kubernetes.io/limit-connections: "50" nginx.ingress.kubernetes.io/enable-cors: "true" nginx.ingress.kubernetes.io/cors-allow-origin: "*" nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, DELETE, PATCH, OPTIONS" nginx.ingress.kubernetes.io/cors-allow-headers: "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization" nginx.ingress.kubernetes.io/affinity: "cookie" nginx.ingress.kubernetes.io/session-cookie-name: "route" nginx.ingress.kubernetes.io/session-cookie-expires: "172800" nginx.ingress.kubernetes.io/session-cookie-hash: "sha1" spec: ingressClassName: nginx tls: - hosts: - myapp.example.com - api.example.com secretName: myapp-tls-secret rules: - host: myapp.example.com http: paths: - path: / pathType: Prefix backend: service: name: frontend-service port: number: 80 - host: api.example.com http: paths: - path: /api/v1 pathType: Prefix backend: service: name: api-service port: number: 8080 - path: /api/v2 pathType: Prefix backend: service: name: api-v2-service port: number: 8080 - path: /admin pathType: Prefix backend: service: name: admin-service port: number: 80805.3 多服务Ingress配置
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: multi-service-ingress annotations: nginx.ingress.kubernetes.io/canary: "true" nginx.ingress.kubernetes.io/canary-weight: "30" spec: rules: - host: app.example.com http: paths: - path: /web pathType: Prefix backend: service: name: web-service port: number: 80 - path: /mobile pathType: Prefix backend: service: name: mobile-service port: number: 80 - path: /api pathType: Prefix backend: service: name: api-service port: number: 8080 - path: /static pathType: Prefix backend: service: name: cdn-service port: number: 80六、Ingress Controller配置
6.1 Nginx Ingress Controller安装
apiVersion: v1 kind: Namespace metadata: name: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx --- apiVersion: v1 kind: ServiceAccount metadata: name: ingress-nginx namespace: ingress-nginx --- apiVersion: v1 kind: ConfigMap metadata: name: ingress-nginx-controller namespace: ingress-nginx data: allow-snippet-annotations: "false" proxy-body-size: "50m" use-forwarded-headers: "true" compute-full-forwarded-for: "true" use-proxy-protocol: "false" --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: ingress-nginx rules: - apiGroups: [""] resources: ["configmaps", "endpoints", "nodes", "pods", "secrets", "namespaces"] verbs: ["list", "watch"] - apiGroups: [""] resources: ["nodes"] verbs: ["get"] - apiGroups: [""] resources: ["services"] verbs: ["get", "list", "watch"] - apiGroups: ["networking.k8s.io"] resources: ["ingresses"] verbs: ["get", "list", "watch"] - apiGroups: [""] resources: ["events"] verbs: ["create", "patch"] - apiGroups: ["networking.k8s.io"] resources: ["ingresses/status"] verbs: ["update"] --- apiVersion: apps/v1 kind: Deployment metadata: name: ingress-nginx-controller namespace: ingress-nginx spec: replicas: 2 selector: matchLabels: app: ingress-nginx template: metadata: labels: app: ingress-nginx spec: serviceAccountName: ingress-nginx containers: - name: controller image: k8s.gcr.io/ingress-nginx/controller:v1.7.0 args: - /nginx-ingress-controller - --configmap=$(POD_NAMESPACE)/nginx-configuration - --election-id=ingress-controller-leader - --ingress-class=nginx - --watch-ingress-without-class=true ports: - name: http containerPort: 80 - name: https containerPort: 443 - name: webhook containerPort: 8443 resources: requests: cpu: 100m memory: 90Mi env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: LD_PRELOAD value: /usr/local/lib/libmimalloc.so6.2 外部DNS配置
apiVersion: v1 kind: Service metadata: name: ingress-nginx-controller namespace: ingress-nginx spec: type: LoadBalancer selector: app: ingress-nginx ports: - name: http port: 80 targetPort: 80 - name: https port: 443 targetPort: 443 --- apiVersion: networking.k8s.io/v1 kind: IngressClass metadata: name: nginx annotations: ingressclass.kubernetes.io/is-default-class: "true" spec: controller: k8s.io/ingress-nginx七、最佳实践
7.1 服务网格集成
apiVersion: v1 kind: Service metadata: name: my-app-service labels: app: my-app annotations: traffic.sidecar.istio.io/includeInboundPorts: "8080" traffic.sidecar.istio.io/includeOutboundPorts: "3306,6379" spec: selector: app: my-app ports: - name: http port: 80 targetPort: 80807.2 金丝雀发布
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-app-canary annotations: nginx.ingress.kubernetes.io/canary: "true" nginx.ingress.kubernetes.io/canary-weight: "20" spec: rules: - host: myapp.example.com http: paths: - path: / pathType: Prefix backend: service: name: my-app-canary port: number: 807.3 网络策略
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: api-network-policy spec: podSelector: matchLabels: app: api-service policyTypes: - Ingress - Egress ingress: - from: - namespaceSelector: matchLabels: name: production - podSelector: matchLabels: app: nginx-ingress ports: - protocol: TCP port: 80807.4 健康检查
apiVersion: v1 kind: Service metadata: name: my-app-service spec: selector: app: my-app ports: - port: 80 targetPort: 8080 healthCheckNodePort: 30900 --- apiVersion: v1 kind: Endpoints metadata: name: my-app-service labels: app: my-app subsets: - addresses: - ip: 10.244.1.10 targetRef: kind: Pod name: my-app-pod-1 ports: - port: 8080 protocol: TCP八、常见问题解决方案
8.1 Service无法访问
# 1. 检查Endpoints kubectl get endpoints my-app-service # 2. 检查Pod状态 kubectl get pods -l app=my-app # 3. 检查DNS解析 kubectl exec -it test-pod -- nslookup my-app-service # 4. 检查网络策略 kubectl get networkpolicy8.2 Ingress 404问题
# 检查Ingress资源 kubectl describe ingress my-ingress # 检查Ingress Controller日志 kubectl logs -n ingress-nginx -l app=ingress-nginx # 验证后端服务 kubectl get svc -o wide8.3 TLS证书问题
apiVersion: v1 kind: Secret metadata: name: myapp-tls namespace: production type: kubernetes.io/tls data: tls.crt: <base64-encoded-cert> tls.key: <base64-encoded-key>总结
Service和Ingress是Kubernetes网络架构的核心组件。通过合理配置不同类型的Service和Ingress,可以实现灵活的服务发现、负载均衡和外部访问控制。结合最佳实践和监控告警,可以构建高可用的微服务架构。
