Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 
(연관된 글이 3개 있습니다.)

kubectl 수행 시 다른 k8s 클러스터로 접속하는 방법

docker의 경우 "-H" 옵션을 이용해,

Linux 운영체제의 docker를 위한 tcp 바인딩 추가
; https://www.sysnet.pe.kr/2/0/12178

Ubuntu 20.04 - docker를 위한 tcp 바인딩 추가
; https://www.sysnet.pe.kr/2/0/12349

또 다른 docker 인스턴스에 접근하는 것이 가능했는데요, kubectl은 이것을 어떻게 할 수 있을까요? 이에 대한 방법을 다음의 글에서 잘 설명하고 있습니다.

Mastering the KUBECONFIG file
; https://ahmet.im/blog/mastering-kubeconfig/

kubeconfig 파일을 사용하여 클러스터 접근 구성하기
; https://kubernetes.io/ko/docs/concepts/configuration/organize-cluster-access-kubeconfig/

간단하게 정리해 볼까요? ^^




지난 글에, docker desktop for windows 환경에서 "Use the WSL 2 based engine" 옵션을 켜고 kind를 이용해 WSL 2와,

$ kind create cluster --name cluster1

$ kubectl cluster-info
Kubernetes master is running at https://127.0.0.1:45381
KubeDNS is running at https://127.0.0.1:45381/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

윈도우 호스트 측에서 각각의 클러스터를 구성할 수 있다고 설명했습니다. (물론, --name의 값만 바꾸면 클러스터를 각각의 환경에서 원하는 대로 생성할 수 있습니다.)

c:\temp\knd> kind create cluster --name cluster2

c:\temp\knd> kubectl cluster-info
Kubernetes master is running at https://127.0.0.1:20971
KubeDNS is running at https://127.0.0.1:20971/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

위와 같은 상황인 경우, WSL 2 측에서 kubectl을 이용해 (윈도우 측에서 생성한) cluster2를 대상으로 명령을 실행하고 싶다면 어떻게 해야 할까요?

간단한 방법이라면, cluster2에 대한 접근 정보를 가지고 있는 윈도우 측의 %USERPROFILE%\.kube\config 파일을 WSL 2 측에 (예를 들어 cluster2.config) 파일로 복사해,

/* 윈도우: type "%USERPROFILE%\.kube\config" */
/* $HOME/.kube 디렉터리에 원래 있던 config 파일 */
$ cat $HOME/.kube/config
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: LS0tL...[생략]...tCg==
    server: https://127.0.0.1:45381
  name: kind-cluster1
contexts:
- context:
    cluster: kind-cluster1
    user: kind-cluster1
  name: kind-cluster1
current-context: kind-cluster1
kind: Config
preferences: {}
users:
- name: kind-cluster1
  user:
    client-certificate-data: LS0t...[생략]...Qo=
    client-key-data: LS0tLS...[생략]...tCg==

/* 윈도우 측의 %USERPROFILE%\.kube\config을 WSL 2 측으로 복사해 온 파일 */
$ cat $HOME/.kube/cluster2.config
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: LS0t...[생략]...Cg==
    server: https://127.0.0.1:20971
  name: kind-cluster2
contexts:
- context:
    cluster: kind-cluster2
    user: kind-cluster2
  name: kind-cluster2
current-context: kind-cluster2
kind: Config
preferences: {}
users:
- name: kind-cluster2
  user:
    client-certificate-data: LS0t...[생략]...Qo=
    client-key-data: LS0tL...[생략]...o=

그 경로를 kubectl의 --kubeconfig 인자로 넘겨주면 됩니다.

$ kubectl --kubeconfig=$HOME/.kube/cluster2.config cluster-info
Kubernetes master is running at https://127.0.0.1:20971
KubeDNS is running at https://127.0.0.1:20971/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

편의상, 명령을 자주 실행해야 한다면 KUBECONFIG 환경 변수를 이용해 지정해 두는 것도 가능합니다.

// 기본 config 경로인 $HOME/.kube/config 정보로 k8s 클러스터 접근
$ kubectl cluster-info
Kubernetes master is running at https://127.0.0.1:45381
KubeDNS is running at https://127.0.0.1:45381/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

