LabHub
学习 学习路径 课程

ICA — Istio 认证助理

ICA 模拟考 A

在 LabHub 中继续学习

这是 ICA 模拟考试 A。限时 120 分钟,共 17 道题,合格线为 68%。 采用部分计分制,因此遇到卡住的题目,最好先跳过,稍后再回来处理。

这是模拟考试,请不要查看提示和答案,先独立完成全部题目。 因为时间不足而没做完,与因为不会而没做完,是两类不同的问题;只有区分两者, 才能决定下一步该学习什么。请完成并评分后再展开提示。

真实考试环境

考试期间可以查看 istio.io/docsistio.io/blogkubernetes.io/docs。 允许通过 istio.io/search/ 在文档站内搜索,但不能点击外部搜索结果。 k 别名、bash 自动补全以及 istioctl 自动补全都已配置。每道题需要通过 ssh 连接到指定主机操作,不支持嵌套 ssh。终端复制使用 Ctrl+Shift+C, 粘贴使用 Ctrl+Shift+V

本模拟考试环境

直接在 Pod 内的单人集群中操作(不需要 ssh)。kube-apiserver 是真实的,因此错误清单 会被实际拒绝,但 Sidecar 不会启动,也不会有真实流量。评分器会重新读取你留在集群中的配置。

第 1 题是后续大多数题目的前提。在 Istio 资源类型注册之前,kubectl apply 不会接受 VirtualService。请先完成它。


1. 生成默认 profile 的 Istio 安装清单,保存到 /root/ica/install/manifest.yaml。 然后只筛选清单中的 CustomResourceDefinition 并注册到集群。本环境不会启动 istiod Pod, 因此只需要 API 类型。

2. 创建三个命名空间并添加 Sidecar 注入标签。

3. 在 Pod 级别反转命名空间的决定。两个 Deployment 均为 1 个副本,镜像为 nginx:1.27-alpine

4.ica-shop 中部署三个版本的 reviews 服务并定义 subset。

5.ica-shop 中创建 VirtualService reviews。host 为 reviews.ica-shop.svc.cluster.local,使用一条无条件规则,将 80 分配给 subset v1, 20 分配给 subset v2

6. 在第 5 题的 VirtualService reviews 前面再添加两条规则,共三条。 顺序属于评分内容。

  1. 请求头 end-user 精确等于 tester 时路由到 subset v3
  2. uri 前缀为 /api/v2 且方法同时为 GET 时路由到 subset v2
  3. 第 5 题的加权规则作为最后一条无条件规则保留

7. 为同一个 VirtualService reviews 的最后一条(无条件)规则添加弹性配置。 总超时为 2s,重试 3 次,每次尝试超时 500ms,重试条件为 5xxresetconnect-failure

8. 为 DestinationRule reviewstrafficPolicy 添加上限和异常检测。

9.ica-shop 中建立入口。

10. 在整个服务网格中强制 mTLS,但为旧命名空间设置例外。

11. 只把 ica-legacylegacy-api 工作负载升级为 STRICT,但为 8080 端口设置例外。 PeerAuthentication 名称为 legacy-api,selector 为 app: legacy-apimtls.modeSTRICTportLevelMtls 的 8080 为 DISABLE

12.ica-shop 中创建两条授权策略。两者的 selector 都是 app: reviews

13.ica-shop 中的 app: reviews 工作负载添加 JWT 验证。

14. 某团队准备在 ica-fix 命名空间中使用下面的 VirtualService,但目前执行 istioctl analyze 会报错。诊断并补齐缺失内容,使 istioctl analyze -n ica-fix 不再产生任何 Error。

apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: payments
  namespace: ica-fix
spec:
  hosts:
    - payments.ica-fix.svc.cluster.local
  http:
    - route:
        - destination:
            host: payments.ica-fix.svc.cluster.local
            subset: stable

需要补充的规格如下。Deployment payments 的 Pod 标签为 app=paymentsversion=v1; Service payments 的端口为 9090,端口名称为 http;DestinationRule payments 以上述 FQDN 作为 host,并将 subset stable 定义为 version: v1。不要在该命名空间中留下 与题目无关的资源,否则 analyze 也会将其报告出来。

15.ica-triage 命名空间应用下面的 VirtualService 后,即使添加 x-beta: true 请求头,也总是路由到 stable。请诊断原因并应用修复,仍然保留两条规则。

apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: checkout
  namespace: ica-triage
spec:
  hosts:
    - checkout.ica-triage.svc.cluster.local
  http:
    - route:
        - destination:
            host: checkout.ica-triage.svc.cluster.local
            subset: stable
    - match:
        - headers:
            x-beta:
              exact: "true"
      route:
        - destination:
            host: checkout.ica-triage.svc.cluster.local
            subset: beta

16. 应用下面的策略后,ica-triage 中的 payments 工作负载拒绝了所有请求。 诊断原因并修复,使其只允许 cluster.local/ns/ica-triage/sa/frontend 通过 POST 访问 /pay*

apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: payments-allow
  namespace: ica-triage
spec:
  selector:
    matchLabels:
      app: payments
  action: ALLOW
  rules: []

17.ica-triage 中放置下面两个资源后,所有调用 orders 的客户端都失败。 保持服务器端要求不变,只修复客户端设置。

apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
  name: default
  namespace: ica-triage
spec:
  mtls:
    mode: STRICT
---
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
  name: orders
  namespace: ica-triage
