728x90

기초적인 것들이 늘 가장 어려운 법입니다. 여러 환경에 구축된 쿠버네티스 클러스터를 다루는 상황이 되니 이게 뭥미~ 하는 생각이 들면서 머릿속이 하얗게 변했습니다. 가령 로컬 환경에 시험용 클러스터가 구축되어 있고 (이하 docker-desktop) 구글 클라우드 플랫폼에 클러스터를 하나 구성한 상황에서 (이하 k8snopd) kubectl 로 양쪽 클러스터를 제어하는 방법의 정리입니다. 


kubectl 설정 파일 확인하기 

kubectl 을 사용하고 있다면 .kube/config 파일에 (맥 기준) 액세스 할 수 있는 클러스터 정보가 기록되어 있습니다. 언급 드린 것처럼 로컬 환경과 GCP 환경에 클러스터가 구성되어 있습니다. 로컬 환경은 맥 용 Docker Desktop 에서 클러스터를 만들었고, GCP 는 gcloud CLI 를 이용해서 원격지 환경에 클러스터를 만들고 접근할 수 있게 가이드를 따랐습니다.

이 상태라면 .kube/config 에는 두 클러스터 접근을 위한 설정이 들어가 있게 됩니다. 설정된 내용은 cat 등으로 조회할 수도 있지만 kubectl 을 이용해서 조회하는 것이 더 깔끔합니다. 

% kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://kubernetes.docker.internal:6443
  name: docker-desktop
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://xx.xxx.xxx.xx
  name: gke_k8s-practice-310514_asia-northeast1-a_k8snopd
contexts:
- context:
    cluster: docker-desktop
    user: docker-desktop
  name: docker-desktop
- context:
    cluster: gke_k8s-practice-310514_asia-northeast1-a_k8snopd
    user: gke_k8s-practice-310514_asia-northeast1-a_k8snopd
  name: gke_k8s-practice-310514_asia-northeast1-a_k8snopd
current-context: gke_k8s-practice-310514_asia-northeast1-a_k8snopd
kind: Config
preferences: {}
users:
- name: docker-desktop
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED
- name: gke_k8s-practice-310514_asia-northeast1-a_k8snopd
  user:
    auth-provider:
      config:
        access-token: ya29.a0AfH6SM...........................
        cmd-args: config config-helper --format=json
        cmd-path: /Downloads/google-cloud-sdk/bin/gcloud
        expiry: "2021-04-15T09:00:09Z"
        expiry-key: '{.credential.token_expiry}'
        token-key: '{.credential.access_token}'
      name: gcp

먼저 clusters 노드로 두개의 cluster 가 지정돤 것이 보입니다. name 키에 지정된 이름이 각각 다른게 보이시죠? GCP 에 만든 클러스터 이름은 다소 복잡합니다. GCP 의 리전명 등이 포함되어 있네요. 이어서 각 클러스터에 접근할 때 사용되는 사용자 토큰 등의 정보가 이어집니다. 

 

kubectl 에서 클러스터 바꾸는 방법

위의 설정에서 주목할 값 중 하나는 current-context 입니다. 제 경우는 GCP 를 나중에 설정해서 그런지 GCP 가 현재 컨텍스트라고 지정되어 있습니다. 즉, kubectl 명령을 사용하면 특별히 컨텍스트를 지정하지 않으면 GCP 의 클러스터로 명령을 날리게 됩니다. 한번 해볼까요?

% kubectl get nodes
NAME                                     STATUS   ROLES    AGE   VERSION
gke-k8snopd-default-pool-8130c84d-371t   Ready    <none>   63m   v1.18.16-gke.502
gke-k8snopd-default-pool-8130c84d-l26t   Ready    <none>   63m   v1.18.16-gke.502
gke-k8snopd-default-pool-8130c84d-xrkt   Ready    <none>   63m   v1.18.16-gke.502

 

