
Jenkins는 오픈소스 자동화 서버로, 소프트웨어 개발 프로젝트의 빌드(Build), 테스트(Test), 배포(Deploy) 과정을 자동화하는 데 사용된다.
CI/CD(Continuous Integration/Continuous Deployment) 파이프라인을 구축하는 데 있어 가장 널리 사용되는 도구 중 하나인데, Jenkins는 다양한 플러그인을 통해 확장할 수 있고, 사용자 정의가 가능한 UI와 커뮤니티 지원을 제공한다.
(💭 원래 Hudson이라는 이름의 소프트웨어였는데, 오라클과의 상표권 분쟁으로 인해 Jenkins라는 이름으로 바뀌었다고한다…)
지속적 통합(CI)은 개발자들이 개별적으로 작업한 코드를 정기적으로 통합하고 테스트하는 프로세스를 의미한다.
CI의 핵심은 코드 변경 사항을 가능한 자주 통합함으로써 코드의 충돌 가능성을 줄이고, 문제를 빠르게 발견하여 수정하는 데 있다.
Jenkins와 같은 도구를 사용하면 코드가 변경될 때마다 자동으로 빌드하고 테스트할 수 있다.
지속적 배포(CD)는 CI의 확장된 개념으로, 통합된 코드가 자동으로 배포(Deploy)되는 과정을 의미한다.
이는 두 가지로 나뉘는데, 지속적 배포(Continuous Deployment)는 코드가 변경되면 자동으로 프로덕션 환경에 배포되는 반면, 지속적 제공(Continuous Delivery)은 자동화된 테스트까지 완료된 후, 배포는 수동으로 진행된다.
Jenkins는 이러한 배포 파이프라인을 구성하는 데도 유용하다.
쿠버네티스(Kubernetes)는 컨테이너화된 애플리케이션을 관리하기 위한 오픈소스 플랫폼이다. Jenkins를 쿠버네티스에서 운영하면 확장성, 관리 용이성, 복원력 등의 장점을 극대화할 수 있다.
먼저 Jenkins를 배포할 네임스페이스를 생성해준다.
네임스페이스는 쿠버네티스 클러스터 내에서 리소스를 격리하여 관리할 수 있도록 해준다.
kubectl create namespace jenkins
Jenkins가 쿠버네티스 클러스터 내에서 적절한 권한을 가지고 동작하도록 하기 위해 서비스 계정과 역할(Role)을 설정한다.
apiVersion: v1
kind: ServiceAccount
metadata:
name: jenkins
namespace: jenkins
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: jenkins-admin
namespace: jenkins
rules:
- apiGroups: [""]
resources: ["pods", "pods/logs"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch"]
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: jenkins-admin-binding
namespace: jenkins
subjects:
- kind: ServiceAccount
name: jenkins
namespace: jenkins
roleRef:
kind: Role
name: jenkins-admin
apiGroup: rbac.authorization.k8s.io
위의 파일을 jenkins-service-account.yaml로 저장하고, 다음 명령어로 적용한다.
kubectl apply -f jenkins-service-account.yaml
Jenkins의 데이터를 영구적으로 저장하기 위해 퍼시스턴트 볼륨(Persistent Volume, PV)과 퍼시스턴트 볼륨 클레임(Persistent Volume Claim, PVC)을 생성한다.
apiVersion: v1
kind: PersistentVolume
metadata:
name: jenkins-pv
namespace: jenkins
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data"
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: jenkins-pvc
namespace: jenkins
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
이 파일을 jenkins-pv-pvc.yaml로 저장한 후, 아래 명령어로 적용한다.
kubectl apply -f jenkins-pv-pvc.yaml
Jenkins를 실제로 배포하기 위한 Deployment와 외부에서 접근할 수 있도록 Service를 설정한다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: jenkins
namespace: jenkins
spec:
replicas: 1
selector:
matchLabels:
app: jenkins
template:
metadata:
labels:
app: jenkins
spec:
serviceAccountName: jenkins
containers:
- name: jenkins
image: jenkins/jenkins:lts
ports:
- containerPort: 8080
- containerPort: 50000
volumeMounts:
- name: jenkins-home
mountPath: /var/jenkins_home
volumes:
- name: jenkins-home
persistentVolumeClaim:
claimName: jenkins-pvc
apiVersion: v1
kind: Service
metadata:
name: jenkins
namespace: jenkins
spec:
type: NodePort
ports:
- port: 8080
targetPort: 8080
nodePort: 30000
selector:
app: jenkins
이 파일을 jenkins-deployment.yaml로 저장한 후, 다음 명령어로 Jenkins를 배포한다.
kubectl apply -f jenkins-deployment.yaml
Jenkins가 설치된 후, 브라우저에서 Jenkins UI에 접속하기 위해 다음 명령어를 사용해 NodePort를 확인한다.
kubectl get svc -n jenkins
이제 http://<Node IP>:30000으로 접속하면 Jenkins의 초기 설정 화면에 접근할 수 있다.
초기 비밀번호는 Jenkins Pod의 로그에서 확인할 수 있다.
kubectl logs <Jenkins Pod Name> -n jenkins