Enhance entrypoint and deployment configurations for Kubernetes management pod
All checks were successful
Build k8s-mgmt-pod image / Build & Push (push) Successful in 44s

- Add K8S_RUNTIME_ENV_PROFILE and KUBERNETES_SECRETS_DIR variables in entrypoint.sh
- Implement service account kubeconfig installation and environment variable persistence
- Update deployment.yaml to include fsGroup and fsGroupChangePolicy in securityContext
- Modify container ports and resource limits for better management
This commit is contained in:
Michael Trip 2026-06-23 16:37:14 +02:00
parent 795d3844dc
commit 41d4b36345
2 changed files with 117 additions and 10 deletions

View file

@ -4,12 +4,14 @@ set -Eeuo pipefail
STATE_DIR="/var/lib/k8s-mgmt-pod"
GENERATED_PASSWORDS_FILE="${STATE_DIR}/generated-passwords.env"
SSH_DYNAMIC_CONFIG="/etc/ssh/sshd_config.d/20-k8s-mgmt-pod-auth.conf"
K8S_RUNTIME_ENV_PROFILE="/etc/profile.d/30-kubernetes-runtime-env.sh"
PASSWORD_AUTH_REQUIRED=0
SSHD_PID=""
WEBSSH2_PID=""
NGINX_PID=""
BOOTSTRAP_KUBECONFIG="${BOOTSTRAP_KUBECONFIG:-/bootstrap/kubeconfig/config}"
ENABLE_BOOTSTRAP_KUBECONFIG="${ENABLE_BOOTSTRAP_KUBECONFIG:-false}"
KUBERNETES_SECRETS_DIR="${KUBERNETES_SECRETS_DIR:-/var/run/kubernetes.io}"
SSH_PORT="${SSH_PORT:-2222}"
if [[ -z "${WEBSSH2_SSH_PORT:-}" ]]; then
@ -96,12 +98,84 @@ write_authorized_keys() {
install_kubeconfig_for_user() {
local username="$1"
local source_kubeconfig="$2"
local home_dir="/home/${username}"
local kube_dir="${home_dir}/.kube"
local kube_config="${kube_dir}/config"
mkdir -p "${kube_dir}"
install -m 0600 -o "${username}" -g "${username}" "${BOOTSTRAP_KUBECONFIG}" "${kube_config}"
install -m 0600 -o "${username}" -g "${username}" "${source_kubeconfig}" "${kube_config}"
}
resolve_kubernetes_secrets_dir() {
local configured_dir="${KUBERNETES_SECRETS_DIR}"
local fallback_dir="/var/run/secrets/kubernetes.io/serviceaccount"
if [[ -f "${configured_dir}/token" && -f "${configured_dir}/ca.crt" && -f "${configured_dir}/namespace" ]]; then
printf '%s\n' "${configured_dir}"
return 0
fi
if [[ "${configured_dir}" != "${fallback_dir}" ]] \
&& [[ -f "${fallback_dir}/token" && -f "${fallback_dir}/ca.crt" && -f "${fallback_dir}/namespace" ]]; then
printf '%s\n' "${fallback_dir}"
return 0
fi
return 1
}
install_serviceaccount_kubeconfig() {
local sa_dir=""
local token_file=""
local ca_file=""
local namespace_file=""
local namespace=""
local kubernetes_host="${KUBERNETES_SERVICE_HOST:-kubernetes.default.svc}"
local kubernetes_port="${KUBERNETES_SERVICE_PORT_HTTPS:-443}"
local server=""
local generated_kubeconfig="${STATE_DIR}/incluster.kubeconfig"
if ! sa_dir="$(resolve_kubernetes_secrets_dir)"; then
log "Skipping in-cluster kubeconfig generation because no service-account mount was found in ${KUBERNETES_SECRETS_DIR} or /var/run/secrets/kubernetes.io/serviceaccount."
return
fi
token_file="${sa_dir}/token"
ca_file="${sa_dir}/ca.crt"
namespace_file="${sa_dir}/namespace"
namespace="$(tr -d '\n' < "${namespace_file}")"
if [[ -z "${namespace}" ]]; then
namespace="default"
fi
server="https://${kubernetes_host}:${kubernetes_port}"
cat > "${generated_kubeconfig}" <<EOF
apiVersion: v1
kind: Config
clusters:
- name: in-cluster
cluster:
certificate-authority: ${ca_file}
server: ${server}
contexts:
- name: in-cluster
context:
cluster: in-cluster
user: service-account
namespace: ${namespace}
current-context: in-cluster
users:
- name: service-account
user:
tokenFile: ${token_file}
EOF
chmod 0600 "${generated_kubeconfig}"
install_kubeconfig_for_user admin "${generated_kubeconfig}"
install_kubeconfig_for_user user "${generated_kubeconfig}"
log "Installed generated in-cluster kubeconfig for admin and user from ${sa_dir}."
}
install_bootstrap_kubeconfig() {
@ -114,8 +188,8 @@ install_bootstrap_kubeconfig() {
return
fi
install_kubeconfig_for_user admin
install_kubeconfig_for_user user
install_kubeconfig_for_user admin "${BOOTSTRAP_KUBECONFIG}"
install_kubeconfig_for_user user "${BOOTSTRAP_KUBECONFIG}"
log "Installed mounted kubeconfig for admin and user."
}
@ -199,10 +273,27 @@ KbdInteractiveAuthentication ${keyboard_interactive_value}
EOF
}
persist_kubernetes_login_env() {
local kubernetes_host="${KUBERNETES_SERVICE_HOST:-kubernetes.default.svc}"
local kubernetes_https_port="${KUBERNETES_SERVICE_PORT_HTTPS:-443}"
local kubernetes_port="${KUBERNETES_SERVICE_PORT:-${kubernetes_https_port}}"
cat > "${K8S_RUNTIME_ENV_PROFILE}" <<EOF
# Generated at container start so SSH login shells see Kubernetes API environment values.
export KUBERNETES_SERVICE_HOST='${kubernetes_host}'
export KUBERNETES_SERVICE_PORT='${kubernetes_port}'
export KUBERNETES_SERVICE_PORT_HTTPS='${kubernetes_https_port}'
EOF
chmod 0644 "${K8S_RUNTIME_ENV_PROFILE}"
}
prepare_runtime() {
mkdir -p /var/run/sshd
ensure_host_keys
install_serviceaccount_kubeconfig
install_bootstrap_kubeconfig
persist_kubernetes_login_env
configure_user_auth admin ADMIN_SSH_PUBKEY ADMIN_PASSWORD
configure_user_auth user USER_SSH_PUBKEY USER_PASSWORD
render_sshd_auth_config

View file

@ -16,20 +16,24 @@ spec:
spec:
serviceAccountName: k8s-mgmt-pod
automountServiceAccountToken: true
securityContext:
seccompProfile:
type: RuntimeDefault
fsGroup: 1000
fsGroupChangePolicy: OnRootMismatch
containers:
- name: k8s-mgmt-pod
image: git.alcatrash.net/michael/k8s-mgmt-pod/k8s-mgmt-pod:latest
imagePullPolicy: Always
ports:
- name: ssh
containerPort: 2222
protocol: TCP
- name: webssh
containerPort: 3000
protocol: TCP
env:
- name: ADMIN_SSH_PUBKEY
valueFrom:
@ -55,6 +59,7 @@ spec:
name: k8s-mgmt-pod-auth
key: USER_PASSWORD
optional: true
resources:
requests:
cpu: 100m
@ -62,30 +67,41 @@ spec:
limits:
cpu: 500m
memory: 512Mi
readinessProbe:
tcpSocket:
port: 2222
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 2222
initialDelaySeconds: 15
periodSeconds: 20
volumeMounts:
- name: state
mountPath: /var/lib/k8s-mgmt-pod
securityContext:
# sshd still runs as root to switch to authenticated user sessions.
# Binding uses a non-privileged port, so NET_BIND_SERVICE is not required.
runAsUser: 0
runAsGroup: 0
runAsNonRoot: false
allowPrivilegeEscalation: false
readOnlyRootFilesystem: false
capabilities:
drop: ["ALL"]
add: ["CHOWN", "DAC_OVERRIDE", "FOWNER", "SETGID", "SETUID", "SYS_CHROOT"]
drop:
- ALL
add:
- AUDIT_WRITE
- CHOWN
- DAC_OVERRIDE
- FOWNER
- SETGID
- SETUID
- SYS_CHROOT
volumes:
- name: state
emptyDir: {}