亲眼看网格真的强制了什么
本实验在真正的 Istio 中进行
VM 内实际运行着 k3s + Istio。Sidecar 会真正注入, mTLS 会真正强制执行,VirtualService 也会真正转发流量。
ICA 课程中的其他实验在只加载了 CRD 的模拟集群中进行。在那里,
kubectl apply 只会成功执行,实际却不会发生任何事情。
首次启动需要 2~3 分钟。
目标
确认 Sidecar 被注入到哪里,并根据响应码区分 mTLS 和授权策略 实际阻止了什么。
为什么重要
服务网格的价值不在于“写了配置”,而在于“配置得到强制执行”。 这一主题的陷阱在于,未强制执行的状态看起来也很正常。
最常见的问题是 Sidecar 未注入。在给命名空间添加标签之前
创建的 Pod 没有 Sidecar。Pod 处于 Running 状态,Service 也会响应。
但由于流量不经过服务网格,mTLS、授权策略和路由都不会生效。
这会形成一种安全策略全都写好了,却什么也没有受到保护的状态。
而且,如今连确认方法本身也发生了变化。Istio 现在使用 Kubernetes 的
原生 Sidecar。istio-proxy 不再位于 spec.containers,而是进入
spec.initContainers(使用 restartPolicy: Always)。因此,过去用
kubectl get pod -o jsonpath='{.spec.containers[*].name}' 检查的习惯,
现在即使存在 Sidecar,也会回答不存在。
步骤
- 检查
istioctl version和注入标签,并保存到/root/ica/install.txt。 - 创建
webPod(nginx),确认istio-proxy进入了哪里,并保存到/root/ica/sidecar.txt。必须把spec.containers和spec.initContainers两者都输出。 - 使用
strictPeerAuthentication 将 mTLS 设为 STRICT,分别从网格内外发出请求,并保存到/root/ica/mtls.txt。 - 使用
web-vsVirtualService,让它只对/teapot路径返回 418,并将结果保存到/root/ica/routing.txt。 - 使用
web-authzAuthorizationPolicy 仅允许特定的服务账号,测试允许方和非允许方,并保存到/root/ica/authz.txt。 - 确认工作负载的 SPIFFE 身份,并保存到
/root/ica/identity.txt。 - 保留网格外工作负载(
nomesh命名空间),在/root/ica/outside.txt中说明为什么一次性切换到 STRICT 很危险。 - 在
/root/ica/report.md中写入sidecar_location=、authz_denied_code=、mesh_identity=三行及说明。
参考
- 只有在添加标签之后创建的 Pod 才会注入。已有 Pod 需要执行
kubectl rollout restart或重新创建。 - 对带有 Sidecar 的 Pod 执行
kubectl exec时,最好指定-c <앱컨테이너>。若不指定,其行为会随默认容器而变化。 - Istio 的授权拒绝是 403(
RBAC: access denied)。不满足 mTLS 时,连接本身会被重置,因此没有响应码(curl 会得到000或 exit 56)。区分这两种情况是诊断的关键。 - SPIFFE 身份的格式为
spiffe://cluster.local/ns/<네임스페이스>/sa/<서비스어카운트>。可以用istioctl proxy-config secret <파드>查看证书。 - 常见错误 1:VirtualService 中
http列表的顺序。规则按从上到下的顺序采用首个匹配项,因此把宽泛规则放在上面,会导致下面的规则永远无法匹配。 - 常见错误 2:保留在添加标签前创建的 Pod,然后声称“策略不生效”。如果没有 Sidecar,任何策略都不会生效。
当前运行着什么
检查 istioctl version 和注入标签,并保存到 /root/ica/install.txt。
使用 istioctl version 同时查看控制平面和数据平面的版本。然后检查 default 命名空间的 istio-injection 标签。
Sidecar 被放在哪里
创建 web Pod(nginx),确认 istio-proxy 进入了哪里,并保存到 /root/ica/sidecar.txt。必须把 spec.containers 和 spec.initContainers 两者都输出。
把 .spec.containers 和 .spec.initContainers 两者都输出查看。如今 Istio 使用原生 Sidecar。
STRICT 会真正阻断流量
使用 strict PeerAuthentication 将 mTLS 设为 STRICT,分别从网格内外发出请求,并保存到 /root/ica/mtls.txt。
分别从网格内(带 Sidecar 的 Pod)和网格外(没有 Sidecar 的命名空间)发出请求。从外部请求时,连响应码都不会返回。
规则顺序会改变结果
使用 web-vs VirtualService,让它只对 /teapot 路径返回 418,并将结果保存到 /root/ica/routing.txt。
http 列表按从上到下的顺序采用首个匹配项。把具体规则放在上面,宽泛规则放在下面。
根据身份允许访问
使用 web-authz AuthorizationPolicy 仅允许特定的服务账号,测试允许方和非允许方,并保存到 /root/ica/authz.txt。
在 principals 中使用 SPIFFE 格式的服务账号。拒绝时返回 403。
身份存放在哪里
确认工作负载的 SPIFFE 身份,并保存到 /root/ica/identity.txt。
使用 istioctl proxy-config secret <파드> 查看 Sidecar 持有的证书。SAN 中包含 SPIFFE URI。
为什么不能一次性切换到 STRICT
保留网格外工作负载(nomesh 命名空间),在 /root/ica/outside.txt 中说明为什么一次性切换到 STRICT 很危险。
只要还存在一个网格外工作负载,STRICT 就会立即中断与它的通信。请说明为什么要用 PERMISSIVE 分阶段迁移。
学到了什么
在 /root/ica/report.md 中写入 sidecar_location=、authz_denied_code=、mesh_identity= 三行及说明。
除了 sidecar_location=、authz_denied_code=、mesh_identity= 三行之外,还要写明如何区分两种“无法访问”。