아마 Yocto가 필요 없을 것이고, 그래도 괜찮다
(sigma-star.at)- Yocto는 배포판이 아니라 자체 Linux 배포판을 조립하는 도구이며, 필요한 제어가 없다면 기본 선택지로 삼기 어려움
- 자체 배포판은 자체 유지보수를 뜻하며, CRA 같은 규제와 제품 수명 동안의 보안 업데이트 책임까지 함께 따라옴
- Yocto 도입에는 수 시간 빌드, 100GiB 이상 빌드 디렉터리, 몇 주짜리 학습 곡선, 품질이 들쭉날쭉한 BSP 레이어가 포함됨
- 애플리케이션 실행용 견고한 Linux 기반이면 Debian과 mkosi·ELBE·debos 같은 이미지 도구가 훨씬 적은 프로젝트별 작업으로 충분할 수 있음
- 강한 맞춤화, 크기·부팅 시간 제약, 라이선스 제외, 견고한 벤더 Yocto 지원이 있을 때만 Yocto가 이기며, 의심스럽다면 기존 배포판이 낫다
Yocto의 실제 성격과 기본 선택지가 되는 이유
- Yocto는 “Yocto Linux 배포판”이 아니라 자체 Linux 배포판을 만들기 위한 도구 모음임
- Yocto Project는
bitbake,openembedded-core,meta-yocto로 만든 참조 배포판 Poky를 함께 제공함 - Yocto는 임베디드 프로젝트에 필요한 Linux 시스템을 세밀하게 조립할 수 있게 해줌
- 전체 사용자 공간을 대상 CPU용으로 컴파일 가능함
- 어떤 컴포넌트에도 패치를 적용할 수 있음
- 각 레시피의 기능을 켜거나 끌 수 있음
- 모든 버전을 고정하거나 변경할 수 있음
- 많은 SoC 벤더와 하드웨어 파트너가 바로 사용할 수 있는 BSP(Board Support Package) 레이어를 제공해 실제 하드웨어에서 동작하는 출발점을 만들어줌
- 유연성과 벤더 지원의 조합 때문에 Yocto가 기본 선택지가 되지만, 그만큼의 제어가 필요하지 않다면 부담이 더 커질 수 있음
자체 배포판은 자체 유지보수를 뜻함
- Cyber Resilience Act(CRA) 같은 규제는 제품 공급자가 배포한 소프트웨어를 안전하게 유지하고 제품 수명 동안 보안 업데이트를 제공하도록 요구함
- 일반 Yocto 릴리스는 다음 릴리스가 나올 때까지 약 7개월만 유지됨
- Yocto 5.0 Scarthgap부터 현재 정책상 LTS 릴리스는 최대 4년 업데이트를 받음
- Yocto 릴리스는 특정 버전과 메타데이터를 가진
bitbake레시피 집합, 그리고 참조 배포판 Poky로 구성됨 - 유지보수 기간 동안 Yocto 유지관리자는 컴포넌트와 Poky에 버그 및 보안 수정사항을 적용하며, 소프트웨어 컴포넌트 수정은 보통 최신 업스트림 버전에서 백포트됨
- 실제 제품에서는 Yocto를 그대로 쓰기보다 다음과 같은 변경이 들어가기 쉬움
- 일부 컴포넌트에 비단순 패치나 로컬 변경 적용
- Yocto가 제공하지 않는 추가 컴포넌트 포함
- 수정사항을 받거나 알려진 양호 상태를 유지하기 위한 버전 업그레이드 또는 고정
- Yocto 유지보수 릴리스가 나올 때마다 로컬 변경이 새 상태 위에 깨끗하게 적용되는지 확인해야 함
- 추가하거나 고정한 컴포넌트는 Yocto 유지관리자가 알 수 없으므로, 해당 컴포넌트가 계속 수정사항을 받고 있는지도 직접 확인해야 함
- Poky를 거의 변경하지 않고 쓴다면, Yocto가 필요한 이유를 다시 따져봐야 함
Linux 커널과 벤더 의존성
- Yocto는 각 릴리스의 일부로 Linux 커널을 제공하고 유지하지만, 실제 제품에서 이를 수정 없이 쓰는 경우는 드묾
- 보통 최소한 벤더 패치를 적용해야 하고, 필요한 드라이버와 수정사항이 들어간 충분히 새로운 커널을 사용해야 함
- CVE 추적까지 포함하면 커널만으로도 Yocto 사용 여부와 관계없이 큰 유지보수 부담이 됨
- 유지보수 부담을 제어하려면 kernel.org의 LTS 커널 위에 구축하고 모든 변경을 정돈된 패치 큐로 유지하는 방식이 권장됨
- 보안 수정사항을 따라가려면 새 stable 릴리스로 이동한 뒤 패치 큐를 다시 적용함
- kernel.org는 LTS 커널을 여러 해 유지하므로, 보통 패치 큐는 깨끗하게 적용되고 새 LTS 릴리스로 넘어갈 때만 실질적인 작업이 필요함
- 설정과 보안 요구사항에 따라 부트로더에도 같은 원칙이 적용되며, 부트로더 역시 보통 벤더 특화 요소가 큼
- 벤더가 제공하는 커널을 그대로 유지하는 방식은 대체로 좋지 않음
- vendor kernel은 kernel.org보다 수년 뒤처져 있는 경우가 많음
- 업데이트를 거의 받지 않음
- 대부분의 보안 수정사항을 놓침
Yocto 도입 비용
- 자체 배포판을 만든다는 선택은 실제 엔지니어링 시간을 요구함
-
빌드 시간
- Yocto는 사실상 모든 것을 소스에서 컴파일함
- 복잡하지 않은 수준을 넘는 이미지의 클린 빌드도 빠른 워크스테이션에서 수 시간 걸림
sstate-cache와 공유DL_DIR은 반복 빌드를 빠르게 만들지만, 작은 레시피 변경만으로도 캐시의 큰 부분이 무효화될 수 있음
-
디스크와 CI 비용
- Yocto 빌드 디렉터리는 쉽게 100GiB 이상까지 커짐
- CI 러너에는 충분한 스토리지와 작업 간
sstate공유 방식이 필요함 sstate와DL_DIR를 미러링하면 고통을 줄일 수 있지만, 그 인프라는 직접 운영해야 함
-
학습 곡선
bitbake레시피, 레이어, 동적 레이어, 클래스, 오버라이드,bbappend파일,PACKAGECONFIG,DEPENDS와RDEPENDS의 차이 등 익혀야 할 항목이 많음- 엔지니어가 Yocto 코드베이스에 온보딩되는 데는 며칠이 아니라 몇 주가 걸림
-
BSP 레이어 품질 편차
- 일부 SoC 벤더는 깨끗하고 잘 유지되는 BSP 레이어를 제공함
- 다른 벤더는 5년 된 커널이나 부트로더를 고정하고, 머신별 레시피를 잘못된 레이어에 하드코딩하며, Poky를 올릴 때마다 깨지는
meta-vendor레이어를 제공하기도 함 - 좋은 출발점처럼 보이는 BSP가 빌드에서 가장 나쁜 부분이 될 수 있음
- 이런 요소들은 Yocto를 피해야 할 이유가 아니라, 도입 전에 실제로 필요한지 확인해야 할 이유임
대안: 검증된 배포판 재사용
- 애플리케이션을 실행할 견고한 Linux 기반만 필요하다면 Debian GNU/Linux 같은 기존 배포판이 같은 문제의 상당 부분을 프로젝트별 작업량을 훨씬 줄여 해결함
- Debian은 현재 약 70,000개 바이너리 패키지를 제공함
- 지원 아키텍처에는
amd64,i386,arm64,armhf,riscv64,ppc64el등이 포함됨 - 많은 SoC는 재컴파일 없이 Debian 바이너리를 직접 실행할 가능성이 높음
- Debian은
systemd,udev,dbus가 포함된 현대적인 사용자 공간만 제공하는 배포판이 아님 - 아카이브에는 SysV 스타일 init이나 BusyBox 기반의 작은 Linux 시스템을 만들기 위한 요소도 포함됨
- 얇은 기반을 선택하고 제품에 필요한 패키지만 설치하면서도 Debian 패키지 유지관리자의 작업을 활용할 수 있음
Debian 유지보수 모델
- Debian stable은 Debian Security Team으로부터 약 3년 동안 보안 업데이트를 받음
- 이후 커뮤니티 기반 Debian LTS 프로젝트가 일반 아키텍처에서 약 2년 더 지원을 연장함
- 실제로 릴리스당 약 5년 지원이 가능해 Yocto LTS와 비슷한 수준이지만, 프로젝트별 작업은 훨씬 적음
- 최신 수정사항을 받으려면 최신 Debian 패키지를 가져와 이미지를 다시 만들면 됨
- Yocto에서 업스트림 패치를 직접 백포트하거나 로컬 변경이 유지보수 릴리스 위에 계속 적용되는지 다시 확인하는 방식과는 작업 성격이 크게 다름
임베디드 이미지 구성 방식
- Debian 기반 임베디드 이미지는 SoC에서 USB 플래시 드라이브로 부팅해 Debian 설치 프로그램을 실행하는 방식이 아님
- 빌드 호스트에서 플래시 가능한 이미지를 생성하고 이를 장치에 기록하는 방식임
- 필요한 구성 요소는 다음과 같음
- 보통 SoC 특화인 부트로더 예:
u-boot - 보통 SoC 특화인 Linux 커널
- Debian에서 바로 가져온 Linux 사용자 공간 기반 루트 파일시스템
- 세 요소를 플래시 가능한 이미지로 결합하는 이미지 조립 도구
- 보통 SoC 특화인 부트로더 예:
- 이미지 조립 도구의 일반적인 선택지는
mkosi,ELBE,debos임 - 세 도구는 모두 자유 소프트웨어이며, 하드웨어에 플래시할 수 있는 결정적 이미지를 생성함
- 유지보수 작업은 크게 줄어들며, 대부분의 업데이트는 레시피 재작성보다 이미지 안 패키지를
apt방식으로 새로고침하는 일이 됨
debos 기반 Debian 빌드 예시
debos는 YAML 레시피를 읽음- 레시피는 명령 실행, 루트 파일시스템 생성, 설정된 소스에서 Debian 패키지 설치 같은 액션 목록으로 구성됨
- 기본 흐름은 다음과 같음
aptly로 필요한 모든 Debian 패키지의 사본을 담는 로컬 Debian 미러를 운영함- Linux 커널과 필요하면 부트로더를 Debian 패키지로 빌드해 미러에 추가함
- 미러 스냅샷을 만들고 태그를 붙임
- 이 태그가 릴리스가 됨
debos가 해당 미러를 사용하도록 설정하고 대상 이미지를 만드는 레시피 액션을 작성함- 필요하면 Debian 소스 패키지와 이미지의 SBOM(Software Bill of Materials)을 이미지와 함께 보관함
- 소스 패키지와 SBOM 보관은 GPL 소스 제공 의무와 CRA의 자재 명세 요구사항을 지키는 데 도움이 됨
debsbom같은 도구는 Debian 시스템에서 직접 SBOM을 생성함
Yocto를 선택해야 하는 경우
- 강하게 맞춤화된 배포판이 필요할 때 Yocto가 적합함
- 맞춤 사용자 공간
- 맞춤 컴파일 플래그
- 기반 컴포넌트에 대한 깊은 변경
- 기성 배포판으로 충족할 수 없는 엄격한 크기 또는 부팅 시간 제약이 있을 때 적합함
- 일반적인 라이선스 범주를 제외해야 하는 라이선스 제약이 있을 때 적합함
- 의료기기, 자동차, 일부 방산 작업 등 일부 산업에서는 GPLv3 컴포넌트를 배포하지 않음
- Yocto의
INCOMPATIBLE_LICENSE메커니즘은 이미지 전체에서 특정 라이선스 계열을 제외하기 쉽게 만듦 - 일반 Debian 기반에서는 패키지를 직접 감사하고 줄여야 함
- SoC 벤더의 공식 지원 경로가 Yocto이고 BSP 품질이 견고할 때 적합함
Yocto를 피해야 하는 경우
- 애플리케이션을 올려 실행할 현대적인 Linux만 필요하다면 Yocto가 필요하지 않을 수 있음
- 스토리지와 메모리 예산이 일반 Debian 기반 이미지를 감당할 수 있다면 Yocto의 이점이 줄어듦
- 예시 기준은 수백 MB 플래시와 256MB 이상 RAM임
- 제품 수명이 길고 자체 유지보수보다 Debian Security Team에 의존하는 쪽이 낫다면 Yocto를 피하는 편이 맞음
Debian을 피해야 하는 경우
- Debian 패키지를 많이 수정하거나 다시 빌드해야 한다면 Debian이 불리함
- 몇 개 패키지 재빌드는 관리 가능함
- 각 재빌드 패키지는 직접 떠안는 유지보수 작업이 됨
- 수십 개 업스트림 패키지를 패치하면 Debian 유지관리자가 대신하던 작업을 다시 만드는 셈임
- 이 규모에서는 Yocto의 레시피 모델이 더 깔끔하게 처리함
musl이나uClibc같은 비-glibc libc가 필요하면 Debian이 맞지 않음- Debian의 메인 아카이브는 전반적으로 glibc를 사용함
- 이를 교체하려면 아카이브 대부분을 직접 다시 빌드해야 함
- Debian stable이 제공하는 것보다 훨씬 최신 소프트웨어가 필요하면 Debian이 불리함
- backports가 일부 패키지에는 도움이 됨
- 최근 컴파일러나 최근 런타임이 제품에 필요하면 Debian stable과 충돌함
- Debian testing은 프로덕션 대상이 아님
결정 원칙과 결론
- Yocto 여부는 의식적으로, 제품 초기에 결정해야 함
- 이 선택은 제품이 현장에 배포된 뒤 되돌리기 어려운 기반 선택임
- 의심스럽다면 기존 배포판에서 시작하는 편이 나음
- 실제 이유가 생긴 뒤 나중에 Yocto로 이동하는 비용은, 프로젝트 중간에 실질적 이익 없이 수년의 유지보수 작업을 떠안았음을 발견하는 것보다 훨씬 낮음
- Yocto는 필요한 Linux 시스템을 정확히 만들 수 있게 해주는 뛰어난 엔지니어링 산물이지만, 바로 그 정확한 제어가 필요하지 않을 때 문제가 됨
- Buildroot 같은 다른 소스 기반 빌드 도구에도 같은 논리가 거의 그대로 적용됨
- 자체 배포판을 조립하는 순간 그 유지보수 책임도 직접 소유하게 됨
- 핵심 결론은 명확함
- “자체 배포판”은 실제로 자체 유지보수를 뜻함
- CRA와 유사 규제는 그 비용을 실제 부담으로 만듦
- 크게 수정된 Yocto 빌드는 업스트림 수정사항을 공짜로 상속하지 않음
- 각 유지보수 릴리스는 검토와 재작업이 됨
mkosi,ELBE,debos로 이미지화한 Debian 같은 기존 배포판은 일반적인 경우를 훨씬 적은 프로젝트별 노력으로 처리함- 시스템을 외과적으로 제어해야 할 때는 Yocto가 이김
- 그렇지 않을 때 Yocto를 고르는 것은 존재하지 않는 문제를 길고 비싸게 푸는 방식이 됨
댓글과 토론
Lobste.rs 의견들
-
SoC 벤더의 공식 지원 경로가 Yocto라면 BSP가 탄탄하지 않더라도, 대체로 품질이 낮은 Ubuntu 포팅보다 낫다고 봄
Ubuntu 포팅은 RAUC 통합이나 루트 파일시스템 불변화 같은 작업을 번거롭게 만듦. Yocto와 그 변형된 bash/python 방언은 정말 싫지만, 결국 거기에 묶여 있음 -
Yocto 컨설팅을 많이 하지만, 글에서 한탄하는 문제는 겪어본 적이 거의 없음. 보통은 반대로, Yocto가 최선인 상황에서도 고객이 굳이 피하려고 해서 경영진을 설득해야 하는 경우가 많음
다만 Yocto가 미움받는 건 이해됨. 어렵고, 헷갈리고, 느리고, 도구도 더 나아질 수 있음. 그래도 실질적인 대안이 있는지 모르겠고, BSD 쪽에도 비슷한 게 있는지 궁금함- Yocto와 얼마나 비슷한지는 모르겠지만, FreeBSD에서 임베디드 시스템 이미지를 만드는 일반적인 방식은 NanoBSD임
https://docs.freebsd.org/en/articles/nanobsd/ - 실전에서 깊게 써보진 않았고 Yocto보다 덜 완성됐을 수는 있지만, buildroot 에는 꽤 괜찮은 것들이 들어 있음
주로 Nerves 맥락에서 써봤는데, Nerves는 기본적으로 buildroot + fwup + Erlang VM과 지원 소프트웨어 조합임. 임베디드 Linux 시스템을 개발하고 패키징/배포하기에 꽤 편했음 - 임베디드 Linux/BSD 시스템을 직접 다루진 않지만, NetBSD를 써본 입장에선 빌드 시스템인 build.sh만으로도 충분해 보임
커널과 사용자 공간을 쉽게 교차 컴파일할 수 있음. 마지막에 pkgsrc 애플리케이션을 추가하거나 생성 이미지에 u-boot 같은 부트로더를 넣어야 하면 스크립트가 좀 필요할 수는 있음. 애플리케이션에 맞게 바로 커스터마이즈 가능한 완성된 흐름은 아닐 수 있지만, 기반으로는 괜찮음 - NetBSD는 제한된 환경을 대상으로 교차 컴파일하기 좋게 구성돼 있고, 한번 감을 잡으면 꽤 쾌적함
- Yocto와 얼마나 비슷한지는 모르겠지만, FreeBSD에서 임베디드 시스템 이미지를 만드는 일반적인 방식은 NanoBSD임
-
임베디드 쪽의 끔찍함을 조금 겪어본 한정된 경험으로는, 이런 용도에는 NixOS가 꽤 잘 맞았고 빌드 도구도 Yocto보다 훨씬 좋았음
- ARM 장치에서도 그런지 궁금함. NixOS 생태계는 그런 기기에는 아직 조금 이른 줄 알았음
-
마침 회사에서 Rockchip 기반 장치용 커스텀 Linux 커널과 배포판을 계획하고 만들기 시작했는데, 시기적절한 글임
BSP는 유지보수할 게 꽤 많아 보이고, Debian을 “그냥 쓰는” 편이 내가 엉망으로 작성한 bitbake 작업보다 훨씬 관리 가능해 보임. 그래도 Yocto 생태계 자체는 꽤 괜찮고, 시작을 쉽게 해주는 kas나 isar 같은 도구가 있음- isar README를 보면 Yocto가 아니라 Debian 기반으로 보임. 둘을 섞어 쓰는 게 흔한지 궁금함
글에서는 Yocto 아니면 Debian처럼 말하지, 둘을 합친 방식은 아닌 것 같음
- isar README를 보면 Yocto가 아니라 Debian 기반으로 보임. 둘을 섞어 쓰는 게 흔한지 궁금함