Zee - Blog
Published on

Visualization service - Setup K8s on Digital Ocean

Authors
  • avatar
    Name
    Zee Lu
    Twitter

Setting Up Kubernetes on DigitalOcean with HTTPS

This guide walks through setting up a production-ready Kubernetes cluster on DigitalOcean with automatic SSL certificate management using Let's Encrypt.

Overview

We'll set up:

  • DigitalOcean Kubernetes cluster
  • NGINX Ingress Controller
  • cert-manager for automatic SSL certificates
  • Domain configuration with HTTPS
  • Test application to verify everything works

Prerequisites

  • DigitalOcean account
  • Domain name (I used my own domain zeelu.me with subdomain ingresstest.do.zeelu.me)
  • kubectl configured to access your cluster
  • helm package manager

Step 1: Create DigitalOcean Kubernetes Cluster

  1. Go to DigitalOcean Control Panel
  2. Navigate to KubernetesCreate Cluster
  3. Choose your configuration:
    • Datacenter: I used Toronto Datacenter
    • Node pool: I only get 1 nodes for testing purpose, which I get vCPU: 1 Shared, vRAM: 2 GB, Storage: 50 GB for $12/month
    • Node size: Basic plan (2GB RAM minimum) - The cheapest plan
  4. Click Create Cluster

Step 2: Configure kubectl

After the cluster is created, it will pop up some instructions, simply follow the DigitalOcean's guide to install doctl, and set up the kubeconfig.

Step 3: Install Helm

Install Helm package manager:

bash
# On macOS with Homebrew
brew install helm

# Verify installation
helm version

Add required repositories:

bash
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo add jetstack https://charts.jetstack.io
helm repo update

Step 4: Install NGINX Ingress Controller

Install the NGINX Ingress Controller:

bash
helm install ingress-nginx ingress-nginx/ingress-nginx \
  --namespace ingress-nginx \
  --create-namespace

Check the installation:

bash
kubectl get pods --namespace ingress-nginx
kubectl get service --namespace ingress-nginx ingress-nginx-controller --output wide

Wait for the load balancer to get an external IP (usually 1-2 minutes).

Step 5: Configure DNS

  1. Go to DigitalOcean → NetworkingDomains
  2. Find your domain (zeelu.me)
  3. Add an A record:
    • Name: ingresstest (for ingresstest.do.zeelu.me)
    • Value: YOUR_LOAD_BALANCER_IP (from step 4) - Normally you can select from the dropdown list
    • TTL: default

Test DNS resolution:

Use nslookup or simply view the domain in the browser

bash
nslookup ingresstest.do.zeelu.me

Step 6: Install cert-manager

Install cert-manager for automatic SSL certificate management:

bash
helm install cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --create-namespace \
  --set installCRDs=true

Verify installation:

bash
kubectl get pods --namespace cert-manager

Step 7: Configure Let's Encrypt Issuer

Create a ClusterIssuer for Let's Encrypt:

yaml
# letsencrypt-issuer.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    # The ACME server URL
    server: https://acme-v02.api.letsencrypt.org/directory
    # Email address used for ACME registration
    email: your-email@domain.com  # Replace with your email
    # Name of a secret used to store the ACME account private key
    privateKeySecretRef:
      name: letsencrypt-prod
    # Enable the HTTP-01 challenge provider
    solvers:
    - http01:
        ingress:
          class: nginx

Apply the configuration:

bash
kubectl apply -f letsencrypt-issuer.yaml

Check the issuer status:

bash
kubectl get clusterissuer letsencrypt-prod
# Should show READY=True

Step 8: Deploy Test Application

Create a simple test application:

bash
# Deploy nginx test app
kubectl create deployment test-app --image=nginx:alpine
kubectl expose deployment test-app --port=80 --type=ClusterIP

Step 9: Configure HTTPS Ingress

Create an ingress with SSL certificate:

yaml
# test-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-ingress
  namespace: default
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - ingresstest.do.zeelu.me
    secretName: ingresstest-tls
  rules:
    - host: ingresstest.do.zeelu.me
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: test-app
                port:
                  number: 80

Apply the ingress:

bash
kubectl apply -f test-ingress.yaml

Step 10: Verify SSL Certificate

Check certificate status:

bash
kubectl get certificates
kubectl describe certificate ingresstest-tls

Wait for the certificate to be issued (usually 1-2 minutes). You should see READY=True.

Step 11: Test HTTPS

Test both HTTP and HTTPS:

bash
# Test HTTP
curl http://ingresstest.do.zeelu.me

# Test HTTPS
curl https://ingresstest.do.zeelu.me

# Test with headers
curl -I https://ingresstest.do.zeelu.me

You should see:

  • HTTP/2 response
  • strict-transport-security header
  • Valid SSL certificate

Step 12: Browser Test

Visit https://ingresstest.do.zeelu.me in your browser. You should see the nginx welcome page.

Troubleshooting

DNS Issues

bash
# Check DNS resolution
nslookup ingresstest.do.zeelu.me
dig ingresstest.do.zeelu.me

# Test direct IP
curl -H "Host: ingresstest.do.zeelu.me" http://YOUR_LOAD_BALANCER_IP

Certificate Issues

bash
# Check certificate status
kubectl get certificates
kubectl describe certificate ingresstest-tls

# Check challenges
kubectl get challenges
kubectl describe challenge CHALLENGE_NAME

# Check orders
kubectl get orders
kubectl describe order ORDER_NAME

Ingress Issues

bash
# Check ingress status
kubectl get ingress
kubectl describe ingress test-ingress

# Check ingress controller logs
kubectl logs -n ingress-nginx deployment/ingress-nginx-controller

Cleanup

To remove test resources:

bash
# Delete test application
kubectl delete deployment test-app
kubectl delete service test-app
kubectl delete ingress test-ingress
kubectl delete certificate ingresstest-tls

# Delete ingress controller (optional)
helm uninstall ingress-nginx --namespace ingress-nginx

# Delete cert-manager (optional)
helm uninstall cert-manager --namespace cert-manager

Resources