This is the guideline to set up Istio with KeyfactorCA
- Build Instructions: Link
- Code repository: https://github.com/thedemodrive/istio
- Docker images: https://hub.docker.com/orgs/thedemodrive/repositories
- These steps require you to have a cluster running a compatible version of Kubernetes. You can use any supported platform, for example Minikube or others specified by the platform-specific setup instructions.
- Download binary file at: Click here to download setup binary
- Add the
istioctl
client to your path (Linux or macOS or Windows):- OSX:
istioctl-osx
- Linux:
istioctl-linux-amd64
- Windows:
istioctl-win.exe
- OSX:
- Create a file
./root-cert.pem
contains root certificate from Keyfactor
Create kubernetes secrets with the root-cert (Istiod need root cert to handshake mTLS with IstioAgents)
kubectl create namespace istio-system
kubectl create secret generic cacerts -n istio-system --from-file=./root-cert.pem
file: ./root-cert.pem is CA pem of KeyfactorCA
- Create secret
example-keyfactor-secret
to contains Credentials Keyfactor
Update Keyfactor Credentials within file: ./keyfactor-secret-example.yaml
---
apiVersion: v1
kind: Secret
metadata:
name: keyfactor-secret-example
namespace: istio-system
type: Opaque
stringData:
# Name of certificate authorization
caName: ""
# Using for authentication header
authToken: ""
# Certificate Template for enroll the new one: Default is Istio
caTemplate: "Istio"
# ApiKey from Api Setting
appKey: ""
Create Kubernetes secret with command:
kubectl apply -f ./keyfactor-secret-example.yaml
- Update the Keyfactor configuration at
./keyfactor-with-secret.yaml
---
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
namespace: istio-system
name: keyfactor-with-secret
spec:
profile: demo
values:
global:
hub: thedemodrive
tag: final-01
imagePullPolicy: "Always"
multiCluster:
clusterName: FinalBuildCluster
controlPlaneSecurityEnabled: true
caProvider: "KeyfactorCA"
caAddress: ""
# Configure the external CA Provider by Keyfactor.
keyfactor:
#####
# SecretName name of secret contain Keyfactor Credentials
# Let empty for using yaml config
# Each namespace must have one secret (pod only ready secret within namespace)
secretName: "keyfactor-secret-example"
######
# Customize metadata fields to carry with CSR enroll certificates
# Remove from list if you dont need
# Only support for: Cluster, Service, PodName, PodNameSpace, PodIP, TrustDomain.
metadata:
# Cluster ClusterID or ClusterName of Istio Mesh
- name: Cluster # Name of field in Istio, do not change it
alias: Cluster # Name of custom metadata field on Keyfactor Platform to mapping
# Service name of service
- name: Service
alias: Service
# - name: PodName
# alias: PodName
# - name: PodNamespace
# alias: PodNamespace
# - name: PodIP
# alias: PodIP
# TrustDomain is Kubernetes's domain, default value is cluster.local
# - name: TrustDomain
# alias: TrustDomain
-
Install with Istioctl
istioctl manifest --set installPackagePath=installs apply -f ./keyfactor-with-secret.yaml
- Update the Keyfactor configuration at
./keyfactor-config.yaml
---
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
namespace: istio-system
name: keyfactor-yaml-config
spec:
profile: demo
values:
global:
hub: thedemodrive
tag: final-01
imagePullPolicy: "Always"
multiCluster:
clusterName: FinalBuildCluster
controlPlaneSecurityEnabled: true
caProvider: "KeyfactorCA"
caAddress: ""
# Configure the external CA Provider by Keyfactor.
keyfactor:
########
# SecretName name of secret contain Keyfactor Credentials
# Let empty for using yaml config
# Each namespace must have one secret (pod only ready secret within namespace)
secretName: ""
# Name of certificate authorization
caName: ""
# Using for authentication header
authToken: ""
# ApiKey from Api Setting
appKey: ""
# Name of Keyfactor template
caTemplate: "Istio"
########
# Custom metadata fields attached to CSR request CSR enroll certificates
# Remove from list if you dont need
# Only support for: Cluster, Service, PodName, PodNameSpace, PodIP, TrustDomain.
metadata:
- name: Cluster # Do not modified it
alias: Cluster # Name of custom metadata field on Keyfactor Platform
- name: Service
alias: Service
# - name: PodName
# alias: PodName
# - name: PodNamespace
# alias: PodNamespace
# - name: PodIP
# alias: PodIP
# - name: TrustDomain
# alias: TrustDomain
-
Install with Istioctl
istioctl manifest --set installPackagePath=installs apply -f ./keyfactor-config.yaml
Deploy Book-Info microservice example of Istio (references)
-
Turn on Istio auto-inject for namespace default
kubectl label namespace default istio-injection=enabled
-
Deploy an example of istio (Book-Info)
kubectl apply -f ./samples/bookinfo/platform/kube/bookinfo.yaml
-
Configure a gateway for the Book-Info sample
kubectl apply -f ./samples/bookinfo/networking/bookinfo-gateway.yaml
-
Configure mTLS destination rules
kubectl apply -f ./samples/bookinfo/networking/destination-rule-all-mtls.yaml
-
Lock down mutual TLS for the entire mesh
kubectl apply -f ./samples/peer-authentication.yaml
Lock down mutual TLS for the entire mesh
kubectl apply -f ./samples/peer-authentication.yaml
kubectl create ns insidemesh
kubectl label namespace insidemesh istio-injection=enabled
kubectl apply -f ./samples/sleep/sleep.yaml -n insidemesh
Verify the setup by sending an http request (using curl command) from sleep pod (namespace: insidemesh) to productpage.default:9080:
- To check if the certificate get from productpage.default is issued by KeyfactorCA
kubectl exec $(kubectl get pod -l app=sleep -n insidemesh -o jsonpath={.items..metadata.name}) -c sleep -n insidemesh -- openssl s_client -showcerts -connect productpage.default:9080
- Request using curl
kubectl exec $(kubectl get pod -l app=sleep -n insidemesh -o jsonpath={.items..metadata.name}) -c sleep -n insidemesh -- curl http://productpage.default:9080 -s -o /dev/null -w "sleep.insidemesh to http://productpage.default:9080: -> HTTP_STATUS: %{http_code}\n"
Note: every workload deployed with sidecar can access Book Info services (HTTP_STATUS = 200)
kubectl create ns outsidemesh
kubectl apply -f samples/sleep/sleep.yaml -n outsidemesh
Verify the setup by sending an http request (using curl command) from sleep pod (namespace: outsidemesh) to productpage.default:9080:
kubectl exec $(kubectl get pod -l app=sleep -n outsidemesh -o jsonpath={.items..metadata.name}) -c sleep -n outsidemesh -- curl http://productpage.default:9080 -s -o /dev/null -w "sleep.outsidemesh to http://productpage.default:9080: -> HTTP_STATUS: %{http_code}\n"
Note: every workload deployed without sidecar cannot access Book Info services (HTTP_STATUS = 000)