Kubernetes는 macOS 호스트를 공식 Worker Node로 등록해 일반 Pod를 실행할 수 없으므로, Xcode 작업은 독립된 Mac 풀로 보내야 합니다. 이번 주에는 비생산용 Xcode 작업 하나를 골라 작업 요청, 상태 회신, 서명 격리, 노드 회수까지 검증하십시오. 안정적으로 확인된 뒤에만 고정 Mac과 탄력형 원격 Mac의 규모를 정해야 합니다.

이 글은 이미 Kubernetes 플랫폼을 운영하면서 Apple 플랫폼 빌드까지 통합하려는 인프라 책임자를 위한 내용입니다. 여러 iOS 팀의 공유 빌드 풀과 피크 용량을 계획하는 개발 생산성 책임자, 고정 구매와 렌탈을 비교하는 기술 및 구매 담당자에게도 적합합니다.

01

먼저 확정할 경계: Kubernetes Mac 빌드 머신은 일반 노드가 아닙니다

kubectl을 Mac에 설치할 수 있다는 사실만으로 Mac이 지원되는 Kubernetes Worker가 되지는 않습니다. Kubernetes 공식 문서는 Node를 클러스터의 작업 실행 단위로 설명하며, Node 구성 요소와 운영체제 지원은 Kubernetes Node 관리 문서와 Windows 노드 지원 문서에서 확인할 수 있습니다. macOS를 공식 네이티브 Worker Node로 제시하지는 않습니다.

반면 Apple은 xcodebuild와 simctl을 Xcode가 설치되고 선택된 macOS 환경에서 사용하도록 안내합니다. Apple의 명령줄 도구 설치 안내와 Xcode 자동화 문서는 이 실행 조건을 분명히 구분합니다.

따라서 다음 세 가지를 섞으면 안 됩니다.

  • 제어 통합: Kubernetes가 작업 요청과 원하는 상태를 관리합니다.
  • 작업 예약 통합: Controller, Operator 또는 CI Runner가 외부 Mac에 작업을 배정합니다.
  • 실행 환경 통합: 실제 xcodebuild, 시뮬레이터, Apple SDK는 Mac에서 실행됩니다.

Kubernetes는 대기열과 제어층이 될 수 있습니다. 그러나 Mac을 Linux Pod처럼 취급하는 실행층은 될 수 없습니다.

주의: macOS에서 실행되는 도구와 macOS를 Worker Node로 등록하는 일은 별개입니다. 지원 경계를 확인하지 않은 채 kubelet 구성부터 시도하면 운영 책임과 장애 원인을 분리하기 어려워집니다.

02

첫 번째 경로: Linux Pod에서 끝낼 작업을 먼저 닫습니다

iOS CI 전체를 Kubernetes에 넣으려는 설계는 작업을 성격별로 나눠야 합니다. 코드 검사, 공통 스크립트, 백엔드 테스트, 산출물 전처리, Apple 도구에 의존하지 않는 공유 모듈 테스트는 Linux Pod에서 먼저 끝낼 수 있습니다.

이 단계의 출력은 파일과 상태를 명확히 가져야 합니다.

  • 입력: 커밋 식별자, 의존성 잠금 파일, 빌드 설정
  • 출력: 검사 보고서, 테스트 결과, 전처리된 산출물
  • 실패 상태: 로그 위치, 재시도 가능 여부, 원인 분류
  • 전달 조건: Mac 단계가 읽을 수 있는 저장 위치와 접근 권한

이 계약이 없으면 Mac Runner는 저장소를 다시 내려받고 같은 검사를 반복하게 됩니다. 그 결과 Mac 풀의 대기열이 늘고, 실패 지점도 흐려집니다.

Kubernetes와 Mac Runner의 상태 회신 방식

외부 Mac을 단순히 SSH로 깨우고 스크립트를 실행하는 방식은 빠른 시험에는 쓸 수 있습니다. 운영 환경에서는 작업 상태, 로그, 산출물 주소, 노드 건강 상태를 제어층으로 되돌려야 합니다.

