Cka 정리4
CKA 정리4
144: TLS in Kubernetes
TLS 인증서로 k8s 클러스터를 보호하는 방법을 다룬다. 서버가 public & private key를 이용해서 ssh 연결을 보호하는 방법을 배웠는데 이를 server certificate라고 한다. CA(Certificate Authority)에서 서버 인증서에 서명하는 데 사용하는 CA 자체의 public & private key pair 집합이 있고 이를 root certificates라고 한다.
인증서는 세 가지 유형이 있다.
- 서버에 구성된 서버 인증서
- CA 서버에 구성된 root 인증서
- 클라이언트에 구성된 클라이언트 인증서
인증서가 여러개지만 네이밍 규칙을 알고 있다면 인증서를 구분할 수 있다.
- public key가 있는 인증서는 .crt 혹은 .pem 이다
- 서버 인증서는 server.crt 또는 server.pem
- 클라이언트 인증서는 client.crt 혹은 client.pem
- private key에는 대체로 이름에 ‘-key’ 가 있다.
- server.key, server-key.pem
이런 키 개념이 k8s에는 어떻게 적용될까?
- 마스터-워커 노드간의 통신의 암호화
- 모든 서비스와 클라이언트간 상호 작용의 암호화
- kubectl cli 혹은 kube-apiserver에 접근해 k8s 클러스터와 상호작용할 때 TLS 필요
- k8s 클러스터 내 모든 컴포넌트간 통신
위 요구사항에 따라 두 인증이 필요하다
- Server Certificates for Servers
- Client Certificates for Clients
서버 컴포넌트
kube-apiserver
- API서버는 서버이며 다른 컴포넌트 클라이언트들과 모든 통신을 보호하려면 인증서가 필요하다 etcd-server
- 또 다른 서버로 etcd 서버가 있고 역시 한 쌍이 존재한다. kubelet
- 워커 노드에 존재하는 서버
클라이언트 컴포넌트
- kube-apiserver에 접근하는 클라이언트는 kubectl API를 통해 관리하는 관리자인 우리이다.
- admin 사용자는 kube-API 서버에 인증하기 위해 인증서와 키 쌍이 필요하다
- admin.crt와 admin.key라고 하겠다.
- scheduler
- kube-apiserver와 통신해 스케쥴링이 필요한 파드를 찾아 API서버가 올바른 워커 노드에서 파드를 예약하도록 한다.
- 서버 입장에서 scheduler도 admin처럼 그냥 일반 사용자이다
- kube controll manager
또한 서버는 그들 사이에서도 통신한다 kube-apiserver와 etcd가 통신하는데 etcd는 오직 kube-apiserver과 통신한다. etcd가 서버, kube-apiserver가 클라이언트가 될 수 있다.
인증서를 그룹 지으면 다음과 같다.
- Client Certificates set
- client가 kube-apiserver에 연결하기 위해 사용
- Server Site Certificates
- kube-apiserver, etcd 서버 및 kubelet이 클라이언트들을 인증하는데 사용
인증서 생성은 CA(Certificate Authority)가 필요하다.
- k8s는 클러스터에 적어도 하나 이상의 CA를 요구한다. 2개를 가질 수도 있다
- CA에는 자체 인증서와 키 쌍이 있고 이것이 바로 ca.crt와 ca.key이다 (etcdctl cli 명령어 날릴 때 이를 제공하는 이유)
145: TLS in K8s - Certificate Creation
Generate Certificates
인증서 생성에는 OpenSSL, Easy-RSA CFSSL 등 다양한 툴 이용 가능 (여기선 OpenSSL 이용)
Certificate Authority (CA)
private key 만들기
- $ openssl genrsa -out ca.key 2048 생성한 private key와 함께 CSR(인증서 서명 요청) 생성하기
- $ openssl req -new -key ca.key -subj “/CN=KUBERNETES-CA” -out ca.csr
- 서명 요청은 인증서랑 세부정보부터 모두 같지만 서명이 없는 상태이다. 또한 파라미터로 Common Name(CN) 필드에 인증서의 컴포넌트 이름을 지정한다. k8s CA에 대한 인증서를 생성하므로 KUBERNETES-CA이다.
생성한 CSR을 이용해 인증서에 서명한다
Generate Client Certificates
Admin User Certificates
admin user를 먼저 만들건데 위에서 수행한 프로세스와 같다.
- $ openssl genrsa -out admin.key 2048
- $ openssl req -new -key admin.key -subj “/CN=kube-admin” -out admin.csr 다만 위에서 생성한 CA 인증서와 key를 함께 넣어준다. 이렇게 하면 클러스터 내에서 유효한 인증서가 된다
- $ openssl x509 -req -in admin.csr -CA ca.crt -CAkey ca.key -out admin.crt 이렇게 생성한 관리자 인증서는 관리자가 k8s 클러스터에 여러모로 인증하는데 사용할 인증서이다.
위처럼 키와 인증서 쌍을 생성하는 과정은 새 사용자를 위한 사용자 계정을 만드는 것과 비슷하다
- 인증서는 검증된 사용자 ID이고 키는 passwd와 같아 단순한 username과 pwd보다 훨씬 안전하다
+인증서에 사용자 그룹을 지정해 넣을 수 있고 이를 통해 일반 유저와 관리자 유저를 구분할 수 있다. ex) $ openssl req -new -key admin.key -subj “/CN=kube-admin/O=system:masters” -out admin.csr
- 이름만 admin이던 admin 유저에 system master 권한이 추가되었다.
동일한 절차로 kube-apiserver에 접근하는 다른 모든 컴포넌트에 대해 클라이언트 인증서를 생성한다. 시스템 컴포넌트 kube-scheduler, kube-controller-manager는 이름 앞에 system이라는 키워드가 붙어야 한다.
이제 이 인증서로는 무엇을 할 수 있을까? kube-apiserver에 대한 REST API 호출에서 username과 pwd 대신 이 인증서를 이용할 수 있다.
- key, certificate CA 인증서를 옵션으로 지정
- 혹은 모든 파라미터를 kubeconfig라는 configuration 파일로 옮겨 미리 지정한다
- API 서버 endpoint detilas
- 사용할 인증서
클라이언트-서버 서로의 인증서 유효성을 검증할 때 내장된 CA의 공개 키가 필요하다고 했었고 지금에도 동일하다. 웹 애플리케이션의 경우에는 사용자 브라우저에 이미 있다.
마찬가지로 k8s에서 다양한 컴포넌트가 서로를 확인하려면 모두 CA의 root certificate 사본이 필요하다. 따라서 인증서가 있는 서버나 클라이언트를 구성할때마다 CA root certificate도 지정해야한다.
Generate Server Certificates
ETCD Server certificate
ETCD 인증서를 생성하는건 이전과 동일하다 etcd는 HA(Hight Availability) 고가용성 환경이라면 여러 섭에 걸쳐 클러스터로 배포될 수 있다. 이 경우 보호를 위해 추가 peer 인증서를 생성해야한다.
Kube API-SERVER
kube-apiserver를 모든 컴포넌트들이 사용한다. 다들 각자의 이름으로 부를 수 있다. aliases
- kubernetes
- kubernetes.default
- kubernetes.default.svc
- kubernetes.default.svc.cluster.local (full name)
- 10.96.0.1 이런 모든 이름들은 kube-apiserver 용으로 생성된 인증서에 명시돼있어야 한다.
그러나 모든 alternate name(alias)를 cli로 지정할 수는 없는 노릇이다. 이를 위해 CSR에 OpenSSL config 파일을 만들어 openssl.cnf로 넘겨준다.
Kubelet
kubelet은 각 노드에서 실행되는 서버이다. 그렇다는건 apiserver는 가 노드에 대한 키 인증서 pair가 필요하다는 것을 알 수 있다. 인증서의 이름은 node01, node02, node03처럼 노드이름을 따서 지정된다.
- kubelet 또한 시스템 컴포넌트이므로 system:node:node02 처럼 형식을 맞춰야한다
146: View Certificate Details
클러스터에서 인증서를 확인하는 방법
View Certs
전체 클러스터에 있는 모든 인증서의 상태 확인을 수행해야할때 어떻게 해야할까? 우선 클러스터 설정을 확인해야한다.
- 까다로운 설정: 모든 컴포넌트를 노드에 service로 배포한 상황
- $ cat /etc/kubernetes/manifests/kube-apiserver.yaml 을 확인하면 key, 인증서 등등이 어디에 있는지 확인 가능하다
이후 각 인증서를 가져와 내부를 살펴보고 detail을 찾는다.
- $ openssl x509 -in /etc/kubernetes/pki/apiserver.crt -text -noout
인증서 이름: Subject 대체 이름: DNS, IP Address 확인 인증서 발급자: Issuer 확인
- kubeadm은 k8s CA의 이름을 kubernetes 자체로 지정
Inspect Server Logs - Hardware setup
kubeadm이 아닌 native service로 구동한 경우 OS 로깅 기능으로 서비스 로그를 살펴야함
- $ journalctl -u etcd.service -l
Inspect Server Logs - kubeadm setup
kubeadm으로 클러스터를 설정하는 경우 다양한 컴포넌트가 파드로 배포된다. 다음 명령어로 확인 가능
- $ kubectl logs {파드이름}
- ex) $ kubectl logs etcd-master
k8s API 서버 혹은 etcd 서버와 같은 코어 컴포넌트가 다운되면 kubectl이 먹지 않으므로 더 한단계 내려가야한다.
- $ docker ps -a
- $ docker logs container-id
150: Certificates API
인증서 관리방법과 k8s의 인증서 API에 대하여
우리가 유일한 k8s 관리자이자 사용자이며 관리다 인증서와 키를 가지고 있을 때 신규 관리자가 들어왔다 생각해보자
클러스터에 접근할 수 있게 인증서와 키가 필요하다. 그녀는 private key를 만들고 인증서 서명 요청(CSR)을 보내왔다.
우리는 유일한 관리자이므로 우리의 CA 서버로 인증서 서명 요청을 받고 CA 서버의 private key와 인증서 경로를 기입해 CA 서버에서 서명을 받아 인증서를 생성한 다음, 인증서를 그녀에게 다시 보낸다. 이제 그녀는 클러스터에 액세스하는 데 사용할 수 있는 유효한 인증서와 키 쌍을 갖게 되었습니다.
+인증서에는 유효기간이 있어 만료전에 새로운 CSR을 받고 CA로부터 인증서를 갱신해야한다.
CA(Certificate Authority)
ca는 권한을 부여하고 서명하는 매우 중요한 장치로 인증서와 키이다. 이 파일 쌍에 접근할 수 있는 권한을 얻은 사람은 누구나 k8s 환경의 모든 인증서에 서명할 수 있다. 원하는 권한을 가진 사용자를 원하는만큼 만들어낼 수 있다. 그렇다면 이런 파일 쌍의 절대적 권한에 대한 안전이 보장되는지 의문이 생길 수 있다.
CA 인증서와 키를 안전한 다른 서버에 보관한다고 생각하자. 이제 이 서버가 CA서버가 되고 인증서에 서명할때마다 해당 서버에 접속해야 서명할 수 있다. 현재 마스터 노드에 CA파일이 위치하므로 마스터 노드는 CA 서버이다.
여태 수동으로 서명했으나 유저가 늘어남에 따라 인증서, 서명 요청을 관리하고 만료시 교채하는 자동화가 필요하다
k8s에는 이를 수행하는 인증서 API가 내장돼있다. flow
- 인증서 API로 API 호출을 날려서 k8s에 CSR을 요청
- CSR을 받으면 관리자가 마스터 노드에 로그인해 인증서에 직접 서명받는 대신 “인증서 서명 요청”이라는 8s API object를 만든다
- 오브젝트가 생성되면 클러스터 관리자가 모든 인증서 서명 요청을 확인해 볼 수 있고 kubectl 커맨드를 이용해 확인하고 승인할 수 있다
- 이후 승인한 인증서를 추출해 사용자에게 반환할 수 있다
신규 유저 Jane을 예시로 해보자 사용자는 키를 만든다
- $ openssl genrsa -out jane.key 2048 Jane은 자신의 이름 키를 이용해 인증서 서명 요청을 생성하고 요청을 관리자에게 보낸다.
- $ openssl req -new -key jane.key -subj “/CN=jane” -out jane.csr
관리자는 키를 가져와 인증서 서명 오브젝트를 만든다. apiVersion: certificates.k8s.io/v1beta1 kind: CertificateSigningRequest metadata: name: jane spec: groups: - system: authenticated usages:
- digital signature
- key encipherment
- server auth request: certificate-goes-here
kind는 CertificateSigningRequest이다. spec에서 사용자가 속해야 하는 그룹을 지정하고 usage들도 정해준다
reuqest 필드에는 사용자가 보낸 인증서 서명 요청을(jane.csr 파일) 지정한다(CSR). 일반 텍스트가 아닌 base64로 인코딩한 CSR을 넣어야 한다.
$ cat jane.csr base64
jane-csr.yaml파일을 통해 오브젝트가 생성되면 다음 커맨드로 인증서 서명 요청을 확인해 볼 수 있다.
- $ kubectl get csr
새요청을 식별하고 요청을 승인한다
- $ kubectl certificate approve jane
k8s는 CA 키 쌍을 사용해 인증서에 서명하고 신규 유저를 위한 인증서를 생성한다. 이 인증서를 추출해 사용자에게 공유할 수 있다.
위 과정이 어떻게 작동하는지는 알겠는데 누가 이 작업을 하는걸까? 실제 모든 인증서 관련 작업은 Controller Manager가 수행한다. 내부에 CSR 승인, CSR 서명 등 특정 작업을 수행하는 컨트롤러가 있다.
어떤 인증서에 서명하기 위해서는 CA root의 인증서와 private key가 필요하다 Controller Manager service configuration에는 이를 지정하는 두 옵션이 있다.
153: KubeConfig
클라이언트는 ca 인증서와 유저의 인증서 & private key가 있다면 k8s REST API에 http 요청하거나 kubectl 명령어를 이용해 파드 목록을 얻을 수 있다.
이렇게 여러 인증서들과 키를 전달하는건 번거로우니 정보들을 kubeconfig 옵션에 config 파일로 지정할 수 있다.
- $ kubectl get pods —kubeconfig config
그런데 default로 kubectl tool은 .kube 디렉토리에서 config라는 파일을 찾는다. 즉, 그곳에 갖다놓으면 kubectl command에서 파일 경로를 명시적으로 지정하지 않아도 된다.
Kubeconfig File
kubeconfig 파일은 특정 형식을 가지고 있다. config 파일에는 세 섹션이 있다
- clusters
- 접근해야하는 다양한 k8s 클러스터이다. DEV ,TEST, PROD 환경이나 다른 조직 등 여러 클러스터가 있을 수 있다.
- users
- 클러스터에 접근할 수 있는 사용자 계정이다. admin user, dev/prod , …
- contexts
사용자의 권한을 지정하고 접근가능한 클러스터를 정의하면 모든 kubectl 커맨드에서 사용자 인증서와 서버 주소를 지정하지 않아도 된다.
위처럼 context는 user와 cluster를 실제로 @로 join해서 저장한다.
kubeconfig 파일에 current-context 필드를 추가하여 사용할 default 컨텍스트를 지정할 수 있다. 이 경우 kubectl은 항상 dev-user@google 컨텍스트를 사용하여 Google 클러스터에 액세스합니다.
kubectl 커맨드를 사용해 kubeconfig 파일을 열고 수정할 수 있다.
- $ kubectl config view
- 클러스터의 contexts, user 그리고 사용중인 현재 context 또한 보여준다
- 특정 config를 지정해 보여줄 수도 있다
- $ kubectl config veiw –kubeconfig=my-custom-config
current context는 어떻게 업데이트할까? 같은 production 클러스터 환경에 유저를 my-kube-admin에서 prod-user로 바꿔서 접근가능하게 하고 싶다.
prod-user의 context로 전환
- $ kubectl config use-context prod-user@production
Namespace는?
클러스터를 내 여러 namespace들이 있는데 특정 namespace로 전환하도록 context를 구성할 수 있을까?
kubeconfig 파일의 context 섹션은 특정 네임스페이스를 지정할 수 있는 namespace라는 추가 필드를 사용할 수 있다. 이렇게 하면 해당 컨텍스트로 전환할 때 자동으로 특정 네임스페이스에 있게 된다
+config와 인증서 clusters-cluster 의 certificate-authority 필드에 ca.crt 인증서를 절대경로로 제공할 수 있다. 하지만 certificate-authority-data 필드에 인증서를 base64 인코딩해서 넣어버릴수도 있다
157: API Groups
k8s API란 무엇인가 지금까지 클러스터에서 수행한 작업은 kubectl 혹은 REST를 통해 직접 API 서버와 상호작용했다. 우리는 “마스터 노드 주소” + 6443포트(default) + API version으로 API 서버에 접근할 수 있다. ex) 버젼을 반환하는 API
- $ curl https://kube-master:6443/version ex) 파드 목록을 반환하는 API
- $ curl https://kube-master:6443/api/v1/pods
k8s API는 목적에 따라 APIs, healthz, metrics, logs 등 여러 그룹으로 그룹화된다.
- Metrics와 Health API는 클러스터의 상태를 모니터링하는 데 사용된다
- logs는 타사 로깅 애플리케이션과 통합하는 데 사용된다.
API and APIs
API는 core 그룹과 named 그룹 두개로 분류된다. 코어 그룹에는 다음 그림처럼 모든 핵심 기능이 존재한다
named 그룹 API는 더욱 체계화돼있고 앞으로 named 그룹을 통해 모든 최신 기능을 사용할 수 있게 된다.
- API Groups 그리고 Resources, Verbs가 있다.
- 큰 상위 카테고리인 그룹이 있고 하위에 리소스 그리고 리소스로 수행할 수 있는 작업들이다.
- networking.k8s.io에는 네트워크 정책이 있고 certificates.k8s.io에는 인증서 서명 요청(CSR)이 있다.
curl을 통해 kube API에 접근해 코어의 버젼과 사용가능한 API 그룹을 알 수 있다.
- $ curl http://localhost:6443 -kl # API 버젼 알 수 있음
- $ curl http://localhost:6443/apis -k | grep “name” # API 그룹 내에서 지원되는 모든 리소스 그룹을 반환한다.
Kube API server 접근 시 참고사항
- curl을 통해 직접 API에 접근하는 경우 인증을 거치지 않았으므로 버젼과 같은 특정 API를 제외하고는 접근이 허용되지 않는다.
- 유저의 인증서와 private key 그리고 CA의 인증서를 넘겨주면 권한 문제를 해결할 수 있다.
혹은 다른 방법이 있는데 그것은 바로 Kube Control Proxy Client를 시작하는 것이다.
- kubectl proxy 커맨드는 로컬로 8001포트에서 프록시 서비스를 시작하고 kube configuration 파일의 자격 증명과 인증서를 사용하여 클러스터에 접근한다.
- 이제 8001 포트에서 kubectl proxy 서비스에 접근할 수 있게 된다.
kube proxy vs kubectl proxy
위 둘은 같지 않다.
- kube proxy: 클러스터의 여러 노드에서 파드와 서비스간 연결을 활성화하는 데 사용된다
- kubectl proxy: kube-apiserver에 접근하기 위해 kubectl 유틸리티에서 만든 http proxy 서비스이다
+k8s의 모든 리소스는 서로 다른 API 그룹으로 묶인다. 최상위에 core API 그룹과 named API 그룹이, namepd API 그룹은 하위에 섹션마다 있다. 서로 다른 resources가 있고 verb라는 작업들이 있는데 각 작업과 사용자를 묶어 접근 제한하거나 허용하는 것을 알아보자
158: Authorization
사람 또는 머신이 클러스터에 접근하는 방법을 여태 알아보았다. 접근한 뒤에는 어떤 작업들을 할 수 있을까? Authorization은 이것들을 제한한다.
Cluster에 Authorization이 필요한 이유
클러스터 관리자는 pod, node, deployment같은 다양한 오브젝트에 대한 get, create, delete 등 다양한 종류의 작업을 할 수 있다.
- $ kubectl get nodes
- $ kubectl get pods
- $ kubectl delete node worker-2
관리자는 모든 작업을 할 수 있으나 다른 관리자, 개발자 ,테스터, 모니터링 앱, jenkins 등 다른 유저들 또한 클러스터에 접근할 것이다. 우리는 이들 모두가 관리자 수준의 액세스 권한을 갖길 원하지 않는다. 그렇기 때문에 username/passwd 혹은 토큰 혹은 서명된 TLS 인증서 혹은 서비스 계정을 생성해 제한할 것이다.
- ex1) 개발자가 노드 추가/삭제, 스토리지 혹은 네트워킹 config과 같은 클러스터 설정을 볼 수는 있지만 수정할 수 없게 제한하고 애플리케이션 배포에 접근할 수 있게 한다.
- ex2) 서비스 계정을 통해 작업을 수행하는 데 필요한 최소한 권한만 외부 애플리케이션에 제공. 다른 조직이나 팀간 클러스터를 고유할 때 namespace를 사용해 클러스터를 논리적으로 분할.
Authorization Mechanisms
- Node Authorization
- Attribute-based Authorization (ABAC)
- Role-Based Authorization (RBAC)
- Webhook
Node Authorization
노드 정보를 kube-apiserver에 보고하는데 이러한 요청은 node authorizer라는 특수 authorizer가 처리한다. 인증서에 대해 얘기할 때 kubelet은 시스템 노드 그룹의 일부여야 하며 system:node:node01 접두사가 붙는 이름을 가져야 한다고 했었다.
ABAC
위처럼 policy 파일을 만들어서 정책을 API 서버 초기화할 때 함께 전달한다. 파일 내 각 사용자 또는 그룹에 대한 정책 정의 파이릉ㄹ 만들고 보안 정책을 추가하거나 변경할 때마다 이 파일을 편집하고 kube-apiserver를 다시 시작해야한다. 속성 기반 접근 컨트롤은 관리하기 어렵다.
RBAC
역할 기반 액세스 제어는 훨씬 쉬워진다. 사용자/그룹을 권한 묶음에 직접 연결하는 대신 사용자를 위한 역할을 정의한다. 권한 세트로 역할을 만든 뒤 필요한 사람들을 해당 역할에 연결한다. 사용자 액세스를 변경해야할 때 역할을 수정하기만 하면 사용자들에게 즉시 반영된다. (이것이 표준적인 방식임)
Webhook
기본 제공 매커니즘을 통하지 않고 외부에서 authorization을 관리하는 걸 가정하자 Open Policy Agent를 통해 API 호출을 도울 수 있다.
+추가로 두 방식이 더 있다.
모드는 kube-apiserverdp서 –authorization-mode 옵션을 사용해 설정됨. default는 AlwaysAllow이며 여러개를 지정할 수 있는데 이 경우 순서대로 처리함 –authorization-mode=Node,RBAC,Webhook 일 경우 노드 authorizer가 검사하고 RBAC에 넘김 중간에 승인이 발생하면 더 이상 확인하지 않고 권한 부여
159: Role Based Access Controls
RBAC을 더 자세히 보자
역할 생성
역할 object를 생성해 수행한다. apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: developer rules:
- apiGroups: [””] # “” indicates the core API group resources: [“pods”] verbs: [“get”, “watch”, “list”, “update”, “delete”, “create”]
apiGroups: [””] # “” indicates the core API group resources: [“ConfigMap”] verbs: [“create”]
- $ kubectl create -f developer-role.yaml
역할과 사용자를 연결하기
롤 바인딩이라는 또 다른 오브젝트를 만들어야 한다
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: devuser-developer-binding subjects:
- kind: User name: dev-user apiGroup: rbac.authorization.k8s.io roleRef: kind: Role #this must be Role or ClusterRole name: developer apiGroup: rbac.authorization.k8s.io
subject는 유저 정보를 지정하는 곳이고 roleRef는 생성한 역할 정보를 제공하는 곳이다.
- $ kubectl create -f devuser-developer-binding.yaml
역할 확인
역할 확인
- $ kubectl get roles 롤 바인딩 확인
- $ kubectl get rolebindings 역할에 대한 자세한 정보 확인
- $ kubectl describe role developer
imperative way
- $ kubectl create role foo –verb=get,list,watch –resource=rs.apps
- $ kubectl create rolebinding admin-binding –role=admin –serviceaccount=monitoring:sa-dev
접근 가능 여부 확인
사용자가 클러스터의 특정 리소스에 접근할 수 있는지 확인하는 방법이 있다
- $ kubectl auth can-i create deployments
- $ kubectl auth can-i delete nodes
관리자의 경우 다른 유저의 권한을 확인할 수 있다
- $ kubectl auth can-i create deployments –as dev-user
- $ kubectl auth can-i create pods –as dev-user –namespace test
Resouce Names
더 아래로 내려가서 namespace에 모든 파드가 아니라 이름을 명시해 특정 리소스에만 가용하도록 제한할 수도 있다
+kube-apiserver의 authorization-mode를 확인하려면 $ cat /etc/kubernetes/manifest/kube-apiserver.yaml
162: Cluster Roles and Role Binding
롤과 롤바인딩이 있듯 클러스터 롤과 클러스터 롤바인딩 또한 존재한다.
Roles
롤과 롤바인딩은 namespace 안에서 작용합니다. namespace를 지정하지 않으면 default namespace에 생성되며 해당 namespace 내에서만 접근을 제어합니다.
Namespaces
namespace가 pods와 deployments & services과 같은 리소스를 묶거나 격리하는 데 사용되는 걸 배웠다. 그러나 Node는 특정 namespace에 연결할 수 없다. namespace 내에 노드를 그룹화하거나 격리할 수 없다. 즉, 리소스는 namespace 혹은 클러스터 범위로 분류된다. namespace resource: ReplicaSets, jobs, deployments, services, secrets, … cluster resource: cluster role, cluster role binding, Nodes, persistent volume (namespace 지정 않는 리소스)
namespace가 지정된 리소스와 namespace의 구애를 받지 않는 리소스의 전체 목록을 보려면 kubectl 커맨드로 볼 수 있다.
- $ kubectl api-resources –namespaced={true|false}
Cluster Roles and Cluster Role Bindings
이전에 사용자에게 namespace resource 접근 권한을 부여하기 위해 role과 role binding을 사용했다. 사용자에게 Node 또는 persistent volume 같은 cluster resource 권한을 부여하려면 어떻게 해야할까? 바로 cluster role과 cluster role binding이다. 그리고 cluster role과 role은 다루는 resource 차이만 있을 뿐 원리는 같다.
- ex) 클러스터 관리자 롤을 생성하여 노드의 get, create, delete 권한을 제공
- ex) 스토리지 관리자 롤을 생성하여 스토리지 권한을 제공
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: cluster-administrator rules:
- apiGroups: [””] # “” indicates the core API group resources: [“nodes”] verbs: [“get”, “list”, “delete”, “create”] apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: cluster-admin-role-binding subjects:
- kind: User name: cluster-admin apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole #this must be Role or ClusterRole name: cluster-administrator apiGroup: rbac.authorization.k8s.io
롤과 롤 바인딩을 생성한다
- $ kubectl create -f cluster-admin-role.yaml
- $ kubectl create -f cluster-admin-role-binding.yaml
imperative way
- $ kubectl create role foo –verb=get,list,watch –resource=rs.apps
- $ kubectl create rolebinding admin –clusterrole=admin –user=user1 –user=user2 –group=group1
+주의할점 클러스터롤과 바인딩은 엄격한 규칙이 아니다. namespace resource에 대해 클러스터롤도 생성할 수 있다. 하지만 이렇게 하면 사용자는 클러스터 전체에 있는 해당 리소스에 접근하게되는 일이 생긴다.
+role과 rolebinding 개수 셀 때 사용하는 linux line counter
$ k get clusterroles wc -l - 단, 첫줄 (columns 도 함께 표시되니 -1 해야함)