This project is part of a knowledge sharing presentation done in-house with the purpose of displaying how to run a kubernetes cluster (locally) and deploy http/grpc services on it that can receive external traffic. It uses KinD (Kubernetes in Docker) and the nginx-ingress controller(maintained by kubernetes
- Docker installation docs
- kubectl installation guide
- KinD installation guide
- openssl docs
- grpcurl repo to make gRPC requests
Run make create-cluster
Running the command above will execute kind create cluster --config infra/kind_config.yml
which will create a Kubernetes cluster running on docker based on the configuration
located in infra/kind_config.yml file. The Kubernetes cluster will have 1 control-plane
node and 3 worker nodes
Run make apply-deloyment
This will execute kubectl apply -f infra/deployment.yml command which will provision 2
Deployments which creates
2 ReplicaSets that
will bring up 2 Pods each. Those pods consist
of one container running the hashicorp/http-echo:0.2.3 image. This image is a simple
http server that can return the text given by the -text argument. In our example one deployment
will run the containers with -text=foo and the other with -text=bar. Those containers expose the
port 5678 which is the default port of this image
We can spin up a new pod with an apline image by running
kubectl run -i --tty --rm debug --image=alpine --restart=Never -- sh after that we can install
cURL apk add curl
in order to communicate form our debug pod to the 2 deployments we created previously we have
to know their IP addresses to find them we can use kubectl get pods -n default command
to find out the pod names (you should be able to see 2 bar-deployment*, 2 foo-deployment* and the debug pods).
Then we can use the kubectl describe pod {pod-name} command to get some more details about a specific Pod
Pods have the following DNS record
{IP address separated with dashes}.{namespace of the pod}.pod.cluster.local so you could make a
request to the pods by using the DNS record or by using directly the pod's IP address.
Kubernetes has the Service concept as "an abstract way to expose an application running on a set of Pods as a network service."
So we can create a service resource for the deployments we added on the previous set by running
make apply-services command. Run kubectl get services -n default to see the service resources
created. Now there are also DNS records for this service {service-name}.{namespace}.svc.cluster.local.
You can now try to do a nslookup form the debug container nslookup bar-service which should
return something like
Name: bar-service.default.svc.cluster.local
Address: 10.96.193.17
also you can call those services e.g curl bar-service:80, curl foo-service:80 note that we
use the port 80 here because we have configured in the Service resource definition the port mapping
from port 80 to port 5678
Kubernetes has the Ingress resource to manage the external access to the services.
you can run make apply-ingress to create this resource for our services which is configured to
route the traffic {host}/bar to bar-service and {host}/foo to the foo-service. When running
kubectl get ingress command you should see an output similar to this one:
NAME CLASS HOSTS ADDRESS PORTS AGE
http-ingress <none> * 80 10s
An ingress my itself does not do anything, there is a need to have an Ingress controller. For this example we'll use the nginx ingress controller maintained by the Kubernetes.
to apply it run make install-nginx-controller this will create a nginx-controller and wait for it to become ready
you can run kubectl get pods -n ingress-nginx to see the pods created by the command.
After the above command you can access your services by calling the localhost/foo and localhost/bar endpoints
(You can use a browser or cURL for the requests)
Next we'll see how to route traffic to a gRPC service, you can run make apply-grpc
this will create certificates for demo.localhost
You can add a record to your /etc/hosts file
127.0.0.1 demo.localhost
and store the certificate in a secret.
Additionally, it will create a deployment, service and an Ingress.
After that you should be able to call the gRPC service from your host
grpcurl -insecure -d '{"name":"Adjoe"}' demo.localhost:443 helloworld.Greeter/SayHello
Simply run make delete-cluster
running make up will create the cluster and all the resources mentioned above.