지난 포스팅에서는 DevOps의 개념과 필요성에 대해 간단히 살펴보았습니다. 이번에는 이를 기반으로 실제 DevOps 환경을 어떻게 구축할 수 있는지, 로컬 환경에서 Jenkins, Docker, Kubernetes를 활용한 CI/CD 파이프라인 구성 과정을 정리해보았습니다.
1. 젠킨스 서버 UTM으로 구축하기
Jenkins 서버를 설치할 가상 머신은 UTM을 통해 구축합니다.
[K8S] K8S 설치하기
이번에는 클라우드가 아닌 로컬 온프레미스 환경에서 직접 Kubernetes 클러스터를 구성해보겠습니다. MacOS 환경을 기반으로, 가상 머신 설정부터 Kubernetes 설치 및 네트워크 구성까지 총 9단계에 걸
recordhm.tistory.com
UTM 설치 및 기본 설정 과정은 이전 포스팅에서 자세히 다뤘기 때문에, 이번에는 달라진 부분만 간단히 짚고 넘어가겠습니다.
Jenkins 서버의 IP는 192.168.56.20으로 호스트 전용 네트워크에서 고정하였습니다. 이처럼 고정 IP를 사용하는 이유는, CI/CD 파이프라인 내에서 Kubernetes 클러스터가 Jenkins에 webhook이나 빌드 요청을 보낼 수 있도록 항상 일정한 주소로 접근 가능하게 하기 위함입니다. DHCP를 사용할 경우 IP가 변경될 수 있어, 실습 환경에서 서비스 간 통신이 원활하지 않거나 빌드 실패의 원인이 될 수 있습니다. 따라서 Jenkins 서버에도 고정 IP를 설정해 네트워크 상의 안정성을 확보했습니다.
inet 192.168.56.20/24
2. CI / CD 서버 구축하기
1. kubectl 설치
Jenkins 서버에서도 배포를 위해 kubectl 명령어가 필요하므로 설치합니다.
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.27/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.27/rpm/repodata/repomd.xml.key
exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni
EOF
yum install -y kubectl-1.27.2-150500.1.1.aarch64 --disableexcludes=kubernetes
2. Docker 설치
Jenkins가 애플리케이션을 컨테이너 이미지로 빌드하기 위해 필요합니다.
yum install -y yum-utils
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install -y docker-ce docker-ce-cli containerd.io
systemctl daemon-reload
systemctl enable --now docker
3. Java 설치
Spring 기반 애플리케이션 빌드를 위한 Java 런타임 환경을 설치합니다.
yum install -y java-17-openjdk
4. Gradle 설치
Jenkins가 빌드할 Java 프로젝트의 의존성 관리와 빌드 도구로 사용됩니다.
yum -y install wget unzip
wget https://services.gradle.org/distributions/gradle-7.6.1-bin.zip -P ~/
unzip -d /opt/gradle ~/gradle-*.zip
cat <<EOF |tee /etc/profile.d/gradle.sh
export GRADLE_HOME=/opt/gradle/gradle-7.6.1
export PATH=\$GRADLE_HOME/bin:\$PATH
EOF
chmod +x /etc/profile.d/gradle.sh
source /etc/profile.d/gradle.sh
5. Git 설치
소스코드를 GitHub에서 가져오기 위해 Git을 설치합니다.
yum install -y git
6. Jenkins 설치
CI/CD 자동화를 위한 Jenkins 서버를 설치하고 실행합니다.
wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key
yum install -y jenkins-2.440.2-1.1
systemctl enable jenkins
systemctl start jenkins
3. Jenkins 사용자 셋팅
Jenkins를 처음 설치하면 기본적으로 초기 관리자 비밀번호가 랜덤한 문자열로 생성됩니다.
웹 브라우저에서 http://<서버 IP>:8080으로 접속하면 아래와 같은 Unlock Jenkins 화면이 나타납니다.

cat /var/lib/jenkins/secrets/initialAdminPassword
위 명령어를 통해 /var/lib/jenkins/secrets/initialAdminPassword 파일에 저장된 초기 비밀번호를 확인할 수 있습니다.
복사한 비밀번호를 입력하면 다음 단계로 넘어갑니다.
Jenkins는 초기 설정 단계에서 아래와 같은 플러그인 설치 화면을 보여줍니다. Jenkins는 다양한 기능을 플러그인 기반으로 제공하며, CI/CD 파이프라인 구성에 필요한 기능 대부분도 플러그인을 통해 구현됩니다.

이 옵션을 선택하면 주요 플러그인들이 자동 설치됩니다.
다음으로, Jenkins 서버에서 사용할 계정과 비밀번호 설정을 해줍니다.

