본문 바로가기

⭐ CICD/Jenkins

jenkins를 pod로 설치 및 실행하기

# jenkins를 pod로 설치 및 실행하기

- jenkins를 pod로 설치하여 실행하는 방법에 대해서 알아본다.

jenkins는 가장 많이 사용하고 있는 오픈소스 CI 툴이다. 물론 AWS나 구글 클라우드 등에서 제공하는 CI 서비스 제공하여 CSP에서 제공하는 서비스를 많이 사용하고 있는 추세이다.

설치하는 방법은 아래와 같다.

1. jenkins deployment.yaml 파일 배포

- 해당 코드에서는 별도의 pv를 설정하지는 않았지만 운영환경이나 기타 pv가 필요한 환경에서는 pv 설정을 반드시 해줘야 데이터의 손실을 막을 수 있다. 해당 과정은 테스트 과정이므로 emptyDir 로 설정을 하여 진행 한다.

emptyDi과 관련된 내용은 아래의 URL을 참고한다.

2021.09.11 - [⭐ Kubernetes & EKS/볼륨 스토리지 (Volume Storage)] - 쿠버네티스 스토리지 & EmptyDir

 

쿠버네티스 스토리지 & EmptyDir

# 쿠버네티스 스토리지 - 임시볼륨: 컨테이너간 공유위해 - 로컬볼륨: 노드간 공유위해 # EmptyDir을 활용한 컨테이너 간 데이터 공유 - 공유디렉토리 : 볼륨 - 컨테이너별 디렉토리를 볼륨을 통해

may9noy.tistory.com

- jenkins_deployment.yaml 파일의 내용은 아래와 같다.

주의해야할 점은 아래의 코드에서는 namespace를 정의하지는 않았지만 namespace를 정의해야 추후 관리가 편해지므로 namespace를 반드시 지정해 주도록 한다.

# jenkins_deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: jenkins
spec:
  replicas: 1
  selector:
    matchLabels:
      app: jenkins
  template:
    metadata:
      labels:
        app: jenkins
    spec:
      containers:
      - name: jenkins
        image: jenkins/jenkins:lts
        ports:
          - name: http-port
            containerPort: 8080
          - name: jnlp-port
            containerPort: 50000
        volumeMounts:
          - name: jenkins-vol
            mountPath: /var/jenkins_vol
      volumes:
        - name: jenkins-vol
          emptyDir: {}

- jenkins_service.yaml 파일을 작성하면 아래와 같다.

위의 deployment에서 ports를 2개의 경로로 나누어 설정을 하였다. 하나는 8080이고 하나는 50000번이다. 이렇게 나눠서 설정을 한 이유는 간단한데 8080은 jenkins 웹서버를 접근하기 위한 포트이고 50000번은 다른 컴퓨터에서 해당 jenkins에 Agent를 활용하여 접근이 가능하도록 하기 위함이다. (노드관리에서 Master Node와 Agent Node를 구분하여 CI 과정을 수행하기 위함이다.)

- 그리고 서비스 타입은 모두 LoadBalancer로 구성을 하였다. 로드 밸런서로 구성을 하면 별도의 설정없이 외부에서 LB DNS 주소로 접근이 가능하므로 편리하다.

# jenkins_service.yaml

apiVersion: v1
kind: Service
metadata:
  name: jenkins
spec:
  type: LoadBalancer
  ports:
    - port: 8080
      targetPort: 8080
      nodePort: 30000
  selector:
    app: jenkins

---

apiVersion: v1
kind: Service
metadata:
  name: jenkins-jnlp
spec:
  type: LoadBalancer
  ports:
    - port: 50000
      targetPort: 50000
  selector:
    app: jenkins

2. 생성한 yaml 파일 실행하기

- 위의 코드에서는 namespace를 지정하지 않아서 별도의 namespace를 생성하지 않아도 되지만, 보통은 해당 namespace에 리소스를 생성하므로 namespace를 생성하는 코드를 1번으로 정의 하였다.

- 2번은 deployment와 관련된 내용이고, 3번은 service와 관련된 내용이다. 해당 yaml 파일을 배포한다.

# 1. jenkins namespace 생성
kubectl create namespace jenkins

# 2. jenkins_deployment.yaml 배포 
kubectl apply -f jenkins_deployment.yaml

# 3. jenkins_service.yaml 배포 
kubectl apply -f jenkins_service.yaml

3. 생성된 리소스를 확인하기

- namespace를 생성하지 않았기에 해당 pod나 서비스의 namespace는 default로 설정이 되어 있을 것이다.

