클라우드 네이티브 애플리케이션 부트캠프 알림

티스토리 뷰

Agile&DevOps/CI, CD 툴 설치

Jenkins 설치

Happy@Cloud 2019. 9. 12. 13:01

1. 사전준비

- nfs dynamic provisioning

happycloud-lee.tistory.com/178?category=832243

 

2. Jenkins설치

- helm repository를 추가합니다.

$ helm repo add bitnami https://charts.bitnami.com/bitnami 
$ helm repo update

- helm chart를 다운로드 하고, 압축을 풉니다. 그리고 jenkins디렉토리로 이동합니다. 

$ mkdir ~/install && cd ~/install
$ helm search repo jenkins
NAME           	CHART VERSION	APP VERSION	DESCRIPTION                                       
bitnami/jenkins	12.4.4       	2.426.1    	Jenkins is an open ..

$ helm pull bitnami/jenkins 
$ tar xvf jenkins-12.4.4.tgz
$ cd jenkins

 

- jenkins.yaml을 아래 예제를 참고하여 적절히 수정하십시오. 

persistence.storageClass는 kubectl get sc로 확인하고 맞게 수정해야 합니다. 

global:
  storageClass: "nfs-retain"

##
jenkinsUser: admin
jenkinsPassword: "P@ssw0rd$"
jenkinsHost: "http://myjenkins.io"
jenkinsHome: /bitnami/jenkins/home

## 한글 안깨지게 charset 지정 
javaOpts:
  - -Dfile.encoding=UTF-8
  
agent:
  enabled: true

containerPorts:
  http: 8080
  https: 8443
  agentListener: 50000

agentListenerService:
  enabled: true
  type: ClusterIP
  ports:
    agentListener: 50000

##
service:
  ##
  type: NodePort
  ##
  ports:
    http: 80
    https: 443
  ##
  nodePorts:
    http: "32080"
    https: "32443"
##
ingress:
  enabled: true
  pathType: ImplementationSpecific
  ##
  hostname: myjenkins.io
  path: /
  ingressClassName: "nginx"

##
persistence:
  enabled: true
  storageClass: "nfs-retain"
  accessModes:
    - ReadWriteOnce
  size: 8Gi
  
## 아래 옵션은 minikube에 설치할 때만 필요 
tls:
  autoGenerated: true
  password: P@ssw0rd$

 

- 설치 

--dry-run옵션은 설치 전 테스트를 하는 옵션입니다. 

$ kubectl create ns jenkins

$ kubens jenkins

$ helm install jenkins -f jenkins.yaml bitnami/jenkins --dry-run

$ helm install jenkins -f jenkins.yaml bitnami/jenkins

 

- 확인

$ watch kubectl get po로 모든 Pod가 실행될때까지 기다립니다. 약 5분정도 걸립니다. 

작업  PC의 hosts파일에 ingress host를 등록 합니다. 

ingress 주소로 웹브라우저에서 접근하고, jenkins.yaml에서 지정한 id와 암호로 로그인 합니다. 

 

Jenkins 환경설정

1) jenkins plugin 추가

- [Available] TAB을 클릭하고, 설치할 plugin을 검색한 후, 하단의 [Install without restart]를 선택하세요.

설치할 Plugin은 아래와 같습니다.

- Kubernetes

- Pipeline Utility Steps

- Docker Pipeline

- GitHub

- Slack Notification

- Blue Ocean

플러그인은 병렬로 설치할 수 있습니다. [Install without restart]를 클릭하고, 다른 플러그인을 설치하십시오.

모두 설치하는데 약 5분 정도로 걸리므로, 그정도 기다렸다가
아래와 같이 [Installed]탭 클릭 후 맨 아래로 내려 [Restart Once No Jobs Are Running]을 클릭하여 restart합니다.

 

Plugin의 일부 모듈이 설치 실패하는 경우 Plugin 수동 설치 

plugin 일부 모듈 설치 안되는 경우가 있습니다.  

다시 시도하면 또 몇개는 설치되고 또 다시 시도하면 몇개 또 추가로 설치되는 식입니다.  

