Belajar Kubernetes - Episode 37 - Pengenalan dan Penjelasan Pod Security Context

Belajar Kubernetes - Episode 37 - Pengenalan dan Penjelasan Pod Security Context

Di episode ini kita akan coba bahas Kubernetes Pod Security Context untuk control Pod dan container security setting. Kita akan mempelajari bagaimana run Pod sebagai non-root user, set capability, enforce read-only filesystem, dan best practice untuk Pod security.

Arman Dwi Pangestu
Arman Dwi PangestuApril 12, 2026
0 views
7 min read

Pendahuluan

Catatan

Untuk kalian yang ingin membaca episode sebelumnya, bisa click thumbnail episode 36 di bawah ini

Episode 36Episode 36

Di episode sebelumnya, kita menjelajahi NetworkPolicy, yang mengontrol lalu lintas jaringan antara Pod dan jaringan eksternal. Sekarang kita akan mendalami Pod Security Context, yang mengontrol pengaturan keamanan untuk Pod dan container.

Catatan: Disini saya akan menggunakan Kubernetes Cluster yang di install melalui K3s.

Pod Security Context mendefinisikan pengaturan terkait privilege dan access control untuk Pod atau container. Ini mengontrol aspek seperti user ID, group ID, izin filesystem, dan Linux capability. Dengan mengonfigurasi security context dengan benar, Anda dapat secara signifikan mengurangi attack surface aplikasi Anda.

Memahami Pod Security Context

Pod Security Context adalah serangkaian pengaturan terkait keamanan yang berlaku untuk Pod dan container. Ini beroperasi pada tingkat kernel Linux dan mengontrol bagaimana container berinteraksi dengan sistem host.

Mengapa Pod Security Context Penting

1. Principle of Least Privilege

Jalankan container dengan izin minimal yang diperlukan. Jangan jalankan sebagai root kecuali benar-benar diperlukan.

2. Prevent Privilege Escalation

Batasi container dari mendapatkan privilege tambahan.

3. Enforce Read-Only Filesystem

Cegah container dari memodifikasi filesystem.

4. Control Linux Capability

Berikan hanya Linux capability yang diperlukan daripada semua root capability.

5. Compliance and Security Standards

Penuhi persyaratan compliance keamanan seperti PCI-DSS, HIPAA, dan SOC 2.

Pod-Level vs Container-Level Security Context

Security context dapat diterapkan pada dua level:

Pod-Level - Berlaku untuk semua container di Pod Container-Level - Berlaku untuk container tertentu (menimpa pengaturan Pod-level)

KubernetesPod dan Container Security Context
apiVersion: v1
kind: Pod
metadata:
  name: security-context-demo
spec:
  securityContext:
    runAsUser: 1000
    runAsGroup: 3000
    fsGroup: 2000
  containers:
  - name: app
    image: myapp:latest
    securityContext:
      runAsUser: 2000
      allowPrivilegeEscalation: false

Menjalankan sebagai Non-Root User

Pod-Level runAsUser

KubernetesPod-Level runAsUser
apiVersion: v1
kind: Pod
metadata:
  name: non-root-pod
spec:
  securityContext:
    runAsUser: 1000
  containers:
  - name: app
    image: myapp:latest

Ini menjalankan semua container di Pod sebagai user ID 1000.

Container-Level runAsUser

KubernetesContainer-Level runAsUser
apiVersion: v1
kind: Pod
metadata:
  name: mixed-users
spec:
  containers:
  - name: app1
    image: app1:latest
    securityContext:
      runAsUser: 1000
  - name: app2
    image: app2:latest
    securityContext:
      runAsUser: 2000

Container berbeda berjalan sebagai user berbeda.

runAsNonRoot

KubernetesEnforce Non-Root
apiVersion: v1
kind: Pod
metadata:
  name: enforce-non-root
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
  containers:
  - name: app
    image: myapp:latest

Pengaturan runAsNonRoot: true mencegah container berjalan sebagai root. Jika image mencoba berjalan sebagai root, Pod akan gagal dimulai.

Pengaturan Group

runAsGroup

KubernetesSet Primary Group
apiVersion: v1
kind: Pod
metadata:
  name: group-demo
spec:
  securityContext:
    runAsUser: 1000
    runAsGroup: 3000
  containers:
  - name: app
    image: myapp:latest

Ini menetapkan primary group ID ke 3000.

fsGroup

KubernetesSet Filesystem Group
apiVersion: v1
kind: Pod
metadata:
  name: fsgroup-demo
spec:
  securityContext:
    runAsUser: 1000
    fsGroup: 2000
  containers:
  - name: app
    image: myapp:latest
    volumeMounts:
    - name: data
      mountPath: /data
  volumes:
  - name: data
    emptyDir: {}

