How to setup service mesh in IBM cloud with Istio and Kubernetes - Part 3
Published On: 2020/04/23
In the third and final article of this series, we will be looking into the details of configuring Istio mesh for the secure communication among components in the mesh.
Istio’s Citadel component manages all the parts and pieces of securing the services in a service mesh. Citadel provides strong service-to-service and end-user authentication using mutual TLS, with built-in identity and credential management. It manages the lifecycle of keys and certificates issued for services. Istio uses these keys and certificates when establishing a mTLS connection between client and server components.
What is mutual TLS
The mutual TLS (mTLS) protocol is used in the Server-to-Server communication. When a mTLS connection is being established, the server originating the message (Server A) and the server which recieves it (Server B) exchange certificate from a mutually trusted Certificate Authority (CA). The certificates prove the identity of each server to the other and ensures that the traffic is both secure and trusted in both directions.
Configure mutual TLS
In Istio we could enable the mutual TLS for a specific service, for a specific namespace or for the mesh itself using authentication policies. These authentication policies, which are ditributed to the Envoy Proxy by the Pilot component, define the kind of requests that a service receives, whether it is encrypted using mutual TLS or plain text.
Create a namespace scoped policy - In this setup we will be creating the policy which is applicable to all services in the namespace “cloud-cargo”. This configuration instruct the target service in the Istio mesh to recieve mutual TLS traffic.
apiVersion: "authentication.istio.io/v1alpha1"
kind: "Policy"
metadata:
name: "default"
namespace: "cloud-cargo"
spec:
peers:
- mtls: {}
Create destination rules - Destination rule, a core part of Istio routing, is an instruction for the client service to make mutual TLS communication with the target services.
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: freight-rating-server
spec:
host: freight-rating-server
trafficPolicy:
tls:
mode: ISTIO_MUTUAL
subsets:
- name: v1
labels:
version: v1
In the above configuration any client which wants to communicate with the freight-rating-server (spec.host configuration) service must use the certificates created by the Citadel component for authentication as mutual TLS (tls.mode = ISTIO_MUTUAL) is the mode of traffic.
Configure Ingress controller with Secure Gateway (SDS)
By default the SDS feature of Istio is disabled. You need to enable the istio-ingressgateway.sds.enabled installation option and generate the istio-ingressgateway.yaml file.
istioctl manifest generate \
--set values.gateways.istio-egressgateway.enabled=false \
--set values.gateways.istio-ingressgateway.sds.enabled=true > \
$HOME/istio-ingressgateway.yaml
kubectl apply -f $HOME/istio-ingressgateway.yaml
I have enabled this by editing the istio-ingressgateway deployment which is already running in the kubernetes environment. Search for the sds flag in the deployment config and put the value “true”.
Create new certifcates to configure the ingress gateway using the below commands.
**1** openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=Cargo Inc./CN=cargo.com' -keyout ca.key -out ca.crt
**2** openssl req -out ingressgateway.csr -newkey rsa:2048 -nodes -keyout ingressgateway.key -subj "/CN=poc.cargo.com/O=poc organization"
**3** openssl x509 -req -days 365 -CA ca.crt -CAkey ca.key -set_serial 0 -in ingressgateway.csr -out ingressgateway.crt
**4** kubectl create -n istio-system secret generic cargo-gateway-certs \
--from-file=key=ingressgateway.key \
--from-file=cert=ingressgateway.crt
You could now create the Gateway object, which accepts the https traffic, with the secret “cargo-gateway-certs” created in the above step.
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: cargo-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 443
name: https
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: cargo-gateway-certs
hosts:
- "*"
Create a VirtualService object which instruct the istio system to do the routing based on the incoming url pattern.
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: cargo-vs
spec:
hosts:
- "*"
gateways:
- cargo-gateway
http:
- match:
- uri:
prefix: /api/freight-rating
route:
- destination:
host: freight-rating-server
port:
number: 8080
- match:
- uri:
prefix: /api/freight-tariff
route:
- destination:
host: freight-tariff-server
port:
number: 8080
- match:
- uri:
prefix: /
route:
- destination:
host: cargo-webapp
port:
number: 80
Create DNS entry for the cluster
Use the below commands to create the DNS entry for your cluster
1 - Obtain the Istio ingress gateway’s external IP
kubectl get service istio-ingressgateway -n istio-system
ibmcloud ks nlb-dns-create --cluster <name of the cluster> --ip <External IP address>
ibmcloud ks nlb-dnss --cluster <name of the cluster>
Setup Kiali
Kiali is an observability console for Istio with service mesh configuration capabilities. This helps you view how the apps are interconnected in the mesh and provides the health of your mesh.
KIALI_USERNAME=$(read '?Username: ' uval && echo -n $uval | base64)
KIALI_PASSPHRASE=$(read -s "?Password: " pval && echo -n $pval | base64)
Once the username , password varibles are created use it to create secret to access kiali dashboard.
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
name: kiali
namespace: istio-system
labels:
app: kiali
type: Opaque
data:
username: $KIALI_USERNAME
passphrase: $KIALI_PASSPHRASE
EOF
Use the istioctl tool to start kiali dashboard using the command given below.
istioctl dashboard kiali
Conclusion
In the final part of this series we have gone through the settings required to create a secure gateway by enabling sds feature of Istio. Use Kiali to, Jager and Grafana which comes along with the Istio addon to monitor your mesh once the setup of your mesh is completed. Thank you for reading this series.