연결 방식은 다음처럼 선택합니다.

  • CI 플랫폼의 기본 Runner: 이미 사용하는 CI 플랫폼의 작업 모델과 권한 체계를 유지하고 싶을 때 적합합니다.
  • 대기열 소비자: Mac Runner가 작업 큐를 읽고 완료 상태를 회신합니다. 작은 팀의 PoC에 단순합니다.
  • Custom Resource와 Controller: Mac 작업을 Kubernetes 객체처럼 표현하고 상태를 조정해야 할 때 적합합니다. Kubernetes의 Custom Resource 확장 방식과 Operator 개념을 참고할 수 있습니다.

세 방식 모두 Mac이 Kubernetes Node라는 뜻은 아닙니다. Controller가 외부 실행 자원을 관리하는 구조입니다.

03

두 번째 경로: Xcode와 시뮬레이터 작업은 외부 Mac 풀로 보냅니다

Kubernetes가 Xcode 작업 요청을 생성할 수는 있습니다. 실제 빌드와 테스트는 Xcode가 설치된 Mac에서 실행해야 합니다. 작업 흐름은 다음과 같이 분리하는 편이 추적하기 쉽습니다.

커밋 → Linux 검사 → 작업 요청 → Mac Runner 배정 → xcodebuild 실행 → 로그와 산출물 회신 → 다음 단계

외부 Mac 호출에는 최소한 다음 정보가 포함되어야 합니다.

  • 필요한 Xcode 선택값과 SDK 조건
  • 저장소 또는 입력 산출물의 주소
  • 작업 식별자와 재시도 횟수
  • 로그와 결과물의 저장 위치
  • 성공, 실패, 취소, 시간 초과 상태
  • 작업 종료 뒤 워크스페이스 정리 결과

xcodebuild의 자동화와 테스트 실행 방식은 Apple의 자동화 기술 문서에서 확인할 수 있습니다. 특정 버전이나 빌드 시간은 환경과 프로젝트에 따라 달라지므로, 문서에 없는 용량과 성능을 일반화해서는 안 됩니다.

04

세 번째 경로: 서명과 배포는 일반 빌드 풀에서 분리합니다

일반 빌드가 공유 가능하다고 해서 배포 서명까지 공유해야 하는 것은 아닙니다. Developer ID, 코드 서명 개인 키, Keychain, 배포 API 자격 증명은 별도의 신뢰 경계에 두는 편이 안전합니다. Apple의 배포 서명 코드 안내도 서명 자산을 별도 관리해야 하는 작업임을 보여줍니다.

권장 흐름은 다음과 같습니다.

  • Kubernetes에서 코드 검사와 사전 검증을 수행합니다.
  • 일반 Mac 풀에서 서명 전 빌드와 테스트를 수행합니다.
  • 승인된 산출물만 신뢰 가능한 Mac으로 전달합니다.
  • 신뢰 가능한 Mac에서 서명과 배포를 수행합니다.
  • 작업 종료 뒤 Keychain 접근 상태, 임시 파일, 토큰과 로그를 확인합니다.

서명 노드에는 작업 승인 주체와 산출물 해시를 남겨야 합니다. 실패하면 어떤 자격 증명이 사용됐는지, 재시도 전에 폐기하거나 교체해야 하는지 기록되어야 합니다.

경험상 가장 위험한 설계는 일반 Runner에 서명 키를 함께 넣고, 실패한 작업의 워크스페이스를 그대로 재사용하는 방식입니다. 빌드 성공률보다 자격 증명 흐름과 회수 증적을 먼저 검증해야 합니다.

05

네 번째 경로: 고정 풀과 탄력형 원격 Mac을 조건으로 나눕니다

고정 Mac 풀은 상시 빌드와 예측 가능한 대기열에 맞습니다. 버전 출시, 대규모 회귀 테스트, 신규 파이프라인 이전, 장애 대체처럼 일시적으로 작업이 늘어나는 경우에는 탄력형 원격 Mac을 별도로 붙이는 편이 낫습니다.

Mac 수를 개발자 수로 계산하면 안 됩니다. 다음 입력을 기반으로 산정해야 합니다.

  • 동시에 대기하는 작업 수
  • Mac 한 대가 처리할 수 있는 유효 작업량
  • 환경 전달과 Runner 등록에 필요한 시간
  • 재시도와 장애 대체를 위한 여유 자원
  • 서명 노드의 별도 수요
  • 출시 시간대의 집중 정도
