How to Create Services in Kubernetes

03.16.2022

Intro

In Kubernetes, a service is a set of pods that provides and IP and/or DNS name for the pods to be accessed. This is the entry point for you app. Say you launch a pod or pods with a python api and a Postgres database, you will need a service to connect that to the outside world.

The Quick Answer

If you are here for the quick answer, here it is. Otherwise, continue to Getting Started.

Save the following to a file service.yaml

apiVersion: v1
kind: Service
metadata:
   name: MyService
spec:
   type: LoadBalancer
   ports:
   - port: 8080 # the port for users to access
   targetPort: 3000 # the port our app runs on internally

Then use the following command.

kubectl apply -f service.yaml

If running locally:

kubectl port-forward MyService 8080:8080

Getting Setup

We will be working with minikube for most tutorials. This creates a local kubernetes cluster that you can develop on.

Feel free to use another kubernetes cluster for these tutorials as well. There will be articles underneath our kubernetes tags on how to run clusters on multiple providers such as AWS, Google Cloud, and Azure.

Once you have minikube installed, start the cluster using the following command.

minikube start

Creating a Service

Before we create a service, we first need an app. Let's start by launching the following deployment which will be a nginx container that serves http requests on port 80.

Create a file called deployment.yml and add the following.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-app
spec:
  selector:
    matchLabels:
      app: nginx-app
  template:
    metadata:
      labels:
        app: nginx-app
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
          - containerPort: 80

Now, we can create the pod using the following.

kubectl apply -f deployment.yml

Check the status of our deployment using the get deployment command.

kubectl get deployment
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          74s

At the moment, we are unable to access our pod, so we will need a service. The service below will allow us to expose the port 80 by using the selector that matches our deployment.

selector:
   app: nginx-app

Create a file called services.yml and add the following:

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  labels:
    app: nginx-app
spec:
  ports:
  - port: 80
  selector:
    app: nginx-app

Now, create the service using the following:

kubectl apply -f services.yml 

We can get the status of our service with the get service command.

$ kubectl get service
NAME            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
kubernetes      ClusterIP   10.96.0.1      <none>        443/TCP    212d
nginx-service   ClusterIP   10.109.88.45   <none>        80/TCP   16s

Now, our service can be access internally via other services, but not externally. If we were deploying this on a managed cluster like AWS, we can add type: LoadBalancer to our service and AWS will create a LB and assign an IP for us. Note this will not work on our local machine.

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  labels:
    app: nginx-app
spec:
   type: LoadBalancer
  ports:
  - port: 80
  selector:
    app: nginx-app
kubectl apply -f services.yml 

However, since we are running locally, we need to use the port-forward command.

kubectl port-forward svc/nginx-service 4000:80

You will then see the following:

Forwarding from 127.0.0.1:4000 -> 80
Forwarding from [::1]:4000 -> 80

Open up http://localhost:4000/ and you will see the nginx landing page.

Clean up

Let's end by cleaning up our resource. Run the following commands to delete our deployment and service.

kubectl delete deployment nginx-app
kubectl delete service nginx-service