ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 16. 클러스터 유지와 보안 트러블 슈팅 (2)
    개발 스터디/데브옵스(DevOps)를 위한 쿠버네티스 마스터 2021. 9. 8. 19:09
    반응형

    이 문서는 인프런 강의 "데브옵스를 위한 쿠버네티스 마스터"을 듣고 작성되었습니다. 최대한 요약해서 강의 내용을 최소로 하는데 목표를 두고 있어서, 더 친절하고 정확한 내용을 원하신다면 강의를 구매하시는 것을 추천드립니다. => 강의 링크

    TLS 통신의 이해와 인증서 위치 확인

    Kubernetes에서 사용자를 제어하기 위해서 TLS 통신 방식을 이용한다.

    TLS는 기존 통신 계층에 대해서 조금 더 보안이 높은 통신을 위해 만들어졌다. 즉, 4계층인 Transport Layer(TCP)와 7 계층인 Application Layer(HTTP) 사이에서 동작한다. 다음과 같은 기능이 있다.

    • 데이터 암호화
    • 데이터 무결성
    • 서버/클라이언트 인증

    다음은 HTTPTLS 통신 방식을 곁들인 HTTPS 통신 방식의 흐름도이다.

    1. 서버 오픈 시, 개인 키를 생성하여 CA(Certificate Authority)에서 인증서를 발급 받는다. 이 때 공개 키도 만들어진다.
    2. 이제 클라이언트에서 서버로 요청이 온다.
    3. 이 때 서버에서는 공개 키를 전달한다.
    4. 클라이언트는 전달 받은 공개 키가 유효한지 CA에서 확인한다. 인증이 되면 서버의 개인 키로 암호화된 "세션 키"를 발급받는다.
    5. 그 후 클라이언트는 암호화된 세션 키를 전달한다.
    6. 세션 키를 받은 서버는 개인 키로 복호화 후, 유효한 키인지 확인한다. 확인이 되면 ACK 응답을 보낸다.
    7. 이제 암호화된 데이터 송/수신이 이루어진다.

    Kubernetes 클러스터 인증서 정보 확인과 자동 갱신

    이번 절은 VM에서 진행된다.


    Kuberenetes의 컴포넌트들의 인증서의 위치는 다음에서 확인할 수 있다.

    $ sudo ls -al /etc/kubernetes/pki
    total 72
    drwxr-xr-x 3 root root 4096  9월  1 21:37 .
    drwxr-xr-x 4 root root 4096  7월  3 18:50 ..
    -rw-r--r-- 1 root root 1281  7월  3 18:50 apiserver.crt
    -rw-r--r-- 1 root root 1155  7월  3 18:50 apiserver-etcd-client.crt
    -rw------- 1 root root 1679  7월  3 18:50 apiserver-etcd-client.key
    -rw------- 1 root root 1675  7월  3 18:50 apiserver.key
    -rw-r--r-- 1 root root 1164  7월  3 18:50 apiserver-kubelet-client.crt
    -rw------- 1 root root 1679  7월  3 18:50 apiserver-kubelet-client.key
    -rw-r--r-- 1 root root 1066  7월  3 18:50 ca.crt
    -rw------- 1 root root 1679  7월  3 18:50 ca.key
    drwxr-xr-x 2 root root 4096  7월  3 18:50 etcd
    -rw-r--r-- 1 root root 1078  7월  3 18:50 front-proxy-ca.crt
    -rw------- 1 root root 1679  7월  3 18:50 front-proxy-ca.key
    -rw-r--r-- 1 root root 1119  7월  3 18:50 front-proxy-client.crt
    -rw------- 1 root root 1675  7월  3 18:50 front-proxy-client.key
    -rw------- 1 root root 1675  7월  3 18:50 sa.key
    -rw------- 1 root root  451  7월  3 18:50 sa.pub
    -rw-r--r-- 1 root root  101  9월  1 21:37 token.csv

    etcd의 인증서는 다음에서 확인할 수 있다.

    $ sudo ls -al /etc/kubernetes/pki/etcd
    total 40
    drwxr-xr-x 2 root root 4096  7월  3 18:50 .
    drwxr-xr-x 3 root root 4096  9월  1 21:37 ..
    -rw-r--r-- 1 root root 1058  7월  3 18:50 ca.crt
    -rw------- 1 root root 1675  7월  3 18:50 ca.key
    -rw-r--r-- 1 root root 1159  7월  3 18:50 healthcheck-client.crt
    -rw------- 1 root root 1675  7월  3 18:50 healthcheck-client.key
    -rw-r--r-- 1 root root 1192  7월  3 18:50 peer.crt
    -rw------- 1 root root 1675  7월  3 18:50 peer.key
    -rw-r--r-- 1 root root 1192  7월  3 18:50 server.crt
    -rw------- 1 root root 1679  7월  3 18:50 server.key

    이제 다음 명령어를 입력해서 apiserver-etcd-client의 인증서 정보를 확인해보자.

    $ sudo openssl x509 -in /etc/kubernetes/pki/apiserver-etcd-client.crt -text
    Certificate:
        Data:
            Version: 3 (0x2)
            Serial Number: 3420255542562728634 (0x2f77304b6f832aba)
            Signature Algorithm: sha256WithRSAEncryption
            Issuer: CN = etcd-ca
            Validity
                Not Before: Jul  3 09:50:42 2021 GMT
                Not After : Sep  6 23:27:47 2022 GMT
            Subject: O = system:masters, CN = kube-apiserver-etcd-client
            Subject Public Key Info:
                Public Key Algorithm: rsaEncryption
                    RSA Public-Key: (2048 bit)
                    Modulus:
                        00:ae:c3:ba:41:42:e6:6c:83:7a:dd:48:6a:db:53:
                        a3:fa:be:53:32:13:6f:0f:79:85:7c:59:df:6a:d0:
                        af:d3:9c:b0:a1:de:0b:e6:76:5f:2f:8d:55:54:b3:
                        65:17:74:99:2c:87:71:22:3e:0c:60:63:2b:b2:c8:
                        27:9e:47:cf:bc:e5:f1:d3:8a:a6:b2:06:a6:5f:36:
                        24:cd:71:de:73:1c:68:d3:39:4f:7e:48:8b:ea:17:
                        19:6e:cc:ba:56:22:3b:4e:eb:c5:58:96:88:e1:e3:
                        00:be:8e:58:e8:2e:c3:da:97:26:19:00:b7:f2:ae:
                        6e:e6:26:78:c4:ce:8a:27:c0:94:eb:06:05:dd:c9:
                        f6:fa:20:d4:7b:9a:7c:9a:8d:8c:8f:02:cc:c8:4b:
                        88:93:8f:f7:74:49:0c:a5:a3:0d:8b:7f:7b:97:7c:
                        87:97:b3:4c:38:e3:be:22:cf:ea:d6:ad:56:3d:68:
                        84:7c:a4:6c:ca:4a:9f:e2:84:60:3c:bb:b1:7b:78:
                        6b:a7:57:41:49:24:00:49:f9:2c:53:48:27:b8:03:
                        9e:0c:45:e0:b0:71:a2:b5:ef:27:ea:73:42:e2:34:
                        73:40:7b:db:88:fa:c1:0d:71:ce:11:2a:fb:5f:1f:
                        06:d5:b5:72:71:3a:05:72:25:bc:7d:a1:4e:12:7c:
                        d4:f3
                    Exponent: 65537 (0x10001)
            X509v3 extensions:
                X509v3 Key Usage: critical
                    Digital Signature, Key Encipherment
                X509v3 Extended Key Usage: 
                    TLS Web Client Authentication
                X509v3 Basic Constraints: critical
                    CA:FALSE
                X509v3 Authority Key Identifier: 
                    keyid:71:EC:FC:4E:F4:1A:B0:A2:94:0A:84:83:0B:C1:8B:30:96:A2:79:6B
    
        Signature Algorithm: sha256WithRSAEncryption
             24:da:bf:53:86:fd:85:be:a9:ff:ab:77:4d:99:e7:3a:ab:7e:
             6b:cb:45:9b:f8:62:b5:bf:fb:cf:d6:63:69:f7:fd:92:8c:5f:
             e9:62:e1:96:92:d7:6e:fa:44:cb:bb:53:bd:aa:11:ca:7f:d2:
             8d:31:88:3b:96:5a:94:ee:94:cc:da:89:e5:9b:21:64:36:7e:
             7f:22:8b:34:6b:e5:74:a7:e7:ba:0d:1a:a6:8b:70:97:33:31:
             85:2f:01:86:87:a4:2e:80:58:0e:ee:00:82:38:32:4a:59:f2:
             20:45:4a:b4:6d:62:3c:2c:19:c0:29:9f:fd:a4:1b:94:f8:e1:
             b6:52:27:d1:e8:fe:76:fd:39:32:92:7c:7e:53:91:e6:a1:41:
             00:e3:84:4e:45:4a:cb:3d:f0:bb:1d:d2:c8:89:5c:6d:33:57:
             d3:3f:fa:6d:ad:10:1e:bd:26:e4:36:75:7f:91:13:7c:f1:6c:
             5e:c3:92:24:18:38:da:e6:b3:00:99:91:75:5a:31:a2:ec:93:
             9a:57:80:e6:36:d7:ba:25:cb:f8:04:7d:12:02:5d:00:d3:5d:
             6e:b4:f3:57:fe:b4:c2:05:c9:87:92:4f:5e:c3:0b:21:5d:c8:
             ea:de:14:b2:0d:16:8d:0e:ab:82:c5:d2:15:47:7e:1a:50:71:
             a6:64:26:ff
    -----BEGIN CERTIFICATE-----
    MIIDKDCCAhCgAwIBAgIIL3cwS2+DKrowDQYJKoZIhvcNAQELBQAwEjEQMA4GA1UE
    AxMHZXRjZC1jYTAeFw0yMTA3MDMwOTUwNDJaFw0yMjA5MDYyMzI3NDdaMD4xFzAV
    BgNVBAoTDnN5c3RlbTptYXN0ZXJzMSMwIQYDVQQDExprdWJlLWFwaXNlcnZlci1l
    dGNkLWNsaWVudDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK7DukFC
    5myDet1IattTo/q+UzITbw95hXxZ32rQr9OcsKHeC+Z2Xy+NVVSzZRd0mSyHcSI+
    DGBjK7LIJ55Hz7zl8dOKprIGpl82JM1x3nMcaNM5T35Ii+oXGW7MulYiO07rxViW
    iOHjAL6OWOguw9qXJhkAt/KubuYmeMTOiifAlOsGBd3J9vog1HuafJqNjI8CzMhL
    iJOP93RJDKWjDYt/e5d8h5ezTDjjviLP6tatVj1ohHykbMpKn+KEYDy7sXt4a6dX
    QUkkAEn5LFNIJ7gDngxF4LBxorXvJ+pzQuI0c0B724j6wQ1xzhEq+18fBtW1cnE6
    BXIlvH2hThJ81PMCAwEAAaNWMFQwDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoG
    CCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUcez8TvQasKKUCoSD
    C8GLMJaieWswDQYJKoZIhvcNAQELBQADggEBACTav1OG/YW+qf+rd02Z5zqrfmvL
    RZv4YrW/+8/WY2n3/ZKMX+li4ZaS1276RMu7U72qEcp/0o0xiDuWWpTulMzaieWb
    IWQ2fn8iizRr5XSn57oNGqaLcJczMYUvAYaHpC6AWA7uAII4MkpZ8iBFSrRtYjws
    GcApn/2kG5T44bZSJ9Ho/nb9OTKSfH5TkeahQQDjhE5FSss98Lsd0siJXG0zV9M/
    +m2tEB69JuQ2dX+RE3zxbF7DkiQYONrmswCZkXVaMaLsk5pXgOY217oly/gEfRIC
    XQDTXW6081f+tMIFyYeST17DCyFdyOreFLINFo0Oq4LF0hVHfhpQcaZkJv8=
    -----END CERTIFICATE-----

    확인해야할 양이 너무 길다. 몇 개만 간추려서 확인해보자. 여기서 Issuer를 확인하면 누구한테 인증되었는지 확인할 수 있다.

    $ sudo openssl x509 -in /etc/kubernetes/pki/apiserver-etcd-client.crt -text | grep "Issuer"
            Issuer: CN = etcd-ca

    Subject를 확인하면 누가 인증을 받았는지 확인할 수 있다.

    $ sudo openssl x509 -in /etc/kubernetes/pki/apiserver-etcd-client.crt -text | grep "Subject"
            Subject: O = system:masters, CN = kube-apiserver-etcd-client
            ...

    여기서 O는 기관 명, CN은 인증을 받은 주체를 의미한다. 또한, Validity 밑에 Not *로 유효기간을 확인할 수 있다.

    $ sudo openssl x509 -in /etc/kubernetes/pki/apiserver-etcd-client.crt -text | grep "Not"
                Not Before: Jul  3 09:50:42 2021 GMT
                Not After : Sep  6 23:27:47 2022 GMT
    

    위 인증서는 즉 2021년 7월 3일 09:50:42 부터 2022년 9월 6일 23:27:47까지 유효하다. 이제 갱신을 해보자. 먼저 다음 명령어를 통해서 클러스터 내 모든 인증서들의 유효기간을 확인할 수 있다.

    $ sudo kubeadm certs check-expiration
    [check-expiration] Reading configuration from the cluster...
    [check-expiration] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
    
    CERTIFICATE                EXPIRES                  RESIDUAL TIME   CERTIFICATE AUTHORITY   EXTERNALLY MANAGED
    admin.conf                 Jul 03, 2022 09:50 UTC   299d                                    no      
    apiserver                  Jul 03, 2022 09:50 UTC   299d            ca                      no      
    apiserver-etcd-client      Jul 03, 2022 09:50 UTC   299d            etcd-ca                 no      
    apiserver-kubelet-client   Jul 03, 2022 09:50 UTC   299d            ca                      no      
    controller-manager.conf    Jul 03, 2022 09:50 UTC   299d                                    no      
    etcd-healthcheck-client    Jul 03, 2022 09:50 UTC   299d            etcd-ca                 no      
    etcd-peer                  Jul 03, 2022 09:50 UTC   299d            etcd-ca                 no      
    etcd-server                Jul 03, 2022 09:50 UTC   299d            etcd-ca                 no      
    front-proxy-client         Jul 03, 2022 09:50 UTC   299d            front-proxy-ca          no      
    scheduler.conf             Jul 03, 2022 09:50 UTC   299d                                    no      
    
    CERTIFICATE AUTHORITY   EXPIRES                  RESIDUAL TIME   EXTERNALLY MANAGED
    ca                      Jul 01, 2031 09:50 UTC   9y              no      
    etcd-ca                 Jul 01, 2031 09:50 UTC   9y              no      
    front-proxy-ca          Jul 01, 2031 09:50 UTC   9y              no   

    대부분의 인증서는 1년 정도 유효 기간이 주어지는데, 쉽게 업데이트를 하려면 클러스터를 업데이트 하면 된다. 그러면 인증서들이 모두 자동 갱신된다. 만약 수동으로 갱신해야 한다면, 터미널에 다음을 입력하면 된다.

    $ sudo kubeadm certs renew all 
    [renew] Reading configuration from the cluster...
    [renew] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
    
    certificate embedded in the kubeconfig file for the admin to use and for kubeadm itself renewed
    certificate for serving the Kubernetes API renewed
    certificate the apiserver uses to access etcd renewed
    certificate for the API server to connect to kubelet renewed
    certificate embedded in the kubeconfig file for the controller manager to use renewed
    certificate for liveness probes to healthcheck etcd renewed
    certificate for etcd nodes to communicate with each other renewed
    certificate for serving etcd renewed
    certificate for the front proxy client renewed
    certificate embedded in the kubeconfig file for the scheduler manager to use renewed
    
    Done renewing certificates. You must restart the kube-apiserver, kube-controller-manager, kube-scheduler and etcd, so that they can use the new certificates

    그럼 모든 인증서가 갱신된다. 한 번 확인해보면, 이전과 달리 364d로 유효 기간이 늘어난 것을 확인할 수 있다.

    $ sudo kubeadm certs check-expiration
    [check-expiration] Reading configuration from the cluster...
    [check-expiration] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
    
    CERTIFICATE                EXPIRES                  RESIDUAL TIME   CERTIFICATE AUTHORITY   EXTERNALLY MANAGED
    admin.conf                 Sep 06, 2022 23:27 UTC   364d                                    no      
    apiserver                  Sep 06, 2022 23:27 UTC   364d            ca                      no      
    apiserver-etcd-client      Sep 06, 2022 23:27 UTC   364d            etcd-ca                 no      
    apiserver-kubelet-client   Sep 06, 2022 23:27 UTC   364d            ca                      no      
    controller-manager.conf    Sep 06, 2022 23:27 UTC   364d                                    no      
    etcd-healthcheck-client    Sep 06, 2022 23:27 UTC   364d            etcd-ca                 no      
    etcd-peer                  Sep 06, 2022 23:27 UTC   364d            etcd-ca                 no      
    etcd-server                Sep 06, 2022 23:27 UTC   364d            etcd-ca                 no      
    front-proxy-client         Sep 06, 2022 23:27 UTC   364d            front-proxy-ca          no      
    scheduler.conf             Sep 06, 2022 23:27 UTC   364d                                    no      
    
    CERTIFICATE AUTHORITY   EXPIRES                  RESIDUAL TIME   EXTERNALLY MANAGED
    ca                      Jul 01, 2031 09:50 UTC   9y              no      
    etcd-ca                 Jul 01, 2031 09:50 UTC   9y              no      
    front-proxy-ca          Jul 01, 2031 09:50 UTC   9y              no  

    TLS 인증서를 활용한 유저 생성

    이번엔 TLS 인증서를 이용해서 유저를 생성할 수 있다. 먼저 개인 키를 생성해야 한다. 터미널에 다음을 입력한다.

    $ openssl genrsa -out gurumee.key 2048
    Generating RSA private key, 2048 bit long modulus (2 primes)
    ...................+++++
    ......................................+++++
    e is 65537 (0x010001)

    이러면 gurumee.key라는 개인 키가 생성된다. 그 후 개인 키를 기반으로 인증서 서명을 요청할 수 있다. 터미널에 다음을 입력한다.

    $ openssl req -new -key gurumee.key -out gurumee.csr -subj="/CN=gurumee/O=inflearn-k8s"

    그러면 guruemee.csr이 생성된다. 그 후 CA기관, 여기서는 마스터 서버에 인증서 요청을 할 수 있다.

    $ sudo openssl x509 -req -in gurumee.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out gurumee.crt -days 500
    Signature ok
    subject=CN = gurumee, O = inflearn-k8s
    Getting CA Private Key

    이제 gurumee.crt까지 만들어졌다. 이제 만든 crtkey를 기반으로 유저를 생성하면 된다.

    $ kubectl config set-credentials gurumee --client-certificate=./gurumee.crt --client-key=./gurumee.key
    User "gurumee" set.

    그 후 유저 컨텍스트를 생성한다.

    $ kubectl config set-context gurumee-context --cluster=kubernetes --namespace=office --user=gurumee
    Context "gurumee-context" created.

    이제 이 컨텍스트를 기반으로 명령어를 실행해보자.

    $ kubectl get pod --context gurumee-context 
    Error from server (Forbidden): pods is forbidden: User "gurumee" cannot list resource "pods" in API group "" in the namespace "office"

    이 유저는 Pod 목록을 읽을 권한이 없기 때문에 위에 에러는 유효한 에러이다.

    RBAC

    RBAC는 유저에게 kubernetes 클러스터가 관리하는 리소스들에 대한 접근 제어를 가능하게 해준다. Role단위로 접근 권한을 생성하며 RoleBinding으로 생성한 Role을 유저에게 부여할 수 있다.

    AWS를 빗대어서 표현하자면 PolicyRole, 유저는 유저, 그리고 유저에 Policy를 할당하는 과정을 RoleBinding이라고 보면 된다. RBAC는 다음과 같이 총 4개의 리소스가 있다.

    • Role
    • RoleBinding
    • ClusterRole
    • ClusterRoleBinding

    Role, RoleBinding은 네임스페이스에 종속적이다. 반면에 ClusterRole, ClusterRoleBinding 네임스페이스에 종속적이지 않으며 클러스터 전체에 영향을 줄 수 있다. 따라서 보통 다음과 같이 권한을 부여하는 편이다.

    • User(Developer), ServiceAccount: Role, RoleBinding
    • User(Admin): ClusterRole, ClusterRoleBinding

    이제 한 번 RoleRoleBinding을 생성해보자. 위의 절에서 만든 유저에 대해서 office 네임스페이스에서 Pod, Deployment, ReplicaSet을 만들고 조회할 수 있는 권한을 부여할 것이다. 먼저 Role을 다음과 같이 생성한다.

    src/ch16/k8s/rbac-deployment-manager.yaml

    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      namespace: office
      name: deployment-manager
    rules:
    - apiGroups: ["", "extensions", "apps"] 
      resources: ["pods", "deployments", "replicasets"]
      verbs: ["get", "watch", "list", "create", "update", "patch", "delete"],
    
    ---
    # RoleBinding
    # ...

    그 후, 유저에게 Role을 부여하는 RoleBinding을 생성한다.

    src/ch16/k8s/rbac-deployment-manager.yaml

    # Role
    # ...
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: deploy-manager
      namespace: office
    subjects:
      - kind: User
        name: gurumee
        apiGroup: rbac.authorization.k8s.io
    roleRef:
      kind: Role 
      name: deployment-manager 
      apiGroup: rbac.authorization.k8s.io

    그리고 생성한다. 이 때 Namespaceoffice와 유저인 gurumee는 미리 생성되어 있어야 한다.

    $ kubectl create -f rbac-deployment-manager.yaml 
    role.rbac.authorization.k8s.io/deployment-manager created
    rolebinding.rbac.authorization.k8s.io/deploy-manager created

    그 후, gurumee-contextPod을 조회할 수 있다.

    $ kubectl get pod --context gurumee-context
    No resources found in office namespace.

    또한 조회 뿐 아니라, 생성, 삭제, 업데이트도 가능하다. 물론 Deployment, ReplicaSet도 가능하다.

    Kubectl Config 더 깊이!

    사실, 이런식으로 api-server에 리소스 요청이 가능하다.

    $ curl https://kube-api-server:6443/api/v1/pods\
    --key user.key
    --cert user.crt # cluster, user 위한 정보
    --cacert ca.crt 

    하지만 이렇게 하기는 매우 불편하기 때문에, kubectl이라는 클라이언트를 통해서 리소스 요청을 한다.

    $ kubectl get pod

    이런 리소스를 요청하기 위해서는 유저와 컨텍스트, 그리고 RBAC가 적절히 생성되어야 한다. 여태까지 설정한 config는 다음 명령어로 확인이 가능하다.

    $ kubectl config view
    apiVersion: v1
    clusters:
    - cluster:
        certificate-authority-data: DATA+OMITTED  # kubernetes-admin crt 암호화
        server: https://10.0.2.15:6443
      name: kubernetes
    contexts:
    - context:
        cluster: kubernetes
        namespace: office
        user: gurumee
      name: gurumee-context
    - context:
        cluster: kubernetes
        user: kubernetes-admin
      name: kubernetes-admin@kubernetes
    - context:
        cluster: kubernetes
        namespace: frontend
        user: user1
      name: user1-context
    current-context: kubernetes-admin@kubernetes # 현재 사용중인 쿠버네티스 계정
    kind: Config
    preferences: {}
    users:
    - name: gurumee
      user:
        client-certificate: /home/gurumee/k8s-master/ch16/gurumee.crt
        client-key: /home/gurumee/k8s-master/ch16/gurumee.key
    - name: kubernetes-admin
      user:
        client-certificate-data: REDACTED # kubernetes-admin crt 암호화
        client-key-data: REDACTED         # kubernetes-admin key 암호화
    - name: user1
      user:
        token: REDACTED

    만약 위 내용을 평문으로 보고 싶다면 다음 명령어를 입력하면 된다.

    $ cat ~/.kube/config
    apiVersion: v1
    clusters:
    - cluster:
        certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM1ekNDQWMrZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJeE1EY3dNekE1TlRBME1Wb1hEVE14TURjd01UQTVOVEEwTVZvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTm1ICkZUVnN4SGdQWEtKT29ybkJGNXd6L25Cb2NwdmR4Qlo1Snd5eVZLWHU5b1Q5VFhDY1FBR3dNTFFOOURCZ2NnMDIKMmEvTE1rd2RkVDdTZS8wazB1TngxcDJidzFlMlFjVU5tUkt5S2o0VUdvS28raXBzZ1BzeU1xRCt3aVpCUkNCegpaeVV3MHFkTmZFOFJwVDRIcFJtd0hJZ2lzZWdRYUZ3Q0x2M3dtbHV1RGg3TzBUYktkMmxZcVJvdS9teWwzV21RCitCSG1ZSmxMayt4Vk1QNEorM05URTdJVXNpNWVHYnNYanJhcmZmYUVLWTdMUWd1aHVKNFdlZ3NvQmFjVW1VWmIKZVdLU0dxdllwa3NsT2tiSGNyUVlsNUF3QlNzcmg0YlVaelQ4bFBOVGk3NW0zaHU4NnZ1L3lDM2FNZ2tXS0w5bAphZFYyTU04VTZxa2h6dzRjY2xFQ0F3RUFBYU5DTUVBd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZMeEd4YXd6Uk1jNnFZSmhtazZyR1JPUHZUSzFNQTBHQ1NxR1NJYjMKRFFFQkN3VUFBNElCQVFDV2xVZEZyNTZ6alFiOVFhTnJqYXRCUHJGQ0FZRGNaSysvWjVKd2p2cWZCL21xeERkOQpDNFhTSEVoa3o1VDV1cjFUdXJYSFE1Z2FqaldEWnJhMGoxZEVjVysrYWV2a3J5VXloazUyaHlVd1lVckRzempGCkpnQXY3bXR5N0xiQXZXOU1kK3BsbkFjejhFSVlUOWlCaUpaVU1qeHJFTWNWNWpnaHczSDgrNmVrZURRMHFROHQKOU9hdGMrbzZhU0pLMi81RG1BSjFqQ2krNUZyNDZiaDNyWjRLNHdtU3h4RG1UWGpNaStYSndSQ1drMFFldzdrcQpnaUVZWEtkSmliV2Q2YndxSFBrd0RrMEd3N09TMXMyblEyVGhZdGpkajZlMit3cEdTemwxTHEzZm83Z2s1N3g2CmNrWE5MOFh0OXdMbW1VSmc5Q29vUy82WUdHcXk2ZTZQLy9BMAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
        server: https://10.0.2.15:6443
      name: kubernetes
    contexts:
    - context:
        cluster: kubernetes
        namespace: office
        user: gurumee
      name: gurumee-context
    - context:
        cluster: kubernetes
        user: kubernetes-admin
      name: kubernetes-admin@kubernetes
    - context:
        cluster: kubernetes
        namespace: frontend
        user: user1
      name: user1-context
    current-context: kubernetes-admin@kubernetes
    kind: Config
    preferences: {}
    users:
    - name: gurumee
      user:
        client-certificate: /home/gurumee/k8s-master/ch16/gurumee.crt
        client-key: /home/gurumee/k8s-master/ch16/gurumee.key
    - name: kubernetes-admin
      user:
        client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURJVENDQWdtZ0F3SUJBZ0lJVUIxeDZVQXl4WFl3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB5TVRBM01ETXdPVFV3TkRGYUZ3MHlNakEzTURNd09UVXdORE5hTURReApGekFWQmdOVkJBb1REbk41YzNSbGJUcHRZWE4wWlhKek1Sa3dGd1lEVlFRREV4QnJkV0psY201bGRHVnpMV0ZrCmJXbHVNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXhtclI1aUZIai8ycHVSbGwKUjdobzRnUU1XUmd2RXNCcXRKNjljaUtJUGZUVFNadTRObW5TMDdnODV4dTE4K3NHN0h6Z3FpY0ZkdUdxWFNIUgpDNUVhbFg4ekRJZ01jV1YwNnNkUWl1TWNKNUFDSUVLK2dMVWRJTUVDLytGYWxKQ1pvZ2RFVmpSRGJPQ0NtNU0vCmMzYk9xcjRUaWlSWFdjSGxNdkJ0bHI5SWdSZ2R2QXNxMzBkdUhkZnJuYWoxV3Z1OTJqUU8zUzJOMDZBM3R4Y1EKME9CQzhCTHFESjBLN0p3ZHJFTVljSXhBZzdiMWpLS09LcHZQdk1hQXhmL2FLRFpKTUNMQ1N2dUdPeFZOSmFMMwpaY1ovcThmUzBRRmJXV3JCakpkUi9ESU5QVWc2NDFFUzNadnFmNGhSMXVjT3VOUi85VWo1TndOY25YWDlHMnNLCkI2dGdpUUlEQVFBQm8xWXdWREFPQmdOVkhROEJBZjhFQkFNQ0JhQXdFd1lEVlIwbEJBd3dDZ1lJS3dZQkJRVUgKQXdJd0RBWURWUjBUQVFIL0JBSXdBREFmQmdOVkhTTUVHREFXZ0JTOFJzV3NNMFRIT3FtQ1lacE9xeGtUajcweQp0VEFOQmdrcWhraUc5dzBCQVFzRkFBT0NBUUVBSXhoNWpWUUFIbXp3ZjlzU3VzRXE2WGZqZ2hZN2NCMDNFSFRpCnU3N0hmeFVyTGRBWitEQXRrTFRrMzEwNkZvMFk3bFJrazRiSWxDN25FTzJKeWNSeWZvdkR2K1VlSElNbG4zbloKMjZtdncwcmRHWTVhUkJkWmE3Q3RCSGR0QVdvNEtkMmxqUjQzZlo3emtYVTRablNQOStSQkhmR3lOdTFneWtWYwpjaTNBaFJ3ZDhkSzNVY0RmQWJEQVB5RWQ4c0t2cDBidE9vbWd0d1lHNHBpSWpHSXFXN2lrSXRoei9kMXZ0S3pSCnN2c1VaMzE3ZzVGa3I0Zm90Q2VZblhwcHpNR1JtNXNCMkJqZlRlSmFnREptTSt5eVBXSTRXVGt0VmxqUndZL1kKaVVvOUxWSnBNNTZHdmNpcUlPdWZRQTl0Rjh5aEhuU0psUFpuUGNEOFdVM3hHNTIxUnc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
        client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVBeG1yUjVpRkhqLzJwdVJsbFI3aG80Z1FNV1JndkVzQnF0SjY5Y2lLSVBmVFRTWnU0Ck5tblMwN2c4NXh1MTgrc0c3SHpncWljRmR1R3FYU0hSQzVFYWxYOHpESWdNY1dWMDZzZFFpdU1jSjVBQ0lFSysKZ0xVZElNRUMvK0ZhbEpDWm9nZEVWalJEYk9DQ201TS9jM2JPcXI0VGlpUlhXY0hsTXZCdGxyOUlnUmdkdkFzcQozMGR1SGRmcm5hajFXdnU5MmpRTzNTMk4wNkEzdHhjUTBPQkM4QkxxREowSzdKd2RyRU1ZY0l4QWc3YjFqS0tPCktwdlB2TWFBeGYvYUtEWkpNQ0xDU3Z1R094Vk5KYUwzWmNaL3E4ZlMwUUZiV1dyQmpKZFIvRElOUFVnNjQxRVMKM1p2cWY0aFIxdWNPdU5SLzlVajVOd05jblhYOUcyc0tCNnRnaVFJREFRQUJBb0lCQUZwYmlPenBHT0xNM0w3TApmdUR6Yk9nSWVlc1U1VkwveDFncnRoQkZBNUJiYnVEbGhqVlphY1k2NzVrN2VGZjFIdmtSUVdxYlRKUy8zY3A5CnZPb3NrVk9sVW9VUmE4RTBOOU0zSTBtc2RVVGJBdXpZR0ZNYXA0SWtBNDZ0ZkllTmRqbGdYOUYyQ1lLS2wwL3IKOVloS2dZRW1BRlgzaU1QNlZic2wzSEk2OS9TNVRrUGN0WUkxazBTcXNIK1lUVS9EOTgvODluMndUeFV2Znl3VQpFTkJGZ0Z2cG9NRVBhRU42djdKa0YyNGRSUUZVMHRWdzRyQjhlT0NVMWl5UWdyc1pVeHlydVpOOXowQVdKMGJKCm9VVCs3WUthK1pFeko3aEU2OEJVNVJiZW5YVitDeWFWSXdlWUhtUWIzVjB1eUZ0dE94V0lYWVNQek1CVmZ4TmsKQkNsU1kxRUNnWUVBMXBDeEJySms1QjdyM21TeEZ1M1o1MUNhNFJuSzk4NFRxWVh2clF5cXE5TDArcnhVaEMrLwpZRDNFbFJRanpVUTNwVzMyZTRjdUJFK3JReHBPT1RTQ0NPZ0VVN3Bpc1c5WmZpREl3L3Vwa1VPYUw1TFRHckNuCkV4VDMybThhNUQwU0p4TFIxT0JOK0hsVDF0MGVGc2V5Uit2aDlFN05GMDNPYk5xZ0hqaEJjTjBDZ1lFQTdMdlYKbEVCcVh1SG5mS2NCQ2dhaXExM1dUSXIyaVFvWlMySmpOZy9Udysyc2p1dXU2QWoyakhHR0gzK0pPNkpMMGVXOApja2piS0JUZTNXcmJySUEyMFh2MnJsSVduYnBybzRvU21URUpId01OVzhXOFZWN2hLOXBzWC9rakdQRktWME9ECkpmYzlJaUpqazRIazJZN2ZJeVRDNHFnNmc1VndzRkU4Ti9XdXZaMENnWUVBeC9uNUZBM0dYSnE1S1FCZDBNb0QKOGtRODVabWRneEl0WHkxMnNhbUJsRDA4bUVoWTJRNkxaazZMWG9weng4ZFJ1YnhnSXNkZHl5VFpzT1BlamhCegpOWXZSSkp3dGljUUcrN2ZnaGxDU3ZOSHQ3WE1Cai9tZTdmajMvRHpiS21nRStDZmhLMitYSEFNd2NheUtjNTdSCmVaak9jbDNUWm1uYy83VlAwSHFMKzMwQ2dZRUE0Q3ExZ2Q3Rld2ZDdaalFWN2RKK3N0cjJsQ0I2ZHlYUzhlbEcKbk9pNzFDbjVYcFNhV1Nvem5LWGJKWFIxRkwwSUlzZnlmQjIxT08wYVpIeE5hN2sxTDRTOUFEREhMYkJiUU03Nwo4WWZYWlVCVW8vUkg5R2NWdlpybFNMUDNvaVRLQ252cGNrZjk0WmJDeCtrV05WVHV3cTZLeEdvY2pvRXg1aVBtCmErNysrcGtDZ1lFQXVIRnpFZzNpL3BPQjI3cVRyYlI2dDR1UjgzNFpieUNGb1J4cG5qYUViNUt6NlU2ZGo4SncKMGZ6RVpjU2E2U1BPcTBCRUJVUGh5cFY5d3NHTmU2WWhrRjVlZDd3ZFBQYWdPVHUxOXBuYTIxZ2hCa2tvbmV1MgpxN0R3dWpja1FYUTR6TGRaMkMrZDh0SGpKQWdtTmc0ZG5qVDVXSmkrZmI1S0hwVFR0MVdKakprPQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=
    - name: user1
      user:
        token: password1

    참고적으로 사용자를 바꾸는 명령어는 다음과 같다.

    $ kubectl config use-context <바꾸고 싶은 user context>
Designed by Tistory.