성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] 그냥 RSS Reader 기능과 약간의 UI 편의성 때문에 사용...
[이종효] 오래된 소프트웨어는 보안 위협이 되기도 합니다. 혹시 어떤 기능...
[정성태] @Keystroke IEEE의 문서를 소개해 주시다니... +_...
[손민수 (Keystroke)] 괜히 듀얼채널 구성할 때 한번에 같은 제품 사라고 하는 것이 아...
[정성태] 전각(Full-width)/반각(Half-width) 기능을 토...
[정성태] Vector에 대한 내용은 없습니다. Vector가 닷넷 BCL...
[orion] 글 읽고 찾아보니 디자인 타임에는 InitializeCompon...
[orion] 연휴 전에 재현 프로젝트 올리자 생각해 놓고 여의치 않아서 못 ...
[정성태] 아래의 글에 정리했으니 참고하세요. C# - Typed D...
[정성태] 간단한 재현 프로젝트라도 있을까요? 저런 식으로 설명만 해...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>kubeconfig 파일 없이 kubectl 옵션만으로 실행하는 방법</h1> <p> 지난 "<a target='tab' href='https://www.sysnet.pe.kr/2/0/12583'>kubectl 수행 시 다른 k8s 클러스터로 접속하는 방법</a>" 글에서 소개한,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Mastering the KUBECONFIG file ; <a target='tab' href='https://ahmet.im/blog/mastering-kubeconfig/'>https://ahmet.im/blog/mastering-kubeconfig/</a> </pre> <br /> 글에는 "Tip 5: Use kubectl without a kubeconfig"에 대한 명령행이 나옵니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > kubectl get nodes \ --server https://localhost:6443 \ --user docker-for-desktop \ --client-certificate my.cert \ --client-key my.key \ --insecure-skip-tls-verify </pre> <br /> 그런데, 도대체 저 명령행의 my.cert, my.key는 어떻게 구할 수 있는지에 대한 설명이 없습니다. 이번에는 바로 저 내용을 다뤄보려고 하는데요, 대신 인증서와 key 파일을 새로 생성해서 사용하지 않고 기존 kubeconfig 파일의 내용을 기반으로 저 명령어가 동작하게 만들 것입니다.<br /> <br /> <hr style='width: 50%' /><br /> <a name='kubeconfig_path'></a> <br /> 기본적으로 kubectl은 kubeconfig 파일의,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > [WSL 2] $HOME/.kube/config [윈도우] %USERPROFILE\.kube\config </pre> <br /> 설정에 따라 k8s 클러스터와 연동합니다. 그리고 저 config 파일을 보면 다음과 같은 구성을 갖는데요,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > $ <span style='color: blue; font-weight: bold'>cat $HOME/.kube/config</span> apiVersion: v1 clusters: - cluster: <span style='color: blue; font-weight: bold'>certificate-authority-data</span>: LS0tLS1C...[생략]...SUZJQ0FURS0tLS0tCg== 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: <span style='color: blue; font-weight: bold'>client-certificate-data</span>: LS0tLS1CRUdJT...[생략]...tLQo= <span style='color: blue; font-weight: bold'>client-key-data</span>: LS0tLS1CRUdJ...[생략]...U0EgUFJJVkFURSBLRVktLS0tLQo= </pre> <br /> 사실 이 파일이 없어도 kubectl은 옵션 설정만으로 연동을 할 수 있습니다. 가령 다음과 같은 식으로 명령을 수행할 수 있는데요,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > kubectl get nodes --server [master_address] --client-certificate [client_certificate_file_path] --client-key [client_key_file_path] --insecure-skip-tls-verify </pre> <br /> 이 중에서 master_address는 config 파일의 "cluster.server" 항목의 주소(위의 예제에서는 <a target='tab' href='https://127.0.0.1:20971'>https://127.0.0.1:20971</a>)를 넣으면 됩니다. 그다음은 client_certificate_file_path 값을 구해야 하는데요, 이것은 config 파일에 있는 "client-certificate-data" 항목에 설정된 base64 인코딩된 텍스트로부터 구할 수 있습니다.<br /> <br /> 이를 위해 우선 해당 텍스트를 그대로 복사해 (예를 들어 cert-in.txt) 파일로 저장하고,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURFekNDQWZ1Z0F3...[생략]...Q0VSVElGSUNBVEUtLS0tLQo= </pre> <br /> 이 파일을 대상으로 base64 디코딩을 해 인증서 파일(.crt)을 만듭니다. (base64 명령어는 윈도우의 경우 없으므로 <a target='tab' href='https://github.com/stjeong/Utilities/releases/download/v1.1.1/Utilities.zip'>별도로 다운로드</a>해야 합니다.)<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > c:\temp\knd> <span style='color: blue; font-weight: bold'>base64 -d cert-in.txt > cert-in.crt</span> c:\temp\knd> <span style='color: blue; font-weight: bold'>cat cert-in.crt</span> -----BEGIN CERTIFICATE----- MIIDEzCCAfugAwIBAgIIUuKqgS/PRT8wDQYJKoZIhvcNAQELBQAwFTETMBEGA1UE AxMKa3ViZXJuZXRlczAeFw0yMTAzMjQwMjA0NDZaFw0yMjAzMjQwMjA0NDhaMDQx FzAVBgNVBAoTDnN5c3RlbTptYXN0ZXJzMRkwFwYDVQQDExBrdWJlcm5ldGVzLWFk ...[생략]... FS4bA4wsNMBZXYIAjHmvTKPFRl8EDnjSPe31PceV60bkrqhlEwGEYSc8saIXuQd0 fK2inpGIWKfZ6JNnDC4olsAwRHieUaTR/e0xLkP1fX32lxQ9jqp3PmL6lHPq8gWU d9Bh+vOH+kTqeKhbTEGtVaKGoFnS36s= -----END CERTIFICATE----- </pre> <br /> 정상적으로 생성되었는지 openssl을 이용해 crt 파일의 내용을 검증해 볼 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > c:\temp\knd> <span style='color: blue; font-weight: bold'>openssl x509 -in cert-in.crt -noout -text</span> Certificate: Data: Version: 3 (0x2) Serial Number: 5972523527676314943 (0x52e2aa812fcf453f) Signature Algorithm: sha256WithRSAEncryption Issuer: CN = kubernetes Validity Not Before: Mar 24 02:04:46 2021 GMT Not After : Mar 24 02:04:48 2022 GMT Subject: O = system:masters, CN = kubernetes-admin Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public-Key: (2048 bit) Modulus: 00...[생략]...1f: 0f:9b Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Key Usage: critical Digital Signature, Key Encipherment X509v3 Extended Key Usage: TLS Web Client Authentication X509v3 Authority Key Identifier: keyid:98:FA:BD:78:A2:31:85:A3:AA:9D:D5:63:69:03:5C:B6:7E:CE:F6:4B Signature Algorithm: sha256WithRSAEncryption b1:...[생략]...59:d2:df:ab </pre> <br /> 잘 나오는군요. ^^ 마찬가지의 방법으로 [client_key_file_path]를 구할 수 있는데요, config 파일에 있는 client-key-data 값을 cert-in-key.txt로 저장하고,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > LS0tLS1CRU...[생략]...ktLS0tLQo= </pre> <br /> base64 디코딩해 key 파일을 구합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > c:\temp\knd> <span style='color: blue; font-weight: bold'>base64 -d cert-in-key.txt > cert-in.key</span> c:\temp\knd> <span style='color: blue; font-weight: bold'>cat cert-in.key</span> -----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAwCIGezaperQESYswrWaCk/0/EP/Syx/hx8VJIlCwLS1imub7 b1d/oJhi9HbqvTpmq3i1KJFs+uHwT9PSreQqkHIt/M0tWWlXAymPM7bH5H4BTnpK xkaWqToIBlx6oRMdqy+uGZc2yTz8V5WuMHe8lTzxLEslldPnH/GdifvdfBEUc8+x ...[생략]... DexfSujsfyWfXUyLcB0C2xeljvUv+jmyhWs8zcnv5Hkf8ikzURY0YLtjs+qZi6rN csScEQKBgQDxsw0qUZb5gcwt6xZwhTKMiP2dIPIPs85IRu+k1NPJH42ZPNtpAOGy VL/v2JS4DdDExJXsWMLsWTAciYCqFa9+ReBLBoo6mr2UK3UlS19Wtl6VmTgNEByb zcvZmeWJ5C3as4+Vo7nYip6QLjB000b6cPs3wBpszl8znbi1mRrpwg== -----END RSA PRIVATE KEY----- </pre> <br /> 자, 이걸로 준비가 끝났군요. ^^ 인증서와 키 파일을 구했으니 이제 다음과 같은 명령어로 kubectl을 실행할 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > c:\temp\knd> <span style='color: blue; font-weight: bold'>kubectl get nodes --server https://127.0.0.1:20971 --client-certificate cert-in.crt --client-key cert-in.key</span> Error in configuration: * client-cert-data and client-cert are both specified for kind-cluster2. client-cert-data will override. * client-key-data and client-key are both specified for kind-cluster2; client-key-data will override </pre> <br /> (굳이 동작하지 않게 만들 이유가 없었을 것 같은데) 오류의 원인은 %USERPROFILE%\.kube\config 파일이 있기 때문입니다. 임시로, 해당 파일을 삭제(또는 이름 변경)하고 다시 실행해 봅니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > c:\temp\knd> <span style='color: blue; font-weight: bold'>kubectl get nodes --server https://127.0.0.1:20971 --client-certificate cert-in.crt --client-key cert-in.key</span> Unable to connect to the server: x509: certificate signed by unknown authority </pre> <br /> 이 오류는 인증서의 검증을 없애는 옵션을 지정하면 회피할 수 있는데요, 그래서 --insecure-skip-tls-verify 옵션을 주면 다음과 같이 잘 실행이 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > c:\temp\knd> <span style='color: blue; font-weight: bold'>kubectl get nodes --server https://127.0.0.1:20971 --client-certificate cert-in.crt --client-key cert-in.key --insecure-skip-tls-verify</span> NAME STATUS ROLES AGE VERSION cluster2-control-plane Ready control-plane,master 3h48m v1.20.2 </pre> <br /> 또는, --insecure-skip-tls-verify 옵션을 주는 것이 마음에 들지 않는다면 CA 인증서도 함께 명령행에 지정해 주면 됩니다. 이를 위해 config 파일에 있던 "certificate-authority-data" 값을,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > LS0tLS1CRUdJTi...[생략]...0tCg== </pre> <br /> ca-in.txt로 저장하고 base64 디코딩해 파일을 구한 후,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > c:\temp\knd> <span style='color: blue; font-weight: bold'>base64 -d ca-in.txt > ca.crt</span> c:\temp\knd> <span style='color: blue; font-weight: bold'>type ca.crt</span> -----BEGIN CERTIFICATE----- MIIC5zCCAc+gAwIBAgIBADANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwprdWJl cm5ldGVzMB4XDTIxMDMyNDAyMDQ0NloXDTMxMDMyMjAyMDQ0NlowFTETMBEGA1UE AxMKa3ViZXJuZXRlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALXD ...[생략]... 0q4lLsZ0iQz6OtXkmDVvGvF9ICB/x2weBNPuGcWIu4Qs6zf+KO84IqozYqt6XcIc y2bAK1Ho8t45ohcBUFITZDCI+8pgvzB4TBcC -----END CERTIFICATE----- </pre> <br /> --certificate-authority 명령행 인자로 전달하면 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > c:\temp\knd> <span style='color: blue; font-weight: bold'>kubectl get nodes --server https://127.0.0.1:20971 --certificate-authority ca.crt --client-certificate cert-in.crt --client-key cert-in.key</span> NAME STATUS ROLES AGE VERSION cluster2-control-plane Ready control-plane,master 3d5h v1.20.2 </pre> <br /> <hr style='width: 50%' /><br /> <a name='configmaps'></a> <br /> CA의 인증서는 kubectl의 configmaps 옵션을 통해서도 구할 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > C:\temp\knd> <span style='color: blue; font-weight: bold'>kubectl get configmaps</span> NAME DATA AGE kube-root-ca.crt 1 11h </pre> <br /> "kube-root-ca.crt"는 이름으로써만 의미가 있고 실제 물리적인 파일로 놓여 있지는 않습니다. 그리고 이에 대한 인증서는 다음의 명령어로 구할 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > C:\temp\knd> <span style='color: blue; font-weight: bold'>kubectl describe configmaps kube-root-ca.crt</span> Name: kube-root-ca.crt Namespace: default Labels: <none> Annotations: <none> Data ==== ca.crt: ---- <span style='color: blue; font-weight: bold'>-----BEGIN CERTIFICATE----- MIIC5zCCAc+gAwIBAgIBADANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwprdWJl ...[생략]... 0q4lLsZ0iQz6OtXkmDVvGvF9ICB/x2weBNPuGcWIu4Qs6zf+KO84IqozYqt6XcIc y2bAK1Ho8t45ohcBUFITZDCI+8pgvzB4TBcC -----END CERTIFICATE-----</span> Events: <none> </pre> <br /> 바로 저 출력에 포함된 "-----BEGIN CERTIFICATE-----", "-----END CERTIFICATE-----" 내용을 ca.crt 파일로 저장하고 확인해 보면 해당 인증서는 config 파일로부터 추출한 certificate-authority 인증서와 완전히 동일하다는 것을 알 수 있습니다.<br /> <br /> <hr style='width: 50%' /><br /> <br /> 위의 내용을 이해했으면, 이제 "<a target='tab' href='https://www.sysnet.pe.kr/2/0/12583#create_config'>kubectl 수행 시 다른 k8s 클러스터로 접속하는 방법</a>" 글에서 kubeconfig 파일을 kubectl 명령어를 이용해 직접 생성하는 것이 가능하다고 하면서 인증서 파일을 직접을 --client-certificate, --client-key, --certificate-authority 인자로 설정했던 방법을 실습할 수 있을 것입니다.<br /> <br /> <hr style='width: 50%' /><br /> <br /> 참고로, config 파일이 담고 있는 certificate-authority-data CA 인증서 값은 k8s 구성에 사용한 인증서 디렉터리의 ca.crt와 같은 인증서입니다. 따라서 --certificate-authority 옵션에 전달할 인증서 파일을 config으로부터 추출할 필요 없이 k8s의 인증서 디렉터리에서 직접 복사해와도 무방합니다.<br /> <br /> 여기서 유의할 점이 있다면, 지난 글에서도 설명했지만,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Docker Desktop for Windows에서 DockerDesktopVM 기반의 Kubernetes 구성 (2) - k8s 서비스 위치 ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/12576#cert'>https://www.sysnet.pe.kr/2/0/12576#cert</a> </pre> <br /> "Docker Desktop for Windows" 제품을 설치한 경우 k8s 관련 인증서들이 기본적으로 "%LOCALAPPDATA%\Docker\pki" 디렉터리에 있다고 설명했습니다. 그리고 k8s를 DockerDesktopVM에 구성한 경우에는 DockerDesktopVM의 /host/run/config/pki의 내용과 동일하므로 어느 인증서 파일을 사용해도 좋습니다.<br /> <br /> 하지만, <a target='tab' href='https://www.sysnet.pe.kr/2/0/12578#cert_path'>kind로 구성한 k8s의 경우에는 개별 클러스터를 호스팅하는 컨테이너 내의 /etc/kubernetes/pki</a>의 파일들은 "Docker Desktop for Windows"의 "%LOCALAPPDATA%\Docker\pki" 내용과 무관하므로 반드시 해당 클러스트를 호스팅하는 컨테이너 내의 파일들을 사용해야 합니다.<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
3036
(왼쪽의 숫자를 입력해야 합니다.)