×

如果您的服务网格应用程序由复杂的微服务数组构成,您可以使用 Red Hat OpenShift Service Mesh 来定制这些服务之间通信的安全性。Red Hat OpenShift Service on AWS 的基础架构以及 Service Mesh 的流量管理功能可帮助您管理应用程序的复杂性并保护微服务。

开始之前

如果您有项目,请将您的项目添加到 ServiceMeshMemberRoll 资源

如果您没有项目,请安装 Bookinfo 示例应用程序 并将其添加到 ServiceMeshMemberRoll 资源。示例应用程序有助于说明安全概念。

关于互通传输层安全 (mTLS)

互通传输层安全 (mTLS) 是一种允许双方相互验证身份的协议。它是某些协议(IKE、SSH)中的默认身份验证模式,在其他协议(TLS)中则可选。您可以使用 mTLS 而无需更改应用程序或服务代码。TLS 完全由服务网格基础架构和两个 sidecar 代理之间处理。

默认情况下,Red Hat OpenShift Service Mesh 中的 mTLS 已启用并设置为宽松模式,其中 Service Mesh 中的 sidecar 既接受纯文本流量,也接受使用 mTLS 加密的连接。如果您的网格中配置为使用严格 mTLS 的服务正在与网格外部的服务通信,则这些服务之间的通信可能会中断,因为严格的 mTLS 要求客户端和服务器都能够验证彼此的身份。在将工作负载迁移到 Service Mesh 时,请使用宽松模式。然后,您可以跨网格、命名空间或应用程序启用严格的 mTLS。

在服务网格控制平面级别跨网格启用 mTLS 可以保护服务网格中的所有流量,而无需重写您的应用程序和工作负载。您可以在 ServiceMeshControlPlane 资源的数据平面级别保护网格中的命名空间。要自定义流量加密连接,请使用 PeerAuthenticationDestinationRule 资源在应用程序级别配置命名空间。

在服务网格中启用严格的 mTLS

如果您的工作负载不与外部服务通信,您可以快速地在网格中启用 mTLS,而不会中断通信。您可以通过在 ServiceMeshControlPlane 资源中将 spec.security.dataPlane.mtls 设置为 true 来启用它。操作员将创建所需的资源。

apiVersion: maistra.io/v2
kind: ServiceMeshControlPlane
spec:
  version: v2.6
  security:
    dataPlane:
      mtls: true

您也可以使用 Red Hat OpenShift Service on AWS Web 控制台启用 mTLS。

步骤
  1. 登录到 Web 控制台。

  2. 单击**项目**菜单,然后选择安装了 Service Mesh 控制平面的项目,例如**istio-system**。

  3. 单击**操作员**→**已安装的操作员**。

  4. 单击**已提供的 API**下的**服务网格控制平面**。

  5. 单击您的 ServiceMeshControlPlane 资源的名称,例如 basic

  6. 在**详细信息**页面上,单击**安全**部分中**数据平面安全**的切换按钮。

为特定服务的传入连接配置 sidecar

您还可以通过创建策略来为单个服务配置 mTLS。

步骤
  1. 使用以下示例创建一个 YAML 文件。

    PeerAuthentication 策略示例 policy.yaml
    apiVersion: security.istio.io/v1beta1
    kind: PeerAuthentication
    metadata:
      name: default
      namespace: <namespace>
    spec:
      mtls:
        mode: STRICT
    1. <namespace> 替换为服务所在的命名空间。

  2. 运行以下命令以在服务所在的命名空间中创建资源。它必须与您刚刚创建的策略资源中的 namespace 字段匹配。

    $ oc create -n <namespace> -f <policy.yaml>

如果您未使用自动 mTLS 并将 PeerAuthentication 设置为 STRICT,则必须为您的服务创建 DestinationRule 资源。

为传出连接配置 sidecar

创建目标规则以配置 Service Mesh 在向网格中的其他服务发送请求时使用 mTLS。

