05. Week5 Jenkins on Kubernetes 아키텍처 (부록) - chuirang/DevOps GitHub Wiki
참고. Jenkins on Kubernetes 아키텍처 이해
목차
- Jenkins 아키텍처
- Jenkins on Kubernetes 아키텍처
Jenkins 아키텍처
VM기반의 Jenkins는 아래와 같은 문제점이 있다.
- Job이 수행되지 않을 때도 Slave에 대한 비용 발생
- 다수 Slave (노드) 별로 빌드, 배포 환경을 관리
- 특정 빌드 Job으로 Slave 리소스 과부하 발생
Jenkins on Kubernetes 아키텍처
Kubernetes 환경의 jenkins는 아래와 같은 장점이 있다.
- Job이 실행되지 않을 때는 Slave 를 유지할 필요가 없음
- 컨테이너 이미지를 사용해 일관된 환경에서 빌드, 배포를 수행
- 컨테이너 자원 제한을 이용한 리소스 관리
Jenkins를 Kubernetes 환경에서 사용한다는 것은 두 가지 의미가 있다.
-
Jenkins (Master) 를 Pod 형태로 실행시킨다. Pipeline 을 실행하면 Jenkins Agent 가 Pod 형태로 실행된다.
-
Jenkins 의 Pipeline 에서 Kubernetes 에 애플리케이션을 배포(갱신)한다.
Pipeline 을 생성하고 빌드를 실행하면 아래와 같이 실행된다.
그러하므로 Kubernetes 환경에서 Jenkins 를 사용하기 위해서는 아래와 같은 사항이 필요하다.
-
Jenkins Server (Master Pod) 가 API Server로 Pod 실행을 요청하기 위해서 적절한 인증과 허가가 필요하다. 이를 위해서 Service Account 와 RBAC 을 설정해줘야 한다.
-
Jenkins Slave (Job Pod) 가 Pipeline을 실행하기 위한 명령어가 충분히 갖춰진 컨테이너 이미지를 선택해야 한다.
- Docker build 과정을 위해서 docker 명령어가 설치된 컨테이너가 필요
- Deploly 과정을 위해서 kubectl 명령어가 설치된 컨테이너가 필요
이러한 과정을 효과적으로 관리하기 위해서는 Pod template에서 참조하는 이미지를 별도로 관리해야할 필요가 있다. (다만 본 실습의 목적은 Jenkins를 최적화하는 것이 아니므로 명령어가 설치된 임의의 container를 사용함)
참고로 Jenkins 의 Job Pod에 여러 개의 컨테이너 실행하는 경우 동일한 작업공간을 사용하므로, 서로의 결과(각 pipleline의 수행결과)를 참조할 수 있다.
Jenkins on Kubernetes 관련 이슈
- PV IO 성능으로 인한 이슈
- Agent Pod 의 스케쥴링 이슈
Jenkins on Kubernetes 를 위한 설정
Jenkins Agent를 Kubernetes Pod로 사용하기 위해서 아래와 같은 설정이 필요하다.
-
Master 에 할당된 기본 Build Executor 를 0으로 수정한다. Jenkins Dashboard > Manage Jenkins > Manage Nodes and Clouds > 우측화면의 master 에서 톱니모양(configure)
- Number of excutor: 0
해당 설정으로 좌측 바에서 Build Executor Status 의 Idle excutor가 사라진다.
-
Kubernetes 관련 Plugin 을 설치한다. (pipeline에서 kubectl을 사용하기 위해 kubectl CLI 플러그인을 설치하는 것은 별도이다.) Jenkins Dashboard > Manage Jenkins > Manage Plugins
- kubernetes 를 검색하여 체크하고 [Download now and install after restart] 를 수행한다.
-
Jenkins 가 Kubernetes 연동을 위해 사용할 Service Account와 RBAC을 생성한다.
## Service Account 생성 > Token 값 복사 $ kubectl create serviceaccount jenkins -n jenkins $ kubectl describe secret $(kubectl describe serviceaccount jenkins -n jenkins |grep Token | awk '{print $2}') -n jenkins $ kubectl create rolebinding jenkins-admin-binding --clusterrole=admin --serviceaccount=jenkins:jenkins -n jenkins
-
Jenkins 가 연동할 Kubernetes 를 등록해 준다.
- Jenkins Dashboard > Manage Jenkins > Manage Nodes and Clouds > 좌측 바의 Configure Clouds 선택
- Add a new cloud 를 눌러 kubernetes 를 선택하고 아래를 입력 한다.
-
Name: kubernets (default) *다른이름으로 지정하면 job에서 변경된 이름으로 정의해줘야 한다.
-
kubernetes Cloud details.. 클릭
-
Kubernetes URL: Kubernets API Server 입력
-
Kuberntes Namespace: jenkins (jenkins 를 설치한 네임스페이스 입력)
-
Credentials: [Add] 를 누른다.
- Kind: Secret text
- Scope: Global
- Secret: 위에서 생성한 Service Account의 Token을 넣는다
- ID: jenkins_on_kubernetes
-
상기의 설정이 정상이라면 [Test Connection] 이 정상적으로 성공되야한다.
-
Jenkins URL: http://jenkins.jenkins.svc.cluster.local
Jenkins Agent Pod 가 실행되면 Jenkins master로 연결이 되야하는데(jnlp container), 이를 위한 주소를 입력한다. (동일한 Kuberntes 환경에서 Pod-to-Svc 통신이므로 도메인을 입력하면 된다)
-
-
[Save] 를 눌러 저장한다.
-
Test Job 을 생성한다.
-
New Item > 이름 작성 > pipeline 선택 > [Save]
-
Pipeline 에서 [try sample pipeline] 을 누르고 'Declarative (Kubernetes)'를 선택하면 아래와 같은 샘플 파이프라인이 확인된다.
- agent 가 kuberntes 이고, inline pod yaml이 보인다. 이 pod yaml을 통해 Agent Pod가 실행되어 pipeline에 정의한 stages 가 실행된다.
// Uses Declarative syntax to run commands inside a container. pipeline { agent { kubernetes { // Rather than inline YAML, in a multibranch Pipeline you could use: yamlFile 'jenkins-pod.yaml' // Or, to avoid YAML: // containerTemplate { // name 'shell' // image 'ubuntu' // command 'sleep' // args 'infinity' // } yaml ''' apiVersion: v1 kind: Pod spec: containers: - name: shell image: ubuntu command: - sleep args: - infinity ''' // Can also wrap individual steps: // container('shell') { // sh 'hostname' // } defaultContainer 'shell' } } stages { stage('Main') { steps { sh 'hostname' } } } }
- Build Now 를 누른다.
-