Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 
(연관된 글이 1개 있습니다.)
(시리즈 글이 4개 있습니다.)
개발 환경 구성: 557. Docker Desktop for Windows에서 DockerDesktopVM 기반의 Kubernetes 구성
; https://www.sysnet.pe.kr/2/0/12575

개발 환경 구성: 558. Docker Desktop for Windows에서 DockerDesktopVM 기반의 Kubernetes 구성 (2) - k8s 서비스 위치
; https://www.sysnet.pe.kr/2/0/12576

개발 환경 구성: 559. Docker Desktop for Windows 기반의 Kubernetes 구성 - WSL 2 인스턴스에 kind 도구로 k8s 클러스터 구성
; https://www.sysnet.pe.kr/2/0/12577

개발 환경 구성: 560. Docker Desktop for Windows 기반의 Kubernetes 구성 (2) - WSL 2 인스턴스에 kind가 구성한 k8s 서비스 위치
; https://www.sysnet.pe.kr/2/0/12578




Docker Desktop for Windows 기반의 Kubernetes 구성 - WSL 2 인스턴스에 kind 도구로 k8s 클러스터 구성

이전 글을 통해 "Docker Desktop for Windows" 환경에서 쉽게 k8s 구성을 실습할 수 있었는데요,

Docker Desktop for Windows에서 DockerDesktopVM 기반의 Kubernetes 구성
; https://www.sysnet.pe.kr/2/0/12575

위의 글은 DockerDesktopVM 기반이었지만, 새롭게 WSL 2로의 통합 환경에서 k8s를 구성하는 것도 가능합니다.

하지만 아쉽게도 제 경우에 아래의 이유로 실패를 했는데요,

WSL 2 기반으로 "Enable Kubernetes" 활성화 시 초기화 실패
; https://www.sysnet.pe.kr/2/0/12571

^^ 상관없습니다. 그냥 k8s를 구성해도 되기 때문입니다. (아마도 저 문제가 해결되면 저 방법으로 하는 것이 더 좋겠지만!) 어차피 Docker Desktop for Windows의 목적 자체가 로컬 개발 환경인데다, k8s 클러스터를 그런 환경으로 빠르게 구축해 주는 kind라는 도구가 있으므로 환경 구성이 매우 쉽습니다.

WSL+Docker: Kubernetes on the Windows Desktop
; https://kubernetes.io/blog/2020/05/21/wsl-docker-kubernetes-on-the-windows-desktop/

Kind를 이용한 쿠버네티스 클러스터 만들기
; https://jupilhwang.github.io/post/kind%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EC%BF%A0%EB%B2%84%EB%84%A4%ED%8B%B0%EC%8A%A4-%ED%81%B4%EB%9F%AC%EC%8A%A4%ED%84%B0-%EB%A7%8C%EB%93%A4%EA%B8%B0/

kind를 이용해 직접 WSL 2 환경에서 k8s를 운영하면 좋은 한 가지 이점이라면, Hyper-V에서 더 이상 "DockerDesktopVM" 인스턴스가 (필요가 없으므로) 올라오지 않는다는 점입니다.

반면 kind를 이용해 k8s를 구성할 때 한 가지 단점이라면 DockerDesktopVM을 사용할 때와는 달리 WSL 2를 사용하는 경우 약간 혼란스러울 수 있다는 점입니다. DockerDesktopVM을 사용하면 해당 VM에 설치된 리눅스 인스턴스에 (공식적으로) 접근할 수 있는 방법이 없으므로 모든 구성을 윈도우 측의 kubectl.exe, docker.exe를 이용해 통합/구성하게 됩니다. 반면 WSL 2를 이용해 docker/k8s + kind로 구성하면 docker/kubectl 명령을 WSL 2와 윈도우 호스트 측 모두에서 사용 가능하다는 차이점이 발생합니다.

여기서 문제는, docker의 경우 "Use the WSL 2 based engine" 옵션 덕분에 잘 통합이 되어서 WSL 2와 윈도우 호스트 측에서 실행할 때 단일한 docker 인스턴스로 작업을 하는 반면, kind의 경우에는 WSL 2와 윈도우 호스트 측에서 실행할 때 각기 별개의 k8s 클러스터를 생성한다는 것입니다.

이게 어떤 상황인지 좀 더 자세하게 살펴보겠습니다.




이미 언급한 대로 kind 구성은, 1) WSL 2 인스턴스 내에서 할 수도 있고, 2) 윈도우 호스트 측에서 실행하는 것도 가능합니다. 우선, WSL 2 내에서 kind를 실행해 k8s 클러스터를 구성해 보겠습니다.

