AEGLOSLAB ROS 2 Jazzy 대전

제14부 시스템 설계·품질·운영

14.7 품질 수준·REP 2004·의존성 위생

14.7.1 이 장에서 배우는 것 / 선수 지식

"이 패키지를 제품에 써도 되는가?" — ROS 2 생태계에는 수천 개의 패키지가 있고, 품질은 천차만별이다. 어떤 것은 여러 회사가 운영에 쓰는 검증된 코드이고, 어떤 것은 대학원생이 논문용으로 만들고 3년째 방치된 것이다. 겉으로는 구분이 안 된다.

REP 2004는 이 문제에 대한 ROS 2의 답이다 — 패키지가 스스로 품질 수준을 선언하고, 그 근거를 문서로 제시하게 한다. 완벽하지는 않지만, 판단의 출발점을 준다.

이 장은 그 체계와, 더 넓게 의존성을 건강하게 관리하는 실무를 다룬다.

배우는 것:

  • REP 2004 — 품질 수준의 정의.
  • 평가 항목 — 무엇으로 판정하는가.
  • 실무적 해석 — 선언을 어디까지 믿는가.
  • 의존성 평가 — 도입 전 확인.
  • 의존성 위생 — 지속적 관리.
  • 자체 패키지의 품질 — 우리가 만들 때.
  • 취약점·라이선스 — 놓치기 쉬운 축.

선수 지식: 4.1~4.4(패키지·의존성), 4.9(릴리스), 4.10(CI), 13.4.6(갱신), 14.5·14.6(시험).

정직: REP 2004의 정확한 항목·수준 정의와 각 패키지의 현재 선언 상태는 반드시 원문과 해당 저장소로 확인해야 한다(확인 필요). 이 장은 개념과 활용 방법을 다루며, 특정 패키지의 품질을 판정하지 않는다. 라이선스 준수 판단은 법무의 영역이며 이 책은 조언을 제공하지 않는다. 이 환경에서 검증하지 않았다(목차 3).

검증 상태(추가): 이 장의 서술 가운데 1곳은 이후 회차에서 Jazzy 실물과 대조해 확인했다 — 본문의 (실행 확인) 표기가 그것이다. 표기가 없는 서술은 위 고지가 그대로 적용된다(목차 3의 검증 범위 표).

14.7.2 REP 2004 — 품질 수준

패키지를 다섯 수준으로 분류한다(확인 필요: 정확한 정의).

품질 수준 Level 1 가장 엄격 — 핵심 패키지 Level 2 Level 3 Level 4 Level 5 요구 없음
수준대략적 성격
1가장 높은 요구 — 버전 정책·시험·문서·보안 대응 전부
2높음
3중간 — 많은 실무 패키지
4낮음
5요구 없음 — 선언만

평가 축(확인 필요: 정확한 목록):

축내용
버전 정책안정 버전·호환성 정책
변경 통제리뷰·CI 요구
문서화기능·API·라이선스
시험커버리지·시스템 시험·성능
의존성하위 의존의 품질 수준
플랫폼 지원Tier 정책(4.4)
보안취약점 대응 정책

견해: "의존성의 품질 수준이 평가 축에 있다"는 점이 중요하다. Level 1 패키지가 Level 5 패키지에 의존하면 그 사슬이 약점이 된다. 품질은 전이적이므로, 우리 시스템의 품질도 가장 약한 의존성 수준에 가깝다.

정직: 품질 선언은 자기 선언이며 외부 감사가 아니다(확인 필요: 검증 절차 유무). 선언한 항목이 실제로 유지되는지는 별개이므로, 선언을 출발점으로 삼되 스스로 확인해야 한다.

14.7.3 실무적 해석

품질 선언을 어떻게 읽을 것인가.

상황해석
Level 1·2 선언 + 활발한 저장소신뢰도 높음
선언 있으나 저장소 정체선언이 낡았을 수 있음
선언 없음스스로 평가 필요
Level 5정직한 표시 — 그 자체는 문제가 아님

