Skip to main content

Command Palette

Search for a command to run...

Istio 安全设置笔记

Updated
2 min read

Istio 为网格中的微服务提供了较为完善的安全加固功能,在不影响代码的前提下,可以从多个角度提供安全支撑,官方文档做了较为详细的介绍,但是也比较破碎,这里尝试做个简介兼索引,实现过程还是要根据官方文档进行。

Istio 的安全功能主要分为三个部分的实现:

  1. 双向 TLS 支持。
  2. 基于黑白名单的访问控制。
  3. 基于角色的访问控制。
  4. JWT 认证支持。

首先回顾一下 Istio 网格中的服务通信过程:

  1. 利用自动或者手工注入,把 Envoy Proxy 注入到每个服务 Pod 中,用 Sidecar 的方式运行。
  2. Pod 初始化过程里,使用 iptables 劫持所在 Pod 的出入流量。
  3. 服务间的通信,从原来的直接通信,转换为现在的 Envoy 之间通信,Envoy 在这里同时作为客户端和服务端负载均衡组件。
  4. Envoy 的工作过程中,可能会和 Mixer、Pilot 以及 Citadel 等组件发生互动。

双向 TLS 支持

双向 TLS 支持主要针对的是通信方面,把明文传输的服务通信,通过转换为 Envoy 之间的加密通信。这一安全设置较为基础,可以在全局、Namespace 或者单个服务的范围内生效。

这一功能主要通过两个 Istio CRD 对象来完成:

Policy

例如 Basic Authentication Policy 中的一个样例,用于给单个服务设置 mtls:

apiVersion: "authentication.istio.io/v1alpha1"
kind: "Policy"
metadata:
  name: "example-2"
spec:
  targets:
  - name: httpbin
  peers:
  - mtls:

其中 target 是可选项,如果去掉的话,作用域将扩展到整个 Namespace。

DestinationRule

同样的一个例子里面的目标规则如下:

apiVersion: "networking.istio.io/v1alpha3"
kind: "DestinationRule"
metadata:
  name: "example-2"
spec:
  host: httpbin.bar.svc.cluster.local
  trafficPolicy:
    tls:
      mode: DISABLE
    portLevelSettings:
    - port:
        number: 1234
      tls:
        mode: ISTIO_MUTUAL

这个也很容易理解,这一规则用于指派对该地址的访问方式:

  • tls.mode = DISABLE,这个服务缺省是不开启 tls 支持的,如果取值 ISTIO_MUTUAL,则代表这个地址(服务)的所有端口都开启 TLS。
  • port...ISTIO_MUTUAL,只针对这一个端口启用 mTLS 支持。

创建 Policy 之后,Citadel 会生成证书文件,并传递给 Envoy,我们可以在 Envoy 容器(kube-proxy)的 /etc/certs/ 目录中看到这几个 *.pem 文件。如果使用 openssl x509 -text -noout 查看 cert-chain.pem 的证书内容,会看到 spiffe 编码的 ServiceAccount 内容来作为 SAN:

 X509v3 Subject Alternative Name:
            URI:spiffe://cluster.local/ns/default/sa/default

规则生效之后,原有的服务间调用是没有差异的,但是如果在网格之外,就必须 https,结合上面谈到的证书来访问目标服务才能完成访问。

另外这里也提供了外部 CA 的支持,可以使用已有的证书体系来替换网格内的自签发体系。

基于黑白名单的访问控制

黑名单

下面的例子来自官方,禁止 Reviews 的 v3 版本访问 Ratings 服务。

首先使用 denier 适配器定义一个拒绝响应

apiVersion: "config.istio.io/v1alpha2"
kind: denier
metadata:
  name: denyreviewsv3handler
spec:
  status:
    code: 7
    message: Not allowed

这里不需要额外属性输入,因此采用了 checknothing 模板:

apiVersion: "config.istio.io/v1alpha2"
kind: checknothing
metadata:
  name: denyreviewsv3request
spec:

最后使用 rule 对象把这两者联系起来,并配合一个表达式来使之生效:

apiVersion: "config.istio.io/v1alpha2"
kind: rule
metadata:
  name: denyreviewsv3
spec:
  match: destination.labels["app"] == "ratings" && source.labels["app"]=="reviews" && source.labels["version"] == "v3"
  actions:
  - handler: denyreviewsv3handler.denier
    instances: [ denyreviewsv3request.checknothing ]

白名单

官方案例设置了一个允许 v2v3 版本访问 ratings 服务的白名单。

白名单适配器要使用的是 listchecker,提供了一个允许访问的数组。

apiVersion: config.istio.io/v1alpha2
kind: listchecker
metadata:
  name: whitelist
spec:
  # providerUrl: 可以从外部 URL 获取列表内容
  overrides: ["v1", "v2"]  # 静态列表
  blacklist: false

需要使用一个模板将 Pod 标签转换为 listchecker 的版本列表。

apiVersion: config.istio.io/v1alpha2
kind: listentry
metadata:
  name: appversion
spec:
  value: source.labels["version"]

最后使用 Rule 进行连接:

apiVersion: config.istio.io/v1alpha2
kind: rule
metadata:
  name: checkversion
spec:
  match: destination.labels["app"] == "ratings"
  actions:
  - handler: whitelist.listchecker
    instances:
    - appversion.listentry

