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.
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.comDisable 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 containerdConfigure 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 -p2. Firewall Rules (UFW)
Install and enable UFW:
sudo apt update
sudo apt install ufw
sudo ufw enableDefault 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 incomingReload and verify:
sudo ufw reload
sudo ufw status numbered3. 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/16Set token validity to 24 hours:
sudo kubeadm token create --validity 24h --print-join-commandCheck certificate expiration and renew if needed:
sudo kubeadm certs check-expiration
sudo kubeadm certs renew allRestart 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-scheduler4. Network Policy Plugin (Calico)
Download and apply Calico manifests:
curl https://docs.projectcalico.org/manifests/calico.yaml -O
kubectl apply -f calico.yamlVerify 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
- EgressApply 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: 53Example 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/165. 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.ioRestrict 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.ioEnable 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=30Restart 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.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
