第一部分:Service 与服务发现

一、Service 概述

解决的问题: Pod 是临时资源,IP 会变化,Deployment 动态创建销毁 Pod,客户端无法直接追踪 Pod 地址。

Service 的核心作用:

  • 提供固定的虚拟 IP 和端口
  • 为 Pod 提供负载均衡
  • 屏蔽后端 Pod 变化,对客户端透明

二、Service 基本管理

创建 Deployment:

kubectl create deployment web --image=httpd --replicas=3

创建 ClusterIP 类型 Service:

kubectl create service clusterip web --tcp=8080:80
# --tcp=8080:80 表示访问 Service 的 8080 端口转发到 Pod 的 80 端口

验证负载均衡:

# 修改每个 Pod 主页后,循环访问查看分发情况
for i in {1..60}; do curl -s 10.103.19.150:8080; done | sort | uniq -c

关键点:

  • Service 通过 Selector(标签选择器) 关联 Pod
  • 只要 Pod 标签匹配,无论通过 Deployment 还是 kubectl run 创建,都会被 Service 纳入后端
  • kubectl expose 可通过 --selector 指定标签选择器

三、Service 发现的三种方式

1. 通过 IP 访问

直接使用 Service 的 ClusterIP:Port 访问。

2. 通过环境变量访问

Service 创建后,Kubernetes 会向 Pod 注入环境变量:

MYSQL_SERVICE_HOST=10.111.69.45
MYSQL_SERVICE_PORT=3306

Pod 中可通过 $(MYSQL_SERVICE_HOST) 引用。

限制: Service 必须先于 Pod 创建,环境变量才会注入。

3. 通过 DNS 名称访问(推荐)

CoreDNS 为 Service 自动添加 DNS 记录:

<SERVICE_NAME>.<NAMESPACE>.svc.cluster.local
同一 namespace 可简写为:<SERVICE_NAME>

四、Service 类型

类型 说明 适用场景
ClusterIP 仅集群内部访问(默认) 内部服务通信
NodePort 通过节点物理端口暴露(30000-32767) 外部访问、测试环境
LoadBalancer 云厂商 LB + ClusterIP + NodePort 生产环境外部访问
ExternalName DNS CNAME 映射到外部域名 访问外部服务
Headless ClusterIP=None,无负载均衡 StatefulSet 直接访问 Pod

NodePort 端口说明:

  • nodePort:节点监听的端口(物理机端口)
  • port:ClusterIP 监听的端口
  • targetPort:Pod 监听的端口

五、会话保持(Session Affinity)

配置方式:

kubectl patch svc web -p '{"spec":{"sessionAffinity":"ClientIP"}}'

工作原理:

  • 首次访问记录客户端 IP 与 Pod 的映射关系
  • 后续请求转发到同一个 Pod
  • 默认超时时间 10800 秒(3 小时)

适用场景: 有状态服务(Web 登录状态、WebSocket、购物车)

六、金丝雀发布

核心思路: 通过标签区分版本,Service 通过标签选择器同时关联稳定版和灰度版,通过调整副本数控制流量比例。

# 稳定版标签 track: stable
# 灰度版标签 track: canary
# Service 选择器:app: web, tier: frontend

流量比例控制:

kubectl scale deployment web-28 --replicas=8   # 稳定版 80% 流量
kubectl scale deployment web-29 --replicas=2   # 灰度版 20% 流量

第二部分:kube-proxy 工作原理

一、三种工作模式对比

模式 地位 性能 适用场景
iptables 默认模式 中(服务数 < 1000) 小规模集群
IPVS 推荐模式 极高(服务数 10w+) 中大规模生产
Userspace 已废弃 仅兼容旧版

二、IPVS 模式(生产推荐)

特点:

  • 基于内核哈希表,查找效率 O(1)
  • 支持多种调度算法:rr(轮询)、wrr(加权轮询)、lc(最少连接)、sh(源地址哈希)

切换 IPVS 模式:

# 修改 ConfigMap
kubectl edit configmap -n kube-system kube-proxy
# 将 mode 改为 "ipvs"

# 重启 kube-proxy
kubectl rollout restart daemonset -n kube-system kube-proxy

# 验证
kubectl logs -n kube-system kube-proxy-xxx | grep "Using ipvs Proxier"

查看 IPVS 规则:

ipvsadm -Lnt <Service-IP>:<Port>

