新功能:在TwitterMastodon

安装 istio-csr

安装步骤

本指南将逐步介绍从头开始安装和使用 istio-csr。我们将使用 kind 在 Docker 中本地创建一个新的集群,但本指南应该适用于任何集群,只要已执行相关的 Istio 平台设置

请注意,如果您遵循 OpenShift 的平台设置指南,请不要运行 istioctl install 命令,该命令列在该指南中;我们将在稍后运行我们自己的命令。

0. 背景

颁发者配置

istio-csr 使用 cert-manager 来颁发 Istio 证书,并且需要能够引用颁发者资源来执行此操作。

您可以在使用 Helm 图表安装时选择配置颁发者,或者配置一个要监视的 ConfigMap,然后可以使用该 ConfigMap 在运行时配置颁发者。

为颁发者详细信息配置 ConfigMap 被称为“运行时配置”,如果 Helm 图表中未指定颁发者,则需要进行此配置。

如果您在图表中配置了颁发者,您将能够在 istio-csr pod 上线后立即开始颁发,但您需要已经安装 cert-manager 并创建了颁发者。

如果您没有在图表中设置颁发者,istio-csr 将不会准备好,直到通过运行时配置指定颁发者,但您可以同时安装 cert-manager 和 istio-csr。

请注意,图表包含默认颁发者名称,因此使用运行时配置需要明确选择。以下指南假设您将在配置颁发者后安装 istio-csr,而无需运行时配置;底部有关于运行时配置的说明。

Istio Ambient

v0.12.0 开始,istio-csr 支持 Istio Ambient 模式,该模式允许 pod 在没有边车容器的情况下包含在 Istio 网格中。

要启用 Istio Ambient 模式支持,请传递 app.server.caTrustedNodeAccounts Helm 值,它是一个用逗号分隔的 namespace/service-accounts 值列表,表示允许哪些服务帐户使用节点身份验证。

例如,--set app.server.caTrustedNodeAccounts=istio-system/ztunnel

1. 初始设置

您需要在计算机上安装以下工具

此外,Istio 不应该已经安装在您的集群中。在 Istio 之后安装 istio-csr 不受支持。

2. 创建集群并安装 cert-manager

Kind 会自动设置 kubectl 以指向新创建的集群。

我们在这里使用 helm 安装 cert-manager,但如果您有首选方法,您可以通过任何方式安装。

kind create cluster
# Helm setup
helm repo add jetstack https://charts.jetstack.io --force-update
# install cert-manager; this might take a little time
helm install \
cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--version v1.16.1 \
--set crds.enabled=true
# We need this namespace to exist since our cert will be placed there
kubectl create namespace istio-system

3. 创建 cert-manager 颁发者和颁发证书

颁发者告诉 cert-manager 如何颁发证书;我们将创建集群中的自签名根 CA,因为它非常易于配置。

使用本地生成的根证书的方法也适用于生产部署,但 cert-manager 中还有一些其他 颁发者 可供使用。请注意,ACME 颁发者**将无法工作**,因为它无法将必需的字段添加到颁发的证书中。

example-issuer 中还有一些注释提供更多详细信息。还请注意,本指南仅使用 Issuer,而不是 ClusterIssuer - 使用 ClusterIssuer 并不是一种直接替代方案,无论如何,我们建议生产部署使用 Issuer 来简化访问控制和范围。

kubectl apply -f https://raw.githubusercontent.com/cert-manager/website/7f5b2be9dd67831574b9bde2407bed4a920b691c/content/docs/tutorials/istio-csr/example/example-issuer.yaml

4. 将根 CA 导出到本地文件

虽然可以配置 Istio 使其能够自动“发现”根 CA,但这在涉及其他安全漏洞的某些特定情况下可能很危险,从而导致 签名者劫持攻击

因此,我们将导出根 CA 并在稍后使用该静态证书配置 Istio。

# Export our cert from the secret it's stored in, and base64 decode to get the PEM data.
kubectl get -n istio-system secret istio-ca -ogo-template='{{index .data "tls.crt"}}' | base64 -d > ca.pem
# Out of interest, we can check out what our CA looks like
openssl x509 -in ca.pem -noout -text
# Add our CA to a secret
kubectl create secret generic -n cert-manager istio-root-ca --from-file=ca.pem=ca.pem

