CI/CD
CI - Continuous Integration 지속적 통합
CD - Continuous Delivery or Deployment 지속적인 제공 or 배포
CI 목적 - 자동으로 Build/ Test
1. 코드 변경 사항을 주기적으로 빈번하게 Merge 해야 한다
2. 통합을 위한 단계 (Build, Test, Merge) 의 자동화
CI 장점
1. 개발 생산성 향상 -> 코드의 퀄리티 향상
2. 문제점을 빠르게 발견 -> 버그 수정 용이, 문제점을 빠르게 발견
브랜치 전략
* 마스터 브랜치 Main - 배포 가능한 상태만 관리하는 브랜치
* 통합 브랜치 Develop - 다음 배포할 내용들을 개발하는 브랜치
* 기능 브랜치 Feature - 실제 개발이 진행되는 브랜치
CD 목적 - 안정적인 배포
1. CI 이후 프로세스의 자동화
Build, Test 를 통과한 코드를 배포 가능한 상태로 유지
환경에 따라 배포 자동화
2. 사용자에게 빠르고 안정적으로 배포
코드를 신속하게 사용자 환경에 반영
장점
1. 빠른 릴리즈 주기
2. 배포 안정성 증가
3. 개발 생산성 향상
4. 고객 만족도 증가
파이프라인 Pipeline
제공된 데이터 또는 코드에 대해 사전 정의된 작업을 수행하는 일련의 처리 단계
파이프라인의 사용 목적은 반복적인 프로세스를 자동화하여 시간을 절약하고 정밀도를 높이는 것이다
파이프라인이라고 하는 이유는 배포 자동화 과정이 물 흐르듯 흘러가는 것을 묘사해서 그렇게 부른다고 한다
젠킨스 Jenkins 란?
젠킨스는 오픈 소스 자동화 서버로, 소프트웨어 개발 시 지속적으로 통합 서비스를 제공하는 도구이다
모든 언어의 조합과 소스 코드 레포지토리에 대한 CI/CD 환경을 구축하기 위한 도구이다
오픈 소스 자동화 서버이고, 개발자들이 변경 사항의 품질을 신속히 확인하고 문제를 조기에 발견할 수 있도록 돕는다
젠킨스는 Build, Test, Deploy 프로세스를 자동화하여 소프트웨어 품질과 개발 생산성을 높일 수 있다
왜 젠킨스를 사용하는가?
젠킨스는 프로젝트 표준 컴파일 환경에서의 컴파일 오류를 검출해 주고,
정적 코드 분석에 의한 코딩 규약 준수 여부를 체크한다
프로파일링 툴을 이용한 소스 변경에 따른 성능 변화를 감시하며
결합 테스트 환경에 대한 배포 작업도 수행해 준다
자동화 테스트도 젠킨스를 사용해야 하는 가장 큰 이유 중에 하나이다
젠킨스는 Subversion 이나 Git 같은 버전 관리 시스템과 연동하여 코드 변경을 감지하고 자동화 테스트를 수행한다
그래서 Jenkins 를 AWS 에 설치해야 하는데 어떻게 해야 할지 감이 안 잡혀서 여러 블로그를 많이 찾아봤다
1) EC2 서버에 Jenkins 를 설치하고 Gradle 로 빌드하는 방법 (참고) 은
프리티어 용량이 작아서 메모리 스왑을 설정해 줘야 하는데 그래도 속도가 느리다고 한다,
업그레이드하려면 과금이 필요하다 < Jungle 의 예산은 팀 별 AWS Credit $1,000 이다
2) Jenkins 와 Bastion Host 인스턴스를 따로 구축하여 Bastion Host 로 Jump 를 하는 방법 (참고)
3) AWS Session Manager 를 사용하는 방법
우리팀은 비용 절감을 위해 Jenkins 와 Bastion Host 인스턴스를 따로 구축하는 방법을 택했다
Bastion 은 중세 시대에 성 외곽을 보호하기 위해 돌출된 부분이라고 한다 (배스천 으로 읽음)
Bastion Host 도 사용자에게 제공되는 리소스를 보호하기 위한 Host 로, 방화벽 역할을 한다
Jenkins, Bastion Host 인스턴스 만들기
기존에 만들었던 VPC 안에 구성할 예정이다
Jenkins 는 외부에서 직접 접근할 수 없도록 Private Subnet 에 구성하고
그리고 그 Private 에 접근할 수 있도록 Bastion Host 는 Public Subnet 으로 설정한다
그래서 Bastion Host 에서 SSH 터널링을 통해 Jenkins 로 접근 가능하도록 설정해 준다
Bastion Host 에 탄력적 IP 를 할당하고, Jenkins Instance 의 보안 그룹에 Bastion Host 22 Port 만 접근할 수 있게 설정하면 된다
그리고 SSH 로 Bastion Host 에 접근하려고 했는데 BAD PERMISSION 이라고 해서 키 파일 설정도 변경해 주고 잘 접속했다
ahram@AhramuicBookPro ~ chmod 400 /Users/ahram/Desktop/BBanana/BastionHost.pem
ahram@AhramuicBookPro ~ ssh -i /Users/ahram/Desktop/BBanana/BastionHost.pem ec2-user@[Public IP]
, #_
~\_ ####_ Amazon Linux 2023
~~ \_#####\
~~ \###|
~~ \#/ ___ https://aws.amazon.com/linux/amazon-linux-2023
~~ V~' '->
~~~ /
~~._. _/
_/ _/
_/m/'
Last login: Sat Dec 21 09:02:50 2024 from
[ec2-user@ip~]$
ssh -i [Jenkin Key Pair] [Jenkins Private IP]
Bastion Host 접근할 때랑 똑같이 ssh -i 키 주소 넣었는데, 또 Permission Denied 가 떴다
아참, Bastion Host 에는 Key 가 없지!
일단 Bastion Host 에 Jenkins 키페어를 넣어주고 접근했다
[ec2-user@ip- ~]$ ssh -i JenkinsKey.pem ec2-user@[Jenkins Private IP]
, #_
~\_ ####_ Amazon Linux 2023
~~ \_#####\
~~ \###|
~~ \#/ ___ https://aws.amazon.com/linux/amazon-linux-2023
~~ V~' '->
~~~ /
~~._. _/
_/ _/
_/m/'
Last login: Tue Dec 24 04:30:34 2024 from [Bastion Host Private IP]
[ec2-user@ip- ~]$
이 키페어를 어떻게 보관할지는 차차 고민하고, 일단 Jenkins 부터 설치한다
Jenkins 설치
Jenkins 설치는 https://www.jenkins.io/doc/tutorials/tutorial-for-installing-jenkins-on-AWS/ 를 따라했다
sudo yum update –y
sudo wget -O /etc/yum.repos.d/jenkins.repo \ https://pkg.jenkins.io/redhat-stable/jenkins.repo
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key
sudo yum upgrade
sudo dnf install java-17-amazon-corretto -y
sudo yum install jenkins -y
sudo systemctl enable jenkins
sudo systemctl start jenkins
sudo systemctl status jenkins
설치는 했으니 이제 설정을 해 줄 차례다
1. Jenkins 실행 포트 (Default 8080) 를 8081 로 변경하기
📌 지금은 8090 으로 포트를 변경했다 참고!
우리팀의 Jenkins 는 Public IP 가 없으니, 공식 홈페이지에서 알려준, 웹페이지 접속은 불가하다
Console 에서 jenkins.serivce 파일에 접근하여 Port 를 변경해 주고 Daemon, Service 모두 재시작해준다
sudo vi /usr/lib/systemd/system/jenkins.service
sudo systemctl daemon-reload
sudo systemctl restart jenkins
설정해주고, 해당 Port 가 열려 있는지 확인도 해준다
[ec2-user@ip- ~]$ netstat -tnlp
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:40975 0.0.0.0:* LISTEN -
tcp6 0 0 :::22 :::* LISTEN -
tcp6 0 0 :::8081 :::* LISTEN -
[ec2-user@ip- ~]$
이제,.. 문제는 Private IP 만 있는 Jenkins 웹페이지에 어떻게 접근을 해야할지! 가 고민이었는데
하루이가 Local Forwarding 을 쓰면 좋겠다고 얘기해줘서 그 방법을 사용했다
Jenkins WebPage 에 접속하려면 Local 에서 아래 Command 를 사용해야 한다
ssh -L 8081:[Jenkins Private IP]:8081 -i [BastionKeyPair] ec2-user@[Bastion Public IP]
그리고 그냥 콘솔로 접속하기 쉬운 방법은 SSH Config 파일에 저장하면 된다
vi ~/.ssh/config
Host Bastion # Bastion 연결은 그대로
HostName [Bastion Public IP]
User ec2-user
IdentityFile /Users/ahram/Desktop/BBanana/BastionHost.pem # Local Path
Port 22
Host Jenkins
HostName [Jenkins Private IP]
User ec2-user
IdentityFile ~/.ssh/JenkinsKey.pem # Bastion 에 저장된 KeyPair 사용
ProxyJump Bastion
Port 22 # Jenkins 와의 연결은 Bastion 을 통해 22번 포트로 진입
LocalForward 8090 [Jenkins Private IP]:8090 # Local Forwarding
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes 입력
이제 편하게 ssh Jenkins 로 Jenkins Server 에 접근할 수 있다!
그렇게 Jenkins 홈페이지에 들어왔고 초기 비밀번호는 아래 Command 로 알 수 있다, 회원 가입(?)도 했다
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
Github Integration Plugin 도 설치하고
Crendentials 을 등록한다
Username 은 Github ID, Password 는 Github 의 Personal Access Token 을 발급 받아 넣어 준다
ID/ Description 은 하고싶은 대로 쓰면 된다
그리고 다시 대시보드로 돌아와 New Item 에서 Freestyle Project 를 만든다
여기에서 Git Repo 를 연결하려고 하는데 Git Repo 에 접근할 수 없다고 한다
sudo yum install git
찾아보니, Jenkins 가 설치된 Server 에 Git 이 없어서 그랬던 거였다
🐣 ChatGPT 한테 물어봤을 때는 인터넷 연결 확인, 인증 문제, Git Version, Proxy 설정, Github 상태 확인 등등을 제안해서
하나씩 확인해 봐도 다 안 됐는데, 구글링하니까 바로 나왔다, 구글링 먼저 해보기! 🐣
Git 설치 후 Jenkins Console 에서 Restart 해서
Jenkins.instance.safeRestart()
다시 Github 주소를 잘 넣을 수 있었다
일단은 여기까지 했고, 확인은 하루이랑 같이 해봐야겠다
추가 논의가 필요한 내용
Bastion Host 에서 Jenkins 로 접근할 때의 방식을 어떻게 구성할지,
현재는 Bastion Host 안에 AWS Key Pair 가 있는 상태인데 어떻게 숨기지?
'TIL > DOCKER' 카테고리의 다른 글
[Docker] Docker Image Build (0) | 2025.01.04 |
---|---|
Docker Exited (0) 되는 문제 수정하기 (0) | 2024.12.24 |
CI/CD via Jenkins #2 (0) | 2024.12.23 |
쿠버네티스 Kubernetes (0) | 2024.12.17 |
[Docker] docker-container 로 MySQL 접속하기 (2) | 2024.12.07 |