Pengaturan fsGroup mengubah kepemilikan group dari volume yang di-mount. Semua proses di container juga merupakan bagian dari group ini.

supplementalGroups

KubernetesSupplemental Groups
apiVersion: v1
kind: Pod
metadata:
  name: supplemental-groups
spec:
  securityContext:
    runAsUser: 1000
    supplementalGroups: [4000, 5000]
  containers:
  - name: app
    image: myapp:latest

Proses container adalah anggota dari group 4000 dan 5000 selain primary group.

Izin Filesystem

readOnlyRootFilesystem

KubernetesRead-Only Root Filesystem
apiVersion: v1
kind: Pod
metadata:
  name: readonly-fs
spec:
  containers:
  - name: app
    image: myapp:latest
    securityContext:
      readOnlyRootFilesystem: true
    volumeMounts:
    - name: tmp
      mountPath: /tmp
    - name: var-log
      mountPath: /var/log
  volumes:
  - name: tmp
    emptyDir: {}
  - name: var-log
    emptyDir: {}

Ini membuat root filesystem read-only. Container hanya dapat menulis ke volume yang di-mount.

Linux Capability

Linux capability memecah privilege root menjadi unit yang lebih kecil. Daripada memberikan semua root capability, Anda dapat memberikan hanya yang diperlukan.

Drop Capability

KubernetesDrop Unnecessary Capability
apiVersion: v1
kind: Pod
metadata:
  name: drop-caps
spec:
  containers:
  - name: app
    image: myapp:latest
    securityContext:
      capabilities:
        drop:
        - ALL

Ini menghapus semua Linux capability. Container berjalan dengan privilege minimal.

Add Specific Capability

KubernetesAdd Specific Capability
apiVersion: v1
kind: Pod
metadata:
  name: add-caps
spec:
  containers:
  - name: app
    image: myapp:latest
    securityContext:
      capabilities:
        drop:
        - ALL
        add:
        - NET_BIND_SERVICE

Ini menghapus semua capability tetapi menambahkan NET_BIND_SERVICE untuk memungkinkan binding ke port di bawah 1024.

Common Capability

CapabilityTujuan
NET_BIND_SERVICEBind ke port < 1024
NET_RAWGunakan raw socket
SYS_ADMINBerbagai operasi admin
SYS_TIMESet system time
CHOWNUbah kepemilikan file
DAC_OVERRIDEBypass izin file
SETUIDUbah user ID
SETGIDUbah group ID

Privilege Escalation

allowPrivilegeEscalation

KubernetesPrevent Privilege Escalation
apiVersion: v1
kind: Pod
metadata:
  name: no-priv-escalation
spec:
  containers:
  - name: app
    image: myapp:latest
    securityContext:
      allowPrivilegeEscalation: false

Ini mencegah container mendapatkan privilege tambahan melalui setuid atau setgid binary.

privileged Mode

KubernetesPrivileged Container
apiVersion: v1
kind: Pod
metadata:
  name: privileged-pod
spec:
  containers:
  - name: app
    image: myapp:latest
    securityContext:
      privileged: true

Container privileged memiliki akses ke semua device host dan capability. Gunakan hanya jika benar-benar diperlukan.

SELinux Options

SELinux Context

KubernetesSet SELinux Context
apiVersion: v1
kind: Pod
metadata:
  name: selinux-demo
spec:
  securityContext:
    seLinuxOptions:
      level: "s0:c123,c456"
      type: "spc_t"
  containers:
  - name: app
    image: myapp:latest

Ini menetapkan konteks SELinux untuk Pod.

Seccomp Profile

Seccomp (Secure Computing) membatasi system call mana yang dapat dibuat container.

RuntimeDefault Seccomp

KubernetesUse Default Seccomp Profile
apiVersion: v1
kind: Pod
metadata:
  name: seccomp-default
spec:
  securityContext:
    seccompProfile:
      type: RuntimeDefault
  containers:
  - name: app
    image: myapp:latest

Ini menggunakan default seccomp profile dari container runtime.

Custom Seccomp Profile

KubernetesCustom Seccomp Profile
apiVersion: v1
kind: Pod
metadata:
  name: seccomp-custom
spec:
  securityContext:
    seccompProfile:
      type: Localhost
      localhostProfile: my-profile.json
  containers:
  - name: app
    image: myapp:latest

Ini menggunakan custom seccomp profile yang disimpan di node.

Contoh Praktis

Secure Web Application

KubernetesSecure Web Application
apiVersion: v1
kind: Pod
metadata:
  name: secure-web
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
    runAsGroup: 3000
    fsGroup: 2000
  containers:
  - name: web
    image: nginx:latest
    securityContext:
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
      capabilities:
        drop:
        - ALL
        add:
        - NET_BIND_SERVICE
    volumeMounts:
    - name: tmp
      mountPath: /tmp
    - name: cache
      mountPath: /var/cache/nginx
    - name: run
      mountPath: /var/run
  volumes:
  - name: tmp
    emptyDir: {}
  - name: cache
    emptyDir: {}
  - name: run
    emptyDir: {}

