본문 바로가기

Kubernetes

쿠버네티스 보안

쿠버네티스에는 사용자와 비슷한 개념으로 서비스 어카운트(ServiceAccount)가 있다. 서비스 어카운트는 쿠버네티스에서만 사용되는 것으로 파드에서 실행되는 프로세스를 위해 할당되며 네임스페이스와 연결된 리소스다. 파드 기동 시 반드시 서비스 어카운트 한 개를 할당해야 하며 서비스 어카운트 기반 인증/인가를 하고 있다. 지정하지 않으면 기본 서비스 어카운트가 할당된다.

 

apiVersion: v1
kind: ServiceAccount
metadata:
  name: sample-serviceaccount
  namespace: default
imagePullSecrets:
- name: myregistrykey

 

인증이 필요한 개인 저장소에서 지정된 이미지를 가져오기 위해 시크릿인 imagePullSecrets를 설정하는 예제이다. 앞에서 추가한 서비스 어카운트 정보를 확인해보면 생성할 때는 지정하지 않은 시크릿 항목이 존재한다.

 

이 시크릿은 서비스 어카운트를 생성하면 자동으로 토큰 타입으로 자동 생성된다. 서비스 어카운트는 이 토큰으로 쿠버네티스 API에 대한 인증 정보를 사용할 수 있다. 파드의 서비스 어카운트를 명식적으로 지정하려면 spec.serviceAccountName을 지정한다. 서비스 어카운트를 지정한 컨테이너를 생성한 후 기동 된 파드 정보를 확인하면 토큰이 볼륨으로 자동 포함되어 있고 마운트 된 볼륨에는 토큰과 인증서를 사용하여 지정된 서비스 어카운트 권한으로 애플리케이션을 실행할 수 있다.

 

토큰은 자동으로 마운트 되지만 이 자동 마운트 기능을 비활성화할 수도 있다. 설정을 비활성화하려면 ServiceAccount 리소스에서 automountServiceAccountToken을 false로 지정하고 파드 리소스에서 spec.automountServiceAccountToken을 false로 지정할 수 있다. 둘 다 설정한 경우에는 파드 설정이 우선시된다. 

 

Role Based Access Control(RBAC)

RBAC는 어떤 조작을 허용하는지를 결정하는 롤을 생성하고 서비스 어카운트 등의 사용자에게 롤을 연결하여 권한을 부여한다. 

 

롤과 클러스터롤은 모두 네임스페이스 범위의 리소스를 대상으로 인가 설정을 할 수 있다. 롤과 클러스터를 생성할 때는 주로 apiGroups, resources, verbs 세 가지를 지정한다.

 

종류 개요
* 모두 처리
create 생성
delete 삭제
get 조회
list 목록 조회
patch 일부 업데이트
update 업데이트
watch 변경 감시

apiGroups와 resources로 지정된 리소스에 대해 위 테이블처럼 verbs에 해당하는 권한을 인가한다.

 

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: sample-role
  default: default
rules:
- apiGroups:
  - apps
  - extensions
  resources:
  - replicasets
  - deployments
  - deployments/scale
  verbs:
  - "*"

롤을 생성할때는 여러 개의 rules를 설정할 수 있으며 네임스페이스를 지정하여 생성한다.

 

클러스터롤은 기본적으로 롤과 설정 항목이 다르지 않지만 차이가 있다면 nonResourceURLs를 지정할 수 있다는 점과 네임스페이스를 지정할 수 없다는 점이다.

 

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: sample-clusterrole
rules:
- apiGroups:
  - apps
  - extensions
  resources:
  - replicasets
  - deployments
  verbs:
  - get
  - list
  - watch