调度算法与 sessionAffinity 的关系:

  • Service 配置 sessionAffinity: ClientIP → IPVS 自动使用 sh 算法
  • 不配置时使用 scheduler 指定的算法(如 rr

三、iptables 模式(默认)

核心流程: 客户端访问 ClusterIP → KUBE-SERVICES 链 → KUBE-SVC-XXX 服务链(概率负载均衡)→ KUBE-SEP-XXX 端点链(DNAT)→ 后端 Pod

性能瓶颈: 每增加一个 Service/Endpoint 就增加规则,超过 1000 个服务时规则链膨胀,CPU 飙升。


第三部分:Ingress

一、Ingress 概述

解决的问题: NodePort 端口有限且不便于管理,LoadBalancer 成本高,需要七层路由能力(域名、路径分流)。

核心概念:

  • Ingress 资源: 定义路由规则(相当于 Nginx 配置)
  • Ingress Controller: 实际处理流量的负载均衡器(相当于 Nginx 进程)
  • 工作流程:Controller 监听 Ingress 资源变化 → 生成 Nginx 配置 → reload

二、Ingress 规则实践

1. 多域名虚拟主机
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: multi-host-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: webapp01.laoma.cloud
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: webapp01
            port:
              number: 80
  - host: webapp02.laoma.cloud
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: webapp02
            port:
              number: 80
2. 同一域名多路径分流
rules:
- host: www.laoma.cloud
  http:
    paths:
    - path: /
      pathType: Prefix
      backend:
        service:
          name: webapp01
          port:
            number: 80
    - path: /games
      pathType: Prefix
      backend:
        service:
          name: webapp02
          port:
            number: 80
3. 路径重写(生产常用)
metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1
    nginx.ingress.kubernetes.io/use-regex: "true"
spec:
  rules:
  - host: www.laoma.cloud
    http:
      paths:
      - path: /webapp01/(.*)
        pathType: ImplementationSpecific
        backend:
          service:
            name: webapp01
            port:
              number: 80
4. HTTPS + 强制跳转
# 生成自签名证书
openssl genrsa -out www.key 2048
openssl req -new -key www.key -out www.csr -subj "/CN=www.laoma.cloud"
openssl x509 -req -days 3650 -in www.csr -signkey www.key -out www.crt

# 创建 Secret
kubectl create secret tls www-tls --cert=www.crt --key=www.key
metadata:
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
  tls:
  - hosts:
    - www.laoma.cloud
    secretName: www-tls
  rules:
  - host: www.laoma.cloud
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: webapp01
            port:
              number: 80

三、生产常用注解速查

注解 作用
force-ssl-redirect: "true" 80 端口强制跳转 HTTPS
rewrite-target: /$1 路径重写,剥离路由前缀
whitelist-source-range: "10.0.0.0/8" IP 白名单访问控制
limit-rps: "20" 单 IP 每秒请求数限流
limit-connections: "50" 单 IP 最大并发连接数
enable-cors: "true" 开启跨域
proxy-read-timeout: "60" 读超时设置
x-forwarded-for: "true" 透传真实客户端 IP

第四部分:Kubernetes 网络策略(NetworkPolicy)

一、核心概念

默认行为: 所有 Pod 入站和出站流量都允许(非隔离)。

隔离机制: 一旦 Pod 被 NetworkPolicy 选中,该方向的流量默认变为拒绝,只放行策略中明确允许的流量。

策略相加性: 多个 NetworkPolicy 的规则是累加的,不会冲突。

二、核心字段

spec:
  podSelector:        # 策略作用的 Pod(空表示 namespace 所有 Pod)
    matchLabels:
      role: db
  policyTypes:        # Ingress 入站 / Egress 出站
  - Ingress
  - Egress
  ingress:            # 入站规则
  - from:             # 来源
    - podSelector: {} # 同 namespace 的 Pod
    - namespaceSelector: {} # 其他 namespace 的 Pod
    - ipBlock:        # IP 网段
        cidr: 10.0.0.0/16
        except:
        - 10.0.1.0/24
    ports:            # 端口限制
    - protocol: TCP
      port: 6379
  egress:             # 出站规则
  - to:
    - ipBlock:
        cidr: 10.0.0.0/24

三、常见场景配置

1. 允许特定 Pod 访问(同 namespace)
ingress:
- from:
  - podSelector:
      matchLabels:
        run: test
  ports:
  - protocol: TCP
    port: 80
2. 允许特定 namespace 访问
ingress:
- from:
  - namespaceSelector:
      matchLabels:
        project: myproject
  ports:
  - protocol: TCP
    port: 80
3. 允许所有 namespace 访问
ingress:
- from:
  - namespaceSelector: {}
4. IP 网段限制
ingress:
- from:
  - ipBlock:
      cidr: 10.1.8.0/24
      except:
      - 10.1.8.128/26
5. 默认拒绝所有入站流量
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  # 不配置 ingress 规则,默认全部拒绝

四、注意事项

  • 需要支持 NetworkPolicy 的网络插件(如 Calico)
  • 策略是白名单机制,只能添加允许规则,不能显式拒绝
  • ipBlock 对 Service IP 可能失效(因为 SNAT/DNAT 发生在策略评估之前)
  • 无法阻塞 localhost 或节点到 Pod 的流量

第五部分:Pod 调度(Scheduler)

一、调度流程

  1. 过滤(Filter): 找到满足 Pod 资源、端口、选择器等需求的节点
  2. 打分(Score): 对候选节点按规则评分,选最高分节点
  3. 绑定(Bind): 将 Pod 绑定到选中的节点

二、控制 Pod 运行位置的四种方式

方式 优先级 说明
nodeName 最高 直接指定节点名,不推荐
nodeSelector 推荐 基于节点标签的简单选择
节点亲和性 灵活 支持软硬约束、复杂表达式
Pod 亲和性/反亲和性 高级 基于已有 Pod 的调度约束

三、节点亲和性(nodeAffinity)

两种类型:

  • requiredDuringSchedulingIgnoredDuringExecution:硬约束,必须满足
  • preferredDuringSchedulingIgnoredDuringExecution:软约束,尽量满足

示例:

affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: CPU
          operator: In
          values:
          - L1
          - L2
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 1
      preference:
        matchExpressions:
        - key: MEM
          operator: In
          values:
          - L1
          - L2

支持的操作符: InNotInExistsDoesNotExistGtLt

四、Pod 间亲和性/反亲和性

关键概念:

  • topologyKey:拓扑域标签(如 kubernetes.io/hostnametopology.kubernetes.io/zone
  • labelSelector:匹配已有 Pod 的标签

**示例:Pod 反亲和性(每个节点最多一个副本)**r

affinity:
  podAntiAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
    - labelSelector:
        matchExpressions:
        - key: app
          operator: In
          values:
          - store
      topologyKey: "kubernetes.io/hostname"

五、污点(Taint)与容忍度(Toleration)

关系类比: nodeAffinity = Pod 选 Node,Taint = Node 选 Pod

污点效果(effect):

说明
NoSchedule 新 Pod 不能调度上来,已有 Pod 不受影响
PreferNoSchedule 软性 NoSchedule,尽量不调度
NoExecute 新 Pod 不能调度,已有不匹配 Pod 立即驱逐

设置污点:

kubectl taint nodes worker31 CPU=L1:NoSchedule
kubectl taint nodes worker31 CPU:NoSchedule-  # 移除

Pod 容忍度:

tolerations:
- key: "CPU"
  operator: "Equal"
  value: "L1"
  effect: "NoSchedule"

多污点匹配规则: 过滤掉匹配的污点后,剩余污点中存在任一 NoSchedule 则 Pod 不能调度到该节点。

内置污点(自动添加):

  • node.kubernetes.io/not-ready:节点未就绪
  • node.kubernetes.io/unreachable:节点不可达
  • node.kubernetes.io/memory-pressure:内存压力
  • node.kubernetes.io/disk-pressure:磁盘压力

六、节点维护操作

命令 作用
kubectl cordon NODE 标记节点不可调度(新 Pod 不会调度上来)
kubectl uncordon NODE 恢复节点可调度
kubectl drain NODE 驱逐节点上所有 Pod + cordon,用于维护

drain 常用选项:

kubectl drain worker31 --ignore-daemonsets  # 忽略 DaemonSet 管理的 Pod
kubectl drain worker31 --pod-selector='app=web'  # 只驱逐特定 Pod

第六部分:Metrics Server

一、功能与定位

用途:

  • 收集 Node 和 Pod 的 CPU、内存资源使用指标
  • 通过 Metrics API 提供给 HPA(水平自动扩缩容)使用
  • 支持 kubectl top 命令查看资源使用

定位: 仅用于自动扩缩容,不适用于监控告警系统。

二、部署

wget https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.7.1/components.yaml

# 添加 kubelet-insecure-tls 跳过证书验证
sed -i '/metric-resolution/a\        - --kubelet-insecure-tls' components.yaml

# 替换镜像地址
sed -i 's/registry.k8s.io/hub.laoma.cloud/g' components.yaml

kubectl apply -f components.yaml

三、使用

# 查看节点资源使用
kubectl top node
NAME                  CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
master30.laoma.cloud  97m          4%     1328Mi          35%

# 查看 Pod 资源使用
kubectl top pods -n kube-system

单位说明: 1 CPU = 1000m(毫核)


环境清理命令汇总

kubectl delete ns services
kubectl delete ns network web laoma
kubectl delete ns scheduler
kubectl delete ns metric
kubectl delete ns ingress

核心命令速查

命令 说明
kubectl create service clusterip NAME --tcp=port:targetPort 创建 ClusterIP Service
kubectl expose deployment NAME --port=port --target-port=targetPort --type=Type 暴露 Service
kubectl get svc 查看 Service
kubectl describe svc NAME 查看 Service 详情(含 Endpoints)
kubectl patch svc NAME -p '{"spec":{"sessionAffinity":"ClientIP"}}' 开启会话保持
kubectl get cm -n kube-system kube-proxy -o yaml 查看 kube-proxy 配置
kubectl get netpol 查看 NetworkPolicy
kubectl label nodes NODE KEY=VALUE 给节点打标签
kubectl taint nodes NODE KEY=VALUE:EFFECT 给节点打污点
kubectl cordon/drain/uncordon NODE 节点维护操作
kubectl top node/pod 查看资源使用(需 Metrics Server)
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