# OpenShift Service Mesh - Istio installation and configuration
### Objectives
* to install OpenShift 4.2 on AWS
* to install Service Mesh on OpenShift
* to deploy upstream Istio demo application "bookinfo" on OpenShift.
* to configure weighted routing
* TBC
Remarks:
If you use "Red Hat OpenShift Service Mesh in Action" in opentlc, the namespaces in the lab guide are wrong. The correct namespaces should be "user-smcp" for control plane and "user-tutorial" for the demo application
### Background Information
Document Date: Nov 2019
OpenShift Version: 4.2.4 upgrade to --> 4.2.7
Bookinfo Version: 0.12.0
Istio Control plane project name: istio-system
Istio application project name: frankie-bookinfo-istiodemo
Bookinfo link (will be removed soon): http://istio-ingressgateway-istio-service.apps.cluster-08d7.sandbox1438.opentlc.com/productpage
Operator Version:

#### OpenShift setup
##### IPI on AWS
https://www.opentlc.com/labs/ocp4_advanced_deployment/03_1_Installing_OpenShift_on_AWS_Solution_Lab.html
##### UPI on AWS
In this lab, I use UPI to install. IPI will be used in the future.
Refer to Link, complete up to "3.10. Add MachineSets and Remove Workers":
https://www.opentlc.com/labs/ocp4_advanced_deployment/03_2_OpenShift_UPI_on_AWS_Solution_Lab.html
```
sudo -i
#Input variable
OCP_VERSION=4.3.0
#Install AWS cli
curl "https://s3.amazonaws.com/aws-cli/awscli-bundle.zip" -o "awscli-bundle.zip"
unzip awscli-bundle.zip
# Install the AWS CLI into /bin/aws
./awscli-bundle/install -i /usr/local/aws -b /bin/aws
# Validate that the AWS CLI works
aws --version
# Clean up downloaded files
rm -rf /root/awscli-bundle /root/awscli-bundle.zip
#Download OpenShift installer
wget https://mirror.openshift.com/pub/openshift-v4/clients/ocp/${OCP_VERSION}/openshift-install-linux-${OCP_VERSION}.tar.gz
tar zxvf openshift-install-linux-${OCP_VERSION}.tar.gz -C /usr/bin
rm -f openshift-install-linux-${OCP_VERSION}.tar.gz /usr/bin/README.md
chmod +x /usr/bin/openshift-install
#Download OpenShift client
wget https://mirror.openshift.com/pub/openshift-v4/clients/ocp/${OCP_VERSION}/openshift-client-linux-${OCP_VERSION}.tar.gz
tar zxvf openshift-client-linux-${OCP_VERSION}.tar.gz -C /usr/bin
rm -f openshift-client-linux-${OCP_VERSION}.tar.gz /usr/bin/README.md
chmod +x /usr/bin/oc
ls -l /usr/bin/{oc,openshift-install}
oc completion bash >/etc/bash_completion.d/openshift
exit
export AWSKEY=AKIAZDLPCJOWGS4XWK67
export AWSSECRETKEY=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
export REGION=ap-northeast-1
mkdir $HOME/.aws
cat << EOF >> $HOME/.aws/credentials
[default]
aws_access_key_id = ${AWSKEY}
aws_secret_access_key = ${AWSSECRETKEY}
region = $REGION
EOF
ssh-keygen -f ~/.ssh/cluster-${GUID}-key -N ''
openshift-install create cluster --dir $HOME/cluster-${GUID}
```
Get puller secret from https://cloud.redhat.com/openshift/install
Select "sandboxNNN.opentlc.com" as the **Base Domain**
For the cluster name, type "cluster-GUID" where GUID is the assigned GUID
Remarks:
For OpenShift 4.2.4 UPI, remember to disable masterSchedulable parameter due to bug.
Step 3.1 "Create Install Configs"
```
rm -rf $HOME/cluster-${GUID}/openshift/99_openshift-cluster-api_master-machines-*.yaml
rm -rf $HOME/cluster-${GUID}/openshift/99_openshift-cluster-api_worker-machineset-*.yaml
```
After the steps above, modify the manifests/cluster-scheduler-02-config.yml Kubernetes manifest file to prevent Pods from being scheduled on the control plane machines:
> Open the manifests/cluster-scheduler-02-config.yml file.
>
> Locate the mastersSchedulable parameter and set its value to False.
>
> Save and exit the file.
#### Istio control plane setup
Base on operator from operatorhub
1. Elasticsearch Operator
2. Jaeger Operator
3. Kiali Operator
4. Red Hat OpenShift Service Mesh Operator
5. Control plane
6. Member roll
* OpenShift GUI > select Istio-service project> installed operators > Istio Service Mesh Member Roll > default > edit YAML to include project in spec.members

