2019-02-04 CNCJ Meetup: The Kubernetes Playground
- Preparation
- Reference
- Lab 1: Getting to know the environment [5 minutes]
- Lab 2: Deploy your BookInfo application [10 minutes]
- Lab 3: Cluster metrics with Prometheus [5 minutes]
- Lab 4: Trace with Jaeger [5 minutes]
- Lab 5: Deploy BookInfo using Helm [30 minutes]
- Lab 6: Assign a hostname to BookInfo [5 minutes]
- Lab 7: Clean up [5 minutes]
The Kubernetes cluster should be created prior to this workshop with the following addons:
- Kubernetes Dashboard
- Prometheus + Grafana (through
prometheus-operator
) - Istio (with
cert-manager
enaabled) + Jaeger
You should have the following installed on your local machine:
bash
- Any shell/terminal that has
bash
, since there will be some bash scripts that need to be run.
- Any shell/terminal that has
kubectl
- Ensure that
kubectl
is in the $PATH ofbash
.
- Ensure that
helm
- username - The user that is created for you by the organiser of this workshop. This should be your first name appended with the first letter of your last name.
- your_namespace - The namespace that is created for you by the organiser for this workshop. This should be the same as your username.
Since everyone will be working in the same Kubernetes cluster, it is important that everyone works in their own namespace without interfering others.
Your namespace should have been created for you by the organiser prior the workshop.
The interaction with the cluster is done through kubectl
. This is the
Kubernetes client installed on your local machine that interacts with the Kubernetes cluster.
-
A bash script (
enroll.sh
) is provided in the repo root directory. Execute the provided script to enroll as a service account. ReplaceUSERNAME=your_namespace
(line 7) with the username that is given to you. E.g.USERNAME=harryl
. Run the following in a bash terminal.chmod +x enroll.sh ./enroll.sh <token>
- Your namespace/user name and <token> will be emailed to the email address that you entered in the Workshop Register.
-
Run
kubectl get all --namespace your_namespace
to verify that you can access the cluster. Don't worry, it's working if you see No resources found.
The Kubernetes dashboard is a powerful tool which provides a GUI for you to visualise the internal workings of the Kubernetes cluster.
-
Run
kubectl config view
. -
Copy the token.
-
Run
kubectl proxy
, leave it running and do not close the terminal. -
Open your web browser and navigate to: http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:https/proxy/.
-
Log in using the
token
method (paste the token that you retrieved from step 2). -
Now you can view resources in your
namespace
.
Disclaimer: The code for this lab is taken from Istio's BookInfo Application Tutorial.
We have a BookInfo application that is composed of 4 microservices. They have been "dockerised" and the docker images are stored on Docker Hub (public repository). Let's see how we can deploy these 4 services into our Kubernetes cluster.
-
Replace all
namespace
in the Deployment and Service resources inbookinfo.yml
with your_namespace.# replace namespace: your_namespace with the namespace that is assigned to you. # e.g. namespace: harryl
-
Deploy the 4 services of BookInfo into your namespace
kubectl apply -f bookinfo.yml
We have just deployed our BookInfo application (as 4 separate services) into our cluster. Let's see how they are doing.
-
From the Kubernetes dashboard, navigate to your namespace.
-
Verify that the 4 services associated with the 6 pods are created correctly. They should be named, productpage-v1, details-v1, reviews-v1, reviews-v2, reviews-v3 and ratings-v1.
We can access the logs of the pods from the Kubernetes dashboard.
- Select
pods
and view the logs of your pods (try and find where they are). Productpage does not log to stdout, so you won't be able to view any logs for this pod.
Now our services and pods are running fine. Let's access Productpage and see it in action.
-
Access the Productpage service (ensure that the proxy is still running)
http://localhost:8001/api/v1/namespaces/your_namespace/services/productpage:9080/proxy/productpage
- Replace your_namespace
-
Voila, You should be able to see your Productpage with a details section (Details service) and reviews section (Reviews service).
So we realised that the information displayed in the details section is missing a Publisher field. We quickly made the changes to the Details service, build the docker image and pushed. Now let's see how we can swap out the old version.
-
Replace the container image with version 2 on line 47 of
bookinfo.yml
spec: containers: - name: details image: istio/examples-bookinfo-details-v2:1.8.0
-
Deploy the new version of Details
kubectl apply -f bookinfo.yml
-
From the Kubernetes Dashboard, verify that the image for
details-v1
pod is updated. -
Access the Productpage service to see the new changes for the Details service. You should now see two new fields in the details section.
You can route traffic between multiple pods by attaching them to a single service.
-
You will notice that under Reviews service in
bookinfo.yml
, there are two deployments (v2 and v3) that are commented out. Remove the comments and apply the manifest file again.# After you have uncommented the two reviews deployments kubectl apply -f bookinfo.yml
-
Refresh Productpage in your web browser. You will see that each time you refresh, the reviews section is different (no stars, black stars and red stars.)
Now your application is deployed. Let's see how it's doing from the cluster's perspective.
The Kubernetes cluster natively exposes metrics in the Prometheus format. We can view the metrics through Grafana.
-
Accessing Grafana through port forwarding.
kubectl -n monitoring port-forward svc/grafana 3000
-
Login with username:
user
password:user
. -
Click Home on the top left. You should see a list of dashboards. You can now go and explore what each dashboard does.
Prometheus can also be integrated with your application to expose any type of metrics you want. This requires you to instrument your code (this part does not come for free). The source code for the 4 microservices can be found at Bookinfo Sample. You can look at how you can instrument the code at Prometheus Client Libraries.
Let's take a look at how a request to Productpage triggers a chain of events to the other 3 services. We can do this through tracing with Jaeger (integrated with Istio).
-
Istio needs to be enabled for your namespace. Please ask any member of the workshop committee to enable Istio for your namespace.
-
After you have confirmation that Istio has been enabled for your namespace, head over to your Kubernetes Dashboard and delete all the pods (don't delete the deployments).
-
Your pods (the 4 Bookinfo services) will start up again. This time, you will see that every pod now has an
istio-proxy
sidecar container. This is the container that will monitor traffic to and from your pod.
-
Use port-forwarding to access Jaeger:
kubectl -n istio-system port-forward svc/jaeger-query 16686
-
Now you can access the Jaeger UI from your web browser: http://localhost:16686
-
Note that you are viewing the requests coming in to the service mesh of the entire cluster, so you will see traffic to the other namespaces, not just yours.
Let's install the BookInfo services using Helm charts. The helm charts for the
services have already been created for you in the helm-charts
directory.
-
Delete the deployments and services that we created before through a manifest.
kubectl delete -f bookinfo.yml
-
Verify that all deployments and services are deleted by making use of the Kubernetes Dashboard.
For more info on this approach: Deploy Tiller in a namespace, restricted to deploying resources only in that namespace
-
Simply run:
helm init --service-account tiller --tiller-namespace your_namespace
-
Ensure tiller is running:
helm --tiller-namespace your_namespace list
-
Run the commands below from the
helm-charts
directory.helm --tiller-namespace your_namespace install \ --namespace your_namespace \ --name productpage \ --set service.enabled=true \ productpage --debug
-
Now do the same for the other 3 services.
helm --tiller-namespace your_namespace install \ --namespace your_namespace \ --name reviews \ --set service.enabled=true \ reviews --debug
helm --tiller-namespace your_namespace install \ --namespace your_namespace \ --name details \ --set service.enabled=true \ details --debug
helm --tiller-namespace your_namespace install \ --namespace your_namespace \ --name ratings \ --set service.enabled=true \ ratings --debug
-
View the status of all 4 helm releases
helm --tiller-namespace your_namespace list
-
Verify that your Productpage services is running from the Kubernetes Dashboard
You will notice that we only have reviews-v1 deployed as a helm release. We have just added a new feature to display ratings as black stars as part of the Reviews service (reviews-v2). Let's upgrade our Reviews service to version 2.
-
We have already pushed a new image with the new feature, let's upgrade our release.
helm --tiller-namespace your_namespace upgrade \ --namespace your_namespace \ --set service.enabled=true \ --set image.repository=istio/examples-bookinfo-reviews-v2 \ reviews reviews --debug
-
Check Productpage to see black stars under the Reviews section.
We realised that no one likes black stars for ratings! We have to revert back to version 1.
-
Have a look at the new revision for Reviews that you have created in 5.4
helm --tiller-namespace your_namespace list
- You should see two revisions for the
reviews
release.
- You should see two revisions for the
-
Rollback to a previous version
helm --tiller-namespace your_namespace rollback \ reviews 1 --debug
Let's try using stars for ratings again. This time, we will use red stars instead of black stars. Let's deploy version 3 with version 1 so that we can do some A/B testing.
-
Install another helm release, but without enabling an extra service since we are using the same service as Reviews version 1.
helm --tiller-namespace your_namespace install \ --namespace your_namespace \ --name reviews-v3 \ --set image.repository=istio/examples-bookinfo-reviews-v3 \ reviews --debug
-
Refresh Productpage a few times to see the Reviews section alternate between version 1 and version 3.
Istio has advanced traffic management which includes Traffic Shifting. This is particularly useful if you want to do canary or A/B testing on your application. After you have completed Lab 6 you can experiment with this.
We can access our BookInfo via kubectl proxy
. But surely this is not how our
users will access our application! Let's create an URL for our BookInfo.
Istio has its own gateway and virtualservice custom resources that we can use to create a public facing endpoint. Configuring ingress using an Istio Gateway
A Gateway has been created for you in the default
namespace. For the sake of
simplicity and ease of management, you will deploy your own virtualservice to
the default
namespace as well.
The Gateway is integrated with cert-manager which provides a wild card certificate for our domain (*.library.yun.technology) via LetsEncrypt.
Let's install a Virtual Service for BookInfo.
-
Replace all occurrence of your_namespace in
bookinfo-virtualservice.yml
with your namespace. -
Apply the manifest and wait about 3 minutes.
kubectl apply -f bookinfo-virtualservice.yml
-
Access your Productpage service at
https://your_namespace.library.yun.technology/productpage
You can explore the different routing methods/strategies that virtualservice enables you to do with your application such as Traffic Shifting.
Delete all resources that you have created in your namespace.
helm --tiller-namespace your_namespace delete productpage
helm --tiller-namespace your_namespace delete reviews
helm --tiller-namespace your_namespace delete reviews-v3
helm --tiller-namespace your_namespace delete details
helm --tiller-namespace your_namespace delete ratings