CI/CD와 Jenkins

Jaca·2022년 8월 24일
0

Jenkins를 설명하기 전, CI/CD가 무엇인지 알아보자.

CI/CD

CI/CD란, Continuous Integration(지속적 통합)/Continuous Delivery 혹은 Continuous Deployment(지속적 제공) 이다.

CI/CD를 말할때는 가장 기본적으로 지속적인 통합, 지속적인 서비스 제공, 지속적인 배포를 말한다.

CI

CI는 개발자를 위한 자동화 프로세스인 지속적인 통합(Continuous Integration)을 의미한다.

CI를 성공적으로 구현할 경우 애플리케이션에 대한 새로운 코드 변경 사항이 정기적으로 빌드 및 테스트되어 공유 리포지토리에 통합되므로 여러 명의 개발자가 동시에 애플리케이션 개발과 관련된 코드 작업을 할 경우 서로 충돌할 수 있는 문제를 해결할 수 있다.
축약하자면 CI가 새로운 소스코드의 빌드, 테스트, 병합까지를 의미한다.

CD

CD는 지속적인 서비스 제공(Continuous Delivery) 또는 지속적인 배포(Continuous Deployment)를 의미한다.
두 가지 의미 모두 파이프라인의 추가 단계에 대한 자동화를 뜻한다.

Continuous Delivery는 공유 레포지토리로 자동으로 Release 하는 것 Continuous Deployment는 Production 레벨까지 자동으로 deploy 하는 것을 의미한다.
축약하자면 CD는 개발자의 변경 사항이 레포지토리를 넘어, 고객의 프로덕션(Production) 환경까지 릴리즈 되는 것을 의미한다.

Jenkins

Jenkins는 흔히 CI 툴로 많이 사용되었지만 요새는 점점 CD 영역으로 확대되면서 CI/CD 전반적인 흐름을 관장하는 툴로 성장하게 되었다.

Jenkins는 기본적으로 java runtime 위에서 동작하는 자동화 서버이다. 위에서 말한 것처럼 build, test, deployment의 모든 것을 자동화해준다.

대표 기능

  1. 편리한 설정
    웹 기반의 콘솔로 다양한 인증 기반과 결합이 가능하며 권한 관리 기능을 통해 안전한 빌드/배포 환경을 구축할 수 있다. 수많은 플러그인을 사용하여 자동화 할 수 있어 반복되는 작업을 줄일 수 있다.

  2. 안정적인 빌드/배포 환경
    소스 버전 관리 툴과 연동하여 코드 변경을 감지하고, 자동화 테스트를 포함한 빌드를 수행하여 소프트웨어 품질을 향상시킬 수 있다. 자동화 테스트에는 코딩 표준 준수 여부 체크, 유닛 테스트, 통합 테스트 등을 설정할 수 있고 빌드 결과물을 지속적으로 배포하도록 설정하여 개발 프로세스 전체를 자동화할 수 있다.

  3. 다양한 활용 및 손쉬운 확장
    Jenkins는 많이 사용 되고 있는 오픈 소스 소프트웨어로 문서화가 잘 되어 있고, 다양한 플러그인을 사용/개발하여 무한한 확장을 제공한다.

K8S에 Jenkins 설치

service-account.yaml 매니페스트를 작성한다.

#jenkins-service-account.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: jenkins-admin
  namespace: devops-tools
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: jenkins
  namespace: devops-tools
  labels:
    "app.kubernetes.io/name": 'jenkins'
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["create","delete","get","list","patch","update","watch"]
- apiGroups: [""]
  resources: ["pods/exec"]
  verbs: ["create","delete","get","list","patch","update","watch"]
- apiGroups: [""]
  resources: ["pods/log"]
  verbs: ["get","list","watch"]
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: jenkins-role-binding
  namespace: devops-tools
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: jenkins
subjects:
- kind: ServiceAccount
  name: jenkins-admin
  namespace: devops-tools