5. 安装 istio-csr

istio-csr 最好通过 Helm 安装,安装应该简单快捷。Helm 图表还有许多其他配置选项,您可以在 此处 查看。

helm repo add jetstack https://charts.jetstack.io --force-update
# We set a few helm template values so we can point at our static root CA
helm upgrade cert-manager-istio-csr jetstack/cert-manager-istio-csr \
--install \
--namespace cert-manager \
--wait \
--set "app.tls.rootCAFile=/var/run/secrets/istio-csr/ca.pem" \
--set "volumeMounts[0].name=root-ca" \
--set "volumeMounts[0].mountPath=/var/run/secrets/istio-csr" \
--set "volumes[0].name=root-ca" \
--set "volumes[0].secret.secretName=istio-root-ca"
# Check to see that the istio-csr pod is running and ready
kubectl get pods -n cert-manager
NAME READY STATUS RESTARTS AGE
cert-manager-aaaaaaaaaa-11111 1/1 Running 0 9m46s
cert-manager-cainjector-aaaaaaaaaa-22222 1/1 Running 0 9m46s
cert-manager-istio-csr-bbbbbbbbbb-00000 1/1 Running 0 63s
cert-manager-webhook-aaaaaaaaa-33333 1/1 Running 0 9m46s

6. 安装 Istio

如果您没有在 kind 上运行,您可能需要在安装 Istio 之前执行一些其他 设置任务

我们使用 istioctl CLI 来安装 Istio,使用自定义 IstioOperator 清单进行配置。

自定义清单执行以下操作

  • 禁用 istiod 中的 CA 服务器,
  • 确保 Istio 工作负载从 istio-csr 请求证书,
  • 确保 istiod 证书和密钥从安装 istio-csr 时创建的证书中装载。

首先我们下载演示清单,然后我们应用它。

curl -sSL https://raw.githubusercontent.com/cert-manager/website/7f5b2be9dd67831574b9bde2407bed4a920b691c/content/docs/tutorials/istio-csr/example/istio-config-getting-started.yaml > istio-install-config.yaml

如果您知道自己在做什么,您可能希望检查并调整 istio-install-config.yaml,但此清单应该按原样适用于示例目的。

如果您在之前通过 helm 安装 istio-csr 时设置了自定义 app.tls.trustDomain,则需要确保该值在 istio-install-config.yaml 中重复。

此最终命令将安装 Istio;您需要的确切命令可能因平台而异,并且肯定会在 OpenShift 上有所不同。

# This takes a little time to complete
istioctl install -f istio-install-config.yaml
# If you're on OpenShift, you need a different profile:
# istioctl install --set profile=openshift -f istio-install-config.yaml

系统将提示您输入内容以确认您选择的 Istio 配置文件

This will install the Istio 1.14.1 demo profile with ["Istio core" "Istiod" "Ingress gateways" "Egress gateways"] components into the cluster. Proceed? (y/N)

通过在控制台中输入 y 来确认您的选择,以继续安装。

验证安装

以下步骤是可选的,但可以按照以下步骤验证一切是否都正确连接

  1. 部署示例应用程序并观察 certificaterequests.cert-manager.io 资源
  2. 验证 cert-manager 日志中是否有新的 certificaterequests 和响应
  3. 验证 istio-proxy 边车容器中使用的 CA 端点
  4. 使用 istioctl 获取 istio-proxy 容器的证书信息

为了让您了解所有这些操作,让我们从 Istio 示例 部署一个非常简单的示例应用程序。

首先设置一些环境变量,如果需要可以更改其值

# Set namespace for sample application
export NAMESPACE=default
# Set env var for the value of the app label in manifests
export APP=httpbin
# Grab the installed version of istio
export ISTIO_VERSION=$(istioctl version -o json | jq -r '.meshVersion[0].Info.version')

为了简单起见,我们使用 default 命名空间,因此让我们为 Istio 注射标记命名空间

kubectl label namespace $NAMESPACE istio-injection=enabled --overwrite

在另一个终端中,您现在应该跟踪 cert-manager 的日志