/* kind 실행 모듈 다운로드 */
$ curl -Lo ./kind https://github.com/kubernetes-sigs/kind/releases/download/v0.10.0/kind-linux-amd64
$ chmod +x ./kind
$ sudo mv ./kind /usr/local/bin/

/* kind로 클러스터 구성 */
$ kind create cluster --name mycluster1
Creating cluster "mycluster1" ...
 ✓ Ensuring node image (kindest/node:v1.17.0) 🖼
 ✓ Preparing nodes 📦
 ✓ Writing configuration 📜
 ✓ Starting control-plane 🕹️
 ✓ Installing CNI 🔌
 ✓ Installing StorageClass 💾
Set kubectl context to "kind-mycluster1"
You can now use your cluster with:

kubectl cluster-info --context mycluster1

Not sure what to do next? 😅 Check out https://kind.sigs.k8s.io/docs/user/quick-start/

저게 끝입니다. kind는 "create cluster ..." 명령어로 이미 k8s 클러스터 관련한 모든 구성을 완료합니다. 이렇게 구성한 "mycluster1" 클러스터에 대한 정보는 이렇게 알아낼 수 있습니다.

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

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

$ kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://127.0.0.1:39339
  name: kind-mycluster1
contexts:
- context:
    cluster: kind-mycluster1
    user: kind-mycluster1
  name: kind-mycluster1
current-context: kind-mycluster1
kind: Config
preferences: {}
users:
- name: kind-mycluster1
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED

즉, kind가 하는 일은 k8s 클러스터를 위한 모든 서비스를 구성하고, 현재 사용자의 프로파일 디렉터리($HOME/.kube)에 config 파일을 만들어 해당 클러스터에 대한 연결 정보를 구성합니다.

참고로, WSL 2에서 실행한 kind는 윈도우 호스트 환경을 인식하지는 않으므로 kubectl.exe 명령을 윈도우 호스트 측에서 실행하면 다음과 같은 출력이 나옵니다.

c:\temp\knd> kubectl config view
apiVersion: v1
clusters: null
contexts: null
current-context: ""
kind: Config
preferences: {}
users: null

c:\temp\knd> kubectl get pods
Unable to connect to the server: dial tcp [::1]:8080: connectex: No connection could be made because the target machine actively refused it.

그래서 이런 경우에는 WSL 2 인스턴스 측에서 kubectl proxy를 실행해 두면,

$ kubectl proxy -p=8080
Starting to serve on 127.0.0.1:8080

(WSL 2의 네트워크 구성의 특징에 따라) 윈도우 호스트 측에서 kubectl이 정상적으로 실행됩니다.

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

C:\temp> kubectl get pods
NAME        READY   STATUS    RESTARTS   AGE
nginx-app   1/1     Running   0          16s

C:\temp> kubectl expose pod nginx-app --type=NodePort
service/nginx-app exposed

C:\temp> kubectl get svc
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP        16h
nginx-app    NodePort    10.96.199.21   <none>        80:32539/TCP 6s

/* 삭제
kubectl delete svc nginx-app
kubectl delete pod nginx-app

kind delete cluster --name mycluster1
*/




위에서는 WSL 2 인스턴스 환경 내에서 kind를 실행해 클러스터를 생성했지만, 윈도우 호스트 측에서 하는 것도 가능합니다. 이를 위해 PowerShell을 이용해 chocolatey 패키지 관리자를 먼저 설치한 후,

Running kind in Windows
; https://blog.nillsf.com/index.php/2020/08/28/running-kind-in-windows/

Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))

이것을 이용해 kind 도구를 구성할 수 있습니다.

// 관리자 권한으로 실행

choco install kind -y

choco upgrade kind -y

이후 클러스터 생성 방법은 WSL 2에서의 실행과 동일합니다.

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

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

위의 출력 결과에서 볼 수 있듯이, kind는 WSL 2 환경을 인식하지 않으므로 윈도우 명령행에서 실행하면 또다시 새롭게 k8s 클러스터를 만듭니다. 그리고, 역시 윈도우 사용자의 프로파일 디렉터리(%USERPROFILE%\.kube)에 새롭게 생성한 k8s 클러스터를 바라보는 config 파일을 구성하게 됩니다.




이런 식으로 따로 구성을 하기 때문에 혼란스러운 점이 하나 있는데요.

WSL 2에서 구성했을 때는 이후 윈도우 호스트 측에서 WSL 2로 kubectl proxy를 이용해 접속하는 것이 가능했지만, 그 반대인 이번 경우에는 WSL 2에서 호스트 측으로의 "localhost"를 이용한 통신이 안 되므로, 윈도우 호스트 환경 내에서만 kubectl로 해당 클러스터를 사용할 수 있다는 차이가 있습니다. (물론, kubectl proxy를 이용한 방법은 안 되지만 "kubectl 수행 시 다른 k8s 클러스터로 접속하는 방법"를 이용하면 WSL 2 측의 kubectl로 윈도우 호스트에 구성한 클러스터를 접근하는 것이 가능합니다.)