spec:
  host: orders.ica-triage.svc.cluster.local
  trafficPolicy:
    tls:
      mode: DISABLE

第 15~17 题无需在 ica-triage 中创建工作负载,需要修复的是配置。

在集群中注册服务网格 API 类型

istioctl manifest generate 把 Chart 内置在二进制文件中,因此无需互联网也能运行。输出还包含 istiod 和 Service,但本环境只需要 CRD,请按 kind 过滤。应用时使用 --server-side。Istio CRD 的注解很大,会超过普通 apply 的 last-applied-configuration 上限(262144 字节)。

按命名空间设置 Sidecar 注入标签

revision 标签与 istio-injection 标签同时存在时,istio-injection 优先。因此迁移 revision 时若不删除旧标签,新 revision 会被静默忽略。删除时在标签名称后加减号。

在 Pod 级别反转注入决定

sidecar.istio.io/inject 应放在 Pod 模板标签中,不是 Deployment 自身的标签或注解。值必须是带引号的字符串。Kubernetes 标签值只接受字符串,不加引号会被 apiserver 拒绝。

创建各版本工作负载与 subset

如果 Service selector 包含 version,就只会选中一个版本,无法进行加权分流。区分版本由 DestinationRule 的 subset 完成。subset 的 labels 必须与 Pod 标签逐字一致,而不是 subset 名称;spec.host 请使用 FQDN 而非短名称。Service 端口名称是 Istio 判断协议的依据。

按权重进行 80 比 20 分流

权重放在 route 数组各 destination 上,总和必须为 100。该规则不要设置 match。后续题目会把条件规则放在它前面,无条件规则必须始终位于最后。

把具体规则放在 catch-all 前面

规则自上而下评估,第一个匹配获胜。无条件规则位于最前时,后续规则永远不会被评估。要把两个条件按 AND 组合,必须并列写在同一个 match 块中;拆成两个块就会成为 OR。

协调超时与重试的关系

timeout 是包含重试的总截止时间。perTryTimeout 乘以尝试次数超过 timeout 时,最后一次尝试尚未开始就会被截断。此处 500ms × 3 为 1.5 秒,可容纳在 2 秒内。retryOn 是逗号连接的字符串,留空就没有定义针对哪些失败重试。

设置连接池上限与异常检测

两者都位于同一个 trafficPolicy 中,但作用不同。connectionPool 限制本端发出的负载,outlierDetection 在对端实例持续返回 5xx 时暂时将其移除。未写 maxEjectionPercent 时该字段不会保存,因此请显式指定。注意不要删除前题创建的 loadBalancer

建立入口网关

Gateway 只开放端口,不负责路由。若未在 VirtualService 的 spec.gateways 中写入名称进行绑定,该规则只作用于服务网格内部,外部请求会收到 404。httpsRedirect 放在 80 端口 server 的 tls 下。证书由网关 Pod 在其命名空间中通过 credentialName 查找。

服务网格全局 STRICT 与命名空间例外

PeerAuthentication 有三个作用层级。无 selector 且位于根命名空间(istio-system)时作用于整个服务网格;无 selector 但位于其他命名空间时作用于整个命名空间;有 selector 时作用于工作负载。范围更窄的策略优先。给全局策略添加 selector 后,它就不再是全局策略。

为工作负载 STRICT 设置端口例外

portLevelMtls 只在具有 selector 的工作负载策略中生效。没有 selector 时 apiserver 会拒绝。这里填写的是 Pod 容器端口,而不是 Service 端口。填写 Service 端口会导致例外完全不生效,而且不会产生任何错误。

分别编写 ALLOW 与 DENY 策略

DENY 先于 ALLOW 评估,只要命中就立即结束。评估顺序是 CUSTOM、DENY、ALLOW。principal 是服务账号的 SPIFFE 身份,格式为 cluster.local/ns/<네임스페이스>/sa/<서비스계정>。路径末尾的星号表示前缀匹配。

同时设置 JWT 验证与令牌要求

RequestAuthentication 只会在存在令牌时验证,没有令牌的请求会直接通过。若要强制令牌,必须同时设置使用 requestPrincipals 的 AuthorizationPolicy。requestPrincipals 由 issuer 与 subject 以斜杠连接;只限制签发者时,将后半部分设为星号。

补齐 analyze 发现的缺失项

先运行 istioctl analyze -n ica-fix,阅读它找不到什么。IST0101 表示无法找到所引用的 host,或 host 与 subset 的组合。Service 不存在与 DestinationRule 缺少 subset 都会产生同一代码。逐项补齐并重新运行,可看到剩余问题逐步减少。

恢复无法到达的规则

规则自上而下评估,第一个匹配获胜。无条件规则匹配所有请求,因此位于最前时,后续规则永远不会被评估。该配置不会报错且仍然有效,只能靠人工查看发现。

修复阻止所有请求的空 ALLOW 策略

只要某工作负载匹配任意 AuthorizationPolicy,它就会切换为默认拒绝。在这种状态下,ALLOW 规则为空意味着没有请求可以匹配规则,因此全部被拒绝。没有策略与存在空策略会产生完全相反的结果。

修复与服务器要求不一致的客户端 TLS

PeerAuthentication 决定服务器接受什么,DestinationRule 的 trafficPolicy.tls 决定客户端如何连接。服务器为 STRICT 而客户端为 DISABLE 时,客户端会使用明文连接并被断开。两者本身都是有效配置,不会产生错误,这正是故障难排查的原因。请选择由 Sidecar 代管证书的模式。