kubectl logs -n cert-manager $(kubectl get pods -n cert-manager -o jsonpath='{.items..metadata.name}' --selector app=cert-manager) --since 2m -f

在另一个独立的终端中,让我们观察 istio-system 命名空间中的 certificaterequests

kubectl get certificaterequests.cert-manager.io -n istio-system -w

现在,在标记的命名空间中部署示例应用程序 httpbin。请注意,使用变量来匹配清单版本与已安装的 Istio 版本

kubectl apply -n $NAMESPACE -f https://raw.githubusercontent.com/istio/istio/$ISTIO_VERSION/samples/httpbin/httpbin.yaml

您应该看到类似于这里 certificaterequests 的输出

NAME APPROVED DENIED READY ISSUER REQUESTOR AGE
istio-ca-74bnl True True selfsigned system:serviceaccount:cert-manager:cert-manager 2d2h
istiod-w9zh6 True True istio-ca system:serviceaccount:cert-manager:cert-manager 27m
istio-csr-8ddcs istio-ca system:serviceaccount:cert-manager:cert-manager-istio-csr 0s
istio-csr-8ddcs True istio-ca system:serviceaccount:cert-manager:cert-manager-istio-csr 0s
istio-csr-8ddcs True True istio-ca system:serviceaccount:cert-manager:cert-manager-istio-csr 0s
istio-csr-8ddcs True True istio-ca system:serviceaccount:cert-manager:cert-manager-istio-csr 0s

在本例输出中,关键请求是 istio-csr-8ddcs。然后,您应该检查您的 cert-manager 日志输出,查找两条日志行,其中该请求分别为“已批准”和“已准备就绪”。

I0113 16:51:59.186482 1 conditions.go:261] Setting lastTransitionTime for CertificateRequest "istio-csr-8ddcs" condition "Approved" to 2022-01-13 16:51:59.186455713 +0000 UTC m=+3507.098466775
I0113 16:51:59.258876 1 conditions.go:261] Setting lastTransitionTime for CertificateRequest "istio-csr-8ddcs" condition "Ready" to 2022-01-13 16:51:59.258837897 +0000 UTC m=+3507.170859959

现在,您应该看到应用程序正在运行,包含应用程序容器和 sidecar。

~ kubectl get pods -n $NAMESPACE
NAME READY STATUS RESTARTS AGE
httpbin-74fb669cc6-559cg 2/2 Running 0 4m

要验证 istio-proxy sidecar 容器已从正确的服务请求证书,请检查容器日志。

kubectl logs $(kubectl get pod -n $NAMESPACE -o jsonpath="{.items...metadata.name}" --selector app=$APP) -c istio-proxy

您应该看到一些类似于此示例的早期日志。

Istio v1.12 及更早版本

2022-01-13T16:51:58.495493Z info CA Endpoint cert-manager-istio-csr.cert-manager.svc:443, provider Citadel
2022-01-13T16:51:58.495817Z info Using CA cert-manager-istio-csr.cert-manager.svc:443 cert with certs: var/run/secrets/istio/root-cert.pem
2022-01-13T16:51:58.495941Z info citadelclient Citadel client using custom root cert: cert-manager-istio-csr.cert-manager.svc:443

Istio v1.13+

2022-01-13T16:51:58.495493Z info CA Endpoint cert-manager-istio-csr.cert-manager.svc:443, provider Citadel
2022-01-13T16:51:58.495817Z info Using CA cert-manager-istio-csr.cert-manager.svc:443 cert with certs: var/run/secrets/istio/root-cert.pem
2022-01-13T16:51:58.495941Z info citadelclient Citadel client using custom root cert: var/run/secrets/istio/root-cert.pem

最后,我们可以检查 Envoy 在内存中使用的证书。此单行代码应返回您使用的证书。

istioctl proxy-config secret $(kubectl get pods -n $NAMESPACE -o jsonpath='{.items..metadata.name}' --selector app=$APP) -o json | jq -r '.dynamicActiveSecrets[0].secret.tlsCertificate.certificateChain.inlineBytes' | base64 --decode | openssl x509 -text -noout

特别是寻找以下部分:

Signature Algorithm: ecdsa-with-SHA256
Issuer: O=cert-manager, O=cluster.local, CN=istio-ca
Validity
Not Before: Jan 13 16:51:59 2022 GMT
Not After : Jan 13 17:51:59 2022 GMT
...
X509v3 Subject Alternative Name:
URI:spiffe://cluster.local/ns/default/sa/httpbin

您应该在发行者中看到相关的信任域。在默认情况下,它应该为:cluster.local (如上所示)。请注意,如果您使用不同的命名空间或应用程序,SPIFFE URI 可能不同。

清理

假设您在 kind 中运行,您可以简单地删除集群。

kind delete cluster

使用运行时配置安装

使用运行时配置安装有两种选择。

  1. 在 cert-manager 之后安装,在 Helm 图表中仍然提供显式的 issuerRef
  2. 在 Helm 图表中清空 issuerRef,并使用纯运行时配置。

这两种选择都需要创建一个 ConfigMap 来指向发行者。此 ConfigMap 可以在安装之前或之后创建,并且必须在与 istio-csr pod 相同的命名空间中创建。

创建 ConfigMap

需要三个键,分别指定发行者名称、类型和组。任何创建 ConfigMap 的方法都适用。例如:

kubectl create configmap -n cert-manager istio-issuer \
--from-literal=issuer-name=my-issuer-name \
--from-literal=issuer-kind=ClusterIssuer \
--from-literal=issuer-group=cert-manager.io

Helm 图表包括在安装时创建运行时配置 ConfigMap 的功能,如果需要,可以通过 app.runtimeConfiguration.issuer 值进行。

app:
runtimeConfiguration:
issuer:
name: my-issuer-name
kind: Issuer
group: cert-manager.io

选项 1:在 cert-manager 之后安装

如果 cert-manager 已经安装,您可以使用与上面相同的 helm upgrade 命令,但也指定运行时配置 ConfigMap 的名称。

helm upgrade cert-manager-istio-csr jetstack/cert-manager-istio-csr \
--install \
--namespace cert-manager \
--wait \
...
--set "app.runtimeConfiguration.name=istio-issuer"

在这种情况下,在 app.certmanager.issuer 中定义的发行者将在启动时使用,并用于创建 istiod 证书。

当 istio-csr 检测到运行时 ConfigMap 时,它将使用那里配置的发行者。如果 ConfigMap 更新,istio-csr 将动态地尊重该更新。

如果运行时 ConfigMap 被删除,istio-csr 将恢复使用来自 app.certmanager.issuer 的值。

选项 2:纯运行时配置

纯运行时配置仅在 istio-csr v0.11.0 或更高版本中实用。

纯运行时配置需要设置更多值。

  1. 必须清空 app.certmanager.issuer 值(因为它们在图表中设置为默认值)。
  2. 不应与 istio-csr 资源一起配置 istiod 证书。通过传递 app.tls.istiodCertificateEnable=dynamic,istiod 将在运行时配置可用时动态生成。
  3. 必须设置 app.runtimeConfiguration.name

以下是纯运行时配置的示例 values.yaml 文件:

app:
runtimeIssuanceConfigMap: istio-issuer
certmanager:
issuer:
enabled: false # Important: the default issuer is enabled by default
tls:
rootCAFile: "/var/run/secrets/istio-csr/ca.pem"
istiodCertificateEnable: dynamic
volumeMounts:
- name: root-ca
mountPath: /var/run/secrets/istio-csr
volumes:
- name: root-ca
secret:
secretName: istio-root-ca

然后可以使用以下命令使用此文件:

helm upgrade cert-manager-istio-csr jetstack/cert-manager-istio-csr \
--install \
--namespace cert-manager \
--wait \
--values values.yaml

完成纯运行时安装

为了使 istio-csr 更容易与 cert-manager 一起安装,纯运行时配置稍微修改了 istio-csr 健康检查的行为。这是因为 Helm 在健康检查通过之前不会完成安装。

如果且仅当使用纯运行时配置时,istio-csr 的健康检查将报告为健康,直到运行时配置首次可用。

在运行时配置首次可用后,健康检查将恢复其正常操作。

使用

📖 阅读 istio-csr 文档