How to integrate SPRIRE in Istio?

Note: SPIRE support is a new feature of Istio 1.14, please make sure to install Istio 1.14 and above.

Install Istio

to GitHub
Download the Istio installation package from above. After decompressing, it is recommended to use istioctl install Istio.

 istioctl install --set profile = demo

If you have an Istio version lower than 1.14 installed, please upgrade Istio first.

Install SPIRE

We use the quick installation method provided by Istio:

 kubectl apply -f samples/security/spire/spire-quickstart.yaml

This will install the following components:

 namespace/spire created csidriver.storage.k8s.io/csi.spiffe.io created customresourcedefinition.apiextensions.k8s.io/spiffeids.spiffeid.spiffe.io created clusterrolebinding.rbac.authorization.k8s.io/k8s-workload-registrar-role-binding created clusterrole.rbac.authorization.k8s.io/k8s-workload-registrar-role created configmap/k8s-workload-registrar created serviceaccount/spire-server created configmap/trust-bundle created clusterrole.rbac.authorization.k8s.io/spire-server-trust-role created clusterrolebinding.rbac.authorization.k8s.io/spire-server-trust-role-binding created configmap/spire-server created statefulset.apps/spire-server created service/spire-server created serviceaccount/spire-agent created clusterrole.rbac.authorization.k8s.io/spire-agent-cluster-role created clusterrolebinding.rbac.authorization.k8s.io/spire-agent-cluster-role-binding created configmap/spire-agent created daemonset.apps/spire-agent created

It needs to be patched so that all sidecars and ingresses can share the UNIX Domain Socket of SPIRE agent.

 istioctl install --skip-confirmation -f - <<EOF apiVersion : install.istio.io/v1alpha1 kind : IstioOperator metadata :   namespace : istio-system spec :   profile : default   meshConfig :     trustDomain : example.org   values :     global :     # This is used to customize the sidecar template     sidecarInjectorWebhook :       templates :         spire : |  spec: containers: - name: istio-proxy volumeMounts: - name: workload-socket mountPath: /run/secrets/workload-spiffe-uds readOnly: true volumes: - name: workload-socket csi: driver: "csi.spiffe.io"             components :     ingressGateways :       - name : istio-ingressgateway         enabled : true         label :           istio : ingressgateway         k8s :           overlays :             - apiVersion : apps/v1               kind : Deployment               name : istio-ingressgateway               patches :                 - path : spec.template.spec.volumes.[name:workload-socket]                   value :                     name : workload-socket                     csi :                       driver : "csi.spiffe.io"                 - path : spec.template.spec.containers.[name:istio-proxy].volumeMounts.[name:workload-socket]                   value :                     name : workload-socket                     mountPath : "/run/secrets/workload-spiffe-uds"                     readOnly : true EOF 

With Istio and SPIRE installed, we can register the payload.

Automatically register Kubernetes payloads

During the quick install of SPIRE, we already installed the SPRIE Kubernetes Workload Registrar
, which means that we have turned on automatic load registration. Now check to see if SPIRE issued an identity certificate to the payload.

 kubectl exec -i -t spire-server-0 -n spire -c spire-server -- /bin/sh -c "bin/spire-server entry show -socketPath /run/spire/sockets/server.sock"

You will see results like the following:

 # Node Entry ID : 3f17c8be-1379-4b7c-9a01-90805165d59f SPIFFE ID : spiffe://example.org/k8s-workload-registrar/demo-cluster/node/gke-jimmy-cluster-default-pool-d5041909-3atb Parent ID : spiffe://example.org/spire/server Revision : 0 TTL : default Selector : k8s_psat:agent_node_uid:cbab5123-b32f-49d0-89f2-0a7e4d2b0edd Selector : k8s_psat:cluster:demo-cluster # Ingress gateway Entry ID : ffc76b2e-e602-4ad3-8069-993ffbf4440e SPIFFE ID : spiffe://example.org/ns/istio-system/sa/istio-ingressgateway-service-account Parent ID : spiffe://example.org/k8s-workload-registrar/demo-cluster/node/gke-jimmy-cluster-default-pool-d5041909-0ucb Revision : 1 TTL : default Selector : k8s:node-name:gke-jimmy-cluster-default-pool-d5041909-0ucb Selector : k8s:ns:istio-system Selector : k8s:pod-uid:be32b10a-b5a4-4716-adaf-eab778f58c13 DNS name : istio-ingressgateway-6989cbc776-87qb6 DNS name : istio-ingressgateway.istio-system.svc # SPIRE Server Entry ID : 54444848-95ec-4b4d-a7c5-902a4049c96a SPIFFE ID : spiffe://example.org/ns/spire/sa/spire-server Parent ID : spiffe://example.org/k8s-workload-registrar/demo-cluster/node/gke-jimmy-cluster-default-pool-d5041909-0ucb Revision : 1 TTL : default Selector : k8s:node-name:gke-jimmy-cluster-default-pool-d5041909-0ucb Selector : k8s:ns:spire Selector : k8s:pod-uid:4917defc-9b5a-42d8-9b98-c0e0a48c0313 DNS name : spire-server-0 DNS name : spire-server.spire.svc

