The following guide presumes you have done the following:
- Provisioned an Azure KeyVault
- Provisioned a Kubernetes Cluster
- Installed the Istio Service Mesh
- Installed and configured the kubernetes-keyvault-flexvol project with a Service Principal
- The Azure CLI installed
- OpenSSL tools installed
Additionally, you'll need to confirm that you can make changes to the istio-ingressgateway
deployment in the istio-system
namespace. We will be making changes to the canonical yaml that represents the ingress gateway.
To demonstrate configuring Istio to work with an SSL certificates hosted in Keyvault, let's create a self signed certificate and private key. In a production setting, you will want a signed certificate from a trusted issuer. Let's Encrypt offers signed certificates for free, with the understanding that the certificates expire in 90 days.
To create a certificate and private key, run the following in your terminal, and fill out the information requested:
openssl req -x509 -newkey rsa:2048 -keyout certificate-private.key -out certificate.crt -days 365 -nodes
OpenSSL will create a certificate (certificate.crt) and a private key (certificate-private.key). We will be upload these to Keyvault.
Keyvault expects that a certificate be uploaded with it's private key. To do this, we concatenate the certificate with the private key into a new file, certificate.includesprivatekey.pem:
cat certificate.crt certificate-private.key > certificate.includesprivatekey.pem
Then, we upload the certificate and private key to Keyvault.
Certificate:
az keyvault certificate import -n mycertificate --vault-name mykeyvault -f certificate.includesprivatekey.pem
Private key:
az keyvault key import -n myprivatekey --vault-name mykeyvault -f certificate-private.key
From here on, configuration is manual. As of Istio 1.0.6, Istio does not yet support configuring the ingress gateway to support external Key Management Services. Refer to the Istio 1.0.6 sample ingress-gateway for how to configure the ingressgateway. Let's break this sample down.
To the ingress gateway, we add an extra read-only volume mount that refers to the keyvault-certs
volume, which is mounted by the kubernetes-keyvault-flexvolume plugin:
- mountPath: /etc/istio/keyvault-certs
name: keyvault-certs
readOnly: true
We also add an extra volume that is referred to by the volume mount above:
- name: keyvault-certs
flexVolume:
driver: "azure/kv"
secretRef:
name: kvcreds
options:
usepodidentity: "false"
keyvaultname: "mykeyvault"
keyvaultobjectnames: "myprivatekey;mycertificate"
keyvaultobjecttypes: "key;cert"
tenantid: "azuretenantid"
In the above example, we declare a volume named keyvault-certs
, and configure the Keyvault volume driver with a secret backed by a service principal. We also configure the names of the private key and certificate, and the types of secrets requested from Keyvault, along with the resource group of the Keyvault, the subcription id, and the tenant id.
Next, we configure an Istio Gateway on port 443. See the provided gateway sample for a full example of a configured gateway:
- port:
number: 443
name: https
protocol: HTTPS
tls:
mode: SIMPLE
serverCertificate: /etc/istio/keyvault-certs/mycertificate
privateKey: /etc/istio/keyvault-certs/myprivatekey
As we've configured the Ingress Gateway Deployment to read certificates from Keyvault, we can simply point the gateway's tls options to the certificate and private key pulled down from Keyvault, and mounted in the Ingress Gateway's keyvault-certs volume.
Once the above steps are done, you can deploy the sample echo-apple application provided to your cluster. The sample application utilizes the Gateway configured above to route ingress traffic to your service over https.