# Deploying Kubernetes Pods with NodePort, ClusterIP, and LoadBalancer Services

In this guide, we'll walk through how to expose a Kubernetes pod to the outside world using three different types of services: NodePort, ClusterIP, and LoadBalancer. By the end of this tutorial, you will understand how each service type functions and how to test them.

### **Expose a Pod Using NodePort**

**NodePort** allows you to expose a service on a static port on each node’s IP address.

**<mark>Step 1: Check the Existing Services</mark>**

Before creating a new service, let's check which services are currently running in the cluster:

```plaintext
kubectl get services
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1724270325719/65245892-5c5c-4f49-9eb0-894f9bf9994a.png align="center")

**<mark>Step 2: Create a NodePort Service</mark>**

Create a YAML configuration file for the NodePort service. Save this as `nodeport.yaml`:

```plaintext
apiVersion: v1
kind: Service
metadata:
  name: my-nodeport
spec:
  type: NodePort
  selector:
    app: dev
  ports:
    - port: 80
      targetPort: 80
      nodePort: 32001
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1724270395677/51b184b2-ca3b-44ba-aec6-e14a9896977f.png align="center")

Apply the configuration:

```plaintext
kubectl apply -f nodeport.yaml
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1724270461842/7e262a9d-8a76-40bb-a1ab-cfedbb53cb6b.png align="center")

Verify that the service has been created:

```plaintext
kubectl get services
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1724270500729/0dc4cffb-34a0-42cc-ae12-1fa688e83913.png align="center")

**<mark>Step 3: Create a Pod</mark>**

Create a YAML configuration file for the pod. Save this as `pod.yaml`:

```plaintext
apiVersion: v1
kind: Pod
metadata:
  name: my-pod1
  labels:
    app: dev
spec:
  containers:
  - name: cont1
    image: httpd
    ports:
    - containerPort: 80
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1724270568808/26a3dedd-e872-4e48-91e1-185186471427.png align="center")

Apply the configuration:

```plaintext
kubectl apply -f pod.yaml
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1724270609543/f22da6fa-5209-4eeb-adab-3f580b4a0048.png align="center")

**Find the Worker Node IP Address**

Identify which worker node the pod is running on:

```plaintext
kubectl get pod -o wide
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1724271101411/4d18e079-2695-46cd-a955-ac8fef5e652e.png align="center")

Access the service via the worker node IP address and NodePort in your browser:

```plaintext
http://<worker-node-ip>:32001
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1724271056046/efa0a672-f126-4c2c-a456-0b2d8c16bdf3.png align="left")

Ensure that the port 32001 is open in the security group associated with your worker nodes.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1724270988630/3e409f78-182a-4d2e-b603-6bff16aeaf84.png align="center")

If you have multiple worker nodes, you should be able to access the pod via any worker node’s IP and the same port number.

### Create ClusterIP for Pod-to-Pod Communication

**ClusterIP** exposes the service on a cluster-internal IP. It’s the default service type and is only accessible within the cluster.

**<mark>Step 1 : Create a ClusterIP Service</mark>**

Create a YAML configuration file for the ClusterIP service. Save this as `cluster-ip.yaml`

```plaintext
apiVersion: v1
kind: Service
metadata:
  name: my-clusterip
spec:
  type: ClusterIP
  ports:
    - port: 80
  selector:
    app: nginx
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1724271160029/1e5266f4-44fa-495a-b4ae-2cd4b48ee4f2.png align="center")

Apply the configuration:

```plaintext
 kubectl apply -f cluster-ip.yaml
```

Verify the service:

```plaintext
kubectl get services
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1724271255129/899c4442-c011-4e03-9e43-ad56c496dab4.png align="center")

**Create a New Pod for Communication**

Create a new pod with the `nginx` image. Save this as `pod2.yaml`:

```plaintext
apiVersion: v1
kind: Pod
metadata:
  name: my-pod2
  labels:
    app: nginx
spec:
  containers:
  - name: cont1
    image: nginx
    ports:
    - containerPort: 80
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1724271297296/1c773a34-5115-4d22-a3f5-2ef1622ae659.png align="center")

Apply the configuration:

```plaintext
kubectl apply -f pod2.yaml
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1724271341487/48c60ad1-87da-461c-8027-1cff8f422535.png align="center")

**Test Pod-to-Pod Communication**

Access the first pod:

```plaintext
kubectl exec -it my-pod1 -- /bin/bash
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1724271388622/08da94e7-67db-4164-9c10-3ae512589029.png align="center")

Use `curl` to test communication:

Check the pod2 ip address

```plaintext
kubectl get pods -o wide
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1724272015142/376dac95-abad-43fa-90f4-6baca4dd3d91.png align="center")

```plaintext
curl http://<pod2-ip>:80
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1724272207633/30d77820-98e4-4068-abbc-7c4749eb322f.png align="center")

Also, test accessing the ClusterIP service:

```plaintext
curl http://<cluster-ip>:80
```

You should see the output from `nginx`, confirming that both direct pod-to-pod communication and service-based communication are working.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1724272426539/938ac58a-39c0-475d-99a6-e1735a92612a.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1724272504823/54e196fa-fef2-4175-a746-21862ad971f1.png align="center")

### Step 3: Create a LoadBalancer Service

**LoadBalancer** provisions a load balancer for your service, making it accessible from outside the cluster. This is particularly useful in cloud environments.

**Create a LoadBalancer Service and Deployment**

Create a YAML configuration file for the LoadBalancer service and a corresponding deployment. Save this as `loadbalancer.yaml`:

```plaintext
apiVersion: v1
kind: Service
metadata:
  name: my-loadbalancer
spec:
  type: LoadBalancer
  selector:
    app: hello
  ports:
    - name: http
      protocol: TCP
      port: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello
  template:
    metadata:
      labels:
        app: hello
    spec:
      containers:
        - name: cont-1
          image: httpd
          ports:
          - containerPort: 80
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1724272890726/51660218-d4f6-4054-94c3-5b25de868263.png align="center")

Apply the configuration:

```plaintext
kubectl apply -f loadbalancer.yaml
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1724272944821/edf35148-23aa-4361-bf64-0d4e854295f3.png align="center")

Verify that the LoadBalancer service has been created and is provisioning:

```plaintext
kubectl get services
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1724272989037/2cad5272-10c2-4183-962f-6aceff37fc11.png align="center")

```plaintext
ad856d5d974ee4258b970fb02ff1b8f7-1585886479.us-east-2.elb.amazonaws.com
```

**Check LoadBalancer on Cloud Console**

If you are using a cloud provider like AWS, navigate to the Load Balancer section of your console. You should see a new Load Balancer created. Copy the DNS name of the Load Balancer.

**Access the Application**

Open a browser and navigate to the Load Balancer’s DNS name:

```plaintext
http://<loadbalancer-dns-name>
http://ad856d5d974ee4258b970fb02ff1b8f7-1585886479.us-east-2.elb.amazonaws.com
```

You should see the output from the `httpd` container.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1724273141931/2722def5-c46a-4ad1-b888-c934a3e46679.png align="center")

**Clean Up**

Once you are done, you can delete the services and deployments:

```plaintext
kubectl delete services my-nodeport my-clusterip my-loadbalancer
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1724273308743/d8c27f32-11d7-42ca-8daf-ccf327176991.png align="center")

```plaintext
kubectl delete deployment my-deployment
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1724273335181/a758b9d4-0a03-4753-9b6c-99b1d3cbe9d3.png align="center")

By following these steps, you’ve learned how to expose a Kubernetes pod using different service types and tested their functionality.
