12、微服务通信安全与服务网格可观测性

微服务通信安全与服务网格可观测性

1. 微服务通信安全

1.1 部署与 mTLS 配置

在微服务通信中,为了确保通信的安全性,我们需要进行一系列的配置。首先,部署 httpbin Pod、Ingress 网关和虚拟服务:

$ kubectl apply -f Chapter6/02-httpbin-deployment-MTLS.yaml

为了实现 mTLS,还需要生成客户端证书以证明客户端的身份,具体步骤如下:

$ openssl req -out bootstrapistio.packt.com.csr -newkey rsa:2048 -nodes -keyout bootstrapistio.packt.com.key -subj "/CN= bootstrapistio.packt.com/O=packt.com"
$ openssl x509 -req -sha256 -days 365 -CA sock.inc.crt -CAkey sock.inc.key -set_serial 0 -in bootstrapistio.packt.com.csr -out bootstrapistio.packt.com.crt

通过在请求中传递客户端证书来测试与 httpbin.org 的连接:

% curl -v -HHost:httpbin.org --connect-to "httpbin.org:443:a816bb2638a5e4a8c990ce790b47d429-1565783620.us-east-1.elb.amazonaws.com" --cacert sock.inc.crt --cert bootstrapistio.packt.com.crt --key bootstrapistio.packt.com.key https://httpbin.org:443/get

完成操作后,不要忘记清理资源:

kubectl delete -n istio-system secret httpbin-credential
kubectl delete -f Chapter6/02-httpbin-deployment-MTLS.yaml

1.2 配置请求认证(RequestAuthentication)

Istio 不仅可以实现服务到服务的认证,还能对终端用户进行认证。RequestAuthentication 策略用于指定工作负载支持的认证方法,它会识别经过认证的身份,但不强制决定请求是否被允许,而是将认证身份信息提供给授权策略。下面我们将配置 Auth0 并执行 OAuth 流程,具体步骤如下:
1. 注册 Auth0 账号。
2. 注册成功后,在 Auth0 中创建一个应用程序。
3. 创建应用程序后,创建一个 API,并提供 Ingress URL 作为标识符。
4. 声明 API 消费者访问该 API 所需的权限。
5. 从通用设置中为 API 启用基于角色的访问控制(RBAC)。
6. 创建 API 后,返回应用程序并授权该应用程序访问 EnvoyDummy API,同时配置作用域。
7. 最后,前往应用程序页面获取用于获取访问令牌的请求。复制包含 client_id、client_secret 等的 curl 字符串。

使用复制的 curl 字符串从终端获取访问令牌:

$ curl --request POST --url https://dev-0ej7x7k2.us.auth0.com/oauth/token --header 'content-type:application/json' --data '{"client_id":"XXXXXX-id","client_secret":"XXXXX-secret","audience":"http://a816bb2638a5e4a8c990ce790b47d429-1565783620.us-east-1.elb.amazonaws.com/","grant_type":"client_credentials"}'

获取访问令牌后,应用 RequestAuthentication 策略:

apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
  name: "auth0"
  namespace: chapter6
spec:
  selector:
    matchLabels:
      name: envoydummy
  jwtRules:
  - issuer: "https://dev-0ej7x7k2.us.auth0.com/"
    jwksUri: "https://dev-0ej7x7k2.us.auth0.com/.well-known/jwks.json"

在使用 RequestAuthentication 策略时,最好同时配置 RequestAuthentication 和 AuthorizationPolicy,并强制执行不允许空主体请求的规则。以下是一个示例授权策略:

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: auth0-authz
  namespace: chapter6
spec:
  action: DENY
  selector:
    matchLabels:
      name: envoydummy
  rules:
  - from:
    - source:
        notPrincipals: ["*"]

1.3 配置请求授权(RequestAuthorization)

在前面的部分,我们配置了 RequestAuthentication 策略来验证 JWT 令牌。在这一部分,我们将学习如何利用认证策略提供的信息来授权客户端访问服务器。

为了让 curl 使用 Auth0 颁发的访问令牌访问 envoy dummy,需要创建一个 AuthorizationPolicy:

apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
  name: "envoydummy-authz-policy"
  namespace: utilities
spec:
  action: ALLOW
  selector:
    matchLabels:
      name: envoydummy
  rules:
  - when:
    - key: request.auth.claims[permissions]
      values: ["read:profile"]

