Packer 빌드 디버깅
Packer 빌드 디버깅
packer build -on-error=ask를 사용하면 빌드를 다시 시작하기 전에 실패를 살펴보고 해결책을 시험해 볼 수 있어요.
출처: Packer 공식 문서
본문
Amazon Web Services AMI 같은 클라우드 프로바이더의 원격 빌드의 경우, packer build -debug를 사용하면 디버깅이 훨씬 수월해져요. 이 옵션은 병렬 처리를 비활성화하고 디버그 모드를 켜요.
디버그 모드는 빌더에게 디버깅 정보를 출력하라고 알려줘요. 디버그 모드의 정확한 동작은 빌더에게 맡겨져요. 일반적으로 빌더는 각 단계 사이에서 멈추고 계속하기 전에 키보드 입력을 기다려요. 이 덕분에 상태 등을 살펴볼 수 있어요.
디버그 모드에서는 원격 인스턴스가 생성되면 Packer가 현재 디렉터리에 임시 개인 SSH 키를 .pem 파일로 내보내요. 이 키로 ssh -i <key.pem>을 사용해 원격 빌드 인스턴스에 접속해서 디버깅을 위해 무슨 일이 벌어지고 있는지 볼 수 있어요. 이 키는 클라우드 기반 빌더에 대해서만 내보내져요. 임시 키는 Packer 실행이 끝나면 정리 과정에서 삭제돼요.
로컬 빌더의 경우, 빌드 전에 PACKER_LOG=1 환경 변수를 설정하면 시작된 SSH 세션이 제공되는 상세 정보에서 볼 수 있어요. 그리고 로컬 VM을 초기화할 때 연관된 kickstart나 preseed에 정의된 사용자 ID와 비밀번호로 로컬 머신에 접속할 수 있어요.
-on-error의 옵션 중 하나가 retry라는 점에 유의해야 해요. 해당 단계의 재시도에는 제한이 있어요:
- Packer가 빌드 중인 템플릿은 파일에서 다시 로드되지 않아요.
- 빌더가 지정한 리소스는 파일에서 다시 로드돼요.
빌더의 동작을 확인하려면 빌더의 세부 사항을 살펴봐야 해요.
Windows
Packer 0.8.1부터 기본 WinRM 커뮤니케이터가 원격 데스크톱 연결(Remote Desktop Connection)의 비밀번호를 인스턴스로 내보내요. 이는 인스턴스가 부팅되는 동안 몇 분간 멈춘 뒤에 발생해요. 비밀번호를 안전하게 전송하기 위해 .pem 키가 여전히 생성된다는 점에 유의하세요. Packer는 디버그 모드에서 비밀번호를 자동으로 해독해 줘요.
Packer 디버깅
어떤 것이 완전히 올바르게 동작하지 않거나 올바르게 동작하는 것처럼 보이지 않는 문제가 가끔 발생해요. 이런 경우 Packer가 실제로 무엇을 하고 있는지 더 자세히 보는 것이 도움이 될 때가 있어요.
Packer에는 상세 로그가 있어서, PACKER_LOG 환경 변수를 빈 문자열("")과 "0"을 제외한 어떤 값으로든 설정해서 켤 수 있어요. 예: PACKER_LOG=1 packer build <config.json>. 이렇게 하면 상세 로그가 stderr에 나타나요. 로그에는 Packer의 로그 메시지와 사용 중인 플러그인의 로그 메시지가 포함돼요. 플러그인의 로그 메시지는 해당 애플리케이션 이름이 접두사로 붙어요.
Packer는 고도로 병렬화되어 있기 때문에, 특히 플러그인과 관련해서 로그 메시지가 순서가 뒤섞여 나타날 때가 있어요. 이 경우 순서를 판단하려면 로그 메시지의 타임스탬프에 주의를 기울이는 것이 중요해요.
로그를 단순히 켜는 것 외에도 PACKER_LOG_PATH를 설정하면 로깅이 활성화될 때 로그가 항상 특정 파일로 가도록 강제할 수 있어요. PACKER_LOG_PATH를 설정해도, 어떤 로깅이든 활성화되려면 PACKER_LOG를 설정해야 한다는 점에 유의하세요.
플러그인 디버깅 (Debugging Plugins)
각 packer 플러그인은 별도의 프로세스로 실행되고 소켓을 통해 RPC로 통신해요. 그래서 디버거를 사용하는 것은 동작하지 않아요(적어도 복잡해져요).
하지만 Packer 코드 대부분은 정말 단순하고 PACKER_LOG를 켜면 쉽게 따라갈 수 있어요. 그것으로 충분하지 않다면, 문제를 좁혀낸 뒤 약간의 디버그 출력을 추가하는 것으로 충분한 경우가 보통이에요.
Powershell/Windows에서 Packer 디버깅
Windows에서는 PowerShell 환경 변수를 사용해 상세 로그 환경 변수 PACKER_LOG나 로그 변수 PACKER_LOG_PATH를 설정할 수 있어요. 예를 들어:
$env:PACKER_LOG=1
$env:PACKER_LOG_PATH="packerlog.txt"
Packer에서 버그를 발견하면 gist 같은 서비스를 사용해 상세 로그를 포함해 주세요.
Ubuntu 패키지 설치 문제 (Issues Installing Ubuntu Packages)
Ubuntu AMI를 사용하고 빌드할 때, Ubuntu의 Main 저장소에서 설치되어야 하는 일반적인 패키지가 프로비저너 단계에서 발견되지 않는 문제가 발생할 수 있어요:
amazon-ebs: No candidate version found for build-essential
amazon-ebs: No candidate version found for build-essential
당연히 이 문제는 적절한 패키지가 올바르게 프로비저닝되지 못해 빌드가 성공적으로 끝나지 못하게 할 수 있어요. 이 문제는 packer가 프로비저닝 단계를 시작할 때까지 cloud-init이 소스 AMI에서 완전히 실행되지 않았을 때 발생해요.
Packer 템플릿에 다음 프로비저너를 추가하면, packer가 소스 AMI 프로비저닝을 시작하기 전에 cloud-init 프로세스가 완전히 끝나도록 해 줘요.
{
"type": "shell",
"inline": [
"cloud-init status --wait"
]
}
많은 Builder/Provisioner/Post-Processor를 사용할 때의 문제
Packer는 각 빌더, 프로비저너, 포스트-프로세서, 플러그인에 별도의 프로세스를 사용해요. 경우에 따라 이런 것들이 너무 많으면 파일 디스크립터(file descriptor)가 부족해질 수 있어요. 그러면 다음과 같은 오류가 발생할 수 있어요:
error initializing provisioner 'powershell': fork/exec /files/go/bin/packer:
too many open files
Unix 시스템에서는 ulimit -Sn으로 파일 디스크립터 한도를 확인할 수 있어요. 이 한도를 높이는 방법은 OS 공급업체에 확인해야 해요.
긴 임시 디렉터리를 사용할 때의 문제
Packer는 내부적으로 Unix 소켓을 사용하는데, 이 소켓은 임시 파일의 기본 디렉터리 안에 생성돼요. 일부 운영 체제는 소켓 이름의 길이에 제한을 두는데, 보통 80~110자 사이예요. (Docker뿐 아니라 어떤 빌더에서든) 다음과 같은 오류가 발생하면:
Failed to initialize build 'docker': error initializing builder 'docker': plugin exited before we could connect
임시 디렉터리를 더 짧은 것으로 설정해 보세요. 이는 TMPDIR 환경 변수로 할 수 있어요.