yeonghoon.kim

  • 게시판
  • 갤러리

ARM Kubernetes 구축 8 - 실전 보안 RBAC 네트워크 정책 Pod 보안

김영훈 2026.02.20 13:59 조회 수 : 194

Kubernetes 클러스터 보안 설정 테스트.

RBAC.
NetworkPolicy.
Pod Security Standards.

RBAC 예제.

apiVersion: v1
kind: Namespace
metadata:
  name: app-ns

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: app-deployer
  namespace: app-ns

---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: app-deployer-role
  namespace: app-ns
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

- apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["get", "list"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: app-deployer-binding
  namespace: app-ns
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: app-deployer-role
subjects:
- kind: ServiceAccount
  name: app-deployer
  namespace: app-ns

적용.

kubectl apply -f rbac-example.yaml

확인.

kubectl get rolebindings -n app-ns

kubectl describe rolebinding app-deployer-binding -n app-ns

권한 테스트.

kubectl auth can-i get pods \
  --as=system:serviceaccount:app-ns:app-deployer \
  -n app-ns

kubectl auth can-i create pods \
  --as=system:serviceaccount:app-ns:app-deployer \
  -n app-ns

Secret 접근은 막힘.

kubectl auth can-i get secrets \
  --as=system:serviceaccount:app-ns:app-deployer \
  -n app-ns

Pod에서 ServiceAccount 사용.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-deployer-pod
  namespace: app-ns
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app-deployer
  template:
    metadata:
      labels:
        app: app-deployer
    spec:
      serviceAccountName: app-deployer
      containers:
      - name: app
        image: nginx:alpine
        volumeMounts:
        - name: token
          mountPath: /var/run/secrets/kubernetes.io/serviceaccount
          readOnly: true
      volumes:
      - name: token
        projected:
          sources:
          - serviceAccountToken:
              audience: https://kubernetes.default.svc.cluster.local
              expirationSeconds: 3600
              path: token

NetworkPolicy 예제.

기본 차단 후 필요한 통신만 허용.

frontend -> api
api -> database

Namespace.

apiVersion: v1
kind: Namespace
metadata:
  name: multi-tier

기본 deny.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
  namespace: multi-tier
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress

Frontend -> API 허용.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: frontend-to-api
  namespace: multi-tier
spec:
  podSelector:
    matchLabels:
      tier: api
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          tier: frontend
    ports:
    - protocol: TCP
      port: 8000

API -> Database 허용.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: api-to-database
  namespace: multi-tier
spec:
  podSelector:
    matchLabels:
      tier: database
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          tier: api
    ports:
    - protocol: TCP
      port: 5432

Frontend 80 허용.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: frontend-ingress
  namespace: multi-tier
spec:
  podSelector:
    matchLabels:
      tier: frontend
  policyTypes:
  - Ingress
  ingress:
  - from:
    - namespaceSelector: {}
    ports:
    - protocol: TCP
      port: 80

DNS egress 허용.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns-egress
  namespace: multi-tier
spec:
  podSelector: {}
  policyTypes:
  - Egress
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          name: kube-system
    ports:
    - protocol: UDP
      port: 53
  - to:
    - namespaceSelector: {}
    ports:
    - protocol: TCP
      port: 443

적용.

kubectl apply -f network-policy-example.yaml

확인.

kubectl get networkpolicies -n multi-tier

테스트.

kubectl exec -it <frontend-pod> -n multi-tier -- sh

curl http://api-service:8000

nc -zv database-service 5432

frontend에서 database는 실패해야 함.

api pod에서는 database 접근 성공해야 함.

Pod Security Standards.

Namespace에 restricted 적용.

apiVersion: v1
kind: Namespace
metadata:
  name: secure-app
  labels:
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/audit: restricted
    pod-security.kubernetes.io/warn: restricted

보안 Pod.

apiVersion: v1
kind: Pod
metadata:
  name: secure-app
  namespace: secure-app
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
    fsGroup: 2000
    seccompProfile:
      type: RuntimeDefault
  containers:
  - name: app
    image: python:3.11-slim
    ports:
    - containerPort: 8000
    securityContext:
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
      capabilities:
        drop:
        - ALL
        add:
        - NET_BIND_SERVICE
    resources:
      requests:
        memory: "128Mi"
        cpu: "100m"
      limits:
        memory: "256Mi"
        cpu: "500m"
    volumeMounts:
    - name: tmp
      mountPath: /tmp
    - name: app-data
      mountPath: /app/data
  volumes:
  - name: tmp
    emptyDir: {}
  - name: app-data
    emptyDir: {}

보안 Deployment.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: secure-deployment
  namespace: secure-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: secure-app
  template:
    metadata:
      labels:
        app: secure-app
    spec:
      securityContext:
        runAsNonRoot: true
        runAsUser: 1000
        fsGroup: 2000
      containers:
      - name: app
        image: nginx:1.25-alpine
        ports:
        - containerPort: 8080
        securityContext:
          allowPrivilegeEscalation: false
          readOnlyRootFilesystem: true
          capabilities:
            drop:
            - ALL
            add:
            - NET_BIND_SERVICE
        resources:
          requests:
            memory: "64Mi"
            cpu: "50m"
          limits:
            memory: "128Mi"
            cpu: "200m"
        volumeMounts:
        - name: cache
          mountPath: /var/cache/nginx
        - name: run
          mountPath: /var/run
        - name: tmp
          mountPath: /tmp
      volumes:
      - name: cache
        emptyDir: {}
      - name: run
        emptyDir: {}
      - name: tmp
        emptyDir: {}

PDB.

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: secure-app-pdb
  namespace: secure-app
spec:
  minAvailable: 1
  selector:
    matchLabels:
      app: secure-app

적용.

kubectl apply -f pod-security-example.yaml

확인.

kubectl get namespace secure-app --show-labels

kubectl get pod secure-app -n secure-app -o yaml | grep -A 10 securityContext

non-root 확인.

kubectl exec -it secure-app -n secure-app -- id

read-only root filesystem 확인.

kubectl exec -it <pod-name> -n secure-app -- touch /test.txt

Capability 확인.

kubectl exec -it <pod-name> -n secure-app -- grep Cap /proc/1/status

팀별 RBAC 예시.

apiVersion: v1
kind: ServiceAccount
metadata:
  name: team-a
  namespace: team-a-ns

---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: deployer
  namespace: team-a-ns
rules:
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "list", "create", "update", "patch"]
- apiGroups: [""]
  resources: ["services"]
  verbs: ["get", "list"]

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: team-b
  namespace: team-b-ns

