Integrating Firefly with OpenShift Service Mesh¶
These instruction show to use a Firefly Sub CA to sign the mTLS certificates of OpenShift Service Mesh. The advantages of this setup are:
- Your PKI team will be able to see how many certificates have been created for the mesh.
- Your PKI team will be able enforce policies for the mesh certificates.
- Your platform will be using the PKI of your organization, rather than shadow PKI which OpenShift Service Mesh uses by default.
Important
This solution is for experienced users and there are several things that you should bear in mind with this set-up:
- Complexity - There five components (istio-proxy, istiod, Istio CSR, cert-manager, Firefly) involved in the signing of every service mesh workload certificate. If something goes wrong, your platform team must know how to diagnose problems in each of these components.
- Fragility - Each of the five components is a single point of failure. If any component stops working, then the workload will fail to start.
- Performance bottlenecks - If any of the five components is overwhelmed or under resourced, then there will be delays creating the workload certificates.
If you are willing to accept these trade-offs, please read on.
Prerequisites¶
A Red Hat OpenShift v4 cluster.
Info
This tutorial has been verified on a single node CRC based cluster using 8 CPUS, 32GiB RAM, 200GiB Disk, with monitoring systems disabled. The following versions were used:
- CRC: v2.44.0
- OpenShift: v4.17.3
- Red Hat OpenShift Service Mesh: v2.6.5-0
- Venafi Control Plane Operator: v1.5.0
The Red Hat OpenShift documentation contains a separate guide about integrating Service Mesh with cert-manager and Istio CSR, which you should read, but if you have already followed that process, you should uninstall cert-manager and Istio CSR before continuing this tutorial, as these instructions are designed to work seamlessly with the Venafi distributions of those software packages.
Step 1: Create projects (namespaces)¶
First, create the two projects (namespaces) used in this tutorial.
oc create namespace venafi
oc create namespace istio-system
Important
You must create the istio-system
namespace before installing Istio CSR. Without it, Istio CSR will fail to install, and the Venafi Control Plane Operator will hang.
If you have previously deployed Istio and later deleted it, some resources may have been left behind in the istio-system
namespace, which may interfere with Istio CSR. In particular, you should delete the following Secret resources which may contain stale CA certificates:
cacerts
istio-ca-secret
You can see the priority of loading of CA certificates in the istio-operator webhook CA source code.
Step 2: Install OperatorHub Operators¶
Install the following operators from the OperatorHub dashboard in the OpenShift web console:
-
Red Hat OpenShift Service Mesh: This operator will allow you to install a service mesh later in this tutorial. It installs the Operator and CRDs required to create a service mesh. Multiple service meshes can be run within a single OpenShift cluster. Read the Red Hat OpenShift Service Mesh 2.x installation documentation to learn more.
-
Venafi Control Plane Operator: Install this operator in the
venafi
project (namespace). Choose the option to create avenafi
project (namespace) if it does not already exist.
This operator will allow you to install cert-manager, Istio CSR, and Firefly components of Venafi TLSPK. Read the Venafi Control Plane Operator installation page to learn more.
Step 3: Prepare the Firefly service account, Firefly policy and Firefly configuration¶
- Create a Firefly service account in Venafi Control Plane. Save the private key and the client ID as you will need both later.
- Create a Firefly Policy to use when issuing certificates in Venafi Control Plane.
- Create a Firefly configuration to map the policy to the service account in Venafi Control Plane.
Info
Read Firefly path to success; a road map to help you get started with Firefly.
Step 4: Create a service account private key secret¶
Before Firefly can be installed, a Secret resource containing the Venafi Control Plane service account private key must be created:
export FIREFLY_PRIVATE_KEY_FILE=path/to/firefly-private.key
oc create secret generic venafi-credentials \
--namespace venafi \
--from-file=svc-acct.key=${FIREFLY_PRIVATE_KEY_FILE}
Info
This private key is used by Firefly to authenticate to the Venafi Control Plane, from where it downloads its configuration, and to where it uploads signing metrics.
Step 5: Create an image pull secret¶
-
Next, Create a new Venafi Registry service account. This is required to pull Helm charts and Docker images from the Venafi private OCI registries.
-
Apply the image pull secret to the
venafi
namespace (copy and paste the exact command from the "Add a New Service Account" (Settings > Service Accounts > New) page of the Venafi Control Plane):oc create namespace venafi oc apply --namespace=venafi -f - <<EOF apiVersion: v1 kind: Secret metadata: name: venafi-image-pull-secret data: .dockerconfigjson: YOUR_BASE64_ENCODED_PULL_SECRET type: kubernetes.io/dockerconfigjson EOF
Info
This command will contain a unique Docker pull secret that will be used by Venafi Control Plane Operator to pull Helm charts from the Venafi Enterprise registry, and which will then be used by Kubernetes to pull Docker images from the same registry.
Step 6: Publish the Firefly root CA certificate to your cluster¶
Istio requires a special ConfigMap resource in each namespace, containing the root CA that signed the istiod
serving certificate. The Istio sidecars use this to verify the serving certificate when they connect to istiod
to request workload certificates. Istio CSR will take care of creating these ConfigMap resources for you, but you must tell it which CA certificate to use. In this tutorial, Istio CSR will be using a gRPC serving certificate that has been signed by Firefly, so we need to download the Firefly root certificate, put it in a Secret in the cluster, and then tell Istio CSR to mount that Secret and use the CA certificate contained within it.
To download the Firefly root certificate from the Venafi Control Plane:
- Click Configurations > Firefly Configurations.
- Click the link in the Sub CA Provider column of the "Firefly Configurations" page.
- Click the link in the CA Account column of the "Firefly Sub CA Providers" page.
- Click Download chain > Root certificate first.
Copy the root CA certificate into a Secret resource in the venafi
project (namespace) of your OpenShift cluster:
oc create secret generic firefly-root-ca \
--namespace=venafi \
--from-file=ca.crt=firefly-root-ca.pem
Info
The certificate may contain a chain of certificates which include the root, but that's OK. The istio-proxy is able to extract the self signed root from the chain to verify the serving certificate of istiod
.
Step 7: Install cert-manager, Istio CSR and Firefly¶
-
Create a manifest
venafi-components.yaml
to configure the installation of cert-manager, Istio CSR, and Firefly. You can use one of the samples below:venafi-components.yamlapiVersion: installer.venafi.com/v1alpha1 kind: VenafiInstall metadata: name: venafi-components spec: globals: enableDefaultApprover: true # (1)! imagePullSecretNames: [venafi-image-pull-secret] namespace: venafi vcpRegion: US region: US certManager: install: true firefly: install: true acceptTOS: true clientID: ${FIREFLY_SERVICE_ACCOUNT_CLIENT_ID} # (2)! certManagerIstioCSR: install: true trustDomain: cluster.local # (3)! runtimeConfigMapName: istio-csr-ca # (4)! values: app: certmanager: preserveCertificateRequests: true additionalAnnotations: - name: firefly.venafi.com/policy-name value: ${FIREFLY_POLICY_NAME} controller: configmapNamespaceSelector: "maistra.io/member-of=istio-system" istio: namespace: istio-system revisions: ["basic"] tls: rootCAFile: /firefly-root-ca/ca.crt volumeMounts: - name: firefly-root-ca mountPath: /firefly-root-ca volumes: - name: firefly-root-ca secret: secretName: firefly-root-ca
- Istio CSR works best with the cert-manager default approver.
- Replace with the client ID of the Firefly service account.
- Provide the name of the Istio trust domain.
- This is the default name of the ConfigMap from which Istio CSR loads runtime configuration. You will create this ConfigMap in the next steps, in the
venafi
namespace, where Istio CSR is deployed.
Regional registries
The example above uses the Venafi US registry parameters. If you want to use a different Venafi registry replace
vcpRegion: US
andregion: US
with the relevant regional repository value:-
EU registry
venafi-components.yaml... spec: globals: ... vcpRegion: EU region: EU ...
-
UK registry
venafi-components.yaml... spec: globals: ... vcpRegion: UK region: UK ...
-
Australian registry
venafi-components.yaml... spec: globals: ... vcpRegion: AU region: AU ...
For more information on Venafi OCI registries, see Configuring access to a Venafi OCI Registry.
venafi-components.yamlapiVersion: installer.venafi.com/v1alpha1 kind: VenafiInstall metadata: name: venafi-components spec: globals: enableDefaultApprover: true # (1)! imagePullSecretNames: [venafi-image-pull-secret] namespace: venafi certManager: install: true firefly: install: true acceptTOS: true clientID: ${FIREFLY_SERVICE_ACCOUNT_CLIENT_ID} # (2)! certManagerIstioCSR: install: true trustDomain: cluster.local # (3)! runtimeConfigMapName: istio-csr-ca # (4)! values: app: certmanager: preserveCertificateRequests: true additionalAnnotations: - name: firefly.venafi.com/policy-name value: ${FIREFLY_POLICY_NAME} controller: configmapNamespaceSelector: "maistra.io/member-of=istio-system" istio: namespace: istio-system revisions: ["basic"] tls: rootCAFile: /firefly-root-ca/ca.crt volumeMounts: - name: firefly-root-ca mountPath: /firefly-root-ca volumes: - name: firefly-root-ca secret: secretName: firefly-root-ca
- Istio CSR works best with the cert-manager default approver.
- Replace with the client ID of the Firefly service account.
- Provide the name of the Istio trust domain.
- This is the default name of the ConfigMap from which Istio CSR loads runtime configuration. You will create this ConfigMap in the next steps, in the
venafi
namespace, where Istio CSR is deployed.
Notes
Use the
trustDomain
field to specify the Istio trust domain.Tip
For a complete list of Venafi Control Plane Operator configuration parameters, see the Venafi Control Plane Operator API reference page.
-
Apply the manifest:
export FIREFLY_SERVICE_ACCOUNT_CLIENT_ID=<REPLACE_ME> export FIREFLY_POLICY_NAME=<REPLACE_ME> oc apply -f <(envsubst < venafi-components.yaml)
Info
We use
envsubst
to substitute some Firefly configuration in the YAML template. Alternatively, you could edit the YAML directly and then apply it. -
Monitor the progress of the installation.
You can monitor the actions that are being performed by the Venafi Control Plane Operator, as follows:
oc describe VenafiInstall -namespace venafi
oc logs deploy/vcp-operator --follow --namespace venafi
oc get events --watch --namespace venafi
Step 8: Verify the installation¶
-
Verify whether cert-manager, Istio CSR and Firefly are successfully installed by running the following command:
oc get venafiinstall,pods --namespace venafi
Sample output:
NAME STATUS LAST SYNC venafiinstall.installer.venafi.com/venafi-components Synced 103s NAME READY STATUS RESTARTS AGE pod/cert-manager-bf4fdfdbb-cvnqb 1/1 Running 0 4m13s pod/cert-manager-cainjector-57b7b6f978-mtw5n 1/1 Running 0 4m13s pod/cert-manager-istio-csr-b446698f7-xtl59 1/1 Running 0 118s pod/cert-manager-webhook-857699b5bc-9fmdj 1/1 Running 0 4m13s pod/firefly-588458dcbd-pb7r6 1/1 Running 0 119s pod/firefly-588458dcbd-xxw4n 1/1 Running 0 119s pod/vcp-operator-5f5854b74c-wqs6q 1/1 Running 0 137m
Warning
There is a known issue in Firefly where its readiness checks fail after a time.
Step 9: Create an Istio CSR "runtime configuration"¶
Istio CSR need some more "runtime configuration" to know what issuerRef
to use for the Certificate and CertificateRequests that it generates..
-
Create the following ConfigMap:
istio-ca.yaml# The runtime configuration ConfigMap that tells Istio CSR which issuer to use. # This is installed in the **venafi** namespace. # The name must match the name given in the VenafiInstall resource earlier. apiVersion: v1 kind: ConfigMap metadata: name: istio-csr-ca namespace: venafi data: issuer-name: firefly issuer-kind: Issuer issuer-group: firefly.venafi.com
-
Apply the manifest by running the following command:
oc apply -f istio-ca.yaml
After you apply the ConfigMap, Istio CSR will create a cert-manager Certificate referencing the Firefly issuer, which cert-manager will reconcile and place the resulting leaf certificate in a Secret called
istiod-tls
.istiod
in theistio-system
namespace will use that signed certificate for its gRPC server. -
Monitor the Istio CSR controller:
If you want to understand what actions are being performed by Istio CSR, you can monitor its logs, as follows:
oc logs deploy/cert-manager-istio-csr --follow --namespace venafi
-
Verify that the CA certificate has been created:
oc -n istio-system get cert-manager,configmap,secret
Sample output:
NAME APPROVED DENIED READY ISSUER REQUESTER AGE certificaterequest.cert-manager.io/istiod-dynamic-1 True True firefly system:serviceaccount:venafi:cert-manager 3m20s NAME READY SECRET AGE certificate.cert-manager.io/istiod-dynamic True istiod-tls 3m21s NAME DATA AGE configmap/kube-root-ca.crt 1 15m configmap/openshift-service-ca.crt 1 15m NAME TYPE DATA AGE secret/builder-dockercfg-cgfvn kubernetes.io/dockercfg 1 15m secret/default-dockercfg-h5x89 kubernetes.io/dockercfg 1 15m secret/deployer-dockercfg-r9t4q kubernetes.io/dockercfg 1 15m secret/istiod-tls kubernetes.io/tls 2 3m20s
-
Examine the resulting
istiod-tls
certificate.The resulting
istiod
serving certificate should have been signed by your Firefly Sub CA. You can check this using the following command:oc get secret istiod-tls -n istio-system -o jsonpath='{.data.tls\.crt}' \ | base64 -d \ | openssl x509 -noout -text
Certificate: Data: Version: 3 (0x2) Serial Number: 33:fb:0b:06:8c:c0:c5:48:70:08:ac:40:35:90:2a:bb Signature Algorithm: sha256WithRSAEncryption Issuer: C = GB, ST = England, L = Bristol, O = Venafi, OU = Team cert-manager, CN = firefly-1-20241217171011 firefly-richardw-1 Validity Not Before: Dec 17 17:18:49 2024 GMT Not After : Mar 17 17:18:49 2025 GMT Subject: CN = istiod.istio-system.svc ... X509v3 Subject Alternative Name: DNS:istiod-basic.istio-system.svc, URI:spiffe://cluster.local/ns/istio-system/sa/istiod-service-account ...
The certificate should also have a DNS name for an Istio revision named basic. The revision name basic represents the name of the ServiceMeshControlPlane (SCMP) which you will deploy in the next step.
Important
If you have previously deployed Istio and later deleted it, some resources may have been left behind in the
istio-system
namespace, which may interfere with Istio CSR. In particular, you should delete the following Secret resources which may contain stale CA certificates:cacerts
istio-ca-secret
You can see the priority of loading of CA certificates in the istio-operator webhook CA source code.
Info
Read 2.3.4. Upgrading the control plane in the OpenShift documentation which has this to say about the use of revision for supporting multiple service meshes in a cluster,rather than for supporting canary upgrades:
Although you can deploy multiple versions of the control plane in the same cluster, Red Hat OpenShift Service Mesh does not support canary upgrades of the service mesh. That is, you can have different SCMP resources with different values for spec.version, but they cannot be managing the same mesh.
Step 10: Deploy the Service Mesh Control Plane¶
The ServiceMeshControlPlane object creates an istiod
control plane, you use this to configure your service-mesh to use cert-manager Istio CSR to sign certificates.
-
Create a ServiceMeshControlPlane
istio-installation.yamlapiVersion: maistra.io/v2 kind: ServiceMeshControlPlane metadata: name: basic namespace: istio-system spec: version: v2.6 addons: grafana: enabled: false prometheus: enabled: false kiali: enabled: false gateways: enabled: false security: certificateAuthority: cert-manager: address: cert-manager-istio-csr.venafi.svc:443 type: cert-manager dataPlane: mtls: true identity: type: ThirdParty tracing: type: None --- apiVersion: maistra.io/v1 kind: ServiceMeshMemberRoll metadata: name: default namespace: istio-system spec: members: - test-project-1
oc apply -f istio-installation.yaml
Important
If you have previously deployed Istio and later deleted it, some resources may have been left behind in the
istio-system
namespace, which may interfere with Istio CSR. In particular, you should delete the following Secret resources which may contain stale CA certificates:cacerts
istio-ca-secret
You can see the priority of loading of CA certificates in the istio-operator webhook CA source code.
Info
We disabled all addons and gateways, to reduce the resource requirements for the Istio control plane, which allows us to verify this tutorial on a single node CRC (Code Ready Containers) cluster. In production, you may want to enable the add-ons and gateways.
Info
The ServiceMeshMemberRoll contains a reference to the
test-project-1
project (namespace) which we will create in the next step. This ensures that themaistra.io/member-of: istio-system
label will be added to the namespace when we create it.
Step 11: Verify mTLS¶
-
First, create a new project to deploy some sample applications:
oc new-project test-project-1
-
Verify that the namespace has been labelled.
The ServiceMeshMemberRoll which we created in the previous step, contains a reference to the
test-project-1
project (namespace) which tells the OpenShift Service Mesh Operator to add themaistra.io/member-of: istio-system
label to the namespace. You can see this by using the following command:oc get ns test-project-1 -o yaml
-
Verify that the Istio CA has been added to the namespace.
The presence of the
maistra.io/member-of: istio-system
label on the namespace, tells Istio CSR to create anistio-ca-root-cert
ConfigMap in the namespace. You can see this as follows:oc get cm istio-ca-root-cert -o yaml --namespace test-project-1
If you're following the Istio CSR logs, you'll also see a message like this:
I1219 14:18:44.090159 1 configmap.go:188] "creating configmap with root CA data" logger="controller.configmap" namespace="test-project-1" configmap="istio-ca-root-cert"
-
Deploy a sample server and a sample client:
oc apply -n test-project-1 -f https://raw.githubusercontent.com/maistra/istio/maistra-2.4/samples/httpbin/httpbin.yaml
oc apply -n test-project-1 -f https://raw.githubusercontent.com/maistra/istio/maistra-2.4/samples/sleep/sleep.yaml
-
Verify that the server is using a Firefly issued certificate.
In these examples, we
exec
into the Istio side-car container of thesleep
Pod, and run theopenssl
tool to examine the TLS connection to thehttpbin
server:oc exec deploy/sleep -n test-project-1 -c istio-proxy \ -- openssl s_client -CAfile /var/run/secrets/istio/root-cert.pem httpbin:8000
oc exec deploy/sleep -n test-project-1 -c istio-proxy \ -- openssl s_client -CAfile /var/run/secrets/istio/root-cert.pem httpbin:8000 \ | openssl x509 -noout -text
You should see the details of the serving certificate returned by the istio-proxy of the
httpbin
server, and you should see that it has been signed by our Firefly Sub CA. Here's an example of the output:CONNECTED(00000003) --- Certificate chain 0 s:O = i:C = GB, ST = England, L = Bristol, O = Venafi, OU = Team cert-manager, CN = firefly-1-20241219114107 firefly-richardw-1 a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256 v:NotBefore: Dec 19 15:40:34 2024 GMT; NotAfter: Mar 19 15:40:34 2025 GMT 1 s:C = GB, ST = England, L = Bristol, O = Venafi, OU = Team cert-manager, CN = firefly-1-20241219114107 firefly-richardw-1 i:C = US, O = "Venafi, Inc.", OU = Built-in, CN = Dedicated - Venafi Cloud Built-In Intermediate CA - G1 a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256 v:NotBefore: Dec 19 11:40:46 2024 GMT; NotAfter: Mar 19 11:41:16 2025 GMT 2 s:C = US, O = "Venafi, Inc.", OU = Built-in, CN = Dedicated - Venafi Cloud Built-In Intermediate CA - G1 i:C = US, O = "Venafi, Inc.", OU = Built-in, CN = Dedicated - Venafi Cloud Built-In CA a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256 v:NotBefore: Jul 21 21:34:37 2023 GMT; NotAfter: Jul 19 21:35:07 2028 GMT 3 s:C = US, O = "Venafi, Inc.", OU = Built-in, CN = Dedicated - Venafi Cloud Built-In CA i:C = US, O = "Venafi, Inc.", OU = Built-in, CN = Dedicated - Venafi Cloud Built-In CA a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256 v:NotBefore: Jul 21 21:34:36 2023 GMT; NotAfter: Jul 18 21:35:06 2033 GMT 4 s:C = US, O = "Venafi, Inc.", OU = Built-in, CN = Dedicated - Venafi Cloud Built-In Intermediate CA - G1 i:C = US, O = "Venafi, Inc.", OU = Built-in, CN = Dedicated - Venafi Cloud Built-In CA a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256 v:NotBefore: Jul 21 21:34:37 2023 GMT; NotAfter: Jul 19 21:35:07 2028 GMT