Use a custom Certificate Authority with Istio
This guide demonstrates how to modify the default IstioControlPlane
Custom Resource (CR) provided by Streaming Data Manager to provision workload certificates using a custom certificate authority (CA) which integrates with the Kubernetes Certificate Signing Request (CSR) API.
Load the CA’s root certificate
Load the CA’s root certificate into a secret that istiod can access.
$ cat <<EOF > ./external-ca-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: external-ca-cert
namespace: istio-system
data:
root-cert.pem: <tls.cert>
EOF
$ kubectl apply -f external-ca-secret.yaml
Replace <tls.cert>
with the CA’s base64 encoded public key (without line wrapping).
This step is necessary for Istio to verify that the workload certificates have been signed by the correct certificate authority and to add the root-cert to the trust bundle for mTLS to work.
Modify the IstioControlPlane CR
-
Add the
EXTERNAL_CA
andK8S_SIGNER
environment variables to thespec.istiod.deployment
section of theIstioControlPlane
CR. These configure istiod to use an external signer and specify the name of the signer to use.apiVersion: servicemesh.cisco.com/v1alpha1 kind: IstioControlPlane metadata: name: istio-sample-v115x ... spec: ... istiod: deployment: image: "033498657557.dkr.ecr.us-east-2.amazonaws.com/banzaicloud/istio-pilot:v1.15.3-bzc" env: # Indicate to Istiod that we use an external signer - name: EXTERNAL_CA value: ISTIOD_RA_KUBERNETES_API # Indicate to Istiod the external K8S Signer Name - name: K8S_SIGNER value: csr.banzaicloud.io/privateca ...
-
Mount an overlay patch to inject the secret created above into Istio. Add this modification to the
IstioControlPlane
CR:k8sResourceOverlays: - groupVersionKind: group: apps kind: Deployment version: v1 objectKey: name: istiod-<icp-name> patches: - parseValue: true path: /spec/template/spec/volumes/- type: replace value: | name: external-ca-cert secret: secretName: external-ca-cert optional: true - parseValue: true path: /spec/template/spec/containers/name=discovery/volumeMounts/- type: replace value: | name: external-ca-cert mountPath: /etc/external-ca-cert readOnly: true
Replace
<icp-name>
above with the name of theIstioControlPlane
CR. For example, if the name field in theIstioControlPlane
CR is set toistio-sample-v115x
, this should beistiod-istio-sample-v115x
. -
Patch the istiod ClusterRole to give it permission to approve Certificate Signing Requests with the
csr.banzaicloud.io/privateca
signer name. Add this section to theIstioControlPlane
CR as well:k8sResourceOverlays: - groupVersionKind: group: rbac.authorization.k8s.io kind: ClusterRole version: v1 objectKey: name: <istiod-clusterrole-name> patches: - parseValue: true path: /rules/- type: replace value: | apiGroups: - certificates.k8s.io resourceNames: - csr.banzaicloud.io/privateca resources: - signers verbs: - approve
Replace
<istiod-clusterrole-name>
above with the name of the Istiod ClusterRole object. For example, if the name and the namespace field in theIstioControlplane
CR are set toistio-sample-v115x
andistio-system
,respectively, this should beistiod-istio-sample-v115x-istio-system
. -
Deploy the modified
IstioControlPlane
CR into your cluster and verify that theistiod-istio-sample-v115x-istio-system
ClusterRole has permission to approvecertificatesigningrequests.certificates.k8s.io
resources.
Test the modified IstioControlPlane CR
To test the IstioControlPlane
CR modifications you can deploy any pod to a namespace where injection is enabled. For example, to deploy a test image you can use the following spec:
apiVersion: v1
kind: Pod
metadata:
name: connect-test
spec:
containers:
- name: kafka-test
image: ubuntu:latest
# Just spin and wait forever
command: ["bin/bash", "-c", "--" ]
args: [ "while true; do sleep 3000; done;" ]
If the connect-test pod is up and running, your custom CA has been successfully integrated with Istio.