This project is to explore a kubernetes + envoy/istio integration. In the first part we will explore the basic infrastructure of a kubernetes cluster.
- docker must be installed
https://docs.docker.com/ - virtual box must be installed (for minikube)
https://www.virtualbox.org/wiki/Downloads - minikube must be installed
brew cask install minikube or https://kubernetes.io/docs/tasks/tools/install-minikube/ - kubectl must be installed
brew install kubernetes-cli or https://kubernetes.io/docs/tasks/tools/install-kubectl/
this will create a vm running kubernetes master
minikube start
// use this to view the vm ip address (ssh username: docker, password: tcuser)
kubectl cluster-info (or "minikube ip")
We will write several simple go server programs to simulate our micro-service.
In ./siplehttpserver we created an go server will reply "Hello {/path}, I'm {IP address}".
(You don't have to build docker image here, you can just reuse the image built in my hub stardust1991)
Or you can just run "cd ./docker && ./buildSimpleServer.sh"
CGO_ENABLED=0 GOOS=linux go build -a -o main simplehttpserver
If you encountered "golang.org/x/sys/unix not found", run "go get golang.org/x/sys/unix"
// tag and push the image to docker hub
docker build -t stardust1991/hellomain -f SimpleDockerfile .
docker push stardust1991/hellomain
rm main
From here we will need some kubernetes concepts
Reading Prerequisites:
- Understand Pods in Kubernetes
https://kubernetes.io/docs/concepts/workloads/pods/pod-overview/ - Understand Controllers (ReplicaSet, Deployment in our case)
https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/
https://kubernetes.io/docs/concepts/workloads/controllers/deployment/ - Understand Services
https://kubernetes.io/docs/concepts/services-networking/service/
In ./kube directory, we've created several kubernetes configuration files.
We can use simple-deployment.yaml to create a deployment, this will bring up 3 hello server instances.
kubectl create -f simple-deployment --save-config
run this command to get information about Pods, Deployments...
"kubectl get all -o wide"
After deployment finished, let's add our server instances behind an abstraction called Service.
kubectl create -f simple-service --save-config
The service will be bound to Node port 30001 in the configuration. So we can access our go server endpoint in several ways:
- use the ip address get from kubectl cluster-info, say 192.168.99.101, run "curl 192.168.99.101:30001/anything"
- ssh into 192.168.99.101 (use docker:tcuser), get helloservice cluster-ip address from kubectl get all -o wide, say 10.107.114.97, run curl 10.107.114.97:7777/anything
- select any of your pod (or helloservice), say "hellodeployment-7475db8bd7-2kb46", run kubectl port-forward hellodeployment-7475db8bd7-2kb46 8888:8080
(if it's service then run kubectl port-forward service/helloservice 8888:7777) and in another terminal run curl 127.0.0.1:8888/anything
We will observe the requests are load balanced from the IP address in server's response.
Let's explore how the services communication happens in kubernetes . For this purpose we will host another go grpc server, which has an API to count bytes in string.
Implementation is under ./simplegrpcserver.
Our previous simple http server will call the grpc server, just to count the byte of the url path
In ./docker folder, we build and push the grpc server image similarly.
we will deploy the counter service the same way (here we name it as backenddeployment)
kubectl create -f backend-deployment --save-config (under folder ./kube)
and create service for the counter server:
kubectl create -f backend-service --save-config
in the simple service program, the server will get the backendservice address from the environment variable:
BACKENDSERVICE_SERVICE_HOST and BACKENDSERVICE_SERVICE_PORT_GRPC_PORT
To view the environment variables you can use this command:
kubectl exec yourpod -- printenv
//since our go server image is scratch (empty) image you can deploy pod with other images, eg.:
kubectl create -f ./kube/pod-with-env
kubectl exec monolith -- printenv
and kubernetes will do the routing to the counter server.
when we query the simple server, the response will be:
➜ kube git:(master) ✗ curl 192.168.99.101:30001/myname
Hello myname, I'm 172.17.0.9. Counter server says: 6
Useful commands: ./docker/buildSimpleServer.sh && kubectl apply -f ./kube/simple-deployment