步骤
  1. 使用以下示例创建一个 YAML 文件。

    DestinationRule 示例 destination-rule.yaml
    apiVersion: networking.istio.io/v1alpha3
    kind: DestinationRule
    metadata:
      name: default
      namespace: <namespace>
    spec:
      host: "*.<namespace>.svc.cluster.local"
      trafficPolicy:
       tls:
        mode: ISTIO_MUTUAL
    1. <namespace> 替换为服务所在的命名空间。

  2. 运行以下命令以在服务所在的命名空间中创建资源。它必须与您刚刚创建的 DestinationRule 资源中的 namespace 字段匹配。

    $ oc create -n <namespace> -f <destination-rule.yaml>

设置最小和最大协议版本

如果您的环境对服务网格中的加密流量有特定要求,您可以通过设置 ServiceMeshControlPlane 资源中的 spec.security.controlPlane.tls.minProtocolVersionspec.security.controlPlane.tls.maxProtocolVersion 来控制允许的加密函数。在您的服务网格控制平面资源中配置的这些值定义了网格组件在通过 TLS 安全通信时使用的最小和最大 TLS 版本。

默认值为 TLS_AUTO,并且未指定 TLS 版本。

表 1. 有效值
描述

TLS_AUTO

默认值

TLSv1_0

TLS 版本 1.0

TLSv1_1

TLS 版本 1.1

TLSv1_2

TLS 版本 1.2

TLSv1_3

TLS 版本 1.3

步骤
  1. 登录到 Web 控制台。

  2. 单击**项目**菜单,然后选择安装了 Service Mesh 控制平面的项目,例如**istio-system**。

  3. 单击**操作员**→**已安装的操作员**。

  4. 单击**已提供的 API**下的**服务网格控制平面**。

  5. 单击您的 ServiceMeshControlPlane 资源的名称,例如 basic

  6. 单击**YAML**选项卡。

  7. 在 YAML 编辑器中插入以下代码片段。将 minProtocolVersion 中的值替换为 TLS 版本值。在此示例中,最小 TLS 版本设置为 TLSv1_2

    ServiceMeshControlPlane 代码片段
    kind: ServiceMeshControlPlane
    spec:
      security:
        controlPlane:
          tls:
            minProtocolVersion: TLSv1_2
  8. 单击**保存**。

  9. 单击**刷新**以验证更改是否已正确更新。

使用 Kiali 验证加密

Kiali 控制台提供了几种方法来验证您的应用程序、服务和工作负载是否启用了 mTLS 加密。

mTLS enabled
图 1. 网格范围 mTLS 已启用的主标题图标

在主标题的右侧,当网格为整个服务网格严格启用了 mTLS 时,Kiali 会显示一个锁图标。这意味着网格中的所有通信都使用 mTLS。

mTLS partially enabled
图 2. 网格范围 mTLS 部分启用的主标题图标

当网格配置为 PERMISSIVE 模式或网格范围 mTLS 配置中存在错误时,Kiali 将显示一个空心锁图标。

Security badge
图 3. 安全徽章

图表页面可以选择在图表边上显示一个安全徽章,以指示已启用mTLS。要在图表上启用安全徽章,请从显示菜单下的显示徽章中选中安全复选框。当边上显示锁图标时,表示至少存在一个启用了mTLS的请求。如果同时存在mTLS和非mTLS请求,侧面板将显示使用mTLS的请求百分比。

应用程序详细信息概述页面在图表边上显示一个安全图标,其中至少存在一个启用了mTLS的请求。

工作负载详细信息概述页面在图表边上显示一个安全图标,其中至少存在一个启用了mTLS的请求。

服务详细信息概述页面在图表边上显示一个安全图标,其中至少存在一个启用了mTLS的请求。另请注意,Kiali在网络部分的已配置为mTLS的端口旁边显示一个锁图标。

配置基于角色的访问控制 (RBAC)

基于角色的访问控制 (RBAC) 对象决定用户或服务是否被允许在项目中执行给定的操作。您可以在网格中为网格、命名空间和工作负载定义工作负载的访问控制。

要配置RBAC,请在您正在配置访问权限的命名空间中创建一个AuthorizationPolicy资源。如果您正在配置网格范围的访问权限,请使用安装服务网格控制平面的项目,例如istio-system

