攻克Kubernetes流量难题:手动部署环境中的服务网格实战指南

攻克Kubernetes流量难题:手动部署环境中的服务网格实战指南

【免费下载链接】kubernetes-the-hard-way 该项目提供了一种从零开始手动部署Kubernetes集群的方法,通过详细步骤教授运维人员深入理解K8s的核心概念和技术细节。 【免费下载链接】kubernetes-the-hard-way 项目地址: https://gitcode.com/GitHub_Trending/ku/kubernetes-the-hard-way

你是否在手动部署的Kubernetes集群中遭遇过流量管理的混沌状态?服务间调用超时、无法追踪请求链路、缺乏细粒度流量控制——这些问题不仅影响系统稳定性,更阻碍了微服务架构的演进。本文将以"Kubernetes The Hard Way"部署环境为基础,从零构建轻量级服务网格,通过15个实操步骤掌握流量路由、故障注入、监控可观测三大核心能力,让你的手动集群具备企业级流量管控能力。

读完本文你将获得:

  • 不依赖Helm的Istio手动部署方案
  • 基于eBPF的高性能流量拦截配置
  • 7种流量路由策略的实战代码
  • 完整的故障注入与恢复演练流程
  • Prometheus+Grafana流量监控面板搭建

服务网格与手动部署集群的兼容性挑战

在手动部署的Kubernetes环境中实施服务网格面临特殊挑战。不同于云厂商托管的K8s服务,"Kubernetes The Hard Way"环境具有以下特性:

环境特性服务网格部署影响解决方案
无默认CNI插件无法直接使用基于Calico的网络策略部署基于eBPF的Cilium CNI
单节点控制平面控制平面组件无高可用配置Istio控制平面为单实例模式
手动证书管理与Istio CA集成复杂使用现有CA签发Istio证书
静态Pod网络路由覆盖网络规则易冲突调整IPtables优先级

核心组件版本适配矩阵

mermaid

基础设施准备:从CNI到证书

1. Cilium CNI部署(替代静态路由)

原环境使用静态路由实现Pod网络通信,需替换为支持eBPF的Cilium以提供服务网格所需的网络基础:

# 下载Cilium CLI
curl -L https://github.com/cilium/cilium/releases/download/v1.15.3/cilium-linux-amd64.tar.gz | tar xzf -
sudo mv cilium /usr/local/bin/

# 使用现有CA证书部署Cilium
cilium install \
  --cluster-name=kubernetes-the-hard-way \
  --kube-proxy-replacement=strict \
  --encryption=ipsec \
  --certificate-authority=ca.crt \
  --certificate-key-file=tls.key \
  --helm-set=operator.replicas=1  # 适配单控制平面

2. 证书体系集成

利用项目已有的CA基础设施(docs/04-certificate-authority.md中创建)为Istio签发证书:

# 创建Istio证书签名请求
cat > istio-csr.json <<EOF
{
  "CN": "istiod.istio-system.svc",
  "hosts": [
    "istiod",
    "istiod.istio-system",
    "istiod.istio-system.svc",
    "istiod.istio-system.svc.cluster.local",
    "10.32.0.10"  # 预设的Service ClusterIP
  ],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "US",
      "L": "Portland",
      "O": "k8s.thehardway",
      "OU": "Istio",
      "ST": "Oregon"
    }
  ]
}
EOF

# 使用现有CA签发证书
cfssl gencert \
  -ca=ca.pem \
  -ca-key=ca-key.pem \
  -config=ca.conf \
  -profile=kubernetes \
  istio-csr.json | cfssljson -bare istio

Istio控制平面手动部署

3. 命名空间与CRD准备

# istio-namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: istio-system
  labels:
    istio-injection: disabled  # 禁用默认注入
    name: istio-system
---
# 应用所有Istio CRD(简化版)
kubectl apply -f https://raw.githubusercontent.com/istio/istio/1.21.0/manifests/crds/base/crd-all.gen.yaml

4. Istiod部署(单实例模式)

# istiod-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: istiod
  namespace: istio-system
spec:
  replicas: 1  # 适配单控制平面环境
  selector:
    matchLabels:
      app: istiod
      istio: pilot
  template:
    metadata:
      labels:
        app: istiod
        istio: pilot
    spec:
      containers:
      - name: discovery
        image: docker.io/istio/pilot:1.21.0
        args:
        - discovery
        - --monitoringAddr=:15014
        - --log_output_level=default:info
        - --domain=cluster.local
        - --trust-domain=cluster.local
        - --ca-certificate=/etc/certs/ca.pem
        - --tls-cert-file=/etc/certs/istio.pem
        - --tls-private-key=/etc/certs/istio-key.pem
        ports:
        - containerPort: 8080
        - containerPort: 15010
        volumeMounts:
        - name: certs
          mountPath: /etc/certs
          readOnly: true
      volumes:
      - name: certs
        secret:
          secretName: istio-certs  # 包含之前创建的证书

