How to Secure Your Ubuntu Kubernetes Cluster: A Step‑by‑Step Hardening Guide

This comprehensive guide explains how to harden an Ubuntu‑based Kubernetes cluster with external IPs by applying system hardening, firewall rules, TLS encryption, Calico network policies, RBAC permissions, audit logging, and verification steps to achieve a multi‑layered security posture.

Raymond Ops
Raymond Ops
Raymond Ops
How to Secure Your Ubuntu Kubernetes Cluster: A Step‑by‑Step Hardening Guide

Overview

When deploying a Kubernetes cluster on Ubuntu with an external IP, multi‑layer security measures are required. This guide covers system hardening, firewall configuration, TLS communication, network policies, RBAC, audit logging and verification steps.

1. Basic System Hardening

Install and configure NTP for time sync, disable swap, install Docker or containerd, and set required kernel parameters for Kubernetes networking.

sudo apt update
sudo apt install ntpdate ntp
sudo ntpdate ntp1.aliyun.com

# Disable swap
sudo swapoff --all
# edit /etc/fstab to comment swap line

# Docker installation
sudo apt-get update
sudo apt-get install docker.io

# Containerd installation
sudo apt-get update
sudo apt-get install containerd

# Kernel parameters
cat >> /etc/sysctl.d/kubernetes.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
sysctl -p

2. Firewall Rules (UFW)

Enable UFW and allow only required ports such as SSH (22), API server (6443), kubelet (10250, 10255), DNS (53) and etcd (2379/2380) from trusted IP ranges.

sudo apt update
sudo apt install ufw
sudo ufw enable

# Example rules
sudo ufw allow from 192.168.1.0/24 to any port 22 proto tcp
sudo ufw allow from 10.0.0.0/24 to any port 6443 proto tcp
sudo ufw allow from <master-node-IP> to any port 2379 proto tcp
sudo ufw allow from 10.0.0.0/24 to any port 10250 proto tcp
sudo ufw allow from 10.0.0.0/24 to any port 53 proto tcp
sudo ufw allow from 10.0.0.0/24 to any port 53 proto udp

sudo ufw default deny incoming
sudo ufw reload
sudo ufw status numbered

3. TLS Communication

Initialize the control plane with kubeadm init enabling TLS and adding the external IP as a SAN. Set token validity to 24 h and renew certificates when needed.

sudo kubeadm init \
  --apiserver-advertise-address=<internal-IP> \
  --apiserver-cert-extra-sans=<external-IP> \
  --pod-network-cidr=10.244.0.0/16

sudo kubeadm token create --validity 24h --print-join-command
sudo kubeadm certs check-expiration
sudo kubeadm certs renew all
systemctl restart kubelet
kubectl delete pod -n kube-system -l k8s-app=kube-apiserver
kubectl delete pod -n kube-system -l k8s-app=kube-controller-manager
kubectl delete pod -n kube-system -l k8s-app=kube-scheduler

4. Network Policy (Calico)

Deploy Calico as the CNI plugin and apply a global deny policy followed by namespace‑specific exceptions such as DNS.

# Download and apply Calico
curl https://docs.projectcalico.org/manifests/calico.yaml -O
kubectl apply -f calico.yaml

# Global deny policy (global-network-policy.yaml)
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: default-deny
spec:
  selector: all()
  types:
  - Ingress
  - Egress

kubectl apply -f global-network-policy.yaml

# DNS allow policy (dns-policy.yaml)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns
  namespace: default
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: kube-system
    - podSelector:
        matchLabels:
          k8s-app: kube-dns
    ports:
    - protocol: TCP
      port: 53
    - protocol: UDP
      port: 53

5. RBAC and Auditing

Create minimal‑privilege Roles and RoleBindings for developers, restrict the default ServiceAccount, and enable API‑server audit logging.

# Example Role (dev-namespace-role.yaml)
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: dev-namespace
  name: dev-namespace-role
rules:
- apiGroups: [""]
  resources: ["pods","services"]
  verbs: ["get","list","create","update","delete"]
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get","list","create","update","delete"]
- apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["get","list"]

# Bind the role
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: dev-namespace-binding
  namespace: dev-namespace
subjects:
- kind: User
  name: dev-team
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: dev-namespace-role
  apiGroup: rbac.authorization.k8s.io

# Read‑only pod role for default SA
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-reader-role
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get","watch","list"]

6. Verification

After hardening, verify firewall rules with ufw status, TLS with kubectl cluster-info, network policies by testing pod‑to‑pod connectivity, RBAC by attempting privileged actions with different users, and audit logs in /var/log/kubernetes/audit.log.

Conclusion

Applying layered security—system hardening, firewall, TLS, network policies, RBAC and continuous audit—creates a resilient Ubuntu‑based Kubernetes deployment. Regular updates, monitoring and a security‑first culture are essential for long‑term protection.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

KubernetesSecurityTLSRBACUbuntuHardeningufw
Raymond Ops
Written by

Raymond Ops

Linux ops automation, cloud-native, Kubernetes, SRE, DevOps, Python, Golang and related tech discussions.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.