// $HOME/.kube/cluster2.config 정보로 k8s 클러스터 접근
$ export KUBECONFIG=$HOME/.kube/cluster2.config
$ kubectl cluster-info
Kubernetes master is running at https://127.0.0.1:20971
KubeDNS is running at https://127.0.0.1:20971/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy




또 다른 방법으로, 별도로 구성한 kubeconfig 파일을 마치 병합하는 듯한 효과를 줘서 kubectl 수행 시 --context 인자로 구분하는 것도 가능합니다. 이를 위해 KUBECONFIG 환경 변수를 다음과 같이 설정하고,

$ export KUBECONFIG=$HOME/.kube/config:$HOME/.kube/cluster2.config

각각의 config 파일 내에 클러스터의 "name: " 항목에 지정하고 있는 이름을 --context 인자에 넘겨 사용할 수 있습니다.

/* 어차피 기본 파일은 $HOME/.kube/config이 있으므로 아래의 명령어는 "kubectl cluster-info"로 대체 가능 */
$ kubectl --context=kind-cluster1 cluster-info
Kubernetes master is running at https://127.0.0.1:45381
KubeDNS is running at https://127.0.0.1:45381/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

$ kubectl --context=kind-cluster2 cluster-info
Kubernetes master is running at https://127.0.0.1:20971
KubeDNS is running at https://127.0.0.1:20971/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

위와 같이 KUBECONFIG을 사용하면 매번 환경 변수를 지정해야 하는 불편함이 있는데, 이를 보완하기 위해 아예 하나의 config 파일로 합치는 방법도 있습니다. 수작업으로 kubeconfig yaml 문법에 맞게 병합할 수 있겠지만, 해당 기능을 kubectl 명령어의 옵션으로도 제공하므로 합쳐질 파일들의 목록을 KUBECONFIG 환경 변수로 전달해 다음과 같이 실행할 수 있습니다.

$ export KUBECONFIG=$HOME/.kube/config:$HOME/.kube/cluster2.config
$ kubectl config view --merge --flatten > out.txt
$ cat out.txt
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: LS0t...[생략]...g==
    server: https://127.0.0.1:45381
  name: kind-cluster1
- cluster:
    certificate-authority-data: LS0...[생략]...==
    server: https://127.0.0.1:20971
  name: kind-cluster2
contexts:
- context:
    cluster: kind-cluster1
    user: kind-cluster1
  name: kind-cluster1
- context:
    cluster: kind-cluster2
    user: kind-cluster2
  name: kind-cluster2
current-context: kind-cluster1
kind: Config
preferences: {}
users:
- name: kind-cluster1
  user:
    client-certificate-data: LS...[생략]...Qo=
    client-key-data: LS0t...[생략]...g==
- name: kind-cluster2
  user:
    client-certificate-data: LS0...[생략]...tLQo=
    client-key-data: LS0t...[생략]...LQo=

이렇게 단일 kubeconfig 파일에 다수의 cluster 정보를 가진 경우 기본적으로는 "current-context"에 지정한 클러스터가 kubectl의 기본 명령어 대상이 됩니다. 실습을 위해 위와 같이 출력한 out.txt 파일을 $HOME/.kube/config 파일로 복사해 놓고 다음의 명령어를 실행해 볼 수 있습니다.

$ kubectl cluster-info
Kubernetes master is running at https://127.0.0.1:45381
KubeDNS is running at https://127.0.0.1:45381/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

$ kubectl cluster-info --context=kind-cluster2
Kubernetes master is running at https://127.0.0.1:20971
KubeDNS is running at https://127.0.0.1:20971/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

/* 아울러 current-context를 명령어를 이용해 변경하는 것도 가능하고! */

// kubeconfig 파일에 등록된 context 목록
$ kubectl config get-contexts
CURRENT   NAME            CLUSTER         AUTHINFO        NAMESPACE
*         kind-cluster1   kind-cluster1   kind-cluster1
          kind-cluster2   kind-cluster2   kind-cluster2