이런 경우 아래와 같이 해 보십시오. 

- update site 변경

좌측 'Advanced Settings'를 누르고 'https://'를 'http://'로 변경하십시오.

로그 아웃 했다가 다시 로그인 하고 다시 설치 해 봅니다. 

 여전히 실패하는 경우 아래와 같이 해 보십시오. 

- nginx ingress controller의 Body size와 timeout 늘리기 

Body size와 timeout을 충분히 먼저 늘려 줍니다.  그리고 다시 시도해 봅니다. 

k edit ing jenkins 

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/proxy-body-size: 300m
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "360s"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "360s"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "360s"

그래도 안되면 아래 방법으로 수동 설치 합니다. 

- 실패한 모듈의 URL 찾기

실패 로그에 보면 'hpi'로 끝나는 모듈 다운로드 URL이 있습니다.  

이 URL을 복사합니다.  

- 수동 설치

좌측 Advanced Setting을 누르고 수동 설치 합니다. 

그래도 실패하면 모듈 주소로 hpi파일을 다운로드 한 후 파일을 지정하여 설치합니다.  

 

2) System 설정

slack설정을 빼고는 다른 항목은 기본값 그대로 사용하면 됩니다.

중요한 설정은 아래와 같습니다.

- 동시 실행 수: 0이면 한번에 1개의 Pipeline만 수행됨

- Jenkins 주소: 설치 시 지정한 ingress주소로 지정되므로, 그대로 사용합니다.

- Docker image registry 정보: Pipeline script에서 지정하기 때문에 값은 셋팅하지 않아도 됩니다.

* Docker Pipeline 플러그인을 설치해야 나오며,

Pipeline script에서 'docker.withRegistry(..'명령을 사용하려면 이 플러그인을 설치해야 합니다.

- github에 webhook설정할 때 github를 위한 jenkins secret설정할 때 지정합니다.

'GitHub'플러그인을 설치해야 나오며, 사용법은 'Webhook추가'편을 참조하세요.

- Slack 설정

'Slack Notification'플러그인을 설치해야 나오며, 자세한것은 'Slact 연동'편을 참고하세요.

3) kubernetes 연결 설정

- jenkins가 설치된 namespace의 service account 'jenkins'에게 적절하게 권한을 부여합니다. 

모든 namespace에 배포할 권한을 부여하려면 아래와 같이 cluster-admin역할을 부여합니다.

kubectl create clusterrolebinding {name} --clusterrole=cluster-admin --serviceaccount={jenkins가 설치된 namespace}:jenkins

예) kubectl create clusterrolebinding crb_jenkins --clusterrole=cluster-admin --serviceaccount=jenkins:jenkins 

 

- 'Clouds'를 클릭합니다. 

- 새로운 Cloud를 작성합니다. 이름은 적절히 지정하시고, Type은 Kubernetes를 선택합니다. 

 

- Kubernetes cluster정보를 입력합니다. 

. Kubernetes URL은 'default' namespace에 있는 service 객체의 주소를 입력합니다. 

아래와 같이 https://kubernetes.default라고 입력하면 됩니다. 

. Kubernetes Namespace에는 Jenkins가 설치된 namespace를 입력합니다. 

[Test Connection]을 클릭하여 연결되는지 확인합니다.

 

- Jenkins URL은 jenkins namespace에 생성된 Service객체의 이름과 포트와 맞게 지정합니다. 

[kbdemobastion@bastion jenkins]$ k get svc -n jenkins
NAME                     TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                     
jenkins                  NodePort    10.97.200.111   <none>        80:32080/TCP,443:32443/TCP  
jenkins-agent-listener   ClusterIP   10.106.77.80    <none>        50000/TCP

 

Tunneling할 50000번 포트를 활성화 합니다.

 


 

계정 및 권한 관리

학습 목적으로 Jenkins를 사용한다면 admin user만 있으면 되므로 이 작업은 필요 없습니다. 

하지만 실무에 사용하려면 계정과 권한관리는 반드시 하셔야 합니다. 

 