견해: Level 5 선언을 부정적으로만 보지 말라. "우리는 품질 보증을 하지 않는다"고 정직히 밝힌 것이며, 실험적 패키지에는 적절하다. 문제는 Level 5 패키지를 운영에 쓰면서 그것을 모르는 것이다.

견해: 선언보다 저장소의 실제 상태가 더 많은 것을 말해 준다. 최근 커밋, 이슈 응답, CI 상태, 릴리스 빈도, 기여자 수 — 이런 것들이 "이 패키지가 유지보수되고 있는가" 를 알려준다. 품질 선언과 함께 봐야 한다.

14.7.4 의존성 평가

새 패키지를 도입하기 전에 확인할 것.

의존성 후보 ① 필요성 정말 필요한가 ② 품질 · 활성도 ③ 라이선스 ④ 의존 사슬 ⑤ 대안 · 이탈 비용 결정 · 기록
항목질문
① 필요성직접 구현 대비 이득이 큰가
② 활성도유지되고 있는가·이슈 응답
③ 라이선스우리 배포 방식과 맞는가
④ 의존 사슬무엇을 함께 끌고 오는가
⑤ 이탈 비용나중에 뺄 수 있는가
⑥ 배포 가능성바이너리 있나·빌드 필요한가
⑦ 플랫폼대상 아키텍처 지원(4.4)
⑧ 보안취약점 이력·대응
# 의존 사슬 확인
rosdep keys --from-paths src --ignore-src
colcon list --topological-order
ros2 pkg xml <package>          # 메타데이터 (확인 필요: 명령)

견해: ④(의존 사슬)를 확인하지 않으면 작은 편의를 위해 큰 부담을 진다. 유틸리티 하나를 쓰려고 대규모 프레임워크를 끌고 오면, 빌드 시간·이미지 크기·취약점 표면이 모두 늘어난다. "이 패키지가 데려오는 것"을 먼저 보라.

견해: ⑤(이탈 비용)를 도입 시점에 생각하라. 인터페이스를 우리 코드로 감싸 두면(어댑터) 나중에 교체할 수 있지만, 그 타입이 우리 코드 전체에 퍼지면 뺄 수 없다. 핵심 의존성일수록 경계를 두는 것이 값을 한다(14.1.5).

정직: 라이선스 적합성 판단은 법무의 영역이다. 라이선스 종류를 확인하고 조직의 정책·법무에 확인하는 절차를 두어야 하며, 이 책은 특정 라이선스의 해석이나 준수 방법을 조언하지 않는다.

14.7.5 의존성 위생

도입 후 지속적으로 관리한다.

활동주기
의존성 목록 유지상시
취약점 확인정기
버전 갱신계획적(13.4.6)
미사용 의존성 제거정기
중복 기능 정리정기
고정(pin) 정책 검토릴리스마다
라이선스 재확인변경 시

흔한 위생 문제:

문제결과
선언되지 않은 의존다른 환경에서 빌드 실패(4.3.6)
과다 선언불필요한 설치
버전 미고정재현 불가
과도한 고정보안 패치 못 받음
방치된 의존성취약점·비호환
순환 의존빌드 문제
<!-- package.xml — 의존 종류를 정확히 (4.3) -->
<depend>rclcpp</depend>                     <!-- 빌드 + 실행 -->
<build_depend>ament_cmake</build_depend>
<exec_depend>rviz2</exec_depend>            <!-- 실행만 -->
<test_depend>ament_lint_auto</test_depend>  <!-- 시험만 -->

함정: "내 머신에서는 빌드된다"의 최다 원인이 미선언 의존이다(4.3.6). 시스템에 이미 설치되어 있어 빌드가 되지만, 클린 환경에서는 실패한다. CI를 클린 컨테이너에서 실행하면 이것이 검출된다(4.10).

견해: 버전 고정은 재현성과 보안의 절충이다. 모두 고정하면 재현 가능하지만 패치를 못 받고, 안 하면 어제 되던 빌드가 오늘 깨진다. 릴리스는 고정, 개발은 유연하게 두고, 정기적으로 고정 버전을 갱신하는 절차를 두는 것이 흔한 답이다.

