# Working with Namespaces and Services in Kubernetes

In Kubernetes (often abbreviated as K8s), "Namespaces" and "Services" are fundamental concepts that help organize and manage containers and services within a cluster. Let's explore each concept in more detail:

1. **Namespaces**:
    
    * **Purpose**: Namespaces provide a way to logically divide and isolate resources within a Kubernetes cluster. They are used to create separate virtual clusters within a single physical cluster. This isolation helps prevent naming conflicts and resource collisions between different teams, applications, or environments (e.g., development, testing, production).
        
    * **Use Cases**: Namespaces are often used to group related resources together, such as pods, services, config maps, and secrets.
        
    * **Default Namespace**: By default, when you create resources in Kubernetes without specifying a namespace, they are created in the `default` namespace.
        
    * **Syntax**: When creating or referencing resources within a specific namespace, you can specify the namespace in YAML definitions or when using `kubectl` commands.
        
    
    Example YAML defining a pod in a specific namespace:
    
    ```yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: my-pod
      namespace: my-namespace
    spec:
      containers:
      - name: my-container
        image: nginx
    ```
    
    Example `kubectl` command to list pods in a specific namespace:
    
    ```shell
    kubectl get pods -n my-namespace
    ```
    
2. **Services**:
    
    * **Purpose**: Services in Kubernetes provide network abstraction to access a group of pods. They allow you to expose and discover services running within a cluster, such as web applications, databases, or other microservices.
        
    * **Types of Services**: Kubernetes supports several types of services:
        
        * **ClusterIP**: Exposes the service on an internal cluster IP, making it accessible only from within the cluster.
            
        * **NodePort**: Exposes the service on a static port on each node's IP, allowing external access to the service.
            
        * **LoadBalancer**: Exposes the service using a cloud provider's load balancer (if available) or a custom external load balancer.
            
        * **ExternalName**: Maps the service to an external DNS name.
            
    * **Use Cases**: Services are used to ensure that applications and services can communicate with each other reliably and to provide a stable endpoint for applications to connect to.
        
    
    Example YAML defining a NodePort service:
    
    ```yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: my-service
    spec:
      selector:
        app: my-app
      ports:
      - protocol: TCP
        port: 80
        targetPort: 8080
      type: NodePort
    ```
    
    In this example, the service named "my-service" exposes pods with the label `app: my-app` on port 8080, and it is accessible on a static port on each node's IP.
    

Namespaces and Services are essential tools for managing and organizing resources in a Kubernetes cluster, making it easier to scale and maintain complex containerized applications.

## Task 1

**Let's create a namespace for the todo deployment**

1. To create a namespace run the command `kubectl create namespace <name>`, replace the name with your desired name. I named it with `nodeapp` . To see the namespaces run the command `kubectl get namespace`
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1694207075833/f0ea94ed-7d58-4672-a5e9-18dd737f9ece.png align="center")
    
2. Now let's make the changes in the `deployment.yml` file to update the namespace in it.
    

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: todo-deployment
  namespace: todoapp # added this line
  labels:
    app: todo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: todo
  template:
    metadata:
      labels:
        app: todo
      namespace: todoapp 
    spec:
      containers:
        - name: todo
          image: keshavkumar23022000/node-deploy
          ports:
            - containerPort: 8000
                         
```

1. Apply it to the cluster using `kubectl apply -f deployment.yml`
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1694207377660/fd7d2e5f-1f06-4439-8b0a-c4f4b0e78426.png align="center")

It will show you similar output.

## Task 2

**Learning about Service, load balancing and Networking in K8s**

In Kubernetes, Services play a crucial role in load balancing and networking for containerized applications. Let's delve deeper into how Services, load balancing, and networking are interconnected:

1. **Services**:
    
    * **Purpose**: A Kubernetes Service is an abstraction that enables network communication to a set of Pods. It provides a stable and reliable endpoint for applications to access a group of Pods, regardless of which individual Pod is handling the request.
        
    * **Types of Services**: Kubernetes offers several types of Services, including:
        
        * **ClusterIP**: Exposes a service on an internal cluster IP, making it accessible only from within the cluster.
            
        * **NodePort**: Exposes a service on a static port on each node's IP, allowing external access to the service.
            
        * **LoadBalancer**: Exposes a service using a cloud provider's load balancer (if available) or a custom external load balancer.
            
        * **ExternalName**: Maps the service to an external DNS name.
            
    * **Use Cases**: Services are used to enable intra-cluster and inter-cluster communication, provide load balancing across Pods, and ensure high availability and fault tolerance.
        
2. **Load Balancing**:
    
    * **Purpose**: Load balancing is the process of distributing incoming network traffic across multiple backend resources (in this case, Pods) to ensure even distribution of requests and efficient utilization of resources.
        
    * **Load Balancing with Services**: Kubernetes Services provide load balancing for Pods that are part of the service. Here's how it works:
        
        * For ClusterIP Services, traffic is internally load-balanced among the Pods within the cluster.
            
        * For NodePort Services, traffic is load-balanced across the nodes, and each node forwards requests to the appropriate Pod.
            
        * For LoadBalancer Services, traffic is load-balanced by an external load balancer, which then forwards traffic to the cluster's nodes and Pods.
            
    * **Benefits**: Load balancing enhances the availability, scalability, and reliability of applications by distributing traffic evenly and routing it away from unhealthy Pods.
        
3. **Networking**:
    
    * **Networking Model**: Kubernetes employs a robust networking model to ensure that Pods can communicate with each other both within and outside the cluster. Key networking concepts include:
        
        * **Pod-to-Pod Communication**: Pods can communicate with each other using their IP addresses, and this communication is typically unrestricted within a cluster.
            
        * **Service Discovery**: Services provide DNS-based service discovery, enabling Pods to discover and access other services by their DNS names.
            
        * **Ingress**: Kubernetes Ingress controllers manage external access to services, handling HTTP and HTTPS traffic and providing advanced routing and host-based access control.
            

**Network Policies**: Network Policies define rules for controlling network traffic between Pods, allowing fine-grained control over communication within the cluster

##   
**Let's use Service in our Todo App**

1. Creating service yaml file
    
    ```yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: node-svc
    spec:
      selector:
        app: todo
      ports:
        - protocol: TCP
          port: 80
          targetPort: 8000
          nodePort: 30007 # there is predefined range 30000-32767 ports to be allocated using the service
      type: NodePort # this will help to access our app outside k8s cluster
    ```
    
2. Creating the deployment yaml file
    
    ```yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: todo-deployment
      labels:
        app: todo
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: todo
      template:
        metadata:
          labels:
            app: todo
        spec:
          containers:
            - name: todo
              image: keshavkumar23022000/node-deploy
              ports:
                - containerPort: 8000
    ```
    
3. Applying both to the Kubernetes Cluster
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1694207974980/ffcde10d-e215-4575-827b-ba74c055eb26.png align="center")
    
4. Add the port 30007 in the inbound rules of the worker node and try to access it from the cluster first
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1694208099921/c4c31fd1-da44-48ed-ac0b-69ff949a35c3.png align="center")
    
5. Let's now try to access it over the web, using the Public IP of the Worker node and binding it with the Port 30007 as shown
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1694208194942/073d93aa-1dd1-4e60-bc0a-fd98a5dc7e0a.png align="center")
    
    I have used the previous image and not done modifications to it, you can modify it and deploy it. We will deep dive into more about Services in the next blog. Happy Kubernetting.
