- Published on
Jenkins 에이전트 오프라인 원인·복구 10분
- Authors
- Name
- 스타차일드
- https://x.com/ETFBITX
서버가 멀쩡해 보이는데 Jenkins에서만 에이전트가 Offline 으로 보이면, 대개 원인은 단순합니다. 네트워크/포트, 자바 프로세스, 디스크/메모리, 인증(키/토큰/인증서), 컨테이너 런타임 중 하나가 끊겼는데, Jenkins UI 메시지만으로는 힌트가 부족한 경우가 많습니다.
이 글은 “10분 안에” 원인을 좁히고 복구하는 것을 목표로 합니다. 에이전트 유형(SSH, JNLP, Kubernetes/Docker 등)에 따라 확인 포인트가 조금씩 다르지만, 공통 진단 흐름은 같습니다.
0. 10분 복구 플로우(요약)
아래 순서대로만 따라가면 대부분의 케이스가 잡힙니다.
- Jenkins UI에서 에이전트 로그/오프라인 사유 확인
Manage Jenkins→Nodes→ 해당 노드 →Log- 오프라인 원인 문구(예:
Channel closed,Connection timed out,No route to host,Disk full)를 먼저 확보
- 컨트롤러에서 에이전트까지 네트워크/포트 확인
- SSH 방식이면
22포트 - JNLP(인바운드)면 에이전트가 컨트롤러의
TCP agent port로 접속
- 에이전트 머신에서 자원(디스크/메모리) 확인
- 디스크 100%면 에이전트 프로세스가 죽거나 워크스페이스 쓰기 실패로 쉽게 오프라인
- 인증/키/토큰/인증서 확인
- SSH 키 변경, known_hosts 문제, JNLP secret 갱신, TLS 체인 변경
- 에이전트 프로세스 재기동
systemd서비스 또는 컨테이너 재시작
1. Jenkins에서 먼저 봐야 하는 로그 포인트
1) 노드 로그(Node Log)
노드 상세 화면의 로그는 “왜 끊겼는지”를 가장 빠르게 알려줍니다.
자주 나오는 패턴:
java.io.EOFException/Channel closed: 네트워크 단절, 에이전트 프로세스 종료, 프록시/로드밸런서 idle timeoutConnection timed out: 방화벽/보안그룹/라우팅/포트 문제Host key verification failed: SSH known_hosts 불일치No space left on device: 디스크 100%
2) 컨트롤러 시스템 로그
컨트롤러 쪽에서도 에이전트 연결 문제를 더 자세히 볼 수 있습니다.
Manage Jenkins→System Log- 또는 컨테이너/서버 로그
예시(리눅스 패키지 설치형 Jenkins):
sudo journalctl -u jenkins -n 200 --no-pager
2. 네트워크/포트: “연결이 되나?”를 1분 안에 확인
오프라인의 절반은 네트워크/포트입니다.
SSH 에이전트인 경우(컨트롤러가 에이전트로 접속)
컨트롤러에서 에이전트로 SSH가 되는지 확인합니다.
ssh -vvv -o BatchMode=yes -o ConnectTimeout=5 jenkins@AGENT_IP 'echo ok'
Connection timed out이면 보안그룹/방화벽/라우팅Permission denied (publickey)이면 키/계정/권한Host key verification failed이면 known_hosts
known_hosts 이슈는 다음처럼 정리합니다.
ssh-keygen -R AGENT_IP
ssh-keyscan -H AGENT_IP >> ~/.ssh/known_hosts
JNLP(인바운드) 에이전트인 경우(에이전트가 컨트롤러로 접속)
이 경우는 반대로 “에이전트에서 컨트롤러로 나가는” 연결을 확인해야 합니다.
컨트롤러에서 TCP agent port 설정을 확인:
Manage Jenkins→Security→TCP port for inbound agents
에이전트 머신에서 포트 연결 확인:
nc -vz JENKINS_URL_HOST 50000
- 연결이 안 되면 방화벽/보안그룹/프록시 정책을 의심
- 특히 사내망에서 프록시가
WebSocket또는 특정 TCP 포트를 막는 경우가 많습니다
3. 디스크/메모리: 에이전트가 “죽는” 가장 흔한 시스템 원인
에이전트는 빌드 산출물, 체크아웃, 캐시로 디스크를 금방 채웁니다. 디스크가 100%면 다음이 연쇄적으로 발생합니다.
- 워크스페이스 쓰기 실패
- Docker 이미지/레이어 풀 실패
- 로그 기록 실패
- 결국 에이전트 프로세스 종료 또는 Jenkins가 헬스체크 실패로 오프라인
1) 디스크 사용량 확인
df -h
sudo du -h -d 1 /var/lib/jenkins | sort -h | tail -n 20
Docker를 쓰면 다음도 확인합니다.
docker system df
정리(주의: 운영 영향 가능):
docker system prune -af
디스크가 100%인데 df -h 상 여유가 있어 보이면 inode 고갈일 수 있습니다.
df -i
inode 고갈 진단/복구는 아래 글이 체크리스트로 좋습니다.
2) 메모리/프로세스 확인
free -h
ps aux --sort=-%mem | head
journalctl -n 200 --no-pager | tail -n 50
OOM 킬이 있었다면 커널 로그에 흔적이 남습니다.
dmesg -T | egrep -i 'oom|killed process' | tail -n 50
4. 에이전트 프로세스 자체가 살아있나?
systemd 서비스로 띄운 에이전트
에이전트 호스트에서 상태를 확인합니다.
sudo systemctl status jenkins-agent --no-pager
sudo journalctl -u jenkins-agent -n 200 --no-pager
재시작:
sudo systemctl restart jenkins-agent
수동 실행(JNLP)이라면 프로세스 확인
ps aux | grep -i agent.jar | grep -v grep
없다면 죽은 것입니다. 보통은 서비스화 해두는 편이 복구가 빠릅니다.
5. JNLP 에이전트: secret/URL/TLS에서 자주 미끄러진다
JNLP 에이전트는 대개 이런 형태로 실행합니다.
java -jar agent.jar \
-url https://jenkins.example.com/ \
-secret JNLP_SECRET \
-name agent-01 \
-workDir /var/lib/jenkins
1) secret 갱신/노드 재생성
- 노드를 삭제 후 재생성했는데 예전 secret으로 실행하면 바로 실패합니다.
- 노드 화면에서 제공하는 최신 커맨드를 그대로 복사하는 것이 가장 확실합니다.
2) TLS/인증서 체인 변경
사내 CA 교체, 프록시 SSL 검사 등으로 자바가 인증서를 신뢰하지 못하면 연결이 실패합니다.
에러 예:
PKIX path building failed
해결 방향:
- 자바 truststore에 CA 추가
- 또는 프록시 SSL 검사 예외 처리
6. SSH 에이전트: 키/권한/known_hosts가 80%
SSH 방식은 Jenkins 컨트롤러가 에이전트에 로그인합니다.
1) Jenkins Credentials의 키가 바뀌었나?
- 에이전트 OS 계정의
authorized_keys변경 - Jenkins에 등록된 private key 교체 누락
2) sudo/권한 문제
빌드에서 Docker를 쓰는데 에이전트 계정이 docker 그룹에 없으면, 빌드 실패 후 재시도 과정에서 에이전트 상태가 불안정해지는 경우가 있습니다.
id jenkins
getent group docker
7. Docker/컨테이너 기반 에이전트: “컨테이너가 떠있나?”부터
Docker로 에이전트를 띄우면 컨테이너 재시작 정책, 디스크 압박, 이미지 풀 실패가 원인인 경우가 많습니다.
docker ps -a --filter name=jenkins-agent
docker logs --tail 200 jenkins-agent
Kubernetes 에이전트(동적 Pod)라면:
kubectl get pod -n jenkins
kubectl describe pod -n jenkins POD_NAME
kubectl logs -n jenkins POD_NAME --tail=200
특히 Pod는 Running 인데 실제로 서비스가 안 되는 것처럼, “겉보기 상태”와 “실제 준비 상태”가 다를 때가 있습니다. 쿠버네티스 트러블슈팅 감각을 잡는 데는 아래 글의 점검 흐름도 참고할 만합니다.
8. 프록시/로드밸런서 idle timeout: 연결은 되는데 자주 끊긴다
증상:
- 빌드가 한동안 없다가 다음 빌드 때 에이전트가
Offline - 로그에
Channel closed가 반복
원인 후보:
- L4/L7 로드밸런서 idle timeout
- NAT 게이트웨이/방화벽 세션 타임아웃
- 프록시가 WebSocket 또는 장기 TCP 연결을 끊음
대응:
- JNLP 인바운드 포트(예:
50000)를 LB 뒤에 두지 않기 - WebSocket 모드 지원 여부 확인
- keepalive 설정(SSH keepalive, TCP keepalive) 조정
SSH keepalive 예:
# ~/.ssh/config
Host AGENT-*
ServerAliveInterval 30
ServerAliveCountMax 3
9. 10분 안에 “복구”까지 하는 실전 체크리스트
1) UI에서 오프라인 사유/로그 캡처
- 노드 로그 30줄만 봐도 방향이 정해집니다.
2) 네트워크 확인
- SSH:
ssh -vvv ... - JNLP:
nc -vz host port
3) 자원 확인
df -h
free -h
디스크가 가득 찼다면 우선순위는 “빌드 재개”입니다.
- 워크스페이스/캐시 정리
- Docker prune
- 필요 시 디스크 증설
4) 에이전트 재기동
- systemd면
restart - 컨테이너면
restart
5) 재발 방지(최소 조치)
- 워크스페이스/캐시 주기 정리
- 에이전트 헬스체크(디스크 80% 알람)
- JNLP secret/노드 템플릿 변경 시 운영 절차화
디스크/네트워크 같은 “기초 체력” 문제는 다른 장애에서도 반복됩니다. 예를 들어 SSH 타임아웃을 10분 안에 좁혀가는 방식은 Jenkins 에이전트 네트워크 문제에도 그대로 적용됩니다.
10. 부록: 상황별 에러 메시지와 즉시 액션
Host key verification failed
- 액션: 컨트롤러의 known_hosts 정리 후 재시도
ssh-keygen -R AGENT_IP
ssh-keyscan -H AGENT_IP >> ~/.ssh/known_hosts
Permission denied (publickey)
- 액션: Jenkins Credentials의 private key와 에이전트
authorized_keys일치 확인
java.io.EOFException / Channel closed
- 액션: 네트워크 idle timeout 의심, 에이전트 로그에서 종료 시점 확인, keepalive 또는 LB 경로 제거
No space left on device
- 액션:
df -h와df -i확인 후 workspace/Docker 정리
df -h
df -i
PKIX path building failed
- 액션: 자바 truststore에 CA 추가 또는 프록시 SSL 검사 예외
마무리
Jenkins 에이전트 오프라인은 “복잡한 Jenkins 문제”라기보다, 대부분은 네트워크/자원/인증 중 하나가 끊긴 결과입니다. 노드 로그에서 단서를 잡고, 연결 확인과 디스크 확인을 2~3분 안에 끝내면 복구까지 10분 내에 가능한 케이스가 많습니다.
다음 단계로는 오프라인이 반복되는 노드에 대해 (1) 디스크 알람, (2) 에이전트 프로세스 서비스화, (3) LB/프록시 경로 제거, (4) 주기적 캐시 정리까지 묶어두면 재발률이 크게 떨어집니다.