#!/usr/bin/env bash
#
# Disable the AlwaysAdmit admission plugin in kube-apiserver static pod manifest.
# Target: every control plane node
# Safe to re-run; backs up the manifest once per change and only edits when needed.
set -euo pipefail
MANIFEST="/etc/kubernetes/manifests/kube-apiserver.yaml"
BACKUP_DIR="/etc/kubernetes/manifests/backup-$(date +%Y%m%d)"
mkdir -p "$BACKUP_DIR"
if [[ ! -f "$MANIFEST" ]]; then
echo "ERROR: $MANIFEST not found. Run this script on a control plane node."
exit 1
fi
# Function: check if AlwaysAdmit is currently enabled in the manifest
has_always_admit() {
grep -E -- '--enable-admission-plugins=.*AlwaysAdmit' "$MANIFEST" >/dev/null 2>&1
}
# Function: check if AlwaysAdmit is explicitly disabled
has_always_admit_in_disable() {
grep -E -- '--disable-admission-plugins=.*AlwaysAdmit' "$MANIFEST" >/dev/null 2>&1
}
echo "Inspecting $MANIFEST for AlwaysAdmit..."
if ! has_always_admit; then
echo "AlwaysAdmit is not enabled in --enable-admission-plugins. No change needed."
else
echo "AlwaysAdmit found in --enable-admission-plugins. Patching manifest..."
cp -n "$MANIFEST" "$BACKUP_DIR/kube-apiserver.yaml.$(date +%H%M%S)"
TMP="$(mktemp)"
cp "$MANIFEST" "$TMP"
# 1. Remove AlwaysAdmit from any existing --enable-admission-plugins list
# Handles both comma-separated and single-value cases.
python3 - "$TMP" <<'PYCODE'
import re, sys, shutil, tempfile
path = sys.argv[1]
with open(path, 'r', encoding='utf-8') as f:
data = f.read()
pattern = re.compile(r'(--enable-admission-plugins=)(\S+)')
def repl(m):
prefix, val = m.groups()
plugins = val.split(',')
plugins = [p for p in plugins if p != 'AlwaysAdmit']
if not plugins:
# remove the flag entirely by returning just a comment marker
return '# ' + prefix + val
return prefix + ','.join(plugins)
new_data = pattern.sub(repl, data)
fd, tmp_out = tempfile.mkstemp()
with open(tmp_out, 'w', encoding='utf-8') as f:
f.write(new_data)
shutil.move(tmp_out, path)
PYCODE
# 2. Optionally ensure AlwaysAdmit is explicitly disabled (defensive),
# but only if it's not already present in --disable-admission-plugins.
if ! has_always_admit_in_disable; then
echo "Adding AlwaysAdmit to --disable-admission-plugins for defense-in-depth..."
# If --disable-admission-plugins exists, append; else, add a new arg line.
if grep -q -- '--disable-admission-plugins=' "$TMP"; then
python3 - "$TMP" <<'PYCODE'
import re, sys, shutil, tempfile
path = sys.argv[1]
with open(path, 'r', encoding='utf-8') as f:
data = f.read()
pattern = re.compile(r'(--disable-admission-plugins=)(\S+)')
def repl(m):
prefix, val = m.groups()
plugins = val.split(',')
if 'AlwaysAdmit' not in plugins:
plugins.append('AlwaysAdmit')
return prefix + ','.join(plugins)
new_data = pattern.sub(repl, data)
fd, tmp_out = tempfile.mkstemp()
with open(tmp_out, 'w', encoding='utf-8') as f:
f.write(new_data)
shutil.move(tmp_out, path)
PYCODE
else
# Insert a new argument line under the kube-apiserver container args
python3 - "$TMP" <<'PYCODE'
import sys, shutil, tempfile
path = sys.argv[1]
with open(path, 'r', encoding='utf-8') as f:
lines = f.readlines()
out = []
inserted = False
for i, line in enumerate(lines):
out.append(line)
if not inserted and line.lstrip().startswith('args:'):
indent = ' ' * (len(line) - len(line.lstrip()))
out.append(f"{indent}- --disable-admission-plugins=AlwaysAdmit\n")
inserted = True
if not inserted:
# Fallback: just append at end
out.append(" - --disable-admission-plugins=AlwaysAdmit\n")
fd, tmp_out = tempfile.mkstemp()
with open(tmp_out, 'w', encoding='utf-8') as f:
f.writelines(out)
shutil.move(tmp_out, path)
PYCODE
fi
fi
# Move patched temp file back into place
mv "$TMP" "$MANIFEST"
echo "Patched $MANIFEST. kube-apiserver static pod will be restarted by kubelet."
fi
echo
echo "Verification (this may take up to a minute while kube-apiserver restarts)..."
# Wait until kube-apiserver process is present and does not reference AlwaysAdmit in enable flag
for i in {1..30}; do
if /bin/ps -ef | grep kube-apiserver | grep -v grep >/dev/null 2>&1; then
if ! /bin/ps -ef | grep kube-apiserver | grep -v grep | grep -E -- '--enable-admission-plugins=.*AlwaysAdmit' >/dev/null 2>&1; then
echo "PASS: kube-apiserver is running and AlwaysAdmit is not enabled."
exit 0
fi
fi
sleep 2
done
echo "WARNING: kube-apiserver process still shows AlwaysAdmit in --enable-admission-plugins."
echo "Inspect current flags with:"
echo "/bin/ps -ef | grep kube-apiserver | grep -v grep"
exit 1