AuthorizationPolicy 包含以下数据:
| 字段 | 描述 |
| ---- | ---- |
| action | 定义请求匹配规则时要采取的操作类型,可能的值为 ALLOW、DENY 和 AUDIT。 |
| selector | 定义此策略应应用于哪些工作负载,提供一组标签,这些标签应与工作负载的标签匹配以成为选择的一部分。 |
| rules | 定义一组应与请求匹配的规则,包含 source(请求来源规则)、to(请求相关规则,如目标主机、方法名、请求的资源等)和 when(指定额外条件列表)。 |

在应用更改之前,确保可以访问虚拟数据,并确保 Ingress 网关和 envoydummy Pod 已部署在 utilities 命名空间中。如果未部署,可以使用以下命令:

$ curl -Hhost:mockshop.com http://a816bb2638a5e4a8c990ce790b47d429-1565783620.us-east-1.elb.amazonaws.com/

应用两个策略:

% kubectl apply -f Chapter6/01-requestAuthentication.yaml
% kubectl apply -f Chapter6/02-requestAuthorization.yaml

测试访问 mockshop.com:

% curl -Hhost:mockshop.com http://a816bb2638a5e4a8c990ce790b47d429-1565783620.us-east-1.elb.amazonaws.com/

由于需要在请求中提供有效的访问令牌,因此访问会被拒绝。复制之前获取的访问令牌并再次尝试:

$ curl -Hhost:mockshop.com -H "authorization: Bearer xxxxxx-accesstoken " http://a816bb2638a5e4a8c990ce790b47d429-1565783620.us-east-1.elb.amazonaws.com/

由于 RBAC 控制,请求仍然失败。将规则中的 read:dummyData 改为 read:profile 并更新配置:

% kubectl apply -f Chapter6/03-requestAuthorization.yaml

再次测试:

$ curl -Hhost:mockshop.com -H "authorization: Bearer xxxxxx-accesstoken " http://a816bb2638a5e4a8c990ce790b47d429-1565783620.us-east-1.elb.amazonaws.com/

接下来,我们将修改 curl Pod 以使用不同的服务账户 chapter6sa:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: chapter6sa
  namespace: utilities

由于无法更改现有 Pod 的服务账户,需要删除之前的部署并重新部署:

Kubectl delete -f Chapter6/01-curl-deployment.yaml
kubectl apply -f Chapter6/02-curl-deployment.yaml

创建一个 AuthorizationPolicy,允许请求者主体为 cluster.local/ns/utilities/sa/curl 的请求访问 httpbin Pod:

apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
  name: "httpbin-authz-policy"
  namespace: chapter6
spec:
  action: ALLOW
  selector:
    matchLabels:
      app: httpbin
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/utilities/sa/curl"]
  - to:
    - operation:
        methods: ['*']

在 source 配置中,可以定义以下字段:
| 字段 | 描述 |
| ---- | ---- |
| principals | 从 mTLS 期间的客户端证书派生的接受身份列表,格式为 /ns/ /sa/ 。 |
| notPrincipals | 不接受请求的身份列表,派生方式与 principals 相同。 |
| requestPrincipals | 接受的身份列表,请求主体从 JWT 派生,格式为 / 。 |
| notRequestPrincipals | 不接受请求的身份列表,主体从 JWT 派生,格式为 / 。 |
| namespaces | 接受请求的命名空间列表,从对等证书详细信息派生。 |
| notNamespaces | 不允许请求的命名空间列表,从对等证书详细信息派生。 |
| ipBlocks | 接受请求的 IP 或 CIDR 块列表,从 IP 数据包的源地址填充。 |
| notIpBlocks | 拒绝请求的 IP 块列表。 |
| remoteIpBlocks | 从 X-Forwarded-For 标头或代理协议填充的 IP 块列表。 |
| notRemoteIpBlocks | remoteIpBlocks 的否定列表。 |

应用配置并测试是否可以访问 httpbin:

$ kubectl apply -f Chapter6/04-httpbinAuthorizationForSpecificSA.yaml
$ kubectl exec -it curl -n utilities -- curl -v http://httpbin.chapter6.svc.cluster.local:8000/headers

由于 curl Pod 呈现的对等证书中的主体为 cluster.local/ns/utilities/sa/chapter6sa,而不是 cluster.local/ns/utilities/sa/curl,因此请求被拒绝。可以使用以下命令修复问题:

$ kubectl delete -f Chapter6/02-curl-deployment.yaml
$ kubectl apply -f Chapter6/03-curl-deployment.yaml

我们再实现一个授权策略,该策略将强制使用 utilities 或 curl 服务账户的请求者只能访问 httpbin 的 /headers:

apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
  name: "httpbin-authz-policy"
  namespace: chapter6