// current-context의 값을 kind-clsuter2로 변경
$ kubectl config use-context kind-cluster2

$ kubectl config get-contexts
CURRENT   NAME            CLUSTER         AUTHINFO        NAMESPACE
          kind-cluster1   kind-cluster1   kind-cluster1
*         kind-cluster2   kind-cluster2   kind-cluster2

참고로 병합한 파일로부터 다시 특정 클러스터 설정만을 별도의 kubeconfig 파일로 뽑아내는 것도 가능합니다.

$ kubectl config view --minify --flatten --context=kind-cluster2 > cluster2.config

$ cat cluster2.config
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: LS0t...[생략]...Cg==
    server: https://127.0.0.1:20971
  name: kind-cluster2
contexts:
- context:
    cluster: kind-cluster2
    user: kind-cluster2
  name: kind-cluster2
current-context: kind-cluster2
kind: Config
preferences: {}
users:
- name: kind-cluster2
  user:
    client-certificate-data: LS0t...[생략]...LQo=
    client-key-data: LS0t...[생략]...LQo=




원한다면, 자동 생성된 kubeconfig 파일을 kubectl 명령어를 이용해 직접 생성하는 것이 가능합니다.

c:\temp\knd> kubectl config --kubeconfig=config-demo set-cluster kind-cluster3 --server=https://127.0.0.1:20971 --certificate-authority="ca-cert-in.crt"
c:\temp\knd> kubectl config --kubeconfig=config-demo set-credentials kind-cluster3 --client-certificate="cert-in.crt" --client-key="cert-in.key"
c:\temp\knd> kubectl config --kubeconfig=config-demo set-context kind-cluster3 --cluster=kind-cluster3 --user=kind-cluster3
c:\temp\knd> kubectl config --kubeconfig=config-demo use-context kind-cluster3

그럼 다음과 같은 config-demo 파일이 생성됩니다.

apiVersion: v1
clusters:
- cluster:
    certificate-authority: ca-cert-in.crt
    server: https://127.0.0.1:20971
  name: kind-cluster3
contexts:
- context:
    cluster: kind-cluster3
    user: kind-cluster3
  name: kind-cluster3
current-context: kind-cluster3
kind: Config
preferences: {}
users:
- name: kind-cluster3
  user:
    client-certificate: cert-in.crt
    client-key: cert-in.key

인증서의 파일 경로는 kubectl을 실행한 경로에 대해 상대적으로 설정되는데요, 따라서 위의 경우에는 실행 시 해당 인증서를 현재의 디렉터리에서 찾을 수 있도록 인증서 및 키 파일을 복사하고 kubectl.exe를 실행해야 합니다.

// c:\temp\knd 디렉터리에 ca-cert-in.crt, cert-in.crt, cert-in.key 파일이 있다고 가정

c:\temp\knd> kubectl cluster-info --kubeconfig=config-demo
Kubernetes master is running at https://127.0.0.1:20971
KubeDNS is running at https://127.0.0.1:20971/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

위의 내용을 실습하려면, config-demo 파일 내에 지정한 certificate-authority, client-certificate, client-key 인증서를 어떻게 구할 수 있느냐라는 문제가 남는데요, 이에 대해서는 다른 글을 통해 다뤄보도록 하겠습니다. ^^




그럴 경우가 많지 않겠지만, 이런 식으로 kind를 이용해 Windows 10에 k8s 클러스터를 구성한 경우 다른 컴퓨터에서 접속하고 싶다면 부가적인 작업을 더 해야 합니다. 우선, kind가 생성하는 기본 클러스터는 TCP 바인딩을 "127.0.0.1"로 고정하기 때문에,

c:\temp> kubectl cluster-info
Kubernetes master is running at https://127.0.0.1:9272
KubeDNS is running at https://127.0.0.1:9272/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

c:\temp> netstat -ano | findstr 20971
  TCP    127.0.0.1:20971        0.0.0.0:0              LISTENING       34208

이것을 "0.0.0.0"으로 바인딩을 바꾸기 위해 yml에 명시하고,

