인증
공식 문서: https://kubernetes.io/docs/reference/access-authn-authz/authentication/
쿠버네티스의 사용자
- Service Account(SA): 쿠버네티스가 관리하는 SA 사용자
- 사용자가 사용하지 않는다.
- Pod 가 사용하는 계정이다.
- Normal User: 일반 사용자(쿠버네티스가 관리하지 않는다.)
- 사용자가 사용하는 계정이다.
- Pod 는 사용하지 않는다.
인증 방법:
- x509 인증서
- static token
- Bearer Token
- http 헤더에 인증 정보가 있는 토큰을 담아서 보낸다.
- Service Account Token
- JSON Web Token: JWT
- OpenID Connect(OIDC)
- 외부 인증 표준화 인터페이스
- okta 인증 서버 서비스가 있다.
- OAuth Provider: EKS 에서 IAM 계정을 사용하는 방식이 바로 OIDC 를 사용한 방식이다.
- Bearer Token
Pod 는 SA 계정을 사용하고 SA 계정에 할당받은 Token 을 사용한다.
사용자(나)는 x509 를 사용하여 kubectl 을 사용한다.
RBAC: Role Based Access Control
공식 문서: https://kubernetes.io/docs/reference/access-authn-authz/rbac/, https://kubernetes.io/ko/docs/reference/access-authn-authz/authorization/
역할 기반 접근 제어(RBAC, Role-based access control)는 클러스터 내 개별 사용자의 역할을 기반으로 컴퓨터나 네트워크 리소스에 대한 접근을 규제하는 방식이다. 이 맥락에서 접근은 개별 사용자가 파일을 보거나 만들거나 수정하는 것과 같은 특정 작업을 수행할 수 있는 능력이다.
- Role: 특정 Name Space 내에서만 권한 부여 가능
- ClusterRole: 글로벌하게 권한 부여 가능
- view: 읽을 수 있는 권한
- edit: 생성/삭제/변경할 수 있는 권한
- admin: 모든 것 관리(RBAC의 ClusterRole 제외)
- cluster-admin: 모든 것 관리
- RoleBinding
- 특정 Name Space 내에서 Role 과 SA/User 사용자를 연결시켜 주는 것이 RoleBinding 이다.
- ClusterRoleBinding
- ClusterRole 과 SA/User 사용자를 연결시켜주는 것이 ClusterRoleBinding 이다.
$ kubectl get po -v=7
I0526 06:31:24.674874 163632 loader.go:372] Config loaded from file: /home/vagrant/.kube/config
I0526 06:31:24.695368 163632 round_trippers.go:432] GET <https://127.0.0.1:6443/api/v1/namespaces/default/pods?limit=500>
I0526 06:31:24.695939 163632 round_trippers.go:438] Request Headers:
I0526 06:31:24.696880 163632 round_trippers.go:442] Accept: application/json;as=Table;v=v1;g=meta.k8s.io,application/json;as=Table;v=v1beta1;g=meta.k8s.io,application/json
I0526 06:31:24.697384 163632 round_trippers.go:442] User-Agent: kubectl/v1.22.8 (linux/amd64) kubernetes/7061dbb
I0526 06:31:24.713208 163632 round_trippers.go:457] Response Status: 200 OK in 15 milliseconds
NAME READY STATUS RESTARTS AGE
nfs-client-provisioner-758f8cd4d6-rt2t8 1/1 Running 5 (4h25m ago) 2d1h
-v 옵션을 사용해서 Request, Response 를 자세하게 확인할 수 있다.
kubectl create 커맨드 → api-server 에 HTTP POST 요청
kubectl get, list, watch 커맨드 → api-server 에 HTTP GET 요청
kubectl update 커맨드 → api-server 에 HTTP PUT 요청
kubectl patch 커맨드 → api-server 에 HTTP PATCH 요청
kubectl delete, deletecollection 커맨드 → api-server 에 HTTP DELTE 요청
Role 예제
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]
Cluster Role 예제
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
# "namespace" omitted since ClusterRoles are not namespaced
name: secret-reader
rules:
- apiGroups: [""]
#
# at the HTTP level, the name of the resource for accessing Secret
# objects is "secrets"
resources: ["secrets"]
verbs: ["get", "watch", "list"]
RoleBinding 예제
apiVersion: rbac.authorization.k8s.io/v1
# This role binding allows "jane" to read pods in the "default" namespace.
# You need to already have a Role named "pod-reader" in that namespace.
kind: RoleBinding
metadata:
name: read-pods
namespace: default
subjects:
# You can specify more than one "subject"
- kind: User
name: jane # .kube/config 에 users.user.name 에 jane 이 있어야 한다.
apiGroup: rbac.authorization.k8s.io
roleRef:
# "roleRef" specifies the binding to a Role / ClusterRole
kind: Role #this must be Role or ClusterRole
name: pod-reader # this must match the name of the Role or ClusterRole you wish to bind to
apiGroup: rbac.authorization.k8s.io
ClusterRoleBinding 예제
apiVersion: rbac.authorization.k8s.io/v1
# This cluster role binding allows anyone in the "manager" group to read secrets in any namespace.
kind: ClusterRoleBinding
metadata:
name: read-secrets-global
subjects:
- kind: Group
name: manager # Name is case sensitive
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
Service Account(SA)
kubectl craete sa <SA_NAME>
$ kubectl create sa myuser1
serviceaccount/myuser1 created
$ kubectl describe sa myuser1
Name: myuser1
Namespace: default
Labels: <none>
Annotations: <none>
Image pull secrets: <none>
Mountable secrets: myuser1-token-lgpsj
Tokens: myuser1-token-lgpsj
Events: <none>
$ kubectl get secret
NAME TYPE DATA AGE
default-token-jw8gl kubernetes.io/service-account-token 3 2d4h
myuser1-token-lgpsj kubernetes.io/service-account-token 3 14s
nfs-client-provisioner-token-bgdtf kubernetes.io/service-account-token 3 2d1h
사용자 생성을 위한 x509 인증서
Private Key 생성
openssl genrsa -out myuser.key 2048
x509 인증서 요청 생성
openssl req -new -key myuser.key -out myuser.csr -subj "/CN=myuser"
/CN=myuser 을 작성한 이유는 인증서의 Common Name 과 ~/.kube/config 의 users.name 과 똑같아야 한다. 그 때문에 /CN=myuser 를 하면 간단하게 Common Name 을 지정할 수 있다.
인증서 base64 인코딩
cat myuser.crt | base64 | tr -d "\\n"
csr.yml
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: myuser-csr
spec:
usages:
- client auth
signerName: kubernetes.io/kube-apiserver-client
request: LS0tLS1CRUdJTiB
kubectl create -f csr.yaml
kubectl get csr
상태: Pending
kubectl certificate approve myuser-csr
kubectl get csr
상태: Apporved, Issued
kubectl get csr myuser-csr -o yaml
spec.status.certificate 확인
kubectl get csr myuser-csr -o jsonpath='{.status.certificate}' | base64 -d > myuser.crt
openssl x509 -in myuser.crt --text
Kubeconfig 사용자 생성
kubectl config set-credentials myuser --client-certificate=myuser.crt --client-key=myuser.key --embed-certs=true
Kubeconfig 컨텍스트 생성
kubectl config set-context myuser@cluster.local --cluster=cluster.local --user=myuser --namespace
=default
kubectl config get-users
kubectl config get-clusters
kubectl config get-contexts
kubectl config use-context myuser@cluster.local
ClusterRole view 권한을 myuser 사용자에게 부여
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: myuser-view-crb
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: view
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: myuser
kubectl create -f myuser-view-crb.yml
kubectl describe clusterrolebindings.rbac.authorization.k8s.io myuser-view-crb
kubectl config use-context myuser@cluster.local
Switched to context "myuser@cluster.local".
kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
kubernetes-admin@cluster.local cluster.local kubernetes-admin
* myuser@cluster.local cluster.local myuser default
kubectl get pods
NAME READY STATUS RESTARTS AGE
nfs-client-provisioner-758f8cd4d6-rt2t8 1/1 Running 6 (23m ago) 2d19h
kubectl auth can-i get pod
yes
만약 새로운 ClusterRole 만들고 싶을 때는 아래처럼 하면 된다.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
namespace: default
name: myuser-role
rules:
- apiGroups: ["*"] # "" indicates the core API group
resources: ["secrets"]
verbs: ["get", "watch", "list"]