How to Harden Ubuntu Kubernetes Clusters: A Complete Security Blueprint

This guide walks you through securing an Ubuntu‑hosted Kubernetes cluster by configuring system settings, firewall rules, TLS encryption, network policies, RBAC permissions, audit logging, and verification steps, providing a layered defense strategy for production environments.

MaGe Linux Operations
MaGe Linux Operations
MaGe Linux Operations
How to Harden Ubuntu Kubernetes Clusters: A Complete Security Blueprint

Ubuntu K8s Cluster Security Hardening

When deploying a Kubernetes cluster on Ubuntu servers that have external IPs, multiple layers of protection are required. This solution builds a secure environment through system firewall configuration, TLS communication, network policy enforcement, and RBAC access control.

1. Basic System Security

Time synchronization – install and configure NTP:

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

Disable swap – edit /etc/fstab to comment out swap lines and run: swapoff --all Install a container runtime (Docker or containerd):

sudo apt-get update
sudo apt-get install docker.io
sudo apt-get update
sudo apt-get install containerd

Configure kernel parameters for Kubernetes networking:

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)

Install and enable UFW:

sudo apt update
sudo apt install ufw
sudo ufw enable

Default policy denies all inbound traffic. Allow only required ports:

# SSH
sudo ufw allow from 192.168.1.0/24 to any port 22 proto tcp
# API Server (cluster nodes only)
sudo ufw allow from 10.0.0.0/24 to any port 6443 proto tcp
# etcd communication (master nodes only)
sudo ufw allow from <master-node-IP1> to any port 2379 proto tcp
sudo ufw allow from <master-node-IP2> to any port 2379 proto tcp
# Kubelet API (cluster nodes only)
sudo ufw allow from 10.0.0.0/24 to any port 10250 proto tcp
# DNS (cluster nodes only)
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
# Default deny incoming
sudo ufw default deny incoming

Reload and verify:

sudo ufw reload
sudo ufw status numbered

3. TLS Secure Communication

Initialize the control plane with TLS and extra SANs:

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

Set token validity to 24 hours:

sudo kubeadm token create --validity 24h --print-join-command

Check certificate expiration and renew if needed:

sudo kubeadm certs check-expiration
sudo kubeadm certs renew all

Restart components after renewal:

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 Plugin (Calico)

Download and apply Calico manifests:

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

Verify all Calico pods are Running: kubectl get pods -n calico-system Deploy a global deny policy as a security baseline:

apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: default-deny
spec:
  selector: all()
  types:
  - Ingress
  - Egress

Apply DNS exception policy:

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

Example of namespace isolation for a sensitive database namespace:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
  namespace: database
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress
  egress:
  - to:
    - ipBlock:
        cidr: 0.0.0.0/0
        except:
        - ipBlock:
            cidr: 10.0.0.0/16

5. RBAC Permissions and Auditing

Create a minimal role for developers in dev-namespace:

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 to a user:

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

Restrict the default service account to read‑only pod access:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-reader-role
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get","watch","list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: default
subjects:
- kind: ServiceAccount
  name: default
  namespace: default
roleRef:
  kind: Role
  name: pod-reader-role
  apiGroup: rbac.authorization.k8s.io

Enable API‑server audit logging by creating /etc/kubernetes/audit/audit-policy.yaml and adding the following flags to the kube‑apiserver service:

--audit-policy-file=/etc/kubernetes/audit/audit-policy.yaml
--audit-log-path=/var/log/kubernetes/audit.log
--audit-log-maxsize=100
--audit-log-maxbackup=5
--audit-log-maxage=30

Restart kubelet to apply changes and verify logs at /var/log/kubernetes/audit.log. Tools such as kube-audit can be used for analysis.

6. Best Practices

Deploy clusters in a private network; expose the API server via a load balancer with IP whitelisting.

Use Pod Security Policies or OPA Gatekeeper to restrict privileged pods.

Store sensitive data in encrypted Secrets.

Keep the OS and Kubernetes components up‑to‑date.

Use trusted container images and scan them with tools like Trivy.

Implement regular backups of etcd and certificates.

Monitor the cluster with Prometheus/Grafana and set alert rules for abnormal API calls.

Consider advanced CNI plugins (e.g., Cilium) for zero‑trust networking.

7. Post‑Hardening Validation

Firewall verification : ufw status and port tests with nc -zv <IP> <port>.

TLS verification : kubectl cluster-info and HTTPS access to the API server.

Network policy verification : create test pods in different namespaces and attempt ping.

RBAC verification : try privileged actions with different accounts.

Audit log verification : inspect /var/log/kubernetes/audit.log and analyze with kube-audit.

Following these steps ensures that the security hardening measures are correctly applied and provides a solid foundation for ongoing secure operations.

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.

KubernetesSecurityTLSRBACUbuntuCalicoNetworkPolicyufw
MaGe Linux Operations
Written by

MaGe Linux Operations

Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.

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.