例如,使用RBAC,您可以创建以下策略:

  • 配置项目内通信。

  • 允许或拒绝对默认命名空间中所有工作负载的完全访问。

  • 允许或拒绝入口网关访问。

  • 要求访问令牌。

授权策略包括选择器、操作和规则列表。

  • selector字段指定策略的目标。

  • action字段指定是允许还是拒绝请求。

  • rules字段指定何时触发操作。

    • from字段指定对请求来源的约束。

    • to字段指定对请求目标和参数的约束。

    • when字段指定要应用规则的其他条件。

步骤
  1. 创建您的AuthorizationPolicy资源。以下示例显示一个资源,该资源更新入口策略AuthorizationPolicy以拒绝IP地址访问入口网关。

    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
      name: ingress-policy
      namespace: istio-system
    spec:
      selector:
        matchLabels:
          app: istio-ingressgateway
      action: DENY
      rules:
      - from:
        - source:
            ipBlocks: ["1.2.3.4"]
  2. 在您编写资源后运行以下命令,以便在您的命名空间中创建您的资源。命名空间必须与您的AuthorizationPolicy资源中的metadata.namespace字段匹配。

    $ oc create -n istio-system -f <filename>
后续步骤

考虑以下其他常用配置示例。

配置项目内通信

您可以使用AuthorizationPolicy配置您的服务网格控制平面以允许或拒绝与您的网格或网格中的服务通信的流量。

限制对命名空间外部服务的访问

您可以使用以下AuthorizationPolicy资源示例拒绝来自不在bookinfo命名空间中的任何来源的请求。

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: httpbin-deny
 namespace: bookinfo
spec:
 selector:
   matchLabels:
     app: httpbin
     version: v1
 action: DENY
 rules:
 - from:
   - source:
       notNamespaces: ["bookinfo"]

创建允许所有和默认拒绝所有授权策略

以下示例显示一个允许所有授权策略,该策略允许完全访问bookinfo命名空间中的所有工作负载。

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: allow-all
  namespace: bookinfo
spec:
  action: ALLOW
  rules:
  - {}

以下示例显示一个策略,该策略拒绝对bookinfo命名空间中所有工作负载的任何访问。

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: deny-all
  namespace: bookinfo
spec:
  {}

允许或拒绝对入口网关的访问

您可以设置授权策略以基于IP地址添加允许或拒绝列表。

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: ingress-policy
  namespace: istio-system
spec:
  selector:
    matchLabels:
      app: istio-ingressgateway
  action: ALLOW
  rules:
  - from:
    - source:
       ipBlocks: ["1.2.3.4", "5.6.7.0/24"]

使用JSON Web令牌限制访问

您可以使用JSON Web令牌 (JWT) 限制可以访问您的网格的内容。身份验证后,用户或服务可以访问与该令牌关联的路由和服务。

创建一个RequestAuthentication资源,该资源定义工作负载支持的身份验证方法。以下示例接受由http://127.0.0.1:8080/auth/realms/master颁发的JWT。

apiVersion: "security.istio.io/v1beta1"
kind: "RequestAuthentication"
metadata:
  name: "jwt-example"
  namespace: bookinfo
spec:
  selector:
    matchLabels:
      app: httpbin
  jwtRules:
  - issuer: "http://127.0.0.1:8080/auth/realms/master"
    jwksUri: "http://keycloak.default.svc:8080/auth/realms/master/protocol/openid-connect/certs"

然后,在同一个命名空间中创建一个AuthorizationPolicy资源以与您创建的RequestAuthentication资源一起工作。以下示例要求在向httpbin工作负载发送请求时,在Authorization标头中存在JWT。

apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
  name: "frontend-ingress"
  namespace: bookinfo
spec:
  selector:
    matchLabels:
      app: httpbin
  action: DENY
  rules:
  - from:
    - source:
        notRequestPrincipals: ["*"]

配置密码套件和ECDH曲线

密码套件和椭圆曲线Diffie-Hellman (ECDH曲线)可以帮助您保护您的服务网格。您可以使用spec.security.controlplane.tls.cipherSuites定义密码套件的逗号分隔列表,并使用ServiceMeshControlPlane资源中的spec.security.controlplane.tls.ecdhCurves定义ECDH曲线。如果这两个属性为空,则使用默认值。