# cluster-config.yml
kind: Cluster
name: cluster3
apiVersion: kind.x-k8s.io/v1alpha4
networking:
  apiServerAddress: "0.0.0.0"

클러스터를 생성하면,

c:\temp\wsl2> kind create cluster --config=cluster-config.yml

C:\temp\wsl2> docker ps
CONTAINER ID   IMAGE                  COMMAND                  CREATED          STATUS          PORTS                       NAMES
382ca15b6502   kindest/node:v1.20.2   "/usr/local/bin/entr…"   39 seconds ago   Up 36 seconds   0.0.0.0:16109->6443/tcp     cluster3-control-plane

c:\temp\wsl2> netstat -ano | findstr 16109
  TCP    0.0.0.0:16109          0.0.0.0:0              LISTENING       34208
  TCP    [::]:16109             [::]:0                 LISTENING       34208
  TCP    [::1]:16109            [::]:0                 LISTENING       25360

TCP 바인딩이 "0.0.0.0"으로 바뀌었습니다. 이제 %USERPROFILE\.kube\config 파일을 다른 컴퓨터에 복사하고, 아래의 "server" 주소만 "0.0.0.0"에서,

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: LS0tLS1...[생략]...Cg==
    server: https://0.0.0.0:16109
  name: kind-cluster3
...[생략]...

IP 주소(예를 들어, 이 글에서는 192.168.100.50이라고 가정)를 직접 기입한 후 kubectl.exe를 다음과 같이 실행해 볼 수 있습니다.

C:\temp> kubectl get pods
Unable to connect to the server: x509: certificate is valid for 10.96.0.1, 172.18.0.3, 0.0.0.0, not 192.168.100.50

보는 바와 같이 허용된 DNS/IP가 인증서에 포함되어 있지 않기 때문에 발생하는 오류입니다. 괜찮습니다, ^^ 이런 경우에도 "--insecure-skip-tls-verify" 옵션을 적용하면 되기 때문입니다.

C:\temp> kubectl cluster-info  --insecure-skip-tls-verify
Kubernetes master is running at https://192.168.100.50:16109
KubeDNS is running at https://192.168.100.50:16109/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

C:\temp> kubectl run nginx-app --image nginx --port=80 --insecure-skip-tls-verify
pod/nginx-app created




config 파일의 설정에서 특정 클러스터 정보를 삭제하려면 3번의 명령을 수행해야 합니다. 즉, 각 yaml 설정에서 users, contexts, clsuters에 추가된 항목의 이름을 알아내 개별 삭제합니다.
$ kubectl config unset users.[지우려는 users의 name]
$ kubectl config unset contexts.[지우려는 contexts의 name]
$ kubectl config unset clusters.[지우려는 clusters의 name]

이후 만약 삭제한 클러스터가 current-context에 해당한다면 다음의 명령어로 다른 클러스터로 스위칭을 합니다.
$ kubectl config use-context [...남아 있는 클러스터 이름...]




다음과 같이 kubeconfig 파일 변경 시 권한 오류가 발생한다면?

/* 사용자 명이 testusr인 경우 */

$ kubectl config set-context kindcluster2
error: open /home/testusr/.kube/config: permission denied

아마도 WSL 2의 config 파일을 윈도우 탐색기를 이용해 "\\wsl$\Ubuntu20.04\home\testusr\.kube" 디렉터리로 접근 후 직접 config 파일을 생성하는 등의 변경을 가해서 그런 경우일 수 있습니다. 실제로 권한을 확인해 보면,

$ ls -l /home/testusr/.kube
total 40
drwxr-x--- 4 testusr testusr  4096  Mar 21 16:25 cache
-rw-r--r-- 1 root    root     10970 Mar 24 11:38 config

라는 식으로 나올 텐데요, 다음과 같이 권한을 변경해 주면 됩니다.

$ sudo chown $USER:$USER /home/testusr/.kube/config




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]

[연관 글]






[최초 등록일: ]
[최종 수정일: 1/26/2022]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




