하위 태스크 1

Role 생성

네임스페이스 레벨 권한을 정의하는 Role 생성

Pod를 조회할 수 있는 권한을 가진 Role을 생성한다.

role.yaml:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

Role을 생성한다.

kubectl apply -f role.yaml

하위 태스크 2

RoleBinding 생성

사용자에게 Role을 부여하는 RoleBinding 생성

kubernetes-admin에 이전 하위 태스크에서 만든 pod-reader 권한을 부여한다.

rolebinding.yaml:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: default
subjects:
- kind: User
  name: kubernetes-admin
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

RoleBinding을 생성한다.

kubectl apply -f rolebinding.yaml

하위 태스크 3

권한 테스트

부여한 권한이 정상적으로 동작하는지 테스트

pod-reader Role을 통해 부여받은 Pod 조회 권한이 있는지 확인한다.

kubectl auth can-i get pods

결과:

yes

권한을 부여하지 않은 Pod 삭제를 시도한다.

kubectl auth can-i delete pods

결과:

no

하위 태스크 4

ClusterRole 생성

클러스터 레벨 권한을 정의하는 ClusterRole 생성

클러스터 전체의 노드 정보를 조회할 수 있는 권한을 정의한다.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: node-reader
rules:
- apiGroups: [""]
  resources: ["nodes"]
  verbs: ["get", "watch", "list"]

ClusterRole을 생성한다.

kubectl apply -f clusterrole.yaml

하위 태스크 5

ClusterRoleBinding 생성

사용자에게 ClusterRole을 부여하는 ClusterRoleBinding 생성

생성한 ClusterRole을 사용자에게 연결해 클러스터 전체 권한을 활성화한다.

clusterrolebinding.yaml:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: read-nodes-global
subjects:
- kind: User
  name: kubernetes-admin
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: node-reader
  apiGroup: rbac.authorization.k8s.io

ClusterRoleBinding을 생성한다.

kubectl apply -f clusterrolebinding.yaml

하위 태스크 6

ServiceAccount 생성

파드가 사용할 ServiceAccount 생성

Pod가 사용할 계정을 생성한다.

serviceaccount.yaml:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: pod-manager
  namespace: default

ServiceAccount를 생성한다.

kubectl apply -f serviceaccount.yaml

하위 태스크 7

ServiceAccount 권한 부여

ServiceAccount에 Role을 부여하여 파드 권한 설정

이전 하위 태스크에서 생성한 ServiceAccount에 실제 권한을 연결한다.

sa-rolebinding.yaml:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: sa-read-pods
  namespace: default
subjects:
- kind: ServiceAccount
  name: pod-manager
  namespace: default
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

RoleBinding을 생성한다.

kubectl apply -f sa-rolebinding.yaml

하위 태스크 8

ResourceQuota 생성

네임스페이스별 리소스 제한 설정

새 네임스페이스를 생성한다.

kubectl create namespace team-a

resourcequota.yaml:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: team-a-quota
  namespace: team-a
spec:
  hard:
    requests.cpu: "2"
    requests.memory: 2Gi
    limits.cpu: "4"
    limits.memory: 4Gi
    pods: "10"

ResourceQuota를 생성한다.

kubectl apply -f resourcequota.yaml -n team-a

하위 태스크 9

리소스 사용량 확인

kubectl describe로 쿼터 사용량 확인

쿼터 요약 정보를 확인한다.

kubectl get resourcequota -n team-a

결과:

NAME           AGE   REQUEST                                                 LIMIT
team-a-quota   4s    pods: 0/10, requests.cpu: 0/2, requests.memory: 0/2Gi   limits.cpu: 0/4, limits.memory: 0/4Gi

상세 사용량과 제한을 확인한다.

kubectl describe resourcequota team-a-quota -n team-a

결과:

Name:            team-a-quota
Namespace:       team-a
Resource         Used  Hard
--------         ----  ----
limits.cpu       0     4
limits.memory    0     4Gi
pods             0     10
requests.cpu     0     2
requests.memory  0     2Gi

하위 태스크 10

쿼터 초과 테스트

쿼터를 초과하는 리소스 생성 시도

제한량을 초과하는 리소스를 요청하여 생성이 거부되는지 테스트한다.

