Skip to Content
Blog개발환경 — 브라우저와 아이패드
  • #개발환경
  • #SSO
  • #Claude Code

개발환경 — 터미널 하나를 어디서든 같은 자리로 연다

앞 게시글에서는 홈랩의 멀티 클러스터 이야기를 다뤘었습니다. 이번엔 그 클러스터 위에서 제가 실제로 코드를 관리하는 이야기를 다루겠습니다.

TLDR: hub 클러스터에 code-server를 pod로 띄워 두고 노트북이든 데스크탑이든 브라우저로 들어가 그 터미널에 앉는 구조입니다. 같은 터미널에 아이패드로도 붙습니다. 이 글도 그 터미널 안에서 쓰고 있습니다.

클러스터 배치와 NAS, 그리고 Keycloak 한 곳으로 로그인을 모으는 원칙은 hub / edge 구조에 있습니다. 여기서는 그 둘 위에 사람의 작업 자리를 어떻게 마련했는지만 봅니다.

전체 그림

사용자 기기 — 브라우저hub 클러스터 — Kubernetes홈서버 중 한 노드HTTPSHTTPS인증 후attachclaudePVCHTTPS/rc 연결노트북웹 VS Code데스크탑웹 VS CodeiPad · 폰Remote Control관문Keycloak 인증Anthropic 릴레이인바운드 포트 Xcode-server podtmux 터미널main 세션Claude Code/rcStoragePVC 작업 디렉토리
전체 오버뷰 — 왼쪽이 사용자 기기, 오른쪽이 개발환경입니다. 노트북이든 데스크탑이든 브라우저로 웹 VS Code(code-server)에 들어가고, 편집기와 터미널을 한 화면에서 씁니다. 그 요청은 hub 클러스터의 관문에서 Keycloak 인증을 지나 code-server pod에 닿습니다. pod는 홈서버 여러 대 중 한 노드에 뜨는데 어느 노드든 상관없습니다 — 작업 디렉토리가 NAS에 있으니까요. 아이패드는 관문을 거치지 않고 Anthropic 릴레이로 그 pod 안의 Claude Code에 붙습니다. 두 길은 같은 tmux 세션에서 만납니다.

노트북이나 데스크탑에서 브라우저로 웹 VS Code에 접속하면 IDE와 터미널이 같이 있습니다. Keycloak 인증을 받은 뒤, code-server 를 띄워놓은 pod에 접속해서, tmux 위에서 Claude Code를 띄웁니다.

pod는 홈서버들 중 한 노드에 뜨는데 어느 노드든 상관없습니다. 작업 디렉토리가 NAS에 있으니까요. Claude 세션이 실행되는 주체는 홈서버지만, 아이패드는 Anthropic 릴레이를 통해 같은 Claude Code에 붙습니다. 어느 쪽으로 들어와도 같은 pod의 같은 tmux 세션에서 돌아가는거죠.

호스팅 구조 — 관문과 pod

hub 클러스터 — Kubernetes홈서버 중 한 노드HTTPS라우팅OIDC인증 후터미널PVC브라우저노트북 · 데스크탑istio gateway공인 도메인oauth2-proxy로그인 위임KeycloakSSOcode-server podauth=nonetmux main창 유지StoragePVC 작업 디렉토리
호스팅 구조 — 클러스터 안쪽을 편 그림입니다. 브라우저는 공인 도메인으로 istio gateway에 닿고, 앞에 선 oauth2-proxy가 Keycloak에 로그인을 위임합니다. 통과한 요청만 code-server pod에 들어갑니다. pod는 홈서버 여러 대 중 한 노드에 뜨고 홈 디렉토리는 NAS의 NFS PVC라 pod가 다른 노드로 옮겨 떠도 작업물은 그대로입니다. 테두리 색은 시리즈 공통 — 파랑 배포 · 보라 상태 · 주황 접근.

브라우저가 공인 도메인으로 들어와 istio gateway를 지나면 oauth2-proxy가 로그인 쿠키를 검사합니다. 쿠키 유무를 통해 Keycloak 혹은 code-server로 넘깁니다. pod의 홈 디렉토리는 별도로 사용중인 볼륨이 따로있어 노드장애에 대응이 가능한 구조입니다.

