Project Status: Initial development
login-protector provides a feature to prevent the reboot of Pods that are logged in within a Kubernetes cluster.
In Kubernetes clusters, Pods are sometimes used as bastion servers for operations. When these Pods are rebooted, the logged-in session is disconnected, causing operational interruptions. login-protector prevents this by ensuring that logged-in Pods are not rebooted.
login-protector checks if the processes in the target Pod are using TTY to determine if the Pod is logged in.
If a Pod is found to be logged in, login-protector generates a PodDisruptionBudget with maxUnavailable: 0
to prevent the Pod from being evicted.
This ensures that the Pod is not rebooted during maintenance or upgrades when a Kubernetes Node is drained.
Additionally, login-protector can prevent the container image or PodTemplate of logged-in Pods from being updated. To achieve this, the Pods targeted by login-protector must be created by a StatefulSet with the updateStrategy set to OnDelete.
To avoid issues with long-term Pod logins blocking necessary Node reboots or Pod updates, it is advisable to set up alert checks for prolonged logins. Furthermore, the PodDisruptionBudget can be disabled by adding an annotation to force a Pod reboot.
Run the following command to install login-protector:
curl -fsL https://github.com/cybozu-go/login-protector/releases/latest/download/install.yaml | kubectl apply -f -
login-protector targets only StatefulSets. The StatefulSet should be configured as follows:
- Add the label
login-protector.cybozu.io/protect: "true"
to the StatefulSet. - Add the sidecar container
ghcr.io/cybozu-go/local-session-tracker
and specifyshareProcessNamespace: true
. - Set the
updateStrategy
totype: OnDelete
.
Example manifest:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: target-sts
labels:
login-protector.cybozu.io/protect: "true"
spec:
replicas: 1
selector:
matchLabels:
name: target-sts
serviceName: target-sts
template:
metadata:
labels:
name: target-sts
spec:
containers:
- name: main
image: ghcr.io/cybozu/ubuntu:22.04
imagePullPolicy: IfNotPresent
command: [ "sleep", "infinity" ]
- name: local-session-tracker
image: ghcr.io/cybozu-go/local-session-tracker:latest
imagePullPolicy: IfNotPresent
ports:
- name: sidecar
containerPort: 8080
shareProcessNamespace: true
updateStrategy:
type: OnDelete
Annotations can be used to modify the behavior of login-protector for the target StatefulSet:
login-protector.cybozu.io/tracker-name
: Specify the name of the local-session-tracker sidecar container. Default is "local-session-tracker".login-protector.cybozu.io/tracker-port
: Specify the port of the local-session-tracker sidecar container. Default is "8080".
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: target-sts
labels:
login-protector.cybozu.io/protect: "true"
annotations:
login-protector.cybozu.io/tracker-name: sidecar
login-protector.cybozu.io/tracker-port: "9090"
spec:
replicas: 1
selector:
matchLabels:
name: target-sts
serviceName: target-sts
template:
metadata:
labels:
name: target-sts
spec:
containers:
- name: main
image: ghcr.io/cybozu/ubuntu:22.04
imagePullPolicy: IfNotPresent
command: [ "sleep", "infinity" ]
- name: sidecar
image: ghcr.io/cybozu-go/local-session-tracker:latest
imagePullPolicy: IfNotPresent
ports:
- name: sidecar
containerPort: 9090
shareProcessNamespace: true
updateStrategy:
type: OnDelete
The following annotation can be used to disable the creation of a PodDisruptionBudget for the target Pod:
login-protector.cybozu.io/no-pdb
: Set to "true" to prevent the creation of a PodDisruptionBudget.
If you want to force a Pod reboot, you can add the annotation to the target Pod:
$ kubectl annotate pod target-sts-0 login-protector.cybozu.io/no-pdb=true
login-protector provides the following metrics:
login_protector_pod_pending_updates
: The number of Pods that have pending updates.login_protector_pod_protecting
: The number of Pods that are being protected.login_protector_watcher_errors_total
: The number of errors that occurred in the Pod watcher.
Install Golang, Docker, Make, and aqua beforehand.
Tilt is a local development tool that makes it easy to develop applications for Kubernetes. You can use Tilt to automatically build and deploy login-protector.
# Install necessary tools.
make setup
# Start a test Kubernetes cluster.
make start-dev
# Start development with Tilt.
tilt up
Access the Tilt dashboard at http://localhost:10350. Changes to the source code or manifests will be automatically reflected.
If you don't want to use Tilt, you can use the following commands:
# Install necessary tools.
make setup
# Start a test Kubernetes cluster.
make start-kind
# Load container images.
make load-image
# Deploy login-protector.
make deploy
After deploying login-protector, you can test it with the following steps:
Deploy a test StatefulSet with the following command:
kubectl apply -f ./test/testdata/statefulset.yaml
Log in to the test Pod with the following command:
kubectl exec -it target-sts-0 bash
To evict the test Pod, you can use kubectl-evict. Install kubectl-evict with the following command:
go install github.com/ueokande/kubectl-evict@latest
Then, evict the test Pod with the following command:
kubectl evict target-sts-0
The test Pod should not be evicted because it is logged in.
Update the container image of the test Pod with the following command:
kubectl set image sts/target-sts main=ghcr.io/cybozu/ubuntu-debug:22.04
The container image of the test Pod should not be updated because it is logged in.
Log out of the test Pod with the following command:
exit
The container image of the test Pod should be updated because it is no longer logged in.
Apache License 2.0