Demo to build Service Mesh on Kubernetese using Envoy as data plane and SPIRE and OPA as control plane. This demo is zlabjp/spiffejp-demo with OPA added.
- Use Kubernetes 1.17.0
- Use Envoy 1.12.2, SPIRE 0.9.0 and OPA 0.15.1
- Envoy uses SPIRE as SDS Server to obtain TLS certificate
- Envoy uses OPA as External Authorization Server to check if the incoming request is authorized or not
Blog is here. (Japanese)
Four services are running in Kubernetes Cluster.
- ec-web(
spiffe://example.org/ec-web)ec-webONLY accept requests with custom header "X-Opa-Secret" containing "ec-web-secret" value
- ec-backend(
spiffe://example.org/ec-backend)ec-backendcan ONLY be accessed fromec-web
- news-web(
spiffe://example.org/news-web)news-webONLY accept requests with custom header "X-Opa-Secret" containing "news-web-secret" value
- news-backend(
spiffe://example.org/news-backend)news-backendcan ONLY be accessed fromnews-web
- Authentication using SPIRE
- Authorization using OPA
Create a Kubernetes cluster with the required flags to run NodeAttestor "k8s_psat" in SPIRE.
minikube start \
--kubernetes-version v1.17.0 \
--extra-config=apiserver.service-account-signing-key-file=/var/lib/minikube/certs/sa.key \
--extra-config=apiserver.service-account-key-file=/var/lib/minikube/certs/sa.pub \
--extra-config=apiserver.service-account-issuer=api \
--extra-config=apiserver.service-account-api-audiences=api,spire-serverDeploy SPIRE Server as StatefulSet.
kubectl apply -f spire-server.yamlDeploy SPIRE Agent as DaemonSet.
kubectl apply -f spire-agent.yamlCreate node entry.
kubectl exec -n spire spire-server-0 -- /opt/spire/bin/spire-server entry create \
-spiffeID spiffe://example.org/node \
-selector k8s_psat:cluster:demo-cluster \
-nodeCreate workload entries.
kubectl exec -n spire spire-server-0 -- /opt/spire/bin/spire-server entry create \
-parentID spiffe://example.org/node \
-spiffeID spiffe://example.org/ec-web \
-selector k8s:pod-label:app:ec-web
kubectl exec -n spire spire-server-0 -- /opt/spire/bin/spire-server entry create \
-parentID spiffe://example.org/node \
-spiffeID spiffe://example.org/ec-backend \
-selector k8s:pod-label:app:ec-backend
kubectl exec -n spire spire-server-0 -- /opt/spire/bin/spire-server entry create \
-parentID spiffe://example.org/node \
-spiffeID spiffe://example.org/news-web \
-selector k8s:pod-label:app:news-web
kubectl exec -n spire spire-server-0 -- /opt/spire/bin/spire-server entry create \
-parentID spiffe://example.org/node \
-spiffeID spiffe://example.org/news-backend \
-selector k8s:pod-label:app:news-backendConfirm the created registration entries.
kubectl exec -n spire spire-server-0 -- /opt/spire/bin/spire-server entry showDeploy four services. SPIRE Agent (Unix Domain Socket) mounts on Envoy container and run Envoy and OPA as sidecar.
kubectl apply -f ec-backend.yaml
kubectl apply -f ec-web.yaml
kubectl apply -f news-backend.yaml
kubectl apply -f news-web.yamlExpect 200 OK response.
curl -i -H 'Host: ec-web.example.org' -H 'X-Opa-Secret: ec-web-secret' http://$(minikube ip)/noproxy
curl -i -H 'Host: news-web.example.org' -H 'X-Opa-Secret: news-web-secret' http://$(minikube ip)/noproxyExpect 403 Forbidden response.
curl -i -H 'Host: ec-web.example.org' http://$(minikube ip)/noproxy
curl -i -H 'Host: news-web.example.org' http://$(minikube ip)/noproxyExpect 200 OK response.
curl -i -H 'Host: ec-web.example.org' -H 'X-Opa-Secret: ec-web-secret' http://$(minikube ip)/data
curl -i -H 'Host: news-web.example.org' -H 'X-Opa-Secret: news-web-secret' http://$(minikube ip)/dataExpect 403 Forbidden response.
curl -i -H 'Host: ec-web.example.org' -H 'X-Opa-Secret: ec-web-secret' http://$(minikube ip)/admin
curl -i -H 'Host: news-web.example.org' -H 'X-Opa-Secret: news-web-secret' http://$(minikube ip)/adminExpect 403 Forbidden response.
curl -i -H 'Host: news-web.example.org' -H 'X-Opa-Secret: news-web-secret' http://$(minikube ip)/ec-backend-datakubectl delete -f spire-server.yaml
kubectl delete -f spire-agent.yaml
kubectl delete -f ec-backend.yaml
kubectl delete -f ec-web.yaml
kubectl delete -f news-backend.yaml
kubectl delete -f news-web.yamlMIT