견해: 의존성 목록(SBOM 성격)을 산출물로 남기라(13.4.6). 취약점 공지가 나왔을 때 "우리가 영향받는가"를 즉시 답할 수 있고, 감사·규제 대응에도 쓰인다. 릴리스 시점에 자동 생성하는 것이 현실적이다.

14.7.6 ROS 배포판과 버전

ROS 2 특유의 의존성 문제다.

축고려
배포판 고정Jazzy에 맞춘 패키지 버전(4.4)
바이너리 vs 소스apt 설치 vs 워크스페이스 빌드
백포트새 기능이 필요할 때
EOL배포판 지원 종료(15.1)
혼합 위험배포판 간 패키지 섞기

함정: 다른 배포판용 패키지를 섞으면 ABI·API 불일치가 난다. 빌드는 되는데 실행 시 비정상적으로 종료되는 경우가 있어 진단이 어렵다. 한 배포판으로 통일하고, 필요하면 소스에서 빌드한다.

견해: "바이너리로 되는 것은 바이너리로"가 유지보수에 유리하다. 소스 빌드가 늘수록 빌드 시간과 관리 부담이 는다. 수정이 필요한 것만 소스로 두고, 그것도 upstream에 기여해 되돌리는 것이 장기적으로 낫다.

견해: 포크는 마지막 수단이다. 급한 수정을 위해 포크하면 그 순간부터 upstream 변경을 따라가야 하는 부담이 생긴다. 패치를 upstream에 보내고 기다리는 동안 로컬 패치로 관리하는 편이 부채가 적다.

14.7.7 자체 패키지의 품질

우리가 만드는 것에도 같은 기준을 적용한다.

항목실무 조치
README무엇·어떻게·인터페이스
인터페이스 문서토픽·서비스·파라미터(14.1.5)
라이선스 명시package.xml·파일 헤더
CI빌드·시험·린트(4.10)
시험단위·통합(14.5·14.6)
버전 정책언제 갱신하는가
CHANGELOG변경 이력
이슈 대응내부 팀이라도
# 린트 (ament) — 확인 필요: 사용 가능한 린터
colcon test --packages-select my_pkg
# uncrustify · cpplint · flake8 · copyright 등

문서를 생성할 것인가, 쓸 것인가. REP 2004의 상위 품질 수준은 문서를 요구하고(14.7.2), 그 요구는 두 종류로 갈린다.

종류만드는 법값어치
API 참조(클래스·함수 시그니처)Doxygen(C++)·Sphinx(Python)로 소스 주석에서 생성. ROS 생태계에서는 rosdoc2가 이 둘을 감싸 패키지 단위로 빌드하며, package.xml의 <rosdoc2> export로 설정을 가리킨다(4.4.6의 export 절)생성이 자동이라 낡지 않는다. 다만 "이 함수는 무엇을 하는가"만 답하고 "왜·언제 쓰는가"는 답하지 않는다
인터페이스·운용 문서(토픽·서비스·파라미터·프레임·단위·QoS)사람이 쓴다. 자동 생성 대상이 아니다위 표가 말한 그 문서다. 노드를 쓰는 사람에게 실제로 필요한 것은 이쪽이다

정직: rosdoc2는 Jazzy의 apt 인덱스에 없다(실행 확인 — ros-jazzy-rosdoc2 패키지 없음). 소스나 pip로 설치해야 하며, 설치 방법·사용법·지원 범위는 프로젝트 문서가 정본이다(확인 필요). 이 책은 도구 사용법을 다루지 않는다.

견해: 문서 자동 생성은 있으면 좋지만 우선순위가 높지 않다. 로봇 패키지에서 사람이 실제로 찾는 것은 헤더 파일의 함수 목록이 아니라 "이 노드가 무슨 토픽을 어떤 주기·프레임·단위로 내는가" 이고, 그것은 생성되지 않는다. README 한 장 + 인터페이스 표가 Doxygen 사이트보다 값을 한다. 공개 라이브러리를 배포한다면 이야기가 달라진다.