- nonResourceURLS:
  - /healthz
  - /healthz/*
  - /version
  verbs:
  - get

 

롤바인딩과 클러스터롤바인딩

롤바인딩(RoleBinding)과 클러스터롤바인딩(ClusterRoleBinding)도 구성은 거의 동일하다. roleRef에서 연결하는 롤과 subjects에 연결하는 사용자나 서비스 어카운트를 지정한다.

 

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: sample-rolebinding
  namespace: default
roleRef:
  apiGroups: rbac.authorization.k8s.io
  kind: Role
  name: sample-role
subjects:
- kind: ServiceAccount
  name: sample-serviceaccount
  namespace: default

 

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: sample-clusterrolebinding
roleRef:
  apiGroups: rbac.authorization.k8s.io
  kind: ClusterRole
  name: sample-clusterrole
subjects:
- kind: ServiceAccount
  name: sample-serviceaccount
  namespace: default

 

보안 컨텍스트

보안 컨텍스트는 각 컨테이너에 대한 보안 설정이다. 설정 가능한 항목은 아래와 같다.

 

종류 개요
privileged 특수 권한을 가진 컨테이너로 실행
capabilities Capabilities의 추가와 삭제
allowPrivilegeEscalation 컨테이너 실행 시 상위 프로세스보다 많은 권한을 부여할지 여부
readOnlyRootFileSystem root 파일 시스템을 읽기 전용으로 할지 여부
runAsUser 실행 사용자
runAsGroup 실행 그룹
runAsNonRoot root에서 실행을 거부
seLinuxOptions SELinux 옵션

 

특수 권한 컨테이너로 설정하면 컨테이너 내부에서 기동 하는 프로세스의 리눅스 Capabilities가 호스트와 동등한 권한을 가지게 된다.

 

apiVersion: v1
kind: Pod
metadata:
  name: sample-privileged
spec:
  containers:
  - name: nginx-container
    image: nginx:1.16
    securityContext:
      privileged: true

특수 권한 컨테이너는 호스트와 동등한 Capabilities가 추가되지만 더 세분화된 특정 Capabilities만을 컨테이너에 부여/제거할 수도 있다.

 

apiVersion: v1
kind: Pod
metadata:
  name: sample-capabilities
spec:
  containers:
  - name: nginx-container
    image: nginx:1.16
    securityContext:
      capabilities:
        add: ["SYS_ADMIN"]
        drop: ["AUDIT_WRITE"]

 

파드 보안 컨텍스트

파드 보안 컨텍스트는 파드에 대한 보안 설정이다. 설정 가능한 항목은 아래와 같다.

 

설정 항목 내용
runAsUser 실행 사용자
runAsGroup 실행 그룹
runAsNonRoot root에서 실행을 거부
supplementalGroups 프라이머리 GUI에 추가로 부여할 GID 목록을 지정
fsGroup 파일 시스템 그룹 지정
sysctls 덮어 쓸 커널 파라미터 지정
seLinuxOptions SELinux 옵션 지정

 

컨테이너가 실행하는 Entrypoint 실행 사용자를 변경할 수 있다.

 

apiVersion: v1
kind: Pod
metadata:
  name: sample-runuser
spec:
  containers:
  - name: nginx-container
    image: nginx:1.16
  securityContext:
    runAsUser: 65534
    runAsGroup: 65534
    supplementalGroups:
    - 1002
    - 1002

 

실행된 컨테이너에서 실행 사용자를 확인 하면 UID: 65534 사용자 및 GID: 65534 그룹으로 실행되는 것을 확인할 수 있으며 실행 권한에 서브 그룹으로 1001과 1002가 포함되어 있다.

 

일반적으로 마운트한 볼륨의 소유자와 그룹은 root:root로 되어 있다. 즉 실행 사용자를 변경한 경우에는 마운트한 볼륨에 권한이 없는 경우가 있다. 따라서 마운트 하는 볼륨의 그룹을 변경할 수 있도록 되어 있다.

 

apiVersion: v1
kind: Pod
metadata:
  name: sample-fsgroup
spec:
  containers:
  - name: nginx-container
    image: nginx:1.16
    volumeMounts:
      - name: cache-volume
        mountPath: /cache
  volumes:
  - name: cache-volume
    emptyDir: {}
  securityContext:
    fsGroup: 1001

 

네트워크 정책

네트워크 정책은 쿠버네티스 클러스터 내부에서 파드 간에 통신할 경우 트래픽 룰을 규정하는 것이다. 네트워크 정책을 사용하면 네임스페이스 별로 트래픽을 전송하지 못하게 하거나 기본적으로 모든 파드 간 통신을 차단하고 특정 파드 간 통신만 허용하는 화이트리스트 방식을 사용할 수 있다.

 

네트워크 정책은 인그레스와 이그레스로 구성되어 있으면 인그레스는 인바운드 방향의 트래픽 룰을 설정하고 이그레스는 아웃바운드 방향의 트래픽 룰을 설정한다.

 

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: sample-networkpolicy
  namespace: default
spec:
  podSelector:
    #설정할 대상 파드를 여기 기입
    # 레이블 셀렉터이므로 여러 파드를 대상으로 할 수 있음
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    # 인그레스 룰을 여기에 기입
    ports:
    # 인그레스 룰로 허가할 수신 포트 번호와 프로토콜 기입
  egress:
  - to:
    # 이그레스 룰을 여기에 기입
    ports:
    # 이그레스 룰로 허가할 수신 포트 번호와 프로토콜 기입

 

PodSeletor는 특정 파드에서의 통신을 제어하는 정책이며 namespaceSelector는 특정 네임스페이스상에 있는 파드에서의 통신을 제어하는 정책이다. 마지막으로 ipBlock은 특정 CIDR(ClasslessInter-Domain Routing)에서의 통신을 제한하는 정책이다. 

 

'Kubernetes' 카테고리의 다른 글

쿠버네티스 헬름  (0) 2022.01.31
쿠버네티스 노드 스케줄링  (0) 2022.01.28
쿠버네티스 헬스 체크  (0) 2022.01.22
쿠버네티스 리소스 관리 및 오토 스케일링  (0) 2022.01.08
쿠버네티스 볼륨  (0) 2022.01.02