DEV Community

Ibrahim Cisse
Ibrahim Cisse

Posted on

Secure Kubernetes Persistent Storage with RBAC and Pod Security Standard (PSA)

Securing Stateful Apps in Kubernetes: MySQL with Persistent Volumes & RBAC

Kubernetes Security

Learn how to deploy stateful applications securely in Kubernetes while enforcing storage security and Pod hardening. We'll deploy MySQL with Persistent Volumes (PVs) while implementing RBAC, Pod Security Admission (PSA), and Secret management.


πŸ” Why This Matters

Stateful applications like databases require special attention in Kubernetes:

  • Data persistence: Storage must survive Pod restarts
  • Security: Sensitive credentials and storage access need protection
  • Compliance: Pods should follow security best practices by default

πŸ› οΈ Key Security Practices

  1. RBAC: Limit access to storage resources
  2. Pod Security Admission: Enforce security contexts
  3. Secrets Management: Encrypt sensitive credentials
  4. Persistent Storage: Use PVs/PVCs for data persistence

πŸš€ Deployment Walkthrough

Prerequisites

  • Minikube (with Docker driver)
  • kubectl
minikube start --driver=docker

**1. Create Dedicated Namespace**

Enter fullscreen mode Exit fullscreen mode


bash
kubectl create namespace secure-storage

2. RBAC Configuration

Role Definition (rbac-role.yaml):

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: secure-storage
  name: storage-manager-role
rules:
- apiGroups: [""]
  resources: ["pods", "persistentvolumeclaims"]
  verbs: ["get", "list", "create", "delete"]
Enter fullscreen mode Exit fullscreen mode

Role Binding (rbac-binding.yaml):

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: storage-manager-binding
  namespace: secure-storage
subjects:
- kind: ServiceAccount
  name: default
  namespace: secure-storage
roleRef:
  kind: Role
  name: storage-manager-role
  apiGroup: rbac.authorization.k8s.io
Enter fullscreen mode Exit fullscreen mode

Apply RBAC rules:

kubectl apply -f rbac-role.yaml
kubectl apply -f rbac-binding.yaml
Enter fullscreen mode Exit fullscreen mode

3. Persistent Storage Setup

Persistent Volume (pv.yaml):

apiVersion: v1
kind: PersistentVolume
metadata:
  name: secure-pv
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/mnt/data"
Enter fullscreen mode Exit fullscreen mode

Persistent Volume Claim (pvc.yaml):

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: secure-pvc
  namespace: secure-storage
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 500Mi
Enter fullscreen mode Exit fullscreen mode

Create storage resources:

kubectl apply -f pv.yaml
kubectl apply -f pvc.yaml
Enter fullscreen mode Exit fullscreen mode

4. MySQL Deployment with Secrets

Create Database Credentials:

kubectl create secret generic mysql-secret \
  --from-literal=mysql-root-password=root_password \
  --from-literal=mysql-user=user \
  --from-literal=mysql-password=user_password \
  --namespace secure-storage
Enter fullscreen mode Exit fullscreen mode

StatefulSet Configuration (mysql-statefulset.yaml):

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: secure-mysql
  namespace: secure-storage
spec:
  serviceName: "mysql-service"
  replicas: 1
  template:
    metadata:
      labels:
        app: secure-mysql
    spec:
      containers:
      - name: mysql
        image: mysql:5.7
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secret
              key: mysql-root-password
        # ... full config in GitHub repo
  volumeClaimTemplates:
  - metadata:
      name: mysql-storage
    spec:
      accessModes: ["ReadWriteOnce"]
      resources:
        requests:
          storage: 500Mi
Enter fullscreen mode Exit fullscreen mode

5. Enforce Pod Security

Apply restricted PSA policy:

kubectl label namespace secure-storage \
  pod-security.kubernetes.io/enforce=restricted \
  --overwrite
Enter fullscreen mode Exit fullscreen mode

πŸ§ͺ Security Validation

Test PSA Enforcement:

kubectl apply -f non-compliant-pod.yaml -n secure-storage
# Expected error: violates PodSecurity "restricted:latest"
Enter fullscreen mode Exit fullscreen mode

Verify RBAC Restrictions:

kubectl delete pod --namespace kube-system
# Error: User cannot delete resources in kube-system
Enter fullscreen mode Exit fullscreen mode

βœ… Key Outcomes

Secure Storage: PVs/PVCs with RBAC-controlled access

Secret Protection: Sensitive data encrypted at rest

Pod Hardening: PSA enforces security contexts

Auditability: Clear access boundaries through roles

πŸ“š Full Code & Contribution

Explore the complete implementation and contribute:

Github repository

πŸ’¬ Discussion Points

How do you handle storage security in your Kubernetes clusters?

What additional security measures do you implement for stateful workloads?

Have you tried the new PSA policies in production?

Let's discuss in the comments! πŸ‘‡

Top comments (0)