1) 계정 관리

계정관리를 위해서는 Security Realm(렐름)의 옵션을 설정해야 합니다.  

'Jenkins 관리 > Security'를 클릭 하십시오. 

기본은 'Jenkins own user database'로 되어 있고 '사용자의 가입 허용'은 체크되어 있지 않습니다. 

계정을 관리하는 방법은 아래와 같이 5가지가 있습니다. 

이 글에서는 제일 많이 사용하는 'Jenkins own user database'와 'LDAP'옵션에 대해서만 설명 합니다. 

- Delegate to servlet container: 서블릿 컨테이너를 사용하여 컨테이너를 인증하는 방식이라는데 Jenkins 1.163이전 버전 사용시만 유효한 것이므로 그 이후 버전은 절대 체크하지 마십시오

- Jenkins own user database: Jenkins가 자체 계정관리를 하는 경우 선택하십시오. 사용자에게 계정을 스스로 만들게 허용하려면 '사용자의 가입 허용'을 체크하십시오.

- LDAP: LDAP에서 계정관리를 하는 경우 선택 하십시오. LDAP설정 방법은 아래에서 설명 합니다. 

- Unix user/group database: OS의 user/group을 이용하는 방법입니다. 실무에서 거의 사용하지 않아 별도로 설명하지 않겠습니다. 

-  None: 계정관리를 하지 않겠다는 뜻이고 로그인 없이 사용할때만 선택하셔야 합니다.  이 옵션을 선택할 때는  반드시 그 밑에 있는 Authorization 섹션에서 'Anyone can do anything'을 선택하셔야 합니다. 

Tip) Security Realm 옵션을 잘못 선택하여 Jenkins를 사용 못하게 되었을 때 초기화 방법

Jenkins설정 파일인 config.xml파일을 아래와 같이 수정하고 재시작하면 로그인 없이 접근할 수 있습니다. 

그 다음에 Global Security 설정을 다시 하면 됩니다.

$ cd /var/lib/jenkins
$ vi config.xml
useSecurity, authorizationStrategy, securityRealm 항목을 아래와 같이 변경

<useSecurity>true</useSecurity>
<authorizationStrategy class=”hudson.security.AuthorizationStrategy$Unsecured”/>
<securityRealm class=”hudson.security.SecurityRealm$None”/>


$ systemctl restart jenkins

 

Security Realm: Jenkins own user database 옵션

이 옵션은 Jenkins 자체적인 DB에 계정관리를 하는 방법 입니다. 

옵션을 체크하고 '사용자의 가입 허용' 은 필요 시 체크 하십시오.

그리고 일단 Authorization 옵션은 아래와 같이 선택 하십시오. 

이제 admin을 로그 아웃하고 로그인 페이지를 보면 아래와 같이 '계정 생성' 메뉴가 보일 겁니다. 

계정을 생성 하고 그 유저로 로그인 되면 성공 입니다. 

 

Security Realm: LDAP 옵션

LDAP서버에서 계정 관리를 하려면 이 옵션을 선택 하십시오. 

먼저 'LDAP' 플러그인을 설치해야 옵션이 제공 됩니다. 

그리고 아래 글을 참조하여 LDAP서버를 설치 하고 유저와 그룹도 생성 하십시오. 

https://happycloud-lee.tistory.com/117

 

LDAP서버 설치

LDAP서버를 설치하는 방법은 docker로 설치하는 방법과 k8s Pod로 설치하는 방법이 있습니다. 빠르게 설치하려면 docker로 설치하십시오. 실제 업무에 적용할때는 Pod로 설치하여 이중화하는것이 좋습

happycloud-lee.tistory.com

 

이제 Jenkins의 Security Realm 옵션을 LDAP으로 바꾸시면 LDAP서버 연결 정보를 셋팅하는 화면이 나옵니다. 

LDAP이 아래와 같이 구성 되었다면 이 정보를 참조하여 아래 예와 같이 셋팅하시면 됩니다. 

Server의 주소는 Jenkins 설치 형태에 따라 아래와 같이 구하십시오.