如果您的服务网格使用TLS 1.2或更早版本,则cipherSuites设置有效。在与TLS 1.3协商时,它无效。

按优先级顺序设置逗号分隔列表中的密码套件。例如,ecdhCurves: CurveP256, CurveP384CurveP256设置为比CurveP384更高的优先级。

配置密码套件时,必须包含TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256。HTTP/2支持至少需要其中一个密码套件。

支持的密码套件为:

  • TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256

  • TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256

  • TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

  • TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256

  • TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384

  • TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384

  • TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256

  • TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA

  • TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256

  • TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA

  • TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA

  • TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA

  • TLS_RSA_WITH_AES_128_GCM_SHA256

  • TLS_RSA_WITH_AES_256_GCM_SHA384

  • TLS_RSA_WITH_AES_128_CBC_SHA256

  • TLS_RSA_WITH_AES_128_CBC_SHA

  • TLS_RSA_WITH_AES_256_CBC_SHA

  • TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA

  • TLS_RSA_WITH_3DES_EDE_CBC_SHA

支持的ECDH曲线为:

  • CurveP256

  • CurveP384

  • CurveP521

  • X25519

配置JSON Web密钥集解析器证书颁发机构

您可以从ServiceMeshControlPlane (SMCP)规范配置您自己的JSON Web密钥集 (JWKS) 解析器证书颁发机构 (CA)。

步骤
  1. 编辑ServiceMeshControlPlane规范文件

    $ oc edit smcp <smcp-name>
  2. 通过将ServiceMeshControlPlane规范中mtls字段的值设置为true来启用数据平面的mtls,如下例所示

    spec:
      security:
        dataPlane:
            mtls: true # enable mtls for data plane
        # JWKSResolver extra CA
        # PEM-encoded certificate content to trust an additional CA
        jwksResolverCA: |
            -----BEGIN CERTIFICATE-----
            [...]
            [...]
            -----END CERTIFICATE-----
    ...
  3. 保存更改。Red Hat OpenShift Service on AWS 会自动应用这些更改。

将创建一个名为pilot-jwks-cacerts-<SMCP name>ConfigMap,其中包含CA的.pem 数据

ConfigMap pilot-jwks-cacerts-<SMCP name>示例
kind: ConfigMap
apiVersion: v1
data:
  extra.pem: |
      -----BEGIN CERTIFICATE-----
      [...]
      [...]
      -----END CERTIFICATE-----

添加外部证书颁发机构密钥和证书

默认情况下,Red Hat OpenShift Service Mesh会生成一个自签名根证书和密钥,并使用它们来签署工作负载证书。您也可以使用用户定义的证书和密钥来使用用户定义的根证书签署工作负载证书。此任务演示了一个将证书和密钥插入Service Mesh的示例。

先决条件
  • 安装启用相互TLS的Red Hat OpenShift Service Mesh以配置证书。

  • 此示例使用来自Maistra 仓库的证书。在生产环境中,请使用您自己的证书颁发机构颁发的证书。

  • 按照这些说明部署Bookinfo示例应用程序以验证结果。

  • 需要OpenSSL来验证证书。

添加现有证书和密钥