구성실제 값
도메인공인 도메인 하나 — istio gateway가 받아 pod로 넘김
인증oauth2-proxy (OIDC) → Keycloak SSO, 그룹 code-server-users
code-server--auth=none. 인증은 앞단이 끝냈으니 본체는 믿고 받음
홈 디렉토리스토리지 PVC — 노드에는 남길 것이 없음
배치클러스터 안 pod — 홈서버 중 한 노드, 상태는 NAS

인증을 code-server 밖으로 뺀 이유

code-server 자체에도 비밀번호 인증이 있어 처음엔 그걸 썼습니다.

지금은 code-server의 자체인증을 제거하고, 클러스터 안의 oauth2-proxy가 Keycloak에 로그인을 위임합니다.

  • 조금 더 설명을 붙여보자면, code-server 내에서 호스팅하는 일부 웹서비스들의 도메인을 public / private (적어도 인증/인가는 걸어둔) 도메인들을 구분하자니, 별도의 ouath 를 처리해주는 프록시를 두는게 이점이 더 많았습니다.

hub / edge 구조에서 ArgoCD 로그인을 Keycloak을 공유한것과 같은 방식입니다.

Keycloak이 죽으면 code-server에 못 들어갈 순 있겠지만, SPOF라고 볼 수는 없는게 이미 열린 세션은 쿠키가 살아 있는 동안 유지되고 터미널 안에서 돌던 것들은 tmux가 잘 살려둡니다. 로그인 만 잠깐 닫힌다고 작업이 날아가는 것은 다른 일입니다.

  • 물론 Keycloak 자체의 가용성은 별도로 관리가 필요합니다.

터미널은 tmux 위에서

code-server의 통합 터미널은 탭을 닫으면 셸이 죽습니다. 브라우저 탭이 날아가도, 노트북을 덮어도 문제가 발생될 여지가 있기때문에, 터미널이 열릴 때 tmux세션을 사용하도록 구성했습니다.

터미널을 열 때마다 그 세션에 묶인 grouped session을 하나 만들어 새 window를 띄웁니다. 터미널을 닫으면 그 window가 빈 bash였을 때만 정리하고 claude나 ssh처럼 뭔가 돌고 있으면 main에 남깁니다. 다음에 어느 브라우저에서 들어와도 prefix+w로 어제 돌려 둔 것을 그대로 잡을 수 있습니다.

아이패드에서 같은 Claude Code에 붙는다

사용자 기기연결 경로code-server pod로그인세션 쿠키attach실행HTTPS릴레이 · pod가 밖으로 연 연결브라우저웹 VS CodeKeycloakoauth2-proxy → OIDCcode-server통합 터미널tmux window/rcClaude Code같은 tmux 세션iPad · 폰Remote ControlAnthropic 릴레이인바운드 포트 X
두 개의 입구 — 위 줄은 브라우저가 Keycloak을 거쳐 code-server 터미널에 앉는 길, 아래 줄은 아이패드가 Anthropic 릴레이를 거쳐 그 터미널 안의 Claude Code에 붙는 길입니다. 두 길은 같은 pod의 같은 tmux 세션에서 만납니다. 릴레이 연결은 pod가 밖으로 여는 아웃바운드라 집 쪽에 포트를 하나도 더 열지 않습니다.

위 줄이 지금까지 설명한 Flow 입니다.

터미널에서 claude를 띄우고 /rc를 치면 그 세션이 Anthropic 릴레이에 등록됩니다. 아이패드의 Claude 앱에서 그 세션을 고르면 pod 안에서 돌고 있는 바로 그 Claude Code가 화면에 뜹니다. 별도의 code-server 로그인도, VPN도 없습니다. 연결은 pod가 밖으로 여는 아웃바운드 HTTPS라 집 쪽에 포트를 하나도 더 열지 않습니다.

브라우저로 들어간 터미널과 아이패드가 보는 Claude Code는 같은 pod의 같은 tmux window입니다. 아이패드에서 “이 파일 고쳐”라고 한 결과가 나중에 노트북 브라우저로 들어가면 그 변경이 그대로 있습니다. 기기가 바뀌어도 작업은 한 곳에서 돌아갑니다.

책상에서는 브라우저로 code-server를 열어 편집기와 터미널을 같이 씁니다. 자리를 뜰 땐 tmux가 붙들고 있으니 아무것도 정리하지 않습니다. 밖에서 혹은 침대에 누워서 아이패드로 같은 Claude Code 세션을 이어서 시킵니다.

돌아와 브라우저를 열면 아이패드에서 한 일이 그 터미널의 scrollback에 남아 있습니다.