자체 빌드 이미지 3종(cloudnative-pg/cnpg-postgresql/etcd) + 대응 헬름 차트 도입

security-catalog 프로젝트에서 첫 실사용 자체 빌드 이미지 3종을 포팅한다 — 전부
상위 태그·베이스 OS 교체로 해소 안 되는 CVE(Go 모듈 정적 링크 또는 미수정 CRITICAL/
HIGH)를 자체 빌드(소스 컴파일 또는 SUSE BCI 재설치)로 대응한다:

- images/cloudnative-pg: CNPG operator, release-1.30 소스 컴파일 + bci-micro
- images/cnpg-postgresql: PostgreSQL 18.4, bci-base + zypper 재설치
- images/etcd: etcd v3.7.1, 소스 컴파일(x/text 강제 업그레이드) + bci-micro

함께 추가:
- manifests/helm/{cloudnative-pg,cnpg-cluster,etcd} — 위 이미지를 참조하는 카탈로그 차트
- scripts/deploy-test/*.sh, .claude/deploy-test-procedure.md — CVE 0건과 별개로
  "실제로 뜨는가"를 검증하는 배포 스모크 테스트
- .claude/pitfalls.md — 자체 빌드/배포 테스트 중 실측한 함정 모음

검토 중 발견해 반영한 수정:
- cloudnative-pg 차트의 image 블록을 etcd와 동일한 registry/repository/tag 3필드+
  따옴표 포맷으로 통일 — 기존 포맷(repository에 registry+repo 결합, 따옴표 없음)은
  patch-catalog-tag.py 의 split 패처가 tag만 갱신하고 repository는 그대로 남기는
  조용한 부분 치환을 일으켜, 향후 레지스트리 마이그레이션 시 깨진 참조를 만들 수 있었다
- cnpg-cluster 차트의 SLES 커버리지 코멘트를 최신 실측(trivy가 SLES 15.7을 정상
  커버함, 2026-07-29 재측정)에 맞게 정정 — 폐기된 "측정 불가/OVAL 우회 필요" 결론이
  남아있었다
- CLAUDE.md/MEMORY.md 의 "images/ 디렉토리 없음" 서술을 갱신하고, 레지스트리
  마이그레이션(docker.io/wbsong111 → docker.io/paasup)·decisions/analysis 문서 이관·
  리소스 프로파일 추가를 다음 작업으로 기록

이 3개 이미지는 아직 dip-catalog 자체 CI(build-image.yml)로 빌드·게이트·push 를
실행해본 적이 없다 — 현재 참조 태그는 security-catalog 쪽에서 이미 검증된 것이다.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
wbsong111
2026-08-03 12:03:37 +09:00
parent a168a3c7e6
commit 6878b61efa
89 changed files with 36608 additions and 11 deletions
+83
View File
@@ -0,0 +1,83 @@
# CloudNativePG PostgreSQL — SUSE BCI 기반 자체 빌드
#
# 업스트림 CNPG Dockerfile(Debian/apt/PGDG-deb)을 SUSE(zypper/PGDG-rpm)로 이식한 것이다.
# ARG BASE 만 바꾸는 수준이 아니라 패키지 관리자·저장소 설정·패키지명·경로가 모두 다르다.
#
# 업스트림과의 대응 관계
# postgresql-common + apt.postgresql.org.sh → rpm --import + zypper addrepo (PGDG zypp)
# postgresql-18 → postgresql18-server
# postgresql-18-pgaudit / -pgvector → pgaudit_18 / pgvector_18
# locales-all → glibc-locale
# usermod -u 26 postgres → 불필요 (PGDG RPM 이 uid 26 으로 생성)
# /usr/lib/postgresql/18/bin → /usr/pgsql-18/bin
#
# CNPG 호환성 근거 (실측)
# - uid 26: PGDG RPM 이 postgres 를 uid/gid 26 으로 만든다 (RPM 계열 관례)
# - 바이너리 탐색: CNPG 는 경로를 하드코딩하지 않고 PATH 로 찾는다.
# cloudnative-pg 소스에서 "usr/lib/postgresql" 는 테스트 픽스처에만 등장한다.
# 그래도 하드코딩 경로를 쓰는 코드가 생길 경우를 대비해 심볼릭 링크를 함께 둔다.
#
# 측정 가능성 — trivy 는 SLES 15.7 을 정상 커버한다.
# 2026-07-29 이전에는 "trivy 의 SUSE 데이터가 15.7 을 커버하지 않는다" 로 판단했으나
# 양성 대조(SBOM 사본에 취약 버전 주입 후 재스캔)로 재측정한 결과 오판이었다 — trivy 는
# 13건을 잡았다(SUSE-SU ID 포함). 0건은 이 이미지가 실제로 최신이라서다.
# scan-sbom.sh 의 커버리지 자가진단이 매 스캔마다 이를 확인한다.
# 경위: doc/analysis/sles-oval-measurement.md
ARG BASE=registry.suse.com/bci/bci-base:15.7
FROM $BASE AS minimal
ARG PG_MAJOR=18
ARG PG_VERSION=18.4-4200001PGDG.sles15.7
ARG SLE_REPO=sles-15.7-x86_64
ARG PGDG_KEY=PGDG-RPM-GPG-KEY-SLES15
ENV PATH=$PATH:/usr/pgsql-${PG_MAJOR}/bin
# PGDG 저장소는 GPG 키를 미리 import 해야 한다. addrepo 만 하면
# "Signature verification failed for repomd.xml" 로 저장소가 스킵된다.
RUN set -eux; \
rpm --import "https://download.postgresql.org/pub/repos/zypp/keys/${PGDG_KEY}"; \
zypper --non-interactive addrepo --refresh \
"https://download.postgresql.org/pub/repos/zypp/${PG_MAJOR}/suse/${SLE_REPO}/" pgdg; \
zypper --non-interactive refresh; \
zypper --non-interactive install -y --no-recommends \
"postgresql${PG_MAJOR}-server=${PG_VERSION}"; \
zypper clean --all; \
rm -rf /var/log/zypp /var/cache/zypp
# CNPG 는 PATH 로 바이너리를 찾지만, Debian 레이아웃을 가정하는 코드가 생길 경우를 대비한다.
RUN set -eux; \
mkdir -p /usr/lib/postgresql; \
ln -sfn "/usr/pgsql-${PG_MAJOR}" "/usr/lib/postgresql/${PG_MAJOR}"; \
id postgres | grep -q 'uid=26(' || { echo "postgres uid 가 26 이 아니다"; exit 1; }
USER 26
FROM minimal AS standard
ARG PG_MAJOR=18
# 업스트림 standard 와 동등한 구성: pgaudit, pgvector, contrib(pg_stat_statements), 전 로케일.
# pg-failover-slots 는 PGDG zypp 저장소에 없어 제외한다 (업스트림 Debian standard 와의 차이).
ARG EXTENSIONS="pgaudit_${PG_MAJOR} pgvector_${PG_MAJOR}"
USER 0
RUN set -eux; \
zypper --non-interactive install -y --no-recommends \
glibc-locale \
"postgresql${PG_MAJOR}-contrib" \
${EXTENSIONS}; \
zypper clean --all; \
rm -rf /var/log/zypp /var/cache/zypp
USER 26
# 베이스 이미지에 남은 구버전 패키지를 보안 업데이트로 올린다.
# Debian 판의 `apt-get upgrade` 단계에 대응한다 (그쪽에서 NVD 기준 HIGH 5건을 해소했다).
FROM standard AS patched
USER 0
RUN set -eux; \
zypper --non-interactive refresh; \
zypper --non-interactive update -y --no-recommends; \
zypper clean --all; \
rm -rf /var/log/zypp /var/cache/zypp
USER 26