Docker & Kubernetes : Istio (service mesh) sidecar proxy on GCP Kubernetes - 2020
In this post, we'll add Istio support to services by deploying a special sidecar proxy to each of our application's Pods.
The sidecar proxy for each application has all the non-business logic. So, it lets developers can focus on application/service itself not worring about security or monitoring etc.
Istio is a Service Mesh that manages communications between microservices.
Picture source: Using Kubernetes, Spinnaker and Istio to Manage a Multi-cloud Environment
The proxy intercepts all network communication between microservices and is configured and managed using Istio's control plane functionality. Sometimes, it is called a Service-Side Load Balancer, and it allows us to skip extra hops that required when we use other types of LB.
Picture source: Istio : Integrating Virtual Machines
Picture source: Introduction to Service Management with Istio Service Mesh (Cloud Next '18) where Pilot: Control plane to configure and push service communication policies. Mixer: Policy enforcement with a flexible plugin model for providers for a policy. Citadel: Service-to-Service auth[n,z] using mutual TLS, with built-in identity and credential management.
We'll learn how to install and configure Istio on Kubernetes Engine, deploy an Istio-enabled multi-service application, and dynamically change request routing.
Istio is an open source framework for connecting, securing, and managing microservices. It lets us create a network of deployed services with load balancing, service-to-service authentication, monitoring without requiring any changes in service code.
Google Cloud Shell is loaded with development tools and it offers a persistent 5GB home directory and runs on the Google Cloud. Google Cloud Shell provides command-line access to our GCP resources. We can activate the shell: in GCP console, on the top right toolbar, click the Open Cloud Shell button:
In the dialog box that opens, click "START CLOUD SHELL".
gcloud is the command-line tool for Google Cloud Platform. It comes pre-installed on Cloud Shell and supports tab-completion.
Set our zone:
$ gcloud config set compute/zone us-central1-f Updated property [compute/zone].
Run the following command to create a Kubernetes cluster:
$ gcloud container clusters create my-istio --num-nodes 4 ... kubeconfig entry generated for my-istio. NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS my-istio us-central1-f 1.11.7-gke.4 35.238.72.145 n1-standard-1 1.11.7-gke.4 4 RUNNING
Now, grant admin permissions in the cluster to the current gcloud user. We need these permissions to create the necessary cluster permissions to install Istio:
$ kubectl create clusterrolebinding cluster-admin-binding \ --clusterrole=cluster-admin \ --user=$(gcloud config get-value core/account) ... clusterrolebinding.rbac.authorization.k8s.io "cluster-admin-binding" created
Now, install Istio. Istio's control plane (istiod) is installed in its own Kubernetes istio-system namespace, and can manage microservices from all other namespaces. The installation includes Istio core components, tools, and samples.
The Istio release page offers download artifacts for several OSs. In this post, we'll use this convenient command in Cloud Shell to download and extract the 0.5.1 release automatically:
$ curl -L https://git.io/getLatestIstio | ISTIO_VERSION=0.5.1 sh - ... Downloaded into istio-0.5.1: bin install istio.VERSION LICENSE README.md samples tools ...
The installation directory contains the following files which we'll use:
- Installation .yaml files for Kubernetes in install/kubernetes
- Sample applications in samples/
- The istioctl client binary in the bin/ directory. Similar to kubectl for Kubernetes, this is the tool used to manage Istio, including network routing and security policies.
- The istio.VERSION configuration file
Let's add the istioctl client to our PATH:
$ cd ./istio-* $ export PATH=$PWD/bin:$PATH
Next, we'll install Istio's core components and the optional Istio Auth components, which enable mutual TLS authentication between the sidecars:
$ kubectl apply -f install/kubernetes/istio-auth.yaml namespace "istio-system" created clusterrolebinding.rbac.authorization.k8s.io "istio-pilot-admin-role-binding-istio-system" created clusterrolebinding.rbac.authorization.k8s.io "istio-sidecar-injector-admin-role-binding-istio-system" created clusterrolebinding.rbac.authorization.k8s.io "istio-ca-role-binding-istio-system" created clusterrolebinding.rbac.authorization.k8s.io "istio-ingress-admin-role-binding-istio-system" created clusterrolebinding.rbac.authorization.k8s.io "istio-sidecar-role-binding-istio-system" created clusterrolebinding.rbac.authorization.k8s.io "istio-mixer-admin-role-binding-istio-system" created configmap "istio-mixer" created service "istio-mixer" created serviceaccount "istio-mixer-service-account" created deployment.extensions "istio-mixer" created customresourcedefinition.apiextensions.k8s.io "rules.config.istio.io" created customresourcedefinition.apiextensions.k8s.io "attributemanifests.config.istio.io" created customresourcedefinition.apiextensions.k8s.io "circonuses.config.istio.io" created customresourcedefinition.apiextensions.k8s.io "deniers.config.istio.io" created customresourcedefinition.apiextensions.k8s.io "fluentds.config.istio.io" created customresourcedefinition.apiextensions.k8s.io "kubernetesenvs.config.istio.io" created customresourcedefinition.apiextensions.k8s.io "listcheckers.config.istio.io" created customresourcedefinition.apiextensions.k8s.io "memquotas.config.istio.io" created customresourcedefinition.apiextensions.k8s.io "noops.config.istio.io" created customresourcedefinition.apiextensions.k8s.io "opas.config.istio.io" created customresourcedefinition.apiextensions.k8s.io "prometheuses.config.istio.io" created customresourcedefinition.apiextensions.k8s.io "rbacs.config.istio.io" created customresourcedefinition.apiextensions.k8s.io "servicecontrols.config.istio.io" created customresourcedefinition.apiextensions.k8s.io "stackdrivers.config.istio.io" created customresourcedefinition.apiextensions.k8s.io "statsds.config.istio.io" created customresourcedefinition.apiextensions.k8s.io "stdios.config.istio.io" created customresourcedefinition.apiextensions.k8s.io "apikeies.config.istio.io" created customresourcedefinition.apiextensions.k8s.io "authorizations.config.istio.io" created customresourcedefinition.apiextensions.k8s.io "checknothings.config.istio.io" created customresourcedefinition.apiextensions.k8s.io "kuberneteses.config.istio.io" created customresourcedefinition.apiextensions.k8s.io "listentries.config.istio.io" created customresourcedefinition.apiextensions.k8s.io "logentries.config.istio.io" created customresourcedefinition.apiextensions.k8s.io "metrics.config.istio.io" created customresourcedefinition.apiextensions.k8s.io "quotas.config.istio.io" created customresourcedefinition.apiextensions.k8s.io "reportnothings.config.istio.io" created customresourcedefinition.apiextensions.k8s.io "servicecontrolreports.config.istio.io" created customresourcedefinition.apiextensions.k8s.io "tracespans.config.istio.io" created customresourcedefinition.apiextensions.k8s.io "serviceroles.config.istio.io" created customresourcedefinition.apiextensions.k8s.io "servicerolebindings.config.istio.io" created configmap "istio" created customresourcedefinition.apiextensions.k8s.io "destinationpolicies.config.istio.io" created customresourcedefinition.apiextensions.k8s.io "egressrules.config.istio.io" created customresourcedefinition.apiextensions.k8s.io "routerules.config.istio.io" created service "istio-pilot" created serviceaccount "istio-pilot-service-account" created deployment.extensions "istio-pilot" created service "istio-ingress" created serviceaccount "istio-ingress-service-account" created deployment.extensions "istio-ingress" created serviceaccount "istio-ca-service-account" created deployment.extensions "istio-ca" created ...
As we can see from the output, it creates the istio-system namespace along with the required RBAC permissions, and deploys the four primary Istio control plane components:
- Pilot: Handles configuration and programming of the proxy sidecars.
- Mixer: Handles policy decisions for your traffic and gathers telemetry.
- Ingress: Handles incoming requests from outside your cluster.
- CA: the Certificate Authority.
Just to make sure, let's check if the following Kubernetes services are deployed: istio-pilot, istio-mixer, and istio-ingress by getting the services in istio-system namespace:
$ kubectl get svc -n istio-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE istio-ingress LoadBalancer 10.23.254.98 35.222.16.117 80:30497/TCP,443:31582/TCP 6m istio-mixer ClusterIP 10.23.254.230 <none> 9091/TCP,15004/TCP,9093/TCP,9094/TCP,9102/TCP,9125/UDP,42422/TCP 7m istio-pilot ClusterIP 10.23.241.41 <none> 15003/TCP,8080/TCP,9093/TCP,443/TCP 6m
Also, we need to make sure that the corresponding Kubernetes pods are deployed and all containers are up by running:
$ kubectl get pods -n istio-system NAME READY STATUS RESTARTS AGE istio-ca-7c7894c898-dhbmd 1/1 Running 0 58s istio-ingress-68868ccb77-6rvtr 1/1 Running 0 59s istio-mixer-6cdf78c8f5-qvchl 3/3 Running 0 1m istio-pilot-f464f5cfb-xkxrt 2/2 Running 0 59s 6m
Now that Istio is installed and verified, we can deploy one of the sample applications provided with the installation - BookInfo.
This is a simple mock bookstore application made up of four microservices - all managed using Istio. Each microservice is written in a different language, to demonstrate how we can use Istio in a multi-language environment, without any changes to code.
The microservices are:
- productpage: calls the details and reviews microservices to populate the page.
- details: contains book information.
- reviews: contains book reviews. It also calls the ratings microservice. There are 3 versions of the reviews microservice:
- Reviews v1 doesn't call the ratings service.
- Reviews v2 calls the ratings service, and displays each rating as 1 - 5 black stars.
- Reviews v3 calls the ratings service, and displays each rating as 1 - 5 red stars.
- ratings: contains book ranking information that accompanies a book review.
We find the source code and all the other files used in this example in our Istio samples/bookinfo directory.
Let's have a look at the samples/bookinfo/kube/bookinfo.yaml which describes the bookInfo application:
apiVersion: v1 kind: Service metadata: name: details labels: app: details spec: ports: - port: 9080 name: http selector: app: details --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: details-v1 spec: replicas: 1 template: metadata: labels: app: details version: v1 spec: containers: - name: details image: istio/examples-bookinfo-details-v1:1.5.0 imagePullPolicy: IfNotPresent ports: - containerPort: 9080 --- ################################################################################################## # Ratings service ################################################################################################## apiVersion: v1 kind: Service metadata: name: ratings labels: app: ratings spec: ports: - port: 9080 name: http selector: app: ratings --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: ratings-v1 spec: replicas: 1 template: metadata: labels: app: ratings version: v1 spec: containers: - name: ratings image: istio/examples-bookinfo-ratings-v1:1.5.0 imagePullPolicy: IfNotPresent ports: - containerPort: 9080 --- ################################################################################################## # Reviews service ################################################################################################## apiVersion: v1 kind: Service metadata: name: reviews labels: app: reviews spec: ports: - port: 9080 name: http selector: app: reviews --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: reviews-v1 spec: replicas: 1 template: metadata: labels: app: reviews version: v1 spec: containers: - name: reviews image: istio/examples-bookinfo-reviews-v1:1.5.0 imagePullPolicy: IfNotPresent ports: - containerPort: 9080 --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: reviews-v2 spec: replicas: 1 template: metadata: labels: app: reviews version: v2 spec: containers: - name: reviews image: istio/examples-bookinfo-reviews-v2:1.5.0 imagePullPolicy: IfNotPresent ports: - containerPort: 9080 --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: reviews-v3 spec: replicas: 1 template: metadata: labels: app: reviews version: v3 spec: containers: - name: reviews image: istio/examples-bookinfo-reviews-v3:1.5.0 imagePullPolicy: IfNotPresent ports: - containerPort: 9080 --- ################################################################################################## # Productpage services ################################################################################################## apiVersion: v1 kind: Service metadata: name: productpage labels: app: productpage spec: ports: - port: 9080 name: http selector: app: productpage --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: productpage-v1 spec: replicas: 1 template: metadata: labels: app: productpage version: v1 spec: containers: - name: productpage image: istio/examples-bookinfo-productpage-v1:1.5.0 imagePullPolicy: IfNotPresent ports: - containerPort: 9080 --- ########################################################################### # Ingress resource (gateway) ########################################################################## apiVersion: extensions/v1beta1 kind: Ingress metadata: name: gateway annotations: kubernetes.io/ingress.class: "istio" spec: rules: - http: paths: - path: /productpage backend: serviceName: productpage servicePort: 9080 - path: /login backend: serviceName: productpage servicePort: 9080 - path: /logout backend: serviceName: productpage servicePort: 9080 - path: /api/v1/products.* backend: serviceName: productpage servicePort: 9080
Note that there are Deployments, Services, and an Ingress to deploy the BookInfo application, however, there is nothing Istio-specific here at all. If we were to deploy the application as it is, it would work, but it would not have any Istio functionality.
We will use the following Istio command to inject the proxy sidecar along with each Pod that is deployed. istioctl kube-inject
takes a Kubernetes YAML file as input, and outputs a version of that YAML which includes the Istio proxy server:
$ istioctl kube-inject -f samples/bookinfo/kube/bookinfo.yaml
Look at one of the Deployments. Now it contains a second container, the Istio sidecar, along with all the configuration necessary.
We can take the output from istioctl kube-inject
and feed it directly to kubectl
to create the objects with their sidecars:
$ kubectl apply -f <(istioctl kube-inject -f samples/bookinfo/kube/bookinfo.yaml) service "details" created deployment.extensions "details-v1" created service "ratings" created deployment.extensions "ratings-v1" created service "reviews" created deployment.extensions "reviews-v1" created deployment.extensions "reviews-v2" created deployment.extensions "reviews-v3" created service "productpage" created deployment.extensions "productpage-v1" created ingress.extensions "gateway" created
Let's confirm that the application has been deployed correctly by running the following commands, and when all the pods have been created, we should see five services and six pods:
$ kubectl get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE details ClusterIP 10.23.254.193 <none> 9080/TCP 2m kubernetes ClusterIP 10.23.240.1 <none> 443/TCP 30m productpage ClusterIP 10.23.241.147 <none> 9080/TCP 2m ratings ClusterIP 10.23.246.53 <none> 9080/TCP 2m reviews ClusterIP 10.23.247.61 <none> 9080/TCP 2m $ kubectl get pods NAME READY STATUS RESTARTS AGE details-v1-65dfd4dd95-z84nm 2/2 Running 0 3m productpage-v1-846f956479-wtzl4 2/2 Running 0 3m ratings-v1-59486f4787-7wms8 2/2 Running 0 3m reviews-v1-686c54676c-2rxtk 2/2 Running 0 3m reviews-v2-84dbbd6dbc-ln4n2 2/2 Running 0 3m reviews-v3-7b8bb94fff-kwfxq 2/2 Running 0 3m
Let's get the ingress IP and port:
$ kubectl get ingress NAME HOSTS ADDRESS PORTS AGE gateway * 35.184.41.14 80 3m
Copy and paste the ingress IP into the our gateway IP environment variable:
$ export GATEWAY_URL=35.184.41.14
Once we have the address and port, check that the BookInfo app is running with curl:
$ curl -o /dev/null -s -w "%{http_code}\n" http://${GATEWAY_URL}/productpage 200
Refresh the page several times. Notice how we see three different versions of reviews! If we refer back to the diagram, we will see there are three different book review services which are being called in a round-robin style - no stars, black stars, and red stars. This is normal Kubernetes balancing behavior.
Istio can also be used to control which users are routed to which version of the services.
When we were accessing the application, we saw the three versions of reviews. This is because without an explicit default version set, Istio will route requests to all available versions of a service, in a round-robin fashion.
Route rules control how requests are routed within an Istio service mesh. Requests can be routed based on the source and destination, HTTP header fields, and weights associated with individual service versions.
Now we'll use the istioctl
command line tool to control routing.
Static Routing
Let's add a route rule that says all traffic should go to v1 of the reviews service.
First, confirm that there are no route rules installed:
$ istioctl get routerules No resources found.
This example of a route rule will route all traffic for a service named reviews to Pods running v1 of that service, as identified by Kubernetes labels:
apiVersion: config.istio.io/v1alpha2 kind: RouteRule metadata: name: reviews-default spec: destination: name: reviews precedence: 1 route: - labels: version: v1
BookInfo includes a sample with rules for all available services. Install it by running:
$ istioctl create -f samples/bookinfo/kube/route-rule-all-v1.yaml Created config route-rule/default/productpage-default at revision 4534 Created config route-rule/default/reviews-default at revision 4535 Created config route-rule/default/ratings-default at revision 4536 Created config route-rule/default/details-default at revision 4537
Confirm that four rules were created:
$ istioctl get routerules NAME KIND NAMESPACE details-default RouteRule.v1alpha2.config.istio.io default productpage-default RouteRule.v1alpha2.config.istio.io default ratings-default RouteRule.v1alpha2.config.istio.io default reviews-default RouteRule.v1alpha2.config.istio.io default
Go back to the BookInfo application (http://$GATEWAY_URL/productpage) in the browser. Refresh a few times. Do we see any stars? We should see the book review with no rating stars because the service reviews:v1 does not have any stars.
Dynamic Routing
As the mesh operates at Layer 7, we can use HTTP attributes (paths or cookies) to decide on how to route a request.
In this example, a rule which routes certain users (in this case, Jason) to a service (v2) based on a cookie, looks like this:
apiVersion: config.istio.io/v1alpha2 kind: RouteRule metadata: name: reviews-test-v2 spec: destination: name: reviews precedence: 2 match: request: headers: cookie: regex: "^(.*?;)?(user=jason)(;.*)?$" route: - labels: version: v2
Create the rule from the sample file:
$ istioctl create -f samples/bookinfo/kube/route-rule-reviews-test-v2.yaml Created config route-rule/default/reviews-test-v2 at revision 5227
List the rules and make sure it's there:
$ istioctl get routerule NAME KIND NAMESPACE details-default RouteRule.v1alpha2.config.istio.io default productpage-default RouteRule.v1alpha2.config.istio.io default ratings-default RouteRule.v1alpha2.config.istio.io default reviews-default RouteRule.v1alpha2.config.istio.io default reviews-test-v2 RouteRule.v1alpha2.config.istio.io default
Use -o yaml to see the full output:
$ istioctl get routerule reviews-test-v2 -o yaml kind: RouteRule metadata: creationTimestamp: null name: reviews-test-v2 namespace: default resourceVersion: "5227" spec: destination: name: reviews match: request: headers: cookie: regex: ^(.*?;)?(user=jason)(;.*)?$ precedence: 2 route: - labels: version: v2
Now we have routed requests from the user "jason" to use the reviews:v2 service.
Test how the page behavior changes with this new rule.
Log in as user "jason" on the product page web page by clicking the Sign in button at the top of the screen, typing jason as the user name - we don't need a password - then clicking Sign in.
Refresh the browser. We should now see black ratings stars next to each review.
If we try logging in as any other user (log out as Jason and sign in as Kylie), or don't log in at all, we will continue to see reviews: v1.
Run these commands to remove the routing rules:
$ istioctl delete -f samples/bookinfo/kube/route-rule-all-v1.yaml Deleted config: route-rule/default/productpage-default Deleted config: route-rule/default/reviews-default Deleted config: route-rule/default/ratings-default Deleted config: route-rule/default/details-default $ istioctl delete -f samples/bookinfo/kube/route-rule-reviews-test-v2.yaml Deleted config: route-rule/default/reviews-test-v2
We can go back to the tab with the web app to see that when we refresh the page, we're back to cycling through the 3 types of Reviews available:
Docker & K8s
- Docker install on Amazon Linux AMI
- Docker install on EC2 Ubuntu 14.04
- Docker container vs Virtual Machine
- Docker install on Ubuntu 14.04
- Docker Hello World Application
- Nginx image - share/copy files, Dockerfile
- Working with Docker images : brief introduction
- Docker image and container via docker commands (search, pull, run, ps, restart, attach, and rm)
- More on docker run command (docker run -it, docker run --rm, etc.)
- Docker Networks - Bridge Driver Network
- Docker Persistent Storage
- File sharing between host and container (docker run -d -p -v)
- Linking containers and volume for datastore
- Dockerfile - Build Docker images automatically I - FROM, MAINTAINER, and build context
- Dockerfile - Build Docker images automatically II - revisiting FROM, MAINTAINER, build context, and caching
- Dockerfile - Build Docker images automatically III - RUN
- Dockerfile - Build Docker images automatically IV - CMD
- Dockerfile - Build Docker images automatically V - WORKDIR, ENV, ADD, and ENTRYPOINT
- Docker - Apache Tomcat
- Docker - NodeJS
- Docker - NodeJS with hostname
- Docker Compose - NodeJS with MongoDB
- Docker - Prometheus and Grafana with Docker-compose
- Docker - StatsD/Graphite/Grafana
- Docker - Deploying a Java EE JBoss/WildFly Application on AWS Elastic Beanstalk Using Docker Containers
- Docker : NodeJS with GCP Kubernetes Engine
- Docker : Jenkins Multibranch Pipeline with Jenkinsfile and Github
- Docker : Jenkins Master and Slave
- Docker - ELK : ElasticSearch, Logstash, and Kibana
- Docker - ELK 7.6 : Elasticsearch on Centos 7
- Docker - ELK 7.6 : Filebeat on Centos 7
- Docker - ELK 7.6 : Logstash on Centos 7
- Docker - ELK 7.6 : Kibana on Centos 7
- Docker - ELK 7.6 : Elastic Stack with Docker Compose
- Docker - Deploy Elastic Cloud on Kubernetes (ECK) via Elasticsearch operator on minikube
- Docker - Deploy Elastic Stack via Helm on minikube
- Docker Compose - A gentle introduction with WordPress
- Docker Compose - MySQL
- MEAN Stack app on Docker containers : micro services
- MEAN Stack app on Docker containers : micro services via docker-compose
- Docker Compose - Hashicorp's Vault and Consul Part A (install vault, unsealing, static secrets, and policies)
- Docker Compose - Hashicorp's Vault and Consul Part B (EaaS, dynamic secrets, leases, and revocation)
- Docker Compose - Hashicorp's Vault and Consul Part C (Consul)
- Docker Compose with two containers - Flask REST API service container and an Apache server container
- Docker compose : Nginx reverse proxy with multiple containers
- Docker & Kubernetes : Envoy - Getting started
- Docker & Kubernetes : Envoy - Front Proxy
- Docker & Kubernetes : Ambassador - Envoy API Gateway on Kubernetes
- Docker Packer
- Docker Cheat Sheet
- Docker Q & A #1
- Kubernetes Q & A - Part I
- Kubernetes Q & A - Part II
- Docker - Run a React app in a docker
- Docker - Run a React app in a docker II (snapshot app with nginx)
- Docker - NodeJS and MySQL app with React in a docker
- Docker - Step by Step NodeJS and MySQL app with React - I
- Installing LAMP via puppet on Docker
- Docker install via Puppet
- Nginx Docker install via Ansible
- Apache Hadoop CDH 5.8 Install with QuickStarts Docker
- Docker - Deploying Flask app to ECS
- Docker Compose - Deploying WordPress to AWS
- Docker - WordPress Deploy to ECS with Docker-Compose (ECS-CLI EC2 type)
- Docker - WordPress Deploy to ECS with Docker-Compose (ECS-CLI Fargate type)
- Docker - ECS Fargate
- Docker - AWS ECS service discovery with Flask and Redis
- Docker & Kubernetes : minikube
- Docker & Kubernetes 2 : minikube Django with Postgres - persistent volume
- Docker & Kubernetes 3 : minikube Django with Redis and Celery
- Docker & Kubernetes 4 : Django with RDS via AWS Kops
- Docker & Kubernetes : Kops on AWS
- Docker & Kubernetes : Ingress controller on AWS with Kops
- Docker & Kubernetes : HashiCorp's Vault and Consul on minikube
- Docker & Kubernetes : HashiCorp's Vault and Consul - Auto-unseal using Transit Secrets Engine
- Docker & Kubernetes : Persistent Volumes & Persistent Volumes Claims - hostPath and annotations
- Docker & Kubernetes : Persistent Volumes - Dynamic volume provisioning
- Docker & Kubernetes : DaemonSet
- Docker & Kubernetes : Secrets
- Docker & Kubernetes : kubectl command
- Docker & Kubernetes : Assign a Kubernetes Pod to a particular node in a Kubernetes cluster
- Docker & Kubernetes : Configure a Pod to Use a ConfigMap
- AWS : EKS (Elastic Container Service for Kubernetes)
- Docker & Kubernetes : Run a React app in a minikube
- Docker & Kubernetes : Minikube install on AWS EC2
- Docker & Kubernetes : Cassandra with a StatefulSet
- Docker & Kubernetes : Terraform and AWS EKS
- Docker & Kubernetes : Pods and Service definitions
- Docker & Kubernetes : Service IP and the Service Type
- Docker & Kubernetes : Kubernetes DNS with Pods and Services
- Docker & Kubernetes : Headless service and discovering pods
- Docker & Kubernetes : Scaling and Updating application
- Docker & Kubernetes : Horizontal pod autoscaler on minikubes
- Docker & Kubernetes : From a monolithic app to micro services on GCP Kubernetes
- Docker & Kubernetes : Rolling updates
- Docker & Kubernetes : Deployments to GKE (Rolling update, Canary and Blue-green deployments)
- Docker & Kubernetes : Slack Chat Bot with NodeJS on GCP Kubernetes
- Docker & Kubernetes : Continuous Delivery with Jenkins Multibranch Pipeline for Dev, Canary, and Production Environments on GCP Kubernetes
- Docker & Kubernetes : NodePort vs LoadBalancer vs Ingress
- Docker & Kubernetes : MongoDB / MongoExpress on Minikube
- Docker & Kubernetes : Load Testing with Locust on GCP Kubernetes
- Docker & Kubernetes : MongoDB with StatefulSets on GCP Kubernetes Engine
- Docker & Kubernetes : Nginx Ingress Controller on Minikube
- Docker & Kubernetes : Setting up Ingress with NGINX Controller on Minikube (Mac)
- Docker & Kubernetes : Nginx Ingress Controller for Dashboard service on Minikube
- Docker & Kubernetes : Nginx Ingress Controller on GCP Kubernetes
- Docker & Kubernetes : Kubernetes Ingress with AWS ALB Ingress Controller in EKS
- Docker & Kubernetes : Setting up a private cluster on GCP Kubernetes
- Docker & Kubernetes : Kubernetes Namespaces (default, kube-public, kube-system) and switching namespaces (kubens)
- Docker & Kubernetes : StatefulSets on minikube
- Docker & Kubernetes : RBAC
- Docker & Kubernetes Service Account, RBAC, and IAM
- Docker & Kubernetes - Kubernetes Service Account, RBAC, IAM with EKS ALB, Part 1
- Docker & Kubernetes : Helm Chart
- Docker & Kubernetes : My first Helm deploy
- Docker & Kubernetes : Readiness and Liveness Probes
- Docker & Kubernetes : Helm chart repository with Github pages
- Docker & Kubernetes : Deploying WordPress and MariaDB with Ingress to Minikube using Helm Chart
- Docker & Kubernetes : Deploying WordPress and MariaDB to AWS using Helm 2 Chart
- Docker & Kubernetes : Deploying WordPress and MariaDB to AWS using Helm 3 Chart
- Docker & Kubernetes : Helm Chart for Node/Express and MySQL with Ingress
- Docker & Kubernetes : Deploy Prometheus and Grafana using Helm and Prometheus Operator - Monitoring Kubernetes node resources out of the box
- Docker & Kubernetes : Deploy Prometheus and Grafana using kube-prometheus-stack Helm Chart
- Docker & Kubernetes : Istio (service mesh) sidecar proxy on GCP Kubernetes
- Docker & Kubernetes : Istio on EKS
- Docker & Kubernetes : Istio on Minikube with AWS EC2 for Bookinfo Application
- Docker & Kubernetes : Deploying .NET Core app to Kubernetes Engine and configuring its traffic managed by Istio (Part I)
- Docker & Kubernetes : Deploying .NET Core app to Kubernetes Engine and configuring its traffic managed by Istio (Part II - Prometheus, Grafana, pin a service, split traffic, and inject faults)
- Docker & Kubernetes : Helm Package Manager with MySQL on GCP Kubernetes Engine
- Docker & Kubernetes : Deploying Memcached on Kubernetes Engine
- Docker & Kubernetes : EKS Control Plane (API server) Metrics with Prometheus
- Docker & Kubernetes : Spinnaker on EKS with Halyard
- Docker & Kubernetes : Continuous Delivery Pipelines with Spinnaker and Kubernetes Engine
- Docker & Kubernetes : Multi-node Local Kubernetes cluster : Kubeadm-dind (docker-in-docker)
- Docker & Kubernetes : Multi-node Local Kubernetes cluster : Kubeadm-kind (k8s-in-docker)
- Docker & Kubernetes : nodeSelector, nodeAffinity, taints/tolerations, pod affinity and anti-affinity - Assigning Pods to Nodes
- Docker & Kubernetes : Jenkins-X on EKS
- Docker & Kubernetes : ArgoCD App of Apps with Heml on Kubernetes
- Docker & Kubernetes : ArgoCD on Kubernetes cluster
- Docker & Kubernetes : GitOps with ArgoCD for Continuous Delivery to Kubernetes clusters (minikube) - guestbook
Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization