이 글은 기계 번역의 미러 문서이며, 원본 기사로 바로 이동하려면 여기를 클릭해 주세요.

보기: 1081|회답: 1

재현 가능한 빌드에 대한 간략한 소개

[링크 복사]
2025-4-30 10:09:27에 게시됨 | | | |
반복 가능한 빌드란 무엇인가요?

결정론적 빌드와 재현 가능한 빌드는 약간 다르지만, 이 글에서 같은 의미로 이해할 수 있습니다.

재현 가능한 빌드는 다음을 의미합니다.동일한 입력과 빌드 환경에서 빌드 프로세스를 여러 번 실행하면 동일한 결과를 얻을 수 있습니다。 이 기술은 소프트웨어 개발, 배포 및 보안 검증에 중요합니다.

빌드가 언제 어디서 실행되든 정확히 동일한 출력을 제공한다면 재현 가능하다고 할 수 있습니다. 어떤 컴퓨터에서든, 시간대가 어떻든, 네트워크를 통해 어떤 외부 서비스에 접속하든, 재현 가능한 빌드는 동일한 바이트 단위 출력을 냅니다. 이 방법은 개발(재현 가능한 빌드는 여러 개발자 기기 간에 쉽게 공유할 수 있기 때문)과 프로덕션 모두에 매우 좋습니다(재현 가능한 빌드의 결과가 조작되지 않았는지 쉽게 확인할 수 있으니 – 자신의 컴퓨터에서 빌드를 다시 실행하고 결과가 일관되는지 확인하면 됩니다!). 매우 유용합니다.



반복 가능한 빌드의 세 가지 기둥

기둥 1: 반복 가능한 빌드

빌드 반복성은 빌드 머신 자체에 어떤 일이 일어나는지를 의미합니다. 빌드 입력이 사용 가능하고 주변 세계에 아무런 변화가 없다면, 빌드를 반복해도 같은 출력이 나오나요?

결정론적 설치 계획

반복 가능한 빌드에서 가장 먼저 요구되는 가장 단순하며 명확한 요구사항은 결정론적 의존성 설치 계획입니다.

대부분의 언어에서는 잠긴 파일을 확인하는 것만큼 간단합니다. 현대 빌드 도구는 프로젝트가 직접 의존성 요구사항을 제약 조건으로 표현하고, 그 제약 조건을 해결해 설치 계획(의존성 이름과 설치 버전 쌍 목록)을 생성할 수 있도록 허용하는 경우가 많습니다. 이들 도구 중 다수는 직렬화된 설치 계획에 대한 잠금 파일도 생성합니다. 개발자는 이러한 락 파일을 버전 관리에 제출하여 향후 빌드에서 동일한 의존성 이름과 버전을 사용할 수 있도록 할 수 있습니다.

의존성 빌드 자체(버전 선택뿐만 아니라)에서도 결정론적 설정이 필요하다는 점을 참고하세요. 결정론적 설치 계획만으로는 이를 달성할 수 없습니다!

결정론적 구성

무엇을 만들어야 할지 알게 되면, 우리 빌드 자체(우리 코드와 의존성 코드 빌드 포함)는 실제로 결정론적이어야 합니다.

컴파일 단계가 없는 프로젝트라면 이 문제가 아닐 수도 있습니다! 예를 들어, 모든 의존성을 가진 노드 프로젝트는 순수 자바스크립트이며, 효과적인 결정론을 달성하기 위해 추가 작업이 필요하지 않습니다.

컴파일 또는 변환(소스 간 컴파일) 단계를 포함하는 프로젝트의 경우, 결정론을 보장하는 것이 재현 가능한 빌드를 구축하는 데 가장 어려운 부분입니다. 컴파일 과정은 다음과 같은 여러 방식으로 암묵적으로 비결정성을 도입할 수 있습니다:

  • 튜링 완전 프로그램 빌드 스크립트는 컴파일된 출력을 자유롭게 변경할 수 있습니다.
  • 실행 파일 시스템 조회나 네트워크 호출에 의존하는 설치 후 스크립트.
  • 서로 다른 헤더를 가진 시스템 바인딩이 서로 다른 출력을 낼 수 있는 시스템 설치 패키지에 C 바인딩을 적용합니다.
  • 버전 관리 범위를 벗어나 읽을 수 있는 파일을 만드는 단계들.
  • 시스템 타임을 이용해 타임스탬프를 생성하는 단계를 구축하세요.
  • 네트워크 다운로드 설치 계획에 명시되지 않은 의존성을 구축하는 단계(예: C-바운드 캐시된 이진 빌드에 대해 GitHub에서 NPM 의존성을 다운로드하는 것).
  • 현재 설정된 환경 변수를 기반으로 동작을 변경하되, 환경 변수 구성이 포함된 빌드는 제출하지 마세요.