Database Container

KubernetesSecure Database Container
apiVersion: v1
kind: Pod
metadata:
  name: secure-db
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 999
    runAsGroup: 999
    fsGroup: 999
  containers:
  - name: postgres
    image: postgres:15
    securityContext:
      allowPrivilegeEscalation: false
      capabilities:
        drop:
        - ALL
    volumeMounts:
    - name: data
      mountPath: /var/lib/postgresql/data
  volumes:
  - name: data
    emptyDir: {}

Minimal Privilege Container

KubernetesMinimal Privilege Container
apiVersion: v1
kind: Pod
metadata:
  name: minimal-privilege
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
  containers:
  - name: app
    image: myapp:latest
    securityContext:
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
      capabilities:
        drop:
        - ALL
    volumeMounts:
    - name: tmp
      mountPath: /tmp
  volumes:
  - name: tmp
    emptyDir: {}

Security Context di Deployment

KubernetesDeployment with Security Context
apiVersion: apps/v1
kind: Deployment
metadata:
  name: secure-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: secure-app
  template:
    metadata:
      labels:
        app: secure-app
    spec:
      securityContext:
        runAsNonRoot: true
        runAsUser: 1000
        fsGroup: 2000
      containers:
      - name: app
        image: myapp:latest
        securityContext:
          allowPrivilegeEscalation: false
          readOnlyRootFilesystem: true
          capabilities:
            drop:
            - ALL
        volumeMounts:
        - name: tmp
          mountPath: /tmp
      volumes:
      - name: tmp
        emptyDir: {}

Kesalahan dan Jebakan Umum

Kesalahan 1: Menjalankan sebagai Root

Problem: Container memiliki privilege yang tidak perlu.

KubernetesKesalahan: Running as Root
# JANGAN LAKUKAN INI - Berjalan sebagai root
apiVersion: v1
kind: Pod
metadata:
  name: root-pod
spec:
  containers:
  - name: app
    image: myapp:latest

Solusi: Selalu tentukan runAsUser:

KubernetesCorrect: Non-Root User
apiVersion: v1
kind: Pod
metadata:
  name: non-root-pod
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
  containers:
  - name: app
    image: myapp:latest

Kesalahan 2: Mengizinkan Privilege Escalation

Problem: Container dapat mendapatkan privilege tambahan.

KubernetesKesalahan: Allow Privilege Escalation
# JANGAN LAKUKAN INI - Mengizinkan privilege escalation
apiVersion: v1
kind: Pod
metadata:
  name: escalation-pod
spec:
  containers:
  - name: app
    image: myapp:latest

Solusi: Nonaktifkan privilege escalation:

KubernetesCorrect: Prevent Privilege Escalation
apiVersion: v1
kind: Pod
metadata:
  name: secure-pod
spec:
  containers:
  - name: app
    image: myapp:latest
    securityContext:
      allowPrivilegeEscalation: false

Kesalahan 3: Writable Root Filesystem

Problem: Container dapat memodifikasi filesystem.

KubernetesKesalahan: Writable Root Filesystem
# JANGAN LAKUKAN INI - Root filesystem dapat ditulis
apiVersion: v1
kind: Pod
metadata:
  name: writable-pod
spec:
  containers:
  - name: app
    image: myapp:latest

Solusi: Buat root filesystem read-only:

KubernetesCorrect: Read-Only Root Filesystem
apiVersion: v1
kind: Pod
metadata:
  name: readonly-pod
spec:
  containers:
  - name: app
    image: myapp:latest
    securityContext:
      readOnlyRootFilesystem: true
    volumeMounts:
    - name: tmp
      mountPath: /tmp
  volumes:
  - name: tmp
    emptyDir: {}

Kesalahan 4: Memberikan Semua Capability

Problem: Container memiliki capability yang tidak perlu.

KubernetesKesalahan: All Capability
# JANGAN LAKUKAN INI - Container memiliki semua capability
apiVersion: v1
kind: Pod
metadata:
  name: all-caps-pod
spec:
  containers:
  - name: app
    image: myapp:latest

Solusi: Hapus semua capability dan tambahkan hanya yang diperlukan:

KubernetesCorrect: Minimal Capability
apiVersion: v1
kind: Pod
metadata:
  name: minimal-caps-pod
spec:
  containers:
  - name: app
    image: myapp:latest
    securityContext:
      capabilities:
        drop:
        - ALL
        add:
        - NET_BIND_SERVICE

Kesalahan 5: Menggunakan Privileged Container

