diff --git a/deploys/ops-manual/01-server-overview.md b/deploys/ops-manual/01-server-overview.md index 545e608..eeced64 100644 --- a/deploys/ops-manual/01-server-overview.md +++ b/deploys/ops-manual/01-server-overview.md @@ -156,7 +156,7 @@ | Prometheus | 2.51.0 | 9090 | - (localhost only) | | Grafana | - | 3100 | monitor.sam.it.kr | | node_exporter | 1.8.2 | 9100 | - | -| Java | OpenJDK 17.0.18 | - | Jenkins 런타임 | +| Java | OpenJDK 21.0.10 | - | Jenkins 런타임 | | Certbot | - | - | SSL 자동 갱신 | | fail2ban | - | - | SSH 보호 | @@ -180,6 +180,8 @@ | Nginx 사이트 | /etc/nginx/sites-available/{ci,git,monitor}.sam.it.kr | | Jenkins 홈 | /var/lib/jenkins/ | | Jenkins JVM 설정 | /etc/systemd/system/jenkins.service.d/override.conf | +| Jenkins Agent | /var/lib/jenkins-agent/ (workspace, agent.jar) | +| Jenkins Agent 서비스 | /etc/systemd/system/jenkins-agent.service | | Jenkins 환경파일 | /var/lib/jenkins/env-files/react/.env.{develop,stage,main} | | Gitea 설정 | /etc/gitea/app.ini | | Gitea 저장소 | /var/lib/gitea/data/repositories/ | diff --git a/deploys/ops-manual/04-service-cicd.md b/deploys/ops-manual/04-service-cicd.md index be941ac..bcc5189 100644 --- a/deploys/ops-manual/04-service-cicd.md +++ b/deploys/ops-manual/04-service-cicd.md @@ -20,14 +20,17 @@ sudo systemctl status jenkins | 파일 | 용도 | |------|------| | /var/lib/jenkins/ | Jenkins 홈 (jobs, plugins, credentials) | -| /etc/systemd/system/jenkins.service.d/override.conf | JVM 메모리 설정 | +| /etc/systemd/system/jenkins.service.d/override.conf | JVM 옵션 (메모리, CSP) | | /var/lib/jenkins/env-files/ | 배포 환경변수 (.env 파일) | +| /var/lib/jenkins-agent/ | Agent 워크스페이스 (빌드 실행 격리) | +| /etc/systemd/system/jenkins-agent.service | Agent systemd 서비스 | -**JVM 메모리 설정:** +**JVM 설정:** ```bash # /etc/systemd/system/jenkins.service.d/override.conf -# Environment="JAVA_OPTS=-Xmx2048m -Xms512m -Djava.awt.headless=true" +# - 메모리: -Xmx2048m -Xms512m +# - CSP: DirectoryBrowserSupport.CSP (workspace 브라우저 보안) # 변경 후 적용 sudo systemctl daemon-reload @@ -75,16 +78,46 @@ sudo journalctl -u jenkins --since "2 hours ago" --no-pager 플러그인 업데이트 후 Jenkins 재시작이 필요한 경우: `sudo systemctl restart jenkins` +### Build Agent (분산 빌드) + +Built-in Node의 executor는 0으로 설정되어 있으며, 빌드는 로컬 Agent(`local-agent`)에서 실행된다. + +| 항목 | 값 | +|------|-----| +| Agent 이름 | local-agent | +| Workspace | /var/lib/jenkins-agent/ | +| Executor 수 | 2 | +| 라벨 | build | +| 연결 방식 | WebSocket (Inbound) | + +**서비스 제어:** + +```bash +sudo systemctl start jenkins-agent +sudo systemctl stop jenkins-agent +sudo systemctl restart jenkins-agent +sudo systemctl status jenkins-agent + +# Agent 로그 +sudo journalctl -u jenkins-agent -f +``` + +> **참고**: Jenkins 마스터 재시작 시 Agent가 자동 재연결된다. Agent가 연결 실패하면 `sudo systemctl restart jenkins-agent`로 수동 재시작. + ### Workspace 정리 ```bash -# 용량 확인 -sudo du -sh /var/lib/jenkins/workspace/* +# Agent workspace 용량 확인 +sudo du -sh /var/lib/jenkins-agent/workspace/* # 특정 workspace 삭제 -sudo rm -rf /var/lib/jenkins/workspace/ +sudo rm -rf /var/lib/jenkins-agent/workspace/ # 전체 workspace 정리 (빌드 중이 아닌지 확인 후) +sudo rm -rf /var/lib/jenkins-agent/workspace/* + +# 레거시 Built-in workspace (이전 빌드 잔존 시) +sudo du -sh /var/lib/jenkins/workspace/* sudo rm -rf /var/lib/jenkins/workspace/* # 임시 파일 정리 diff --git a/deploys/ops-manual/11-server-setup.md b/deploys/ops-manual/11-server-setup.md index ef87eeb..e161efc 100644 --- a/deploys/ops-manual/11-server-setup.md +++ b/deploys/ops-manual/11-server-setup.md @@ -580,7 +580,7 @@ stage-api.sam.it.kr은 api.sam.it.kr과 동일 구조 (소켓: php8.4-fpm-api-st |------|------|--------| | ① | OS 기본 셋팅 (UFW, 스왑, 타임존) | - | | ② | MySQL 8.4 | ① | -| ③ | Java 17 (Jenkins 런타임) | ① | +| ③ | Java 21 (Jenkins 런타임) | ① | | ④ | Gitea | ② | | ⑤ | 개발서버 post-receive hook 설정 | ④ | | ⑥ | Jenkins | ③ | @@ -626,13 +626,19 @@ GRANT ALL PRIVILEGES ON *.* TO 'hskwon'@'localhost' WITH GRANT OPTION; FLUSH PRIVILEGES; ``` -### ③ Java 17 +### ③ Java 21 ```bash -sudo apt install -y openjdk-17-jre-headless +sudo apt install -y openjdk-21-jre-headless java -version +# openjdk version "21.0.x" 확인 + +# 여러 버전 설치 시 기본 Java 전환 +sudo update-alternatives --set java /usr/lib/jvm/java-21-openjdk-amd64/bin/java ``` +> **참고**: Java 17은 2026-03-31 Jenkins 지원 종료. Java 21 사용 필수. + ### ④ Gitea ```bash @@ -746,11 +752,11 @@ done | 저장소 | hook 대상 브랜치 | 동작 | |--------|-----------------|------| -| sam-react-prod | stage, develop | CI/CD Gitea에 push | -| sam-api | stage | CI/CD Gitea에 push | +| sam-react-prod | main, develop | CI/CD Gitea에 push | +| sam-api | main | CI/CD Gitea에 push | +| sam-manage | main | CI/CD Gitea에 push (2026-02-24 추가) | | sam-sales | main | CI/CD Gitea에 push | | sam-landing | main | CI/CD Gitea에 push | -| sam-manage | ❌ 없음 | main만 사용, 배포관리자 수동 push | ### ⑥ Jenkins @@ -765,11 +771,11 @@ echo "deb [signed-by=/usr/share/keyrings/jenkins-keyring.gpg]" \ sudo apt update sudo apt install -y jenkins -# JVM 메모리 제한 +# JVM 옵션 (메모리 + CSP) sudo mkdir -p /etc/systemd/system/jenkins.service.d sudo tee /etc/systemd/system/jenkins.service.d/override.conf > /dev/null << 'EOF' [Service] -Environment="JAVA_OPTS=-Xmx2048m -Xms512m -Djava.awt.headless=true" +Environment="JAVA_OPTS=-Xmx2048m -Xms512m -Djava.awt.headless=true -Dhudson.model.DirectoryBrowserSupport.CSP=\"default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:;\"" EOF sudo systemctl daemon-reload @@ -810,6 +816,64 @@ sudo -u jenkins ssh-keyscan -H 114.203.209.83 >> /var/lib/jenkins/.ssh/known_hos - `deploy-ssh-key`: SSH 키 (hskwon@운영/개발 서버 공용) - `gitea-api-token`: Gitea API 토큰 +**분산 빌드 설정 (Built-in Node 보안 격리):** + +```bash +# 1. Built-in Node executor를 0으로 변경 (Jenkins 정지 상태에서) +sudo systemctl stop jenkins +sudo sed -i 's|2|0|' /var/lib/jenkins/config.xml +# Agent 포트 활성화 (0 = 랜덤 포트) +sudo sed -i 's|-1|0|' /var/lib/jenkins/config.xml + +# 2. Agent workspace 디렉토리 +sudo mkdir -p /var/lib/jenkins-agent/workspace +sudo chown -R jenkins:jenkins /var/lib/jenkins-agent + +# 3. Agent 노드 설정 +sudo mkdir -p /var/lib/jenkins/nodes/local-agent +# config.xml 생성 (JNLP WebSocket, executor 2, label: build) +sudo chown -R jenkins:jenkins /var/lib/jenkins/nodes/local-agent + +# 4. Jenkins 시작 → Agent secret 확인 (UI 또는 Groovy 스크립트) +sudo systemctl start jenkins + +# 5. Agent jar 다운로드 +sudo curl -sL http://localhost:8080/jnlpJars/agent.jar -o /var/lib/jenkins-agent/agent.jar +sudo chown jenkins:jenkins /var/lib/jenkins-agent/agent.jar + +# 6. Agent systemd 서비스 +sudo tee /etc/systemd/system/jenkins-agent.service > /dev/null << 'AGENTEOF' +[Unit] +Description=Jenkins Build Agent +After=network.target jenkins.service +Wants=jenkins.service + +[Service] +Type=simple +User=jenkins +Group=jenkins +WorkingDirectory=/var/lib/jenkins-agent +ExecStart=/usr/bin/java -jar /var/lib/jenkins-agent/agent.jar \ + -url http://localhost:8080/ \ + -secret \ + -name local-agent \ + -workDir /var/lib/jenkins-agent \ + -webSocket +Restart=always +RestartSec=10 + +[Install] +WantedBy=multi-user.target +AGENTEOF + +sudo systemctl daemon-reload +sudo systemctl enable jenkins-agent +sudo systemctl start jenkins-agent +``` + +> **참고**: Agent secret은 Jenkins UI > Manage Jenkins > Nodes > local-agent에서 확인하거나, +> init.groovy.d 스크립트로 추출 가능. + ### ⑦ Nginx + SSL (CI/CD) **리버스 프록시 설정:**