Remarks:
Two m4.large worker nodes will lead to insufficient CPU during set up. I use 4 x m4.large worker nodes.
Configure "Desired Count" to 2 for each worker node Machine set


Link:
https://docs.openshift.com/container-platform/4.2/service_mesh/service_mesh_install/installing-ossm.html
#### Testing application - bookinfo
Base on Red Hat document for bookinfo application
```
oc new-project bookinfo
oc apply -n bookinfo -f https://raw.githubusercontent.com/Maistra/bookinfo/maistra-1.0/bookinfo.yaml
oc apply -n bookinfo -f https://raw.githubusercontent.com/Maistra/bookinfo/maistra-1.0/bookinfo-gateway.yaml
oc apply -n bookinfo -f https://raw.githubusercontent.com/istio/istio/release-1.1/samples/bookinfo/networking/destination-rule-all.yaml
###If you want to enable MTLS
oc apply -n bookinfo -f https://raw.githubusercontent.com/istio/istio/release-1.1/samples/bookinfo/networking/destination-rule-all-mtls.yaml
```
Link:
https://docs.openshift.com/container-platform/4.2/service_mesh/service_mesh_day_two/prepare-to-deploy-applications-ossm.html
### Generate traffic for application
Check the istio ingress gateway by replacing "istio-service" with your own istio control plane project
```
#oc get route -n istio-system istio-ingressgateway
NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD
istio-ingressgateway istio-ingressgateway-istio-service.apps.cluster-08d7.sandbox1438.opentlc.com istio-ingressgateway 8080 None
```
For bookinfo application, append /productpage at the end of the gateway
`#while : ; do curl istio-ingressgateway-istio-system.apps.cluster-24b8.sandbox777.opentlc.com/productpage ; done ;`
https://istio.io/docs/examples/bookinfo/withistio.svg
### A/B testing and canary rollouts
Before applying weight setting, the traffic should be evently distributed among reviews v1, v2 and v3. This behavior is due to the default round robin setting in the load balancer.

```
# cat virtualservice-review.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
weight: 80
- destination:
host: reviews
subset: v2
weight: 20
```
```
# oc apply -f virtualservice-review.yaml
```
```
# oc get istio-io
...
NAME GATEWAYS HOSTS AGE
virtualservice.networking.istio.io/bookinfo [bookinfo-gateway] [*] 47h
virtualservice.networking.istio.io/reviews [reviews] 16h
```
After apply the rule, the Reviews traffic should look like this:

Remarks:
I am not able to configure three destinations. I wonder the "weight" is designed for A/B testing and canary rollouts, so only two destinations could be configured.
### Istio Load balancing type
#### Load balancing options:
> * Random: Requests are forwarded at random to instances in the pool.
> * Weighted: Requests are forwarded to instances in the pool according to a specific percentage.
> * Least requests: Requests are forwarded to instances with the least number of requests.
Link:
https://istio.io/docs/concepts/traffic-management/#load-balancing-options
Please note that these options are not the type to configure, refer to the following LB type.
#### Load balancing type:
>lb_type
(required, string) The load balancer type to use when picking a host in the cluster. Possible options are roundrobin, leastrequest, ringhash, random, and originaldstlb. Note that originaldstlb must be used with clusters of type originaldst, and may not be used with any other cluster type.
#### Example
```
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: my-destination-rule
spec:
host: my-svc
trafficPolicy:
loadBalancer:
simple: RANDOM
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
- name: v3
labels:
version: v3
```
Link:
https://www.envoyproxy.io/docs/envoy/v1.5.0/api-v1/cluster_manager/cluster#config-cluster-manager-cluster-lb-type