SOCKS5 프록시로 쿠버네티스 API에 접근하기
SOCKS5 프록시로 쿠버네티스 API에 접근하기 (Use a SOCKS5 Proxy to Access the Kubernetes API)
이 페이지는 SOCKS5 프록시를 사용해 원격 쿠버네티스 클러스터의 API에 접근하는 방법을 보여 줘요. 접근하려는 클러스터가 공개 인터넷에 API를 직접 노출하지 않을 때 유용해요.
출처: 문서
본문
시작하기 전에
쿠버네티스 클러스터가 필요하고, kubectl 명령줄 도구가 클러스터와 통신하도록 설정돼 있어야 해요. 이 튜토리얼은 제어 플레인 호스트 역할을 하지 않는 노드가 최소 두 개 있는 클러스터에서 실행하는 것을 권장해요. 아직 클러스터가 없다면 minikube를 사용하거나 다음 쿠버네티스 플레이그라운드 중 하나를 사용해 만들 수 있어요.
- iximiuz Labs
- Killercoda
- KodeKloud
쿠버네티스 서버는 버전 v1.24 이상이어야 해요. 버전을 확인하려면 kubectl version을 입력하세요.
SSH 클라이언트 소프트웨어(ssh 도구)와 원격 서버에서 실행 중인 SSH 서비스가 필요해요. 원격 서버의 SSH 서비스에 로그인할 수 있어야 해요.
작업 맥락 (Task context)
참고:
그림 1은 이 작업에서 달성하려는 것을 나타내요.
- 쿠버네티스 API와 통신할 요청을 만들 클라이언트 컴퓨터가 있어요. 앞으로의 단계에서는 이를 'local'이라고 해요.
- 쿠버네티스 서버/API는 원격 서버에 호스팅돼요.
- SSH 클라이언트와 서버 소프트웨어를 사용해 local과 원격 서버 사이에 보안 SOCKS5 터널을 만들 거예요. 클라이언트와 쿠버네티스 API 사이의 HTTPS 트래픽은, 그 자체가 SSH 위에 터널링된 SOCKS5 터널을 통해 흐를 거예요.
그림 1. SOCKS5 튜토리얼 구성 요소
graph LR;
subgraph local[Local client machine]
client([client])-. local traffic .-> local_ssh[Local SSH SOCKS5 proxy];
end
local_ssh[SSH SOCKS5 proxy]-- SSH Tunnel -->sshd
subgraph remote[Remote server]
sshd[SSH server]-- local traffic -->service1;
end
client([client])-. proxied HTTPs traffic going through the proxy .->service1[Kubernetes API];
classDef plain fill:#ddd,stroke:#fff,stroke-width:4px,color:#000;
classDef k8s fill:#326ce5,stroke:#fff,stroke-width:4px,color:#fff;
classDef cluster fill:#fff,stroke:#bbb,stroke-width:2px,color:#326ce5;
class ingress,service1,service2,pod1,pod2,pod3,pod4 k8s;
class client plain;
class cluster cluster;
ssh로 SOCKS5 프록시 만들기
다음 명령은 클라이언트 머신과 원격 SOCKS 서버 사이에 SOCKS5 프록시를 시작해요.
# 이 명령을 실행하면 SSH 터널이 포그라운드에서 계속 실행됨
ssh -D 1080 -q -N [email protected]
SOCKS5 프록시는 다음 구성에 따라 클러스터의 API 서버에 연결하게 해줘요.
-D 1080: 로컬 포트 1080에 SOCKS 프록시를 염.-q: quiet 모드. 대부분의 경고와 진단 메시지를 억제함.-N: 원격 명령을 실행하지 않음. 포트 포워딩만 하는 데 유용함.[email protected]: 그 뒤에서 쿠버네티스 클러스터가 실행되는 원격 SSH 서버(예: 베스천 호스트).
클라이언트 구성 (Client configuration)
프록시를 통해 쿠버네티스 API 서버에 접근하려면 kubectl이 앞서 만든 SOCKS 프록시를 통해 쿼리를 보내도록 지시해야 해요. 적절한 환경 변수를 설정하거나, kubeconfig 파일의 proxy-url 속성을 통해 이 작업을 해요. 환경 변수 사용:
export HTTPS_PROXY=socks5://localhost:1080
특정 kubectl 컨텍스트에서 항상 이 설정을 사용하려면 ~/.kube/config 파일의 관련 cluster 항목에 proxy-url 속성을 지정하세요. 예를 들어:
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LRMEMMW2 # 읽기 쉽도록 줄임
server: https://<API_SERVER_IP_ADDRESS>:6443 # "Kubernetes API" 서버, 즉 kubernetes-remote-server.example의 IP 주소
proxy-url: socks5://localhost:1080 # 위 다이어그램의 "SSH SOCKS5 proxy"
name: default
contexts:
- context:
cluster: default
user: default
name: default
current-context: default
kind: Config
preferences: {}
users:
- name: default
user:
client-certificate-data: LS0tLS1CR== # 읽기 쉽도록 줄임
client-key-data: LS0tLS1CRUdJT= # 읽기 쉽도록 줄임
앞서 언급한 ssh 명령으로 터널을 만든 뒤 환경 변수나 proxy-url 속성을 정의했다면, 그 프록시를 통해 클러스터와 상호작용할 수 있어요. 예를 들어:
kubectl get pods
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-85cb69466-klwq8 1/1 Running 0 5m46s
참고:
- kubectl 1.24 이전에는
kubectl exec를 제외한 대부분의 kubectl 명령이 socks 프록시를 사용할 때 동작했어요. - kubectl은
HTTPS_PROXY와https_proxy환경 변수를 모두 지원해요. 이들은curl같은 SOCKS를 지원하는 다른 프로그램도 사용해요. 따라서 일부 경우에는 명령줄에서 환경 변수를 정의하는 것이 더 나을 수 있어요:HTTPS_PROXY=socks5://localhost:1080 kubectl get pods proxy-url을 사용하면 프록시는 관련 kubectl 컨텍스트에서만 사용되는 반면, 환경 변수는 모든 컨텍스트에 영향을 줘요.socks5대신socks5h프로토콜 이름을 사용하면 k8s API 서버 호스트 이름을 DNS 누출로부터 더 보호할 수 있어요. 이 경우 kubectl은 kubectl이 실행되는 시스템에서 k8s API 서버 도메인 이름을 해석하는 대신 프록시 서버(예: ssh 베스천)에 해석을 요청해요. 또한socks5h에서는https://localhost:6443/api같은 k8s API 서버 URL이 로컬 클라이언트 컴퓨터를 가리키지 않아요. 대신 프록시 서버(예: ssh 베스천)가 아는 localhost를 가리켜요.
정리하기 (Clean up)
실행 중인 터미널에서 CTRL+C를 눌러 ssh 포트 포워딩 프로세스를 중지하세요.
터미널에서 unset https_proxy를 입력해 http 트래픽이 프록시를 통해 전달되는 것을 중지하세요.