DEV Community

whchi
whchi

Posted on

Deploy a minimal k8s environment to your local machine.

Web development are becoming more complex nowadays, especially when it's comes to deployment.

In this article, I'll walk through the process of creating a basic Kubernetes (k8s) environment with SSL on local machine, perfect for development and testing purposes. Our setup will include an ingress controller, an nginx service, and an app service.

Prerequisites

Before we begin, make sure you have the following:

  1. Minikube installed on your local machine.
  2. The ingress addon enabled in Minikube. You can enable it using the command: minikube addons enable ingress.
  3. make sure you are in the minikube environment, you can use eval $(minikube docker-env) to enter and eval $(minikube docker-env -u) to leave

Kubernetes Configuration

tls secret

We'll need to create a Kubernetes secret to handle our SSL certificates. You can do this using a YAML file or directly through the command line:

  • Option 1: Using a YAML File (tls-secret.yml)
apiVersion: v1
kind: Secret
metadata:
  name: my-tls-secret
  namespace: default
data:
  tls.crt: BASE64_ENCODED_CERT
  tls.key: BASE64_ENCODED_CERT_KEY
type: kubernetes.io/tls
Enter fullscreen mode Exit fullscreen mode

Replace BASE64_ENCODED_CERT and BASE64_ENCODED_CERT_KEY with your actual SSL certificate and private key encoded in base64 format.

  • Option 2: Using shell
kcc secret generic my-tls-secret \
--from-file=tls.crt=/path/to/cert \
--from-file=tls.key=/path/to/cery-key
Enter fullscreen mode Exit fullscreen mode

Replace /path/to/cert and /path/to/cert-key with the actual file paths of your SSL certificate and private key.

ingress

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: local-ingress
  annotations:
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
  tls:
  - hosts:
    - my.local.example
    secretName: my-tls-secret
  rules:
  - host: "my.local.example"
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-service
            port:
              number: 80

Enter fullscreen mode Exit fullscreen mode

nginx

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config
data:
  nginx.conf: |
    user nginx;
    worker_processes  3;
    error_log  /var/log/nginx/error.log;
    events {
      worker_connections  10240;
    }
    http {
      log_format main
              'remote_addr:$remote_addr\t'
              'time_local:$time_local\t'
              'method:$request_method\t'
              'uri:$request_uri\t'
              'host:$host\t'
              'status:$status\t'
              'bytes_sent:$body_bytes_sent\t'
              'referer:$http_referer\t'
              'useragent:$http_user_agent\t'
              'forwardedfor:$http_x_forwarded_for\t'
              'request_time:$request_time';
      access_log    /var/log/nginx/access.log main;
      include /etc/nginx/virtualhost/virtualhost.conf;
    }
  virtualhost.conf: |
    upstream nextjs {
      server app-service;
    }
    server {
      listen 80;
      server_name my.local.example;

      server_tokens off;

      gzip on;
      gzip_proxied any;
      gzip_comp_level 4;
      gzip_types text/css application/javascript image/svg+xml;

      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection 'upgrade';
      proxy_set_header Host $host;
      proxy_cache_bypass $http_upgrade;

      location / {
        proxy_pass http://nextjs$request_uri;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
      }
    }

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          volumeMounts:
            - name: nginx-conf
              mountPath: /etc/nginx
          image: nginx:1.25
          ports:
            - containerPort: 443
      volumes:
        - name: nginx-conf
          configMap:
            name: nginx-config
            items:
              - key: nginx.conf
                path: nginx.conf
              - key: virtualhost.conf
                path: virtualhost/virtualhost.conf
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

Enter fullscreen mode Exit fullscreen mode

application

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app
        image: YOUR_IMAGE_NAME
        imagePullPolicy: Never
        ports:
        - containerPort: 3000

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

Enter fullscreen mode Exit fullscreen mode

Replce YOUR_IMAGE_NAME to your local docker builded image

Activation

Once the Kubernetes config is ready, follow these steps to activate your k8s environment:

  1. Apply the resources in the following order:
    1. Ingress controller: kubectl apply -f ingress.yaml
    2. App deployment: kubectl apply -f app-deployment.yaml
    3. Nginx deployment: kubectl apply -f nginx-deployment.yaml
  2. Enable minikube tunnel to expose your ingress controller to the local machine: minikube tunnel
  3. You're all set! Try enter my.local.example in your browser url then you will get your application

Top comments (0)