# Create a new project in GCP and enable billing.
# Then open the Cloud Shell and follow along:
export PROJECT_NAME="istio-workshop-x"
gcloud config set project $PROJECT_NAME
Create Root CA and Intermediate CA certs for Istio
mkdir $HOME/root/ca -p
cd $HOME/root/ca
cp $WORKDIR/openssl-root.cnf openssl.cnf
mkdir certs crl newcerts private
chmod 700 private
touch index.txt
touch index.txt.crl
echo 1000 > index.txt.crl
openssl genrsa -aes256 -out private/ca.key.pem 4096
# Enter pass phrase for ca.key.pem: secretpassword
chmod 400 private/ca.key.pem
openssl req -config openssl.cnf -key private/ca.key.pem -new -x509 -days 7300 -sha256 -extensions v3_ca -out certs/ca.cert.pem
# Enter pass phrase for private/ca.key.pem: password
# You are about to be asked to enter information that will be incorporated
# into your certificate request.
# -----
# Country Name (2 letter code) [GB]:CA
# State or Province Name [England]:Ontario
# Locality Name []:
# Organization Name [Alice Ltd]:Istio Workshop
# Organizational Unit Name []:Istio Workshop Certificate Authority
# Common Name []:Istio Workshop Root CA
# Email Address []:
chmod 444 certs/ca.cert.pem
mkdir $HOME/root/ca/intermediate -p
cd $HOME/root/ca/intermediate
cp $WORKDIR/openssl-intermediate.cnf openssl.cnf
mkdir certs crl csr newcerts private
chmod 700 private
touch index.txt
touch index.txt.crl
echo 1000 > index.txt.crl
cd $HOME/root/ca
openssl genrsa -aes256 -out intermediate/private/intermediate.key.pem 4096
# Enter pass phrase for intermediate/private/intermediate.key.pem: password
# You are about to be asked to enter information that will be incorporated
# into your certificate request.
# -----
# Country Name (2 letter code) [GB]:CA
# State or Province Name [England]:Ontario
# Locality Name []:
# Organization Name [Alice Ltd]:Istio Workshop
# Organizational Unit Name []:Istio Workshop Certificate Authority
# Common Name []:Istio Workshop Intermediate CA
# Email Address []:
chmod 400 intermediate/private/intermediate.key.pem
openssl req -config intermediate/openssl.cnf -new -sha256 -key intermediate/private/intermediate.key.pem -out intermediate/csr/intermediate.csr.pem
# Enter pass phrase for www.example.com.key.pem: password
# You are about to be asked to enter information that will be incorporated
# into your certificate request.
# -----
# Country Name (2 letter code) [GB]:CA
# State or Province Name [England]:Ontario
# Locality Name []:
# Organization Name [Alice Ltd]:Istio Workshop
# Organizational Unit Name []:Istio Workshop Web Services
# Common Name []:www.istioworkshop.com
# Email Address []:
openssl ca -config openssl.cnf -extensions v3_intermediate_ca -days 3650 -notext -md sha256 -in intermediate/csr/intermediate.csr.pem -out intermediate/certs/intermediate.cert.pem
# Using configuration from openssl.cnf
# Enter pass phrase for /home/admin_/root/ca/private/ca.key.pem: password
# Check that the request matches the signature
# Signature ok
# Certificate Details:
# Serial Number: 4096 (0x1000)
# Validity
# Not Before: Nov 7 06:50:30 2019 GMT
# Not After : Nov 4 06:50:30 2029 GMT
# Subject:
# countryName = CA
# stateOrProvinceName = Ontario
# organizationName = Istio Workshop
# organizationalUnitName = Istio Workshop Web Services
# commonName = www.istioworkshop.com
# X509v3 extensions:
# X509v3 Subject Key Identifier:
# 71:2E:5E:DE:46:2E:EC:09:3F:CC:28:9F:58:74:1A:91:DB:17:8A:C7
# X509v3 Authority Key Identifier:
# keyid:3C:34:D8:CA:55:60:ED:00:D1:11:6D:A8:B3:8A:08:46:00:AD:60:C3
#
# X509v3 Basic Constraints: critical
# CA:TRUE, pathlen:0
# X509v3 Key Usage: critical
# Digital Signature, Certificate Sign, CRL Sign
# Certificate is to be certified until Nov 4 06:50:30 2029 GMT (3650 days)
# Sign the certificate? [y/n]:y
#
#
# 1 out of 1 certificate requests certified, commit? [y/n]y
# Write out database with 1 new entries
# Data Base Updated
cat intermediate/certs/intermediate.cert.pem certs/ca.cert.pem > intermediate/certs/ca-chain.cert.pem
chmod 444 intermediate/certs/ca-chain.cert.pem
mkdir $WORKDIR/certs
cp $HOME/root/ca/certs/ca.cert.pem $WORKDIR/certs/root-cert.pem
cp $HOME/root/ca/intermediate/certs/intermediate.cert.pem $WORKDIR/certs/ca-cert.pem
cp $HOME/root/ca/intermediate/private/intermediate.key.pem $WORKDIR/certs/ca-key.encrypted.pem
openssl rsa -in $WORKDIR/certs/ca-key.encrypted.pem -out $WORKDIR/certs/ca-key.pem -passin pass:password
cp $HOME/root/ca/intermediate/certs/ca-chain.cert.pem $WORKDIR/certs/cert-chain.pem
Deploy 05-search using an Elasticsearch K8s Operator
kubectl apply -f https://download.elastic.co/downloads/eck/1.0.0-beta1/all-in-one.yaml
# Wait for elastic-operator stateful set to come online before continuing
kubectl apply -f 05-search/gke/elasticsearch.yaml
sed 's#$INSTANCE_CONNECTION_NAME#'"${PROJECT_NAME}:${REGION_1}:mysql"'#g' $WORKDIR/03-database/gke/deployment.template.yaml > $WORKDIR/03-database/gke/deployment.yaml
cd $WORKDIR
kubectl apply -f 03-database/gke/deployment.yaml,03-database/gke/service.yaml
Build and deploy 02-backend
cd $WORKDIR/02-backend
docker build -t gcr.io/$PROJECT_NAME/02-backend .
docker push gcr.io/$PROJECT_NAME/02-backend
export IMAGE_SHA=$(docker inspect --format='{{index .RepoDigests 0}}' gcr.io/$PROJECT_NAME/02-backend)
sed 's#$IMAGE_SHA#'"${IMAGE_SHA}"'#g' $WORKDIR/02-backend/gke/deployment.template.yaml > $WORKDIR/02-backend/gke/deployment.yaml
cd $WORKDIR
kubectl apply -f 02-backend/gke/deployment.yaml,02-backend/gke/service.yaml
Build and deploy 01-frontend
cd $WORKDIR/01-frontend
docker build -t gcr.io/$PROJECT_NAME/01-frontend .
docker push gcr.io/$PROJECT_NAME/01-frontend
export IMAGE_SHA=$(docker inspect --format='{{index .RepoDigests 0}}' gcr.io/$PROJECT_NAME/01-frontend)
sed 's#$IMAGE_SHA#'"${IMAGE_SHA}"'#g' $WORKDIR/01-frontend/gke/deployment.template.yaml > $WORKDIR/01-frontend/gke/deployment.yaml
cd $WORKDIR
kubectl apply -f 01-frontend/gke/deployment.yaml,01-frontend/gke/service.yaml,01-frontend/gke/ingress.yaml
Wait for frontend ingress to come online
export FRONTEND_IP=$(bash -c 'external_ip=""; while [ -z $external_ip ]; do external_ip=$(kubectl get ingress frontend --template="{{range .status.loadBalancer.ingress}}{{.ip}}{{end}}"); [ -z "$external_ip" ] && sleep 10; done; echo $external_ip; export endpoint=$external_ip')
# Succesful connection may take up to 5 minutes due to the nature of our global SDN
Build and deploy 00-loadgen
cd $WORKDIR/00-loadgen
docker build -t gcr.io/$PROJECT_NAME/00-loadgen .
docker push gcr.io/$PROJECT_NAME/00-loadgen
export IMAGE_SHA=$(docker inspect --format='{{index .RepoDigests 0}}' gcr.io/$PROJECT_NAME/00-loadgen)
sed 's#$IMAGE_SHA#'"${IMAGE_SHA}"'#g' $WORKDIR/00-loadgen/gke/deployment.template.yaml > $WORKDIR/00-loadgen/gke/deployment.yaml
cd $WORKDIR
kubectl apply -f 00-loadgen/gke/deployment.yaml
Explore the application, Kiali, Grafana, Jaeger, etc
kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=kiali -o jsonpath='{.items[0].metadata.name}') 20001:20001
kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=grafana -o jsonpath='{.items[0].metadata.name}') 3000:3000
kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=jaeger -o jsonpath='{.items[0].metadata.name}') 16686:16686
TODO
1. instrument application for spans and tracing
2. configure authentication policies and destination rules
3. enforce service level access control with istio authorization
4. build virtual services for all services