쿠버네티스 전문가 양성과정 10주차 4일(2/23)

최수환·2023년 2월 23일
0

Kubernetes

목록 보기
45/75
post-thumbnail

Authentication

  • 사용자는 kubectl, 클라이언트 라이브러리 또는 REST 요청을 통해 API에 접근한다. 사용자와 쿠버네티스 서비스 어카운트 모두 API에 접근할 수 있다. 요청이 API에 도달하면, 다음 다이어그램에 설명된 몇 가지 단계를 거친다.
  1. 인증 단계 (Authentication)
  • 내가 맞는지 인증하는 단계(= 자격증명)
  • 인증서( x.509등...), 토큰, 패스등으로 인증/자격증명을 한다.
  1. 인가 단계 (Authorization)
  • 인증을 통과하면 해당 사용자가 무엇을 할 수 있는지 인가를 거치게 된다.
  • ABAC모드 ,RBAC(역할 기반)모드 등으로 인가를 하게 된다
  1. 어드미션 제어 단계 (Admission Control)
  • 유효성 검사를 한다.
    -> 예를들어, YAML파일 작성후 create, apply등을 통해
    api-server에 요청하게 되면 yaml파일이 오타가없는지, 요청한 사용자의 인증이 되었는지 등의 유효성 검사를 하게 된다.
  • 기본값 설정
    -> 예를들어, 서비스계정을 따로 설정하지 않으면 파드가 default서비스계정을 사용한다

📒 인증 개념 참조

Service account

  • 계정에는 사용자 계정과 서비스 계정이 존재한다.
  • 서비스 계정 = 파드가 사용하는 계정
    -> 사람이 사용하는 계정이 아니다

📒 서비스 계정 개념 참조

ex) . RBAC실습에서 TEST를 위한 kubectl이미지로 파드 생성

apiVersion: v1
kind: Pod
metadata: 
  name: kubectl 
spec:
  containers:
  - name: kubectl 
    image: bitnami/kubectl:1.24.6
    command: ['sleep']
    args: ['infinity']
  • sleep infinity를 사용하지 않고 그냥 docker hub에 있는 kubectl역할을 하는 이미지를 다운받게 되면 detach모드로 실행될 수 없어서 한번 complete되고 종료가 된다.
  • 계속해서 kubectl 파드를 running상태로 띄우게 하려면 sleep infinity를 사용하는 등의 일종의 '꼼수'를 작성한다.
  • 실무에서는 이처럼 개발자가 만들어놓은 이미지등을 어떻게 사용하고 활용활지 알아야 한다.
kubectl exec -it kubectl -- sh


-> kubectl 파드에 쉘로 접속해 pods, nodes의 정보를 확인해보면 오류가 뜬다.
-> 이것은 단순한 오류가 아닌 해당 pod,node의 default 서비스계정에 대한 권한이 없어서 요청이 거부된 것이다.

kubectl get serviceaccount # 서비스 계정들 확인하기


-> 모든 파드는 따로 설정을 하지 않으면 기본적으로 default 서비스 계정을 사용한다.

kubectl get sa sa이름 -o yaml
# 서비스 계정 자세히 확인
kubectl describe sa sa이름 
# 서비스 계정 자세히 확인 

ex . 서비스 계정 생성하기

kubectl create sa myuser1 # 명령어로 생성

# yaml파일로 생성 
apiVersion: v1
kind: ServiceAccount
metadata:
  name: myadmin
  namespace: default

RBAC

  • 사용자에게 역할기반으로 권한을 부여한다.

  • 리소스를 확인해보면 클러스터롤, 클러스터롤바인딩, 롤, 롤바인딩 4가지가 있는 것을 알 수 있다.

  • 롤 : 해당 롤이 속한 네임스페이스에만 적용된다
  • 롤바인딩 : 사용자와 롤을 연결시켜주는 것
  • 롤바인딩과 롤은 특정 네임스페이스를 사용한다.
    -> 특정 네임스페이스에 롤바인딩과 롤을 설정하여 사용자가 해당 네임스페이스안에서 권한을 부여 받는다.
  • 클러스터롤 : 특정 네임스페이스가 아닌 클러스터 전체 사용 권한을 관리한다.
  • 클러스터롤바인딩 : 클러스터롤과 사용자를 연결시켜주는 것

  • 일반적인 롤의 형태
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: default # 네임스페이스 지정 
  name: read-pod
rules: # 룰 지정 
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list"]

-> default namespace에 대해서 pod리소스에 get과 list를 할 수 있다.

  • verb필드에 사용할 수 있는 여러 동작들

롤 바인딩

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: myuser1-read-pod
  namespace: default # 네임스페이스 지정 
subjects:
- kind: ServiceAccount # 서비스 계정 지정
  name: myuser1
  apiGroup: ""
  namespace: default # 계정이 존재하는 네임스페이스