선택지 Kubernetes의 역할 Mac 실행 위치 적합한 상황 운영상 약점
Kubernetes만 사용 제어와 실행을 모두 담당 Apple 빌드가 없음 iOS 작업이 없는 팀 Xcode 작업을 처리할 수 없음
Kubernetes와 고정 Mac 풀 대기열과 상태 관리 상시 등록된 Mac 부하가 안정적인 팀 유휴 자원과 장애 대체 비용이 남음
고정 풀과 탄력형 원격 Mac 기본 용량과 피크 조정 필요할 때 연결되는 Mac 여러 프로젝트, 출시 피크, 재해 대비 등록과 회수 검증이 필요함
일반 풀과 신뢰 Mac 분리 승인과 흐름 제어 서명 전용 Mac 배포 자격 증명 보호 운영 절차와 감사 항목이 늘어남
06

다섯 번째 경로: 외부 Mac을 생산 큐에 넣기 전 검증합니다

다음 순서로 비생산 작업을 먼저 실행하십시오.

첫째, Mac 환경의 기준을 고정합니다. macOS 설정, Xcode 선택값, 의존성 설치 방식, Runner 버전을 문서화합니다.

둘째, 작업 요청을 만듭니다. Kubernetes 객체나 CI 큐에 저장소, 커밋, 필요한 도구, 결과물 위치를 기록합니다.

셋째, Mac Runner가 작업을 받는지 확인합니다. 단순 접속 성공이 아니라 작업 식별자가 Mac 로그와 제어층 양쪽에 남아야 합니다.

넷째, 실제 xcodebuild와 시뮬레이터 테스트를 실행합니다. 성공 로그만 보지 말고 실패 코드와 중단 신호도 확인합니다.

다섯째, 결과를 회신합니다. 상태, 로그 주소, 산출물 주소, 실패 원인을 제어층에서 조회할 수 있어야 합니다.

여섯째, Mac을 재시작한 뒤 복구를 검증합니다. 진행 중인 작업을 재시도할지 폐기할지 정책이 있어야 합니다.

일곱째, 노드를 회수합니다. Runner 등록 해제, 임시 파일 삭제, 토큰 제거, 작업 디렉터리 초기화를 확인한 뒤에만 다시 큐에 넣습니다.

조건별 자원 결정

  • Apple 빌드가 없으면 Kubernetes만 선택합니다.
  • Apple 빌드가 있고 대기열이 안정적이면 Kubernetes와 고정 Mac 풀을 선택합니다.
  • 여러 프로젝트가 출시 시점에 몰리거나 장애 대체가 필요하면 고정 풀과 탄력형 원격 Mac을 함께 선택합니다.
  • 서명 키를 일반 작업과 공유해야만 운영되는 구조라면 생산 투입을 미룹니다.
  • 상태 회신이나 노드 회수가 확인되지 않으면 외부 Mac 수를 늘리지 말고 PoC로 되돌립니다.

Kubernetes Mac 빌드 머신을 도입할 때 필요한 것은 Mac을 억지로 Node로 만드는 기술이 아닙니다. 제어층, 작업층, 실행층의 경계를 지키는 운영 계약입니다.

현재 방식이 개발자별 실물 Mac 구매라면 장비 유휴 시간, 교체와 유지 관리, 원격 팀의 환경 차이가 남습니다. 반대로 검증 없이 일반 클라우드 작업만 늘리면 Xcode와 Apple SDK를 실행할 실제 환경이 부족하고, 서명 노드의 격리도 어렵습니다. 단기 피크나 PoC라면 VpsMesh의 원격 Mac 접근 방식으로 먼저 작업 라우팅과 회수 절차를 시험하고, 필요하면 Mac mini 렌탈 구성을 고정 풀 후보로 비교하는 편이 현실적입니다. 데이터 보호 항목은 원격 Mac 개인정보 보호 안내와 함께 검토하십시오.

장기적으로 일정한 고강도 부하와 물리 장비 접근이 필요하다면 직접 구매가 더 맞을 수 있습니다. 그렇지 않고 출시 피크, 마이그레이션, 장애 대체처럼 기간이 정해진 수요라면 원격 Mac 렌탈이 장비를 미리 쌓아 두는 방식보다 운영 선택지가 넓습니다. 먼저 비생산 Xcode 작업 하나로 검증하고, 그 결과를 근거로 고정 Mac과 탄력형 Mac의 비율을 결정하십시오.