← 글 목록

notes

Jenkins - Publish over SSH

Jenkins Publish over SSH 플러그인 설정·원격 배포 주의점 메모.

  • Jenkins 컨테이너에 ssh 클라이언트와 키를 먼저 준비한다
  • webhook 은 Payload URL 끝 슬래시와 방화벽에서 제일 많이 막힌다
  • GitHub webhook IP 대역은 바뀌니 규칙 만들 때마다 다시 확인한다

Publish over SSH 란

Untitled

사전 처리 항목은 위 페이지에 따로 정리해 뒀다.

Publish Over SSH 는 Jenkins 에서 빌드한 결과물을 원격 서버로 보내고 거기서 명령까지 실행하게 해 주는 플러그인이다. 서버에 직접 들어가서 파일 올리고 재시작하던 걸 빌드 끝에 붙일 수 있다.

컨테이너 준비

Jenkins 를 Docker 로 띄웠으면 컨테이너 안에 ssh 클라이언트가 있어야 한다. Dockerfile 에 openssh-client 를 넣는다.

#  open ssh 설치
RUN apt-get update &&\
    apt-get upgrade -y &&\
    apt-get install -y openssh-client

볼륨은 세 개를 잡았다. Jenkins 홈, 호스트의 .ssh 폴더, Docker 소켓이다. .ssh 를 컨테이너 /root/.ssh 에 연결해 두면 호스트에서 만든 키를 그대로 쓸 수 있다.

volumes:
- /home/dolfkang/jenkins:/var/jenkins_home
- /home/dolfkang/.ssh:/root/.ssh
- /var/run/docker.sock:/var/run/docker.sock

플러그인 설치

Jenkins 관리로 들어가서 Plugins 에서 Publish Over SSH 를 찾아 설치한다.

SSH 키 만들기

키가 아직 없으면 호스트에서 만든다. 개인키는 Jenkins 에 넣고, 공개키는 배포 서버 authorized_keys 에 넣는다. 새로 만든다면 rsa 대신 ed25519 를 써도 된다.

키 생성과 권한 설정
# SSH 키 생성
ssh-keygen -t rsa -b 4096 -C "your-email@example.com"

# 키 생성 시 나오는 질문들:
# Enter file in which to save the key (/home/dolfkang/.ssh/id_rsa): [엔터]
# Enter passphrase (empty for no passphrase): [엔터]
# Enter same passphrase again: [엔터]

# 키가 생성되었는지 확인
ls -la ~/.ssh/
# id_rsa (개인키)
# id_rsa.pub (공개키) 두 파일이 생긴다

# 개인키 확인 (이 내용을 Jenkins 에 넣는다)
cat ~/.ssh/id_rsa

# 권한 설정
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pub

공개키는 배포 서버에 이렇게 올린다.

ssh-copy-id -i ~/.ssh/id_rsa.pub user@배포서버

SSH 서버 등록

Jenkins 관리 > System (예전 이름은 Configure System) 으로 가서 Publish over SSH 항목에 개인키를 넣고, 아래 SSH Servers 에 배포 서버를 추가한다.

Hostname 에는 서버 IP 나 도메인을 적고, Username 이랑 Remote Directory 를 채운 다음 Test Configuration 으로 접속되는지 확인한다.

webhook 을 받으려면 같은 화면의 GitHub 항목에 GitHub Server 도 추가해 둔다.

GitHub webhook 연결

GitHub 저장소 Settings > Webhooks > Add webhook 에서 Jenkins 주소를 등록한다. 프로젝트 설정의 Build Triggers 에서는 GitHub hook trigger for GITScm polling 을 켠다.

Payload URL 에는 http:// 나 https:// 부터 Jenkins 서버 IP 또는 도메인, 포트까지 적고 끝에 /github-webhook/ 을 붙인다. 마지막 슬래시가 빠지면 전달이 안 된다. Content type 은 application/json 으로 두고 이벤트를 고른 다음 Update webhook 버튼을 클릭

GitHub 가 webhook 을 보내는 IP 는 하나가 아니라 여러 대역이고, api.github.com/meta 의 hooks 항목에 최신 목록이 있다.

내 서버는 Jenkins 를 13002 포트로 열어 둬서 URL 에도 13002 를 적었다. 포트가 하나만 틀려도 전달이 안 된다. 필요하면 Secret 도 여기서 같이 정한다.

방화벽

webhook 이 안 들어오면 방화벽부터 본다. Jenkins 포트를 GitHub webhook 대역에만 열어 뒀다.

이 목록은 고정이 아니다. 지금 meta 의 hooks 에는 아래 IPv4 네 개 말고도 9.234 로 시작하는 /28 대역 세 개랑 IPv6 대역이 같이 올라와 있다. 규칙을 만들기 전에 한 번 확인하고 맞춰 넣는다.

firewalld, iptables 규칙
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.30.252.0/22" port port=8080 protocol=tcp accept'
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="185.199.108.0/22" port port=8080 protocol=tcp accept'
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="140.82.112.0/20" port port=8080 protocol=tcp accept'
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="143.55.64.0/20" port port=8080 protocol=tcp accept'
sudo firewall-cmd --reload



# GitHub Webhook IP 대역 허용
iptables -A INPUT -p tcp -s 192.30.252.0/22 --dport 8080 -j ACCEPT
iptables -A INPUT -p tcp -s 185.199.108.0/22 --dport 8080 -j ACCEPT
iptables -A INPUT -p tcp -s 140.82.112.0/20 --dport 8080 -j ACCEPT
iptables -A INPUT -p tcp -s 143.55.64.0/20 --dport 8080 -j ACCEPT


서비스: TCP
포트: 8080
허용 IP:
- 192.30.252.0/22
- 185.199.108.0/22
- 140.82.112.0/20
- 143.55.64.0/20

소스 코드 관리

프로젝트 Configure 의 Source Code Management 에서 Git 을 고르고 Repository URL 에 저장소 주소, Credentials 에 GitHub 인증 정보를 넣는다. Branch Specifier 를 */main 으로 두면 main 브랜치 변경만 보고 빌드한다.