Problem: Container memiliki akses penuh ke host.

KubernetesKesalahan: Privileged Container
# JANGAN LAKUKAN INI - Privileged container
apiVersion: v1
kind: Pod
metadata:
  name: privileged-pod
spec:
  containers:
  - name: app
    image: myapp:latest
    securityContext:
      privileged: true

Solusi: Gunakan capability tertentu sebagai gantinya:

KubernetesCorrect: Specific Capability
apiVersion: v1
kind: Pod
metadata:
  name: specific-caps-pod
spec:
  containers:
  - name: app
    image: myapp:latest
    securityContext:
      capabilities:
        drop:
        - ALL
        add:
        - NET_ADMIN

Praktik Terbaik

1. Selalu Jalankan sebagai Non-Root

KubernetesNon-Root Best Practice
securityContext:
  runAsNonRoot: true
  runAsUser: 1000

2. Hapus Semua Capability

KubernetesDrop All Capability
securityContext:
  capabilities:
    drop:
    - ALL

3. Buat Root Filesystem Read-Only

KubernetesRead-Only Filesystem
securityContext:
  readOnlyRootFilesystem: true
volumeMounts:
- name: tmp
  mountPath: /tmp

4. Cegah Privilege Escalation

KubernetesPrevent Escalation
securityContext:
  allowPrivilegeEscalation: false

5. Gunakan Security Context di Pod Level

Terapkan security context di Pod level sehingga semua container mewarisinya:

KubernetesPod-Level Security Context
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
    fsGroup: 2000
  containers:
  - name: app
    image: myapp:latest

6. Gabungkan dengan Pod Security Policy

Gunakan Pod Security Policy (atau Pod Security Standard di versi lebih baru) untuk menerapkan persyaratan security context di seluruh cluster.

7. Uji Security Context

Verifikasi bahwa pengaturan security context Anda berfungsi dengan benar:

KubernetesTest Security Context
# Periksa running user
kubectl exec -it pod-name -- id
 
# Periksa izin filesystem
kubectl exec -it pod-name -- ls -la /
 
# Periksa capability
kubectl exec -it pod-name -- grep Cap /proc/self/status

Memeriksa Security Context

Describe Pod

Kubernetesbash
kubectl describe pod pod-name
# Cari bagian "Security Context"

Get Pod YAML

Kubernetesbash
kubectl get pod pod-name -o yaml
# Cari field securityContext

Periksa Running User

Kubernetesbash
kubectl exec -it pod-name -- id
# Output: uid=1000(user) gid=3000(group) groups=2000(fsgroup)

Periksa Capability

Kubernetesbash
kubectl exec -it pod-name -- grep Cap /proc/self/status
# Menunjukkan capability saat ini

Keterbatasan Security Context

1. Container Runtime Dependent

Beberapa pengaturan security context bergantung pada container runtime (Docker, containerd, dll).

2. Host Kernel Limitations

Security context bergantung pada fitur kernel Linux. Beberapa pengaturan mungkin tidak berfungsi di semua sistem.

3. No Application-Level Security

Security context tidak melindungi dari kerentanan tingkat aplikasi.

4. Requires Proper Image Setup

Container image harus dirancang untuk berjalan sebagai non-root.

Kesimpulan

Pada episode 37 ini, kita telah membahas Pod Security Context di Kubernetes secara mendalam. Kita sudah belajar bagaimana control security setting untuk Pod dan container, jalankan sebagai non-root user, manage capability, dan enforce read-only filesystem.

Key takeaway:

  • Pod Security Context mengontrol security setting untuk Pod dan container
  • runAsUser - Jalankan container sebagai user ID tertentu
  • runAsNonRoot - Enforce non-root execution
  • runAsGroup - Set primary group ID
  • fsGroup - Set filesystem group untuk volume
  • readOnlyRootFilesystem - Buat root filesystem read-only
  • capabilities - Grant atau drop Linux capability
  • allowPrivilegeEscalation - Cegah privilege escalation
  • privileged - Jalankan di privileged mode (gunakan jarang)
  • seLinuxOptions - Set SELinux context
  • seccompProfile - Batasi system call
  • Selalu jalankan sebagai non-root - Principle of least privilege
  • Hapus semua capability - Kemudian tambahkan hanya yang diperlukan
  • Buat filesystem read-only - Cegah modifikasi
  • Uji security setting - Verifikasi mereka bekerja dengan benar

Dengan mengonfigurasi Pod Security Context dengan benar, Anda secara signifikan mengurangi attack surface aplikasi Anda dan mengikuti best practice keamanan.

Catatan

Untuk kalian yang ingin melanjutkan ke episode selanjutnya, bisa click thumbnail episode 38 di bawah ini

Episode 38Episode 38

Related Posts