- 前言
- Kubernetes Network Policy 基础
- Network Policy 进阶:Egress、CIDR 与端口控制
- Service Mesh 架构对比(Istio vs Cilium vs Calico)
- 基于 Istio 构建 Service Mesh
- 基于 Cilium 的 eBPF Service Mesh
- mTLS 与零信任网络
- 运维注意事项与排障
- 故障案例与恢复流程
- 性能基准与选型指南
- 结语
- 参考资料

前言
在 Kubernetes 集群中,Pod 之间的通信默认处于全部允许(allow-all)状态。也就是说,只要在同一个集群内,任何 Pod 都可以自由访问其他 Pod。在小规模的开发环境中这算不上什么问题,但如果是生产环境中运行着几十、几百个微服务的场景,这就会成为严重的安全威胁。
因为一旦攻击者攻陷了其中一个 Pod,就能在集群内向所有服务进行横向移动(lateral movement)。要防止这种情况,通过Network Policy实现网络分段,以及通过Service Mesh实现 mTLS 加密与零信任架构,都是必不可少的。
本文将从 Kubernetes Network Policy 的基础一直讲到进阶用法,并对比分析 Istio、Cilium、Calico 三种方案的 Service Mesh 架构。文中还包含实际运维中可能遇到的排障案例与性能基准测试,帮助你为自己的环境做出最合适的选择。
Kubernetes Network Policy 基础
什么是 Network Policy?
Network Policy 是 Kubernetes 原生资源,是在 Pod 层面控制入站(Ingress)与出站(Egress)流量的防火墙规则。它基于标签选择器工作,即使 Pod 重启或在节点之间迁移,也能应用一致的策略。
重要的前提条件:即使创建了 Network Policy 资源,如果没有实现它的 CNI 插件(Calico、Cilium、Antrea 等),策略也完全不会生效。默认的 kubenet 或 Flannel 并不支持 Network Policy。
Default Deny 策略
所有网络安全的起点都是Default Deny策略。先阻断全部流量,然后只显式放行必要的通信,采用白名单方式。
# default-deny-all.yaml
# 阻断命名空间内所有 Pod 的 Ingress/Egress 流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {} # 空选择器 = 命名空间内的所有 Pod
policyTypes:
- Ingress
- Egress
这条策略生效后,production 命名空间中所有 Pod 的入站/出站流量都会被完全阻断。由于连 DNS 查询都无法进行,因此必须同时应用允许 DNS 的策略。
# allow-dns.yaml
# 允许访问 kube-dns(CoreDNS) 的策略
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns
namespace: production
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
放行 Pod 之间的特定通信
下面是在 Default Deny 状态下,允许前端访问后端 API 的示例。
# allow-frontend-to-backend.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: production
spec:
podSelector:
matchLabels:
app: backend-api
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
这条策略只允许带有 app: frontend 标签的 Pod 访问 app: backend-api Pod 的 TCP 8080 端口的入站流量。
Network Policy 进阶:Egress、CIDR 与端口控制
用 Egress 策略控制外部访问
当微服务需要访问外部 API 或数据库时,可以用 Egress 策略精细地限制放行对象。
# egress-external-api-and-db.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-egress-policy
namespace: production
spec:
podSelector:
matchLabels:
app: backend-api
policyTypes:
- Egress
egress:
# 1. 允许访问同一命名空间的 Redis
- to:
- podSelector:
matchLabels:
app: redis
ports:
- protocol: TCP
port: 6379
# 2. 访问外部 PostgreSQL RDS(基于 CIDR)
- to:
- ipBlock:
cidr: 10.100.0.0/16
ports:
- protocol: TCP
port: 5432
# 3. 允许访问外部 HTTPS API
- to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
ports:
- protocol: TCP
port: 443
# 4. 允许 DNS
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- protocol: UDP
port: 53
控制命名空间之间的通信
在多租户环境中,命名空间之间的隔离是必需的。下面是只允许特定命名空间访问的模式。
# cross-namespace-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-monitoring-access
namespace: production
spec:
podSelector:
matchLabels:
app: backend-api
policyTypes:
- Ingress
ingress:
# 只允许 monitoring 命名空间的 Prometheus 抓取指标
- from:
- namespaceSelector:
matchLabels:
team: monitoring
podSelector:
matchLabels:
app: prometheus
ports:
- protocol: TCP
port: 9090
Network Policy 的局限
Kubernetes 内置的 Network Policy 只能做 L3/L4 层面(IP、端口、协议)的控制。以下需求靠内置的 Network Policy 无法满足:
- 基于 L7(HTTP 路径、方法、请求头)的过滤
- mTLS 加密与服务身份认证
- 流量可观测性(Observability)与分布式追踪
- 高级流量管理(金丝雀发布、熔断、重试)
- 基于 FQDN(域名)的 Egress 控制
当需要这些高级能力时,Service Mesh 就登场了。
Service Mesh 架构对比(Istio vs Cilium vs Calico)
下面对三种主流方案的架构与功能进行对比。
| 项目 | Istio(Ambient Mode) | Cilium Service Mesh | Calico(Enterprise) |
|---|---|---|---|
| 数据平面 | ztunnel(L4) + Waypoint Proxy(L7) | eBPF(L3/L4) + 每节点 Envoy(L7) | iptables/eBPF + Envoy(L7) |
| Sidecar | 不需要(Ambient Mode) | 不需要 | 可选 |
| mTLS | 自动(HBONE 协议) | WireGuard/IPsec | WireGuard 手动配置 |
| L7 策略 | AuthorizationPolicy | CiliumNetworkPolicy | GlobalNetworkPolicy |
| 可观测性 | Kiali、Jaeger、Prometheus | Hubble(内置) | Calico Enterprise UI |
| 性能开销 | 中(经由 ztunnel) | 低(内核层) | 中 |
| CPU 使用量 | 一般 | 少 30%(以 L4 为准) | 一般 |
| QPS 性能 | 高(低连接数时优秀) | 高(高连接数时优秀) | 一般 |
| 多集群 | 支持(East-West Gateway) | 支持 Cluster Mesh | 支持 Federation |
| 学习曲线 | 高 | 中等 | 中等 |
| 社区 | 非常大(CNCF Graduated) | 大(CNCF Graduated) | 大(Tigera 主导) |
| Windows 节点 | 不支持 | 不支持 | 支持 |
| 最佳使用场景 | 大规模多集群、L7 精细控制 | 高性能 L4、基于 eBPF 的可观测 | 混合环境、企业合规要求 |
架构选型标准
- 只需要纯粹的 L3/L4 网络安全:Kubernetes 内置 Network Policy + Calico/Cilium CNI
- L7 流量管理 + mTLS 是核心诉求:Istio Ambient Mode
- 高性能 + 内核层可观测性:Cilium Service Mesh
- 企业合规要求 + 混合环境:Calico Enterprise
基于 Istio 构建 Service Mesh
安装 Istio Ambient Mode
从 Istio 1.24 起,Ambient Mode 正式 GA。相比传统 Sidecar 方式,它把 CPU/内存开销降低了 90% 以上,同时依然提供 mTLS 与 L7 流量管理能力。
# 安装 istioctl
curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.24.2 sh -
export PATH="$HOME/istio-1.24.2/bin:$PATH"
# 以 Ambient profile 安装
istioctl install --set profile=ambient --skip-confirmation
# 确认安装结果
kubectl get pods -n istio-system
# NAME READY STATUS RESTARTS AGE
# istiod-7b69f4b6c-xxxxx 1/1 Running 0 60s
# ztunnel-xxxxx 1/1 Running 0 60s
# istio-cni-node-xxxxx 1/1 Running 0 60s
# 为命名空间启用 Ambient 模式
kubectl label namespace production istio.io/dataplane-mode=ambient
部署 Waypoint Proxy(用于 L7 策略)
如果只需要 L4 层面的 mTLS,仅靠 ztunnel 就足够了。若需要 L7 层面的精细流量控制,则要额外部署 Waypoint Proxy。
# 创建 Waypoint Proxy
istioctl waypoint apply --namespace production --name backend-waypoint
# 把 Waypoint 关联到指定 Service
kubectl label service backend-api \
istio.io/use-waypoint=backend-waypoint \
-n production
配置 Istio AuthorizationPolicy
Istio 的 L7 策略通过 AuthorizationPolicy 控制到 HTTP 方法、路径、请求头级别。
# istio-auth-policy.yaml
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: backend-api-policy
namespace: production
spec:
targetRefs:
- kind: Service
group: ''
name: backend-api
action: ALLOW
rules:
- from:
- source:
principals:
- 'cluster.local/ns/production/sa/frontend'
to:
- operation:
methods: ['GET', 'POST']
paths: ['/api/v1/*']
- from:
- source:
principals:
- 'cluster.local/ns/monitoring/sa/prometheus'
to:
- operation:
methods: ['GET']
paths: ['/metrics']
这条策略只允许 frontend 服务账号对 /api/v1/ 路径发起 GET、POST 请求,只允许 Prometheus 对 /metrics 路径发起 GET 请求。其余所有请求都会被以 403 Forbidden 拒绝。
基于 Cilium 的 eBPF Service Mesh
安装 Cilium 并启用 Service Mesh
Cilium 利用 eBPF 在内核层处理网络。它不需要 Sidecar 代理即可处理 L4 流量,只有在需要 L7 处理时才使用每个节点共享的 Envoy 代理。
# 安装 Cilium CLI
CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt)
GOOS=$(go env GOOS)
GOARCH=$(go env GOARCH)
curl -L --fail --remote-name-all \
"https://github.com/cilium/cilium-cli/releases/download/${CILIUM_CLI_VERSION}/cilium-${GOOS}-${GOARCH}.tar.gz"
sudo tar xzvfC "cilium-${GOOS}-${GOARCH}.tar.gz" /usr/local/bin
# 用 Helm 安装 Cilium(启用 Service Mesh + Hubble)
helm repo add cilium https://helm.cilium.io/
helm repo update
helm install cilium cilium/cilium --version 1.17.0 \
--namespace kube-system \
--set kubeProxyReplacement=true \
--set hubble.enabled=true \
--set hubble.relay.enabled=true \
--set hubble.ui.enabled=true \
--set envoy.enabled=true \
--set encryption.enabled=true \
--set encryption.type=wireguard
# 确认安装结果
cilium status --wait
cilium connectivity test
用 CiliumNetworkPolicy 应用 L7 策略
Cilium 通过自有 CRD CiliumNetworkPolicy,支持 HTTP、gRPC、Kafka 等 L7 协议级别的精细策略。
# cilium-l7-policy.yaml
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: backend-l7-policy
namespace: production
spec:
endpointSelector:
matchLabels:
app: backend-api
ingress:
- fromEndpoints:
- matchLabels:
app: frontend
toPorts:
- ports:
- port: '8080'
protocol: TCP
rules:
http:
- method: 'GET'
path: '/api/v1/products'
- method: 'POST'
path: '/api/v1/orders'
- method: 'GET'
path: '/healthz'
- fromEndpoints:
- matchLabels:
app: prometheus
toPorts:
- ports:
- port: '9090'
protocol: TCP
rules:
http:
- method: 'GET'
path: '/metrics'
用 Hubble 做网络观测
Cilium 的 Hubble 基于 eBPF,可以实时监控所有网络流量。
# 安装 Hubble CLI 后进行观测
hubble observe --namespace production --follow
# 只过滤特定 Pod 的流量
hubble observe --namespace production \
--to-label app=backend-api \
--verdict DROPPED
# 观测 HTTP 请求(L7)
hubble observe --namespace production \
--protocol http \
--http-status 5xx
# 网络流量可视化(Hubble UI)
cilium hubble port-forward &
# 在浏览器中访问 http://localhost:12000
Hubble 的输出示例:
TIMESTAMP SOURCE DESTINATION TYPE VERDICT SUMMARY
Mar 14 10:23:01.123 production/frontend production/backend-api L7/HTTP FORWARDED GET /api/v1/products => 200
Mar 14 10:23:01.456 production/attacker production/backend-api L7/HTTP DROPPED POST /api/v1/admin => Policy denied
Mar 14 10:23:02.789 production/backend-api production/redis L4/TCP FORWARDED TCP 6379
mTLS 与零信任网络
什么是零信任?
零信任(Zero Trust)是一种“不信任任何东西,验证所有东西”的安全模型。它要求集群内部通信也必须加密,并在所有服务间调用中验证身份。由于仅靠 Network Policy 无法加密流量,因此需要提供 mTLS(mutual TLS)的 Service Mesh。
Istio Ambient Mode 的 mTLS
Istio Ambient Mode 使用HBONE(HTTP-Based Overlay Network Environment)协议,把所有流量自动进行 mTLS 加密。ztunnel 在节点层面管理证书,并为每个 Pod 签发唯一的、基于 SPIFFE 的工作负载 ID。
# istio-peer-auth.yaml
# STRICT 模式:拒绝非 mTLS 的明文流量
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
name: strict-mtls
namespace: production
spec:
mtls:
mode: STRICT
设置为 STRICT 模式后,该命名空间内的所有服务只接受 mTLS 连接。来自网格之外服务的明文请求会被全部拒绝。
Cilium 基于 WireGuard 的加密
Cilium 使用内核自带的 WireGuard 自动加密节点之间的流量。与 Istio 的 mTLS 不同,它工作在内核层而非应用层,因此性能开销更小。
# 确认 WireGuard 加密状态
cilium encrypt status
# 输出示例:
# Encryption: Wireguard
# Keys in use: 2
# Errors: 0
# Interfaces: cilium_wg0
# 查看加密密钥列表
cilium encrypt get
WireGuard 与 mTLS 的差异:
- WireGuard:节点之间的 L3 层加密,内核层处理,不为每个 Pod 分配单独身份
- mTLS(Istio):服务之间的 L7 层加密,基于 SPIFFE 的工作负载 ID,可做精细的授权策略
在生产环境中,也有团队采用双重安全策略:先用 Cilium WireGuard 做节点间加密,再叠加 Istio mTLS 实现工作负载级别的身份认证。
运维注意事项与排障
1. 注意 Network Policy 的叠加方式
Network Policy 以并集(additive)方式工作。当多条策略作用于同一个 Pod 时,放行规则会被合并。存在冲突的策略时,并不是拒绝规则优先,而是只要有任意一条放行,流量就会通过。
# 确认作用于特定 Pod 的所有 Network Policy
kubectl get networkpolicy -n production -o wide
# 确认 Pod 标签(验证策略选择器是否匹配)
kubectl get pods -n production --show-labels
# 使用 Calico 时确认策略匹配情况
calicoctl get networkpolicy -n production -o yaml
2. 未安装 CNI 插件时 Network Policy 被忽略
这是最常见的失误。即使创建了 Network Policy 资源,只要没有实现它的 CNI 插件,策略就完全不会生效。
# 确认 CNI 插件
kubectl get pods -n kube-system | grep -E 'calico|cilium|antrea'
# 验证 Network Policy 是否真的生效的测试
# 1. 应用 Default Deny
kubectl apply -f default-deny-all.yaml
# 2. 通信测试(被阻断才是正常)
kubectl exec -n production deploy/frontend -- \
curl -s --connect-timeout 3 http://backend-api:8080/healthz
# 出现超时就说明策略已经正确生效
3. DNS 解析失败
应用 Default Deny 策略后如果漏掉了 DNS 放行,所有服务发现都会中断。
# 诊断 DNS 问题
kubectl exec -n production deploy/frontend -- nslookup backend-api
# ;; connection timed out; no servers could be reached
# 确认 CoreDNS Pod
kubectl get pods -n kube-system -l k8s-app=kube-dns
# 应用 DNS 策略后重新测试
kubectl apply -f allow-dns.yaml
kubectl exec -n production deploy/frontend -- nslookup backend-api
# Server: 10.96.0.10
# Name: backend-api.production.svc.cluster.local
4. 应对 Istio ztunnel 故障
ztunnel 以每节点 DaemonSet 的形式运行,一旦发生故障,该节点上所有 Ambient Mesh 流量都会中断。
# 确认 ztunnel 状态
kubectl get pods -n istio-system -l app=ztunnel
# 确认 ztunnel 日志(诊断证书问题)
kubectl logs -n istio-system -l app=ztunnel --tail=50
# 重启 ztunnel
kubectl rollout restart daemonset/ztunnel -n istio-system
# 确认与 Istiod 的 xDS 连接状态
istioctl proxy-status
5. Cilium eBPF map 容量超限
在大规模集群中,Cilium eBPF map 的默认大小可能不够用。
# 确认 eBPF map 使用量
cilium bpf ct list global | wc -l
cilium bpf policy get --all
# 增大 map 大小(修改 Helm values)
# bpf.ctGlobalTCPMax: 524288 (比默认值更大)
# bpf.ctGlobalAnyMax: 262144
# bpf.policyMapMax: 65536
# 应用变更
helm upgrade cilium cilium/cilium \
--namespace kube-system \
--reuse-values \
--set bpf.ctGlobalTCPMax=524288
故障案例与恢复流程
案例 1:错误的 Egress 策略导致全站服务中断
状况:运维团队为了加强安全应用了 Default Deny Egress,却漏掉了 DNS 放行策略,导致所有服务之间的通信中断。
症状:所有 Pod 通过服务名访问都失败。直接指定 IP 时则可以通信。
恢复流程:
# 1. 立即确认问题
kubectl get networkpolicy -n production
# 2. 紧急应用 DNS 放行策略
kubectl apply -f - <<'POLICY'
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: emergency-allow-dns
namespace: production
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
POLICY
# 3. 确认服务已恢复
kubectl exec -n production deploy/frontend -- nslookup backend-api
教训:Default Deny 策略必须与 DNS 放行策略一起应用。变更策略前一定要在预发环境测试,并准备好回滚方案。
案例 2:Istio 升级过程中的 mTLS 不匹配
状况:在 Istio 版本升级过程中,旧版本 Sidecar 与新版本 ztunnel 之间的 mTLS 握手失败。
症状:部分服务之间出现 503 错误以及“upstream connect error”消息。
恢复流程:
# 1. 把 mTLS 模式临时改为 PERMISSIVE(明文和 mTLS 都允许)
kubectl apply -f - <<'POLICY'
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
name: permissive-during-upgrade
namespace: production
spec:
mtls:
mode: PERMISSIVE
POLICY
# 2. 重启所有工作负载以应用最新代理
kubectl rollout restart deployment -n production
# 3. 所有 Pod 都替换为新版本后恢复 STRICT
kubectl rollout status deployment -n production --timeout=300s
kubectl apply -f - <<'POLICY'
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
name: strict-mtls
namespace: production
spec:
mtls:
mode: STRICT
POLICY
案例 3:Cilium Agent 重启导致瞬时流量丢弃
状况:在更新 Cilium DaemonSet 的过程中,节点上的 eBPF 程序被短暂卸载,导致该节点上 Pod 之间的通信中断了数秒。
恢复与预防:
# 采用 Rolling Update 策略逐个节点更新
helm upgrade cilium cilium/cilium \
--namespace kube-system \
--reuse-values \
--set upgradeCompatibility=1.16 \
--set rollOutCiliumPods=true
# 确认 PodDisruptionBudget
kubectl get pdb -n kube-system
# 监控更新进度
kubectl rollout status daemonset/cilium -n kube-system --timeout=600s
性能基准与选型指南
实测基准结果(2025 年)
下面汇总近期在大规模企业环境中的对比测试结果。
| 指标 | Network Policy Only | Istio Ambient | Cilium Service Mesh |
|---|---|---|---|
| P99 延迟(ms) | 1.2 | 3.8 | 2.1 |
| QPS(请求/秒) | 45,000 | 38,000 | 42,000 |
| QPS per Core | - | 2,178 | 1,815 |
| CPU 开销 | 基准 | +15% | +8% |
| 内存开销 | 基准 | +120MB/节点 | +80MB/节点 |
| 低连接数性能 | - | 优秀 | 一般 |
| 高连接数性能 | - | 一般 | 优秀 |
注意:Istio 的 QPS per Core 较高,是因为该数值包含了 L7 处理能力;而 Cilium 的 CPU 测量中未计入内核内 WireGuard 加密的开销,这一点需要纳入考量。
选型指南流程图
-
是否只需要 L3/L4 网络隔离?
- 是:Kubernetes Network Policy + Calico 或 Cilium CNI 就足够
- 否:进入第 2 步
-
是否需要 L7 流量管理(金丝雀、重试、熔断)?
- 是:Istio Ambient Mode 或 Cilium + Envoy
- 否:进入第 3 步
-
基于 mTLS 的零信任是否为硬性要求?
- 是:Istio Ambient Mode(基于 SPIFFE 的工作负载 ID)
- 否:用 Cilium WireGuard 做节点间加密
-
是否优先考虑高性能 + 内核层可观测性?
- 是:Cilium Service Mesh + Hubble
- 否:Istio(L7 功能更丰富)
-
是否混用 Windows 节点或属于混合环境?
- 是:Calico Enterprise
- 否:Istio 或 Cilium
按运维规模给出的建议
- 小规模集群(10 个节点以下):Cilium CNI + 基础 Network Policy。引入 Service Mesh 的收益不足以抵消其开销。
- 中等规模集群(10~100 个节点):Cilium Service Mesh 或 Istio Ambient,按 L7 需求来选。
- 大规模集群(100 个节点以上):Istio Ambient Mode,多集群支持成熟、生态丰富、稳定性好。
- 混合云/多云:Calico Enterprise 或 Cilium Cluster Mesh。
结语
Kubernetes 网络安全不只是应用 Network Policy 那么简单,还需要一套契合应用特性与安全要求的整体策略。
核心要点:
- Network Policy 是基础中的基础:请务必从 Default Deny 开始,采用只放行必要通信的白名单方式。不要忘记 DNS 放行策略。
- Service Mesh 要在需要时才引入:请在确实需要 mTLS、L7 策略、高级流量管理的时点再引入。不必要的复杂度反而会加重运维负担。
- Istio 与 Cilium 之间是权衡取舍:Istio 的 L7 功能与生态更丰富,Cilium 的强项是内核层性能与可观测性。请结合需求来选择。
- 循序渐进是关键:从 Default Deny 策略开始,充分验证 Network Policy 之后,再按需要追加 Service Mesh,这样的分阶段推进最为稳妥。
- 自动化与测试:策略变更一定要通过 CI/CD 流水线先在预发环境验证,并始终备好回滚方案。
网络安全不是设置一次就一劳永逸的事情。随着服务的演进,策略也需要持续复查和更新。建议每季度做一次策略审计,并利用 Hubble 或 Kiali 这类观测工具,基于真实流量模式来优化策略。
参考资料
현재 단락 (1/412)
在 Kubernetes 集群中,Pod 之间的通信默认处于**全部允许**(allow-all)状态。也就是说,只要在同一个集群内,任何 Pod 都可以自由访问其他 Pod。在小规模的开发环境中这算...