Configure Pod Security Standards with baseline and restricted profiles, deploy OPA Gatekeeper admission controller with custom policies, and implement ValidatingAdmissionWebhooks for comprehensive security enforcement in production Kubernetes clusters.
Prerequisites
- Existing Kubernetes cluster with admin access
- kubectl configured
- Basic understanding of Kubernetes RBAC
- Prometheus monitoring stack (optional for alerting)
What this solves
Kubernetes Pod Security Standards provide a built-in framework for enforcing security policies at the namespace level, replacing deprecated Pod Security Policies. This tutorial shows you how to implement Pod Security Standards with baseline and restricted profiles, deploy OPA Gatekeeper for custom policy enforcement, and configure ValidatingAdmissionWebhooks to prevent insecure workloads from running in your cluster. You'll also set up comprehensive monitoring and alerting for security violations to maintain compliance in production environments.
Step-by-step configuration
Update system and install dependencies
Start by updating your system and installing necessary tools for Kubernetes security management.
sudo apt update && sudo apt upgrade -y
sudo apt install -y curl wget git jq
Install kubectl and helm
Install kubectl for cluster management and Helm for package management.
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
sudo apt update
sudo apt install -y helm
Create namespace labels for Pod Security Standards
Configure namespaces with appropriate Pod Security Standard labels for baseline and restricted security profiles.
# Create test namespaces
kubectl create namespace baseline-ns
kubectl create namespace restricted-ns
kubectl create namespace privileged-ns
Label namespaces with Pod Security Standards
kubectl label namespace baseline-ns \
pod-security.kubernetes.io/enforce=baseline \
pod-security.kubernetes.io/audit=baseline \
pod-security.kubernetes.io/warn=baseline
kubectl label namespace restricted-ns \
pod-security.kubernetes.io/enforce=restricted \
pod-security.kubernetes.io/audit=restricted \
pod-security.kubernetes.io/warn=restricted
kubectl label namespace privileged-ns \
pod-security.kubernetes.io/enforce=privileged \
pod-security.kubernetes.io/audit=privileged \
pod-security.kubernetes.io/warn=privileged
Configure cluster-wide Pod Security Standards
Set default Pod Security Standards at the cluster level by modifying the kube-apiserver configuration.
spec:
containers:
- command:
- kube-apiserver
- --admission-control-config-file=/etc/kubernetes/admission-control.yaml
- --feature-gates=PodSecurity=true
# Add other existing flags here
volumeMounts:
- mountPath: /etc/kubernetes/admission-control.yaml
name: admission-control-config
readOnly: true
volumes:
- hostPath:
path: /etc/kubernetes/admission-control.yaml
type: File
name: admission-control-config
Create admission control configuration
Define the admission control configuration file for Pod Security Standards enforcement.
apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: PodSecurity
configuration:
apiVersion: pod-security.admission.config.k8s.io/v1beta1
kind: PodSecurityConfiguration
defaults:
enforce: "baseline"
enforce-version: "latest"
audit: "baseline"
audit-version: "latest"
warn: "baseline"
warn-version: "latest"
exemptions:
usernames: []
runtimeClasses: []
namespaces: ["kube-system", "kube-public", "kube-node-lease"]
Install OPA Gatekeeper
Deploy OPA Gatekeeper admission controller for custom policy enforcement using Helm.
helm repo add gatekeeper https://open-policy-agent.github.io/gatekeeper/charts
helm repo update
Create gatekeeper-system namespace
kubectl create namespace gatekeeper-system
Install Gatekeeper with audit enabled
helm install gatekeeper gatekeeper/gatekeeper \
--namespace gatekeeper-system \
--set audit.replicas=2 \
--set replicas=3 \
--set audit.auditInterval=60 \
--set audit.logLevel=INFO \
--set logLevel=INFO
Create constraint templates for security policies
Define constraint templates for common security policies like required security contexts and resource limits.
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: k8srequiredsecuritycontext
spec:
crd:
spec:
names:
kind: K8sRequiredSecurityContext
validation:
properties:
runAsNonRoot:
type: boolean
runAsUser:
type: integer
fsGroup:
type: integer
allowPrivilegeEscalation:
type: boolean
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8srequiredsecuritycontext
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
not container.securityContext.runAsNonRoot
msg := "Container must run as non-root user"
}
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
container.securityContext.allowPrivilegeEscalation != false
msg := "Container must not allow privilege escalation"
}
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
not container.securityContext.runAsUser
msg := "Container must specify runAsUser"
}
Create resource limits constraint template
Define a constraint template to enforce resource limits on all containers.
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: k8srequiredresourcelimits
spec:
crd:
spec:
names:
kind: K8sRequiredResourceLimits
validation:
properties:
limits:
type: array
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8srequiredresourcelimits
missing_limits[limit] {
required := input.parameters.limits
limit := required[_]
not input.review.object.spec.containers[_].resources.limits[limit]
}
violation[{"msg": msg}] {
limit := missing_limits[_]
msg := sprintf("Container must specify resource limit: %v", [limit])
}
Apply constraint templates
Deploy the constraint templates to your cluster.
kubectl apply -f required-security-context-template.yaml
kubectl apply -f resource-limits-template.yaml
Wait for templates to be established
kubectl wait --for=condition=Established crd/k8srequiredsecuritycontext.templates.gatekeeper.sh --timeout=60s
kubectl wait --for=condition=Established crd/k8srequiredresourcelimits.templates.gatekeeper.sh --timeout=60s
Create security context constraints
Apply constraints using the templates to enforce security context requirements in specific namespaces.
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredSecurityContext
metadata:
name: must-have-security-context
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
excludedNamespaces: ["kube-system", "gatekeeper-system", "kube-public"]
parameters:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 2000
allowPrivilegeEscalation: false
Create resource limits constraints
Apply constraints to enforce resource limits on all containers.
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredResourceLimits
metadata:
name: must-have-resource-limits
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
excludedNamespaces: ["kube-system", "gatekeeper-system", "kube-public"]
parameters:
limits: ["memory", "cpu"]
Apply all constraints
Deploy the constraints to enforce security policies cluster-wide.
kubectl apply -f security-context-constraint.yaml
kubectl apply -f resource-limits-constraint.yaml
Check constraint status
kubectl get constraints
kubectl describe K8sRequiredSecurityContext must-have-security-context
Create ValidatingAdmissionWebhook
Implement a custom ValidatingAdmissionWebhook for additional security checks beyond OPA Gatekeeper.
apiVersion: apps/v1
kind: Deployment
metadata:
name: security-webhook
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: security-webhook
template:
metadata:
labels:
app: security-webhook
spec:
containers:
- name: webhook
image: nginx:1.24
ports:
- containerPort: 8443
volumeMounts:
- name: certs
mountPath: /etc/certs
readOnly: true
securityContext:
runAsNonRoot: true
runAsUser: 1000
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
volumes:
- name: certs
secret:
secretName: webhook-certs
Create webhook certificates
Generate TLS certificates for the ValidatingAdmissionWebhook using OpenSSL.
# Create certificate authority
openssl genrsa -out ca-key.pem 2048
openssl req -new -x509 -key ca-key.pem -out ca-cert.pem -days 365 -subj "/CN=webhook-ca"
Create webhook certificate
openssl genrsa -out webhook-key.pem 2048
openssl req -new -key webhook-key.pem -out webhook-csr.pem -subj "/CN=security-webhook.default.svc"
openssl x509 -req -in webhook-csr.pem -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out webhook-cert.pem -days 365
Create secret with certificates
kubectl create secret tls webhook-certs \
--cert=webhook-cert.pem \
--key=webhook-key.pem
Configure ValidatingAdmissionWebhook
Create the ValidatingAdmissionWebhook configuration to intercept pod creation requests.
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionWebhook
metadata:
name: security-validator
webhooks:
- name: pod-security-validator.example.com
clientConfig:
service:
name: security-webhook-service
namespace: default
path: "/validate"
caBundle: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t... # Base64 encoded CA cert
rules:
- operations: ["CREATE", "UPDATE"]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
admissionReviewVersions: ["v1", "v1beta1"]
sideEffects: None
failurePolicy: Fail
Set up monitoring and alerting
Configure Prometheus monitoring for Pod Security Standards and Gatekeeper violations. This requires an existing Prometheus setup.
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: gatekeeper-audit
namespace: gatekeeper-system
spec:
selector:
matchLabels:
gatekeeper.sh/operation: audit
endpoints:
- port: metrics
interval: 30s
path: /metrics
---
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: pod-security-alerts
namespace: gatekeeper-system
spec:
groups:
- name: gatekeeper.rules
rules:
- alert: GatekeeperViolation
expr: increase(gatekeeper_violations_total[5m]) > 0
for: 0m
labels:
severity: warning
annotations:
summary: "Gatekeeper policy violation detected"
description: "Constraint {{ $labels.violation_kind }} has {{ $value }} violations in the last 5 minutes"
- alert: HighGatekeeperViolationRate
expr: rate(gatekeeper_violations_total[5m]) > 0.1
for: 5m
labels:
severity: critical
annotations:
summary: "High rate of Gatekeeper violations"
description: "Gatekeeper violation rate is {{ $value }} violations per second"
Create audit logging configuration
Configure audit logging to track Pod Security Standards violations and admission webhook activity.
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata
namespaces: ["default", "baseline-ns", "restricted-ns"]
resources:
- group: ""
resources: ["pods"]
omitStages:
- RequestReceived
- level: Request
users: ["system:serviceaccount:gatekeeper-system:gatekeeper-admin"]
resources:
- group: "templates.gatekeeper.sh"
- group: "constraints.gatekeeper.sh"
- level: Violation
annotationAuditLevels:
pod-security.kubernetes.io/enforce-policy: "Request"
pod-security.kubernetes.io/audit-policy: "Metadata"
Test your security policies
Test Pod Security Standards enforcement
Create test pods to verify that Pod Security Standards are properly enforced.
apiVersion: v1
kind: Pod
metadata:
name: insecure-pod
namespace: restricted-ns
spec:
containers:
- name: test
image: nginx:1.24
securityContext:
runAsUser: 0 # This should be rejected in restricted namespace
# This should fail in restricted namespace
kubectl apply -f test-insecure-pod.yaml
Create a compliant pod
cat <
Verify your setup
# Check Pod Security Standards labels
kubectl get namespaces --show-labels | grep pod-security
Verify Gatekeeper installation
kubectl get pods -n gatekeeper-system
kubectl get constrainttemplates
kubectl get constraints
Check constraint violations
kubectl get K8sRequiredSecurityContext must-have-security-context -o yaml
kubectl get K8sRequiredResourceLimits must-have-resource-limits -o yaml
Review audit logs
sudo journalctl -u kubelet | grep -i "pod-security"
Check Gatekeeper metrics
kubectl port-forward -n gatekeeper-system svc/gatekeeper-webhook-service 8443:443 &
curl -k https://localhost:8443/metrics
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| Pod creation fails with "violates PodSecurity" | Pod doesn't meet security standard requirements | Add proper securityContext with runAsNonRoot, runAsUser, and drop capabilities |
| Gatekeeper constraints not enforcing | Template not properly created or constraint misconfigured | Check kubectl get constrainttemplates and verify Rego policy syntax |
| ValidatingAdmissionWebhook fails | Certificate issues or webhook service unreachable | Verify certificate validity and service endpoints with kubectl get svc |
| High violation rates in monitoring | Existing workloads don't comply with new policies | Gradually migrate workloads or use "warn" mode before "enforce" |
| System namespaces affected by policies | Constraints not properly excluding system namespaces | Add exclusions in constraint spec for kube-system, gatekeeper-system |
Next steps
- Implement Kubernetes network policies with Calico CNI and OPA Gatekeeper for security enforcement
- Implement Kubernetes resource quotas and limits for namespace isolation and workload management
- Configure OpenTelemetry sampling strategies for high-traffic applications
- Implement Kubernetes RBAC with service accounts and role-based access control
- Configure Kubernetes secrets management with External Secrets Operator and HashiCorp Vault
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Global variables
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
TEMP_DIR=""
KUBECTL_VERSION=""
HELM_VERSION="v3.13.2"
# Usage function
usage() {
echo "Usage: $0 [OPTIONS]"
echo "Install Kubernetes Pod Security Standards and admission controllers"
echo ""
echo "Options:"
echo " -h, --help Show this help message"
echo " -k, --kubectl-version Specify kubectl version (default: latest stable)"
echo " --skip-gatekeeper Skip OPA Gatekeeper installation"
echo ""
echo "Examples:"
echo " $0"
echo " $0 --kubectl-version v1.28.4"
echo " $0 --skip-gatekeeper"
}
# Cleanup function
cleanup() {
if [[ -n "$TEMP_DIR" && -d "$TEMP_DIR" ]]; then
rm -rf "$TEMP_DIR"
fi
}
# Error handler
error_handler() {
echo -e "${RED}[ERROR] Script failed on line $1${NC}" >&2
cleanup
exit 1
}
# Set error trap
trap 'error_handler $LINENO' ERR
trap cleanup EXIT
# Logging functions
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
log_step() {
echo -e "${BLUE}$1${NC}"
}
# Parse arguments
SKIP_GATEKEEPER=false
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
usage
exit 0
;;
-k|--kubectl-version)
KUBECTL_VERSION="$2"
shift 2
;;
--skip-gatekeeper)
SKIP_GATEKEEPER=true
shift
;;
*)
log_error "Unknown option: $1"
usage
exit 1
;;
esac
done
# Check if running as root or with sudo
check_privileges() {
if [[ $EUID -ne 0 ]] && ! sudo -n true 2>/dev/null; then
log_error "This script requires root privileges or sudo access"
exit 1
fi
}
# Detect distribution
detect_distro() {
if [[ ! -f /etc/os-release ]]; then
log_error "Cannot detect distribution - /etc/os-release not found"
exit 1
fi
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_UPDATE="apt update"
PKG_INSTALL="apt install -y"
PKG_UPGRADE="apt upgrade -y"
;;
almalinux|rocky|centos|rhel|ol|fedora)
PKG_MGR="dnf"
PKG_UPDATE="dnf check-update || true"
PKG_INSTALL="dnf install -y"
PKG_UPGRADE="dnf upgrade -y"
;;
amzn)
PKG_MGR="yum"
PKG_UPDATE="yum check-update || true"
PKG_INSTALL="yum install -y"
PKG_UPGRADE="yum upgrade -y"
;;
*)
log_error "Unsupported distribution: $ID"
exit 1
;;
esac
log_info "Detected distribution: $ID $VERSION_ID"
}
# Update system and install dependencies
install_dependencies() {
log_step "[1/8] Updating system and installing dependencies..."
sudo $PKG_UPDATE
sudo $PKG_UPGRADE
sudo $PKG_INSTALL curl wget git jq
log_info "System dependencies installed successfully"
}
# Install kubectl
install_kubectl() {
log_step "[2/8] Installing kubectl..."
# Get kubectl version if not specified
if [[ -z "$KUBECTL_VERSION" ]]; then
KUBECTL_VERSION=$(curl -L -s https://dl.k8s.io/release/stable.txt)
log_info "Using kubectl version: $KUBECTL_VERSION"
fi
# Download kubectl
TEMP_DIR=$(mktemp -d)
cd "$TEMP_DIR"
curl -LO "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/amd64/kubectl"
curl -LO "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/amd64/kubectl.sha256"
# Verify checksum
echo "$(cat kubectl.sha256) kubectl" | sha256sum --check
# Install kubectl
chmod 755 kubectl
sudo install -o root -g root -m 755 kubectl /usr/local/bin/kubectl
log_info "kubectl installed successfully"
}
# Install Helm
install_helm() {
log_step "[3/8] Installing Helm..."
case "$PKG_MGR" in
apt)
curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
sudo $PKG_UPDATE
sudo $PKG_INSTALL helm
;;
dnf|yum)
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh
;;
esac
log_info "Helm installed successfully"
}
# Create namespaces and configure Pod Security Standards
configure_pod_security_namespaces() {
log_step "[4/8] Configuring Pod Security Standards namespaces..."
# Create test namespaces
kubectl create namespace baseline-ns --dry-run=client -o yaml | kubectl apply -f -
kubectl create namespace restricted-ns --dry-run=client -o yaml | kubectl apply -f -
kubectl create namespace privileged-ns --dry-run=client -o yaml | kubectl apply -f -
# Label namespaces with Pod Security Standards
kubectl label namespace baseline-ns \
pod-security.kubernetes.io/enforce=baseline \
pod-security.kubernetes.io/audit=baseline \
pod-security.kubernetes.io/warn=baseline \
--overwrite
kubectl label namespace restricted-ns \
pod-security.kubernetes.io/enforce=restricted \
pod-security.kubernetes.io/audit=restricted \
pod-security.kubernetes.io/warn=restricted \
--overwrite
kubectl label namespace privileged-ns \
pod-security.kubernetes.io/enforce=privileged \
pod-security.kubernetes.io/audit=privileged \
pod-security.kubernetes.io/warn=privileged \
--overwrite
log_info "Pod Security Standards namespaces configured"
}
# Create admission control configuration
create_admission_config() {
log_step "[5/8] Creating admission control configuration..."
# Create admission control configuration
sudo mkdir -p /etc/kubernetes
sudo tee /etc/kubernetes/admission-control.yaml > /dev/null <<EOF
apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: PodSecurity
configuration:
apiVersion: pod-security.admission.config.k8s.io/v1beta1
kind: PodSecurityConfiguration
defaults:
enforce: "baseline"
enforce-version: "latest"
audit: "baseline"
audit-version: "latest"
warn: "baseline"
warn-version: "latest"
exemptions:
usernames: []
runtimeClasses: []
namespaces: ["kube-system", "kube-public", "kube-node-lease"]
EOF
sudo chmod 644 /etc/kubernetes/admission-control.yaml
log_info "Admission control configuration created"
}
# Install OPA Gatekeeper
install_gatekeeper() {
if [[ "$SKIP_GATEKEEPER" == "true" ]]; then
log_step "[6/8] Skipping OPA Gatekeeper installation..."
return 0
fi
log_step "[6/8] Installing OPA Gatekeeper..."
# Add Gatekeeper Helm repository
helm repo add gatekeeper https://open-policy-agent.github.io/gatekeeper/charts
helm repo update
# Install Gatekeeper
helm upgrade --install gatekeeper gatekeeper/gatekeeper \
--namespace gatekeeper-system \
--create-namespace \
--set enableExternalData=false \
--set controllerManager.exemptNamespaces="{gatekeeper-system,kube-system}" \
--wait
log_info "OPA Gatekeeper installed successfully"
}
# Create sample constraint templates and constraints
create_sample_policies() {
if [[ "$SKIP_GATEKEEPER" == "true" ]]; then
log_step "[7/8] Skipping policy creation..."
return 0
fi
log_step "[7/8] Creating sample security policies..."
# Wait for Gatekeeper to be ready
kubectl wait --for=condition=Ready pod -l control-plane=controller-manager -n gatekeeper-system --timeout=300s
# Create required labels constraint template
kubectl apply -f - <<EOF
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: k8srequiredlabels
spec:
crd:
spec:
names:
kind: K8sRequiredLabels
validation:
type: object
properties:
labels:
type: array
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8srequiredlabels
violation[{"msg": msg}] {
required := input.parameters.labels
provided := input.review.object.metadata.labels
missing := required[_]
not provided[missing]
msg := sprintf("Missing required label: %v", [missing])
}
EOF
# Create constraint for required labels
kubectl apply -f - <<EOF
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
name: must-have-environment
spec:
match:
kinds:
- apiGroups: ["apps"]
kinds: ["Deployment"]
namespaces: ["restricted-ns", "baseline-ns"]
parameters:
labels: ["environment"]
EOF
log_info "Sample security policies created"
}
# Verify installation
verify_installation() {
log_step "[8/8] Verifying installation..."
# Check kubectl
if ! kubectl version --client &>/dev/null; then
log_error "kubectl verification failed"
return 1
fi
# Check Helm
if ! helm version &>/dev/null; then
log_error "Helm verification failed"
return 1
fi
# Check cluster connectivity
if ! kubectl cluster-info &>/dev/null; then
log_warn "Cannot connect to Kubernetes cluster - ensure kubectl is configured"
else
# Check namespaces
for ns in baseline-ns restricted-ns privileged-ns; do
if ! kubectl get namespace "$ns" &>/dev/null; then
log_error "Namespace $ns not found"
return 1
fi
done
# Check Gatekeeper if installed
if [[ "$SKIP_GATEKEEPER" == "false" ]]; then
if ! kubectl get deployment gatekeeper-controller-manager -n gatekeeper-system &>/dev/null; then
log_error "Gatekeeper controller not found"
return 1
fi
fi
log_info "Cluster components verified successfully"
fi
log_info "Installation completed successfully!"
}
# Main execution
main() {
log_info "Starting Kubernetes Pod Security Standards installation"
check_privileges
detect_distro
install_dependencies
install_kubectl
install_helm
configure_pod_security_namespaces
create_admission_config
install_gatekeeper
create_sample_policies
verify_installation
echo ""
log_info "Installation complete! Next steps:"
echo "1. Configure your kube-apiserver to use the admission control config at /etc/kubernetes/admission-control.yaml"
echo "2. Test Pod Security Standards by deploying workloads to the configured namespaces"
echo "3. Create additional Gatekeeper policies as needed for your security requirements"
}
# Run main function
main "$@"
Review the script before running. Execute with: bash install.sh