이 단계에서는 Jenkins 웹 콘솔에 로그인할 수 있는 관리자 계정 ID, 비밀번호, 이름, 이메일 주소 등을 입력합니다.
계정 생성후, 로그인을 성공적으로 하면 다음과 같은 대시보드를 보실 수 있습니다.

4. JDK, Gradle 전역 설정
Jenkins 대시보드에 진입하면, 본격적인 빌드 설정에 앞서 JDK와 Gradle 같은 빌드 도구를 전역으로 등록해주어야 합니다.
Jenkins 관리 -> Tools로 진입해 이전 단계에서 수동으로 설치한 OpenJDK 17과 Gradle 7.6.1을 기반으로 설정해야 합니다.
JDK 설정
- Name: jdk-17
- JAVA_HOME: /usr/lib/jvm/java-17-openjdk-17.0.15.0.6-2.el9.aarch64
Gradle 설정
- Name: gradle-7.6.1
- GRADLE_HOME: /opt/gradle/gradle-7.6.1
이렇게 설정을 마치면 Jenkins는 빌드 시 해당 도구들을 사용할 수 있게 됩니다.
5. Docker 가입
CI/CD 파이프라인에서 애플리케이션을 Docker 이미지로 빌드한 뒤, 이를 공유 가능한 저장소(DockerHub)에 push하고, Kubernetes에서 다시 pull 하여 배포하는 구조로 동작합니다. 이를 위해 Jenkins에서 사용할 DockerHub 계정을 사전에 생성해주어야 합니다.
Docker Hub Container Image Library | App Containerization
Increase your reach and adoption on Docker Hub With a Docker Verified Publisher subscription, you'll increase trust, boost discoverability, get exclusive data insights, and much more.
hub.docker.com
6. Docker 사용 설정
앞서 설치한 Jenkins가 Docker를 통해 이미지를 빌드하고, DockerHub로 push 하기 위해서는 Jenkins 유저가 Docker 명령어를 사용할 수 있도록 권한 설정이 필요합니다.
# Jenkins가 Docker 데몬에 접근 가능하도록 설정
chmod 666 /var/run/docker.sock
# Jenkins 사용자를 docker 그룹에 추가하여 Docker 명령어를 실행할 수 있게 만듭니다.
usermod -aG docker jenkins
다음으로 Jenkins 사용자로 전환한뒤, Dockr로 로그인해줍니다.
su - jenkins -s /bin/bash
docker login
7. Master Node에서 인증서 복사
기존에 쿠버네티스를 설치한 Master Node (192.168.56.30)에서 Jenkins 서버 (192.168.56.20)로 인증서 파일을 복사해옵니다.
이는 Jenkins가 kubectl 명령어를 사용해 원격 Kubernetes 클러스터에 접근할 수 있도록 하기 위함입니다.
kubectl은 $HOME/.kube/config 파일을 통해 인증 정보를 확인하고 클러스터에 접근하므로, 해당 파일을 Jenkins 사용자 홈 디렉토리에 동일하게 설정해주어야 합니다.
# 폴더 생성
[jenkins@cicd-server ~]$ mkdir ~/.kube
# Master Node에서 인증서 가져오기
[jenkins@cicd-server ~]$ scp root@192.168.56.30:/root/.kube/config ~/.kube/
인증서가 정상적으로 복사되었다면, kubectl 명령어를 통해 Kubernetes 클러스터와의 연결이 잘 되었는지 확인할 수 있습니다.
kubectl get pods -A
8. Project 빌드
이제 Jenkins에서 GitHub에 있는 Spring 프로젝트를 자동으로 빌드하도록 설정해보겠습니다. 해당 작업은 Jenkins에서 파이프라인을 구성하는 첫 단계로, 소스 코드를 가져와 컴파일 및 패키징하는 과정을 자동화합니다.
Item 생성
- Jenkins 대시보드에서 새로운 Item(New Item)을 클릭합니다.
- Item 이름을 입력하고, Freestyle project 유형을 선택합니다. → Freestyle 프로젝트는 다양한 빌드 작업을 간단히 구성할 수 있는 형태로, 초보자에게 적합합니다.
GitHub 연동 설정
Source Code Management 섹션에서 Git을 선택하고, Repository URL과 브랜치 이름(main 등)을 입력합니다.

빌드 도구로 Gradle 사용
Build 섹션에서 Invoke Gradle script를 추가합니다. Tasks에는 clean build를 입력합니다. 이전에 생성된 산출물을 모두 삭제하고, 프로젝트를 빌드하여 .jar 파일 등 결과물을 생성해야 하기 때문입니다.