$ kubectl get pod && kubectl get svc
NAME                                  READY   STATUS    RESTARTS   AGE
jenkins-5bf8d67f6c-l4wxt              1/1     Running   0          119m
NAME                            TYPE           CLUSTER-IP       EXTERNAL-IP                                          PORT(S)                       AGE
jenkins                         LoadBalancer   172.20.75.238    a85e055-611579425.ap-northeast-2.elb.amazonaws.com   8080:30000/TCP                119m
jenkins-jnlp                    LoadBalancer   172.20.6.13      a40ebcb-167157429.ap-northeast-2.elb.amazonaws.com   50000:31528/TCP

4. jenkins 웹 서비스로 접근은 해보자.

- 확인하는 명령어는 아래와 같다.

$ kubectl exec -it {jenkins_podname} -- cat /var/jenkins_home/secrets/initialAdminPassword
733a5fe436574cbab3cfe35a9b4c4b24

$ kubectl exec -it jenkins-l4wxt0000 -- cat /var/jenkins_home/secrets/initialAdminPassword

# 조회된 값을 아래의 유형과 비슷한 형태로 출력된다.
733a5fe43657400000000000000

- jenkins의 접근 url은 위에서 LoadBalancer로 생성을 했기 때문에 AWS 로드밸런서 메뉴에서 해당 접속 DNS 주소를 확인할 수 있을 것이다. 내 주소의 유형은 아래와 같다.

- jenkins 웹 페이지로 접속을 하면 비밀번호를 입력하라는 메세지가 나오는데 해당 비밀번호는 위의 명령어로 조회한 값을 넣어주면 된다. (비밀번호 확인 경로 : cat /var/jenkins_home/secrets/initialAdminPassword)

- 접근을 하면 아래와 같이 plug in을 설치한다.

- 플러그인이 전부 설치되면 아래와 같이 새로운 신규 유저를 생성하라는 메세지가 나온다. 신규로 사용자를 생성한다.

- 접속한 jenkins의 메인 화면은 아래와 같다.

- 여기까지 pod로 jenkins app을 올리는 작업을 진행 하였다. 해당 jenkins app을 활용하여 실제 빌드와 배포작업을 진행해보자.

# 추가작업 : Jenkins pod의 스토리지를 pvc로 변경

1. storageclass 생성

스토리지 클래스를 가장 먼서 생성해야 나머지 리소스를 생성하는데 지장이 없다.

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: jenkins-storage
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp2
  fsType: ext4
reclaimPolicy: Delete
mountOptions:
  - debug
volumeBindingMode: Immediate

2. PersistentVolumeClaim 생성

- PVC라고 하고 해당 파일을 생성 후 실행하면 실제 EBS에서 볼륨을 생성한다.

- pod가 어떤 pvc를 할당받는지 확인하는 명령어는 kubectl describe {pod_name} -n {namespace_name} 으로 확인 가능하다.

- AWS의 EBS 메뉴에서 확인을 하면 아래와 같이 확인이 가능하다.

- yaml 파일의 내용은 아래와 같다.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: jenkins-pv-claim
  labels:
    app: jenkins
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi
  storageClassName: jenkins-storage

- 여기서 주의할 점은 pvc.yaml을 delete 할때 리소스가 삭제되지 않고, 삭제 중에서 멈춰있을 수 있다. 이럴경우를 대비하여 삭제 전에 미리 EBS 볼륨과 연결된 인스턴스를 분리시키는 작업을 선행하는 것이 좋다.

3. deployment.yaml 파일에 위에서 생성한 pvc 적용

# jenkins_deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: jenkins
spec:
  replicas: 1
  selector:
    matchLabels:
      app: jenkins
  template:
    metadata:
      labels:
        app: jenkins
    spec:
      containers:
      - name: jenkins
        image: jenkins/jenkins:lts
        ports:
          - name: http-port
            containerPort: 8080
          - name: jnlp-port
            containerPort: 50000
        volumeMounts:
          - name: jenkins-vol
            mountPath: /var/jenkins_vol
      volumes:
        - name: jenkins-vol
          persistentVolumeClaim:
            claimName: jenkins-pv-claim

- jenkins pod를 pvc로 설정한 이유는 이전에는 jenkins pod를 삭제 시 해당 데이터까지 모두 삭제가 되는 문제가 있었다. 하지만 pvc를 사용하게 되면 데이터가 ebs 저장소에 그대로 저장 되므로 pod에 pvc를 마운트하여 사용하여야 ebs가 삭제되지 않는 한 영구적으로 데이터를 보관 및 사용할 수 있다.

- jenkins pod에 pvc를 적용하는 방법에 대해서 알아보았다.

- 끝 -