关于 service-mesh
面向 Kubernetes 运维人员的服务网格技能,提供使用 Istio 或 Linkerd 管理服务间通信的配置指引,涵盖安全、流量控制、可观测性和策略执行。
主要功能
- 01配置服务间 mTLS
- 02设置流量拆分与路由
- 03启用熔断、重试和超时
- 04查看服务级可观测性
- 05制定服务授权策略
适用场景
- 01为微服务通信启用自动 mTLS
- 02配置金丝雀发布或 A/B 测试
- 03无需修改应用代码添加重试
- 04控制服务间访问权限
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ bagelhole/ devops-security-agent-skills --skill service-mesh安装后在 Claude Code 中输入/service-mesh确认已加载。
详细介绍
服务网格
使用 Istio 或 Linkerd 实现服务间通信管理,包括 mTLS、流量整形、可观测性和策略执行。
适用场景
- 通过自动 mTLS 保护微服务通信。
- 实现金丝雀部署、流量拆分或 A/B 测试。
- 无需更改应用程序代码即可添加断路器、重试和超时。
- 获取服务级别的可观测性(延迟、错误率、请求量)。
- 在服务之间执行授权策略。
前提条件
- 已配置 kubectl 的 Kubernetes 集群(1.26+)。
- 已安装 Helm 3(适用于某些安装方式)。
- 集群资源充足(Istio 控制平面需要约 2 GB RAM)。
- 对于 Istio:已安装
istioctlCLI。 - 对于 Linkerd:已安装
linkerdCLI。
安装 Istio
使用 istioctl 安装
# Download istioctl
curl -L https://istio.io/downloadIstio | sh -
cd istio-*
export PATH=$PWD/bin:$PATH
# Install with the production profile
istioctl install --set profile=default -y
# Or use the demo profile (includes all addons, good for learning)
istioctl install --set profile=demo -y
# Verify installation
istioctl verify-install
# Check running components
kubectl get pods -n istio-system
启用 Sidecar 注入
# Enable automatic sidecar injection for a namespace
kubectl label namespace default istio-injection=enabled
# Verify label
kubectl get namespace default --show-labels
# Restart existing pods to inject sidecars
kubectl rollout restart deployment -n default
# Check sidecar status
kubectl get pods -n default -o jsonpath='{range .items[*]}{.metadata.name}{" containers: "}{range .spec.containers[*]}{.name}{" "}{end}{"\n"}{end}'
安装可观测性插件
# Install Kiali, Prometheus, Grafana, Jaeger
kubectl apply -f samples/addons/prometheus.yaml
kubectl apply -f samples/addons/grafana.yaml
kubectl apply -f samples/addons/jaeger.yaml
kubectl apply -f samples/addons/kiali.yaml
# Wait for rollout
kubectl rollout status deployment/kiali -n istio-system
# Access dashboards
istioctl dashboard kiali
istioctl dashboard grafana
istioctl dashboard jaeger
流量管理
VirtualService(路由规则)
# virtualservice.yaml — canary deployment with traffic split
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: my-app
namespace: default
spec:
hosts:
- my-app
http:
# Header-based routing (canary testers)
- match:
- headers:
x-canary:
exact: "true"
route:
- destination:
host: my-app
subset: canary
# Percentage-based traffic split
- route:
- destination:
host: my-app
subset: stable
weight: 90
- destination:
host: my-app
subset: canary
weight: 10
timeout: 30s
retries:
attempts: 3
perTryTimeout: 10s
retryOn: gateway-error,connect-failure,refused-stream
DestinationRule(子集和连接策略)
# destinationrule.yaml
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: my-app
namespace: default
spec:
host: my-app
trafficPolicy:
connectionPool:
tcp:
maxConnections: 100
http:
h2UpgradePolicy: DEFAULT
http1MaxPendingRequests: 100
http2MaxRequests: 1000
maxRequestsPerConnection: 10
outlierDetection:
consecutive5xxErrors: 5
interval: 10s
baseEjectionTime: 30s
maxEjectionPercent: 50
subsets:
- name: stable
labels:
version: v1
- name: canary
labels:
version: v2
Gateway(入口流量)
# gateway.yaml — expose service to external traffic
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: app-gateway
namespace: default
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: https
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: app-tls-cert # Kubernetes secret
hosts:
- app.example.com
- port:
number: 80
name: http
protocol: HTTP
hosts:
- app.example.com
tls:
httpsRedirect: true
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: app-external
namespace: default
spec:
hosts:
- app.example.com
gateways:
- app-gateway
http:
- route:
- destination:
host: my-app
port:
number: 8080
mTLS 配置
严格 mTLS(整个集群)
# peer-authentication.yaml
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: istio-system # Applies to entire mesh
spec:
mtls:
mode: STRICT
宽容 mTLS(按命名空间)
# Allow both plaintext and mTLS during migration
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: legacy-apps
spec:
mtls:
mode: PERMISSIVE
验证 mTLS 状态
# Check mTLS status for a namespace
istioctl x describe pod <pod-name> -n default
# View TLS configuration
istioctl proxy-config cluster <pod-name>.default --fqdn my-app.default.svc.cluster.local -o json | grep -A5 "tlsContext"
# Verify with istioctl authn
istioctl authn tls-check <pod-name>.default my-app.default.svc.cluster.local
授权策略
# authz-policy.yaml — only allow frontend to call API
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: api-access
namespace: default
spec:
selector:
matchLabels:
app: my-api
action: ALLOW
rules:
- from:
- source:
principals:
- "cluster.local/ns/default/sa/frontend"
to:
- operation:
methods: ["GET", "POST"]
paths: ["/api/*"]
---
# Deny all other traffic to api
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: deny-all
namespace: default
spec:
selector:
matchLabels:
app: my-api
action: DENY
rules:
- from:
- source:
notPrincipals:
- "cluster.local/ns/default/sa/frontend"
断路
# circuit-breaker.yaml
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: my-api-circuit-breaker
spec:
host: my-api
trafficPolicy:
connectionPool:
tcp:
maxConnections: 50
http:
http1MaxPendingRequests: 50
http2MaxRequests: 100
maxRetries: 3
outlierDetection:
consecutive5xxErrors: 3
interval: 15s
baseEjectionTime: 60s
maxEjectionPercent: 100
安装 Linkerd
# Install Linkerd CLI
curl --proto '=https' --tlsv1.2 -sSfL https://run.linkerd.io/install | sh
export PATH=$HOME/.linkerd2/bin:$PATH
# Validate cluster prerequisites
linkerd check --pre
# Install Linkerd CRDs
linkerd install --crds | kubectl apply -f -
# Install Linkerd control plane
linkerd install | kubectl apply -f -
# Verify installation
linkerd check
# Inject sidecar into a namespace
kubectl get deploy -n my-app -o yaml | linkerd inject - | kubectl apply -f -
# Or annotate namespace for auto-injection
kubectl annotate namespace my-app linkerd.io/inject=enabled
# View live traffic dashboard
linkerd viz install | kubectl apply -f -
linkerd viz dashboard
Linkerd 流量拆分(SMI)
# traffic-split.yaml
apiVersion: split.smi-spec.io/v1alpha4
kind: TrafficSplit
metadata:
name: my-app-split
namespace: default
spec:
service: my-app
backends:
- service: my-app-stable
weight: 900
- service: my-app-canary
weight: 100
调试
# Istio: check proxy configuration
istioctl proxy-config routes <pod-name>.default
istioctl proxy-config clusters <pod-name>.default
istioctl proxy-config listeners <pod-name>.default
# Istio: analyze configuration for issues
istioctl analyze -n default
# Istio: proxy debug logs
istioctl proxy-config log <pod-name>.default --level debug
# Linkerd: check proxy stats
linkerd viz stat deploy -n default
linkerd viz top deploy/my-app -n default
linkerd viz edges deploy -n default
故障排除
| 症状 | 原因 | 修复方法 |
|---|---|---|
| 未注入 Sidecar | 缺少命名空间标签 | 添加 istio-injection=enabled 标签;重启 Pod |
| 服务间出现 503 错误 | mTLS 不匹配(一侧使用明文) | 迁移期间将 PeerAuthentication 设置为 PERMISSIVE |
| 安装网格后延迟较高 | Sidecar 资源限制过低 | 在网格配置中提高 Sidecar 的 CPU/内存限制 |
| VirtualService 未进行路由 | 缺少 DestinationRule 子集 | 创建具有匹配子集标签的 DestinationRule |
upstream connect error | 断路器已触发 | 检查异常检测设置;提高阈值 |
| 授权策略阻止所有请求 | 默认拒绝,且没有匹配的允许规则 | 在全部拒绝规则之前添加明确的 ALLOW 规则 |
| Kiali 显示“Unknown”流量 | 发起调用的服务缺少 Sidecar | 为所有相互通信的服务注入 Sidecar |
相关技能
- load-balancing - Kubernetes 外部的第 4/7 层负载均衡
- reverse-proxy - 入口层代理
- ai-inference-service-mesh - 面向 ML 工作负载的网格模式
- dns-management - 网格入口网关的 DNS
评论
支持 Markdown