개인적인 의견인데, 저렇게 2개의 클러스터를 사용하면 자칫 실수를 할 수 있기 때문에 제 생각에는 (docker desktop for windows에서 "Use the WSL 2 based engine" 옵션을 켜고 kind를 이용해 구성할 때는) 어느 한 쪽에서 클러스터를 만든 다음 .kube 디렉터리에 생성한 config 파일을,

[WSL 2]
$HOME/.kube/config

[윈도우]
%USERPROFILE\.kube\config

다른 한 쪽에 복사하는 것을 권장합니다. 그럼 같은 클러스터를 바라보게 되므로 사용 중의 혼란을 없앨 수 있습니다. (아마도 이 부분은 "Enable Kubernetes" 옵션이 WSL 2와의 문제없이 잘 실행이 되었다면 config 파일을 양쪽 모두 동일한 클러스터를 바라보도록 공유하지 않았을까... 추측해 봅니다.)




그런데, Docker Desktop for Windows 구성을 DockerDesktopVM에 하는 경우와는 달리 WSL 2에 kind를 이용해 구성하면 불편한 점이 하나 더 있습니다. 일례로 다음과 같이 서비스를 생성한 경우,

c:\temp\knd> kubectl run nginx-app --image nginx --port=80
pod/nginx-app created

c:\temp\knd> kubectl expose pod nginx-app --type=NodePort
service/nginx-app exposed

c:\temp\knd> kubectl get svc
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP        8m45s
nginx-app    NodePort    10.96.56.220   <none>        80:30814/TCP   9s

기존에 DockerDesktopVM을 이용해 구성한 k8s 환경의 경우 curl을 이용해 저 서비스로 곧바로 접속할 수 있었습니다. 하지만, ("Use the WSL 2 based engine" 옵션을 켜고) kind로 구성한 경우에는 curl로 접속이 안 됩니다.

c:\temp\knd> curl localhost:30814
curl: (7) Failed to connect to localhost port 30814: Connection refused

이에 대해서는 다음의 문서에서 다루고 있는데요,

Accessing a Kubernetes Service running in WSL2
; https://kind.sigs.k8s.io/docs/user/using-wsl2/#accessing-a-kubernetes-service-running-in-wsl2

실습을 위해 이전에 생성해 둔 클러스터를 삭제하고, 새롭게 다음의 config으로 클러스터를 생성한 후,

# cluster-config.yml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
  extraPortMappings:
  - containerPort: 30000
    hostPort: 30000
    protocol: TCP

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

nginx 서비스를 deployment를 이용해 구성하면,

c:\temp> kubectl create deployment nginx --image=nginx --port=80

c:\temp> kubectl create service nodeport nginx --tcp=80:80 --node-port=30000

curl 명령어로 nginx로의 접근이 가능합니다.

c:\temp> curl localhost:30000

(왜 이런 차이가 발생하는지에 대한 자세한 설명은 "Docker Desktop for Windows 기반의 Kubernetes 구성 (2) - WSL 2 인스턴스에 kind가 구성한 k8s 서비스 위치" 글을 참고하세요.)




WSL 2 인스턴스 내에서 kind로 클러스터 생성 시 다음과 같은 오류가 발생한다면?

$ kind create cluster --name wslkind
ERROR: failed to list clusters: command "docker ps -q -a --no-trunc --filter label=io.x-k8s.kind.cluster=wslkind --format '{{.Names}}'" failed with error: exit status 1

실제로 문제가 되는 명령어를 직접 실행해 보면 답이 나옵니다.

$ docker ps -q -a --no-trunc --filter label=io.x-k8s.kind.cluster-wslkind --format '{{.Names}}'
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/json?all=1&filters=%7B%22label%22%3A%7B%22io.x-k8s.kind.cluster-wslkind%22%3Atrue%7D%7D: dial unix /var/run/docker.sock: connect: permission denied

따라서, docker 그룹에 현재 로그인 사용자를 등록해 주면 됩니다. (혹은, 권한에 걸리지 않는 root 계정으로 전환 후 실행해도 됩니다.)




간혹, kubectl run 했을 때 다음과 같은 오류가 발생한다면?

c:\temp\knd> kubectl run nginx-app --image nginx --port=80
Error from server (Forbidden): pods "nginx-app" is forbidden: error looking up service account default/default: serviceaccount "default" not found