이러한 동작들이 올바르게 설정되었을 때 반드시 불확실성을 초래하는 것은 아니지만, 빌드 프로세스를 올바르게 구성하는 것은 복잡하고 어려울 수 있습니다. 예를 들어, 크롬 빌드의 불확실성에 관한 이 블로그 글을 읽어보실 수 있습니다. 이러한 문제들 중 많은 부분은 지역 건축 환경을 통제함으로써 완화할 수 있으며, 이는 다음 섹션에서 다룰 것입니다.

기둥 2: 불변의 환경

반복 가능한 빌드가 있더라도 빌드 입력이 변하지 않도록 해야 합니다. 종종 이는 우리가 주변 환경의 불변의 스냅샷 위에 구축하고 싶다는 뜻입니다.

변하지 않는 국소 환경

앞서 논의했듯이, 빌드 불확실성의 흔한 원인은 빌드 도구가 포착하지 않는 '의존성'에 의존하는 것입니다. C-바운드 시스템 라이브러리가 가장 흔한 예이지만, 환경 변수 설정이나 버전 관리 범위를 벗어난 파일 등 다른 로컬 환경 요인도 빌드에 영향을 줄 수 있습니다.

이 문제를 완화하는 쉬운 방법은 빌드를 알려진 변경 불가능한 컨테이너에서 실행하는 것입니다. 예를 들어, Docker와 같은 컨테이너 런타임은 모든 사용자가 동일한 시스템 의존성, 동일한 환경 변수, 동일한 파일 시스템에서 실행되도록 보장합니다. 또한, 컨테이너 내용물이 알려진 좋은 빌드 컨테이너와 일치하는지 쉽게 검증할 수 있으며, 필요하다면 컨테이너를 완전히 제거해 다시 만들 수 있습니다.

알려진 컨테이너 또는 알려진 컨테이너 이미지에 대해 매우 명확히 말씀드리겠습니다. 단순히 Dockerfile 제출만으로는 충분하지 않습니다! 왜? Dockerfile 자체가 Docker 이미지의 완전한 재현 가능한 빌드 프로세스를 설명하지 않기 때문입니다. 왜냐하면 Docker는 불변경 글로벌 환경에서 실행되지 않기 때문입니다.

불변의 글로벌 환경

빌드 시스템은 종종 버전 해석 및 의존성 다운로드와 같은 작업을 수행하기 위해 외부 서비스와 상호작용합니다. 하지만 외부 서비스는 자주 바뀝니다.

오늘 apt install nodejs를 실행하면 작년과는 다른 결과를 얻을 수 있고, 아마 내년에도 다른 결과가 나올 것입니다. 그래서 Dockerfile 자체는 재현 가능한 빌드를 설명할 수 없습니다 - 같은 Docker파일을 다른 시점에 실행하면 다른 빌드 결과물이 나옵니다!

여기서 간단한 완화책은 가능한 한 빌드를 구성하는 것입니다. 정확한 버전(이상적으로는 정확한 콘텐츠 해시도 포함)을 지정하여 앞으로 빌드가 현재 빌드와 같은 버전을 사용하도록 하는 것입니다. 하지만 외부 서비스도 예상치 못하게 동작을 바꿀 수 있습니다. 진정으로 비관적이고 재현 가능한 빌드는 가능한 한 많은 네트워크 자원을 활용한 내부 이미지를 실행합니다.

3기둥: 자원 가용성