The parent ID of each node is spiffe://example.org/ns/spire/sa/spire-server , and the parent of spiffe spiffe://example.org/ns/spire/sa/spire-server is spiffe://example.org/k8s-workload-registrar/demo-cluster/node/gke-jimmy-cluster-default-pool-d5041909-0ucb .

That is to say, the hierarchy of workloads is as follows:

  1. SPIRE Server: spiffe://example.org/spire/server

  2. Kubernetes node: spiffe://example.org/k8s-workload-registrar/demo-cluster/node/

  3. Normal service account: spiffe://example.org/{namespace}/spire/sa/{service_acount}

SPIRE creates SPIFFE IDs for workloads selected via a tag selector.

A workload’s SPIFEE ID is in the format spiffe://<trust.domain>/ns/<namespace>/sa/<service-account> .

Deploy the application

Next we deploy an application, and then check that SPIRE is the identity it should provide.

Deploy the sample application sleep provided by Istio with the following command:

 istioctl kube-inject --filename samples/security/spire/sleep-spire.yaml | kubectl apply -f -

Because we patched when we installed Istio and made SPIRE automatic injection, then all pods will share the UNIX Domain Socket in SPIRE Agent: /run/secrets/workload-spiffe-uds/socket . Getting the YAML of the running sleep pod, we can see that it has a volume configured as follows:

  volumes :     - name : workload-socket       csi :         driver : csi.spiffe.io 

and volumeMounts as follows:

      volumeMounts :         - name : workload-socket           readOnly : true           mountPath : /run/secrets/workload-spiffe-uds         - name : workload-socket           mountPath : /var/run/secrets/workload-spiffe-uds         - name : workload-certs           mountPath : /var/run/secrets/workload-spiffe-credentials         - name : istiod-ca-cert 

This all confirms that the SPRIE Agent shares the UNIX Domain Socket with the workload pod.

Let’s query the SPIRE entry in the Kubernetes cluster again, and you will see that the sleep entry has been registered.

 Entry ID : bd4457af-c55c-4d8c-aee2-4d477a79b465 SPIFFE ID : spiffe://example.org/ns/default/sa/sleep Parent ID : spiffe://example.org/k8s-workload-registrar/demo-cluster/node/gke-jimmy-cluster-default-pool-d5041909-3atb Revision : 1 TTL : default Selector : k8s:node-name:gke-jimmy-cluster-default-pool-d5041909-3atb Selector : k8s:ns:default Selector : k8s:pod-uid:81f116ce-6538-4492-a78a-98b163b58310 DNS name : sleep-9df96d88-tvl49 DNS name : sleep.default.svc

Check the SVID of sleep again.

 istioctl proxy-config secret $SLEEP_POD -o json | jq -r \ '.dynamicActiveSecrets[0].secret.tlsCertificate.certificateChain.inlineBytes' | base64 --decode > chain.pem

The above command obtains the secret of Envoy in the sleep pod, parses the TLS certificate in it, decodes it base64 and saves it to the chain.pem file.

 openssl x509 -in chain.pem -text | grep SPIRE

Using OpenSSL to resolve the issuer, you will get the following result.

 Subject: C = US, O = SPIRE, CN = sleep-9df96d88-tvl49

SPIFFE also supports federation. You can configure bundles for SPIRE Agent SDS. You also need to add the annotation spiffe.io/federatesWith: "<trust.domain>" to the pod, and then Envoy will obtain the bundle from the SPRIE Server. For detailed steps, please refer to Istio official documentation
.

The above is the whole process of integrating SPIRE in Istio.

refer to

This article is reprinted from https://jimmysong.io/blog/how-to-integrate-spire-with-istio/
This site is for inclusion only, and the copyright belongs to the original author.

Leave a Comment