Jenkins를 k8s Pod로 설치한 경우

Jenkins Pod에서 LDAP Pod를 LDAP service명으로 접근할 수 있습니다. 

아래 예와 같이 LDAP service명을 구합니다. 그리고 ldap://{ldap service name}.{ldap이 설치된 namespace}라고 입력 합니다. 

아래와 같다면  ldap://ldap-openldap.ldap 이라고 입력하면 됩니다. 

Jenkins를 VM에 설치한 경우

Jenkins에서 LDAP Pod를 LDAP의 service명으로 접근할 수 없습니다. 

아래 예제와 같이 LDAP service에 externalIPs를 추가하여 Jenkins에서 IP로 접근할 수 있도록 합니다. 

$ kubectl edit svc ldap-openldap -n ldap

externalIPs항목을 추가하고 k8s cluster의 아무 node의 IP를 추가 합니다. 
...
spec:
  ...
  externalIPs:
  - 169.56.70.197
  internalTrafficPolicy: Cluster
...

이제 위에서 지정한 external IP를 LDAP Server정보에 지정 합니다. 

만약 LDAP host가 DNS나 /etc/hosts에 등록 하였다면 IP대신에 LDAP hostname을 지정해도 됩니다. 

root DN, User search base, Group search base는 LDAP  구성 정보를 참조하여 셋팅 합니다. 

Group search filter는 LDAP Group생성 시 선택한 objectclass명을 입력하면  됩니다. 

기본 값은 아래와 같습니다. 정확하게 정의하고 싶으면 'objectclass=groupOfUniqueNames'라고 하면 됩니다. 

(& (cn={0}) (| (objectclass=groupOfNames) (objectclass=groupOfUniqueNames) (objectclass=posixGroup)))

Manager DN/Manager Password는  LDAP admin의 정보를 입력하면 됩니다. 

그 외 항목은 기본 값을 그대로 사용 하십시오. 

 

하단에 있는 [Test LDAP settings]를 클릭하고 LDAP에 등록한 user로 테스트 해 봅니다.

아래와 같이 인증이 성공하면 잘 셋팅된 것입니다.  

일단 Authorization은 아래와 같이 하시고 LDAP에 등록한 유저로 로그인해 보십시오.  

잘 되십니까 ? 그럼 이제 권한 설정으로 넘어 가겠습니다. 

 

하나 더 작업 하셔야 합니다. Jenkins를 admin으로 로그인하면 이제 안될겁니다. 

왜냐하면 LDAP설정 시 user를 'ou=users'밑에서 찾으라고 'User search base'를 지정했기 때문입니다. 

아래와 같이 'ou=users'밑에 'admin' 유저를 추가 하십시오. 그럼 이제 admin으로도 로그인이 되실 겁니다. 

 

2) 권한(Authorization) 설정

위에서 새로운 유저로 로그인해 보면 admin과 동일한 권한이 일반 유저에게도 부여된 것을 확인할 수 있을겁니다.

또한 다른 유저가 만든 파이프라인도 모두 보이구요. 

이제 권한 설정을 하여 일반 유저는 부여 받은 기능과 접근 가능한 파이프라인만 관리할 수 있도록 하겠습니다. 

먼저 LDAP에 아래 예제와 같이 admin group을 만들고 멤버로 ou=users밑에 만든 'admin'을 추가 하십시오. 

Jenkins의 'Security'를 여십시오. 

'Authorization'에서 'Project based Matrix Authorization Strategy'옵션을 선택 합니다. 

이 옵션이 표시 안돼면 플러그인 'Matrix Authorization Strategy'을 설치한 후 수행 하십시오. 

 

옵션의 종류에는 아래와 같은 것이 있습니다. 

- Anyone can do anything: 로그인 했던 안했든 admin과 동일하게 모든 기능과 파이프라인을 사용할 수 있습니다. 

- Legacy mode: Jenkins 1.164이전에만 사용할 수 있는 옵션이므로 무시 하셔도 됩니다 

