kubernetes API 보안
29 May 2019
인증
다음의 방법을 사용해 크라이언트의 ID를 얻습니다.
- 클라이언트 인증서
- HTTP 헤더로 전달된 인증 토큰
- 기본 HTTP 인증
- 기타
인증 플러그인은 인증된 사용자의 사용자 이름, 사용자 ID, 그룹을 반환합니다.
사용자
쿠버네티스는 계정 체계를 관리함에 있어서 하람이 사용하는 사용자 어카운트와 시스템이 사용하는 서비스 어카운트 두가지 개념을 제공합니다.
그룹
사용자 및 서비스 어카운트는 모두 하나 이상의 그룹에 속할 수 있습니다.
프러그인에 의해 반환되는 그룹은 임의의 그룹 이름을 나타내는 문자열일 뿐이지만 시스템에서 제공하는 기본 그룹은 특별한 의미가 있습니다.
- system:unauthenticated 어느 클라이언트도 인증할 수 없을 때
- system:authenticated 성공적으로 인증된 사용자
- system:serviceaccount 시스템의 모든 서비스어카운트를 포함
- system:serviceaccount:
특정 네임스페이스의 모든 서비스어카운트를 포함
서비스어카운트
토큰 파일(secret 볼륨상의 각 컨테이너의 파일 시스템에 마운트된 /var/run/secrets/kuberetes.io/serviceaccount/token)은 서비스어카운트의 인증 토큰을 가지고 있습니다. 포드에서 실행중인 애플리케이션이 이 토큰을 사용해 API 서버에 연결하면 인증 플러그인이 서비스어카운트를 인증하고 서비스어카운트의 사용자 이름(system:serviceaccount:
서비스어카운트는 리소스이며 개별 네임스페이스로 범위가 지정됩니다.
# 서비스어카운트 나열
kubectl get sa
kubectl get serviceaccount
포드 매니페스트에서 계정 이름을 지정해 포드에 서비스어카운트를 할당할 수 있습니다. 명시적으로 지정하지 않으면 포드는 네임스페이스의 디폴트 서비스어카운트를 사용하게 됩니다.
포드에 각기 다른 서비스어카운트를 할당하면 각 포드에 접근할 수 있는 리소스를 제어할 수 있습니다.
kubectl describe sa foo
## response
Name: foo
Namespace: default
Labels: <none>
Image pull secret: <none> # 모든 포드에 자동으로 추가됩니다.
Mountable secret: foo-token-qzie3 # mount할 수 있는 secret
Tokens: foo-token-qzie3 # 인증 토큰
서비스어카운트는 포드가 생성될 때 반드시 지정돼야 합니다. 생성된 이후에는 변경할 수 없습니다.
# 사용자 지정 서비스어카운트를 사용한 포드
apiVersion: v1
kind: Pod
metadata:
name: curl-custom-sa
spec:
serviceAccountName: foo # 이 포드는 default 대신에 foo 서비스어카운트를 사용
containers:
...
RBAC 클러스터 보안
네임스페이스 내에 존재하는 롤과 롤바인딩
RBAC 인증 플러그인은 사용자의 역할을 보고 사용자가 액션을 수행할 수 있는지 여부를 결정할 때 핵심 요소로 사용합니다.
# 롤 정의: service-reader.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: foo
name: service-reader
rules:
- apiGroups: [""] # 서비스는 이름이 없는 core apiGroup의 리소스
verbs: ["get", "list"]
resources: ["services"]
# 롤 생성 명령
kube create role service-read --verb=get --verb=list --resource=service -n bar
롤은 수행할 수 있는 액셕을 정의하지만 누가 수행할 수 있는지는 지정하지 않습니다. 이를 수행하려면 롤을 사용자, 서비스어카운트 또는 그룹이 될 수 있는 주체에 바인딩해야 합니다.
# 롤 바인딩
kubectl create rolebinding test --role=service-reader --serviceaccount=foo:default -n foo
롤바인딩은 항상 하나의 롤을 참조하지만 롤을 어러 subject에 바인딩할 수 있습니다.
클러스터 수준의 RBAC
네임스페이스와 연관 없는 리소스나 리소스가 아닌 URL, 또는 개별 네임스페이스 내부에 바인되는 공통된 롤로 사용하므로 필요할 때마다 동일한 롤을 다시 정의하지 하지 않을 수 있습니다.
# PersistentVolume을 나열하도록 허용하는 role
kubectl create clusterrole pv-reader --verb=get,list --resource=persistentvolumes
# rolebinding
kubectl create clusterrolebinding pv-test --clusterrole=pv-reader --serviceaccount=foo:default
# 주의 아래와 같이 namespace 수준의 rolebinding을 하지 않도록 한다.
kubectl create rolebinding pv-test --clusterrole=pv-reader --serviceaccount=foo:default -n foo
비리소스 URL 접근 허용
비리소스 url에는 명시적으로 접근 권한을 부여해야합니다.
일반적으로 이 작업은 system:discovery 클러스터롤과 이름이 같은 클러스터롤바인딩을 통해 자동으로 수행됩니다.
특정 네임스테이스에서 클러스터롤 사용
클러스터롤바인딩을 생성하고 클러스터롤을 참조할 경우 바인딩에 나열된 주체는 모든 네임스페이스에서 지정된 리소스를 볼 수 있습니다. 반면에 롤바인딩을 만들고 바인딩에 나열된 주체는 롤바인딩의 네임스페이스에 있는 리소스만 볼 수 있습니다.
디폴트 클러스터롤
디폴트 클러스터롤 목록에는 system: 접두사로 시작하는 많은 수의 default 클러스터롤이 있습니다.
중요한 디폴트 클러스터롤
- view: 네임스페이스내의 대부분의 리소스를 읽을 수 있습니다.(롤, 롤바인딩, 스크릿 제외)
- edit: 네임스페이스의 리소스를 수정할 수 있을 뿐만아니라 시크릿을 읽고 수정 가능
- admin: 네임스페이스의 리소스를 완별하게 제어 가능
- cluster-admin: 모든 네임스페이스 제어 가능
롤과 바인딩 타입의 특정 조합 정리
접근 | 롤 타입 | 사용할 바인딩 타입 |
---|---|---|
클러스터 수준 리소스 | 클러스터롤 | 클러스터롤바인딩 |
비리소스 URL | 클러스터롤 | 클러스터롤바인딩 |
모든 네임스페이스의 네임스페이스로 지정된 리소스 | 클러스터롤 | 클러스터롤바인딩 |
여러 네임스페이스의 동일한 클러스터롤 재사용 | 클러스터롤 | 롤바인딩 |
각 네임스페이스에 롤를 정의 | 롤바인딩 | 롤바인딩 |