roleRef: # 롤 지정 
  kind: Role
  name: read-pod
  apiGroup: rbac.authorization.k8s.io

-> 위에서 생성한 롤을 서비스계정 myuser1에 부여한다.
-> 롤 바인딩 또한 default네임스페이스에 있어야 한다.

클러스터롤

  • 롤 형식에서 namespace만 지정하지 않는 것
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata: # 네임스페이스는 지정 x 
  name: read-pod
rules: # 룰 지정 
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get","list"]

-> 모든 네임스페이스(클러스터)에서 pod에 get,list를 할 수 있다.

클러스터롤 바인딩

1 . 생성한 클러스터롤을 사용한 바인딩

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata: # 네임스페이스 지정 x 
  name: myuser2-read-pod
subjects: # 계정 지정 
- kind: ServiceAccount 
  name: myuser2
  namespace: default # 계정이 존재하는 네임스페이스
  apiGroup: ""
roleRef: # 생성했던 클러스터 롤 지정 
  kind: ClusterRole
  name: read-pod
  apiGroup: "rbac.authorization.k8s.io"

-> 위에서 생성한 클러스터롤을 서비스 계정 myuser2에 부여한다.

2 . 기본 롤을 사용한 바인딩

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: myadmin-admin
subjects: # 서비스계정 지정 
- kind: ServiceAccount
  name: myadmin
  namespace: default
  apiGroup: ""
roleRef: # 기본적으로 존재하는 클러스터롤 지정 
  kind: ClusterRole
  name: admin
  apiGroup: "rbac.authorization.k8s.io"

-> admin이라는 클러스터롤은 내가 만든것이 아닌 기본적으로 존재하는 4가지 롤 중하나이다.
-> admin이 가진 권한을 행사할 수 있다.

  • 기본적으로 존재하는 4가지 롤

    	kubectl get clusterroles
  • 명령어로 확인해보면 system을 제외한 기본적으로 제공하는 롤이 4가지가 있다

  • 사용해도되고 안해도 된다.

  • 'system:' 형식은 사용하면 안된다

  • 4가지 기본 롤은 각각 가지고 있는 권한이 다르다

ex . 롤 / 클러스터 롤 테스트

kubectl get pod 파드이름 -o jsonpath='{.spec.serviceAccountName}'
# 해당 파드가 가진 서비스 계정을 알 수 있다.

apiVersion: v1
kind: Pod
metadata: 
  name: kubectl 
spec:
  serviceAccountName: myuser1 # 파드에 서비스 계정 등록
  containers:
  - name: kubectl 
    image: bitnami/kubectl:1.24.6
    command: ['sleep']
    args: ['infinity']
  • 위에서 생성한 kubectl 파드에 서비스 계정 myuser1을 등록한다.
  • 이전에 롤과 롤바인딩을 통해 myuser1이 pod에 대해 get, list를 할 수 있는 권한을 주었다.
kubectl exec -it kubectl -- sh # kubectl 파드에 접속 


-> myuser1이 get과 list를 할 수 있는 권한이 있고 myuser1을 kubectl파드가 가졌기 때문에 get명령이 실행되는 것을 볼 수 있다.
-> 롤과 롤바인드에 설정된 네임스페이스와 롤바인드가 role을 부여하려는 서비스계정이 존재하는 네임스페이스가 일치해야 한다 .

📌 하위 디렉터리의 모든 yaml파일을 생성/삭제하려면 -R 옵션을 사용하면 된다

User Account

  • 외부사용자, 일반적인 사용자 계정
  • 사용자계정은 쿠버네티스에 구현되어있지 않기 때문에 외부의 구글계정이나, 오픈스택의 키스톤, LDAP등 별도의 외부 인증 시스템에 있는 사용자 정보를 연결해 사용한다.
  • LDAP은 인증 서버이고 LDAP서버를 구성해놓은
    MS AD (Microsoft ActiveDirectory)를 사용하여 인증한다.
    하지만 비싸기 때문에 X.509인증서를 통한 실습을 할 것이다.

📒 CSR 개념 참조

ex) 새로운 사용자 계정에 인증서 생성

  1. key를 생성한다.
  2. key로 csr을 생성한다.
  3. yaml파일에서 csr리소스를 사용하여 인코딩한 csr값을 넣는다
  4. 쿠버네티스에서 rootCA는 kubernetes이고 yaml파일을 rootCA에게 준다.
    📒 rootCA는 최상위 기관이기 때문에 자체서명인증서로 된 crt를 갖고 있다.
  5. rootCA는 자신의 crt와 키로 암호화하여 나만의 새로운 인증서를 준다.
  6. 새로운 인증서를 디코딩 및 .crt 파일로 만든다.