- Logged-in user can do anything: 로그인한 유저만  admin과 동일하게 모든 기능과 파이프라인을 사용할 수 있습니다. 

- Matrix-based security: 유저/그룹별로 사용할 수 있는 기능을 설정할 수 있습니다. 파이프라인에 권한을 설정할 순 없습니다. 

- Project-based Matrix Authorization Strategy: 유저/그룹별로 기능과 파이프라인 권한을 설정할 수 있습니다. 파이프라인별 권한 설정은 각 파이프라인의 '구성(Configuration)'에서 합니다.  여기서 'Project'란 파이프라인을 의미 합니다. 

아래 예제와 같이 admin그룹을 추가하고 모든 권한을 부여 합니다. 

Authenticated Users에게는 Overall read와 Job  Build, Cancel, Congigure, Delete 기능만 부여 합니다. 

파이프라인 권한 설정 테스트를 위해 admin 유저로 'test'파이프라인을 만듭니다. 

이제 admin을 로그아웃하고 일반 유저로 로그인해 보십시오.  아래 예제와 같이 일부 기능만 보이고 admin이 만든 'test'파이프 라인도 안 보일 겁니다. 

이제 파이프라인에 권한을 부여해 봅시다. 

먼저 테스트를 위해 LDAP에 아래 예제 처럼 user 'dev1', 'user1'을 만들고, group developers를 만든 후 멤버로 'dev1'만 추가 합니다. 

위에서 만든 'test'파이프 라인에 대해 group 'developers'에게는 권한을 주고 user 'user1'에게는 권한을 부여하지 않도록 해봅시다. 

아래와 같이 'test'파이프라인을 열고 '구성'메뉴를 선택 하십시오.

그리고 'Enable project-based security'를 체크한 후 group 'developers'만 추가 합니다. 

user 'user1'은 별도로 추가하지 않아도 이미 'Global security'설정에서 Job에 대한 'Read'권한이 없도록 했기 때문에 본인 파이프라인 외에는 보이지 않게 됩니다.  

이제 developers그룹의 멤버인 'dev1'으로 로그인 하면 아래와 같이 'test'파이프라인이 보일겁니다.

 

 


VM에 설치하기

Pod가 아닌 VM에 직접 설치하려면 아래와 같이 설치하십시오.

1) openjdk, maven설치 : https://happycloud-lee.tistory.com/186

jenkins는 2021.12.2일 현재 java 1.8과 java 11만 지원하므로, java11을 설치 하십시오. 

 

2) git설치

centos: yum install git -y
ubuntu: apt-get install git -y

 

3) jenkins 설치

centos

설치를 위한 repository를 추가합니다. 

sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo

RPM key를 import합니다. 이때 주소는 아래 페이지에서 확인하십시오. 

https://pkg.jenkins.io/redhat-stable/

 

 

Redhat Jenkins Packages

Jenkins Redhat Packages To use this repository, run the following command: sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key If you've pre

pkg.jenkins.io

위에서 구한 rpm key 주소를 이용하여 impor합니다. 

예시)
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key

 

jenkins를 설치 합니다. 

sudo yum install jenkins -y

설치 시 아래와 같은 에러가 나면 아래 2개 라이브러리를 설치하고 다시 설치하십시오. 

yum install epel-release
yum install daemonize -y

 

ubuntu

- jenkins저장소 Key다운로드
wget -q -O - https://pkg.jenkins.io/debian/jenkins-ci.org.key | sudo apt-key add -

- source.list에 추가
echo deb http://pkg.jenkins.io/debian-stable binary/ | sudo tee /etc/apt/sources.list.d/jenkins.list

- Key 등록
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys FCEF32E745F2C3D5

- apt-get 재 update
apt-get update

- Jenkins 설치
apt-get install jenkins

 

4) port 체크,  JAVA_HOME지정

jenkins의 기본 포트는 8080입니다. 이 포트를 사용하고 있는지 검사하여, 사용중이면 다른 포트로 바꿉니다. 

netstat -an | grep 8080

centos

/etc/sysconfig/jenkins파일의 JENKINS_PORT값을 변경합니다. '80'은 사용할 수 없습니다. 

