×

如果您的服务网格应用程序是由复杂的微服务数组构建的,您可以使用 Red Hat OpenShift Service Mesh 来自定义这些服务之间通信的安全性。OpenShift Container Platform 的基础架构以及 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 来启用它。Operator 将创建所需的资源。

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

您也可以使用 OpenShift Container Platform Web 控制台启用 mTLS。

步骤
  1. 登录 Web 控制台。

  2. 单击**项目**菜单,然后选择安装服务网格控制平面的项目,例如**istio-system**。

  3. 单击**Operators** → **已安装的 Operators**。

  4. 单击**提供的 API**下的**Service Mesh Control Plane**。

  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

创建一个目标规则,以配置服务网格在向网格中的其他服务发送请求时使用 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. 单击**项目**菜单,然后选择安装服务网格控制平面的项目,例如**istio-system**。

  3. 单击**Operators** → **已安装的 Operators**。

  4. 单击**提供的 API**下的**Service Mesh Control Plane**。

  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资源,该资源定义工作负载支持的身份验证方法。以下示例接受由https://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: "https://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曲线)可以帮助您保护您的服务网格。您可以使用ServiceMeshControlPlane资源中的spec.security.controlplane.tls.cipherSuites定义密码套件的逗号分隔列表,使用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. 保存更改。OpenShift Container Platform会自动应用这些更改。

将创建一个ConfigMap,例如pilot-jwks-cacerts-<SMCP name>,其中包含CA.pem data

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

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

默认情况下,Red Hat OpenShift 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。服务网格从密钥安装文件读取证书和密钥。

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

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

    操作员将在pod被删除后自动重新创建它们。

  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 是服务网格控制平面项目的名称。

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

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

关于将服务网格与 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,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 运算符

    • 社区 cert-manager 运算符 1.11 或更高版本

    • cert-manager 1.11 或更高版本

  • OpenShift 服务网格运算符 2.4 或更高版本

  • istio-csr 0.6.0 或更高版本

为了避免在使用jetstack/cert-manager-istio-csr Helm chart 安装istio-csr服务器时在所有命名空间中创建配置映射,请在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 运算符,命名空间称为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

其他资源

有关如何安装适用于 OpenShift Container Platform 的 cert-manager 运算符的信息,请参见:安装适用于 Red Hat OpenShift 的 cert-manager 运算符