Kubernetes网络模型:理解Pod网络与Service通信
Kubernetes网络模型理解Pod网络与Service通信引言网络是Kubernetes的核心组件之一理解K8s网络模型对于构建可靠的分布式系统至关重要。本文将深入探讨Pod网络、Service通信、网络策略以及Ingress等核心概念。一、Kubernetes网络模型1.1 网络原则Kubernetes网络模型遵循以下基本原则所有Pod都可以直接通信不需要NAT所有Node都可以直接通信不需要NATPod自己可以访问自己Pod1 ────────────────────── Pod2 │ │ │ │ └───── Node1 ────网络────── Node21.2 网络插件插件特点适用场景Flannel简单易用性能好中小型集群Calico功能强大支持网络策略生产环境Cilium基于eBPF高性能大规模集群Weave自动发现零配置开发测试二、Pod网络2.1 Pod网络命名空间每个Pod都有独立的网络命名空间apiVersion: v1 kind: Pod metadata: name: network-demo spec: containers: - name: busybox image: busybox:1.35 command: [sleep, 3600] securityContext: allowPrivilegeEscalation: false2.2 Pod间通信package network import ( context fmt net/http time corev1 k8s.io/api/core/v1 metav1 k8s.io/apimachinery/pkg/apis/meta/v1 ) type PodNetwork struct { client *K8sClient } func NewPodNetwork(client *K8sClient) *PodNetwork { return PodNetwork{client: client} } func (pn *PodNetwork) TestPodConnectivity(ctx context.Context, sourcePod, targetPod, namespace string) error { source, err : pn.client.clientset.CoreV1().Pods(namespace).Get(ctx, sourcePod, metav1.GetOptions{}) if err ! nil { return fmt.Errorf(failed to get source pod: %w, err) } target, err : pn.client.clientset.CoreV1().Pods(namespace).Get(ctx, targetPod, metav1.GetOptions{}) if err ! nil { return fmt.Errorf(failed to get target pod: %w, err) } targetIP : target.Status.PodIP if targetIP { return fmt.Errorf(target pod has no IP) } fmt.Printf(Testing connectivity from %s (%s) to %s (%s)\n, sourcePod, source.Status.PodIP, targetPod, targetIP) timeout : 5 * time.Second client : http.Client{Timeout: timeout} _, err client.Get(fmt.Sprintf(http://%s:8080/health, targetIP)) if err ! nil { return fmt.Errorf(connectivity test failed: %w, err) } fmt.Println(Connectivity test passed!) return nil } func (pn *PodNetwork) GetPodNetworkInfo(ctx context.Context, podName, namespace string) (*corev1.PodStatus, error) { pod, err : pn.client.clientset.CoreV1().Pods(namespace).Get(ctx, podName, metav1.GetOptions{}) if err ! nil { return nil, fmt.Errorf(failed to get pod: %w, err) } return pod.Status, nil }三、Service通信3.1 Service类型类型说明访问方式ClusterIP默认仅集群内部访问集群内部IPNodePort映射到Node端口NodeIP:NodePortLoadBalancer云厂商负载均衡外部IPExternalName外部服务别名CNAME记录3.2 Service配置apiVersion: v1 kind: Service metadata: name: backend-service spec: type: ClusterIP selector: app: backend ports: - name: http port: 80 targetPort: 8080 protocol: TCP sessionAffinity: ClientIP sessionAffinityConfig: clientIP: timeoutSeconds: 108003.3 服务发现package network import ( context fmt net time ) type ServiceDiscovery struct { namespace string } func NewServiceDiscovery(namespace string) *ServiceDiscovery { return ServiceDiscovery{namespace: namespace} } func (sd *ServiceDiscovery) ResolveService(serviceName string) ([]string, error) { resolver : net.Resolver{ Dial: func(ctx context.Context, network, address string) (net.Conn, error) { d : net.Dialer{ Timeout: time.Second * 5, } return d.DialContext(ctx, network, address) }, } host : fmt.Sprintf(%s.%s.svc.cluster.local, serviceName, sd.namespace) addrs, err : resolver.LookupHost(context.Background(), host) if err ! nil { return nil, fmt.Errorf(failed to resolve service: %w, err) } return addrs, nil } func (sd *ServiceDiscovery) ResolveWithPort(serviceName string, port int) (string, error) { addrs, err : sd.ResolveService(serviceName) if err ! nil { return , err } if len(addrs) 0 { return , fmt.Errorf(no addresses found for service %s, serviceName) } return fmt.Sprintf(%s:%d, addrs[0], port), nil }四、网络策略4.1 网络策略配置apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: backend-policy namespace: production spec: podSelector: matchLabels: app: backend policyTypes: - Ingress - Egress ingress: - from: - podSelector: matchLabels: app: frontend - ipBlock: cidr: 10.0.0.0/8 except: - 10.0.0.0/24 ports: - protocol: TCP port: 8080 egress: - to: - podSelector: matchLabels: app: database ports: - protocol: TCP port: 33064.2 网络策略类型类型说明Ingress控制进入Pod的流量Egress控制Pod发出的流量Both同时控制进入和发出4.3 网络策略示例package network import ( context fmt networkingv1 k8s.io/api/networking/v1 metav1 k8s.io/apimachinery/pkg/apis/meta/v1 ) func (k *K8sClient) CreateNetworkPolicy(ctx context.Context, name, namespace string) error { policy : networkingv1.NetworkPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: name, Namespace: namespace, }, Spec: networkingv1.NetworkPolicySpec{ PodSelector: metav1.LabelSelector{ MatchLabels: map[string]string{ app: backend, }, }, PolicyTypes: []networkingv1.PolicyType{ networkingv1.PolicyTypeIngress, networkingv1.PolicyTypeEgress, }, Ingress: []networkingv1.NetworkPolicyIngressRule{ { From: []networkingv1.NetworkPolicyPeer{ { PodSelector: metav1.LabelSelector{ MatchLabels: map[string]string{ app: frontend, }, }, }, }, Ports: []networkingv1.NetworkPolicyPort{ { Protocol: []networkingv1.Protocol{TCP}[0], Port: []int32{8080}[0], }, }, }, }, }, } _, err : k.clientset.NetworkingV1().NetworkPolicies(namespace).Create(ctx, policy, metav1.CreateOptions{}) if err ! nil { return fmt.Errorf(failed to create network policy: %w, err) } return nil }五、Ingress5.1 Ingress配置apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: web-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: / nginx.ingress.kubernetes.io/ssl-redirect: true nginx.ingress.kubernetes.io/proxy-read-timeout: 600 spec: tls: - hosts: - example.com secretName: example-tls rules: - host: example.com http: paths: - path: /api pathType: Prefix backend: service: name: api-service port: number: 80 - path: / pathType: Prefix backend: service: name: frontend-service port: number: 805.2 Ingress ControllerapiVersion: apps/v1 kind: Deployment metadata: name: nginx-ingress-controller spec: replicas: 2 selector: matchLabels: app: nginx-ingress template: metadata: labels: app: nginx-ingress spec: serviceAccountName: nginx-ingress-serviceaccount containers: - name: nginx-ingress-controller image: nginx/nginx-ingress:1.1.0 args: - /nginx-ingress-controller - --configmap$(POD_NAMESPACE)/nginx-configuration - --tcp-services-configmap$(POD_NAMESPACE)/tcp-services - --udp-services-configmap$(POD_NAMESPACE)/udp-services env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace ports: - name: http containerPort: 80 - name: https containerPort: 4435.3 路径类型类型说明Prefix前缀匹配Exact精确匹配ImplementationSpecific由Ingress Controller决定六、Service Mesh6.1 Service Mesh概念┌─────────────────────────────────────────────────────────┐ │ Service Mesh │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ Pod 1 │ │ Pod 2 │ │ Pod 3 │ │ │ │ (Sidecar)│ │ (Sidecar)│ │ (Sidecar)│ │ │ └────┬────┘ └────┬────┘ └────┬────┘ │ │ │ │ │ │ │ └──────────────┼──────────────┘ │ │ ▼ │ │ ┌─────────────────────┐ │ │ │ Control Plane │ │ │ │ (Istio/Linkerd) │ │ │ └─────────────────────┘ │ └─────────────────────────────────────────────────────────┘6.2 Istio基础配置apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: my-gateway spec: selector: istio: ingressgateway servers: - port: number: 80 name: http protocol: HTTP hosts: - example.com - port: number: 443 name: https protocol: HTTPS tls: mode: SIMPLE credentialName: example-tls hosts: - example.comapiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: my-virtual-service spec: hosts: - example.com gateways: - my-gateway http: - match: - uri: prefix: /api route: - destination: host: api-service port: number: 80 timeout: 30s retries: attempts: 3 perTryTimeout: 10s - match: - uri: prefix: / route: - destination: host: frontend-service port: number: 80七、总结Kubernetes网络模型是一个复杂但强大的系统Pod网络每个Pod拥有独立IPPod间直接通信Service提供服务发现和负载均衡网络策略控制Pod间的网络流量Ingress管理外部访问入口Service Mesh提供高级流量管理能力理解这些网络概念对于构建可靠的分布式应用至关重要。