要使用现有的签名(CA)证书和密钥,必须创建一个信任链文件,其中包含CA证书、密钥和根证书。必须为每个相应的证书使用以下确切的文件名。CA证书名为ca-cert.pem,密钥为ca-key.pem,签署ca-cert.pem的根证书名为root-cert.pem。如果您的工作负载使用中间证书,则必须在cert-chain.pem文件中指定它们。

  1. Maistra 仓库中的示例证书保存在本地,并将<path>替换为您证书的路径。

  2. 创建一个名为cacert的密钥,其中包含输入文件ca-cert.pemca-key.pemroot-cert.pemcert-chain.pem

    $ oc create secret generic cacerts -n istio-system --from-file=<path>/ca-cert.pem \
        --from-file=<path>/ca-key.pem --from-file=<path>/root-cert.pem \
        --from-file=<path>/cert-chain.pem
  3. ServiceMeshControlPlane资源中,将spec.security.dataPlane.mtls true设置为true,并配置certificateAuthority字段,如下例所示。默认的rootCADir/etc/cacerts。如果密钥和证书安装在默认位置,则无需设置privateKey。Service Mesh会从密钥挂载文件读取证书和密钥。

    apiVersion: maistra.io/v2
    kind: ServiceMeshControlPlane
    spec:
      security:
        dataPlane:
          mtls: true
        certificateAuthority:
          type: Istiod
          istiod:
            type: PrivateKey
            privateKey:
              rootCADir: /etc/cacerts
  4. 创建/更改/删除cacert密钥后,必须重新启动Service Mesh控制平面istiodgateway Pod才能使更改生效。使用以下命令重新启动Pod

    $ oc -n istio-system delete pods -l 'app in (istiod,istio-ingressgateway, istio-egressgateway)'

    删除Pod后,Operator会自动重新创建它们。

  5. 重新启动bookinfo应用程序Pod,以便sidecar代理获取密钥更改。使用以下命令重新启动Pod

    $ oc -n bookinfo delete pods --all

    您应该看到类似以下的输出

    pod "details-v1-6cd699df8c-j54nh" deleted
    pod "productpage-v1-5ddcb4b84f-mtmf2" deleted
    pod "ratings-v1-bdbcc68bc-kmng4" deleted
    pod "reviews-v1-754ddd7b6f-lqhsv" deleted
    pod "reviews-v2-675679877f-q67r2" deleted
    pod "reviews-v3-79d7549c7-c2gjs" deleted
  6. 使用以下命令验证Pod是否已创建并准备就绪

    $ oc get pods -n bookinfo

验证您的证书

使用Bookinfo示例应用程序验证工作负载证书是否由插入CA的证书签署。此过程要求您在计算机上安装openssl

  1. 要从bookinfo工作负载中提取证书,请使用以下命令

    $ sleep 60
    $ oc -n bookinfo exec "$(oc -n bookinfo get pod -l app=productpage -o jsonpath={.items..metadata.name})" -c istio-proxy -- openssl s_client -showcerts -connect details:9080 > bookinfo-proxy-cert.txt
    $ sed -n '/-----BEGIN CERTIFICATE-----/{:start /-----END CERTIFICATE-----/!{N;b start};/.*/p}' bookinfo-proxy-cert.txt > certs.pem
    $ awk 'BEGIN {counter=0;} /BEGIN CERT/{counter++} { print > "proxy-cert-" counter ".pem"}' < certs.pem

    运行该命令后,您的工作目录中应该有三个文件:proxy-cert-1.pemproxy-cert-2.pemproxy-cert-3.pem

  2. 验证根证书是否与管理员指定的证书相同。将<path>替换为您证书的路径。

    $ openssl x509 -in <path>/root-cert.pem -text -noout > /tmp/root-cert.crt.txt

    在终端窗口中运行以下语法。

    $ openssl x509 -in ./proxy-cert-3.pem -text -noout > /tmp/pod-root-cert.crt.txt

    通过在终端窗口中运行以下语法来比较证书。

    $ diff -s /tmp/root-cert.crt.txt /tmp/pod-root-cert.crt.txt

    您应该看到以下结果:Files /tmp/root-cert.crt.txt and /tmp/pod-root-cert.crt.txt are identical

  3. 验证CA证书是否与管理员指定的证书相同。将<path>替换为您证书的路径。

    $ openssl x509 -in <path>/ca-cert.pem -text -noout > /tmp/ca-cert.crt.txt

    在终端窗口中运行以下语法。

    $ openssl x509 -in ./proxy-cert-2.pem -text -noout > /tmp/pod-cert-chain-ca.crt.txt

    通过在终端窗口中运行以下语法来比较证书。

    $ diff -s /tmp/ca-cert.crt.txt /tmp/pod-cert-chain-ca.crt.txt

    您应该看到以下结果:Files /tmp/ca-cert.crt.txt and /tmp/pod-cert-chain-ca.crt.txt are identical.

  4. 验证从根证书到工作负载证书的证书链。将<path>替换为您证书的路径。

    $ openssl verify -CAfile <(cat <path>/ca-cert.pem <path>/root-cert.pem) ./proxy-cert-1.pem

    您应该看到以下结果:./proxy-cert-1.pem: OK