注意:如果开启了 mTLS,可以使用 source.user == "cluster.local/ns/default/sa/bookinfo-productpage" 的形式来匹配 ServiceAccount。

RBAC

Helm 安装时,需要设置 global.rbacEnabled: true

RBAC 提供较细粒度的访问控制。另外其中所使用的 ServiceRoleServiceRoleBinding 也更直观、更加易于管理。

例如来自官方 TaskServiceRole 定义,这个角色允许对指定服务进行只读访问:

apiVersion: "config.istio.io/v1alpha2"
kind: ServiceRole
metadata:
  name: productpage-viewer
  namespace: default
spec:
  rules:
  - services: ["productpage.default.svc.cluster.local"]
    methods: ["GET"]

如果在 Namespace 级别进行设置,则可以这样:

...
  rules:
  - services: ["*"]
    methods: ["GET"]
    constraints:
    - key: "app"
      values: ["productpage"]
...

和 Kubernetes 的 Rolebinding 类似,把用户和角色绑定起来,才能最后生效。

例如:

  - user: alice@yahoo.com

或者

  - properties:
      service: "reviews"
      namespace: "abc"

subject 的内容,同样属于 Adapter 模型的实现范围,因此其可选项目仍然是由 Template 的输入产生的。具体样例可以参考 bookinfo 的 rbac 样板

JWT 认证

没有外部认证的需求,因此就先不理了 lol。

参考链接:

  1. 安全任务:https://istio.io/docs/tasks/security
  2. Istio RBAC 参考:https://istio.io/docs/reference/config/istio.rbac.v1alpha1/
  3. Istio Adapters 参考:https://istio.io/docs/reference/config/policy-and-telemetry/adapters/
  4. Bookinfo 示例:https://github.com/istio/istio/blob/release-0.8/samples/bookinfo/kube/

More from this blog

龙虾恐慌:AIOps 又要改名了?

ChatGPT 开始,把 AI 拉近到普罗大众的面前,让无数人感受到 AI 的亲民魅力。而龙虾,则把大模型驱动的自动化能力,突然间变得水灵灵、活泼泼地走进千家万户。它不只是“风口上的猪”,而是风口本身。热度高到让 Mac mini 一度断货,不知道这在不在库克的预料之内。 每代人都有每代人的鸡蛋,春节期间,我就领了我的鸡蛋。翻出古老的 MacBook Air M1,充值各种大模型。当然了,这个工具

Mar 9, 20261 min read

再见 2025

我猜不少人以为这个号废了吧?并没有,只是今年变化有点大,一直有种抄起键盘,无从说起的感觉,所以一直偷懒到今天,2025 的最后一天。 今年是我的第四个本命年,去年末一期播客里,大内说本命年不是灾年,是变化年,有危也有机。可是讲真啊,只看到危,没看到机。 各种因缘际会,从鹅厂跳槽到前东家,已经接近四年,第一个合同期已经进入尾声。除了前两年还在云原生领域嗷嗷叫,后两年基本都是些鸡零狗碎的东西了,用老东家的术语说是——偏离主航道,可谓是前景暗淡了。 一旦确定要滚蛋,反倒心思轻松起来,每天骑着我的小红车...

Jan 5, 20261 min read

辅助编程?dora 说:我知道你很急可是请你别急

从 OpenGPT 把大模型的火烧旺了之后,这三年来,相信很多组织或摩拳擦掌、或躬身入局,希望借助聪明能干的大模型,或想偿还技术宅,或想降本增效,或想弯道超车。一时间,沉寂许久的 AIxx 又活过来了,LLM Ops、Vibe Coding、中医大模型、GPT 算命等等,全都老树发新芽,焕发了勃勃生机。那么视角拉回从业者最关注的饭碗相关的领域之一——AI 辅助开发,产生了什么触动,应该如何拥抱呢? DORA 的年度报告中给出了很有意思的结论——强者恒强。 执行摘要部分总结了几个有趣的点: 问题...

Oct 6, 20251 min read

[译]dora:ai 辅助软件开发状态报告

执行摘要 在 2025 年,科技领导者面临的核心问题已不再是“是否要采用 AI”,而是“如何实现其价值”。 DORA 的研究基于超过 100 小时的定性访谈和来自全球近 5,000 名技术专业人士的问卷调查。研究揭示了一个关键事实:AI 在软件开发中的主要角色是“放大器”。它会放大高效能组织的优势,也会凸显组织的缺陷。 关键结论:AI 是放大器 AI 投资的最大回报并非来自工具本身,而是来自组织底层系统的战略性建设: 高质量的内部平台 清晰的工作流 团队的协同能力 缺少这些基础,AI ...

Oct 2, 202514 min read

僭越了,有人在用 Rust 写 Kubernetes

一个新语言问世,最爱做的事情之一,就是重写存量软件了。 云原生喝酒 SIG 重点扶持项目——rk8s(https://github.com/rk8s-dev/rk8s) 也可以归在这个范畴里,只不过这个项目重写的东西比较大,是 Kubernetes。 从 2025 年 1 月第一个 Commit 开始,到现在有了 200 多次 Commit,十几万行代码。当然距离 Kubernetes 的几百万行代码还差得远——老马就是喜欢整这种大无畏项目。 另外该项目也是国内第一个脱离 Cargo 转向使用 ...

Sep 27, 20253 min read

【伪】架构师

342 posts