├── .gitignore ├── README.md ├── TROUBLESHOOTING.md ├── exercise-1 ├── README.md └── README_alt.md ├── exercise-10 ├── README.md └── images │ ├── log.png │ ├── query.png │ └── ui.png ├── exercise-11 └── README.md ├── exercise-2 ├── README.md └── optional.md ├── exercise-3 └── README.md ├── exercise-4 └── README.md ├── exercise-5 ├── README.md └── db-service-binding.md ├── exercise-6 └── README.md ├── exercise-7 └── README.md ├── exercise-8 └── README.md ├── exercise-9 └── README.md ├── guestbook ├── broken-redis-service.yaml ├── deleteGuestBook.sh ├── deployGuestBookIstio.sh ├── deployGuestBookIstioWindows.txt ├── deployGuestBookKube.sh ├── frontdoor-ingress.yaml ├── guestbook-deployment.yaml ├── guestbook-ingress.yaml ├── guestbook-service.yaml ├── guestbook-telemetry.yaml ├── guestbook-ui-deployment.yaml ├── guestbook-ui-service.yaml ├── helloworld-deployment-v2.yaml ├── helloworld-deployment.yaml ├── helloworld-service.yaml ├── mixer-kubernetes-rules.yaml ├── mixer-rule-denial-v2.yaml ├── mixer-rule-denial.yaml ├── mysql-deployment.yaml ├── mysql-pvc.yaml ├── mysql-service.yaml ├── rate-limit-ui-service.yaml ├── redis-deployment.yaml ├── redis-service.yaml ├── route-rule-80-20.yaml ├── route-rule-canary.yaml ├── route-rule-delay-guestbook.yaml ├── route-rule-force-hello-v1.yaml ├── route-rule-helloworld-service-503.yaml ├── route-rule-user-agent-chrome.yaml ├── telemetry-global.yaml └── telemtry_rule.yaml ├── istio ├── deny-guestbook-service.yaml ├── guestbook-gateway.yaml ├── guestbook-service-503-vs.yaml ├── guestbook-service-dest.yaml ├── guestbook-service-retry-vs.yaml ├── guestbook-ui-80p-v1-vs.yaml ├── guestbook-ui-chrome-vs.yaml ├── guestbook-ui-delay-vs.yaml ├── guestbook-ui-dest.yaml ├── guestbook-ui-v1-vs.yaml ├── guestbook-ui-vs.yaml ├── helloworld-service-80p-v1-vs.yaml ├── helloworld-service-dest.yaml ├── helloworld-service-v1-vs.yaml └── rate-limits.yaml ├── kubernetes-v2 ├── guestbook-ui-deployment-v2.yaml └── helloworld-deployment-v2.yaml ├── kubernetes ├── guestbook-deployment.yaml ├── guestbook-service.yaml ├── guestbook-ui-deployment.yaml ├── guestbook-ui-service.yaml ├── helloworld-deployment.yaml ├── helloworld-service.yaml ├── mysql-deployment.yaml ├── mysql-service.yaml ├── redis-deployment.yaml └── redis-service.yaml └── setup └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | hs_err_pid* 3 | target 4 | .idea 5 | 6 | target/ 7 | !.mvn/wrapper/maven-wrapper.jar 8 | 9 | ### STS ### 10 | .apt_generated 11 | .classpath 12 | .factorypath 13 | .project 14 | .settings 15 | .springBeans 16 | 17 | ### IntelliJ IDEA ### 18 | .idea 19 | *.iws 20 | *.iml 21 | *.ipr 22 | 23 | ### NetBeans ### 24 | nbproject/private/ 25 | build/ 26 | nbbuild/ 27 | dist/ 28 | nbdist/ 29 | .nb-gradle/ 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Workshop Setup 2 | - [Exercise 1 - Accessing a Kubernetes cluster with IBM Cloud Container Service](exercise-1/README.md) 3 | 4 | ## Exploring Kubernetes (may skip) 5 | 6 | - [Exercise 2 - Deploying a microservice to Kubernetes](exercise-2/README.md) 7 | - [Exercise 3 - Creating a Kubernetes service](exercise-3/README.md) 8 | - [Exercise 4 - Scaling in and out](exercise-4/README.md) 9 | 10 | ## Creating a Service Mesh with Istio 11 | 12 | - [Exercise 5 - Installing Istio](exercise-5/README.md) 13 | - [Exercise 6 - Creating a service mesh with Istio Proxy](exercise-6/README.md) 14 | - [Exercise 7 - Istio Ingress controller](exercise-7/README.md) 15 | - [Exercise 8 - IBM Front Door](exercise-8/README.md) 16 | - [Exercise 9 - Telemetry](exercise-9/README.md) 17 | - [Exercise 10 - Request routing and canary deployments](exercise-10/README.md) 18 | - [Exercise 11 - Service Isolation](exercise-11/README.md) 19 | - [Exercise 12 - Security](exercise-12/README.md) 20 | 21 | 22 | ## Credits 23 | These workshop exercises are built with the help from a number of amazing Kubernetes and Istio experts from Google and Grand Cloud. 24 | 25 | #### Ray Tsang [@saturnism](https://twitter.com/saturnism) 26 | The Kubernetes and Istio exercises are derived from the work of Ray Tsang [@saturnism](https://twitter.com/saturnism) and these repositories: 27 | 28 | [https://github.com/saturnism/spring-boot-docker](https://github.com/saturnism/spring-boot-docker) 29 | 30 | [https://github.com/saturnism/istio-by-example-java](https://github.com/saturnism/istio-by-example-java) 31 | 32 | #### Zach Butcher [@ZachButcher](https://twitter.com/ZackButcher) 33 | Zach was instrumental in helping write the Istio tutorials. 34 | 35 | #### Kelsey Hightower [@kelseyhightower](https://twitter.com/kelseyhightower) 36 | The Istio Ingress Tutorial is largely based on the work of Kelsey and this repository: 37 | 38 | [https://github.com/kelseyhightower/istio-ingress-tutorial](https://github.com/kelseyhightower/istio-ingress-tutorial) 39 | 40 | Kelsey's tutorial uses more advance features of Kubernetes to taint some of the nodes so that the Ingress controller runs on dedicated nodes. The Ingress controller is then deployed as a daemonset. 41 | -------------------------------------------------------------------------------- /TROUBLESHOOTING.md: -------------------------------------------------------------------------------- 1 | ##Kubernetes Troubleshooting 2 | 3 | The most important tool to know for debugging problems is the describe resource command. 4 | It can be used to describe any Kubernetes resource. 5 | 6 | `kubectl describe pod helloworld-service-v1-119527584-jwfzh` 7 | 8 | `kubectl describe service helloworld-service` 9 | 10 | kubectl top can be used to see resource utilization. A very common problem is the pod was not able to be scheduled. 11 | 12 | `kubectl top nodes` 13 | 14 | `kubectl top pods` 15 | -------------------------------------------------------------------------------- /exercise-1/README.md: -------------------------------------------------------------------------------- 1 | # Exercise 1 - Accessing a Kubernetes cluster 2 | 3 | This is the section to configure your kubectl CLI to point to your Kubernetes cluster. For the convienence we will use Minikube here. 4 | 5 | ### Install Minikube on Mac 6 | 7 | The following are the quick steps to install Minikube on Mac if you have homebrew installed: 8 | 9 | ``` 10 | brew cask install virtualbox 11 | 12 | brew cask install minikube 13 | ``` 14 | 15 | Make sure the minikube has at least 4G of memory(more is better). Otherwise it will not be sufficient to run Istio. 16 | 17 | ``` 18 | minikube start 19 | --extra-config=controller-manager.cluster-signing-cert-file="/var/lib/localkube/certs/ca.crt" 20 | --extra-config=controller-manager.cluster-signing-key-file="/var/lib/localkube/certs/ca.key" 21 | --extra-config=apiserver.admission-control="NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" 22 | --kubernetes-version=v1.10.0 23 | ``` 24 | 25 | ### Else 26 | 27 | In case the first approach doesn't work, here are the full references to set up Minikube: 28 | - [Install Minikube](https://kubernetes.io/docs/tasks/tools/install-minikube/) 29 | - [Minikube release](https://github.com/kubernetes/minikube/releases) 30 | - [Vbox download](https://www.virtualbox.org/wiki/Downloads) 31 | - [Set up Minikube](https://kubernetes.io/docs/setup/minikube/) 32 | 33 | 34 | ### Clone the lab repo 35 | 36 | From your command line, run: 37 | 38 | ``` 39 | git clone https://github.com/szihai/istio-workshop 40 | 41 | cd istio-workshop 42 | ``` 43 | 44 | This is the working directory for the lab. 45 | 46 | ### Next step 47 | directly go into Istio topics: 48 | #### [Continue to Exercise 5 - Installing Istio](../exercise-5/README.md) 49 | OR go through the Kubenetes basics 50 | #### [Continue to Exercise 2 - Deploying a microservice to Kubernetes](../exercise-2/README.md) 51 | 52 | -------------------------------------------------------------------------------- /exercise-1/README_alt.md: -------------------------------------------------------------------------------- 1 | ## Exercise 1 - Startup a Kubernetes Cluster 2 | If your cluster has been provisioned for you, simply run: 3 | ``` 4 | bx cs cluster-config [your_cluster_name] 5 | export KUBECONFIG=/Users/ibm/.bluemix/plugins/cs-cli/clusters/wordpress/kube-config-dal10-wordpress.yml 6 | ``` 7 | Or else, follow these steps: 8 | 9 | 1. Create your free Kubernetes cluster 10 | ```bash 11 | $ bx cs cluster-create --name [your_cluster_name] 12 | ``` 13 | A free cluster comes with one worker node to deploy container pods upon. A worker node is the compute host, typically a virtual machine, that your pods run on. A pod is a group of one or more containers, the shared storage for those containers, and the options about how to run them. The pod model is as an "application specific logical host", which means it contains one or more application containers which are relatively tightly coupled. 14 | 15 | > **Note:** It can take up to 2 hours for the worker node machine to be ordered, and for the cluster to be set up and provisioned. 16 | 17 | 2. Before you continue to the next step, verify that the deployment of your worker node is complete. 18 | ```bash 19 | $ bx cs workers [your_cluster_name] 20 | ID Public IP Private IP Machine Type State Status 21 | dal10-pa8dfcc5223804439c87489886dbbc9c07-w1 169.47.223.113 10.171.42.93 free deployed Deploy Automation Successful 22 | ``` 23 | 24 | 3. Set the context for your cluster in your CLI. Every time you log in to the IBM Bluemix Container Service CLI to work with the cluster, you must run these commands to set the path to the cluster's configuration file as a session variable. The Kubernetes CLI uses this variable to find a local configuration file and certificates that are necessary to connect with the cluster in Bluemix. 25 | 26 | a. Download the configuration file and certificates for your cluster using the `cluster-config` command. 27 | ```bash 28 | $ bx cs cluster-config [your_cluster_name] 29 | export KUBECONFIG=/Users/ibm/.bluemix/plugins/cs-cli/clusters/wordpress/kube-config-dal10-wordpress.yml 30 | ``` 31 | 32 | b. Copy and paste the command from the previous step to set the KUBECONFIG environment variable and configure your CLI to run kubectl commands against your cluster. 33 | 34 | 35 | ## Note 36 | 37 | The cluster will take some time to be provisioned. This step is better done before the lab. 38 | 39 | 40 | #### [Continue to Exercise 2 - Deploying a microservice to Kubernetes](../exercise-2/README.md) 41 | 42 | -------------------------------------------------------------------------------- /exercise-10/README.md: -------------------------------------------------------------------------------- 1 | # Exercise 10 - Fault Injection and Circuit Breaking 2 | 3 | In this exercise we will learn how to test the resiliency of an application by injecting faults. 4 | 5 | To test our guestbook application for resiliency, this exercise will test injecting different levels of delay when the user agent accessing the hello world service is mobile. 6 | 7 | #### Inject a route rule to delay request 8 | 9 | We can inject delays into the request. 10 | 11 | ```sh 12 | kubectl apply -f istio/guestbook-ui-delay-vs.yaml 13 | ``` 14 | 15 | Browse to the Guestbook UI, and you'll see that the request is responding much slower! 16 | 17 | #### Inject error responses 18 | 19 | We can also inject error responses, such as returning 503 from a service. 20 | 21 | ```sh 22 | kubectl apply -f istio/guestbook-service-503.yaml 23 | ``` 24 | 25 | Visiting the Guestbook UI, and you'll see that it is now unable to retrieve any Guestbook messages. Luckily, the application has a graceful fallback to display a nice error message. 26 | 27 | #### Remove the faults 28 | 29 | Remove the annoying 503 errors. 30 | 31 | ```sh 32 | kubectl delete -f istio/guestbook-service-503.yaml 33 | ``` 34 | 35 | Then reset the Guestbook UI virtual service so that it routes all requests to V1. 36 | 37 | ```sh 38 | kubectl apply -f istio/guestbook-ui-v1-vs.yaml 39 | ``` 40 | 41 | #### Circuit Breaking 42 | 43 | There are several circuit breaker rules you can apply in Istio: 44 | * Retries 45 | * Outlier Detection 46 | * Connection pooling 47 | 48 | Retries can be configured in the virtual service. 49 | 50 | ```sh 51 | kubectl apply -f istio/guestbook-service-retry-vs.yaml 52 | ``` 53 | 54 | Outlier and connection pooling are configured in the destination rule. 55 | 56 | ```sh 57 | kubectl apply -f istio/guestbook-service-dest.yaml 58 | ``` 59 | 60 | ```sh 61 | kubectl apply -f istio/guestbook-service-dest.yaml 62 | ``` 63 | #### [Continue to Exercise 11 - Service Isolation](../exercise-11/README.md) 64 | -------------------------------------------------------------------------------- /exercise-10/images/log.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/szihai/istio-workshop/14d598b824c1808467db421e2f60be61f22072d8/exercise-10/images/log.png -------------------------------------------------------------------------------- /exercise-10/images/query.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/szihai/istio-workshop/14d598b824c1808467db421e2f60be61f22072d8/exercise-10/images/query.png -------------------------------------------------------------------------------- /exercise-10/images/ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/szihai/istio-workshop/14d598b824c1808467db421e2f60be61f22072d8/exercise-10/images/ui.png -------------------------------------------------------------------------------- /exercise-11/README.md: -------------------------------------------------------------------------------- 1 | # Exercise 11 - Service Isolation 2 | 3 | ## Service Isolation Using Mixer 4 | 5 | We'll block access to the Guestbook Service by adding the `deny-guestbook-service.yaml` rule shown below. 6 | 7 | ```sh 8 | kubectly apply -f istio/deny-guestbook-service.yaml 9 | ``` 10 | 11 | Visit Guestbook UI and see that Guestbook Service can no longer be accessed. 12 | 13 | To remove denial, you can delete the rule. 14 | 15 | ```sh 16 | kubectly delete -f istio/deny-guestbook-service.yaml 17 | ``` 18 | 19 | Congratulations! You have finished the lab. If you want to find out more about Istio, try out more advanced features, or follow more examples and guides, you can find all this and more at https://istio.io/docs/. 20 | 21 | -------------------------------------------------------------------------------- /exercise-2/README.md: -------------------------------------------------------------------------------- 1 | # Exercise 2 - Deploying a microservice to Kubernetes 2 | 3 | 4 | ### Deploy the Hello World service 5 | 6 | 1. Deploy the Hello World service to Kubernetes. 7 | 8 | ``` 9 | kubectl apply -f kubernetes/helloworldservice-deployment.yaml --record 10 | ``` 11 | 12 | 2. Verify that the service was created. It will take a couple minutes for the pods to be ready. 13 | 14 | ```bash 15 | kubectl get pods 16 | 17 | NAME READY STATUS RESTARTS AGE 18 | helloworld-service-v1-.... 1/1 Running 0 20s 19 | ``` 20 | 21 | 3. Note the name of the pod above for use in the command below. Then delete one of the Hello World pods. 22 | 23 | ``` 24 | kubectl delete pod helloworld-service-v1-... 25 | ``` 26 | 27 | 4. Kubernetes will automatically restart this pod for you. Verify that it restarted and reach the `Running` state. 28 | 29 | ```bash 30 | kubectl get pods 31 | ``` 32 | Pick the running pod: 33 | ```bash 34 | NAME READY STATUS RESTARTS AGE 35 | helloworld-service-v1-.... 1/1 Running 0 20s 36 | ``` 37 | 38 | 5. All of the container output to STDOUT and STDERR from the restarted pod will be accessible as Kubernetes logs. 39 | 40 | ``` 41 | kubectl logs helloworld-service-v1-... 42 | ``` 43 | 44 | 45 | ## Explanation 46 | 47 | #### By Ray Tsang [@saturnism](https://twitter.com/saturnism) 48 | 49 | We will be using yaml files throughout this workshop. Every file describes a resource that needs to be deployed into Kubernetes. We won’t be able to go into details on the contents, but you are definitely encouraged to read them and see how pods, services, and others are declared. 50 | 51 | The pod deploys a microservice that is a container whose images contains a self-executing JAR files. The source is available at [istio-by-example-java](https://github.com/saturnism/istio-by-example-java) if you are interested in seeing it. 52 | 53 | In this first example we deployed a Kubernetes pod by specifying a deployment using this [helloworldservice-deployment.yaml](helloworldservice-deployment.yaml). 54 | 55 | A Kubernetes pod is a group of containers, tied together for the purposes of administration and networking. It can contain one or more containers. All containers within a single pod will share the same networking interface, IP address, volumes, etc. All containers within the same pod instance will live and die together. It’s especially useful when you have, for example, a container that runs the application, and another container that periodically polls logs/metrics from the application container. 56 | 57 | You can start a single Pod in Kubernetes by creating a Pod resource. However, a Pod created this way would be known as a Naked Pod. If a Naked Pod dies/exits, it will not be restarted by Kubernetes. A better way to start a pod, is by using a higher-level construct such as Replication Controller, Replica Set, or a Deployment. 58 | 59 | Prior to Kubernetes 1.2, Replication Controller is the preferred way deploy and manage your application instances. Kubernetes 1.2 introduced two new concepts - Replica Set, and Deployments. 60 | 61 | Replica Set is the next-generation Replication Controller. The only difference between a Replica Set and a Replication Controller right now is the selector support. Replica Set supports the new set-based selector requirements whereas a Replication Controller only supports equality-based selector requirements. 62 | 63 | For example, Replication Controller can only select pods based on equality, such as "environment = prod", whereas Replica Sets can select using the "in" operator, such as "environment in (prod, qa)". Learn more about the different selectors in the [Labels guide](http://kubernetes.io/docs/user-guide/labels). 64 | 65 | Deployment provides declarative updates for Pods and Replica Sets. You only need to describe the desired state in a Deployment object, and the Deployment controller will change the actual state to the desired state at a controlled rate for you. You can use deployments to easily: 66 | - Create a Deployment to bring up a Replica Set and Pods. 67 | - Check the status of a Deployment to see if it succeeds or not. 68 | - Later, update that Deployment to recreate the Pods (for example, to use a new image, or configuration). 69 | - Rollback to an earlier Deployment revision if the current Deployment isn’t stable. 70 | - Pause and resume a Deployment. 71 | 72 | In this workshop, because we are working with Kubernetes 1.7+, we will be using Deployment extensively. 73 | 74 | There are other containers running too. The interesting one is the pause container. The atomic unit Kubernetes can manage is actually a Pod, not a container. A Pod can be composed of multiple tightly-coupled containers that is guaranteed to scheduled onto the same node, and will share the same Pod IP address, and can mount the same volumes.. What that essentially means is that if you run multiple containers in the same Pod, they will share the same namespaces. 75 | 76 | A pause container is how Kubernetes uses Docker containers to create shared namespaces so that the actual application containers within the same Pod can share resources. 77 | 78 | 79 | #### [Continue to Exercise 3 - Creating a Kubernetes service](../exercise-3/README.md) 80 | -------------------------------------------------------------------------------- /exercise-2/optional.md: -------------------------------------------------------------------------------- 1 | ## Exercise 2 - Optional 2 | ## Peering under the covers of node 3 | 4 | `kubectl get pods -owide` 5 | 6 | That will list the node the pod is running on. For example you should see: 7 | 8 | `NODE gke-guestbook-...` 9 | 10 | `gcloud compute ssh ` 11 | 12 | `sudo docker ps` 13 | 14 | `someuser@:~$ exit` 15 | 16 | The Pod name is automatically assigned as the hostname of the container: 17 | 18 | ``` 19 | kubectl exec -ti helloworld-service-v1-... /bin/bash 20 | 21 | root@helloworld-...:/data# hostname 22 | helloworld-service-.... 23 | 24 | root@helloworld-...:/app/src# hostname -i 25 | 10.104.1.5 26 | 27 | root@helloworld-...:/app/src# exit 28 | 29 | root@helloworld-...:/data# hostname -i 30 | 10.104.1.5 31 | ``` 32 | 33 | #### [Continue to Exercise 3 - Creating a Kubernetes Service](../exercise-3/README.md) 34 | -------------------------------------------------------------------------------- /exercise-3/README.md: -------------------------------------------------------------------------------- 1 | # Exercise 3 - Creating a Kubernetes service 2 | 3 | Each pod has a unique IP address, but the address is ephemeral. The pod IP addresses are not stable and can change when pods start or restart. A service provides a single access point to a set of pods matching some constraints. A service IP address is stable. 4 | 5 | In Kubernetes, you can instruct the underlying infrastructure to create an external load balancer by specifying the service type as a LoadBalancer. If you open up [helloworldservice-service.yaml](helloworldservice-service.yaml), you will see that it has `type: LoadBalancer`. 6 | 7 | ### Create a LoadBalancer service 8 | 9 | 1. Create a LoadBalancer service for the Hello World service. 10 | 11 | ``` 12 | kubectl apply -f kubernetes/helloworldservice-service.yaml --record 13 | ``` 14 | 15 | 2. Verify that Load Balancer service was created. The `EXTERNAL IP` of the LoadBalancer will start as pending and will be populated after a short period. 16 | 17 | ```bash 18 | kubectl get services 19 | 20 | NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE 21 | helloworld-service 172.21.48.166 169.47.103.138 8080:32678/TCP 1m 22 | ``` 23 | 24 | ### Test the Hello World service 25 | 26 | Curl the external IP address to test the Hello World service. 27 | 28 | curl [EXTERNAL-IP]:8080/hello/world 29 | 30 | 31 | #### Optional - Curl the service using a DNS name 32 | 33 | If you log in to another container, you can access the Hello World service via the DNS name. For example, start `tutum/curl` to get a shell and curl the service using the service name: 34 | 35 | ``` 36 | kubectl run curl --image=tutum/curl -i --tty 37 | 38 | root@busybox:/data# curl http://helloworld-service:8080/hello/Batman 39 | {"greeting":"Hello Batman from helloworld-service-... with 1.0","hostname":"helloworld-service-...","version":"1.0"} 40 | 41 | root@busybox:/data# exit 42 | ``` 43 | 44 | ## Explanation 45 | #### By Ray Tsang [@saturnism](https://twitter.com/saturnism) 46 | 47 | Open the [helloworldservice-service.yaml](helloworldservice-service.yaml) to examine the service descriptor. The important part about this file is the selector section. This is how a service knows which pod to route the traffic to, by matching the selector labels with the labels of the pods. 48 | 49 | The other important part to notice in this file is the type of service is a Load Balancer. This tells Bluemix that an externally facing load balancer should be created for this service so that it is accessible from the outside. 50 | 51 | Since we are running two instances of the Hello World Service (one instance in one pod), and that the IP addresses are not only unique, but also ephemeral - how will a client reach our services? We need a way to discover the service. 52 | 53 | In Kubernetes, Service Discovery is a first class citizen. We created a Service that will: 54 | - act as a load balancer to load balance the requests to the pods, and 55 | - provide a stable IP address, allow discovery from the API, and also create a DNS name! 56 | 57 | #### [Continue to Exercise 4 - Scaling in and out](../exercise-4/README.md) 58 | -------------------------------------------------------------------------------- /exercise-4/README.md: -------------------------------------------------------------------------------- 1 | # Exercise 4 - Scaling in and out 2 | 3 | ### Scale the number of Hello World service pods 4 | 5 | 1. Scale the number of replicas of your Hello World service by running the following commands: 6 | 7 | ```sh 8 | kubectl get deployment 9 | 10 | NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE 11 | helloworld-service-v1 1 1 1 1 1m 12 | ``` 13 | 14 | ```sh 15 | kubectl scale deployment helloworld-service-v1 --replicas=4 16 | ``` 17 | 18 | ```sh 19 | kubectl get deployment 20 | 21 | NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE 22 | helloworld-service-v1 4 4 4 4 1m 23 | ``` 24 | 25 | ```sh 26 | kubectl get pods 27 | 28 | NAME READY STATUS RESTARTS AGE 29 | helloworld-service-v1-... 1/1 Running 0 1m 30 | helloworld-service-v1-... 1/1 Running 0 1m 31 | helloworld-service-v1-... 1/1 Running 0 1m 32 | helloworld-service-v1-... 1/1 Running 0 2m 33 | ``` 34 | 35 | 2. Try scaling out further. 36 | 37 | ``` 38 | kubectl scale deployment helloworld-service-v1 --replicas=17 39 | ``` 40 | 41 | If you look at the pod status, some of the pods will show a `Pending` state. That is because we have cordoned one worker node, leaving only two available for scheduling. And the underlying infrastructure has run out of capacity to run the containers with the requested resources. 42 | 43 | 3. Pick a pod name that has a `Pending` state to confirm the lack of resources in the detailed status. 44 | 45 | ``` 46 | kubectl describe pod helloworld-service... 47 | ``` 48 | 49 | 4. Uncordon the worker to be available for scheduling. 50 | 51 | a. Open another terminal, do the `export KUBECONFIG ...` command in [Lab 1](../exercise-1/README.md) and run: 52 | 53 | ``` 54 | kubectl get po -w -o wide 55 | ``` 56 | This will monitor the recovering process. 57 | 58 | b. Go back the working terminal. Get the name of the worker that has status "not-ready". 59 | 60 | ``` 61 | kubectl get nodes 62 | ``` 63 | 64 | c. Undordon the worker to make it available for scheduling. 65 | 66 | ``` 67 | kubectl uncordon [name] 68 | ``` 69 | 70 | 5. Verify all three workers are available and the pending pod is rescheduled. 71 | 72 | ``` 73 | kubectl get nodes 74 | kubectl get pods -o wide 75 | ``` 76 | 77 | ### Clean up 78 | 79 | Clean up by deleting all deployed services from the cluster. 80 | 81 | ```sh 82 | kubectl delete all --all 83 | ``` 84 | 85 | #### [Continue to Exercise 5 - Installing Istio](../exercise-5/README.md) 86 | -------------------------------------------------------------------------------- /exercise-5/README.md: -------------------------------------------------------------------------------- 1 | # Exercise 5 - Installing Istio 2 | 3 | ### Download Istio 4 | 5 | 1. Either download Istio directly from https://github.com/istio/istio/releases or get the latest version using curl: 6 | 7 | ``` 8 | curl -L https://git.io/getLatestIstio | sh - 9 | ``` 10 | 11 | 2. Extract the installation files. 12 | 13 | 3. Add the `istioctl` client to your PATH. For example, run the following command on a MacOS or Linux system: 14 | 15 | #### Remember to change the [version] to the current value 16 | 17 | ``` 18 | export PATH=$PWD/istio-[version]/bin:$PATH 19 | ``` 20 | 21 | ### Install Istio on the Kubernetes cluster 22 | 23 | 1. Change the directory to the Istio file location. 24 | 25 | ``` 26 | cd [path_to_istio-version] 27 | ``` 28 | 29 | 2. Install Istio on the Kubernetes cluster. 30 | 31 | ``` 32 | kubectl apply -f install/kubernetes/istio-demo-auth.yaml 33 | ``` 34 | 35 | 36 | ### View the Istio deployments 37 | 38 | Istio is deployed in a separate Kubernetes namespace `istio-system` You can watch the state of Istio and other services and pods using the watch flag (`-w`) when listing Kubernetes resources. For example, in two separate terminal windows run: 39 | 40 | ```sh 41 | kubectl get pods -w --all-namespaces 42 | ``` 43 | ```sh 44 | kubectl get services -w --all-namespaces 45 | ``` 46 | ## What just happened 47 | 48 | Congratulations! You have installed Istio into the Kubernetes cluster. A lot has been installed: 49 | 50 | - Istio Controllers and related RBAC rules 51 | - Istio Custom Resource Definitions 52 | - Prometheus and Grafana for Monitoring 53 | - Jeager for Distributed Tracing 54 | - Istio Sidecar Injector (we'll take a look next next section) 55 | 56 | #### [Continue to Exercise 6 - Creating a service mesh with Istio Proxy](../exercise-6/README.md) 57 | -------------------------------------------------------------------------------- /exercise-5/db-service-binding.md: -------------------------------------------------------------------------------- 1 | bx target --cf 2 | bx service create compose-for-mysql Standard "[name]" 3 | The format of the name must match the regex [a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)* (e.g. 'example.com'). 4 | bx service key-create "[name]" Credentials-1 5 | 6 | bx cs clusters 7 | bx cs cluster-service-bind andylab default "[name]" 8 | kubectl get secrets 9 | 10 | bx service key-show "[name]" "Credentials-1" |grep "mysql:" 11 | "uri": "mysql://admin:CAHQDXDYGAWISLZM@sl-us-south-1-portal.15.dblayer.com:28498/compose" 12 | -------------------------------------------------------------------------------- /exercise-6/README.md: -------------------------------------------------------------------------------- 1 | # Exercise 6 - Creating a service mesh with Istio Proxy 2 | 3 | ### What is a service mesh? 4 | 5 | Cloud-native applications require a new approach to managing the communication between each service. This problem is best solved by creating a dedicated infrastructure layer that handles service-to-service communication. With Istio, this infrastructure layer is created by deploying a lightweight proxy alongside each application service. This is done in a way that the application does not need to be aware of the proxy. 6 | 7 | Moving the service communication to a separate layer provides a separation of concerns. The monitoring, management and security of communication can be handled outside of the application logic. 8 | 9 | ### What is a Kubernetes sidecar? 10 | 11 | A Kubernetes pod is a group of containers, tied together for the purposes of administration and networking. Each pod can contain one or more containers. Small containers are often used to provide common utilities for the pod. These sidecar containers extend and enhance the main container. Sidecar containers are a crosscutting concern and can be used across multiple pods. 12 | 13 | ### The Istio Proxy sidecar 14 | 15 | To create a service mesh with Istio, you update the deployment of the pods to add the Istio Proxy (based on the Lyft Envoy Proxy) as a side car to each pod. The Proxy is then run as a separate container that manages all communication with that pod. This can be done either manually or with the latest version of Kubernetes automatically. 16 | 17 | #### Manual sidecar injection 18 | 19 | The side car can be injected manually by running the istioctl kube-inject command, which modifies the YAML file before creating the deployments. This injects the Proxy into the deployment by updating the YAML to add the Proxy as a sidecar. When this command is used, the microservices are now packaged with an Proxy sidecar that manages incoming and outgoing calls for the service. To see how the deployment YAML is modified, run thw following from the `istio-workshop` dir: 20 | 21 | ```sh 22 | istioctl kube-inject -f guestbook/helloworld-deployment.yaml 23 | ``` 24 | 25 | This adds the Istio Proxy as an additional container to the Pod and setups the necessary configuration. Inside the YAML there is now an additional container: 26 | 27 | ``` 28 | image: docker.io/istio/proxy###### 29 | imagePullPolicy: IfNotPresent 30 | name: istio-proxy 31 | ``` 32 | #### Automatic sidecar injection 33 | 34 | Istio sidecars can also be automatically injected into a pod at creation time using a feature in Kubernetes called a mutating webhook admission controller. Note that unlike manual injection, automatic injection occurs at the pod-level. You won't see any change to the deployment itself. Instead you'll want to check individual pods (via kubectl describe) to see the injected proxy. 35 | 36 | An admission controller is a piece of code that intercepts requests to the Kubernetes API server prior to persistence of the object, but after the request is authenticated and authorized. Admission controllers may be “validating”, “mutating”, or both. Mutating controllers may modify the objects they admit; validating controllers may not. 37 | 38 | The admission control process proceeds in two phases. In the first phase, mutating admission controllers are run. In the second phase, validating admission controllers are run. 39 | 40 | MutatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and may change the object. 41 | 42 | For Istio the webhook is the sidecar injector webhook deployment called "istio-sidecar-injector". It will modify a pod before it is started to inject an istio init container and istio proxy container. 43 | 44 | #### Using the Sidecar Injector 45 | 46 | By default, Istio is configured to apply a sidecar injector to namespaces with the label/value of `istio-injection=enabled`. 47 | 48 | Label the default namespace with `istio-injection` label set to `enabled`. 49 | 50 | ```sh 51 | kubectl label namespace default istio-injection=enabled 52 | ``` 53 | 54 | Check that the label is applied. 55 | 56 | ```sh 57 | kubectl get namespace -L istio-injection 58 | 59 | NAME STATUS AGE ISTIO-INJECTION 60 | default Active 1h enabled 61 | istio-system Active 1h 62 | kube-public Active 1h 63 | kube-system Active 1h 64 | ``` 65 | 66 | ### Deploy Guestbook services 67 | 68 | To demonstrate Istio, we’re going to use [this guestbook example](https://github.com/retroryan/spring-boot-docker). This example is built with Spring Boot, a frontend using Spring MVC and Thymeleaf, and two microservices. The 3 microservices that we are going to deploy are: 69 | 70 | * Hello World service - A simple service that returns a greeting back to the user. 71 | 72 | * Guestbook service - A service that keeps a registry of guests and the message they left. 73 | 74 | * Guestbook UI - The front end to the application that calls to the other microservices to get the list of guests, register a new guest, and get the greeting for the user when they register. 75 | 76 | The guestbook example requires MySQL to store guestbook entries and Redis to store session information. 77 | 78 | Note that the services must be started in a fixed order because they depend on other services being started first. 79 | 80 | 1. Deploy MySQL, Redis, the Hello World microservices, and the associated Kubernetes Services from the `istio-workshop` dir: 81 | 82 | ```sh 83 | cd ../istio-workshop 84 | kubectl apply -f kubernetes/ 85 | ``` 86 | 87 | 2. Notice that each of the pods now has one Istio init container and two running containers. One is the main application container and the second is the istio proxy container. 88 | ``` 89 | kubectl get -w deployment 90 | ``` 91 | 92 | When you get the pods you should see in the READY column 2/2 meaning that 2 of 2 containers are in the running state (it might take a minute or two to get to that state). 93 | 94 | When you describe the pod what that shows is the details of the additional containers. 95 | 96 | kubectl describe pods helloworld-service-v1..... 97 | 98 | 3. Verify that previous deployments are all in a state of AVAILABLE before continuing. Do not procede until they are up and running. 99 | 100 | ```sh 101 | kubectl get -w deployment 102 | ``` 103 | 104 | #### [Continue to Exercise 7 - Istio Ingress controller](../exercise-7/README.md) 105 | -------------------------------------------------------------------------------- /exercise-7/README.md: -------------------------------------------------------------------------------- 1 | ## Exercise 7 - Istio Ingress Controller 2 | 3 | **NOTE: If you are using Minikube, this section may not work. However there are other approaches to access the service such as using [telepresence](https://www.telepresence.io/).** 4 | 5 | The components deployed on the service mesh by default are not exposed outside the cluster. External access to individual services so far has been provided by creating an external load balancer on each service. 6 | 7 | Traditionally in Kubernetes, you would use an Ingress to configure a L7 proxy. However, Istio provides a much richer set of proxy configurations that are not well-defined in Kubernetes Ingress. 8 | Thus, in Istio, we will use Isito Gateway to define fine grained control over L7 edge proxy configuration. 9 | 10 | #### Inspecting the Istio Ingress Gateway 11 | 12 | The ingress controller gets expossed as a normal Kubernetes service load balancer: 13 | 14 | ```sh 15 | kubectl get svc istio-ingressgateway -n istio-system -o yaml 16 | ``` 17 | 18 | Find the IP address of the Ingress Gateway: 19 | 20 | ```sh 21 | export INGRESS_IP=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}') 22 | echo $INGRESS_IP 23 | ``` 24 | 25 | `curl` the IP address: 26 | 27 | ```sh 28 | curl http://$INGRESS_IP 29 | ``` 30 | 31 | This will return `connection refused` error. That is because there are no gateway configured to listen to any incoming connections. 32 | 33 | #### Configure Guestbook Ingress 34 | 35 | 1 - Create a new Gateway 36 | 37 | ```sh 38 | kubectl apply -f istio/guestbook-gateway.yaml 39 | ``` 40 | 41 | There is a `selector` block in the gateway definition. The `selector` will be used to find the actual edge proxy that should be configured to accept traffic for the gateway. This example selects pods from any namespaces that has the label of `istio` and value of `ingressgateway`. 42 | 43 | This is similar to running: 44 | ```sh 45 | kubectl get pods -l istio=ingressgateway --all-namespaces 46 | ``` 47 | 48 | You'll find a single pod that matches this label, which is the Ingress Gateway that we looked at earlier. 49 | ``` 50 | NAMESPACE NAME READY STATUS RESTARTS AGE 51 | istio-system istio-ingressgateway-... 1/1 Running 0 7d 52 | ``` 53 | 54 | After creating the Gateway, it'll enable the Istio Ingress Gateway to listen on port `80`. 55 | The `hosts` block of the configuration can be used to configure virtual hosting. E.g., the same IP address can be configured to respond to different host names with different routing rules. 56 | 57 | If you `curl` the ingress IP again: 58 | ```sh 59 | curl -v http://$INGRESS_IP 60 | ``` 61 | 62 | Rather than `connection refused`, you should see the server responded with `404 Not Found` HTTP response. This is because we have not bound any backends to this gatway yet. 63 | 64 | 2 - Create a Virtual Service 65 | 66 | To bind a backend to the gateway, we'll need to create a virtual service. 67 | 68 | ```sh 69 | kubectl apply -f istio/guestbook-ui-vs.yaml 70 | ``` 71 | 72 | A virtual service is a logical grouping of routing rules for a given target service. For ingress, we can use virtual service to bind to a gateway. 73 | 74 | This example binds the to the gateway we just created, and will respond to any hostname. Again, if you need to use virtual hosting and respond to different host names, you can specify them in the `hosts` section. 75 | 76 | 3 - Connect via the Ingress Gateway 77 | 78 | Try connecting to the Ingress Gateway again. 79 | 80 | ```sh 81 | curl http://$INGRESS_IP 82 | ``` 83 | 84 | This time you should see the HTTP response! 85 | 86 | 4 - Browse to the Guestbook UI using the Ingress Gateway IP address. 87 | 88 | 5 - Try Hello a few times 89 | 90 | In the browser, say hello a couple of times, and you'll see that the greeting reply will round robin between v1 and v2 versions of the hello service. 91 | #### [Exercise 8 - Telemetry](../exercise-8/README.md) 92 | -------------------------------------------------------------------------------- /exercise-8/README.md: -------------------------------------------------------------------------------- 1 | # Exercise 8 - Telemetry 2 | 3 | First we need to configure Istio to automatically gather telemetry data for services running in the mesh. 4 | 5 | 1. Create a rule to collect telemetry data. 6 | 7 | ```sh 8 | istioctl create -f guestbook/guestbook-telemetry.yaml 9 | ``` 10 | 2. Generate a small load to the application. 11 | 12 | ```sh 13 | while sleep 0.5; do curl http://$INGRESS_IP/hello/world; done 14 | ``` 15 | 16 | ## View guestbook telemetry data 17 | 18 | ### Grafana 19 | Establish port forwarding from local port 3000 to the Grafana instance: 20 | ```sh 21 | kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=grafana \ 22 | -o jsonpath='{.items[0].metadata.name}') 3000:3000 23 | ``` 24 | 25 | Browse to http://localhost:3000 and navigate to the Istio Dashboard. 26 | 27 | ### Jaeger 28 | Establish port forwarding from local port 16686 to the Jaeger instance: 29 | ```sh 30 | kubectl port-forward -n istio-system \ 31 | $(kubectl get pod -n istio-system -l app=jaeger -o \ 32 | jsonpath='{.items[0].metadata.name}') 16686:16686 & 33 | ``` 34 | 35 | Browse to http://localhost:9411. 36 | 37 | ### Prometheus 38 | Establish port forwarding from local port 9090 to the Prometheus instance: 39 | ```sh 40 | kubectl -n istio-system port-forward \ 41 | $(kubectl -n istio-system get pod -l app=prometheus -o jsonpath='{.items[0].metadata.name}') \ 42 | 9090:9090 43 | ``` 44 | 45 | Browse to http://localhost:9090/graph, and in the “Expression” input box, enter: `request_count`. Click **Execute**. 46 | 47 | 48 | ### Service Graph 49 | Establish port forwarding from local port 8088 to the Service Graph instance: 50 | ```sh 51 | kubectl -n istio-system port-forward \ 52 | $(kubectl -n istio-system get pod -l app=servicegraph -o jsonpath='{.items[0].metadata.name}') \ 53 | 8088:8088 54 | ``` 55 | 56 | Browse to http://localhost:8088/dotviz. 57 | 58 | #### Mixer Log Stream 59 | 60 | ```sh 61 | kubectl -n istio-system logs $(kubectl -n istio-system get pods -l istio=mixer -o jsonpath='{.items[0].metadata.name}') mixer | grep \"instance\":\"newlog.logentry.istio-system\" 62 | ``` 63 | 64 | #### [Continue to Exercise 9 - Request Routing and Canary Deployments](../exercise-9/README.md) 65 | -------------------------------------------------------------------------------- /exercise-9/README.md: -------------------------------------------------------------------------------- 1 | # Exercise 9 - Request routing and canary deployments 2 | 3 | Before modifying any of the routes, a default route must be set to just `v1` of the Hello World service deployment. Otherwise, the round robin between `v1` and `v2` of the service deployment will continue. 4 | 5 | ### Configure the default route for the Hello World service 6 | 7 | 1. Set the default version for all requests to the Hello World service. 8 | 9 | ```sh 10 | istioctl create -f guestbook/route-rule-force-hello-v1.yaml 11 | ``` 12 | 13 | This Ingress rule forces `v1` of the service by giving it a weight of 100. We can see this by describing the resource we created: 14 | 15 | ```sh 16 | kubectl describe routerules helloworld-default 17 | 18 | Name: helloworld-default 19 | Namespace: default 20 | Labels: 21 | Annotations: 22 | API Version: config.istio.io/v1alpha2 23 | Kind: RouteRule 24 | Metadata: 25 | ... 26 | Spec: 27 | Destination: 28 | Name: helloworld-service 29 | Precedence: 1 30 | Route: 31 | Labels: 32 | Version: 1.0 33 | ``` 34 | 35 | 2. Now when you curl the echo service, it should always return `v1` of the Hello World service. 36 | 37 | ```sh 38 | curl http://$INGRESS_IP/echo/universe 39 | 40 | {"greeting":{"hostname":"helloworld-service-v1-286408581-9204h","greeting":"Hello universe from helloworld-service-v1-286408581-9204h with 1.0","version":"1.0"}," 41 | ``` 42 | 43 | ```sh 44 | curl http://$INGRESS_IP/echo/universe 45 | 46 | {"greeting":{"hostname":"helloworld-service-v1-286408581-9204h","greeting":"Hello universe from helloworld-service-v1-286408581-9204h with 1.0","version":"1.0"}," 47 | ``` 48 | 3. Clean up 49 | ```sh 50 | istioctl delete -f guestbook/route-rule-force-hello-v1.yaml 51 | ``` 52 | 53 | ### Canary Deployments 54 | 55 | Currently the routing rule only routes to `v1` of the Hello World service. What we want to do is canary a deployment of `v2` of the Hello World service by allowing only a small amount of traffic to it. This can be done by creating another rule with a higher precedence that routes some of the traffic to `v2`. We'll canary based on HTTP headers: if the user-agent is "mobile", it will go to `v2`; otherwise, requests will go to `v1`. Written as a route rule, this looks like: 56 | 57 | ```yaml 58 | destination: 59 | name: helloworld-service 60 | match: 61 | request: 62 | headers: 63 | user-agent: 64 | exact: mobile 65 | precedence: 2 66 | route: 67 | - labels: 68 | version: "2.0" 69 | ``` 70 | 71 | Note that rules with a higher precedence number are applied first. If a precedence is not specified, then it defaults to 0. So with these two rules in place, the one with precedence 2 will be applied before the rule with precedence 1. 72 | 73 | 1. Test this out by creating the canary rule. 74 | 75 | ```sh 76 | istioctl create -f guestbook/route-rule-canary.yaml 77 | ``` 78 | 79 | 2. Now when you curl the end point, set the user agent to be mobile. You should only see `v2`. 80 | 81 | ```sh 82 | curl http://$INGRESS_IP/echo/universe -A mobile 83 | 84 | {"greeting":{"hostname":"helloworld-service-v2-3297856697-6m4bp","greeting":"Hola world from helloworld-service-v2-1131997838-qnwcm version 2.0","version":"2.0"} 85 | ``` 86 | 87 | Without the user agent being set to mobile, you should still only see `v1`: 88 | 89 | ```sh 90 | $ curl http://$INGRESS_IP/echo/universe 91 | 92 | {"greeting":{"hostname":"helloworld-service-v1-286408581-9204h","greeting":"Hello universe from helloworld-service-v1-286408581-9204h with 1.0","version":"1.0"}," 93 | ``` 94 | 95 | Note that the user-agent HTTP header is propagated in the span baggage. Check out these two classes for details on how the header is [injected](https://github.com/retroryan/istio-by-example-java/blob/master/spring-boot-example/spring-istio-support/src/main/java/com/example/istio/IstioHttpSpanInjector.java) and [extracted](https://github.com/retroryan/istio-by-example-java/blob/master/spring-boot-example/spring-istio-support/src/main/java/com/example/istio/IstioHttpSpanExtractor.java). 96 | 97 | 3. Clean up 98 | ```sh 99 | istioctl delete -f guestbook/route-rule-canary.yaml 100 | ``` 101 | ### Optional - Route based on the browser 102 | 103 | It is also possible to route based on the web browser used. For example, the following rule routes to `v2` if the browser is Chrome: 104 | 105 | ```yaml 106 | match: 107 | request: 108 | headers: 109 | user-agent: 110 | regex: ".*Chrome.*" 111 | route: 112 | - labels: 113 | version: "2.0" 114 | ``` 115 | 116 | 1. To apply this route rule, run: 117 | 118 | ```sh 119 | istioctl create -f guestbook/route-rule-user-agent-chrome.yaml 120 | ``` 121 | 122 | 2. Navigate to `http://$INGRESS_IP/echo/universe` in Chrome. You should see: 123 | 124 | ``` 125 | Hola test from helloworld-service-v2-87744028-x20j0 version 2.0 126 | ``` 127 | 128 | 3. Navigate to `http://$INGRESS_IP/echo/universe` in another browser. You should see: 129 | 130 | ``` 131 | Hello sdsdffsd from helloworld-service-v1-4086392344-42q21 with 1.0 132 | ``` 133 | 4. Clean 134 | 135 | ```sh 136 | istioctl delete -f guestbook/route-rule-user-agent-chrome.yaml 137 | ``` 138 | 139 | #### [Continue to Exercise 10 - Fault Injection and Circuit Breaking](../exercise-10/README.md) 140 | -------------------------------------------------------------------------------- /guestbook/broken-redis-service.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # DO NOT NAME THE PORT REDIS!!! This routes the connection through Istio and breaks the application 16 | 17 | kind: Service 18 | apiVersion: v1 19 | metadata: 20 | name: redis 21 | labels: 22 | app: redis 23 | visualize: "true" 24 | spec: 25 | ports: 26 | - port: 6379 27 | name: redis 28 | selector: 29 | app: redis 30 | -------------------------------------------------------------------------------- /guestbook/deleteGuestBook.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPTDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) 4 | 5 | kubectl delete -f $SCRIPTDIR/mysql-pvc.yaml -f $SCRIPTDIR/mysql-deployment.yaml -f $SCRIPTDIR/mysql-service.yaml 6 | kubectl delete -f $SCRIPTDIR/redis-deployment.yaml -f $SCRIPTDIR/redis-service.yaml 7 | kubectl delete -f $SCRIPTDIR/helloworld-deployment.yaml -f $SCRIPTDIR/helloworld-service.yaml 8 | kubectl delete -f $SCRIPTDIR/helloworld-deployment-v2.yaml 9 | kubectl delete -f $SCRIPTDIR/guestbook-deployment.yaml -f $SCRIPTDIR/guestbook-service.yaml 10 | kubectl delete -f $SCRIPTDIR/guestbook-ui-deployment.yaml -f $SCRIPTDIR/guestbook-ui-service.yaml 11 | -------------------------------------------------------------------------------- /guestbook/deployGuestBookIstio.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPTDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) 4 | 5 | 6 | kubectl apply -f <(istioctl kube-inject -f guestbook/mysql-deployment.yaml) -f guestbook/mysql-service.yaml 7 | kubectl apply -f <(istioctl kube-inject -f guestbook/redis-deployment.yaml) -f guestbook/redis-service.yaml 8 | kubectl apply -f <(istioctl kube-inject -f guestbook/helloworld-deployment.yaml) -f guestbook/helloworld-service.yaml 9 | kubectl apply -f <(istioctl kube-inject -f guestbook/helloworld-deployment-v2.yaml) 10 | 11 | ### Wait for mysql and redis startup before starting guestbook !!!! 12 | sleep 120 13 | 14 | kubectl apply -f <(istioctl kube-inject -f guestbook/guestbook-deployment.yaml) -f guestbook/guestbook-service.yaml 15 | 16 | ### Wait for guestbook service startup before starting Guest Book UI" 17 | sleep 120 18 | 19 | kubectl apply -f <(istioctl kube-inject -f guestbook/guestbook-ui-deployment.yaml) -f guestbook/guestbook-ui-service.yaml 20 | -------------------------------------------------------------------------------- /guestbook/deployGuestBookIstioWindows.txt: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPTDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) 4 | 5 | kubectl apply -f $SCRIPTDIR/mysql-pvc.yaml -f <(istioctl kube-inject -f $SCRIPTDIR/mysql-deployment.yaml) -f $SCRIPTDIR/mysql-service.yaml 6 | kubectl apply -f <(istioctl kube-inject -f $SCRIPTDIR/redis-deployment.yaml) -f $SCRIPTDIR/redis-service.yaml 7 | kubectl apply -f <(istioctl kube-inject -f $SCRIPTDIR/helloworld-deployment.yaml) -f $SCRIPTDIR/helloworld-service.yaml 8 | kubectl apply -f <(istioctl kube-inject -f $SCRIPTDIR/helloworld-deployment-v2.yaml) 9 | echo "Waiting for mysql and redis startup before starting guestbook" 10 | sleep 120 11 | kubectl apply -f <(istioctl kube-inject -f $SCRIPTDIR/guestbook-deployment.yaml) -f $SCRIPTDIR/guestbook-service.yaml 12 | echo "Waiting for guestbook service startup before starting Guest Book UI" 13 | sleep 120 14 | kubectl apply -f <(istioctl kube-inject -f $SCRIPTDIR/guestbook-ui-deployment.yaml) -f $SCRIPTDIR/guestbook-ui-service.yaml 15 | -------------------------------------------------------------------------------- /guestbook/deployGuestBookKube.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPTDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) 4 | 5 | kubectl apply -f $SCRIPTDIR/mysql-pvc.yaml -f $SCRIPTDIR/mysql-deployment.yaml -f $SCRIPTDIR/mysql-service.yaml 6 | kubectl apply -f $SCRIPTDIR/redis-deployment.yaml -f $SCRIPTDIR/redis-service.yaml 7 | kubectl apply -f $SCRIPTDIR/helloworld-deployment.yaml -f $SCRIPTDIR/helloworld-service.yaml 8 | kubectl apply -f $SCRIPTDIR/helloworld-deployment-v2.yaml 9 | echo "Waiting for mysql and redis startup before starting guestbook" 10 | sleep 120 11 | kubectl apply -f $SCRIPTDIR/guestbook-deployment.yaml -f $SCRIPTDIR/guestbook-service.yaml 12 | sleep 120 13 | echo "Waiting for guestbook startup before starting UI" 14 | kubectl apply -f $SCRIPTDIR/guestbook-ui-deployment.yaml -f $SCRIPTDIR/guestbook-ui-service.yaml 15 | -------------------------------------------------------------------------------- /guestbook/frontdoor-ingress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Ingress 3 | metadata: 4 | name: istio-fd 5 | namespace: istio-system 6 | spec: 7 | tls: 8 | - hosts: 9 | - xxxx.us-east.containers.mybluemix.net 10 | secretName: ssss 11 | rules: 12 | - host: xxxx.us-east.containers.mybluemix.net 13 | http: 14 | paths: 15 | - path: / 16 | backend: 17 | serviceName: istio-ingress 18 | servicePort: 80 19 | - host: jaeger.xxxx.us-east.containers.mybluemix.net 20 | http: 21 | paths: 22 | - path: / 23 | backend: 24 | serviceName: jaeger 25 | servicePort: 16686 26 | - host: grafana.xxxx.us-east.containers.mybluemix.net 27 | http: 28 | paths: 29 | - path: / 30 | backend: 31 | serviceName: grafana 32 | servicePort: 3000 33 | -------------------------------------------------------------------------------- /guestbook/guestbook-deployment.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: extensions/v1beta1 16 | kind: Deployment 17 | metadata: 18 | labels: 19 | app: guestbook-service 20 | visualize: "true" 21 | name: guestbook-service 22 | spec: 23 | replicas: 1 24 | selector: 25 | matchLabels: 26 | app: guestbook-service 27 | serving: "true" 28 | template: 29 | metadata: 30 | labels: 31 | app: guestbook-service 32 | serving: "true" 33 | version: latest 34 | visualize: "true" 35 | layer: controller-plane 36 | spec: 37 | containers: 38 | - name: guestbook-service 39 | image: retroryan/guestbook-service-istio:java-1.0 40 | ports: 41 | - containerPort: 8080 42 | name: http 43 | -------------------------------------------------------------------------------- /guestbook/guestbook-ingress.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: networking.istio.io/v1alpha3 16 | kind: Gateway 17 | metadata: 18 | name: simple-ingress 19 | spec: 20 | selector: 21 | istio: ingressgateway 22 | servers: 23 | - port: 24 | number: 80 25 | name: guestbook 26 | protocol: HTTP 27 | -------------------------------------------------------------------------------- /guestbook/guestbook-service.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | kind: Service 16 | apiVersion: v1 17 | metadata: 18 | name: guestbook-service 19 | labels: 20 | app: guestbook-service 21 | visualize: "true" 22 | spec: 23 | ports: 24 | - port: 8080 25 | targetPort: 8080 26 | name: http 27 | selector: 28 | app: guestbook-service 29 | serving: "true" 30 | -------------------------------------------------------------------------------- /guestbook/guestbook-telemetry.yaml: -------------------------------------------------------------------------------- 1 | # Configuration for metric instances 2 | apiVersion: "config.istio.io/v1alpha2" 3 | kind: metric 4 | metadata: 5 | name: doublerequestcount 6 | namespace: istio-system 7 | spec: 8 | value: "2" # count each request twice 9 | dimensions: 10 | source: source.service | "unknown" 11 | destination: destination.service | "unknown" 12 | message: '"twice the fun!"' 13 | monitored_resource_type: '"UNSPECIFIED"' 14 | --- 15 | # Configuration for a Prometheus handler 16 | apiVersion: "config.istio.io/v1alpha2" 17 | kind: prometheus 18 | metadata: 19 | name: doublehandler 20 | namespace: istio-system 21 | spec: 22 | metrics: 23 | - name: double_request_count # Prometheus metric name 24 | instance_name: doublerequestcount.metric.istio-system # Mixer instance name (fully-qualified) 25 | kind: COUNTER 26 | label_names: 27 | - source 28 | - destination 29 | - message 30 | --- 31 | # Rule to send metric instances to a Prometheus handler 32 | apiVersion: "config.istio.io/v1alpha2" 33 | kind: rule 34 | metadata: 35 | name: doubleprom 36 | namespace: istio-system 37 | spec: 38 | actions: 39 | - handler: doublehandler.prometheus 40 | instances: 41 | - doublerequestcount.metric 42 | --- 43 | # Configuration for logentry instances 44 | apiVersion: "config.istio.io/v1alpha2" 45 | kind: logentry 46 | metadata: 47 | name: newlog 48 | namespace: istio-system 49 | spec: 50 | severity: '"warning"' 51 | timestamp: request.time 52 | variables: 53 | source: source.labels["app"] | source.service | "unknown" 54 | user: source.user | "unknown" 55 | destination: destination.labels["app"] | destination.service | "unknown" 56 | responseCode: response.code | 0 57 | responseSize: response.size | 0 58 | latency: response.duration | "0ms" 59 | monitored_resource_type: '"UNSPECIFIED"' 60 | --- 61 | # Configuration for a stdio handler 62 | apiVersion: "config.istio.io/v1alpha2" 63 | kind: stdio 64 | metadata: 65 | name: newhandler 66 | namespace: istio-system 67 | spec: 68 | severity_levels: 69 | warning: 1 # Params.Level.WARNING 70 | outputAsJson: true 71 | --- 72 | # Rule to send logentry instances to a stdio handler 73 | apiVersion: "config.istio.io/v1alpha2" 74 | kind: rule 75 | metadata: 76 | name: newlogstdio 77 | namespace: istio-system 78 | spec: 79 | match: "true" # match for all requests 80 | actions: 81 | - handler: newhandler.stdio 82 | instances: 83 | - newlog.logentry 84 | --- 85 | -------------------------------------------------------------------------------- /guestbook/guestbook-ui-deployment.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: extensions/v1beta1 16 | kind: Deployment 17 | metadata: 18 | name: guestbook-ui 19 | labels: 20 | app: guestbook-ui 21 | visualize: "true" 22 | spec: 23 | replicas: 1 24 | selector: 25 | matchLabels: 26 | app: guestbook-ui 27 | serving: "true" 28 | template: 29 | metadata: 30 | labels: 31 | app: guestbook-ui 32 | version: latest 33 | serving: "true" 34 | visualize: "true" 35 | layer: frontend 36 | annotations: 37 | visualizer/uses: helloworld-service,guestbook-service,redis 38 | spec: 39 | containers: 40 | - name: guestbook-ui 41 | image: retroryan/guestbook-ui-istio:java-1.0 42 | ports: 43 | - name: http 44 | containerPort: 8080 45 | -------------------------------------------------------------------------------- /guestbook/guestbook-ui-service.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | kind: Service 16 | apiVersion: v1 17 | metadata: 18 | name: guestbook-ui 19 | labels: 20 | app: guestbook-ui 21 | visualize: "true" 22 | spec: 23 | type: LoadBalancer 24 | ports: 25 | - port: 80 26 | targetPort: 8080 27 | name: http 28 | selector: 29 | app: guestbook-ui 30 | serving: "true" 31 | -------------------------------------------------------------------------------- /guestbook/helloworld-deployment-v2.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: extensions/v1beta1 16 | kind: Deployment 17 | metadata: 18 | name: helloworld-service-v2 19 | labels: 20 | app: helloworld-service-v2 21 | visualize: "true" 22 | version: "2.0" 23 | spec: 24 | replicas: 1 25 | selector: 26 | matchLabels: 27 | app: helloworld-service 28 | serving: "true" 29 | template: 30 | metadata: 31 | labels: 32 | app: helloworld-service 33 | version: "latest" 34 | serving: "true" 35 | visualize: "true" 36 | version: "2.0" 37 | layer: controller-plane 38 | spec: 39 | containers: 40 | - name: helloworld-service 41 | image: retroryan/helloworld-service-istio:java-1.0 42 | env: 43 | - name: version 44 | value: "2.0" 45 | - name: GREETING 46 | value: "Hola $name from $hostname version $version" 47 | ports: 48 | - name: http 49 | containerPort: 8080 50 | -------------------------------------------------------------------------------- /guestbook/helloworld-deployment.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: extensions/v1beta1 16 | kind: Deployment 17 | metadata: 18 | name: helloworld-service-v1 19 | labels: 20 | app: helloworld-service-v1 21 | visualize: "true" 22 | version: "1.0" 23 | spec: 24 | replicas: 1 25 | selector: 26 | matchLabels: 27 | app: helloworld-service 28 | serving: "true" 29 | template: 30 | metadata: 31 | labels: 32 | app: helloworld-service 33 | version: "latest" 34 | serving: "true" 35 | visualize: "true" 36 | version: "1.0" 37 | layer: controller-plane 38 | spec: 39 | containers: 40 | - name: helloworld-service 41 | image: retroryan/helloworld-service-istio:java-1.0 42 | env: 43 | - name: version 44 | value: "1.0" 45 | ports: 46 | - name: http 47 | containerPort: 8080 48 | -------------------------------------------------------------------------------- /guestbook/helloworld-service.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | kind: Service 16 | apiVersion: v1 17 | metadata: 18 | name: helloworld-service 19 | labels: 20 | app: helloworld-service 21 | visualize: "true" 22 | spec: 23 | type: LoadBalancer 24 | ports: 25 | - port: 8080 26 | targetPort: 8080 27 | name: http 28 | selector: 29 | app: helloworld-service 30 | serving: "true" 31 | -------------------------------------------------------------------------------- /guestbook/mixer-kubernetes-rules.yaml: -------------------------------------------------------------------------------- 1 | rules: 2 | - selector: # must be empty for preprocessing adapters 3 | aspects: 4 | # when running local without a kubeconfig file specified in globalconfig, 5 | # this aspect should be commented out. It is only needed when the attributes 6 | # it produces are needed elsewhere in the config. 7 | - kind: attributes 8 | params: 9 | input_expressions: 10 | sourceUID: source.uid | "" 11 | targetUID: target.uid | "" 12 | originUID: origin.uid | "" 13 | targetService: request.headers["authority"] | request.host | "" 14 | attribute_bindings: 15 | source.ip: sourcePodIp 16 | source.labels: sourceLabels 17 | source.name: sourcePodName 18 | source.namespace: sourceNamespace 19 | source.service: sourceService 20 | source.serviceAccount: sourceServiceAccountName 21 | target.ip: targetPodIp 22 | target.labels: targetLabels 23 | target.name: targetPodName 24 | target.namespace: targetNamespace 25 | target.service: targetService 26 | target.serviceAccount: targetServiceAccountName 27 | -------------------------------------------------------------------------------- /guestbook/mixer-rule-denial-v2.yaml: -------------------------------------------------------------------------------- 1 | 2 | # Create a denier that returns a google.rpc.Code 7 (PERMISSION_DENIED) 3 | apiVersion: "config.istio.io/v1alpha2" 4 | kind: denier 5 | metadata: 6 | name: denyall 7 | namespace: istio-system 8 | spec: 9 | status: 10 | code: 7 11 | message: Not allowed 12 | --- 13 | # The (empty) data handed to denyall at run time 14 | apiVersion: "config.istio.io/v1alpha2" 15 | kind: checknothing 16 | metadata: 17 | name: denyrequest 18 | namespace: istio-system 19 | spec: 20 | --- 21 | # Rule that re-uses denier to deny requests to version two of the hello world UI 22 | apiVersion: "config.istio.io/v1alpha2" 23 | kind: rule 24 | metadata: 25 | name: deny-hello-world 26 | namespace: istio-system 27 | spec: 28 | match: destination.service=="helloworld-service.default.svc.cluster.local" && destination.labels["version"] == "2.0" 29 | actions: 30 | - handler: denyall.denier 31 | instances: 32 | - denyrequest.checknothing 33 | -------------------------------------------------------------------------------- /guestbook/mixer-rule-denial.yaml: -------------------------------------------------------------------------------- 1 | # Create a denier that returns a google.rpc.Code 7 (PERMISSION_DENIED) 2 | apiVersion: "config.istio.io/v1alpha2" 3 | kind: denier 4 | metadata: 5 | name: denyall 6 | namespace: istio-system 7 | spec: 8 | status: 9 | code: 7 10 | message: Not allowed 11 | --- 12 | # The (empty) data handed to denyall at run time 13 | apiVersion: "config.istio.io/v1alpha2" 14 | kind: checknothing 15 | metadata: 16 | name: denyrequest 17 | namespace: istio-system 18 | spec: 19 | --- 20 | # The rule that uses denier to deny requests 21 | apiVersion: "config.istio.io/v1alpha2" 22 | kind: rule 23 | metadata: 24 | name: deny-hello-world 25 | namespace: istio-system 26 | spec: 27 | match: destination.service=="helloworld-service.default.svc.cluster.local" 28 | actions: 29 | - handler: denyall.denier 30 | instances: 31 | - denyrequest.checknothing 32 | -------------------------------------------------------------------------------- /guestbook/mysql-deployment.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: extensions/v1beta1 16 | kind: Deployment 17 | metadata: 18 | name: mysql 19 | labels: 20 | app: mysql 21 | visualize: "true" 22 | spec: 23 | replicas: 1 24 | template: 25 | metadata: 26 | labels: 27 | app: mysql 28 | visualize: "true" 29 | layer: data-plane 30 | spec: 31 | containers: 32 | - name: mysql 33 | image: mysql:5.6 34 | livenessProbe: 35 | tcpSocket: 36 | port: 3306 37 | env: 38 | - name: MYSQL_ROOT_PASSWORD 39 | # change this 40 | value: yourpassword 41 | - name: MYSQL_DATABASE 42 | value: app 43 | ports: 44 | - containerPort: 3306 45 | name: mysql 46 | -------------------------------------------------------------------------------- /guestbook/mysql-pvc.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | kind: PersistentVolumeClaim 16 | apiVersion: v1 17 | metadata: 18 | name: mysql-pvc 19 | annotations: 20 | volume.beta.kubernetes.io/storage-class: "ibmc-file-bronze" 21 | spec: 22 | accessModes: 23 | - ReadWriteOnce 24 | resources: 25 | requests: 26 | storage: 5Gi 27 | -------------------------------------------------------------------------------- /guestbook/mysql-service.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: v1 16 | kind: Service 17 | metadata: 18 | name: mysql 19 | labels: 20 | app: mysql 21 | visualize: "true" 22 | spec: 23 | ports: 24 | # the port that this service should serve on 25 | - port: 3306 26 | name: mysql 27 | # label keys and values that must match in order to receive traffic for this service 28 | selector: 29 | app: mysql 30 | -------------------------------------------------------------------------------- /guestbook/rate-limit-ui-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: config.istio.io/v1alpha2 2 | kind: memquota 3 | metadata: 4 | name: handler 5 | namespace: istio-system 6 | spec: 7 | quotas: 8 | - name: requestcount.quota.istio-system 9 | # default rate limit is 5000qps 10 | maxAmount: 5000 11 | validDuration: 1s 12 | overrides: 13 | # The following override applies to traffic from 'rewiews' version v2, 14 | # destined for the ratings service. The destinationVersion dimension is ignored. 15 | - dimensions: 16 | destination: helloworld-service 17 | maxAmount: 1 18 | validDuration: 60s 19 | 20 | --- 21 | 22 | apiVersion: config.istio.io/v1alpha2 23 | kind: quota 24 | metadata: 25 | name: requestcount 26 | namespace: istio-system 27 | spec: 28 | dimensions: 29 | source: source.labels["app"] | source.service | "unknown" 30 | sourceVersion: source.labels["version"] | "unknown" 31 | destination: destination.labels["app"] | destination.service | "unknown" 32 | destinationVersion: destination.labels["version"] | "unknown" 33 | --- 34 | apiVersion: config.istio.io/v1alpha2 35 | kind: rule 36 | metadata: 37 | name: quota 38 | namespace: istio-system 39 | spec: 40 | actions: 41 | - handler: handler.memquota 42 | instances: 43 | - requestcount.quota 44 | 45 | -------------------------------------------------------------------------------- /guestbook/redis-deployment.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: extensions/v1beta1 16 | kind: Deployment 17 | metadata: 18 | name: redis 19 | labels: 20 | app: redis 21 | visualize: "true" 22 | spec: 23 | replicas: 1 24 | template: 25 | metadata: 26 | labels: 27 | app: redis 28 | version: "4.0.2" 29 | visualize: "true" 30 | spec: 31 | containers: 32 | - name: redis 33 | image: redis 34 | livenessProbe: 35 | tcpSocket: 36 | port: 6379 37 | ports: 38 | - name: redis-server 39 | containerPort: 6379 40 | -------------------------------------------------------------------------------- /guestbook/redis-service.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # DO NOT NAME THE PORT REDIS!!! This routes the connection through Istio and breaks the application 16 | 17 | kind: Service 18 | apiVersion: v1 19 | metadata: 20 | name: redis 21 | labels: 22 | app: redis 23 | visualize: "true" 24 | spec: 25 | ports: 26 | - port: 6379 27 | selector: 28 | app: redis 29 | -------------------------------------------------------------------------------- /guestbook/route-rule-80-20.yaml: -------------------------------------------------------------------------------- 1 | type: route-rule 2 | name: route8020-helloworld-service 3 | spec: 4 | destination: helloworld-service.default.svc.cluster.local 5 | precedence: 1 6 | route: 7 | - tags: 8 | version: "1.0" 9 | weight: 80 10 | - tags: 11 | version: "2.0" 12 | weight: 20 13 | -------------------------------------------------------------------------------- /guestbook/route-rule-canary.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: config.istio.io/v1alpha2 2 | kind: RouteRule 3 | metadata: 4 | name: canary-helloworld 5 | namespace: default 6 | spec: 7 | destination: 8 | name: helloworld-service 9 | match: 10 | request: 11 | headers: 12 | user-agent: 13 | exact: mobile 14 | precedence: 2 15 | route: 16 | - labels: 17 | version: "2.0" 18 | -------------------------------------------------------------------------------- /guestbook/route-rule-delay-guestbook.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: config.istio.io/v1alpha2 2 | kind: RouteRule 3 | metadata: 4 | name: guestbook-test-delay 5 | namespace: default 6 | spec: 7 | destination: 8 | name: helloworld-service 9 | precedence: 2 10 | match: 11 | request: 12 | headers: 13 | user-agent: 14 | exact: mobile 15 | route: 16 | - labels: 17 | version: v2 18 | httpFault: 19 | delay: 20 | percent: 100 21 | fixedDelay: 5s 22 | -------------------------------------------------------------------------------- /guestbook/route-rule-force-hello-v1.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: config.istio.io/v1alpha2 2 | kind: RouteRule 3 | metadata: 4 | name: helloworld-default 5 | namespace: default 6 | spec: 7 | destination: 8 | name: helloworld-service 9 | precedence: 1 10 | route: 11 | - labels: 12 | version: "1.0" 13 | -------------------------------------------------------------------------------- /guestbook/route-rule-helloworld-service-503.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: config.istio.io/v1alpha2 2 | kind: RouteRule 3 | metadata: 4 | name: helloworld-service-503 5 | namespace: default 6 | spec: 7 | destination: 8 | name: helloworld-service 9 | precedence: 10 10 | route: 11 | - labels: 12 | version: "2.0" 13 | httpFault: 14 | abort: 15 | percent: 100 16 | httpStatus: 503 17 | -------------------------------------------------------------------------------- /guestbook/route-rule-user-agent-chrome.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: config.istio.io/v1alpha2 2 | kind: RouteRule 3 | metadata: 4 | name: helloworld-service-chrome 5 | namespace: default 6 | spec: 7 | destination: 8 | name: helloworld-service 9 | precedence: 3 10 | match: 11 | request: 12 | headers: 13 | user-agent: 14 | regex: ".*Chrome.*" 15 | route: 16 | - labels: 17 | version: "2.0" 18 | -------------------------------------------------------------------------------- /guestbook/telemetry-global.yaml: -------------------------------------------------------------------------------- 1 | revision: "2022" 2 | rules: 3 | - aspects: 4 | - kind: attributes 5 | params: 6 | attribute_bindings: 7 | source.ip: sourcePodIp 8 | source.labels: sourceLabels 9 | source.name: sourcePodName 10 | source.namespace: sourceNamespace 11 | source.service: sourceService 12 | source.serviceAccount: sourceServiceAccountName 13 | target.ip: targetPodIp 14 | target.labels: targetLabels 15 | target.name: targetPodName 16 | target.namespace: targetNamespace 17 | target.service: targetService 18 | target.serviceAccount: targetServiceAccountName 19 | input_expressions: 20 | originUID: origin.uid | "" 21 | sourceUID: source.uid | "" 22 | targetService: request.headers["authority"] | request.host | "" 23 | targetUID: target.uid | "" 24 | - kind: quotas 25 | params: 26 | quotas: 27 | - descriptorName: RequestCount 28 | expiration: 1s 29 | maxAmount: 5000 30 | - adapter: prometheus 31 | kind: metrics 32 | params: 33 | metrics: 34 | - descriptor_name: request_count 35 | labels: 36 | method: request.path | "unknown" 37 | response_code: response.code | 200 38 | service: target.labels["app"] | "unknown" 39 | source: source.labels["app"] | "unknown" 40 | target: target.service | "unknown" 41 | version: target.labels["version"] | "unknown" 42 | value: "1" 43 | - descriptor_name: request_duration 44 | labels: 45 | method: request.path | "unknown" 46 | response_code: response.code | 200 47 | service: target.labels["app"] | "unknown" 48 | source: source.labels["app"] | "unknown" 49 | target: target.service | "unknown" 50 | version: target.labels["version"] | "unknown" 51 | value: response.latency | response.duration | "0ms" 52 | - kind: access-logs 53 | params: 54 | log: 55 | descriptor_name: accesslog.common 56 | labels: 57 | method: request.method 58 | originIp: origin.ip 59 | protocol: request.scheme 60 | responseCode: response.code 61 | responseSize: response.size 62 | sourceUser: origin.user 63 | timestamp: request.time 64 | url: request.path 65 | template_expressions: 66 | method: request.method 67 | originIp: origin.ip 68 | protocol: request.scheme 69 | responseCode: response.code 70 | responseSize: response.size 71 | sourceUser: origin.user 72 | timestamp: request.time 73 | url: request.path 74 | logName: access_log 75 | subject: namespace:ns 76 | -------------------------------------------------------------------------------- /guestbook/telemtry_rule.yaml: -------------------------------------------------------------------------------- 1 | # Configuration for metric instances 2 | apiVersion: "config.istio.io/v1alpha2" 3 | kind: metric 4 | metadata: 5 | name: lab10requestcount 6 | namespace: istio-system 7 | spec: 8 | value: "1" # count each request twice 9 | dimensions: 10 | source: source.service | "unknown" 11 | destination: destination.service | "unknown" 12 | message: '"counting!"' 13 | monitored_resource_type: '"UNSPECIFIED"' 14 | --- 15 | # Configuration for a Prometheus handler 16 | apiVersion: "config.istio.io/v1alpha2" 17 | kind: prometheus 18 | metadata: 19 | name: counthandler 20 | namespace: istio-system 21 | spec: 22 | metrics: 23 | - name: request_count # Prometheus metric name 24 | instance_name: lab10requestcount.metric.istio-system # Mixer instance name (fully-qualified) 25 | kind: COUNTER 26 | label_names: 27 | - source 28 | - destination 29 | - message 30 | --- 31 | # Rule to send metric instances to a Prometheus handler 32 | apiVersion: "config.istio.io/v1alpha2" 33 | kind: rule 34 | metadata: 35 | name: prom 36 | namespace: istio-system 37 | spec: 38 | actions: 39 | - handler: counthandler.prometheus 40 | instances: 41 | - lab10requestcount.metric 42 | --- 43 | # Configuration for logentry instances 44 | apiVersion: "config.istio.io/v1alpha2" 45 | kind: logentry 46 | metadata: 47 | name: newlog 48 | namespace: istio-system 49 | spec: 50 | severity: '"warning"' 51 | timestamp: request.time 52 | variables: 53 | source: source.labels["app"] | source.service | "unknown" 54 | user: source.user | "unknown" 55 | destination: destination.labels["app"] | destination.service | "unknown" 56 | responseCode: response.code | 0 57 | responseSize: response.size | 0 58 | latency: response.duration | "0ms" 59 | monitored_resource_type: '"UNSPECIFIED"' 60 | --- 61 | # Configuration for a stdio handler 62 | apiVersion: "config.istio.io/v1alpha2" 63 | kind: stdio 64 | metadata: 65 | name: newhandler 66 | namespace: istio-system 67 | spec: 68 | severity_levels: 69 | warning: 1 # Params.Level.WARNING 70 | outputAsJson: true 71 | --- 72 | # Rule to send logentry instances to a stdio handler 73 | apiVersion: "config.istio.io/v1alpha2" 74 | kind: rule 75 | metadata: 76 | name: newlogstdio 77 | namespace: istio-system 78 | spec: 79 | match: "true" # match for all requests 80 | actions: 81 | - handler: newhandler.stdio 82 | instances: 83 | - newlog.logentry 84 | --- 85 | -------------------------------------------------------------------------------- /istio/deny-guestbook-service.yaml: -------------------------------------------------------------------------------- 1 | # Create a denier that returns a google.rpc.Code 7 (PERMISSION_DENIED) 2 | apiVersion: config.istio.io/v1alpha2 3 | kind: denier 4 | metadata: 5 | name: denyall 6 | namespace: istio-system 7 | spec: 8 | status: 9 | code: 7 10 | message: Not allowed 11 | --- 12 | # The (empty) data handed to denyall at run time 13 | apiVersion: config.istio.io/v1alpha2 14 | kind: checknothing 15 | metadata: 16 | name: denyrequest 17 | namespace: istio-system 18 | spec: 19 | --- 20 | # The rule that uses denier to deny requests with source.labels["app"] == "helloworld-service" 21 | apiVersion: config.istio.io/v1alpha2 22 | kind: rule 23 | metadata: 24 | name: deny-guestbook-service 25 | namespace: istio-system 26 | spec: 27 | match: destination.service=="guestbook-service.default.svc.cluster.local" 28 | actions: 29 | - handler: denyall.denier 30 | instances: 31 | - denyrequest.checknothing 32 | -------------------------------------------------------------------------------- /istio/guestbook-gateway.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: Gateway 3 | metadata: 4 | name: guestbook-gateway 5 | spec: 6 | selector: 7 | istio: ingressgateway 8 | servers: 9 | - hosts: 10 | - "*" 11 | port: 12 | number: 80 13 | name: http 14 | protocol: HTTP 15 | -------------------------------------------------------------------------------- /istio/guestbook-service-503-vs.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: guestbook-service 5 | spec: 6 | hosts: 7 | - guestbook-service 8 | http: 9 | - route: 10 | - destination: 11 | host: guestbook-service 12 | fault: 13 | abort: 14 | percent: 100 15 | httpStatus: 503 16 | -------------------------------------------------------------------------------- /istio/guestbook-service-dest.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: DestinationRule 3 | metadata: 4 | name: guestbook-service 5 | spec: 6 | host: guestbook-service 7 | trafficPolicy: 8 | connectionPool: 9 | tcp: 10 | maxConnections: 100 11 | http: 12 | maxRequestsPerConnection: 10 13 | http1MaxPendingRequests: 1024 14 | outlierDetection: 15 | http: 16 | consecutiveErrors: 7 17 | interval: 5m 18 | baseEjectionTime: 15m 19 | -------------------------------------------------------------------------------- /istio/guestbook-service-retry-vs.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: guestbook-service 5 | spec: 6 | hosts: 7 | - guestbook-service 8 | http: 9 | - route: 10 | - destination: 11 | host: guestbook-service 12 | retries: 13 | attempts: 3 14 | perTryTimeout: 2s 15 | 16 | -------------------------------------------------------------------------------- /istio/guestbook-ui-80p-v1-vs.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: guestbook-ui 5 | spec: 6 | hosts: 7 | - "*" 8 | gateways: 9 | - guestbook-gateway 10 | http: 11 | - match: 12 | - uri: 13 | prefix: / 14 | route: 15 | - destination: 16 | host: guestbook-ui 17 | subset: v1 18 | weight: 80 19 | - destination: 20 | host: guestbook-ui 21 | subset: v2 22 | weight: 20 23 | -------------------------------------------------------------------------------- /istio/guestbook-ui-chrome-vs.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: guestbook-ui 5 | spec: 6 | hosts: 7 | - guestbook-ui 8 | - "*" 9 | gateways: 10 | - guestbook-gateway 11 | http: 12 | - match: 13 | - uri: 14 | prefix: / 15 | headers: 16 | user-agent: 17 | regex: ".*Chrome.*" 18 | route: 19 | - destination: 20 | host: guestbook-ui 21 | subset: v2 22 | - match: 23 | - uri: 24 | prefix: / 25 | route: 26 | - destination: 27 | host: guestbook-ui 28 | subset: v1 29 | -------------------------------------------------------------------------------- /istio/guestbook-ui-delay-vs.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: guestbook-ui 5 | spec: 6 | hosts: 7 | - guestbook-ui 8 | - "*" 9 | gateways: 10 | - guestbook-gateway 11 | http: 12 | - match: 13 | - uri: 14 | prefix: / 15 | route: 16 | - destination: 17 | host: guestbook-ui 18 | subset: v1 19 | fault: 20 | delay: 21 | percent: 100 22 | fixedDelay: 5s 23 | -------------------------------------------------------------------------------- /istio/guestbook-ui-dest.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: DestinationRule 3 | metadata: 4 | name: guestbook-ui 5 | spec: 6 | host: guestbook-ui 7 | subsets: 8 | - name: v1 9 | labels: 10 | version: "1.0" 11 | - name: v2 12 | labels: 13 | version: "2.0" 14 | -------------------------------------------------------------------------------- /istio/guestbook-ui-v1-vs.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: guestbook-ui 5 | spec: 6 | hosts: 7 | - "*" 8 | gateways: 9 | - guestbook-gateway 10 | http: 11 | - match: 12 | - uri: 13 | prefix: / 14 | route: 15 | - destination: 16 | host: guestbook-ui 17 | subset: v1 18 | -------------------------------------------------------------------------------- /istio/guestbook-ui-vs.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: guestbook-ui 5 | spec: 6 | hosts: 7 | - "*" 8 | gateways: 9 | - guestbook-gateway 10 | http: 11 | - match: 12 | - uri: 13 | prefix: / 14 | route: 15 | - destination: 16 | host: guestbook-ui 17 | -------------------------------------------------------------------------------- /istio/helloworld-service-80p-v1-vs.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: helloworld-service 5 | spec: 6 | hosts: 7 | - helloworld-service 8 | http: 9 | - route: 10 | - destination: 11 | host: helloworld-service 12 | subset: v1 13 | weight: 80 14 | - destination: 15 | host: helloworld-service 16 | subset: v2 17 | weight: 20 18 | 19 | -------------------------------------------------------------------------------- /istio/helloworld-service-dest.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: DestinationRule 3 | metadata: 4 | name: helloworld-service 5 | spec: 6 | host: helloworld-service 7 | subsets: 8 | - name: v1 9 | labels: 10 | version: "1.0" 11 | - name: v2 12 | labels: 13 | version: "2.0" 14 | -------------------------------------------------------------------------------- /istio/helloworld-service-v1-vs.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: helloworld-service 5 | spec: 6 | hosts: 7 | - helloworld-service 8 | http: 9 | - route: 10 | - destination: 11 | host: helloworld-service 12 | subset: v1 13 | -------------------------------------------------------------------------------- /istio/rate-limits.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: config.istio.io/v1alpha2 2 | kind: memquota 3 | metadata: 4 | name: handler 5 | namespace: istio-system 6 | spec: 7 | quotas: 8 | - name: requestcount.quota.istio-system 9 | maxAmount: 100 10 | validDuration: 1s 11 | overrides: 12 | - dimensions: 13 | source: guestbook-ui 14 | destination: guestbook-service 15 | maxAmount: 1 16 | validDuration: 1s 17 | - dimensions: 18 | destination: helloworld-service 19 | maxAmount: 500 20 | validDuration: 1s 21 | --- 22 | apiVersion: config.istio.io/v1alpha2 23 | kind: quota 24 | metadata: 25 | name: requestcount 26 | namespace: istio-system 27 | spec: 28 | dimensions: 29 | source: source.labels["app"] | source.service | "unknown" 30 | sourceVersion: source.labels["version"] | "unknown" 31 | destination: destination.labels["app"] | destination.service | "unknown" 32 | destinationVersion: destination.labels["version"] | "unknown" 33 | --- 34 | apiVersion: "config.istio.io/v1alpha2" 35 | kind: rule 36 | metadata: 37 | name: quota 38 | namespace: istio-system 39 | spec: 40 | actions: 41 | - handler: handler.memquota 42 | instances: 43 | - requestcount.quota 44 | --- 45 | apiVersion: config.istio.io/v1alpha2 46 | kind: QuotaSpec 47 | metadata: 48 | name: request-count 49 | namespace: istio-system 50 | spec: 51 | rules: 52 | - quotas: 53 | - charge: 1 54 | quota: RequestCount 55 | --- 56 | apiVersion: config.istio.io/v1alpha2 57 | kind: QuotaSpecBinding 58 | metadata: 59 | name: request-count 60 | namespace: istio-system 61 | spec: 62 | quotaSpecs: 63 | - name: request-count 64 | namespace: istio-system 65 | services: 66 | - name: guestbook-ui 67 | - name: helloworld-service 68 | - name: guestbook-service 69 | -------------------------------------------------------------------------------- /kubernetes-v2/guestbook-ui-deployment-v2.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: extensions/v1beta1 16 | kind: Deployment 17 | metadata: 18 | name: guestbook-ui-v2 19 | labels: 20 | app: guestbook-ui 21 | version: "2.0" 22 | visualize: "true" 23 | spec: 24 | replicas: 1 25 | selector: 26 | matchLabels: 27 | app: guestbook-ui 28 | serving: "true" 29 | template: 30 | metadata: 31 | labels: 32 | app: guestbook-ui 33 | version: "2.0" 34 | serving: "true" 35 | visualize: "true" 36 | annotations: 37 | visualizer/uses: helloworld-service,guestbook-service,redis 38 | spec: 39 | containers: 40 | - name: guestbook-ui 41 | image: saturnism/guestbook-ui-istio:2.0 42 | env: 43 | - name: BACKEND_GUESTBOOK_SERVICE_URL 44 | value: http://guestbook-service:80/messages 45 | ports: 46 | - name: http 47 | containerPort: 8080 48 | -------------------------------------------------------------------------------- /kubernetes-v2/helloworld-deployment-v2.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: extensions/v1beta1 16 | kind: Deployment 17 | metadata: 18 | name: helloworld-service-v2 19 | labels: 20 | app: helloworld-service-v2 21 | visualize: "true" 22 | version: "2.0" 23 | spec: 24 | replicas: 1 25 | selector: 26 | matchLabels: 27 | app: helloworld-service 28 | serving: "true" 29 | template: 30 | metadata: 31 | labels: 32 | app: helloworld-service 33 | serving: "true" 34 | visualize: "true" 35 | version: "2.0" 36 | spec: 37 | containers: 38 | - name: helloworld-service 39 | image: saturnism/helloworld-service-istio:1.0 40 | env: 41 | - name: version 42 | value: "2.0" 43 | - name: GREETING 44 | value: "Hola $name from $hostname with 2.0" 45 | ports: 46 | - name: http 47 | containerPort: 8080 48 | -------------------------------------------------------------------------------- /kubernetes/guestbook-deployment.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: extensions/v1beta1 16 | kind: Deployment 17 | metadata: 18 | labels: 19 | app: guestbook-service 20 | visualize: "true" 21 | name: guestbook-service 22 | spec: 23 | replicas: 1 24 | selector: 25 | matchLabels: 26 | app: guestbook-service 27 | serving: "true" 28 | template: 29 | metadata: 30 | labels: 31 | app: guestbook-service 32 | serving: "true" 33 | version: "1.0" 34 | visualize: "true" 35 | spec: 36 | containers: 37 | - name: guestbook-service 38 | image: saturnism/guestbook-service-istio:1.0 39 | ports: 40 | - containerPort: 8080 41 | name: http 42 | -------------------------------------------------------------------------------- /kubernetes/guestbook-service.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | kind: Service 16 | apiVersion: v1 17 | metadata: 18 | name: guestbook-service 19 | labels: 20 | app: guestbook-service 21 | visualize: "true" 22 | spec: 23 | ports: 24 | - port: 80 25 | targetPort: 8080 26 | name: http 27 | selector: 28 | app: guestbook-service 29 | serving: "true" 30 | -------------------------------------------------------------------------------- /kubernetes/guestbook-ui-deployment.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: extensions/v1beta1 16 | kind: Deployment 17 | metadata: 18 | name: guestbook-ui 19 | labels: 20 | app: guestbook-ui 21 | visualize: "true" 22 | spec: 23 | replicas: 1 24 | selector: 25 | matchLabels: 26 | app: guestbook-ui 27 | serving: "true" 28 | template: 29 | metadata: 30 | labels: 31 | app: guestbook-ui 32 | version: "1.0" 33 | serving: "true" 34 | visualize: "true" 35 | annotations: 36 | visualizer/uses: helloworld-service,guestbook-service,redis 37 | spec: 38 | containers: 39 | - name: guestbook-ui 40 | image: saturnism/guestbook-ui-istio:1.0 41 | env: 42 | - name: BACKEND_GUESTBOOK_SERVICE_URL 43 | value: http://guestbook-service:80/messages 44 | ports: 45 | - name: http 46 | containerPort: 8080 47 | -------------------------------------------------------------------------------- /kubernetes/guestbook-ui-service.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | kind: Service 16 | apiVersion: v1 17 | metadata: 18 | name: guestbook-ui 19 | labels: 20 | app: guestbook-ui 21 | visualize: "true" 22 | spec: 23 | type: LoadBalancer 24 | ports: 25 | - port: 80 26 | targetPort: 8080 27 | name: http 28 | selector: 29 | app: guestbook-ui 30 | serving: "true" 31 | -------------------------------------------------------------------------------- /kubernetes/helloworld-deployment.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: extensions/v1beta1 16 | kind: Deployment 17 | metadata: 18 | name: helloworld-service-v1 19 | labels: 20 | app: helloworld-service-v1 21 | visualize: "true" 22 | version: "1.0" 23 | spec: 24 | replicas: 1 25 | selector: 26 | matchLabels: 27 | app: helloworld-service 28 | serving: "true" 29 | template: 30 | metadata: 31 | labels: 32 | app: helloworld-service 33 | version: "latest" 34 | serving: "true" 35 | visualize: "true" 36 | version: "1.0" 37 | spec: 38 | containers: 39 | - name: helloworld-service 40 | image: saturnism/helloworld-service-istio:1.0 41 | env: 42 | - name: version 43 | value: "1.0" 44 | ports: 45 | - name: http 46 | containerPort: 8080 47 | -------------------------------------------------------------------------------- /kubernetes/helloworld-service.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | kind: Service 16 | apiVersion: v1 17 | metadata: 18 | name: helloworld-service 19 | labels: 20 | app: helloworld-service 21 | visualize: "true" 22 | spec: 23 | ports: 24 | - port: 8080 25 | targetPort: 8080 26 | name: http 27 | selector: 28 | app: helloworld-service 29 | serving: "true" 30 | -------------------------------------------------------------------------------- /kubernetes/mysql-deployment.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: extensions/v1beta1 16 | kind: Deployment 17 | metadata: 18 | name: mysql 19 | labels: 20 | app: mysql 21 | visualize: "true" 22 | spec: 23 | replicas: 1 24 | template: 25 | metadata: 26 | labels: 27 | app: mysql 28 | visualize: "true" 29 | spec: 30 | containers: 31 | - name: mysql 32 | image: mysql:5.6 33 | livenessProbe: 34 | tcpSocket: 35 | port: 3306 36 | env: 37 | - name: MYSQL_ROOT_PASSWORD 38 | # change this 39 | value: yourpassword 40 | - name: MYSQL_DATABASE 41 | value: app 42 | ports: 43 | - containerPort: 3306 44 | name: mysql 45 | -------------------------------------------------------------------------------- /kubernetes/mysql-service.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: v1 16 | kind: Service 17 | metadata: 18 | name: mysql 19 | labels: 20 | app: mysql 21 | visualize: "true" 22 | spec: 23 | ports: 24 | # the port that this service should serve on 25 | - port: 3306 26 | name: mysql 27 | # label keys and values that must match in order to receive traffic for this service 28 | selector: 29 | app: mysql 30 | -------------------------------------------------------------------------------- /kubernetes/redis-deployment.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: extensions/v1beta1 16 | kind: Deployment 17 | metadata: 18 | name: redis 19 | labels: 20 | app: redis 21 | visualize: "true" 22 | spec: 23 | replicas: 1 24 | template: 25 | metadata: 26 | labels: 27 | app: redis 28 | version: "4.0.2" 29 | visualize: "true" 30 | spec: 31 | containers: 32 | - name: redis 33 | image: redis 34 | livenessProbe: 35 | tcpSocket: 36 | port: 6379 37 | ports: 38 | - name: redis-server 39 | containerPort: 6379 40 | -------------------------------------------------------------------------------- /kubernetes/redis-service.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # DO NOT NAME THE PORT REDIS!!! This routes the connection through Istio and breaks the application 16 | 17 | kind: Service 18 | apiVersion: v1 19 | metadata: 20 | name: redis 21 | labels: 22 | app: redis 23 | visualize: "true" 24 | spec: 25 | ports: 26 | - port: 6379 27 | selector: 28 | app: redis 29 | -------------------------------------------------------------------------------- /setup/README.md: -------------------------------------------------------------------------------- 1 | # Exercise 0: Workshop Setup 2 | 3 | 4 | Before you begin learning, you will need to install the required CLIs to create and manage your Kubernetes clusters in IBM Cloud Container Service, and to deploy containerized apps to your cluster. 5 | 6 | This lab includes the information for installing these CLIs and plug-ins: 7 | 8 | * IBM Cloud CLI version 0.5.0 or later 9 | * IBM Cloud Container Service plug-in 10 | * Kubernetes CLI version 1.7.4 or later 11 | * Optional: IBM Cloud Container Registry plug-in 12 | * Optional: Docker version 1.9 or later 13 | 14 | If you have already installed these CLIs and plug-ins, you can skip this lab and proceed to [Exercise 1 - Setting up a Kubernetes cluster](exercise-1/README.md). 15 | 16 | 17 | ## Install the IBM Cloud CLI 18 | 19 | As a prerequisite for the IBM Cloud Container Service plug-in, install the IBM Cloud command line interface, located at https://clis.ng.bluemix.net/ui/home.html. Once installed, you can access IBM Cloud from your command line with the prefix `bx`. 20 | 21 | Log in to the IBM Cloud CLI with `bx login`. Enter your IBM Cloud credentials when prompted. 22 | * Note: If you have a federated ID, use `bx login --sso` to log in to the IBM Cloud CLI. Enter your user name and use the provided URL in your CLI output to retrieve your one-time passcode. You know you have a federated ID when the login fails without the `--sso` and succeeds with the `--sso` option. 23 | 24 | ## Install the IBM Cloud Containers Service Plug-in 25 | 26 | To create Kubernetes clusters and manage worker nodes, install the IBM Cloud Container Service plug-in with `bx plugin install container-service -r Bluemix`. The prefix for running commands by using the IBM Cloud Container Service plug-in is `bx cs`. 27 | 28 | To verify that the plug-in is installed properly, run `bx plugin list`. The IBM Cloud Container Service plug-in is displayed in the results as `container-service`. 29 | 30 | Once the IBM Cloud CLI and the Containers Service plug-in are installed, you can move on to the next phase of the lab. 31 | 32 | ## Install the Kubernetes CLI 33 | 34 | To view a local version of the Kubernetes dashboard and to deploy apps into your clusters, you will need to install the Kubernetes CLI. The following links will install the CLI. Simply click the link corresponding to your operating system: 35 | 36 | OS X: https://storage.googleapis.com/kubernetes-release/release/v1.7.4/bin/darwin/amd64/kubectl 37 | Linux: https://storage.googleapis.com/kubernetes-release/release/v1.7.4/bin/linux/amd64/kubectl 38 | Windows: https://storage.googleapis.com/kubernetes-release/release/v1.7.4/bin/windows/amd64/kubectl.exe 39 | 40 | If you are using Windows, install the Kubernetes CLI in the same directory as the IBM Cloud CLI. This setup saves you some filepath changes when you run commands later. 41 | 42 | If you are using OSX or Linux, complete the following steps. 43 | 44 | Move the executable file to the `/usr/local/bin` directory with `mv //kubectl/usr/local/bin/kubectl`. 45 | 46 | Make sure that `/usr/local/bin` is listed in your PATH system variable. 47 | 48 | ```txt 49 | echo $PATH 50 | /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin 51 | ``` 52 | Convert the binary file to an executable with `chmod +x /usr/local/bin/kubectl`. 53 | 54 | ## Optional: Install the IBM Cloud Container Registry plug-in and Docker 55 | 56 | To manage a private image repository, install the IBM Cloud Container Registry plug-in. Use this plug-in to set up your own namespace in a multi-tenant, highly available, and scalable private image registry that is hosted by IBM, and to store and share Docker images with other users. Docker images are required to deploy containers into a cluster. The prefix for running registry commands is `bx cr`. 57 | 58 | To install the plug-in, run `bx plugin install container-registry -r Bluemix`. 59 | 60 | To verify that the plug-in is installed properly, run `bx plugin list`. The plug-in is displayed in the results as `container-registry`. 61 | 62 | To build images locally and push them to your registry namespace, install [Docker](https://www.docker.com/community-edition#/download). If you are using Windows 8 or earlier, you can install the [Docker Toolbox](https://www.docker.com/products/docker-toolbox) instead. The Docker CLI is used to build apps into images. The prefix for running commands by using the Docker CLI is `docker`. 63 | --------------------------------------------------------------------------------