$ vi /etc/sysconfig/jenkins

...
# Set to -1 to disable
#
JENKINS_PORT="9080"

...

$ systemctl start jenkins 
이미 시작했으면, systemctl restart jenkins로 재시작

$ systemctl status jenkins

* 2023-12-03: 최신 버전에는 위 /etc/sysconfig/jenkins파일이 없는듯 하다. 

/usr/lib/systemd/system/jenkins.service 파일 안에서 아래 부분의 PORT번호를 변경한 후, 

# Port to listen on for HTTP requests. Set to -1 to disable.
# To be able to listen on privileged ports (port numbers less than 1024),
# add the CAP_NET_BIND_SERVICE capability to the AmbientCapabilities
# directive below.
Environment="JENKINS_PORT=11180"

 

jenkins.service파일안의 JAVA_HOME에 Java를 설치한 위치를 지정합니다.

2024.6월 현재 openjdk11까지만 지원합니다. 

# The Java home directory. When left empty, JENKINS_JAVA_CMD and PATH are consulted.
Environment="JAVA_HOME=/usr/lib/jvm/java-11-openjdk-11.0.23.0.9-2.el7_9.x86_64"

 

아래와 같이 daemon-reload와 jenkins 재시작을 한다. 

$ systemctl daemon-reload
$ systemctl restart jenkins

* 만약 firewall이 올라가 있다면 바뀐 포트를 열어주는거 잊지 말자 !

$ firewall-cmd --permanent --add-port=11180/tcp
$ firewall-cmd --reload

 

ubuntu

ubuntu는 /etc/init.d/jenkins파일에서 수정 합니다. 

$ vi /etc/init.d/jenkins
...
check_tcp_port "http" "$HTTP_PORT" "9080" "$HTTP_HOST" "0.0.0.0" || return 2
...

$ systemctl daemon-reload

 

참고로, jenkins의 username은 jenkins이고, Home디렉토리는 /var/lib/jenkins입니다. 

 

5) jenkins를 system service로 등록하고 시작

systemctl enable jenkins
systemctl start jenkins

6) 로그인 

- 작업 PC의  hosts파일에 host를 등록 합니다. 

예) 

169.56.77.150 myjenkins.io

- jenkins를 웹페이지에서 오픈합니다. 

http://myjenkins.io로 접근합니다. 

아래와 같은 화면이 나오고, 초기 암호는 /var/lib/jenkins/secrets/initialAdminPassword파일에 있습니다. 

 

 

아래 화면이 나오면, 첫번째 옵션을 선택하여, 추천 플로그인을 설치합니다. 

 

 

admin계정을 생성합니다. 

jenkins url을 지정합니다. 저는 가비아의 DNS서버에 등록했기 때문에 아래와 같이 도메인으로 지정할 수 있습니다. 

DNS가 없는 분들은 wildcard DNS를 이용하세요.  http://jenkins.{VM public ip}.nip.io:{port}로 지정하시면 됩니다. 

예) http://jenkins.169.56.84.30.nip.io:8080

 

아래와 같이 나오면 성공입니다. 

 

추가작업

1) jenkins user를 docker 그룹에 추가하고, docker.sock의 모드를 변경하여야, pipeline에서 docker 명령을 사용할 수 있습니다. 

usermod -a -G docker jenkins

sudo chmod 666 /var/run/docker.sock

2) podman을 사용하는 경우 아래 작업도 해줘야 에러가 안남

echo jenkins:10000:65536 >> /etc/subuid
echo jenkins:10000:65536 >> /etc/subgid

 

'Agile&DevOps > CI, CD 툴 설치' 카테고리의 다른 글

Nexus 설치 및 구성  (0) 2020.06.12
GitLab image registry 설치 및 사용 환경 구성  (0) 2019.09.12
SonarQube 설치  (0) 2019.09.12
gitlab 설치  (0) 2019.09.12
NFS서버 만들기  (0) 2019.09.12
댓글

클라우드 네이티브 애플리케이션 부트캠프 알림