Services provide networking between pods.
We create services using config files just as we do with pods and deployments.
We are going to make use of services to setup some communication between all of our different pods or to get access to a pod from outside of our cluster.
Anytime we need communication or networking between our pods or anytime we try to access a pod from outside of the cluster we are allways going to make use of a service
Types of services:
- Cluster IP: Sets up an easy-to-remember URL to access a pod. Only exposes pods in the cluster.
- Node Port: Makes a pod accessible outside of a cluster. Usually only used for dev purposes.
- Load Balancer: Makes a pod accessible from outside of a cluster. This is the right way to expose a pod to the outside world.
- External Name: Redirects an in-cluster request to a CNAME url. This is and advanced corner-case.
NOTE: Only ‘Cluster IP’ and ‘Load Balancer’ will be used on daily basis.
For the following steps you can use https://github.com/luckpp/microservices-demo/tree/master/infra/k8s as reference.
Creating a NodePort Service
- Create the posts-nodeport-srv.yaml:
apiVersion: v1 kind: Service metadata: name: posts-nodeport-srv spec: # will customize how this service behaves type: NodePort selector: app: posts ports: - name: posts # this is only for logging purposes protocol: TCP port: 4000 # this is the port of the NodeService targetPort: 4000 # this is the port inside the docker container
- apply the config file to the cluster:
$ kubectl apply -f posts-nodeport-srv.yaml
- list all services running inside the cluster:
$ kubectl get services
- on the PORT(S) column the 4000:3xxxx is listed
- the 3xxxx is the port randomly assigned that we will use to get access to that service from outside of the cluster
- alternative to the previous command is:
$ kubectl describe service posts-nodeport-srv
- and for access from outside of the cluster use the NodePort
Access the service with this address: minikube_ip:service_port
- get the minikue IP address by running:
$ minikube ip
- get the service port obtained with:
$ kubectl get services
$ kubectl describe service posts-nodeport-srv
- NOTE: on Mac/Windows the address is: localhost:service_port
Creating a ClusterIP Service
Creating a ClusterIP Service
NOTE:
- the deployment and service configuration can be co-located in the same yaml file
- in order to create multiple objects inside an yaml file we separate them with —
apiVersion: v1 kind: Service metadata: name: event-bus-srv spec: selector: app: event-bus # type: ClusterIP # this is optional ports: - name: event-bus protocol: TCP port: 4005 targetPort: 4005
Making pods communicate
- identify the service that you want to communicate to
$ kubectl get services
# for example we have identified the service ID ‘event-bus-srv’ - in JS code make calls using that service ID
await axios.post('http://event-bus-srv:4005/events', {…});
- get the minikube ip
$ minikube ip
- get the ‘posts-srv’ service randomly assigned ip (starting with 3xxxx)
$ k get services
- compose the POST request using Postman
Applyng multiple config file: $ kubectl apply -f .
Create a LoadBalancer Service
Create a LoadBalancer Service.
The goal of the LoadBalancer Service is to make sure that we have a single point of entry in our entire cluster.
Terminology arround LoadBalancer:
- LoadBalancer Service: Tells Kubernetes to reach out to its provider and provision a load balancer. Gets traffic into a single pod.
- Ingress or Ingress Controller: A pod with a set of routing rules to distribute traffic to other services.
NOTE:
- the project ingress-nginx will create a Load Balancer Service and an Ingress Controller for us (https://github.com/kubernetes/ingress-nginx)
- there is another project that does the same thing and has the name kubernetes-ingress
Steps:
- as documentation I used https://kubernetes.io/docs/tasks/access-application-cluster/ingress-minikube/
- optionally one can check https://kubernetes.github.io/ingress-nginx/deploy/
- after following the steps from the link above the Ingress Controller has been created
- next one should teach the ingress controller a set of routing rules (through config files)
The configuration file for the Ingress Controller ingress-srv.yaml:
apiVersion: networking.k8s.io/v1beta1 # extensions/v1beta1 kind: Ingress metadata: name: ingress-srv spec: rules: - host: posts.com http: paths: - path: /posts backend: serviceName: posts-srv servicePort: 4000
In order to apply the file:$ kubectl apply -f ingress-srv.yaml
Check that the Ingress has been created:$ kubectl get ingress
In order to access the posts service:
- tweak the /etc/hosts file in order to map the minikube IP to the posts.com domain if you are testing locally
$ minikube ip
# copy this IP$ sudo nano /etc/hosts
- add the following line at the end of the file: 192.168.99.102 posts.com
- CTRL+o CTRL+x
- do a HTTP GET request to the posts API
$ curl http://posts.com/posts