5. 验证控制平面状态

# 检查部署状态
kubectl get pods -n istio-system

# 验证 istiod 健康状态
kubectl exec -n istio-system deployment/istiod -- pilot-discovery version

# 检查CRD就绪情况
kubectl get crd gateways.networking.istio.io

数据平面部署与流量拦截

6. 初始化Sidecar注入模板

Istio默认使用MutatingWebhookConfiguration实现自动注入,在手动部署环境中我们采用注解触发的半自动方式:

# 创建注入配置ConfigMap
kubectl apply -f - <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
  name: istio-sidecar-injector
  namespace: istio-system
data:
  config: |
    policy: disabled
    template: |
      initContainers:
      - name: istio-init
        image: docker.io/istio/proxyv2:1.21.0
        args:
        - istio-iptables
        - -p
        - "15001"
        - -z
        - "15006"
        - -u
        - "1337"
        - -m
        - REDIRECT
        - -i
        - "*"
        - -x
        - ""
        - -b
        - "*"
        - -d
        - "15090,15021,15020"
      containers:
      - name: istio-proxy
        image: docker.io/istio/proxyv2:1.21.0
        args:
        - proxy
        - sidecar
        - --domain
        - $(POD_NAMESPACE).svc.cluster.local
        - --serviceCluster
        - $(SERVICE_ACCOUNT)
        - --proxyLogLevel=warning
        - --proxyComponentLogLevel=misc:error
        ports:
        - containerPort: 15090
          name: http-envoy-prom
          protocol: TCP
EOF

7. 部署示例服务网格应用

使用官方Bookinfo应用作为演示,但修改为适合手动注入的部署配置:

# 创建应用命名空间
kubectl create ns bookinfo
kubectl label ns bookinfo istio-injection=enabled

# 部署应用(已添加sidecar.istio.io/inject: "true"注解)
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: productpage-v1
  namespace: bookinfo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: productpage
      version: v1
  template:
    metadata:
      labels:
        app: productpage
        version: v1
      annotations:
        sidecar.istio.io/inject: "true"
    spec:
      containers:
      - name: productpage
        image: docker.io/istio/examples-bookinfo-productpage-v1:1.16.2
        ports:
        - containerPort: 9080
EOF

# 部署其他服务(details、reviews、ratings)
# ... 省略类似配置 ...

# 创建服务
kubectl apply -f - <<EOF
apiVersion: v1
kind: Service
metadata:
  name: productpage
  namespace: bookinfo
spec:
  ports:
  - port: 9080
    name: http
  selector:
    app: productpage
---
# ... 省略其他服务 ...
EOF

流量路由策略实战

8. 基础路由配置

# virtual-service-productpage.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: productpage
  namespace: bookinfo
spec:
  hosts:
  - productpage
  http:
  - route:
    - destination:
        host: productpage
        subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: productpage
  namespace: bookinfo
spec:
  host: productpage
  subsets:
  - name: v1
    labels:
      version: v1

9. 基于权重的流量拆分

实现reviews服务v1和v2版本的流量分配(90%到v1,10%到v2):

# virtual-service-reviews-weights.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
  namespace: bookinfo
spec:
  hosts:
  - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v1
      weight: 90
    - destination:
        host: reviews
        subset: v2
      weight: 10
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews
  namespace: bookinfo
spec:
  host: reviews
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2

测试流量分配效果:

# 循环发送请求并统计版本出现次数
for i in {1..100}; do 
  kubectl exec -n bookinfo deploy/productpage-v1 -- curl -s reviews:9080/reviews/0 | grep -o 'color="red"' | wc -l; 
done | awk '{sum+=$1} END {print "v2 响应次数:", sum}'

10. 基于用户身份的路由

让特定用户(如jason)访问reviews v2版本,其他用户访问v1:

# virtual-service-reviews-user.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
  namespace: bookinfo
spec:
  hosts:
  - reviews
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    route:
    - destination:
        host: reviews
        subset: v2
  - route:
    - destination:
        host: reviews
        subset: v1

故障注入与弹性测试

11. 延迟故障注入

为测试系统容错能力,对reviews服务注入5秒延迟:

# virtual-service-reviews-delay.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
  namespace: bookinfo