删除证书

要删除您添加的证书,请按照以下步骤操作。

  1. 删除密钥cacerts。在此示例中,istio-system是Service Mesh控制平面项目的名称。

    $ oc delete secret cacerts -n istio-system
  2. ServiceMeshControlPlane资源中使用自签名根证书重新部署Service Mesh。

    apiVersion: maistra.io/v2
    kind: ServiceMeshControlPlane
    spec:
      security:
        dataPlane:
          mtls: true

关于将Service Mesh与cert-manager和istio-csr集成

cert-manager工具是用于Kubernetes上X.509证书管理的解决方案。它提供了一个统一的API,用于将应用程序与私钥或公钥基础设施(PKI)集成,例如Vault、Google Cloud证书颁发机构服务、Let’s Encrypt和其他提供商。

cert-manager工具通过尝试在证书过期前配置的时间内续订证书来确保证书有效且最新。

对于Istio用户,cert-manager还提供与istio-csr的集成,istio-csr是一个证书颁发机构(CA)服务器,用于处理来自Istio代理的证书签名请求(CSR)。然后,服务器将签名委托给cert-manager,后者将CSR转发到配置的CA服务器。

Red Hat提供与istio-csr和cert-manager集成的支持。Red Hat不直接支持istio-csr或社区cert-manager组件。此处显示的社区cert-manager仅用于演示目的。

先决条件
  • cert-manager的以下版本之一

    • 适用于Red Hat OpenShift 1.10或更高版本的cert-manager Operator

    • 社区cert-manager Operator 1.11或更高版本

    • cert-manager 1.11或更高版本

  • OpenShift Service Mesh Operator 2.4或更高版本

  • istio-csr 0.6.0或更高版本

为了避免在使用jetstack/cert-manager-istio-csr Helm图表安装istio-csr服务器时在所有命名空间中创建ConfigMap,请在istio-csr.yaml文件中使用以下设置:app.controller.configmapNamespaceSelector: "maistra.io/member-of: <istio-namespace>"

安装cert-manager

您可以安装cert-manager工具来管理TLS证书的生命周期,并确保它们有效且最新。如果您的环境中运行Istio,您还可以安装istio-csr证书颁发机构(CA)服务器,该服务器处理来自Istio代理的证书签名请求(CSR)。istio-csr CA将签名委托给cert-manager工具,后者再委托给配置的CA。

