개발놀이터

쿠버네티스 실습 : 환경 구축 (워커 노드에 권한 부여) 본문

배포/kubernetes

쿠버네티스 실습 : 환경 구축 (워커 노드에 권한 부여)

마늘냄새폴폴 2024. 9. 15. 16:19

이번 포스팅은 쿠버네티스 환경을 구축하는 과정에서 생긴 실습 과정을 정리해보고자 작성하게 되었습니다. 

 

쿠버네티스는 워커 노드를 설정하면 kubectl 명령어를 곧바로 사용할 수 없습니다. 이를 사용하기 위해서는 쿠버네티스의 인증, 인가 과정을 거쳐야 합니다. 

 

이에대한 자세한 내용은 아래의 링크에 정리되어있습니다!

https://coding-review.tistory.com/549

 

쿠버네티스 이론 : 인증, 인가

쿠버네티스는 쿠버네티스와 관련된 명령어를 사용할 때 마스터 노드에 존재하는 API Server를 지나가게 되어있습니다.  하지만 어떤 곳에서든 kubectl같은 명령어를 사용할 수 있다면 이는 보안적

coding-review.tistory.com

 

워커 노드에서 kubectl 명령어를 사용하기 위해서 저는 kubeconfig와 Service Account (이하 SA) 를 조합해서 워커 노드에 권한을 부여했습니다. 

 

워커 노드에 권한 부여

제가 실습했던 내용을 도식화해봤습니다. 

 

흐름은 이렇게 진행됩니다. 

 

  1. SA를 만든다. 
  2. ClusterRole을 만든다. 이때 API Server에 어떤 명령만 허용할 것인지를 정의한다. 
  3. ClusterRoleBinding으로 SA와 ClusterRole을 이어준다. 
  4. SA를 이용해서 토큰을 만든다. 이는 kubeconfig의 user에 넣어준다. 
  5. admin.conf에서 Certificate Authority Data를 뽑아서 이는 kubeconfig의 certificate-authority-data에 넣어준다.
  6. 워커 노드에서 worker-kubeconfig라는 이름으로 (제가 임의로 지은 이름입니다.) 파일을 만들고 이를 워커 노드의 KUBECONFIG 변수로 정해준다. 
  7. Optional (옵션) : 다른 워커노드에 이 worker-kubeconfig 파일을 옮겨서 적용시킨다. 

 

한번 본격적으로 시작해보도록 하겠습니다! 순서대로 진행할 것이고 순서 옆에 어떤 노드에서 진행되고 있는 것인지 적겠습니다!

 

1. SA를 만든다. (마스터노드)

kubectl create serviceaccount worker-sa

 

2. ClusterRole을 만든다. (마스터노드)

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: worker-node-access
rules:
- apiGroups: [""]
  resources: ["nodes"]
  verbs: ["get", "list", "watch"]

 

임의로 파일 이름을 지어주고 오브젝트를 만들어보겠습니다. 저는 worker-cr 이라고 지었습니다. 

 

kubectl apply -f ./worker-cr

 

이렇게 오브젝트를 만들어줍ㄴ디ㅏ. 

 

3. ClusterRoleBinding을 만든다. (마스터노드)

kubectl create clusterrolebinding {ClusterRoleBinding 이름} --clusterrole={ClusterRole 이름} --serviceaccount=default:{Service Account 이름}

 

4. SA에서 토큰을 뽑아낸다. (마스터노드)

kubectl create token worker-sa

 

이 토큰 값을 잘 적어주시길 바랍니다. 

 

5. admin.conf에서 CA-data를 뽑는다. (마스터노드)

sudo cat /etc/kubernetes/admin.conf | grep certificate-authority-data

 

이 값 또한 잘 적어주시길 바랍니다. 

 

6. 워커노드에서 Config 오브젝트를 만든다. 

apiVersion: v1
kind: Config
clusters:
- cluster:
    server: https://{control-plane의 내부아이피}:6443
    certificate-authority-data: {admin.conf에서 뽑은 CA-data값}
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: worker-sa
  name: worker-sa-context