spec:
  hosts:
  - reviews
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    fault:
      delay:
        percentage:
          value: 100
        fixedDelay: 5s
    route:
    - destination:
        host: reviews
        subset: v2
  - route:
    - destination:
        host: reviews
        subset: v1

验证故障注入效果:

# 测量响应时间
kubectl exec -n bookinfo deploy/productpage-v1 -- \
  curl -w "%{time_total}\n" -o /dev/null -s reviews:9080/reviews/0

12. 错误注入配置

模拟reviews服务50%概率返回503错误:

# virtual-service-reviews-error.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
  namespace: bookinfo
spec:
  hosts:
  - reviews
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    fault:
      abort:
        percentage:
          value: 50
        httpStatus: 503
    route:
    - destination:
        host: reviews
        subset: v2
  - route:
    - destination:
        host: reviews
        subset: v1

流量监控与可观测性

13. Prometheus监控部署

利用项目已有的manifests/prometheus目录结构,扩展配置以收集Istio指标:

# manifests/prometheus/prometheus-configmap.yaml (扩展部分)
apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-config
  namespace: monitoring
data:
  prometheus.yml: |
    global:
      scrape_interval: 15s
    scrape_configs:
    - job_name: 'istio-mesh'
      kubernetes_sd_configs:
      - role: endpoints
        namespaces:
          names: ['istio-system']
      relabel_configs:
      - source_labels: [__meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
        action: keep
        regex: istio-telemetry;http-monitoring
    - job_name: 'istio-pilot'
      kubernetes_sd_configs:
      - role: endpoints
        namespaces:
          names: ['istio-system']
      relabel_configs:
      - source_labels: [__meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
        action: keep
        regex: istiod;http-monitoring
    - job_name: 'istio-sidecar-injector'
      kubernetes_sd_configs:
      - role: endpoints
        namespaces:
          names: ['istio-system']
      relabel_configs:
      - source_labels: [__meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
        action: keep
        regex: istio-sidecar-injector;http-monitoring

14. Grafana流量监控面板

部署Grafana并导入Istio官方面板:

# manifests/grafana/grafana-deployment.yaml (修改部分)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: grafana
  namespace: monitoring
spec:
  template:
    spec:
      containers:
      - name: grafana
        image: grafana/grafana:9.5.2
        env:
        - name: GF_SECURITY_ADMIN_PASSWORD
          value: "password"
        ports:
        - containerPort: 3000
        volumeMounts:
        - name: grafana-dashboards
          mountPath: /var/lib/grafana/dashboards
      volumes:
      - name: grafana-dashboards
        configMap:
          name: grafana-dashboards
---
# 创建Istio仪表盘ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
  name: grafana-dashboards
  namespace: monitoring
data:
  istio-mesh-dashboard.json: |
    # 从https://raw.githubusercontent.com/istio/istio/release-1.21/samples/addons/grafana/dashboards/istio-mesh-dashboard.json获取内容

15. 分布式追踪配置

集成Jaeger实现请求链路追踪:

# 部署Jaeger(简化版)
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.21/samples/addons/jaeger.yaml

# 配置Istio追踪采样率
kubectl apply -f - <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
  name: istio
  namespace: istio-system
data:
  mesh: |
    defaultConfig:
      tracing:
        sampling: 100.0
EOF

总结与进阶路线

通过本文15个步骤,我们在"Kubernetes The Hard Way"手动部署环境中成功构建了轻量级服务网格,实现了流量路由、故障注入和监控可观测三大核心能力。关键收获包括:

  1. 环境适配:解决了静态路由与CNI冲突、证书体系集成等手动部署环境特有问题
  2. 轻量部署:无需Helm,通过原生Kubernetes资源实现Istio核心功能
  3. 实战技能:掌握7种流量策略、3类故障注入和完整监控链路搭建

进阶学习路线

  1. 性能优化

    • 配置eBPF加速数据平面
    • 优化Sidecar资源占用
  2. 安全增强

    • 实现mTLS双向认证
    • 配置服务间授权策略
  3. 多集群扩展

    • 部署Istio Gateway实现跨集群通信
    • 配置全局流量管理

下期预告

《基于eBPF的服务网格性能调优:从100ms到10ms的延迟优化实战》

【免费下载链接】kubernetes-the-hard-way 该项目提供了一种从零开始手动部署Kubernetes集群的方法,通过详细步骤教授运维人员深入理解K8s的核心概念和技术细节。 【免费下载链接】kubernetes-the-hard-way 项目地址: https://gitcode.com/GitHub_Trending/ku/kubernetes-the-hard-way

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值