步骤
  1. 创建根集群颁发者

    1. 创建cluster-issuer对象,如下例所示

      cluster-issuer.yaml示例
      apiVersion: cert-manager.io/v1
      kind: Issuer
      metadata:
        name: selfsigned-root-issuer
        namespace: cert-manager
      spec:
        selfSigned: {}
      ---
      apiVersion: cert-manager.io/v1
      kind: Certificate
      metadata:
        name: root-ca
        namespace: cert-manager
      spec:
        isCA: true
        duration: 21600h # 900d
        secretName: root-ca
        commonName: root-ca.my-company.net
        subject:
          organizations:
          - my-company.net
        issuerRef:
          name: selfsigned-root-issuer
          kind: Issuer
          group: cert-manager.io
      ---
      apiVersion: cert-manager.io/v1
      kind: ClusterIssuer
      metadata:
        name: root-ca
      spec:
        ca:
          secretName: root-ca
      selfsigned-root-issuer颁发者和root-ca证书的命名空间是cert-manager,因为root-ca是集群颁发者,所以cert-manager会在其自己的命名空间中查找引用的密钥。对于Red Hat OpenShift的cert-manager Operator,命名空间称为cert-manager
    2. 使用以下命令创建对象

      $ oc apply -f cluster-issuer.yaml
    3. 创建istio-ca对象,如下例所示

      istio-ca.yaml示例
      apiVersion: cert-manager.io/v1
      kind: Certificate
      metadata:
        name: istio-ca
        namespace: istio-system
      spec:
        isCA: true
        duration: 21600h
        secretName: istio-ca
        commonName: istio-ca.my-company.net
        subject:
          organizations:
          - my-company.net
        issuerRef:
          name: root-ca
          kind: ClusterIssuer
          group: cert-manager.io
      ---
      apiVersion: cert-manager.io/v1
      kind: Issuer
      metadata:
        name: istio-ca
        namespace: istio-system
      spec:
        ca:
          secretName: istio-ca
    4. 使用以下命令创建对象

      $ oc apply -n istio-system -f istio-ca.yaml
  2. 安装istio-csr

    $ helm install istio-csr jetstack/cert-manager-istio-csr \
        -n istio-system \
        -f deploy/examples/cert-manager/istio-csr/istio-csr.yaml
    istio-csr.yaml示例
    replicaCount: 2
    
    image:
      repository: quay.io/jetstack/cert-manager-istio-csr
      tag: v0.6.0
      pullSecretName: ""
    
    app:
      certmanager:
        namespace: istio-system
        issuer:
          group: cert-manager.io
          kind: Issuer
          name: istio-ca
    
      controller:
        configmapNamespaceSelector: "maistra.io/member-of=istio-system"
        leaderElectionNamespace: istio-system
    
      istio:
        namespace: istio-system
        revisions: ["basic"]
    
      server:
        maxCertificateDuration: 5m
    
      tls:
        certificateDNSNames:
        # This DNS name must be set in the SMCP spec.security.certificateAuthority.cert-manager.address
        - cert-manager-istio-csr.istio-system.svc
  3. 部署SMCP

    $ oc apply -f mesh.yaml -n istio-system
    mesh.yaml示例
    apiVersion: maistra.io/v2
    kind: ServiceMeshControlPlane
    metadata:
      name: basic
    spec:
      addons:
        grafana:
          enabled: false
        kiali:
          enabled: false
        prometheus:
          enabled: false
      proxy:
        accessLogging:
          file:
            name: /dev/stdout
      security:
        certificateAuthority:
          cert-manager:
            address: cert-manager-istio-csr.istio-system.svc:443
          type: cert-manager
        dataPlane:
          mtls: true
        identity:
          type: ThirdParty
      tracing:
        type: None
    ---
    apiVersion: maistra.io/v1
    kind: ServiceMeshMemberRoll
    metadata:
      name: default
    spec:
      members:
      - httpbin
      - sleep
配置security.certificateAuthority.type: cert-manager时,必须设置security.identity.type: ThirdParty
验证

使用示例httpbin服务和sleep应用程序检查来自入口网关的mTLS流量,并验证是否已安装cert-manager工具。

  1. 部署 HTTP 和 sleep 应用

    $ oc new-project <namespace>
    $ oc apply -f https://raw.githubusercontent.com/maistra/istio/maistra-2.4/samples/httpbin/httpbin.yaml
    $ oc apply -f https://raw.githubusercontent.com/maistra/istio/maistra-2.4/samples/sleep/sleep.yaml
  2. 验证 sleep 是否可以访问 httpbin 服务

    $ oc exec "$(oc get pod -l app=sleep -n <namespace> \
       -o jsonpath={.items..metadata.name})" -c sleep -n <namespace> -- \
       curl http://httpbin.<namespace>:8000/ip -s -o /dev/null \
       -w "%{http_code}\n"
    示例输出
    200
  3. 检查从入口网关到 httpbin 服务的 mTLS 通信

    $ oc apply -n <namespace> -f https://raw.githubusercontent.com/maistra/istio/maistra-2.4/samples/httpbin/httpbin-gateway.yaml
  4. 获取 istio-ingressgateway 路由

    INGRESS_HOST=$(oc -n istio-system get routes istio-ingressgateway -o jsonpath='{.spec.host}')
  5. 验证从入口网关到 httpbin 服务的 mTLS 通信

    $ curl -s -I http://$INGRESS_HOST/headers -o /dev/null -w "%{http_code}" -s

更多资源

有关如何在 AWS 上安装适用于 Red Hat OpenShift 服务的 cert-manager 运算符的信息,请参阅:安装适用于 Red Hat OpenShift 的 cert-manager 运算符