여기에는 devops-tools 네임스페이스의 포드를 관리할 수 있는 모든 권한이 있는 서비스 계정에 대한 역할 및 역할 바인딩의 내용을 담고있다.

이젠 배포를 위한 jenkins-deployment.yaml를 작성한다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: jenkins-deployment
  namespace: devops-tools
spec:
  replicas: 1
  selector:
    matchLabels:
      app: jenkins
  template:
    metadata:
      labels:
        app: jenkins
    spec:
      serviceAccountName: jenkins-admin
      securityContext:
            fsGroup: 1000
            runAsUser: 1000
      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: {}

# Service Config
---
apiVersion: v1
kind: Service
metadata:
  name: jenkins-service
  namespace: devops-tools
  annotations:
      prometheus.io/scrape: 'true'
      prometheus.io/path:   /
      prometheus.io/port:   '8080'
spec:
  selector:
    app: jenkins
  type: NodePort
  ports:
    - name: http-port
      port: 8080
      targetPort: 8080
      nodePort: 30000
    - name: jnlp-port
      port: 50000
      targetPort: 50000

테스트 환경이므로 Jenkins Volume을 hostPath로 설정하였다.
위 Pod이 생성될 Node의 jenkins_vol 디렉토리에 권한이 777이어야 명령어를 수행해야 정상적으로 진행할 수 있다.
실제 운영 환경에선 반드시 Persistent Volume(EBS, GlusterFS 등)을 통해 설정 및 빌드 이력 등을 잃어버리는 불상사를 피해야 한다.

같은 이유로 NodePort를 사용해 Service를 작성하였다.

이후 Jenkins를 위한 네임스페이스를 생성한다.

kubectl create namespace devops-tools

생성한 네임스페이스에 Jenkins를 배포한다.

kubectl apply -f jenkins-service-account.yaml
kubectl apply -f jenkins-deployment.yaml

잘 생성된 것을 확인할 수 있다.

이제 웹 UI로 접근해보자.

Jenkins 설정

생성된 pod에 NodePort로 최초 접근시 아래와 같은 화면이 출력된다.

최초 접속시 Admin 비밀번호를 요구한다. Container 파일시스템에서 해당 정보를 가져와야 한다.

kubectl exec -it -n jenkins jenkins-pod -- cat /var/jenkins_home/secrets/initialAdminPassword

다음은 권장 플러그인 설치 할 지 물어본다.

각 메뉴에 따라 Jenkins가 자동으로 Git, Pipeline, Mailer 같은 중요 플러그인을 설치할 지, 선택적으로 플러그인을 설치할 지 선택할 수 있다.

테스트 환경이고, 처음 사용하기 때문에 자동 설치를 선택한다.

최초 관리자 계정을 추가한다.

성공적으로 설치 완료된 Jenkins의 최초 화면이다.

'Jenkins 관리 > 플러그인 관리 > 설치 가능' 탭에서 'Kubernetes', 'Docker Pipeline' 플러그인을 검색하여 설치한다.

플러그인을 설치하고 'Jenkins 관리' > 시스템 설정' 에서 버튼을 눌러 Add a new cloud 항목에 들어간다.


박스 순으로 설명한다.

  1. Kubernetes URL 정보 입력
  2. Namespace 입력
  3. https를 위한 Credentials를 위해 kubeconfig 파일을 등록
  4. Jenkins URL 입력.
    일반적으로 Service URL은 http://<service-name>.<namespace>.svc.cluster.local:8080 의 규칙을 따른다.
  5. pod 생성시 붙을 label 등록

위와 같이 설정 후 테스트 빌드를 진행한다.

테스트 빌드

'Jenkins DashBoard > new item' 에서 pipeline을 생성한다.

pipeline script에서 maven으로만 설정해서 확인 후 빌드를 시작한다.

consol output에서 로그 확인이 가능하다.
성공적으로 빌드한 모습

파드가 생성되었다가 삭제되는 모습도 확인할 수 있다.

profile
I am me

0개의 댓글