openssl genrsa -out myuser3.key 2048
#key생성
openssl req -new -key myuser3.key -out myuser3.csr -subj "/CN=myuser3"
#csr생성

base64 myuser3.csr -w 0 # csr 인코딩하기 

apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: myuser3
spec:
  request: <BASE64 ENCODED VALUE> # 생성한 csr 인코딩해서 삽입 
  signerName: kubernetes.io/kube-apiserver-client
  usages:
  - client auth
  • 인코딩할때에는 '-w 0'을 붙여야 공백이 제거되고 한줄로 나온다.
  • csr리소스를 사용해 YAML파일을 작성해서 rootCA에게 CSR을 보낼 준비를 한다
kubectl get csr 
# yaml파일 create 후 생성한 csr 확인 
# 한시간이 지나면 보안을 위해 자동으로 삭제된다

kubectl certificate approve myuser3 # rootCA가 승인을 한다. 

kubectl get csr myuser3 -o yaml # status부분을 보면 생성된 나만의 인증서를 볼 수 있다.

kubectl get csr myuser3 -o jsonpath='{.status.certificate}'
#생성된 인증서를 보는 다른 방법

kubectl get csr myuser3 -o jsonpath='{.status.certificate}' | base64 -d
#생성된 인증서 디코딩

kubectl get csr myuser3 -o jsonpath='{.status.certificate}' | base64 -d > myuser3.crt
#생성된 인증서 디코딩 및 crt파일로 만들기
  • crt와 key파일을 갖게 된다.
  • 최종적으로 새로운 유저계정에 대해 crt, key를 통해 인증을 할 수 있다.
openssl x509 -in myuser3.crt -text -noout
# 생성한 인증서 상세 정보 보기


-> crt, key를 통해 암호화 후 새로운 인증서를 만들어서 나에게 준 rootCA가 kubernetes임을 확인

User계정에 RBAC

1 . 롤 추가

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: default
  name: admin-pod
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["create", "get", "list", "update", "delete"]

-> 파드에 특정 권한을 가진 롤 생성

2 . 롤바인딩 추가

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: myuser3-admin-pod
  namespace: default
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: admin-pod
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User # 유저계정이므로 
  name: myuser3  

-> 롤 바인딩을 통해 myuser3 유정 계정에 롤 바인딩

kubeconfig파일

cd ~/.kube  
# 해당 kubeconfig파일 있는 디렉터리 접속

config파일이 존재한다 # 외부계정은 kubeconfig파일을 참조한다 
kubectl config view # config파일 보기 

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://127.0.0.1:6443 # api-server 
  name: cluster.local # 내가 사용하고 있는 클러스터 이름 
contexts: # 클러스터와 user를 결합한 것 
- context:
    cluster: cluster.local
    namespace: default # default 네임스페이스 설정한다
    user: kubernetes-admin
  name: kubernetes-admin@cluster.local
current-context: kubernetes-admin@cluster.local
kind: Config
preferences: {}
users:
- name: kubernetes-admin # 나의 계정이름 
  user:
    client-certificate-data: REDACTED # crt(인증서)
    client-key-data: REDACTED # key

-> kubeconfig파일은 현재계정, 외부계정에 대한 클러스터, users, context의 정보를 가지고 있다.
-> 현재는 myuser3에 대한 인증서만 생성했지, users와 context를 생성하지 않았기 때문에 kubeconfig파일에 없다.
-> 클러스터는 하나만 사용하기 때문에 생성하지 않는다.

📒 kubeconfig파일 개념 참조

< users,context 생성 >

kubectl config get-cluster
# 클러스터 보기 

kubectl config set-credentials myuser3 --client-certificate=myuser3.crt --client-key=myuser3.key
# 인증서를 내장하지 않고 user생성 

kubectl config view # user가 추가된 것을 확인 
kubectl config get-users  
# user 계정 보기 

kubectl config set-credentials myuser3 --client-certificate=myuser3.crt --client-key=myuser3.key --embed-certs
# 인증서를 내장하는 방식으로 user생성 

kubectl config set-context myuser3@cluster.local --cluster=cluster.local --user=myuser3 --namespace=default
# user계정에 대한 context생성
kubectl config view 
# 컨텍스트가 추가된 것을 확인  

kubectl config get-contexts
# 생성한 context보기
kubectl config use-context myuser3@cluster.local
# 원하는 context로 전환

-> context로 myuser3 계정으로 전환하게 되면 해당 계정은 바인딩된 롤에 의해 파드에 대한 권한만 실행할 수 있다.
-> CKA 시험에서는 문제마다 컨텍스트가 다르다. 따라서 문제마다 컨텍스트 전환을 하지 않고 문제를 풀면 0점이다.
= 컨텍스트 전환에 익숙해져야 한다.

profile
성실하게 열심히!

0개의 댓글