이러한 작업을 완료한 후, 빌드 실행(Build Now)을 클릭하면 설정한 작업이 실행되며, 성공적으로 빌드가 수행되면 Jenkins 서버 내부에 .jar 파일이 생성됩니다. 해당 .jar 파일은 이후 도커 이미지 생성 및 배포 작업의 핵심 산출물로 사용되며, CI/CD 파이프라인의 흐름 상 Build → Package → Deploy단계 중 Package에 해당하는 중요한 단계입니다.
[jenkins@cicd-server ~]$ ll /var/lib/jenkins/.jenkins/workspace/2121-source-build/build/libs
total 18596
-rw-r--r--. 1 jenkins jenkins 19025051 May 27 15:46 app-0.0.1-SNAPSHOT.jar
-rw-r--r--. 1 jenkins jenkins 16297 May 27 15:46 app-0.0.1-SNAPSHOT-plain.jar
9. Container 빌드
이전 단계에서 .jar 파일을 빌드한 것과 동일하게, Jenkins에서 새로운 item을 생성해줍니다. 이 작업은 Docker 이미지를 생성하고 Docker Hub에 업로드하기 위한 작업입니다.
- Jenkins 대시보드에서 New Item 클릭
- Item 이름을 입력하고 Freestyle project 선택
- GitHub Project 체크 후, 해당 GitHub Repository URL과 브랜치를 설정
- Additional Behaviors → Sparse Checkout paths 항목 추가

Build Step에는 Execute shell을 선택한 후 다음과 같이 작성 후, 빌드를 해줍니다.
# jar 파일 복사
cp /var/lib/jenkins/.jenkins/workspace/2121-source-build/build/libs/app-0.0.1-SNAPSHOT.jar ./2121/build/docker/app-0.0.1-SNAPSHOT.jar
# 도커 빌드
docker build -t kmkhm/api-tester:v1.0.0 ./2121/build/docker
# 도커 허브로 푸쉬
docker push kmkhm/api-tester:v1.0.0
이 작업은 앞서 빌드된 .jar 파일을 Docker 이미지로 패키징하고, Docker Hub로 업로드하는 역할을 수행합니다. 이 단계는 CI/CD 파이프라인 상 “Deploy” 단계로 이어지기 위한 준비이며, Kubernetes 클러스터에서 사용할 수 있는 애플리케이션 이미지를 만드는 핵심 작업입니다.
[jenkins@cicd-server ~]$ cat /var/lib/jenkins/.jenkins/workspace/2121-container-build/2121/build/docker/Dockerfile
FROM openjdk:17
COPY ./app-0.0.1-SNAPSHOT.jar /usr/src/myapp/app.jar
ENTRYPOINT ["java", "-Dspring.profiles.active=${spring_profiles_active}", "-Dapplication.role=${application_role}", "-Dpostgresql.filepath=${postgresql_filepath}", "-jar", "/usr/src/myapp/app.jar"]
EXPOSE 8080
WORKDIR /usr/src/myapp
10. Kubenetes 클러스터에 배포하기
앞서 컨테이너 이미지를 빌드하고 Docker Hub에 push했던 Jenkins item을 복사하여 사용합니다. 이는 대부분의 설정(GitHub 연결, sparse checkout 등)이 동일하기 때문에 반복 작업을 줄이고, 배포 단계에만 집중하기 위함입니다.
Additional Behaviors → Sparse Checkout paths 항목을 다시 추가하고, 배포에 필요한 K8s 매니페스트 파일들이 포함된 경로를 지정해줍니다.

Build Step → Execute shell 항목에 다음 스크립트를 작성합니다.
kubectl apply -f ./2121/deploy/k8s/namespace.yaml
kubectl apply -f ./2121/deploy/k8s/pv.yaml
kubectl apply -f ./2121/deploy/k8s/pvc.yaml
kubectl apply -f ./2121/deploy/k8s/configmap.yaml
kubectl apply -f ./2121/deploy/k8s/secret.yaml
kubectl apply -f ./2121/deploy/k8s/service.yaml
kubectl apply -f ./2121/deploy/k8s/hpa.yaml
kubectl apply -f ./2121/deploy/k8s/deployment.yaml
이 명령어들은 각각의 리소스를 순차적으로 쿠버네티스 클러스터에 배포하는 역할을 합니다. 실제로는 kubectl apply -f 명령어가 매니페스트 파일을 읽어들여 Deployment, Service, ConfigMap, Secret, PVC, HPA 등 운영에 필요한 모든 리소스를 자동으로 구성해줍니다.
item 빌드 후, 배포가 정상적으로 완료되면 다음과 같이 대시보드에서 Pod를 확인할 수 있습니다.

'Infra' 카테고리의 다른 글
| [K8S] Jenkins Pipeline (2) | 2025.05.29 |
|---|---|
| [K8S] 배포를 하기전에 알아야 할 것들 (2) | 2025.05.28 |
| [K8S] DevOps (0) | 2025.05.26 |
| [K8S] Component (0) | 2025.05.25 |
| [K8S] PV, PVC, Deployment, Service, HPA (0) | 2025.05.25 |
댓글