quota-exceed-deploy.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: quota-test-deploy
  namespace: team-a
spec:
  replicas: 3
  selector:
    matchLabels:
      app: quota-test
  template:
    metadata:
      labels:
        app: quota-test
    spec:
      containers:
      - name: nginx
        image: nginx
        resources:
          requests:
            cpu: "1"
            memory: "512Mi"

Deployment를 생성한다.

kubectl apply -f quota-exceed-deploy.yaml

배포 상태를 확인한다.

kubectl describe rs -n team-a

결과:

...
Events:
  Type     Reason        Age   From                   Message
  ----     ------        ----  ----                   -------
  Warning  FailedCreate  3s    replicaset-controller  Error creating: pods "quota-test-deploy-594bd68694-lldfc" is forbidden: failed quota: team-a-quota: must specify limits.cpu for: nginx; limits.memory for: nginx
...

하위 태스크 11

LimitRange 생성

컨테이너별 리소스 제한 설정

limitrange.yaml:

apiVersion: v1
kind: LimitRange
metadata:
  name: team-a-limitrange
  namespace: team-a
spec:
  limits:
  - default:
      cpu: "500m"
      memory: "512Mi"
    defaultRequest:
      cpu: "200m"
      memory: "256Mi"
    max:
      cpu: "1"
      memory: "1Gi"
    min:
      cpu: "100m"
      memory: "128Mi"
    type: Container

LimitRange를 생성한다.

kubectl apply -f limitrange.yaml -n team-a

하위 태스크 12

기본값 적용 확인

리소스를 지정하지 않은 Pod에 default 값 적용 확인

team-a 네임스페이스에 Pod를 배포한다.

limitrange-test-pod.yaml:

apiVersion: v1
kind: Pod
metadata:
  name: limitrange-test-pod
  namespace: team-a
spec:
  containers:
  - name: nginx
    image: nginx
    resources:
      requests:
        cpu: "150m"
        memory: "150Mi"
      limits:
        cpu: "600m"
        memory: "600Mi"

Pod를 생성한다.

kubectl apply -f limitrange-test-pod.yaml

생성된 Pod의 정보를 조회한다.

kubectl describe pod limitrange-test-pod -n team-a

결과:

...
    Limits:
      cpu:     600m
      memory:  600Mi
    Requests:
      cpu:        150m
      memory:     150Mi
...

하위 태스크 13

NetworkPolicy 작성

파드 간 통신을 제어하는 NetworkPolicy 작성

테스트용으로 라벨링된 Pod를 준비한다.

kubectl run api-pod --image=nginx --labels="app=api" -n team-a
kubectl run db-pod --image=nginx --labels="app=database" -n team-a

app: database: 라벨을 가진 Pod는 app: api 라벨을 가진 Pod로부터의 접속만 허용하도록 설정한다.

networkpolicy.yaml:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: db-access-policy
  namespace: team-a
spec:
  podSelector:
    matchLabels:
      app: database
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: api

NetworkPolicy를 생성한다.

kubectl apply -f networkpolicy.yaml -n team-a

하위 태스크 14

통신 제어 테스트

허용/차단 규칙이 정상적으로 동작하는지 테스트

허용된 통신을 테스트한다.

kubectl exec api-pod -n team-a -- curl --connect-timeout 2 db-pod

결과:

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, nginx is successfully installed and working.
Further configuration is required for the web server, reverse proxy,
API gateway, load balancer, content cache, or other features.</p>
 
<p>For online documentation and support please refer to
<a href="https://nginx.org/">nginx.org</a>.<br/>
To engage with the community please visit
<a href="https://community.nginx.org/">community.nginx.org</a>.<br/>
For enterprise grade support, professional services, additional
security features and capabilities please refer to
<a href="https://f5.com/nginx">f5.com/nginx</a>.</p>
 
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
  0   113k      0 --:--:-- --:--:-- --:--:--  125k

차단된 통신을 테스트한다.

kubectl run stranger-pod --image=nginx -n team-a
kubectl exec stranger-pod -n team-a -- curl --connect-timeout 2 db-pod

결과:

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:--  0:00:02 --:--:--     0
curl: (28) Connection timed out after 2002 milliseconds
command terminated with exit code 28