Compare commits
No commits in common. "ebea31d03812888ec69d73fdd0aca494deaa8414" and "949663fe2c47761f4f939c4fc9a3771d555544f7" have entirely different histories.
ebea31d038
...
949663fe2c
@ -13,7 +13,6 @@ tags: [infra, 24-server, ubuntu, gnome-terminal, network, python, apt, troublesh
|
|||||||
## 관련 문서
|
## 관련 문서
|
||||||
- [Infra Journey](../README.md)
|
- [Infra Journey](../README.md)
|
||||||
- [23서버 워크스페이스-인프라 구조정리 이슈](./260307_23서버_워크스페이스_인프라_구조정리_이슈.md)
|
- [23서버 워크스페이스-인프라 구조정리 이슈](./260307_23서버_워크스페이스_인프라_구조정리_이슈.md)
|
||||||
- [51123 구 IP 하드코딩과 런타임 SSOT 불일치 이슈](./260309_51123_구IP하드코딩_런타임SSOT불일치_이슈.md)
|
|
||||||
|
|
||||||
## 사건 요약
|
## 사건 요약
|
||||||
- 24 서버에서 GUI 터미널이 열리지 않아 `Ctrl + Alt + F3`로 텍스트 콘솔(TTY, 그래픽 없이 명령만 입력하는 콘솔)로 진입해 복구를 시작했다.
|
- 24 서버에서 GUI 터미널이 열리지 않아 `Ctrl + Alt + F3`로 텍스트 콘솔(TTY, 그래픽 없이 명령만 입력하는 콘솔)로 진입해 복구를 시작했다.
|
||||||
@ -45,7 +44,6 @@ tags: [infra, 24-server, ubuntu, gnome-terminal, network, python, apt, troublesh
|
|||||||
- 시스템 Python 기준을 `3.10`으로 되돌리고,
|
- 시스템 Python 기준을 `3.10`으로 되돌리고,
|
||||||
- `python3-apt`를 다시 설치한 뒤,
|
- `python3-apt`를 다시 설치한 뒤,
|
||||||
- `apt update`가 정상 완료되는 것을 확인하는 순서가 맞았다.
|
- `apt update`가 정상 완료되는 것을 확인하는 순서가 맞았다.
|
||||||
- 별도로 Codex CLI는 전역 진입점과 실제 Node 런타임 버전이 어긋나지 않도록 보정해야 했다.
|
|
||||||
|
|
||||||
## 원인 정리
|
## 원인 정리
|
||||||
### 직접 원인
|
### 직접 원인
|
||||||
@ -81,54 +79,6 @@ sudo apt update
|
|||||||
sudo apt upgrade -y
|
sudo apt upgrade -y
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4. Codex CLI 런타임 근본 복구
|
|
||||||
문제 재현:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo -u happybell80 bash -lc 'which node; node -v; which codex; codex login status'
|
|
||||||
```
|
|
||||||
|
|
||||||
재현 시점 확인값:
|
|
||||||
- `which node` -> `/usr/bin/node`
|
|
||||||
- `node -v` -> `v12.22.9`
|
|
||||||
- `which codex` -> `/usr/local/bin/codex`
|
|
||||||
- 결과: `SyntaxError: Unexpected reserved word`
|
|
||||||
|
|
||||||
원인:
|
|
||||||
- `/usr/local/bin/codex`는 `#!/usr/bin/env node` shebang을 사용한다.
|
|
||||||
- 하지만 `happybell80`의 로그인 셸 기본 PATH에서는 시스템 `node v12.22.9`가 먼저 잡혔다.
|
|
||||||
- 반면 실제 Codex CLI 패키지는 `/home/happybell80/.nvm/versions/node/v24.4.0/...` 아래에 설치돼 있었고, `engines.node >= 16` 요구와 충돌했다.
|
|
||||||
|
|
||||||
적용 조치:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo cp -a /usr/local/bin/codex /usr/local/bin/codex.pre_node24_fix
|
|
||||||
sudo cp -a /usr/local/bin/codex /usr/local/bin/codex.wrapper.20260309
|
|
||||||
sudo ln -sfn /home/happybell80/.nvm/versions/node/v24.4.0/bin/node /usr/local/bin/node
|
|
||||||
sudo ln -sfn /home/happybell80/.nvm/versions/node/v24.4.0/bin/codex /usr/local/bin/codex
|
|
||||||
```
|
|
||||||
|
|
||||||
적용 내용:
|
|
||||||
- `/usr/local/bin/node`를 `node v24.4.0` 바이너리로 연결해, `#!/usr/bin/env node`가 더 이상 시스템 `node v12.22.9`를 집지 않도록 했다.
|
|
||||||
- `/usr/local/bin/codex`는 래퍼가 아니라 원래 Codex CLI 바이너리 심볼릭 링크로 되돌렸다.
|
|
||||||
- 기존 전역 진입점은 `/usr/local/bin/codex.pre_node24_fix`로 유지했고, 임시 래퍼는 `/usr/local/bin/codex.wrapper.20260309`로만 보관했다.
|
|
||||||
- `happybell80`의 `~/.profile`에 Node `v24.4.0` 경로를 PATH 앞단에 두는 설정을 추가해 로그인 셸에서도 동일한 런타임을 사용하도록 맞췄다.
|
|
||||||
|
|
||||||
검증:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo -u happybell80 bash -lc 'which node; node -v; codex --help | sed -n "1,4p"; codex login status'
|
|
||||||
env -i PATH=/usr/local/bin:/usr/bin:/bin HOME=/home/happybell80 USER=happybell80 /usr/local/bin/codex --help
|
|
||||||
```
|
|
||||||
|
|
||||||
검증 결과:
|
|
||||||
- `which node` -> `/home/happybell80/.nvm/versions/node/v24.4.0/bin/node`
|
|
||||||
- `node -v` -> `v24.4.0`
|
|
||||||
- `codex --help` 정상 출력
|
|
||||||
- `codex login status` -> `Logged in using ChatGPT`
|
|
||||||
- 최소 PATH 환경에서도 `/usr/local/bin/codex --help` 정상 출력
|
|
||||||
- 즉 최종 상태는 래퍼 우회가 아니라, `env node`가 시스템 차원에서 지원 버전 Node를 찾도록 바로잡은 상태다.
|
|
||||||
|
|
||||||
## Python 관련 핵심 해설
|
## Python 관련 핵심 해설
|
||||||
- Ubuntu 22.04는 시스템 도구 다수가 `python3.10` 기준으로 패키징돼 있다.
|
- Ubuntu 22.04는 시스템 도구 다수가 `python3.10` 기준으로 패키징돼 있다.
|
||||||
- 여기에는 `apt`, `software-properties`, 일부 배포 관리 유틸리티가 포함된다.
|
- 여기에는 `apt`, `software-properties`, 일부 배포 관리 유틸리티가 포함된다.
|
||||||
@ -150,9 +100,6 @@ python3.13 -m venv .venv
|
|||||||
- `apt update`가 최종적으로 정상 동작하는 상태까지 복구됐다.
|
- `apt update`가 최종적으로 정상 동작하는 상태까지 복구됐다.
|
||||||
- 복구 완료 시점에 `233 packages can be upgraded` 메시지가 관측돼 패키지 목록 로드가 정상화된 것으로 판단했다.
|
- 복구 완료 시점에 `233 packages can be upgraded` 메시지가 관측돼 패키지 목록 로드가 정상화된 것으로 판단했다.
|
||||||
- 23 서버에서 위 SSH 명령으로 실제 접속 검증 시 `hostname=robeing-i9`, `user=admin` 응답을 확인했다.
|
- 23 서버에서 위 SSH 명령으로 실제 접속 검증 시 `hostname=robeing-i9`, `user=admin` 응답을 확인했다.
|
||||||
- 추가 확인 결과 Codex CLI 직접 장애 원인은 네트워크 전면 차단이 아니라 `node v12.22.9`와 `@openai/codex 0.53.0` 조합의 런타임 충돌이었다.
|
|
||||||
- 2026-03-09 수정 후 `happybell80` 로그인 셸과 `/usr/local/bin/codex` 직접 호출 모두 `node v24.4.0` 기준으로 정상 동작한다.
|
|
||||||
- `/usr/local/bin/node`도 `node v24.4.0`를 가리키도록 맞춰, `env node` 기반 실행 경로의 런타임 충돌을 제거했다.
|
|
||||||
|
|
||||||
### 23 서버 현재 점검 범위
|
### 23 서버 현재 점검 범위
|
||||||
- 본 문서는 2026-03-09 현재 작업 환경에서 23 서버로 사용 중인 호스트를 기준으로 확인했다.
|
- 본 문서는 2026-03-09 현재 작업 환경에서 23 서버로 사용 중인 호스트를 기준으로 확인했다.
|
||||||
@ -190,57 +137,16 @@ sudo systemctl reset-failed
|
|||||||
- 이후 `sudo logrotate -d /etc/logrotate.conf`에서 `Ignoring nginx.backup.20251021.bak, because of *.bak pattern match`를 확인했다.
|
- 이후 `sudo logrotate -d /etc/logrotate.conf`에서 `Ignoring nginx.backup.20251021.bak, because of *.bak pattern match`를 확인했다.
|
||||||
- `sudo systemctl status logrotate.service`는 `status=0/SUCCESS`로 종료됐고, `systemctl --failed`는 `0 loaded units listed.`, `sudo systemctl is-system-running`은 `running`으로 복귀했다.
|
- `sudo systemctl status logrotate.service`는 `status=0/SUCCESS`로 종료됐고, `systemctl --failed`는 `0 loaded units listed.`, `sudo systemctl is-system-running`은 `running`으로 복귀했다.
|
||||||
|
|
||||||
## 2026-03-09 추가 확인 및 수정: 잔존 사설 IP 설정
|
|
||||||
- 작업 전 활성 인터페이스 `eno1`에는 `192.168.219.52/24`와 `192.168.0.106/24`가 동시에 붙어 있었다.
|
|
||||||
- 작업 전 `ip route` 기준 기본 경로도 `192.168.0.1` 외에 `192.168.219.1 metric 100`이 함께 남아 있었다.
|
|
||||||
- 원인은 NetworkManager 프로필 `/etc/NetworkManager/system-connections/Wired connection 1.nmconnection`에 과거 고정값이 남아 있던 것이다.
|
|
||||||
|
|
||||||
```ini
|
|
||||||
[ipv4]
|
|
||||||
address1=192.168.0.106/24,192.168.0.1
|
|
||||||
dns=8.8.8.8;1.1.1.1;
|
|
||||||
method=manual
|
|
||||||
route-metric=0
|
|
||||||
```
|
|
||||||
|
|
||||||
적용 조치:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo nmcli connection modify 'Wired connection 1' \
|
|
||||||
ipv4.method manual \
|
|
||||||
ipv4.addresses '192.168.0.106/24' \
|
|
||||||
ipv4.gateway '192.168.0.1' \
|
|
||||||
ipv4.dns '8.8.8.8 1.1.1.1' \
|
|
||||||
ipv4.routes '' \
|
|
||||||
ipv4.route-metric 0
|
|
||||||
sudo ip addr del 192.168.219.52/24 dev eno1
|
|
||||||
sudo ip route del default via 192.168.219.1 dev eno1 metric 100
|
|
||||||
```
|
|
||||||
|
|
||||||
수정 결과:
|
|
||||||
- 활성 `eno1`에는 현재 `192.168.0.106/24`만 남아 있다.
|
|
||||||
- 기본 경로는 `192.168.0.1`만 남아 있다.
|
|
||||||
- 즉 과거 사설 IP `192.168.219.52/24`는 런타임과 영구 설정 모두에서 제거됐다.
|
|
||||||
|
|
||||||
## 24서버 관점에서 남길 운영 메모
|
|
||||||
- 이번 24 서버 장애는 "네트워크가 잠깐 이상했다"로 끝나는 사건이 아니라, 과거 IP `192.168.219.52`가 실제 NetworkManager 설정과 실행 경로에 남아 있으면 언제든 다시 살아날 수 있다는 점을 보여줬다.
|
|
||||||
- 즉 24 서버도 51123과 같은 원칙을 따라야 한다. 현재 운영 주소는 `192.168.0.106`만 SSOT로 취급하고, 코드 기본값, compose fallback, 운영 문서, 수동 명령 예시에서 과거 IP `192.168.219.52`를 병행 허용하면 안 된다.
|
|
||||||
- 특히 23 서버에서 24 서버를 호출하는 URL, 24 서버 내부 서비스의 자기참조 URL, 배포 스크립트, health check, SSH 접속 예시는 모두 `192.168.0.106` 또는 별도 의미 있는 환경변수만 바라보게 정리해야 한다.
|
|
||||||
- 한쪽 서버만 SSOT를 맞추고 다른 쪽에 과거 IP fallback을 남겨두면, 평상시에는 조용하다가 재배포, 장애 복구, env 누락 시점에 다시 옛 경로로 접속을 시도하는 구조적 재발 조건이 된다.
|
|
||||||
- 따라서 24 서버 기준 완료 조건도 "주소가 바뀌었다"가 아니라, 실행 경로에서 `192.168.219.52` literal 검색 결과가 운영 파일 기준 0건이 되는 상태로 본다.
|
|
||||||
|
|
||||||
## 재발 방지
|
## 재발 방지
|
||||||
- 24 서버에서 시스템 `python3` 링크를 변경하지 않는다.
|
- 24 서버에서 시스템 `python3` 링크를 변경하지 않는다.
|
||||||
- 개발용 Python 3.13은 `venv` 또는 명시적 바이너리 경로로만 사용한다.
|
- 개발용 Python 3.13은 `venv` 또는 명시적 바이너리 경로로만 사용한다.
|
||||||
- 고정 IP를 운용할 때는 현재 LAN 대역과 SSOT를 먼저 대조하고, 과거 대역의 잔존 주소를 제거한다.
|
- 고정 IP를 운용할 때는 현재 LAN 대역과 SSOT를 먼저 대조하고, 과거 대역의 잔존 주소를 제거한다.
|
||||||
- Node 기반 전역 CLI는 `#!/usr/bin/env node` shebang에 의존할 때 사용자별 PATH 차이로 런타임 충돌이 날 수 있으므로, 시스템이 먼저 찾는 `node` 경로 자체를 지원 버전으로 유지한다.
|
|
||||||
- GUI 터미널 불가 시에는 바로 재설치부터 하지 말고 `TTY 진입 -> 네트워크 확인 -> 시스템 Python 확인 -> apt 복구` 순서로 본다.
|
- GUI 터미널 불가 시에는 바로 재설치부터 하지 말고 `TTY 진입 -> 네트워크 확인 -> 시스템 Python 확인 -> apt 복구` 순서로 본다.
|
||||||
- 23 서버에서는 `/etc/logrotate.d/` 아래에 운영 중인 설정의 백업 파일을 같은 확장자 없이 남기지 않는다.
|
- 23 서버에서는 `/etc/logrotate.d/` 아래에 운영 중인 설정의 백업 파일을 같은 확장자 없이 남기지 않는다.
|
||||||
|
|
||||||
## 후속 권장 작업
|
## 후속 권장 작업
|
||||||
- 24 서버에서 `node` 경로를 바꿀 일이 생기면 `/usr/local/bin/node`와 `happybell80`의 NVM 기본 버전이 함께 맞는지 점검한다.
|
- 24 서버의 네트워크 설정 파일에서 `192.168.219.52/24`가 다시 붙지 않도록 영구 설정 위치를 확인한다.
|
||||||
- 24 서버에서 Python 3.13이 필요한 프로젝트가 있으면 시스템 링크 변경 없이 가상환경으로 분리한다.
|
- 24 서버에서 Python 3.13이 필요한 프로젝트가 있으면 시스템 링크 변경 없이 가상환경으로 분리한다.
|
||||||
- 24 서버에서 Codex/Node를 업데이트할 때는 `/usr/local/bin/node`, `/usr/local/bin/codex`, `happybell80`의 NVM 기본 버전이 함께 일치하는지 점검한다.
|
|
||||||
- 23/24 공통 운영 기준 문서에 "Ubuntu 22.04 시스템 Python 변경 금지"를 반복 규칙으로 승격할지 검토한다.
|
- 23/24 공통 운영 기준 문서에 "Ubuntu 22.04 시스템 Python 변경 금지"를 반복 규칙으로 승격할지 검토한다.
|
||||||
- 23 서버의 남은 패키지 업데이트 `2건`(`network-manager-openvpn`, `network-manager-openvpn-gnome`)은 영향 시간대 확인 후 반영 여부를 결정한다.
|
- 23 서버의 남은 패키지 업데이트 `2건`(`network-manager-openvpn`, `network-manager-openvpn-gnome`)은 영향 시간대 확인 후 반영 여부를 결정한다.
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user