오류 메시지의 의미는, default 네임스페이스에 default 서비스 계정이 없다는 것입니다. 이에 대한 확인은 다음과 같이 할 수 있는데,

c:\temp\knd> kubectl get serviceaccount -n default
NAME      SECRETS   AGE
default   1         3m50s

저렇게 나오면 다시 "kubectl run ..."을 실행해 보면 됩니다. (만약 실제로 서비스 계정이 없다면 오류가 발생하는 것이 맞습니다.)




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

[연관 글]






[최초 등록일: ]
[최종 수정일: 6/12/2024]

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

비밀번호

댓글 작성자
 




... 91  92  93  94  95  96  97  [98]  99  100  101  102  103  104  105  ...
NoWriterDateCnt.TitleFile(s)
11517정성태5/10/201819439.NET Framework: 746. Azure runbook 예제 - 6시간 동안 수행 중인 VM을 중지 [1]파일 다운로드1
11516정성태5/9/201820192.NET Framework: 745. Azure runbook을 PowerShell 또는 C# 코드로 실행하는 방법파일 다운로드1
11515정성태5/9/201822697.NET Framework: 744. C# 6 - Expression bodied function [1]
11514정성태5/3/201820691오류 유형: 466. Bitvise - Error in component session/transport/kexHandler [2]
11513정성태5/3/201827545.NET Framework: 743. C# 언어의 공변성과 반공변성 [9]파일 다운로드2
11512정성태5/2/201819821개발 환경 구성: 375. Azure runbook 실행 시 "Errors", "All Logs"에 오류 메시지가 출력되는 경우
11511정성태5/2/201821479개발 환경 구성: 374. Azure - Runbook 기능 소개
11510정성태4/30/201822317.NET Framework: 742. windbg로 확인하는 Finalizer를 가진 객체의 GC 과정파일 다운로드1
11509정성태4/28/201820714.NET Framework: 741. windbg로 확인하는 객체의 GC 여부
11508정성태4/23/201822340개발 환경 구성: 373. MSBuild를 이용해 프로젝트 배포 후 결과물을 zip 파일로 압축하는 방법파일 다운로드1
11507정성태4/20/201822916개발 환경 구성: 372. MSBuild - 빌드 전/후, 배포 전/후 실행하고 싶은 Task 정의
11506정성태4/20/201827156.NET Framework: 740. C#에서 enum을 boxing 없이 int로 변환하기 - 두 번째 이야기 [7]파일 다운로드1
11505정성태4/19/201819971개발 환경 구성: 371. Azure Web App 확장 예제 - Simple WebSite Extension
11504정성태4/19/201821565오류 유형: 465. Azure Web App 확장 - Extplorer File manager 적용 시 오류
11503정성태4/19/201820596오류 유형: 464. PowerShell - Start-Service 명령 오류 (Service 'xxx' cannot be started)
11502정성태4/17/201822798개발 환경 구성: 370. Azure VM/App Services(Web Apps)에 Let's Encrypt 무료 인증서 적용 방법 [3]
11501정성태4/17/201820023개발 환경 구성: 369. New-AzureRmADServicePrincipal로 생성한 계정의 clientSecret, key 값을 구하는 방법파일 다운로드1
11500정성태4/17/201821003개발 환경 구성: 368. PowerShell로 접근하는 Azure의 Access control 보안과 Azure Active Directory의 계정 관리 서비스
11499정성태4/17/201819645개발 환경 구성: 367. Azure - New-AzureRmADServicePrincipal / New-AzureRmRoleAssignment 명령어
11498정성태4/17/201819738개발 환경 구성: 366. Azure Active Directory(Microsoft Enfra ID)의 사용자 유형 구분 - Guest/Member
11497정성태4/17/201817563개발 환경 구성: 365. Azure 리소스의 액세스 제어(Access control) 별로 사용자에게 권한을 할당하는 방법 [2]
11496정성태4/17/201818086개발 환경 구성: 364. Azure Portal에서 구독(Subscriptions) 메뉴가 보이지 않는 경우
11495정성태4/16/201819909개발 환경 구성: 363. Azure의 Access control 보안과 Azure Active Directory의 계정 관리 서비스
11494정성태4/16/201816234개발 환경 구성: 362. Azure Web Apps(App Services)에 사용자 DNS를 지정하는 방법
11493정성태4/16/201818027개발 환경 구성: 361. Azure Web App(App Service)의 HTTP/2 프로토콜 지원
11492정성태4/13/201816028개발 환경 구성: 360. Azure Active Directory의 사용자 도메인 지정 방법
... 91  92  93  94  95  96  97  [98]  99  100  101  102  103  104  105  ...