A beginners guide to Kubernetes with Docker
Tags: kubernetes, docker, tutorial, webdev
Published: 2024-06-16 15:31:42

**Kubernetes** (often abbreviated as K8s) is an open-source platform for automating the deployment, scaling, and operation of application containers. It works with various container runtimes, including Docker, to orchestrate containerized applications across clusters of machines.

Here’s a brief tutorial on Kubernetes and how it works with Docker containers:

**1. Basic Concepts in Kubernetes**

- **Cluster:** A set of nodes (machines) running containerized applications managed by Kubernetes.

- **Node:**A single machine in a Kubernetes cluster. It can be a physical or virtual machine.

- **Pod:** The smallest deployable unit in Kubernetes, which can contain one or more containers.

- **Service:***An abstraction that defines a logical set of pods and a policy by which to access them.

- **Deployment:** Manages a set of identical pods, ensuring the correct number of replicas and allowing updates.

- **ConfigMap and Secret:**Objects for managing configuration data and sensitive information, respectively.

**2. Installing Kubernetes**

You can install Kubernetes locally using tools like Minikube or kind (Kubernetes in Docker). For production, you’d typically use a cloud provider’s managed Kubernetes service, such as GKE (Google Kubernetes Engine), EKS (Amazon Elastic Kubernetes Service), or AKS (Azure Kubernetes Service).

**Install Minikube**

Follow the installation guide for your operating system on the [Minikube website
](https://minikube.sigs.k8s.io/docs/start/)

**Start Minikube:**

`minikube start`

**Install kubectl:**

Follow the installation guide on the Kubernetes [website](https://kubernetes.io/)

**3. Creating a Simple Kubernetes Application**

Step 1: Create a Deployment

Create a Docker image:
Dockerfile:

`FROM node:14

WORKDIR /usr/src/app

COPY package*.json ./

RUN npm install

COPY . .

EXPOSE 3000

CMD ["node", "app.js"]`

**Build the Docker image:**

docker build -t node-app:latest .

**Push the image to a container registry (e.g., Docker Hub):**

`docker tag node-app:latest <your-dockerhub-username>/node-app:latest`

`docker push <your-dockerhub-username>/node-app:latest`

**Create a Kubernetes Deployment YAML file (`deployment.yaml`):**

```
apiVersion: apps/v1
kind: Deployment
metadata:
  name: node-app-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: node-app
  template:
    metadata:
      labels:
        app: node-app
    spec:
      containers:
      - name: node-app
        image: <your-dockerhub-username>/node-app:latest
        ports:
        - containerPort: 3000
```

Apply the deployment:

`kubectl apply -f deployment.yaml`

**Check the deployment and pods:**

```
kubectl get deployments
kubectl get pods
```
Step 2: Create a Service

**Create a Service YAML file (`service.yaml`):**

```
apiVersion: v1
kind: Service
metadata:
  name: node-app-service
spec:
  selector:
    app: node-app
  ports:
  - protocol: TCP
    port: 80
    targetPort: 3000
  type: LoadBalancer
```

2. Apply the service:

`kubectl apply -f service.yaml`

3. Check the service:

`kubectl get services`

4. Access the application:

Use the external IP provided by the service (in Minikube, use `minikube service node-app-service – url`).

4. Communicating Between Services

step 1: Set Up a Database Service

Create a PostgreSQL Deployment and Service:

```
apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
      - name: postgres
        image: postgres:latest
        env:
        - name: POSTGRES_DB
          value: mydatabase
        - name: POSTGRES_USER
          value: postgres
        - name: POSTGRES_PASSWORD
          value: mysecretpassword
        ports:
        - containerPort: 5432

---
apiVersion: v1
kind: Service
metadata:
  name: postgres-service
spec:
  selector:
    app: postgres
  ports:
  - protocol: TCP
    port: 5432
    targetPort: 5432
```
2. Apply the deployment and service:

`kubectl apply -f postgres.yaml`

Step 2: Update Node.js Application to Use Database

Modify `app.js` to connect to PostgreSQL:

```
const express = require('express');
const { Pool } = require('pg');
const app = express();
const PORT = 3000;

const pool = new Pool({
  user: 'postgres',
  host: 'postgres-service',
  database: 'mydatabase',
  password: 'mysecretpassword',
  port: 5432,
});

app.get('/', async (req, res) => {
  const result = await pool.query('SELECT NOW()');
  res.send(`PostgreSQL time: ${result.rows[0].now}`);
});

app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});
```

2. Build and push the updated Docker image:

```
docker build -t <your-dockerhub-username>/node-app:latest .
docker push <your-dockerhub-username>/node-app:latest
```

3. Update the deployment:

`kubectl set image deployment/node-app-deployment node-app=<your-dockerhub-username>/node-app:latest`

4. Scaling and Updating Applications

Scale the deployment:

`kubectl scale deployment node-app-deployment – replicas=5`

5. Update the deployment with a new image:

`kubectl set image deployment/node-app-deployment node-app=<your-dockerhub-username>/node-app:new-version`

6. Managing Configurations with ConfigMaps and Secrets

Create a ConfigMap:

`configmap.yaml`

```
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  DATABASE_HOST: postgres-service
  DATABASE_USER: postgres
  DATABASE_PASSWORD: mysecretpassword
  DATABASE_NAME: mydatabase
Applying the ConfigMap:

kubectl apply -f configmap.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: node-app-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: node-app
  template:
    metadata:
      labels:
        app: node-app
    spec:
      containers:
      - name: node-app
        image: <your-dockerhub-username>/node-app:latest
        ports:
        - containerPort: 3000
        env:
        - name: DATABASE_HOST
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: DATABASE_HOST
        - name: DATABASE_USER
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: DATABASE_USER
        - name: DATABASE_PASSWORD
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: DATABASE_PASSWORD
        - name: DATABASE_NAME
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: DATABASE_NAME
```

Make sure to replace <your-dockerhub-username> with your actual Docker Hub username.

The ConfigMap provides database configuration information that the node-app container in the Deployment uses through environment variables. The kubectl apply -f configmap.yaml command applies the ConfigMap configuration to your Kubernetes cluster.

This tutorial covers the basics of Kubernetes, deploying and managing Docker containers, and communicating between services. For more advanced topics, consider exploring Kubernetes documentation and other resources.