그렇다면 로컬 클러스터 (docker-desktop) 로 컨텍스트를 바꾸어 노드 목록을 받아오고 싶다면 어떻게 해야 할까요? kubectl 이 제공하는 --context 매개변수를 이용해서 클러스터의 컨텍스트명을 입력해 주면 쉽게 대상 클러스터를 바꿀 수 있습니다. 함 해보죠!

% kubectl get nodes --context docker-desktop
NAME             STATUS   ROLES    AGE     VERSION
docker-desktop   Ready    master   5d23h   v1.19.3

 


 

 

728x90
728x90

공식 문서의 taints 와 tolerations 에 대해서는 아래의 링크를 참고하면 된다. taints 는 노드에 적용되어 <수용 가능한 Pod 의 특성 정의>정도인 것 같고, tolerations 는 Pod 에 적용되어 <내가 동작할 수 있는 Node 를 선택하기 위한 특성 정의>라고 보면 될 것 같다.

 

테인트(Taints)와 톨러레이션(Tolerations)

노드 어피니티는 노드 셋을 (기본 설정 또는 어려운 요구 사항으로) 끌어들이는 파드의 속성이다. 테인트 는 그 반대로, 노드가 파드 셋을 제외할 수 있다. 톨러레이션 은 파드에 적용되며, 파드

kubernetes.io

 


노드에 설정된 taints 를 확인하기 위해서는 kubectl 에서 describe 옵션을 사용하면 된다.

$ kubectl describe node node01
Name:               node01
Roles:              <none>
Labels:             beta.kubernetes.io/arch=amd64
                    beta.kubernetes.io/os=linux
...
Annotations:        flannel.alpha.coreos.com/backend-data: null
                    flannel.alpha.coreos.com/backend-type: host-gw
...
                    volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp:  Mon, 25 Jan 2021 07:43:27 +0000
Taints:             <none>
Unschedulable:      false
Lease:
  HolderIdentity:  node01
  AcquireTime:     <unset>

 

특정 노드에 특정 key-value 와 effect 값을 지정하여 taints 를 설정. 아래는 spray 를 key 로, mortein 을 value 로, effect 는 NoSchedule 로 지정한 예임

$ kubectl taint nodes node01 spray=mortein:NoSchedule
node/node01 tainted

 

Pod 을 생성할 때 배치된 Node 가 없다면 (이 경우에는 Taints 로 특정한 값이 부여된 Node 밖에 없다) Pod 이 생성되지 못하고 Pending 상태로 머무르며, 상세 에러 내용이 taints 와 tolerations 에 대한 내용이 노출된다.

$ kubectl get pods
NAME       READY   STATUS    RESTARTS   AGE
mosquito   0/1     Pending   0          88s

$ kubectl describe pod mosquito
Name:         mosquito
Namespace:    default
Priority:     0
Node:         <none>
...
...
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                 node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type     Reason            Age               From               Message
  ----     ------            ----              ----               -------
  Warning  FailedScheduling  6s (x3 over 92s)  default-scheduler  0/2 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate, 1 node(s) had taint {spray: mortein}, that the pod didn't tolerate.

 

Pod 을 Taints 가 지정된 Node 로 배포하기 위해서는 Pod 의 스펙에 관련된 값을 지정해 주어야 한다.

$ cat create_pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: bee
spec:
  containers:
  - image: nginx
    name: bee
  tolerations:
  - key: spray
    value: mortein
    effect: NoSchedule
    operator: Equal
    
$ kubectl create -f create_pod.yaml
pod/bee created

 

노드에 할당되어 있는 taints 값의 변경은 아래의 명령으로 수행할 수 있다. 예시는 controlplane 노드에 대하여 값을 부여하고 삭제하는 예시임.

$ kubectl taint nodes controlplane node-role.kubernetes.io/master:NoSchedule
node/controlplane tainted
$
$ kubectl taint nodes controlplane node-role.kubernetes.io/master:NoSchedule-
node/controlplane untainted
728x90

+ Recent posts