![](https://uzilog-upload.s3.ap-northeast-2.amazonaws.com/private/ap-northeast-2%3Ab6c10628-1f45-492c-a9eb-f54020bc8014/1580873956910-image.png ) Jenkins는 2004년 개발된 이래 대표적인 CI / CD 툴로 자리잡았다. 2018년 기준 20.5만개의 Jenkins job과 200,000개 가까운 Jenkins 서버가 가동중이다. 그러나 2018년 Jenkins는 새로운 CI / CD 툴을 개발하여 공개하였다. 바로 Jenkins X 로서 왜 Jenkins는 잘나가는 Jenkins 툴을 두고 새로운 툴을 개발하였을까. 이유는 두가지가 있다. 첫째는 **클라우드** 시대가 되었으며 둘째는 **컨테이너 환경**이 되었다. 이러한 거대한 변화에도 불구하고 아쉽게도 기존 Jenkins로는 따라갈 수 없었다. 대표적인 문제는 아래와 같았다. - 장애가 나서 서비스가 내려갔을 경우 그동안의 git webhook 이벤트를 받을 수 없다. - Disk 공간을 사람이 직접 비워주고 관리를 해주어야 한다. - Plugin 버전이 맞지 않는 경우 장애가 발생한다. - Branch 가 여러개일 경우 속도가 느려진다. - JVM으로 인해 사용중이지 않을 경우에도 메모리를 잡아먹으며 클라우드 환경에서는 불필요한 비용이 발생한다 위와 같은 문제점들로 인해 Jenkins에서는 쿠버네티스 환경에 맞춘 새로운 CI / CD 툴인 Jenkins X 를 개발하게 된 것이다. Jenkins X는 컨테이너 환경에서 돌아가므로 Jenkins 만의 별다른 서버가 존재하지 않으며 기존에 제공하던 웹 UI도 더이상 제공하지 않는다. Jenkins X 에서 Web UI를 통해 설정을 하고 싶은 경우, [공식 문서에서 제안한](https://www.cloudbees.com/jenkins-x/what-is-jenkins-x)대로 사용할 수 있다. 또한 Jenkins X는 개발 환경으로 GitOps에서 추구하는 환경에 맞춰 설계되었다. GitOps란 DevOps와 반대되는 개념이 아니라, DevOps를 하기 위한 방법으로 Git을 활용하여 빌드 및 테스트, 배포를 하는 것이다. 여기서 CI 와 CD는 분리되어 CI가 끝나고 CD 로 이벤트를 보내면 CD 를 수행하는 식으로 동작을 한다. GitOps 관련하여 더 자세한 사항은 [이곳](https://www.weave.works/blog/what-is-gitops-really)을 참고한다. Jenkins X 에서 가장 중요한 개념을 꼽으라면 Pipeline이다. Jenkins X에서 수행되는 모든 과정들은 Pipeline을 통해 수행되며 이는 Jenkins X 내부를 보면 좀 더 이해하기 쉽다. Jenkins X는 Jenkins X로만 이루어 져 있는 것이 아니라, [Prow](https://github.com/kubernetes/test-infra/tree/master/prow) 와 [TEKTON](https://tekton.dev/)을 통해 실행된다. Jenkins X 내부 구조를 간단하게 살펴보면 아래와 같다. ![](https://uzilog-upload.s3.ap-northeast-2.amazonaws.com/private/ap-northeast-2%3Ab6c10628-1f45-492c-a9eb-f54020bc8014/1583483543838-image.png) 먼저 개발자가 Git Repository로 소스를 푸시한다. 특정 branch (master, develop etc.)에 푸시될 경우 Prow에서 이벤트를 받아 파이프라인을 처리한다. 그 후 TEKTON에서 실질적인 파이프라인을 수행하는데 그 전에 Jenkins X가 사전 작업을 수행 후 넘겨주며 최종적으로 우리의 귀엽고 예쁜 Application이 배포되게 된다. 이는 매우 간단하게 살펴본 구조이며 실질적인 구조는 아래와 같이 조금 복잡하다. ![](https://uzilog-upload.s3.ap-northeast-2.amazonaws.com/private/ap-northeast-2%3Ab6c10628-1f45-492c-a9eb-f54020bc8014/1583483716031-image.png) 먼저 Prow의 Hook pod이 Git Webhook을 통해 이벤트를 받아온다. 그런 다음 plugins 실행하고 trigger를 통해 1개 이상의 Prow job을 수행한다. 해당 Prow의 설정 부분을 간단히 보면 아래와 같다. ```yaml plugins: githubOrg/repoName: - approve - trigger [...] triggers: - repos: - githubOrg/repoName trusted_org: githubOrg ``` Job은 `presubmit`, `postsubmit` 두가지 종류가 있는데, presubmit은 master 브랜치에 머지 하기 전일 경우 실행되며 postsubmit은 master 브랜치의 변화로 웹훅이 실행된 경우 실행된다. Prow Job 설정 부분을 좀 더 자세히 살펴보면 아래와 같다.(불필요한 정보는 생략되었다.) ``` yaml apiVersion: prow.k8s.io/v1 kind: ProwJob metadata: labels: prow.k8s.io/job: pr-build prow.k8s.io/refs.org: githubOrg prow.k8s.io/refs.pull: "1" spec: agent: tekton context: pr-build job: pr-build refs: org: githubOrg pulls: - number: 1 type: presubmit ``` 여기서 눈여겨볼 점은 spec의 agent에 tekton이라 명시되어 있는 점이다. ProwJob이 생성되면 pipeline controller가 실행되는데 이 pipeline controller가 Pipeline을 실행하게 되며 여기서 실행될 도구를 설정하는 부분이 agent 부분이다. Prow에서는 기본적으로 tekton을 실행하며 이 외에 다른 도구들을 설정할 수도 있다. Jenkins X에서는 마찬가지로 이 tekton을 활용한다. pipeline controller는 컨트롤러로서 ReplicaSet Controller와 같이 반응한다. Pipeline Controller는 아래와 같이 2가지 모드가 존재한다. 1. `direct`: ProwJob이 생성되면 기본으로 설정된 Tekton을 이용하여 pipeline 수행 2. `delegate`: Tekton이 아닌 다른 도구를 이용하여 pipeline을 수행 그렇다면 Jenkins X에서는 어떻게 동작할까? 정답은 2번인 delegate 모드로 실행된다. 그 이유는 Jenkins X 에서 Tekton 파이프라인을 수행하기 전에 사전 동작을 한 후 tekton 파이프라인을 실행하기 때문이다. Prow의 Pipeline Controller를 통해 Jenkin X PipelineRunner Controller가 실행된다. 해당 컨트롤러를 통해 tekton에서 수행에 필요한 리소스들을 생성 한 후 tekton pipline을 실행시킨다. Tekton은 4가지의 개념이 있는데, `pipelineResource`, `pipelineRun`, `Pipeline`, `Task`들이다. 1개 이상의 Task들이 모여 Pipeline이 설정되고 해당 pipeline을 pipelineRun을 통해 수행된다. 이러한 pipeline 들은 pipelineResource에 모여있다. ![](https://uzilog-upload.s3.ap-northeast-2.amazonaws.com/private/ap-northeast-2%3Ab6c10628-1f45-492c-a9eb-f54020bc8014/1583484864525-image.png) Jenkins X 가 tekton을 실행시킨다는 의미는 이 pipelineRun을 실행시키는 것이며 이에 필요한 리소스인 Pipeline을 미리 생성하고 실행시킨다. 여기까지가 간략한 Jenkins X의 내부 동작이다. 이제 Jenkins X 실행을 위한 설정 파일을 알아보도록 하겠다. Jenkins X는 초창기에 설치하기 위해 `jx install` 명령을 사용했다. 그러나 인프라 관리를 위한 설치 도구로 Terraform이 등장하면서 초기 인프라 관련 설정은 넘기고 Jenkins X 실행을 위한 `jx boot`로 변경하였다. `jx install`로 AWS에서 실행하고자 한다면 실질적으로 `eksctl`을 통해 환경을 설치한다는 뜻이며 그 말은 Cloudformation을 활용 하는 것이다. `jx boot`를 통해 Jenkins X를 설치할 때는 쿠버네티스 환경은 어떤것이든 상관 없다. `jx install`을 통해 설치하거나, Terraform을 통해 설치하거나 또는 프러미스 환경에서 설치가 가능하다. 쿠버네티스가 있다면 Jenkins x를 설치할 수 있다. `jx boot`를 실행하기 위해선 `jx-requirements.yml`파일이 필요하다. ``` yaml cluster: clusterName: YOUR_CLUSTER_NAME devEnvApprovers: - uzihoon environmentGitOwner: uzihoon gitKind: github provider: eks region: ap-northeast-2 ``` 먼저 Cluster 설정 부분이다. 여기서는 Jenkins X가 실행될 환경에 관한 설정을 하는데, 크게 인프라 환경과 Git 환경을 설정한다. 우선 clusterName으로 현재 실행중인 Cluster 이름을 설정하며 provider로 쿠버네티스 환경을 정의한다. AWS의 경우 eks, GCP의 경우 gke로 설정하면 된다. 아쉽게도 이 외 Azure를 Beta로 지원하는 것 외에 [다른 클라우드 환경은 지원하지 않는다.](https://jenkins-x.io/docs/getting-started/setup/boot/clouds/) gitKind는 Git이 저장될 곳을 지정하는데 기본적으로은 Github 이며 디폴트 값을 사용할 경우 따로 설정할 필요가 없다. 이 외 Gitlab 이나 Bitbucket 또는 기업이나 개인에서 사용하는 깃 저장소를 정의해도 된다. Github을 사용하지만 Github에서 지정하는 URL과 다를 경우이거나, 다른 Git 저장소를 사용할 경우 `gitServer`를 통해 URL을 명시해 주면 된다. ```yaml cluster: gitKind: github gitServer: https://github.myserver.com ``` Jenkins X에서 Git 레퍼지토리는 기본적으로 Private인데, Public으로 설정하고자 할때는 `environmentGitPublic`를 true로 명시해주면 된다. ``` yaml environments: - ingress: domain: "" externalDNS: false namespaceSubDomain: "" tls: email: "" enabled: false production: false key: dev repository: environment-terraform-eks-demo-dev - ingress: domain: "" externalDNS: false namespaceSubDomain: "" tls: email: "" enabled: false production: false key: production repository: environment-terraform-eks-demo-production ``` 그 다음으로 배포 환경 설정을 해준다. `key`를 통해 `develop` 환경일 경우, `staging`, `production` 환경일 경우 등을 정의해준다. ``` yaml ### # secretStorage: storage type # * local # * valut - for cloud eg. EKS, GKE etc. ### secretStorage: local ``` secret storage는 config 정보등 secret 정보를 저장할 곳을 지정해 준다. local 과 valut가 있다. ``` yaml storage: backup: enabled: false url: "" logs: enabled: false url: "" reports: enabled: false url: "" repository: enabled: false url: "" ``` 백업파일, 로그 등을 저장할 storage 설정 부분이다. S3등을 이용한다면 url에 지정해 주면 된다. ``` yaml ### # webHook: engine for webhook and optionally supporting ChatOps # * prow - default for ChatOps and Serverless Jenkins X Pipelines with Tekton # * lighthouse - default for ChatOps and Serverless Jenkins X Pipelines with Tekton # and for git surver other than gitub # * jenkins - for static jenkins server ### webhook: prow ``` 가장 중요한 webhook 설정 부분이다. 기본값으로 prow가 설정되어 있으며 그 외에 `lighthouse`, `jenkins`등이 있다. ``` yaml ### # repository: for artifact repositories # * nexus - default # * bucketrepo # * none ### repository: nexus ``` repositry를 설정하는 부분으로 기본 값은 nexus가 있다. nexus로 설정할 경우 Jenkins X 에서 같이 실행 된다. `jx install`이 아닌 온프라미스나 테라폼등으로 설치 할 경우 `terraform`값을 true로 해주어야 한다. ```yaml terraform: true ``` `eksctl`로 설치 되었다 하더라도, `jx install`을 통해 설치하지 않았더라면 `terraform: true`는 필수이다. 위와 같이 설정하였다면 최종 파일은아래와 같다. ``` yaml autoUpdate: enabled: false schedule: "" cluster: clusterName: terraform-eks-demo devEnvApprovers: - uzihoon environmentGitOwner: uzihoon gitKind: github provider: eks region: ap-northeast-2 environments: - key: dev # - key: staging # - key: production kaniko: true ingress: domain: "" externalDNS: false namespaceSubDomain: "" tls: email: "" enabled: false production: false ### # secretStorage: storage type # * local # * valut - for cloud eg. EKS, GKE etc. ### secretStorage: local storage: backup: enabled: false url: "" logs: enabled: false url: "" reports: enabled: false url: "" repository: enabled: false url: "" vault: {} velero: schedule: "" ttl: "" versionStream: ref: v1.0.343 url: "" ### # webHook: engine for webhook and optionally supporting ChatOps # * prow - default for ChatOps and Serverless Jenkins X Pipelines with Tekton # * lighthouse - default for ChatOps and Serverless Jenkins X Pipelines with Tekton # and for git surver other than gitub # * jenkins - for static jenkins server ### webhook: prow ### # repository: for artifact repositories # * nexus - default # * bucketrepo # * none ### repository: nexus terraform: true ``` 설정 파일중 필수 값인데 빠져있을까봐 걱정할 필요 없다. `jx boot`를 실행했을 경우 없는 설정이라면 CLI를 통해 선택을 하도록 해준다. 이제 jx 를 통해 `jx boot`를 실행하면 Jenkins X가 설치된다. jx 설치방법은 [이곳](/post/0aa65480-45a3-11ea-8f9e-157ebb4cbd7f)에서 볼수 있다. 다음 시간엔 `jx boot`를 활용하여 Jenkins X 를 설치하고 CI / CD 환경을 구성하는 것을 다루도록 하겠다.