티스토리 뷰

목차

개요
사전 준비
환경 설정
Jenkins 설치
Kubernetes Cloud 설정

 

개요

개인 프로젝트용으로 로컬 환경에서 간단한 CI/CD를 구성하다가 글로 남겨놓고자 겸사겸사 포스팅합니다.

과정은 아래와 같습니다.

1. 프로젝트 소스를 Github Master Branch에 Push.

2. Github Webhook을 통해 Jenkins에서 Pipeline 수행.

3. Test를 진행한 뒤 Docker Image로 Build 및 Push.

4. Kubernetes에서 DockerHub에 Push된 이미지를 가져와 배포.

 

※ Ingress를 통해 SSL/TLS를 적용하는 부분은 생략하고 관련 링크 첨부합니다.
ingress-tls
nginx-controller

 

사전 준비

  • DockerKubernetes에 대한 기본적인 지식

  • Docker for Window 설치

    위 링크를 참고하여 Docker를 설치합니다. 또한, windows용 Docker에는 로컬용 독립형 kubernetes가 내장되어 있습니다.

  • Docker를 설치한 뒤 아래처럼 Kubernetes를 활성화시켜줍니다.

  • 배포용 프로젝트

    저는 간단하게 create-react-app으로 샘플 프로젝트를 생성했습니다.


1) 환경 설정

Context 및 Namespace, serviceaccount 설정

$ kubectl config get-contexts # 현재 Context 목록을 조회.
$ kubectl config use-context docker-desktop

$ kubectl create namespace dev
$ kubectl config set-context --current --namespace=dev # 선호 namespace를 dev로 설정. 1회성

$ kubectl -n dev create sa jenkins # jenkins용 serviceaccount 생성
# jenkins serviceaccount에 최상위 권한을 부여.
$ kubectl -n dev create rolebinding jenkins-binding --clusterrole=cluster-admin --serviceaccount=dev:jenkins

Context를 Local Docker로 설정했기 때문에 이후 Kubernetes의 파드로 올라간 Container는 Docker ps로 확인할 수 있습니다.

 

2) Jenkins 설치

Jenkins Volume, Pod, Service 정의
적당한 경로에 jenkins 디렉토리를 만들고 kubernetes에 배포할 jenkins의 Volume 및 pod, service를 정의한 yaml파일을 아래와 같이 생성합니다.

 

컨테이너의 파일 시스템은 컨테이너가 살아 있는 동안에만 존재합니다. 만약 Jenkins컨테이너를 생성한 뒤 이런저런 세팅을 마쳤는데 컨테이너가 다시 생성되면 내부의 모든 설정은 전부 소실됩니다. 이런 상황을 위해 Kubernetes에서는 Volume이라는 디렉토리를 제공하며 이를 이용해서 Jenkins의 데이터를 보존할 겁니다.

 

다만, hostPath를 D드라이브에 볼륨용으로 생성해놓은 임의 디렉토리로 설정할 것이기 때문에 docker for windows의 setting에서 공유 드라이브 설정을 아래와 같이 해줍니다.

 

volume.yaml (PV, PVC)

Volume을 정의할 때 사용하는 옵션들의 정보는여기서 확인할 수 있습니다.

apiVersion: v1
kind: PersistentVolume
metadata:
  name: jenkins-pv
spec:
  capacity:
    storage: 1Gi
  volumeMode: Filesystem
  accessModes:
  - ReadWriteOnce
  storageClassName: manual
  persistentVolumeReclaimPolicy: Retain
  hostPath:
    path: /D/workspace/jenkins/volume
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: jenkins-pvc
spec:
  accessModes:
  - ReadWriteOnce
  volumeMode: Filesystem
  resources:
    requests:
      storage: 1Gi
  storageClassName: manual

 

jenkins.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: jenkins
spec:
  replicas: 1
  selector:
    matchLabels:
      run: jenkins
  replicas: 1
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        run: jenkins
    spec:
      securityContext:
        fsGroup: 1000 
        runAsUser: 0
      containers:
      - name: jenkins
        image: jenkins/jenkins:2.222.4
        ports:
        - containerPort: 80
        volumeMounts:
        - name: jenkins-volume
          mountPath: /var/jenkins_home
      volumes:
      - name: jenkins-volume
        persistentVolumeClaim:
          claimName: jenkins-pvc