... 31  32  33  34  35  [36]  37  38  39  40  41  42  43  44  45  ...
NoWriterDateCnt.TitleFile(s)
12739정성태7/28/20217361오류 유형: 746. Azure Active Directory - IDW10106: The 'ClientId' option must be provided.
12738정성태7/28/20217959오류 유형: 745. Azure Active Directory - Client credential flows must have a scope value with /.default suffixed to the resource identifier (application ID URI).
12737정성태7/28/20216917오류 유형: 744. Azure Active Directory - The resource principal named api://...[client_id]... was not found in the tenant
12736정성태7/28/20217463오류 유형: 743. Active Azure Directory에서 "API permissions"의 권한 설정이 "Not granted for ..."로 나오는 문제
12735정성태7/27/20217983.NET Framework: 1081. C# - Azure AD 인증을 지원하는 데스크톱 애플리케이션 예제(Windows Forms) [2]파일 다운로드1
12734정성태7/26/202123940스크립트: 20. 특정 단어로 시작하거나/끝나는 문자열을 포함/제외하는 정규 표현식 - Look-around
12733정성태7/23/202111211.NET Framework: 1081. Self-Contained/SingleFile 유형의 .NET Core/5+ 실행 파일을 임베딩한다면? [1]파일 다운로드2
12732정성태7/23/20216530오류 유형: 742. SharePoint - The super user account utilized by the cache is not configured.
12731정성태7/23/20217724개발 환경 구성: 584. Add Internal URLs 화면에서 "Save" 버튼이 비활성화 된 경우
12730정성태7/23/20219237개발 환경 구성: 583. Visual Studio Code - Go 코드에서 입력을 받는 경우
12729정성태7/22/20218189.NET Framework: 1080. xUnit 단위 테스트에 메서드/클래스 수준의 문맥 제공 - Fixture
12728정성태7/22/20217643.NET Framework: 1079. MSTestv2 단위 테스트에 메서드/클래스/어셈블리 수준의 문맥 제공
12727정성태7/21/20218650.NET Framework: 1078. C# 단위 테스트 - MSTestv2/NUnit의 Assert.Inconclusive 사용법(?) [1]
12726정성태7/21/20218469VS.NET IDE: 169. 비주얼 스튜디오 - 단위 테스트 선택 시 MSTestv2 외의 xUnit, NUnit 사용법 [1]
12725정성태7/21/20217163오류 유형: 741. Failed to find the "go" binary in either GOROOT() or PATH
12724정성태7/21/20219909개발 환경 구성: 582. 윈도우 환경에서 Visual Studio Code + Go (Zip) 개발 환경 [1]
12723정성태7/21/20217535오류 유형: 740. SharePoint - Alternate access mappings have not been configured 경고
12722정성태7/20/20217348오류 유형: 739. MSVCR110.dll이 없어 exe 실행이 안 되는 경우
12721정성태7/20/20217958오류 유형: 738. The trust relationship between this workstation and the primary domain failed. - 세 번째 이야기
12720정성태7/19/20217328Linux: 43. .NET Core/5+ 응용 프로그램의 Ubuntu (Debian) 패키지 준비
12719정성태7/19/20216509오류 유형: 737. SharePoint 설치 시 "0x800710D8 The object identifier does not represent a valid object." 오류 발생
12718정성태7/19/20217084개발 환경 구성: 581. Windows에서 WSL로 파일 복사 시 root 소유권으로 적용되는 문제파일 다운로드1
12717정성태7/18/20217037Windows: 195. robocopy에서 파일의 ADS(Alternate Data Stream) 정보 복사를 제외하는 방법
12716정성태7/17/20217865개발 환경 구성: 580. msbuild의 Exec Task에 robocopy를 사용하는 방법파일 다운로드1
12715정성태7/17/20219503오류 유형: 736. Windows - MySQL zip 파일 버전의 "mysqld --skip-grant-tables" 실행 시 비정상 종료 [1]
12714정성태7/16/20218277오류 유형: 735. VCRUNTIME140.dll, MSVCP140.dll, VCRUNTIME140.dll, VCRUNTIME140_1.dll이 없어 exe 실행이 안 되는 경우
... 31  32  33  34  35  [36]  37  38  39  40  41  42  43  44  45  ...