반응형
KubeConfig
- curl 을 이용해서 REST API에 대한 파드 목록을 조회하는 방법을 사용할 때 kube-apiserver 주소로 curl 요청을 보내면서 옵션으로 bearer 파일과 CA 인증서를 전달해 사용자를 인증하는 데 사용한다.
- 그렇다면 kubectl 명령어를 사용하는 것은 어떨까?
- kubectl 명령어를 사용하면서 키, 인증서 등등 여러가지 옵션을 사용하는 것은 매우 귀찮은 작업이 되기 때문에 kubeconfig라는 구성파일에 이를 저장해 놓는다.
- 그래서 우리가 여태까지 kubectl 명령어를 사용할 때 키,인증서 등등의 옵션 없이도 명령어를 사용할 수 있었던 것이다.
- 기본적으로 kubectl 도구는 사용자의 홈 디렉토리/.kube/config 파일을 찾는다.
- 이 파일에는 Clusters, Contexts, Users 3가지 섹션이 있다.
- clusters의 경우 액세스해야하는 다양한 kubernetes 클러스터이다. 개발, 테스트, 프로덕션 등등 여러 클러스터로 구성되어 있는 경우 config 파일에 등록하면 사용자는 등록된 클러스터에 액세스 할 수 있다.
- users의 경우 이러한 클러스터에 액세스할 수 있는 사용자 계정이다. 예를 들어 개발, 테스트, 프로덕션 등 여러 환경으로 나누어진 사용자 등이 해당된다.
- contexts의 경우 이러한 것들을 결합한다. 어떤 사용자 계정이 어떤 클러스터로 액세스할지 결정한다. 예를 들어 admin@production이라고 컨텍스트를 만들게 되면 production 클러스터에 액세스하는 데 admin 계정을 사용 가능하다.
- 명령어의 서버 지정은 cluster 섹션에 들어간다.
- 관리자 사용자의 키 및 인증서는 users 섹션에 들어간다.
- CA의 루트 인증서는 clusters 섹션에 리스트 별 cluster 항목에 들어간다.
- users 섹션에 지정한 user로 context 항목에 cluster와 user를 지정해주면 결국 user@cluster의 형식으로 context가 설정된 것이고 context에서 설정된 user는 users에서 설정된 user의 이름과 동일해야한다.
- current-context 섹션을 이용해 Default context 즉, 기본 컨텍스트도 지정 가능하다.
- 위와 같이 config 파일만 설정을 하면 어떤 개체도 설정할 필요가 없이 kubectl 명령어에 의해서 읽히게 된다.
- 즉, 별다른 kubectl apply 명령어나 kubectl create 명령어로 생성할 필요 없이 kubectl 을 사용만 해도 해당 config 파일을 읽는다는 이야기이다.
- kubectl config view 명령어를 입력하면 현재 설정되어 있는 config 파일을 확인할 수 있다.
- 또한 새로운 config 파일을 구성한 후 해당하는 config 파일로 kubectl 명령어를 수행 가능하다.
- 해당하는 my-custom-config 파일을 홈 디렉터리/.kube/config 파일로 대체하게되면 해당하는 내용으로 kubectl을 수행하고 cluster, context, user 정보를 참조하게 된다.
- kubectl config use-context prod-user@production 명령어를 사용하게 되면 current-context 항목이 변경되게 된다.
- config 파일을 이용해서 context에 default namespace도 명시할 수 있다.
- config에서 인증서를 등록해 사용할 때 위와 같이 절대 경로로 입력해주는 것이 좋다.
- 인증서를 파일로 구성하지 않고 base64로 인코딩 된 문자열을 직접 입력하여도 상관없다.
API Groups
- 쿠버네티스 API가 무엇인지 알아야한다.
- 쿠버네티스는 클러스터와 상호 작용하는 모든 작업은 kubectl을 통하거나 REST를 통하는 방식으로 어떤 방식으로든 API 서버와 상호 작용했다.
- 예를 들어 버전을 확인 하려면 마스터 노드 뒤에 기본적으로 6443 포트 및 api 버전을 입력해 API 서버로 URL 통신을 하곤 했다.
- 이러한 API 버전 및 API는 목적에 따라 여러 그룹으로 구분된다.
- 예를 들어 버전을 확인하려면 api 주소:6443/api/v1/version 이런 방식으로 API 서버에 액세스해서 버전을 얻는다.
- 이와 같이 목적에 따라 여러 그룹으로 분리가 된다.
- 이 API는 core 그룹과 named 그룹으로 분리가 된다.
- Core 그룹의 경우 namespaces, pod, replication controller, events 등등과 같은 모든 핵심 기능이 있다.
- named 그룹 API는 더 많은 구성이 있다. apps, extension, networking, storage 등
- 네트워크 내에서는 networkpolicies 가 있다.
- /apis 바로 밑에 위치한 항목들이 API Groups의 리소스이다. 이 리소스 각각은 해당되는 동작 집합이 있다.
- 이 리소스와 수행할 수 있는 작업들에 대한 동작이다.
- 예를들어 deployments의 경우 list, get, create, delete 등등의 이 작업들을 일컫는다.
- 이를 Verbs라고 한다.
- 쿠버네티스 API Docs에는 각 객체에 대한 API 그룹이 무엇인지 확인할 수 있다.
- API server에 경로 없이 요청을 보내면 사용 가능한 API Group의 리스트를 전부 출력 해준다.
- grep 을 이용해서 원하는 특정 그룹을 검색할 수도 있습니다.
- API 서버에 직접 curl로 액세스하는 경우 특정 API를 제외하고는 인증 메커니즘을 지정하지 않아서 액세스가 허용되지 않는다.
- 따라서 인증 파일을 명령어에 입력해 API에 인증해야 한다.
- 다른 방법으로는 kubectl proxy를 이용해 로컬 프록시 서비스를 시작해 kube config 파일에서 자격 증명 및 인증서를 사용해 클러스터에 액세스한다.
- 이렇게 하면 curl 명령에서 인증서를 지정할 필요가 없다.
- 우리가 알아야할 점은 쿠버네티스의 모든 리소스는 서로 다른 API 그룹으로 그룹화 된다는 사실이다.
- 최상위에는 Core, Named API Group이 있고, named API group 아래 섹션마다 다양한 리소스가 있고 각 리소스에는 verbs라는 관련 작업 모음이 있다.
Authorization
- 누군가가 클러스터에 한 번 액세스를 얻으면 무엇을 할 수 있을까? 이것이 권한(Authorization)이 정의하는 것이다.
- 권한은 관리자, 개발자, 테스터 또는 모니터링 애플리케이션, 지속적 전달 애플리케이션과 같은 다른 응용프로그램들도 클러스터에 액세스하기 때문에 그들이 클러스터에 각기 다른 행동들을 할 수 있게끔 액세스를 분리하기 위해서 필요하다.
- Service Account도 마찬가지로 외부 응용 프로그램이 필요한 작업을 수행하는 데 필요한 최소한의 액세스만 제공하길 원한다.
- 클러스터를 여러 조직 또는 팀 간에 논리적으로 분할해 네임 스페이스를 사용하여 공유하는 경우 사용자에게는 해당 네임스페이스에 대한 액세스를 제한하는 것으로 권한을 분리할수도 있다
- 쿠버네티스에서는 Node 권한, ABAC, RBAC, Webhook 과 같은 권한 메커니즘을 지원한다.
- kube-apiserver은 관리 목적으로 사용자 및 클러스터 내 노드의 kubelet에 의해 액세스된다.
- kubelet은 클러스터 내에서 관리 프로세스를 위해 API 서버에 액세스한다.
- kubelet은 서비스 및 엔드포인트, 노드 및 파드에 대한 정보를 읽기 위해 API 서버에 액세스한다.
- kubelet이 kube-apiserver에 하는 요청은 노드 권한 부여자(Node Authorizer)라고 알려진 특수한 권한 부여자에 의해 처리된다.
- kubelet은 시스템 노드 그룹(systems:node:)에 속해야하고 시스템 노드로 접두사가 지정된 이름을 가져야한다. 따라서 이름이 시스템 노드로 시작하고 시스템 노드 그룹의 일부인 사용자로부터의 요청은 노드 권한 부여자에 의해 승인되며 이러한 권한이 kubelet에 필요하다. 이것이 클러스터 내에서의 액세스이다.
- 이제 API에 대한 외부 액세스에 대해 이야기 해보자
- 속성 기반 권한(Attribute Based Access Control)은 사용자나 사용자 그룹에 일련의 권한을 연결하는 곳이다. 이 경우 개발자는 리소스에 대한 권한을 얻게 된다.
- 특정 형식으로 정의된 정책 집합과 함께 정책 파일을 생성해 API 서버에 파일을 넘기면 정책이 적용 돼 특정 사용자는 특정 권한을 갖게 된다.
- 다만 보안에 변경이 필요할 때마다 매번 이 정책 파일을 수동으로 편집하고 kube-apiserver를 다시 시작해야 하기 때문에 관리하기 어렵다.
- 역할 기반 접근 제어(Role Based Access Control) 는 사용자나 그룹을 직접 권한과 연결하는 대신 사용자를 위한 역할을 정의한다.
- 우리는 필요한 권한 세트로 개발자를 위한 역할을 만들고 그 역할에 모든 개발자를 연결한다. 마찬가지로 보안 사용자를 위한 올바른 권한 세트로 역할을 만들고 사용자를 해당 역할에 연결한다.
- 앞으로 사용자의 액세스를 변경해야 할 때마다 역할만 수정하면 되며 이는 즉시 모든 개발자에게 반영된다.
- 역할 기반 접근 제어는 클러스터 내에서 액세스를 관리하는 더 표준적인 접근 방식을 제공한다.
- 모든 권한 부여 메커니즘을 외부에서 관리하고 방금 언급한 내장 메커니즘을 통해 관리하지 않고 싶다면 어떻게 할까? Open Policy Agent는 이를 지원하는 서드파티 도구이다.
- 쿠버네티스는 사용자 및 사용자의 액세스 요구 사항에 대한 정보를 Open Policy Agent에게 API 호출을 수행하도록 설정할 수 있으며 Open Policy Agent는 사용자의 허용 여부를 결정할 수 있다. 이 응답에 근거해 사용자는 액세스 권한을 부여 받는다.
- Authorization Mode는 또한 AlwaysAllow , AlwaysDeny도 있다.
- AlwaysAllow는 권한 확인을 수행하지 않고 모든 요청을 허용한다.
- AlwaysDeny는 항상 모든 요청을 거부한다.
- 여러 모드를 구성하는 경우 요청은 지정된 순서대로 각 모드를 사용하여 승인된다.
- 예를 들어 mode가 Node, RBAC, webhook 순서대로 되어 있다면 Node Authorizer가 처리하고, Node Authorizer는 노드 요청이 거절될 시 다음 모듈인 RBAC에게 승인을 확인하고, 승인이 되면 더는 확인하지 않고 사용자가 승인을 받는다.
- 이 처럼 요청이 거부되면 체인의 다음 모듈로 전달 돼 다시 확인한다. 그리고 요청이 승인되는 순간 사용자는 승인을 받는다.
Role Based Access Controls
- RBAC는 어떻게 역할을 생성할까?
- kind: Role 과 apiVersion: rbac.authorization.k8s.io/v1 으로 설정한 파일을 생성해 규칙을 지정해준다.
- 규칙은 rules 항목에 있으며, Core 그룹의 경우 apiGroups 섹션을 비워둘 수 있다. 다른 그룹의 경우 해당 그룹 이름을 지정해준다.
- 위의 예시는 개발자에게 액세스 권한을 부여하려하고 리소스는 파드이며, 수행할 수 있는 동작은 lsit, get, create, update, delete이다.
- pods 에 대한 권한 밑에는 configmap에 대한 권한이며 이처럼 단일 역할에 여러 rules를 추가할 수 있다.
- 위에서는 Role을 생성했으니 이제 Role을 사용자에 연결해야한다. 이를 위해 RoleBinding이라는 객체를 생성해야한다.
- subjects 섹션은 사용자 세부 정보를 지정하는 곳이며, roleRef 섹션에서는 우리가 만든 롤의 세부 사항을 제공하는 곳이다.
- 또한 Role과 RoleBinding은 네임스페이스의 범위에 속한다는 것을 알아야 한다.
- 위의 예시로 보면 namespace를 따로 지정하지 않았기 때문에 default 네임 스페이스로 리소스가 할당이 된다.
- 역할이나 역할 바인딩을 확인하기 위한 명령어는 아래와 같다.
kubectl get roles
kubectl describe roles
kubectl get rolebinding
kubectl describe rolebinding
- describe 명령어로 확인하게 되면 각 리소스 별 리소스 및 권한에 대한 세부 정보를 확인할 수 있다.
- 사용자가 클러스터의 특정 리소스에 접근할 수 있는지 확인하고 싶다면 어떻게 해야 하는 가?
kubectl auth can-i <동작> <리소스>
kubectl auth can-i create deployments
- 체크는 auth can-i 명령로 확인하면 된다.
- 그리고 --as <사용자> 옵션과 함께 사용하게 되면 특정 사용자를 선택해 해당 사용자가 작업을 할 수 있는 지 확인할 수 있다.
Cluster Roles and Role Bindings
- Role과 Role Binding은 네임스페이스의 범위에 속한다고 했었다.
- 그러면 노드 같은 클러스터 범위의 리소스는 어떻게 관리해야 하는가?
- 클러스터 범위의 리소스는 노드나 PV 처럼 생성 시 네임스페이스를 지정하지 않는다. 네임스페이스의 범위에 속하지 않기 때문이다.
- kubectl api-resources --namespaced=<boolean> 명령어를 이용하면 네임스페이스와 네임스페이스가 아닌 리소스 전체 목록을 볼 수 있다.
- 노드나 PV와 같은 클러스터 간 리소스는 사용자에게 Cluster Role 과 Cluster RoleBinding을 이용해서 권한을 부여한다.
- ClusterRole은 클러스터 범위의 리소스에 대한 역할인 것만 제외하면 Role과 동일하다.
- 가령, Cluster Admin 역할은 클러스터 관리자 권한을 제공하기 위해 생성될 수 있다. 예를 들면 클러스터에서 노드를 보거나 생성, 삭제할 수 있도록
- PV와 PVC를 생성 및 관리하기 위해서 Storage Admin 역할을 생성할 수도 있다.
- ClusterRole 에 대한 파일을 생성하고 Role과 유사하게 규칙을 지정한다.
- 위의 예시에서는 node에 대한 권한을 관리하기 위해 resources 섹션은 nodes가 된다.
- 또 이를 사용자를 연결하기 위해서 ClusterRoleBinding을 생성해서 연결해야한다.
- 동일하게 subjects 아래에 사용자 세부 정보를 지정하고 roleRef 아래에 우리가 만든 ClusterRole에 관해 상세히 제공해준다.
- clusterRole과 clusterRoleBinding은 클러스터 범위 리소스에 사용된다고 했지만, 이는 엄격한 규칙은 아니다.
- 클러스터 역할을 namespaced 리소스에 대해 만들 수도 있다.
- 이렇게 하면 사용자가 모든 네임스페이스에서 리소스에 액세스할 수 있게 된다.
- 이전에 사용자에게 파드에 액세스할 권한을 부여하려면 사용자는 특정 네임스페이스의 파드에만 액세스할 수 있었다.
- 그러나 clusterRole을 사용하면 사용자가 클러스터 전체의 모든 파드에 액세스할 수 있다.
- kubernetes는 클러스터가 처음 설정될 때 기본적으로 여러 clusterRole을 생성한다.
반응형
'자격증 > Kubernetes CKA' 카테고리의 다른 글
[CKA] Storage (0) | 2023.12.19 |
---|---|
[CKA] Security - 3 (0) | 2023.12.18 |
[CKA] Security - 1 (0) | 2023.12.12 |
[CKA] Cluster Maintenance (0) | 2023.12.04 |
[CKA] Practice Test - Rolling Updates And Rollbacks (0) | 2023.12.03 |