만약 우리의 빌드가 반복 가능하고 발밑의 세상이 변하지 않는다고 가정해 봅시다. 이제 필요한 건 빌드 입력에 대한 접근뿐입니다. 간단해 보이죠? 잘......

레지스트리가 가끔 실패하기도 합니다

대부분의 노드 개발자들은 최소 한 번의 NPM 장애를 경험했으며, 이 기간 동안 캐싱이나 미러링 없이 NPM 패키지를 구축하는 파이프라인이 중단됩니다. 많은 노드 개발자들도 좌측 패드와 가짜 제거를 경험했으며, 이는 NPM 생태계에 심각한 피해를 주었고 사실상 장애 상태에 해당했습니다.

이런 빌드 중단을 완화하는 유일한 신뢰할 만한 방법은 자체 패키지 레지스트리 미러를 실행하는 것입니다. 외부 서비스가 불가능할 때는 이미지를 온라인에 남길 수 있습니다; 공식 레지스트리가 이전 패키지를 삭제해도 미러는 계속 서비스를 제공할 수 있습니다. 같은 원칙이 다른 원격 서비스에도 적용됩니다: 자체 이미지를 실행하지 않는 한, 빌드 파이프라인의 가용성은 그 서비스의 가용성과 비교할 수 있습니다.

서비스 이미지를 실행하는 것은 항상 섬세한 거래입니다. 한편으로는 NPM과 같은 등록기관이 전담 엔지니어링 및 운영 팀을 보유하고 있어 이러한 시스템을 온라인 상태로 유지할 수 있습니다. 반면, 모든 NPM 이미지를 실행하는 것보다 작은 의존성 집합에 대해 작은 이미지를 실행하는 것이 훨씬 쉽습니다. 각 서비스의 구체적인 상황에 따라 미러링 결정을 내려야 하며, 과거 외부 서비스의 신뢰성과 팀의 빌드 가용성 및 인력 요구를 고려해야 합니다.

공급업체는 최대한의 가용성을 보장합니다

프로젝트 의존성의 최대 가용성을 보장하는 쉬운 방법 중 하나는 이를 공급업체에 추가하는 것입니다. 대부분의 패키지 관리자는 외부 서비스에서 다운로드를 의존하는 대신 의존성 소스 코드를 버전 관리에 저장하며 소스 코드와 공존시키는 '벤더링' 기능을 지원합니다. 예를 들어, Node에서는 node_modules를 소스 컨트롤에 커밋하는 것처럼 보일 수 있습니다.

이 솔루션이 완벽하지는 않지만(벤더와 프로젝트 구성에 따라 버전 관리에 큰 부담이 될 수 있음), 최대 가용성을 위해 가장 간단하고 쉬운 솔루션인 경우가 많습니다.

참조:

하이퍼링크 로그인이 보입니다.
하이퍼링크 로그인이 보입니다.




이전의:.NET/C# 읽기 전용 필드 내용을 수정하기 위해 UnsafeAccessor를 사용해
다음:Angular 18 시리즈 (32) ControlValueAccessor 맞춤 폼 제어
 집주인| 2025-4-30 10:10:23에 게시됨 |
C#에서 NuGet 패키지를 만들 때 반복 가능한 빌드를 사용하는 것에 대해:

하이퍼링크 로그인이 보입니다.
하이퍼링크 로그인이 보입니다.
면책 조항:
Code Farmer Network에서 발행하는 모든 소프트웨어, 프로그래밍 자료 또는 기사는 학습 및 연구 목적으로만 사용됩니다; 위 내용은 상업적 또는 불법적인 목적으로 사용되지 않으며, 그렇지 않으면 모든 책임이 사용자에게 부담됩니다. 이 사이트의 정보는 인터넷에서 가져온 것이며, 저작권 분쟁은 이 사이트와는 관련이 없습니다. 위 내용은 다운로드 후 24시간 이내에 컴퓨터에서 완전히 삭제해야 합니다. 프로그램이 마음에 드신다면, 진짜 소프트웨어를 지원하고, 등록을 구매하며, 더 나은 진짜 서비스를 받아주세요. 침해가 있을 경우 이메일로 연락해 주시기 바랍니다.

Mail To:help@itsvse.com