Bastion 서버 경유 Kubernetes 클러스터 kubectl 접근 설정
게시:
내부망(Private Network)에 위치하여 직접 접근할 수 없는 Kubernetes 클러스터 API 서버를 Bastion 서버를 경유하여 로컬 kubectl로 접근하고 제어하는 방법에 대해 설명합니다.
첫 번째 방법: SOCKS5 프록시 터널 (권장)
터널 하나로 여러 클러스터를 유연하게 관리할 수 있는 가장 권장되는 방식입니다.
Step 1: SOCKS5 SSH 터널 생성 (포그라운드)
로컬 머신에서 SOCKS5 프록시(터널 입구)를 엽니다. 이 터미널이 실행 중일 때만 프록시가 동작하며 Ctrl+C로 명확하게 종료할 수 있습니다.
-D <local_port>: 지정된 로컬 포트(예:1080)를 SOCKS 프록시로 지정합니다.-N: 원격 명령을 실행하지 않고 터널링만 수행합니다.
# <local_port>는 1080 등으로 지정
ssh -D 1080 -N <bastion_user>@<bastion_ip>
백그라운드 실행 방법 (
-f옵션)
터널을 백그라운드로 실행하려면-f옵션을 추가한다. (ssh -D 1080 -Nf ...)
이 경우, 터널을 종료하려면ps aux | grep ssh등으로 PID를 찾아 kill 해야 합니다.
Step 2: Kubeconfig 수정 (proxy-url 추가)
kubectl이 이 SOCKS5 프록시를 사용하도록 ~/.kube/config 파일의 cluster 섹션에 proxy-url을 추가합니다.
- 중요:
localhost대신127.0.0.1(IPv4) 주소를 사용합니다. (IPv6(::1) 해석으로 인한 통신 오류 방지)
clusters:
- cluster:
server: "https://192.168.2.185:6443" # 내부 API 서버의 주소 (변경하지 않음)
certificate-authority-data: ...
proxy-url: "socks5://127.0.0.1:1080" # 1단계에서 생성한 SOCKS5 프록시 터널 지정
name: "remote-cluster1"
...
3단계: 연결 테스트
1단계의 SSH 터널이 실행 중인 상태에서 새로운 터미널 창을 열어 kubectl 명령을 실행합니다.
kubectl config use-context some-k8s-context
kubectl get nodes
두 번째 방법: 1:1 로컬 포트 포워딩 (ssh -L)
SOCKS5 프로토콜이 차단된 환경 등에서 사용할 수 있는 대안이다. 이 방식은 하나의 클러스터 API 서버와 로컬 포트를 1:1로 직접 매핑합니다.
Step 1: 1:1 포트 포워딩 실행 (포그라운드)
-L <local_port>:<k8s_api_ip>:<k8s_api_port>: 로컬 포트를 Bastion을 거쳐 지정된 내부 IP/포트로 1:1 연결합니다.
# 로컬 6443 포트를 192.168.2.185:6443으로 1:1 매핑
# (만약 로컬 6443 포트가 이미 사용 중이면 6444 등으로 변경)
ssh -L 6443:192.168.2.185:6443 -N <bastion_user>@<bastion_ip>
2단계: Kubeconfig 수정 (server 변경)
proxy-url을 사용하는 대신 server 주소 자체를 127.0.0.1과 매핑된 로컬 포트로 변경해야 합니다.
clusters:
- cluster:
certificate-authority-data: ...
server: "https://127.0.0.1:6443" # 'server' 주소를 1:1 매핑된 로컬 주소로 변경합니다.
name: "remote-cluster1"
# proxy-url 항목은 사용하지 않습니다.
SOCKS5 (-D) vs 1:1 포워딩 (-L) 비교
| 특징 | SOCKS5 프록시 (ssh -D) | 1:1 포트 포워딩 (ssh -L) |
|---|---|---|
| 터널 방식 | 범용 터널 | 1:1 지정 터널 |
| 터널 1개당 | **여러 클러스터 동시 접근 가능 | 단 하나의 클러스터만 접근 가능 |
| Kubeconfig | server (내부 IP)는 유지,<br>**proxy-url 추가 |
**server (127.0.0.1)를 수정,<br>proxy-url 미사용 |
| 단점 | SOCKS 프로토콜 지원 필요 | 접근할 클러스터마다 별도 터널 실행 (로컬 포트 충돌 주의) |
트러블슈팅
kubectl 실행 시 TLS handshake timeout 등의 에러가 발생하면 다음을 점검합니다.
- (로컬) 1단계의
ssh터널이 포그라운드에서 정상 실행 중인지 확인합니다. - (Bastion) Bastion 서버에 접속하여 내부 API 서버(
192.168.2.185)로 TCP 연결이 가능한지 확인합니다.# Bastion 서버에서 실행 nc -zv 192.168.2.185 6443succeeded!가 출력되어야 합니다. 실패(Timeout) 시 Bastion의 방화벽(보안 그룹)을 확인합니다.
- (SOCKS5 방식)
kubeconfig의proxy-url이socks5://127.0.0.1:1080로 정확히 설정되었는지 확인합니다. -
(SOCKS5 방식) 로컬 환경 변수
NO_PROXY또는no_proxy에 API 서버의 IP 대역이 포함되어 있는지 확인합니다. 포함 시kubectl이proxy-url을 무시하므로, 해당 변수를unset합니다.echo $NO_PROXY - (1:1 포워딩 방식)
kubeconfig의server가https://127.0.0.1:<local_port>로 정확히 설정되었는지 확인합니다.
댓글남기기