필요한 정보 모아보기
테크

GitHub Actions 우분투(Ubuntu) 26.04 러너 정식 지원 — 10월 19일 ubuntu-latest 전환 전 확인할 것

#GitHub Actions#Ubuntu#CI/CD

GitHub Actions의 Ubuntu 26.04 러너 이미지가 9월 17일 공개 프리뷰를 마치고 x64·arm64 모두 정식 지원(GA)에 들어갔다. 쓰려면 runs-on: ubuntu-26.04(arm64는 ubuntu-26.04-arm)을 지정하면 된다. 더 중요한 일정은 따로 있다. 10월 19일부터 몇 주에 걸쳐 x64 ubuntu-latest 레이블이 24.04에서 26.04로 바뀐다.

GitHub 공지는 한 줄로 경고한다. "Ubuntu 26.04 includes updated, and in some cases removed, tools and tool versions"(26.04에는 업데이트된 도구와, 경우에 따라 제거된 도구가 있다). 무엇이 바뀌었는지는 직접 대조해 보는 수밖에 없다.

자동 전환, 정확히 누구 얘기인가

전환 공지(actions/runner-images #14748)의 문장은 이렇다. "We have monitored customer feedback and image stability, and are now ready to set it as the latest version for the x64 ubuntu-latest label."(고객 피드백과 안정성을 지켜본 결과, x64 ubuntu-latest 레이블의 최신 버전으로 지정할 준비가 됐다.) 그리고 "This change will be rolled out over a period of several weeks beginning October 19, 2026."(10월 19일부터 몇 주에 걸쳐 적용된다.)

정리하면 영향 범위는 이렇다.

워크플로의 runs-on10월 19일 이후
ubuntu-latest몇 주에 걸쳐 26.04로 바뀜
ubuntu-24.04그대로 24.04
ubuntu-24.04-arm 등 arm영향 없음(ubuntu-latest-arm 레이블은 원래 없음)
ubuntu-22.04그대로지만 2027년 4월 17일 완전 종료 예정

-latest가 늘 "가장 새 OS"는 아니라는 점도 기억해 둘 만하다. GitHub 문서의 정의다. "The -latest runner images are the latest stable images that GitHub provides, and might not be the most recent version of the operating system available from the operating system vendor."(-latest는 GitHub이 제공하는 최신 안정 이미지이며, OS 공급사의 최신 버전과는 다를 수 있다.) Ubuntu 26.04 자체는 4월 23일에 나왔는데, 러너의 latest가 되기까지 반년이 걸린 셈이다.

22.04 쪽도 일정이 잡혔다. GitHub은 "GitHub Actions maintains the latest two stable versions of any given OS version."(각 OS는 최신 안정 버전 두 개만 유지한다)이라는 원칙에 따라 22.04 종료 절차를 9월 17일 시작했다. 종료 전에는 일부러 작업을 실패시키는 '브라운아웃' 기간도 예고돼 있다.

실제로 뭐가 바뀌었나 (직접 대조)

GitHub의 러너 이미지 저장소(actions/runner-images)에서 두 이미지의 설치 목록(README)을 받아 diff로 비교했다(9월 30일, 24.04는 20260920.314.1, 26.04는 20260920.143.1 기준).

항목Ubuntu 24.04Ubuntu 26.04
커널6.177.0
Node.js22.23.224.21.0
npm10.9.811.19.0
Python3.12.33.14.4
Ruby3.2.33.3.8
PHP8.3.68.5.4
Java 기본값1725 (Java 8 제거)
OpenSSL3.0.133.5.5
CMake3.31.64.4.3
Docker Compose2.38.25.1.3
Helm3.22.04.3.0
PostgreSQL16.1518.6
MySQL8.0.468.4.11
Julia1.13.0없음
Swift6.4없음(추후 추가 예정)

26.04에서 빠진 건 Julia·Swift 말고도 Miniconda(CONDA 환경변수가 비어 있다), Fastlane, Mercurial, Pulumi, 전역 npm 모듈 Lerna·Newman·Parcel 등이 있다. 제거 사유는 대부분 "maintenance reasons"(유지보수 사유)다. Swift만은 프리뷰 공지에 "Not yet available for Ubuntu 26.04. Will be added later"(아직 없고, 나중에 추가)라고 적혀 있다. Pulumi는 pulumi/actions 액션으로 설치하라고 안내한다. 반대로 PowerShell, 브라우저(Chrome·Edge·Firefox), AWS·Azure·gcloud CLI, Rust, .NET은 버전이 같다.

하나 헷갈리는 부분이 있다. GA 공지 표에는 "Java default remains Java 17"이라고 돼 있는데, 이미지 README와 프리뷰 공지는 26.04 기본값을 25로 적었다. 실제 설치 목록인 README 쪽을 따랐다. Java 빌드가 있다면 actions/setup-java로 버전을 명시하는 게 제일 확실하다.

메이저 버전이 뛴 도구(CMake 4, Docker Compose 5, Helm 4, MySQL 8.4)는 옵션이나 기본 동작이 바뀌었을 가능성이 크다. MySQL 8.4는 Ubuntu 릴리스 노트에 따르면 옛 mysql_native_password 방식 계정을 기본으로 잠근다. 테스트 DB에 이 인증을 쓰고 있었다면 연결부터 실패할 수 있다.

러너 밖에서 온 변화: /tmp와 sudo

26.04 자체의 기본값 변경도 CI에 영향을 준다. Canonical 릴리스 노트의 두 문장이 핵심이다. "The sudo-rs tool is now the default sudo provider."(Rust로 다시 짠 sudo-rs가 기본 sudo가 됐다.) 그리고 "the /tmp directory is now a tmpfs file system by default."(/tmp가 기본으로 메모리 위의 파일시스템이 됐다.)

컨테이너로 직접 확인해 봤다. 9월 30일 macOS의 Docker(arm64)에서 공식 ubuntu:26.04 이미지를 띄운 결과다. 러너 이미지와는 다른, 기본 OS 이미지 기준이다.

VERSION="26.04.1 LTS (Resolute Raccoon)"
ldd (Ubuntu GLIBC 2.43-2ubuntu2.4) 2.43
/usr/bin/ls -> ../lib/cargo/bin/coreutils/ls   # uutils coreutils 0.8.0
/usr/bin/cp -> gnucp                           # cp는 GNU 그대로
sudo --version → sudo-rs 0.2.13

ls 같은 기본 명령이 Rust 구현(uutils)으로 바뀌었다. 다만 cp, mv, rm은 GNU 그대로다. sudo 패키지가 설치돼 있어도 실제로 실행되는 건 sudo-rs였다. 셸 스크립트가 GNU 전용 옵션이나 sudo의 세부 출력에 기대고 있다면 한 번 돌려 볼 이유가 된다.

/tmp 변화는 실제 장애로 이어졌다. 9월 23일 올라온 이슈 #14777에 따르면 26.04 러너의 /tmp는 RAM의 절반(약 7.8G), 사용자당 약 6.3G로 제한돼 큰 Go 빌드가 "disk quota exceeded"로 실패했다. GitHub 쪽에서 재현했고, 수정 PR은 9월 30일 현재 아직 병합되지 않았다. 관리자가 제시한 임시 해결책은 첫 스텝에서 tmpfs를 끄는 것이다.

- name: /tmp tmpfs 끄기 (26.04 임시 조치)
  run: sudo systemctl mask tmp.mount && sudo umount -l /tmp

관리자는 "Run it as the first step, because files already in /tmp won't be visible after the unmount."(마운트를 풀면 기존 /tmp 파일이 안 보이니 반드시 첫 스텝에서 실행하라)라고 덧붙였다. 스텝을 건드리기 싫다면 환경변수 TMPDIR를 ${{ runner.temp }}로 지정하는 방법도 있다.

보안 쪽 미해결 건도 하나 있다. 8월 공개된 Docker 취약점 CVE-2026-17106('CopyEscape', Imperva 보고)은 악성 컨테이너를 대상으로 docker cp를 실행할 때 호스트 파일이 덮어써질 수 있는 문제로, Docker 29.7.2에서 고쳐졌다. 26.04 러너의 Docker는 29.4.2라 아직 이 범위에 있다. 러너 이미지 이슈(#14554)에서 9월 14일 기준 Ubuntu 이미지 업데이트가 진행 중이라고만 밝혔다. 신뢰할 수 없는 이미지를 받아 docker cp를 쓰는 워크플로라면 잠시 피하는 게 낫다.

10월 19일 전에 미리 돌려보는 법

기존 워크플로 옆에 두 버전을 같이 돌리는 matrix를 하나 두면 된다.

# .github/workflows/ubuntu-26-check.yml
name: Ubuntu 26 호환성 체크
on:
  workflow_dispatch:
jobs:
  build:
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-24.04, ubuntu-26.04]
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v7
      - run: lsb_release -a
      # 여기에 실제 빌드·테스트 명령을 그대로 넣는다

actions/checkout은 6월에 v7이 나왔다(현재 v7.0.1). pull_request_target 워크플로에서 포크 코드를 기본으로 체크아웃하지 않도록 바뀐 버전이라, 새로 쓰는 예시라면 @v7이 맞다. fail-fast: false를 둔 이유는 한쪽이 실패해도 다른 쪽 결과까지 끝까지 보기 위해서다.

순서는 이렇다.

  1. 위 파일을 추가하고 Actions 탭에서 Run workflow로 수동 실행한다.
  2. 26.04 쪽만 실패하면 로그에서 도구 버전·/tmp 용량·권한 오류부터 본다.
  3. 당장 못 고치면 원래 워크플로의 ubuntu-latest를 ubuntu-24.04로 고정해 두고, 10월 19일 이후 천천히 옮긴다.

개인적으로는 ubuntu-latest를 쓰는 저장소라면 이번 주 안에 한 번은 돌려 보라고 권하고 싶다. 전환은 몇 주에 걸쳐 저장소마다 다른 날 일어나서, 어제 되던 빌드가 오늘 깨지는 모습으로 나타난다. 원인을 모르면 한참 헤매게 된다. 미리 한 번 돌려 두면 "26.04 때문"이라는 걸 바로 알 수 있다.

actions/runner-images 이슈 문장은 MIT 라이선스 저장소에서, GitHub 문서(docs.github.com) 문장은 CC BY 4.0 라이선스로 인용했다. GitHub 체인지로그와 Canonical 릴리스 노트는 원문을 짧게 인용했다.

출처 github.bloggithub.com/…/14748github.com/…/14226github.com/…/14777docs.github.comdocumentation.ubuntu.com

내용이 틀렸나요? 정정 요청

관련 글