๐ท๏ธ Manage the lifecycle of Kubernetes clusters#
Allow control-plane node to schedule non-system pod#
แ
kb describe no | grep Taints
Taints: node-role.kubernetes.io/control-plane:NoSchedule
Taints: <none>
แ
kb taint node cp-01 node-role.kubernetes.io/control-plane-
node/cp-01 untainted
แ
kb describe no | grep Taints
Taints: <none>
Taints: <none>
แ
kb get no cp-01 -o jsonpath='{.spec.taints}' | jq '.[]'
Revert.
แ
kb taint node cp-01 node-role.kubernetes.io/control-plane:NoSchedule
node/cp-01 tainted
Backup etcd database#
Find data directory.
แ
sudo grep data-dir /etc/kubernetes/manifests/etcd.yaml
- --data-dir=/var/lib/etcd
Find and connect etcd pod.
แ
kb get po -l component=etcd -n kube-system
แ
kb exec -it etcd-cp-01 -n kube-system -- sh
sh-5.2# alias etcdct='etcdctl --cacert="/etc/kubernetes/pki/etcd/ca.crt" --cert="/etc/kubernetes/pki/etcd/server.crt" --key="/etc/kubernetes/pki/etcd/server.key"'
sh-5.2# etcdct member list -w table
+------------------+---------+------------+----------------------------+----------------------------+------------+
| ID | STATUS | NAME | PEER ADDRS | CLIENT ADDRS | IS LEARNER |
+------------------+---------+------------+----------------------------+----------------------------+------------+
| aa5b4d1a0319ca2d | started | cp-01 | https://192.168.94.73:2380 | https://192.168.94.73:2379 | false |
+------------------+---------+------------+----------------------------+----------------------------+------------+
sh-5.2# etcdct endpoint status -w table
+----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| 127.0.0.1:2379 | aa5b4d1a0319ca2d | 3.5.21 | 24 MB | true | false | 2 | 15133 | 15133 | |
+----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
sh-5.2# etcdct snapshot save /var/lib/etcd/snapshot.db
Create backup directory.
แ
sudo cp -p /var/lib/etcd/snapshot.db $HOME/backup/snapshot_$(date +%F).db
แ
sudo cp $HOME/kubeadm-config.yaml backup
แ
k -n kube-system get cm kubeadm-config -o yaml | \
yq -r '.data.ClusterConfiguration' > kubeadm-config-backup.yaml
แ
sudo cp -rp /etc/kubernetes/pki/etcd backup
แ
sudo cp -rp /etc/kubernetes/admin.conf backup/kubeconfig
backup
โโโ etcd
โย ย โโโ ca.crt
โย ย โโโ ca.key
โย ย โโโ healthcheck-client.crt
โย ย โโโ healthcheck-client.key
โย ย โโโ peer.crt
โย ย โโโ peer.key
โย ย โโโ server.crt
โย ย โโโ server.key
โโโ kubeadm-config.yaml
โโโ kubeconfig
โโโ snapshot_2025-10-07.db
Upgrade the cluster#
On a control-plane node.
# Change k8s minor version in source list file
แ
sudo sed -i 's/33/34/g' /etc/apt/sources.list.d/kubernetes.list
# Update and upgrade kubeadm
แ
sudo apt update
แ
sudo apt-mark unhold kubeadm
แ
sudo apt-cache madison kubeadm
แ
sudo apt install kubeadm=1.34.1-1.1 -y
แ
sudo apt-mark hold kubeadm
แ
sudo kubeadm version
# Upgrade the cluster with upgraded kubeadm
แ
kb drain cp-01 --ignore-daemonsets
แ
sudo kubeadm upgrade plan
แ
sudo kubeadm upgrade apply v1.34.1
# Upgrade kubelet and kubectl, also restart kubelet service
แ
sudo apt install kubelet=1.34.1-1.1 kubectl=1.34.1-1.1 -y
แ
sudo apt-mark hold kubelet kubectl
แ
sudo systemctl restart kubelet.service
# Check kubelet logs and uncordon the upgraded node
แ
sudo journalctl -u kubelet.service -f
แ
kb uncordon cp-01
On other node, same as control-plane but just sudo kubeadm upgrade node.
kubectl cache#
Get cluster entry.
แ
kb config view -o jsonpath='{.clusters[0].cluster.server}'
https://cp-01:6443
See cluster API groups and their objects in the kubectl cache.
แ
ls -tr1 .kube/cache/discovery/kube_cp_01_6443
flowcontrol.apiserver.k8s.io
certificates.k8s.io
authentication.k8s.io
networking.k8s.io
authorization.k8s.io
apps
storage.k8s.io
scheduling.k8s.io
rbac.authorization.k8s.io
node.k8s.io
discovery.k8s.io
apiextensions.k8s.io
admissionregistration.k8s.io
policy
events.k8s.io
coordination.k8s.io
batch
autoscaling
apiregistration.k8s.io
cilium.io
metrics.k8s.io
resource.k8s.io
servergroups.json
v1
Configure APIs access#
with certs extracted from kubeconfig file#
Extract certificates then access api-server with curl.
# Extract key and certs, also get the cluster url from kubeconfig
แ
awk '/client-key-data/{print $2}' .kube/config | base64 -d > key.pem
แ
awk '/client-certificate-data/{print $2}' .kube/config | base64 -d > cert.pem
แ
awk '/certificate-authority-data/{print $2}' .kube/config | base64 -d > cacert.pem
แ
k8s_url=$(kb config view -o jsonpath='{.clusters[0].cluster.server}')
# Request some resources
แ
curl --cert cert.pem --key key.pem --cacert cacert.pem $k8s_url/api/v1/pods
แ
curl --cert cert.pem --key key.pem --cacert cacert.pem $k8s_url/api/v1/endpoints
แ
curl --cert cert.pem --key key.pem --cacert cacert.pem $k8s_url/api/v1/nodes
# Create a pod
แ
curl --cert cert.pem --key key.pem --cacert cacert.pem $k8s_url/api/v1/namespaces/default/pods \
-XPOST -H 'Content-Type: application/json' -d@curlpod.json
curlpod.json
{
"kind": "Pod",
"apiVersion": "v1",
"metadata":{
"name": "curlpod",
"namespace": "default",
"labels": {
"name": "examplepod"
}
},
"spec": {
"containers": [{
"name": "nginx",
"image": "nginx",
"ports": [{"containerPort": 80}]
}]
}
}
แ
kb get po
NAME READY STATUS RESTARTS AGE
curlpod 1/1 Running 1 (6h36m ago) 23h
แ
b delete pods curlpod
with token#
Create a token
แ
k8s_url=$(kb config view -o jsonpath='{.clusters[0].cluster.server}')
แ
token="Authorization: Bearer $(kb create token default)"
แ
curl --header $token $k8s_url/apis -k
Check the APIs groups.
แ
curl -s --header $token $k8s_url/apis -k | jq '.groups[].name'
"apiregistration.k8s.io"
"apps"
"events.k8s.io"
"authentication.k8s.io"
"authorization.k8s.io"
"autoscaling"
"batch"
"certificates.k8s.io"
"networking.k8s.io"
"policy"
"rbac.authorization.k8s.io"
"storage.k8s.io"
"admissionregistration.k8s.io"
"apiextensions.k8s.io"
"scheduling.k8s.io"
"coordination.k8s.io"
"node.k8s.io"
"discovery.k8s.io"
"resource.k8s.io"
"flowcontrol.apiserver.k8s.io"
"cilium.io"
"metrics.k8s.io"
Attention
Connection with token is not a full APIs access.
แ
curl -s --header $token $k8s_url/api/v1/namespaces -k
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": "Failure",
"message": "namespaces is forbidden: User \"system:serviceaccount:default:default\" cannot list resource \"namespaces\" in API group \"\" at the cluster scope",
"reason": "Forbidden",
"details": {
"kind": "namespaces"
},
"code": 403
}
with kube proxy#
Create a kube proxy on a node.
แ
kb proxy --api-prefix=/
Starting to serve on 127.0.0.1:8001
Access the APIs via a local proxy (full permissionsโฆas long as your kubeconfig has full access).
แ
curl -sk http://127.0.0.1:8001/api/v1/namespaces/ | jq '.items[].metadata.name'
"cilium-secrets"
"default"
"kube-node-lease"
"kube-public"
"kube-system"
"low"