IT/쿠버네티스 / / 2020. 2. 17.

[kubernetes-실습] Security - Authentication, Authorization, Admission

포스팅 목차

    Kubernetes 클러스터는 사용자의 유형으로 service accoount와 normal users 가 있지만 normal users는 외부 서비스에 의해 관리된다. normal users를 나타낼 개체가 없고, 또한 API 호출을 통해 추가할 수도 없다. 하지만 service account를 추가할 수 있다. RBAC을 사용하여 개발자 devJang을 위한 네임스페이스 내의 행동에 대한 접근을 테스트해 본다.

    # Authentication, Authorization 

    - 두개의 테스트용 dev, prod namespace를 생성한다.

    # dev, prod의 두개 namespace를 생성한다.
    ps0107@k8smaster1:~$ kubectl create ns dev
    namespace/dev created
    
    ps0107@k8smaster1:~$ kubectl create ns prod
    namespace/prod created

     

    - 사용가능한 현재 클러스터와 context 를 확인한다

    # 사용가능한 현재 클러스터와 context 를 확인한다.
    # context 를 사용하면 클러스터가 쉽고 일관된 방식으로 kubectl 명령에 사용할 클러스터, 네임스페이스 및 사용자를 구성할 수 있다.
    ps0107@k8smaster1:~$ kubectl config get-contexts
    CURRENT   NAME                          CLUSTER      AUTHINFO           NAMESPACE
    *         kubernetes-admin@kubernetes   kubernetes   kubernetes-admin   

     

    - 사용자 계정을 추가 및 key 생성

    # 사용자 계정을 추가한다.
    ps0107@k8smaster1:~$ sudo useradd -s /bin/bash devJang                                                                                ps0107@k8smaster1:~$ sudo passwd devJang 
    Enter new UNIX password: 
    Retype new UNIX password: 
    passwd: password updated successfully
    
    # devJang 계정을 위한 CSR(Certificate Signing Request) private key를 생성한다.
    ps0107@k8smaster1:~$ openssl genrsa -out devJang.key 2048
    Generating RSA private key, 2048 bit long modulus
    ............................+++
    ....................................................................+++
    e is 65537 (0x10001)
    
    ps0107@k8smaster1:~$ openssl req -new -key devJang.key -out devJang.csr -subj "/CN=devJang/O=dev"                                     
    
    # x509 프로토콜을 사용하는 self-signed certificate를 생성 요청하여 새롭게 생성된 것을 사용한다.
    # kubernetes 클러스터를 위한 CA key를 사용한다. 그리고 45일 만료로 세팅해 준다.
    ps0107@k8smaster1:~$ sudo openssl x509 -req -in devJang.csr \
    > -CA /etc/kubernetes/pki/ca.crt \
    > -CAkey /etc/kubernetes/pki/ca.key \                                                                                                 
    > -CAcreateserial \
    > -out devJang.crt -days 45                                                                                                           
    
    Signature ok
    subject=/CN=devJang/O=dev
    Getting CA Private Key
    
    # 새로운 key와 certificate를 참조하기 위해 config file 접근을 업데이트한다.
    # 보통 root가 아닌 사용자의 home 에 이동시켜 두는게 좋다.
    ps0107@k8smaster1:~$ kubectl config set-credentials devJang \
    > --client-certificate=/home/ps0107/devJang.crt \                                                                                    
    > --client-key=/home/ps0107/devJang.key                                                                                               
    User "devJang" set.
    
    # credentials file 업데이트를 확인 해본다. diff 로 비교해본다.
    ps0107@k8smaster1:~$ diff cluster-api-config .kube/config                                                                             
    15a16,19
    > - name: devJang
    >   user:
    >     client-certificate: /home/ps0107/devJang.crt
    >     client-key: /home/ps0107/devJang.key

     

    - context 생성 및 확인 (dev)

    # context를 생성한다.
    ps0107@k8smaster1:~$ kubectl config set-context devJang-context \
    > --cluster=kubernetes \
    > --namespace=dev \                                                                                                                   
    > --user=devJang
    
    Context "devJang-context" created.
    
    # devJang-context로 pod를 보려고 시도해보자.
    # 권한이 없어 에러가 발생한다.
    ps0107@k8smaster1:~$ kubectl --context=devJang-context get pods
    Error from server (Forbidden): pods is forbidden: User "devJang" cannot list resource "pods" in API group "" in the namespace "dev"
    
    # context 확인 해본다.
    ps0107@k8smaster1:~$ kubectl config get-contexts 
    CURRENT   NAME                          CLUSTER      AUTHINFO           NAMESPACE
              devJang-context               kubernetes   devJang            dev
    *         kubernetes-admin@kubernetes   kubernetes   kubernetes-admin   
    
    # 다시 한번 변경된 cluster access config file을 확인해본다.
    ps0107@k8smaster1:~$ diff cluster-api-config .kube/config
    9a10,14
    >     namespace: dev
    >     user: devJang
    >   name: devJang-context
    > - context:
    >     cluster: kubernetes
    15a21,24
    > - name: devJang
    >   user:
    >     client-certificate: /home/ps0107/devJang.crt
    >     client-key: /home/ps0107/devJang.key

     

    - 권한을 주기위해 Role 생성 및 RoleBinding을 해준후 테스트 한다. (개발자에게 개발 관련 권한 전체 부여)

    # RBAC 을 할당하기 위해 yaml 파일을 만들어 준다.
    ps0107@k8smaster1:~$ vi role-dev.yaml 
    kind: Role
    apiVersion: rbac.authorization.k8s.io/v1beta1
    metadata:
      namespace: dev
      name: developer
    rules:
    - apiGroups: ["", "extensions", "apps"]
      resources: ["deployments", "replicasets", "pods"]
      verbs: ["list", "get", "watch", "create", "update", "patch", "delete"]
    # You can use ["*"] for all verbs
    
    # RBAC object를 생성한다.
    ps0107@k8smaster1:~$ kubectl create -f role-dev.yaml 
    role.rbac.authorization.k8s.io/developer created
    
    # user에 Role을 할당하기 위해 RollBinding을 생성한다.
    ps0107@k8smaster1:~$ vi rolebind.yaml
    kind: RoleBinding
    apiVersion: rbac.authorization.k8s.io/v1beta1
    metadata:
      name: developer-role-binding
      namespace: dev
    subjects:
    - kind: User
      name: devJang
      apiGroup: ""
    roleRef:
      kind: Role
      name: developer
      apiGroup: ""
    
    ps0107@k8smaster1:~$ kubectl apply -f rolebind.yaml                                                                                   rolebinding.rbac.authorization.k8s.io/developer-role-binding created
    
    # context를 다시 테스트 해본다.
    # 이번엔 정상적으로 수행된다.
    ps0107@k8smaster1:~$ kubectl --context=devJang-context get pods
    No resources found.
    
    # deployment도 한번 만들어서 조회해 보자.
    ps0107@k8smaster1:~$ kubectl --context=devJang-context create deployment nginx --image=nginx                                          deployment.apps/nginx created
    
    # 역시 조회가 잘되는것을 확인할 수 있다.
    ps0107@k8smaster1:~$ kubectl --context=devJang-context get pods
    NAME                     READY   STATUS    RESTARTS   AGE
    nginx-554b9c67f9-pnwl5   1/1     Running   0          10s
    
    # 확인 했으니 deployment를 삭제해주자.
    ps0107@k8smaster1:~$ kubectl --context=devJang-context delete deploy nginx
    deployment.extensions "nginx" deleted

     

    - 이번엔 devJang에서 prod에 대한 일부 권한을 부여해 보자. (개발자이므로 운영모든 권한 부여는 필요없음)

    # 이번엔 devJang에 prod namespace의 권한을 설정해 본다.
    ps0107@k8smaster1:~$ vi role-prd.yaml
    kind: Role
    apiVersion: rbac.authorization.k8s.io/v1beta1
    metadata:
      namespace: prod
      name: dev-prod
    rules:
    - apiGroups: ["", "extensions", "apps"]
      resources: ["deployments", "replicasets", "pods"]
      verbs: ["list", "get", "watch"]
    # You can use ["*"] for all verbs
    
    # RollBinding도 설정하기 위해 yaml파일을 만든다ㅏ.
    ps0107@k8smaster1:~$ vi rolebindprod.yaml
    kind: RoleBinding
    apiVersion: rbac.authorization.k8s.io/v1beta1
    metadata:
      name: prod-role-binding
      namespace: prod
    subjects:
    - kind: User
      name: devJang
      apiGroup: ""
    roleRef:
      kind: Role
      name: dev-prod
      apiGroup: ""
    
    # role 객체를 생성해 준다.
    ps0107@k8smaster1:~$ kubectl apply -f role-prd.yaml 
    role.rbac.authorization.k8s.io/dev-prod created
    
    # rolebinding 객체를 생성해 준다.
    ps0107@k8smaster1:~$ kubectl apply -f rolebindprod.yaml                                                                               rolebinding.rbac.authorization.k8s.io/prod-role-binding created
    
    # prod context를 만들어준다.
    ps0107@k8smaster1:~$ kubectl config set-context prodJang-context \
    > --cluster=kubernetes \
    > --namespace=prod \
    > --user=devJang
    
    Context "prodJang-context" created.
    
    # 생성된 context로 pod를 조회해 본다.
    # 정상적으로 조회가 된다.
    ps0107@k8smaster1:~$ kubectl --context=prodJang-context get pods
    No resources found.
    
    # 설정된 role을 확인해볼수 있다.
    ps0107@k8smaster1:~$ kubectl -n prod describe role dev-prod 
    Name:         dev-prod
    Labels:       <none>
    Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                    {"apiVersion":"rbac.authorization.k8s.io/v1beta1","kind":"Role","metadata":{"annotations":{},"name":"dev-prod","namespace":"prod"},"rules"...
    PolicyRule:
      Resources               Non-Resource URLs  Resource Names  Verbs
      ---------               -----------------  --------------  -----
      deployments             []                 []              [list get watch]
      pods                    []                 []              [list get watch]
      replicasets             []                 []              [list get watch]
      deployments.apps        []                 []              [list get watch]
      pods.apps               []                 []              [list get watch]
      replicasets.apps        []                 []              [list get watch]
      deployments.extensions  []                 []              [list get watch]
      pods.extensions         []                 []              [list get watch]
      replicasets.extensions  []                 []              [list get watch]

     

    # Admission

    ps0107@k8smaster1:~$ sudo grep admission /etc/kubernetes/manifests/kube-apiserver.yaml 
        - --enable-admission-plugins=NodeRestriction

    • 네이버 블로그 공유
    • 네이버 밴드 공유
    • 페이스북 공유
    • 카카오스토리 공유