spec:
  action: ALLOW
  selector:
    matchLabels:
      app: httpbin
  rules:
  - from:
    - source:
        requestPrincipals: ["cluster.local/ns/utilities/sa/curl"]
  - to:
    - operation:
        methods: ["GET"]
        paths: ["/get"]

在这个策略中,to 字段包含了 HTTP 方法和 HTTP 路径的定义。operation 字段支持以下参数:
| 参数 | 描述 |
| ---- | ---- |
| hosts | 指定接受请求的主机名列表,如果未设置,则允许任何主机。 |
| notHosts | 主机的否定列表。 |
| ports | 接受请求的端口列表。 |
| notPorts | 端口的否定匹配列表。 |
| methods | HTTP 请求中指定的方法列表,如果未设置,则允许任何方法。 |
| notMethods | HTTP 请求中指定的方法的否定匹配列表。 |
| paths | HTTP 请求中指定的路径列表,路径将根据 https://istio.io/latest/docs/reference/config/security/normalization/ 进行规范化。 |
| notPaths | 路径的否定匹配列表。 |

应用更改:

kubectl apply -f Chapter6/05-httpbinAuthorizationForSpecificPath.yaml

尝试访问 httpbin:

kubectl exec -it curl -n utilities -- curl -X GET -v http://httpbin.chapter6.svc.cluster.local:8000/headers

由于授权策略只允许使用 HTTP GET 方法的 /get 请求,因此访问会被拒绝。正确的请求如下:

kubectl exec -it curl -n utilities -- curl -X GET -v http://httpbin.chapter6.svc.cluster.local:8000/get

1.4 总结

通过以上步骤,我们完成了微服务通信的安全配置,包括:
1. 配置 Auth0 作为认证提供者和 OAuth 服务器。
2. 创建 RequestAuthentication 策略来验证请求中提供的承载令牌。
3. 创建 AuthorizationPolicy 来验证 JWT 令牌中呈现的声明,并根据声明是否匹配所需值来决定是否允许请求通过。

2. 服务网格可观测性

2.1 理解可观测性

使用微服务架构构建的分布式系统复杂且不可预测,故障、崩溃、内存泄漏等问题很可能发生。主动观察系统以识别潜在问题是处理此类事件的最佳策略。可观测性是指基于系统的信号和外部输出观察来理解系统内部状态的能力,它可以帮助我们理解系统行为和故障背后的根本原因,从而更有信心地进行故障排除和分析潜在修复的效果。

在 IT 领域,系统通常指软件系统,控制器可以是其他软件系统或人工操作员,如站点可靠性工程师(SRE)。他们依赖可观测系统提供的测量数据。如果希望软件系统具有弹性和自我调节能力,那么系统的各个部分都应该是可观测的。

遥测数据是用于系统可观测性的数据,通常包括日志、事件跟踪和指标:
| 类型 | 描述 |
| ---- | ---- |
| 日志 | 软件系统以详细格式发出的信息,通常由应用程序发出,开发人员可通过关联日志与发出日志的代码块来进行故障排除。日志可以是结构化的,也可以是非结构化的,Istio 会生成每个请求的完整记录,包括源和目标元数据。 |
| 跟踪 | 在分布式系统或应用程序中,跟踪用于查找请求或活动如何在多个组件中处理和执行。跟踪由描述系统内执行/软件处理的跨度组成,多个跨度组合在一起提供请求执行的跟踪信息。Istio 为每个服务生成分布式跟踪跨度,提供请求流和各种服务之间的依赖关系详细信息。 |
| 指标 | 特定时间段内内部值的数值测量,用于聚合大量数据,并在一段时间间隔内使用这些数据进行分析。 |

graph LR
    A[系统] --> B[信号和外部输出]
    B --> C[控制器]
    C --> D[补偿控制]
    D --> A

以上是关于微服务通信安全与服务网格可观测性的部分内容,后续还将介绍如何使用 Prometheus 进行指标抓取、自定义 Istio 指标、使用 Grafana 可视化遥测数据以及实现分布式跟踪等内容。

2.2 指标抓取使用 Prometheus

Prometheus 是一个开源的系统监控和警报工具包,可用于从 Istio 中抓取指标。以下是使用 Prometheus 进行指标抓取的一般步骤:

  1. 安装 Prometheus :可以通过 Helm 等工具进行安装。
  2. 配置 Prometheus 以抓取 Istio 指标 :需要在 Prometheus 的配置文件中添加 Istio 相关的抓取任务。例如:
scrape_configs:
  - job_name: 'istio-mesh'
    kubernetes_sd_configs:
      - role: endpoints
    relabel_configs:
      - source_labels: [__meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
        action: keep
        regex: istio - pilot;http - monitor
  1. 启动 Prometheus :安装和配置完成后,启动 Prometheus 服务。
  2. 验证指标抓取 :访问 Prometheus 的 Web 界面(通常为 http://<prometheus_ip>:9090 ),在查询框中输入 Istio 相关的指标名称,如 istio_requests_total ,查看是否能获取到指标数据。

2.3 自定义 Istio 指标

Istio 允许用户自定义指标以满足特定的监控需求。以下是自定义 Istio 指标的步骤:

  1. 定义指标模板 :创建一个指标模板,指定指标的名称、标签、类型等信息。例如:
apiVersion: telemetry.istio.io/v1alpha1
kind: Metrics
metadata:
  name: custom - metric
  namespace: istio - system
spec:
  metrics:
    - name: custom_requests_total
      dimensions:
        source_service: source.service
        destination_service: destination.service
      value: '1'
      tags:
        - tag: source_service
        - tag: destination_service
      metricType: COUNTER
  1. 应用指标模板 :使用 kubectl apply 命令将指标模板应用到集群中。
kubectl apply -f custom - metric.yaml
  1. 配置遥测策略 :关联自定义指标到遥测策略,确保指标被正确收集。
apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
  name: custom - telemetry
  namespace: istio - system
spec:
  metrics:
    - providers:
        - name: prometheus
      overrides:
        - match:
            context: ANY
          metrics:
            - name: custom_requests_total
              dimensions:
                source_service: source.service
                destination_service: destination.service
  1. 验证自定义指标 :在 Prometheus 中查询自定义指标,确保数据被正确收集。

2.4 可视化遥测数据使用 Grafana

Grafana 是一个流行的开源可视化工具,可用于将从 Istio 收集的遥测数据进行可视化展示。以下是使用 Grafana 可视化 Istio 遥测数据的步骤:

  1. 安装 Grafana :可以通过 Helm 等方式进行安装。
  2. 配置数据源 :在 Grafana 中配置 Prometheus 作为数据源,以便从 Prometheus 获取指标数据。
    • 登录 Grafana 界面(通常为 http://<grafana_ip>:3000 )。
    • 点击左侧菜单中的 “Configuration” -> “Data Sources”。
    • 点击 “Add data source”,选择 Prometheus。
    • 配置 Prometheus 的 URL(如 http://<prometheus_ip>:9090 ),然后保存配置。
  3. 创建仪表盘 :使用 Grafana 的仪表盘功能创建可视化面板。
    • 点击左侧菜单中的 “Create” -> “Dashboard”。
    • 点击 “Add panel”,选择要展示的指标,如 istio_requests_total
    • 配置面板的样式、图表类型等,然后保存面板。
    • 可以继续添加更多的面板,以展示不同的指标和数据。

2.5 实现分布式跟踪

分布式跟踪可以帮助我们理解请求在分布式系统中的流动和性能。Istio 支持与 Jaeger 等分布式跟踪系统集成。以下是实现分布式跟踪的步骤:

  1. 安装 Jaeger :可以通过 Helm 等方式进行安装。
  2. 配置 Istio 以启用分布式跟踪 :在 Istio 的配置中启用分布式跟踪,并指定 Jaeger 的地址。
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  values:
    tracing:
      enabled: true
      provider: jaeger
      sampling: 100
      zipkin:
        address: jaeger - collector.istio - system.svc.cluster.local:9411
  1. 部署应用程序 :部署包含 Istio 代理的应用程序,确保请求能够被跟踪。
  2. 查看跟踪数据 :访问 Jaeger 的 Web 界面(通常为 http://<jaeger_ip>:16686 ),在界面中输入服务名称或跟踪 ID 等信息,查看请求的跟踪数据。

2.6 总结

通过以上内容,我们了解了服务网格可观测性的重要性以及相关的实现方法。具体包括:
1. 理解了可观测性的概念以及遥测数据的类型(日志、跟踪、指标)。
2. 学会了使用 Prometheus 从 Istio 中抓取指标。
3. 掌握了自定义 Istio 指标的方法。
4. 能够使用 Grafana 对 Istio 的遥测数据进行可视化展示。
5. 实现了分布式跟踪,通过与 Jaeger 集成,更好地理解请求在分布式系统中的流动。

通过对微服务通信安全和服务网格可观测性的学习和实践,我们可以构建更加安全、可靠和可维护的微服务架构。在实际应用中,可以根据具体需求进一步调整和优化相关配置,以满足业务的发展和变化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值