데브옵스는 소프트웨어의 개발(development)과 운영(Operations)의 합성어로 소프트웨어 개발자와 정보기술 전문가 간의 소통, 협업 및 통합을 강조하는 개발환경이나 문화를 말한다.
소프트웨어 엔지니어링에서 CI/CD는 통합과 전달/배포의 결합된 방식이다.
CI(Continuous Integration): 작은 변경 사항을 메인 브랜치로 자주 병합
(패키징, 빌드, 테스트 과정)
CD(Continuous Delivery): 소프트웨어를 빠른 속도와 빈도로 짧은 주기로 생산하여 언제든지 신뢰할 수 있는 소프트웨어를 출시할 수 있도록하고 배포를 결정할 때 간단하고 반복가능한 배포 프로세스를 사용
(도커 이미지로 제작, 저장소에 push)
CD(Continuous Deployment): 소프트웨어 기능이 완전히 자동으로 롤아웃
(실질적인 프로덕션 서버에 k8s로 리소스 배포)
젠킨스는 오픈소스 자동화 서버이다. 이는 빌드, 테스트 및 배포와 관련된 소프트웨어 개발 부분을 자동화하여 지속적인 통합 및 지속적인 전달을 촉진한다. Apache Tomcat 과 같은 서블릿 컨테이너 에서 실행되는 서버 기반 시스템이다.
Pipeline-as-code 및 Jenkinsfile을 지원하는 새 젠킨스 버전
DSL(Domain-Specific Language):
이름: Jenkins, 우분투 20.4 이미지, t3 medium, 보안그룹: SSH, HTTP, TCP 8080, 키페어 등록, 스토리지: 40G 로 설정한 이후 인스턴스를 생성한다.
cd .\Users\shin\Downloads\
PS C:\Users\shin\Downloads> ssh ubuntu@3.37.130.209 -i .\mykey.pem
# 이름 변경
sudo hostnamectl set-hostname jenkins
exec bash
sudo apt update
# 자바 설치
sudo apt install -y openjdk-11-jdk
java -version
# Long Term Support release로 설치
curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo tee \
/usr/share/keyrings/jenkins-keyring.asc > /dev/null
echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] \
https://pkg.jenkins.io/debian-stable binary/ | sudo tee \
/etc/apt/sources.list.d/jenkins.list > /dev/null
sudo apt-get update
sudo apt-get install -y jenkins
# 실행 확인
systemctl status jenkins
내부에 톰켓을 가지고 있고 war파일로 구성되어 있는 것을 확인
새 Jenkins 인스턴스에 처음 액세스하면 자동으로 생성된 암호를 사용하여 잠금을 해제하라는 메시지가 표시된다.
localhost:8080 (또는 Jenkins를 설치할 때 구성한 포트)하고 Jenkins 잠금 해제 페이지가 나타날 때까지 기다린다.
명령: sudo cat /var/lib/jenkins/secrets/initialAdminPassword 콘솔에서 암호를 인쇄한다.
Jenkins 잠금 해제 페이지에서 이 암호를 관리자 암호 필드에 붙여넣고 계속을 클릭한다.
제안된 플러그인 설치 - 가장 일반적인 사용 사례를 기반으로 하는 권장 플러그인 세트를 설치한다.
첫 번째 관리 사용자 만들기 페이지가 나타나면 해당 필드에 관리자 사용자의 세부 정보를 지정하고 저장 및 완료를 클릭한다. Jenkins 준비 완료 페이지가 나타나면 Start using Jenkins를 클릭한다.(계정명: admin으로 지정)
젠킨스에서 사용가능한 플러그인들을 찾을 수 있다.
젠킨스 플러그인 검색 사이트
item: 하나의 프로젝트를 의미, 자동화
아이템 만들기
Freestyle project
git - 저장소 주소: https://github.com/c1t1d0s7/source-maven-java-spring-hello-webapp
Branch Specifier - */main
Build Steps - Execute shell: echo "hello wolrd" > hello.txt
Apply -> 저장
지금 빌드를 클릭하면 저장한 프로젝트가 실행된다. 첫단계 실행이기에 #1로 나온다. 들어가서 Console Output를 확인하면 로그를 볼 수 있다.
# jenkins 계정으로 전환
sudo -i -u jenkins
# 경로
pwd
# 저장소를 클론해온 것
cd ~/workspace/test_project
# 저장소와 동일
ls
# 명령어를 실행한 결과파일이 존재
cat hello.txt
젠킨스 컨셉
기본적인 컨셉은 명령어로 실행하는 것을 젠킨스 대쉬보드에서 적용시켜두고 자동으로 빌드되도록 하는 것이다. 즉 어떤 명령어를 어떻게 실행시킬 것인지만 구성하면 그 과정을 알아서 자동으로 진행하도록 하는 것이다.
포크는 원래 "업스트림" 리포지토리와 코드 및 표시 유형 설정을 공유하는 새 리포지토리이다.
깃허브 포크 방법 설명
기존 위에서 설정했던 깃 저장소의 주소로 들어가 이를 내 저장소로 포크해온다. 그 후 test_project의 구성에서 포크해온 내 저장소의 주소로 URL를 바꿔준다.
지금 빌드를 클릭하면 저장한 프로젝트가 실행된다. #2로 나온 것에 들어가서 Console Output를 확인하면 저장소를 새로 가져온 것과 쉘에서 등록했던 명령들이 실행된 로그를 볼 수 있다.
# 기존 사용자로 돌아와서
exit
sudo apt install -y maven
젠킨스 사이트의 구성에서 쉘 스크립트 수정
mvn clean package
지금 빌드를 실행하면 target이 만들어진다.
상태에서 현재 어떻게 바뀌었는지 작업공간을 확인 가능하다.따라서 jenkins 계정으로 전환하여 매번 들어가서 확인 할 필요가 없다.
플러그인 관리 -> Available plugins -> Maven Integration -> Install without restart
Global Tool Configuration 설정
자바 추가
자바 위치 확인: ls -l which java
, ls -l /etc/alternatives/java(최종 위치 확인)
JAVA_HOME: /usr/lib/jvm/java-11-openjdk-amd64
maven 추가
maven 위치 확인: ls -l which mvn
, ls -l /etc/alternatives/mvn(최종위치 확인)
MAVEN_HOME: /usr/share/maven
새로운 아이템 만들기에 들어가보면 아까전에 보이지 않았던 Maven project가 나타난다.
젠킨스는 빌드를 위한 시스템이고 실제로 서비스를 배포할 시스템을 따로 두려고 한다. 따라서 실제로 서버에 배포하기 위한 서버 생성한다.
이름: Tomcat, 우분투 20.4 이미지, t3 small, 보안그룹: SSH, HTTP, TCP 8080, 키페어 등록, 스토리지: 8G 로 설정한 이후 인스턴스를 생성한다.
# tomcat 인스턴스 접속
ssh ubuntu@43.201.98.136 -i mykey.pem
# 이름 변경
sudo hostnamectl set-hostname tomcat
exec bash
# tomcat9 설치
sudo apt update
sudo apt intall -y tomcat9
scp는 ssh 원격 접속 프로토콜을 기반으로 한 SecureCopy(scp)의 약자로서 원격지에 있는 파일과 디렉터리를 보내거나 가져올 때 사용하는 파일 전송 프로토콜이다.
현재 jenkins 서버와 tomcat 서버는 VPC로 연결이 되어있고 scp/ssh로 서로 접속할 수 있다.
: scp [옵션][파일명] [원격지_id]@[원격지_ip]:[받는 위치]
# 키 생성
ssh-keygen
# 키 확인
ls .ssh
authorized_keys id_rsa id_rsa.pub(공개키)
# 키 복사
cat id_rsa.pub
# 기존 키에 이어서 내용 복붙
vi .ssh/authorized_keys
# tomcat IP 주소로 접속
ssh ubuntu@43.201.98.136
정식적인 방법으로는 ssh-copy-id 명령으로 jenkins의 .pub 공개키를 tomcat 서버의 .ssh/authorized_keys에 등록를 시켜야한다. 하지만 이 명령이 실행되지 않으므로 직접 복사해서 붙여넣는 방식으로 진행한 것이다.
이유
jenkins 서버에서 생성한 공개키 파일이 tomcat 시스템에 등록(복사)이 되어 있어야 하는데 방금 만든 것이라 인증을 할 수 없다. 현재 유일하게 인증 가능한 방법은 인스턴스 생성시 만든 프라이빗 키파일(.pem)에 대한 퍼블릭 키(authorized_keys)만 등록이 되어있다.
# jenkins에서 tomcat으로 파일 복사
scp /var/lib/jenkins/workspace/maven_project/target/hello-world.war ubuntu@172.31.47.106:/var/lib/tomcat9/webapps
-> scp: /var/lib/tomcat9/webapps/hello-world.war: Permission denied
-----------------------------------------
# tomcat 서버에 가서 확인
# 소유자와 소유그룹이 tomcat에만 write 권한이 존재
ls -ld /var/lib/tomcat9/webapps
# tomcat 서버에서 등록
sudo usermod -aG tomcat $USER
# jenkins 서버에서 명령 실행
scp /var/lib/jenkins/workspace/maven_project/target/hello-world.war ubuntu@172.31.47.106:/var/lib/tomcat9/webapps
cd /var/lib/tomcat9/webapps
ls
위에서 생성한 maven_project를 수정해서 사용한다. 배포를 위해 build 다음의 Post stops를 구성한다.
scp /var/lib/jenkins/workspace/maven_project/target/hello-world.war ubuntu@172.31.47.106:/var/lib/tomcat9/webapps
이대로 시작을 하면 현재 빌드는 실패한다.
젠키스라고 하는 자바 어플리케이션을 jenkins라는 사용자가 실행하고 있기 때문에 젠킨스에서 실행하는 모든 작업도 젠킨스의 권한으로 실행된다.
하지만 위는 ubuntu 사용자의 홈디렉터의 .ssh 키를 지정해서 사용했기때문에 젠킨스가 톰켓 서버에 접근할 권한이 없기 때문이다.
# jenkins 사용자 전환
sudo -i -u jenkins
# jenkins의 홈 디렉터리는 /var/lib/jenkins이다.
ssh-keygen
cd .ssh
# 키 내용 복사
cat id_rsa.pub
-----------------------
# tomcat 서버로 가서 복사한 키 내용 추가, 이전에 위에서 추가한 키는 없애준다.
vi .ssh/authorized_keys
위에서 설정했듯이 우분투 사용자는 쓰기권한을 가져야 하기 때문에 tomcat 그룹에 속해있어야 한다.
컨트롤러(마스터): 젠킨스 시스템의 핵심, 모든 설정/옵션/잡(project)에 대해 관리, 다른 시스템이 설정되어 있지 않으면 잡을 실행하는 기본 노드, 가능한 무거운 작업은 노드에서 실행
-> 별도의 노드가 없으면 컨트롤러가 노드의 역할도 함
노드(슬레이브): 컨트롤러에 의해 관리되고 잡을 실행하기 위한 모든(컨트롤러/노드) 시스템, 에이전트가 설치되어 있어야함
에이전트: 컨트롤러에 연결하는 java 클라이언트 프로그램/프로세스
엑시큐터(Executor): 잡을 실행하기 위한 슬롯, 에이전트의 스레드, 해당 노드에서 실행할 수 있는 동시 작업 수
젠킨스 글로벌 도구 (Dashboard > Jenkins > Global Tool Configuration)
컨트롤러나 노드에서 빌드에 필요한 도구 설정, 기본 도구 이외에 플러그인에 의해 추가할 수 있음
젠킨스 플러그인 (Dashboard > Jenkins > 플러그인 관리)
컨트롤러에 설치되며 젠킨스의 기능을 향상시키는 수단이다.
젠킨스 자격증명 (Dashboard > Jenkins > Manage Credentials)
젠킨스는 상호작용할 수 있는 타사 사이트 및 애플리케이션을 위한 자격증명을 구성 할 수 있음, 작업을 위한 인증을 할때 필요한 정보를 저장해둠(ssh, 토큰 등)
이름: jenkins-node, 우분투 20.4 이미지, t3 small, 보안그룹: SSH, HTTP, TCP 8080, 키페어 등록, 스토리지: 40G 로 설정한 이후 인스턴스를 생성한다.
ssh ubuntu@13.124.236.117 -i mykey.pem
# 이름 변경
sudo hostnamectl set-hostname jenkins-node
exec bash
sudo apt update && sudo apt install -y openjdk-11-jdk maven
# 보통 jenkins로 맞춰줌
sudo useradd jenkins -d /var/lib/jenkins -m -s /bin/bash
sudo -i -u jenkins
mkdir .ssh
cd .ssh/
# 키 생성, 내용은 젠키스 사용자의 id_rsa.pub의 내용임
vi authorized_keys
--------
# jenkins 계정의 접속해서 만든 키 복사후 붙여넣기
cat ~/.ssh/id_rsa.pub
# jenkins-node의 프라이빗 IP
ssh jenkins@172.31.37.146
jenkins 관리 -> 노드관리
신규노드를 클릭한 후 노드명(jenkins-node)과 Permanent Agent(영구 agent 허용)을 체크한 후 생성을 진행한다.
보면 노드가 생성이 되었고 이제부터는 이 노드에 일을 시킬 수 있다.
빌드인 노드 설정 : executor: 1개, 라벨: jenkins-controller, Usage: Only build with label...(컨트롤 노드이기에 라벨과 매칭될떄만 사용하게 만듬)
이후 maven 프로젝트를 지금 빌드를 클릭하고 대쉬보드에 가서 보면 이제는 노드에서 작업을 진행하는 것을 볼 수 있다.
jenkins 계정에서 확인해보면 maven_project에 아무것도 없는 것을 볼 수 있다. 즉 저장소가 컨트롤러가 아닌 원격에 있다는 것이다. jenkins-node의 workspace에 내용이 여기에 존재한다.
또한 빌드 결과를 보면 ssh 인증에 실패한 것으로 나온다. 이는 현재 컨트롤러가 노드에게 명령을 내렸고 노드에서 build 작업을 마친 후 tomcat에 접속하려는 것이다. 하지만 노드에서 tomcat에 접근하는 key를 등록를 하지 않았기 때문에 인증이 안되는 것이다. 위에서 등록한 것은 컨트롤러에서 직접 tomcat에 접근하는 인증을 해준 것이다.
# jenkins-node에서 실행
# 현재 계정은 jenkins임
cd ~
ssh-keygen
# 복사
cat .ssh/id_rsa.pub
--------
# tomcat 서버로 가서 진행
# 전에 등록했던 키에 이어서 등록
vi ~/.ssh/authorized_keys
위 내용 복붙
이후 지금 빌드를 실행하면 처음 한번은 실패한다. 그 이유는 처음에 명령어로 노드에서 toncat에 접근할때 지문을 확인한다. 이는 SSH가 PKI구조가 아니여서 제 3자가 공개키를 인증할 수 있는 구조가 아니다. 따라서 처음에 직접 확인해서 등록을 해야된다.
# jenkins-node에서 진행
# 노드에서 톰켓에 접속, 지문에 yes라 답함
ssh ubuntu@172.31.47.106
여기까지 진행한 이후 젠킨스 페이지에서 지금 빌드를 해주면 정상적으로 실행되는 것을 볼 수 있다.
프로젝트안에서 구성에 들어가보면 빌드 유발이라는 것이 있다.
# 스케줄 등록, 매 분마다 확인
*****
깃 배쉬에 접속해서 새로 만든 저장소를 클론해온다. 윈도우 ssh 인증을 하지 않았더라면 다음을 참고
ssh 원격 인증
cd ~
mkdir git
cd git
# 이전에 원도우용 ssh키를 등록했기 때문에 ssh 주소를 이용해서 내 저장소 클론
git clone git@github.com:hsshin0602/source-maven-java-spring-hello-webapp.git
# 클론한 저장소로 이동
cd source-maven-java-spring-hello-webapp
# 확인
git remote -v
내용을 바뀌고 자동으로 빌드를 진행하는지 확인해본다.
# 웹 내용 수정
vi src/main/webapp/WEB-INF/views/index.jsp
-> Version 부분을 1.0.1로 수정해본다.
# 수정한 사항 깃에 푸쉬
git add .
git commit -m 'version: 1.0.1'
git push