견해: 내부 패키지라도 인터페이스 문서는 반드시 쓰라(14.1.5의 반복). 6개월 뒤의 자신과 새로 온 동료가 그 문서의 독자다. 토픽 이름·타입·주기·프레임·단위·QoS를 적는 데 10분이면 되고, 그것을 안 적어 생기는 손실은 훨씬 크다.

견해: 품질 수준을 내부적으로 등급화하는 것도 유용하다. "이 패키지는 실험용", "이것은 운영 필수"를 명시하면, 어디에 시험과 리뷰를 집중할지 정해진다. 모든 패키지를 같은 기준으로 다루면 자원이 분산된다.

함정: 린트를 나중에 도입하면 대량 수정이 발생한다. 처음부터 켜 두면 점진적으로 유지되지만, 나중에 켜면 수백 개 경고가 대량 출력돼 결국 끈다. 새 패키지는 처음부터 린트를 켜라.

14.7.8 취약점 대응

활동설명
의존성 목록 유지무엇을 쓰는가(14.7.5)
공지 추적배포판·주요 라이브러리
영향 평가우리가 그 경로를 쓰는가
패치 적용·검증13.4.6
기록무엇을 언제

견해: "영향 평가"가 실무의 핵심이다. 취약점 공지가 나와도 우리가 그 기능을 안 쓰면 영향이 없을 수 있다. 무조건 갱신"과 "무조건 무시" 사이에서 판단하려면 의존성 목록과 사용 경로를 알아야 한다.

정직: 취약점 대응 절차의 수립은 보안 전문가의 영역이다(13.1.1). 여기서는 개발 실무의 준비(목록·추적·검증 체계)만 다루며, 규제 요구가 있으면 전문가의 설계를 따라야 한다.

14.7.9 함정 카탈로그

#함정증상대처
1품질 선언만 믿음낡은 정보저장소 상태 확인
2Level 5를 무조건 배제과도한 제약용도별 판단
3Level 5를 운영에 무자각 사용위험인지·문서화
4의존 사슬 미확인부담 폭증사전 확인
5이탈 비용 미고려교체 불가어댑터 경계
6라이선스 자체 판단법적 위험법무 확인
7미선언 의존타 환경 빌드 실패클린 CI
8버전 전면 고정패치 못 받음정기 갱신 절차
9고정 없음재현 불가릴리스 고정
10배포판 혼합ABI 문제통일
11불필요한 소스 빌드관리 부담바이너리 우선
12성급한 포크지속 부채upstream 기여
13인터페이스 문서 없음사용·유지 어려움항상 작성
14린트 늦은 도입대량 경고·포기처음부터
15의존성 목록 없음취약점 대응 불가자동 생성
16미사용 의존 방치표면 확대정기 정리

14.7.10 체크포인트

  • REP 2004의 다섯 수준과 대략적 성격을 말할 수 있는가.
  • 평가 축 일곱 가지와, "의존성의 품질 수준"이 축에 있는 의미는?
  • 품질 선언을 해석할 때 함께 봐야 할 것은?
  • Level 5 선언을 어떻게 받아들여야 하는가.
  • 의존성 평가의 여덟 항목을 들 수 있는가.
  • 의존 사슬 확인을 강조하는 이유는?
  • 이탈 비용을 도입 시점에 고려하는 방법은?
  • 의존성 위생의 일곱 활동과 흔한 문제 여섯 가지는?
  • "내 머신에서는 빌드된다"의 최다 원인과 예방은?
  • 버전 고정의 절충과, 흔한 해법은?
  • 의존성 목록을 산출물로 남기는 이유 셋은?
  • 배포판 혼합의 위험과, 바이너리·소스 선택 원칙은?
  • 포크를 마지막 수단으로 두는 이유는?
  • 자체 패키지에서 반드시 할 것 여덟 가지와, 내부 패키지에도 문서가 필요한 이유는?
  • 내부 품질 등급화의 이점은?
  • 린트를 처음부터 켜라는 조언의 근거는?
  • 취약점 대응에서 "영향 평가"가 핵심인 이유는?

다음 장 14.8은 이 모든 것을 로봇에 배포하는 문제 — systemd·컨테이너·OTA 배포를 다룬다.