current-context: worker-sa-context
users:
- name: worker-sa
  user:
    token: {SA에서 뽑은 토큰 값}

 

이렇게 만든 다음 주의해야할 점은 contexts > context > user 에 있는 worker-sa라는 값과 users > name 에 있는 worker-sa라는 값이 동일해야합니다. 

 

7. 워커노드에서 이 값을 바탕으로 KUBECONFIG 환경변수로 설정해준다.

저는 위의 Config파일 이름을 worker-kubeconfig라고 지어줬습니다. 

 

export KUBECONFIG=./worker-kubeconfig

 

이제 kubectl get nodes를 입력해보면?

 

 

pods는 조회할 수 없는 것을 확인할 수 있습니다. 

 

그런데 이 방식은 문제가 있습니다. 사실 함정이 있습니다. 

 

Short Term Token VS Long Term Token

위에서 언급한 방식은 Short Term Token 즉, 토큰이 금방 만료된다는 특징이 있습니다. 

 

보통 이런 짧은 만료시간을 가진 토큰을 사용하는 이유는 보안의 위험때문인데요. JWT에서 Access Token과 Refresh Token이 따로 존재하는 것이고 우리는 지금 Access Token을 발급받아서 사용한 것입니다. 

 

그럼 Refresh Token처럼 오랫동안 사용할 수 있는 토큰을 발급받아서 오래 사용할 수 있는 방법도 있을까요? 

 

당연히 있습니다.

 

바로 Secret 오브젝트를 만들어서 토큰을 발급하는 방법입니다. 

 

맨처음 우리가 토큰을 만들 때 사용한 방식은 SA를 토큰으로 만들었습니다. 이렇게 SA로 토큰을 만들면 짧은 만료기간을 가진 토큰이 발급됩니다. 

 

하지만 Secret으로 발급하면 우리가 이 Secret을 삭제하지 않는한 계속 이 토큰을 사용할 수 있습니다. 

 

 

이 그림에서 SA가 Secret으로 바뀌기만 한다고 생각해주시면 될 것 같습니다. 

 

그럼 Secret을 만들어야겠죠? 한번 만들어보겠습니다. 이 작업은 모두 마스터 노드에서 진행해야합니다. 

 

apiVersion: v1
kind: Secret
metadata:
  name: worker-node-access-secret
  annotations:
    kubernetes.io/service-account.name: worker-sa
type: kubernetes.io/service-account-token

 

여기서 주의하셔야할 점은 우리가 만든 SA를 사용하지 않는 것은 아니라는 것이고 우리가 만든 worker-sa를 그대로 사용해야한다는 것입니다. 

 

이름이 틀리면 적용되지 않으니 주의해주시면 감사하겠습니다. 

 

저는 이 파일이름을 worker-node-access-secret.yml로 지었습니다. 

 

kubectl apply -f ./worker-node-access-secret.yml

 

이렇게 배포하고 토큰을 만들어줍니다. 

 

kubectl get secret {Secret 이름} -o jsonpath="{.data.token}" | base64 --decode

 

이제 나온 토큰을 다시 워커 노드로 가져가서 user > token에 넣어주시면 됩니다. 위에서 언급했으니 내용을 다루진 않겠습니다. 

 

그리고 다시 kubect get nodes를 해보면?

 

 

이렇게 잘 나오는 것을 확인할 수 있습니다. 

 

 

마치며

이렇게 쿠버네티스 워커 노드에 권한을 부여해봤습니다. 사실 모든 권한을 다 주는 것이 편하지만 실제 환경을 구축해봄으로서 조금 리얼한 실습을 할 수 있었습니다. 

 

저번 포스팅에선 본격적으로 Spring Boot를 띄워보겠다고 했었는데 kubectl 명령어가 워커 노드에서 동작하지 않아서 이 부분을 해결하느라 시간을 조금 썼습니다. 

 

이제 진짜진짜 본격적으로 pod나 apply에 대한 권한도 워커 노드에 부여하고 본격적으로 스프링 부트를 외부에서 붙을 수 있도록 도전해보겠습니다. 

 

오늘도 긴 글 읽어주셔서 감사합니다. 즐거운 하루 되세요!