---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: viewer
  namespace: team-b-ns
rules:
- apiGroups: [""]
  resources: ["pods", "pods/log"]
  verbs: ["get", "list"]
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "list"]

체크리스트.

RBAC 활성화.
NetworkPolicy 적용.
Pod Security Standards 적용.
non-root 실행.
readOnlyRootFilesystem 설정.
allowPrivilegeEscalation false.
capabilities drop ALL.
resource limits 설정.

  • 추천 0

  • 비추천 0
이 게시물을
목록

댓글 0

번호 제목 글쓴이 날짜 조회 수
공지 2025 일본 여행 계획 김영훈 2024.10.10 4118
공지 현금, 저축, 투자, 지출, 예산, 보험 내역(2024-05-30) 김영훈 2024.03.10 3752
317 OpenClaw 복원과 GLM-5.1 전환 김영훈 2026.04.07 145
316 교토 4박 5일 여행 일정: Google Calendar로 관리하는 일정짜기 김영훈 2026.04.05 124
315 7일간의 일본 여행 일정 짜기: 신칸센 + JR 패스 + Google Calendar 활용 프로젝트 김영훈 2026.03.28 128
314 JSON-LD 학습 - 메일과 Calendar 자동 인식 김영훈 2026.03.28 151
313 WAF 운영 6주 분석 김영훈 2026.03.13 199
312 Tech Support 플랫폼 김영훈 2026.03.04 80
311 ChloeToken 테스트넷 배포 김영훈 2026.03.02 232
310 Redis 대기열 시스템 김영훈 2026.03.01 212
309 Apache RewriteRule 쿼리스트링 처리 김영훈 2026.02.28 258
308 비트코인 자동매매 봇 대시보드 김영훈 2026.02.21 144
307 ARM Kubernetes 구축 6 - 무중단 업그레이드 김영훈 2026.02.20 208
» ARM Kubernetes 구축 8 - 실전 보안 RBAC 네트워크 정책 Pod 보안 김영훈 2026.02.20 194
305 ARM Kubernetes 구축 7 - 클러스터 무중단 업그레이드 v1.29→v1.35 김영훈 2026.02.20 252
304 ARM Kubernetes 구축 4 - 외부 접근 환경 VPN MetalLB Ingress 김영훈 2026.02.18 246
303 ARM Kubernetes 구축 5 - 실전 업그레이드 경험기 v1.29→v1.35 김영훈 2026.02.18 238
302 ARM Kubernetes 구축 3 - 모니터링 스택 Prometheus Grafana 김영훈 2026.02.16 179
301 ARM Kubernetes 구축 1 - VNC & KVM 설치 김영훈 2026.02.14 70
300 ARM Kubernetes 구축 2 - VM 생성과 클러스터 설치 김영훈 2026.02.14 138
299 OpenClaw 모델 삭제 사고 김영훈 2026.02.13 114
298 LLM 모델 선정 김영훈 2026.02.12 141
쓰기 태그
 첫 페이지 1 2 3 4 5 6 7 8 9 10 끝 페이지