---
apiVersion: v1
kind: Service
metadata:
  name: jenkins
  labels:
    run: jenkins
spec:
  selector:
    run: jenkins
  ports:
  - name: jenkins
    port: 8080
    targetPort: 8080
    protocol: TCP
  - name: jenkins-agent
    port: 50000
    targetPort: 50000
    protocol: TCP
  type: LoadBalancer

command prompt(이하 cmd)를 열고 아래와 같이 진행합니다.

$ kubectl apply -f ./volume.yaml
$ kubectl apply -f ./jenkins.yaml
$ kubectl get pods # 파드가 제대로 구성되었는지 체크합니다.

 

http://localhost:8080 이동하면 아래 화면이 나타납니다.
만약 연결이 되지 않는다면 방화벽에서 Docker의 백엔드 포트를 허용해줍니다.

또한, 다음 포스팅에서 구성할 Github의 Webhook이 Jenkins에 접근할 수 있도록 해야합니다.

방화벽에서 포트 개방 혹은 포트포워딩 등 추가적으로 처리가 필요할 수 있습니다.

 

$ kubectl logs jenkins-5f98d9fd5d-hdf8z # jenkins의 파드명으로 로그를 조회합니다.

표시된 password를 위 빈 칸에 입력합니다.

로그에 키가 나오지 않는다면 다음과 같이 확인합니다.

$ kubectl exec -it <pod-name> /bin/bash
$ root@[pod-name]:/# cat /var/jenkins_home/secrets/initialAdminPassword

초기 설치단계에서 제안하는 플러그인만 설치하고 계정을 생성하여 설치를 완료합니다.

 

3) Kubernetes Cloud 설정

Jenkins 관리 -> 플러그인 관리에서 [Kubernetes] 플러그인을 찾아 설치합니다.
설치가 완료되면 Jenkins를 재시작한 뒤 Jenkins 관리 -> 시스템 설정으로 이동하고 맨 하단 Cloud로 이동합니다.

위 표시된 부분들을 입력하고 Pod Template를 추가해야 합니다.
Pod Template부분은 플러그인 공식 문서를 참고해서 동일하게 작성하면 됩니다.

 

Configure Clouds에 표시된 부분들도 공식 문서와 동일하게 작성하면 되지만 헤맬 수 있는 부분들이 있어 여기에 정리합니다.

- Kubernetes URL

$ kubectl config view # docker-desktop cluster의 server URL

 

- Kubernetes server certificate key , Credentials

아래 커맨드를 통해 secret의 name을 확인합니다.

$ kubectl get sa jenkins -o yaml # 초기에 설정했던 jenkins용 serviceaccount 조회

 

위에서 확인한 secret의 name을 조회해 ca.crt와 token을 확인합니다.

$ kubectl get secret <secret.name> -o yaml

ca.crt를 Base64로 디코딩하고 Kubernetes server certificate key에 넣어줍니다.


그리고 Credentials에서 키를 아래와 같이 추가합니다. secret란에 Base64로 디코딩한 token을 넣어줍니다.

 

- Kubernetes Namespace

초기에 설정했던 namespace인 dev
Service Account에는 namespace가 지정되어 있고 해당 계정으로 파드를 생성하면 이 namespace에 생성됩니다.

 

- Jenkins URL

jenkins의 URL

ex) http://0.0.0.0:8080

 

- Jenkins tunnel

jenkins의 URL에서 http://를 제외한 부분을 50000포트로 입력합니다.

ex) 0.0.0.0:50000

 

※ 설정 완료

Test Connection을 눌러서 제대로 연결이 성공하는지 확인합니다.

에러가 발생한다면 Kubernetes URL, Kubernetes server certificate key부분을 확인합니다.

 

 

다음 포스팅에서는 샘플 프로젝트의 소스를 github에 push할 때 빌드 및 테스트, 배포되도록 구성합니다.

'Docker' 카테고리의 다른 글

CI/CD with Jenkins & Docker & Kubernetes on Windows [2/2]  (0) 2020.05.30
댓글