正在加载,请稍候…

Kubernetes 网络:Ingress、Service 与网络策略

掌握 Kubernetes 网络。了解 Service 类型、带 TLS 的 Ingress 控制器、用于安全性的 NetworkPolicy、DNS 以及集群

Kubernetes 网络:Ingress、Service 与网络策略

Kubernetes 网络:Ingress 与网络策略

Service 类型

# ClusterIP(默认)- 仅集群内部
apiVersion: v1
kind: Service
metadata:
  name: api-service
spec:
  selector:
    app: api
  ports:
  - port: 80
    targetPort: 3000
  type: ClusterIP  # 仅在集群内可访问

---
# NodePort - 在每个节点 IP 上暴露
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 3000
    nodePort: 30080  # 30000-32767

---
# LoadBalancer - 配置云负载均衡器
spec:
  type: LoadBalancer
  ports:
  - port: 443
    targetPort: 3000

Kubernetes 网络:Ingress、Service 与网络策略示意图

Nginx Ingress 控制器

# 安装 Nginx Ingress
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/cloud/deploy.yaml

---
# 带 TLS 的 Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api-ingress
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - api.example.com
    secretName: api-tls-cert
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 80
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80

Kubernetes 网络:Ingress、Service 与网络策略示意图

cert-manager 实现自动 TLS

# Let's Encrypt 的 ClusterIssuer
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: ops@example.com
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
    - http01:
        ingress:
          class: nginx

Kubernetes 网络:Ingress、Service 与网络策略示意图

网络策略(零信任)

# 默认拒绝所有入站流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
  namespace: production
spec:
  podSelector: {}  # 应用于所有 Pod
  policyTypes:
  - Ingress

---
# 仅允许特定流量到达 API Pod
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-api-ingress
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: api
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: ingress-nginx  # 仅来自 Ingress 控制器
    ports:
    - protocol: TCP
      port: 3000
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: postgres   # 可访问数据库
    ports:
    - protocol: TCP
      port: 5432
  - to:
    - podSelector:
        matchLabels:
          app: redis
    ports:
    - protocol: TCP
      port: 6379

DNS 与服务发现

# Service DNS 格式:<service>.<namespace>.svc.cluster.local
# 同一命名空间内:直接使用服务名
curl http://api-service/health

# 跨命名空间
curl http://api-service.production.svc.cluster.local/health

# 调试 DNS
kubectl run debug --image=busybox --rm -it -- nslookup api-service.production.svc.cluster.local
kubectl run debug --image=nicolaka/netshoot --rm -it -- bash

调试网络问题

# 检查 Service 端点(你的 Pod 是否被选中?)
kubectl get endpoints api-service

# 从 Pod 测试连通性
kubectl exec -it <pod-name> -- curl http://api-service/health
kubectl exec -it <pod-name> -- nc -zv postgres-service 5432

# 检查网络策略
kubectl describe networkpolicy default-deny-ingress

# 查看 Ingress 状态
kubectl describe ingress api-ingress

# 检查 Ingress 控制器日志
kubectl logs -n ingress-nginx -l app.kubernetes.io/component=controller

NetworkPolicy 实现了微隔离——Pod 通信的最小权限原则。