gloriaJun / til

Lessoned Learned
3 stars 0 forks source link

Configuration jenkins with docker #143

Open gloriaJun opened 2 years ago

gloriaJun commented 2 years ago

Server spec

Table of content

gloriaJun commented 2 years ago

Installation Jenkins with Docker

Create volume directory

/var/jenkins_home에 매핑해주기 위한 디렉토리를 생성하고, 해당 디렉토리에 대한 권한을 변경해준다. (sudo 권한을 가진 사용자로 작업해주어야한다)

sudo /usr/sbin/useradd jenkins -u 1000
sudo /usr/sbin/usermod -aG docker jenkins

sudo mkdir -p /home1/irteam/jenkins_home
sudo chown -R jenkins:docker /home1/irteam/jenkins_home

docker-compose 생성

# docker-compose-jenkins.yml
version: '3'
services:
  jenkins:
    image: jenkins/jenkins:lts
    container_name: jenkins
    privileged: true
    restart: always
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /usr/bin/docker:/usr/bin/docker
      - $HOME/jenkins_home:/var/jenkins_home
    ports:
      - 80:8080
    environment:
      - TZ=Asia/Seoul

Create docker container

docker-compose -f docker-compose-jenkins.yml up -d

정상적으로 jenkins가 생성되었는 지와 초기 password 확인을 위해 아래와 같이 log를 확인해본다

docker container logs jenkins

Access to Jenkins web browser

<jenkins_server_domain>:80으로 접속하면, 아래와 같은 화면을 확인할 수 있다.

초기 패스워드를 log에서 확인하지 못한 경우, 아래의 명령어를 통하여 확인할 수 있다.

docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword

Install suggested plugins

로그인 후에 Install suggested pluins 버튼을 통해 기본적인 플러그인들을 설치해준다.

gloriaJun commented 2 years ago

Update Jenkins version in Docker

docker 환경으로 설치된 jenkins 업데이트를 위한 방법

Connect to docker container

docker container exec -u 0 -it jenkins bash

Download war file with wget

wget <jenkins war link url>

Move war file

mv ./jenkins.war /usr/share/jenkins
chown jenkins:jenkins /usr/share/jenkins/jenkins.war
exit

Restart docker container

docker container restart jenkins
gloriaJun commented 2 years ago

Add slave node

slave node를 생성하고, master와 연결해준다.

Generate ssh key of master server

master server의 jenkins로 접속해서 ssh key를 생성한다.

[irteam@ci-master ~]$ docker container exec -it jenkins /bin/bash
jenkins@f81705b28f66:/$ ssh-keygen -t rsa -C "jenkins-master"
Generating public/private rsa key pair.
Enter file in which to save the key (/var/jenkins_home/.ssh/id_rsa):
Created directory '/var/jenkins_home/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /var/jenkins_home/.ssh/id_rsa
Your public key has been saved in /var/jenkins_home/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:gwPOKn/0PhBQCb1jITLtXG/xae1D9VmFXVTtjsyxass jenkins-master
The key's randomart image is:
+---[RSA 3072]----+
| ..+..         +X|
|o + = .     . . +|
| = +.+ o o . . + |
|  oo=.o.+ o   + .|
|   .o+o.So   o = |
|   .o  . .o   = .|
|. .. o     . .   |
| o  . o    .o    |
|  .. ...   .E.   |
+----[SHA256]-----+

생성한 공개키를 확인한다.

jenkins@f81705b28f66:/$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC****** jenkins-master

Regist ssh key of master server to slave node server

slave 노드 서버에 접속해서 앞에서 생성한 master node의 공개키를 등록한다.

만약, ~/.ssh/authorized_keys 가 없다면 아래와 같이 생성해준다.

cd ~
mkdir .ssh
chmod 700 .ssh
cd .ssh
touch authorized_keys
chmod 644 authorized_keys

master node의 공개키를 클립보드로 복사한 뒤에 authorized_keys 파일에 붙여넣는다.

아래와 같이 master node에서 slave node 서버로 ssh를 이용하여 접속이 되는 지 확인한다.

jenkins@f81705b28f66:/$ ssh <username>@<slave_node server hostname>
The authenticity of host '<slave_node server hostname> (10.241.43.26)' can't be established.
ECDSA key fingerprint is SHA256:JRhdTGqvANvFIdQjVoSoBoaPf/K3lItFteFHHspIeAw.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '<slave_node server hostname>,10.241.43.26' (ECDSA) to the list of known hosts.
Last login: Thu Apr 21 18:42:23 2022 from 10.231.201.89
[<username>@<slave_node server hostname> ~]$

Create a Credential for slave node

Jenkins 관리 -> Manage Credentials에서 slave 노드의 정보를 등록해준다.

Add slave node

Jenkins 관리 -> 노드 관리 -> 신규 노드에서 slave node를 생성한다.

create-node create-node-ssh

노드가 정상적으로 등록이 되면 아래와 같이 확인할 수 있다.

node-status
gloriaJun commented 2 years ago

Install Custom Jenkins plugins

다음으로는 추가적으로 필요한 plugin 들을 설치해준다.

====

Warnings Next Generation

ESLint와 같은 정적 분석 도구에 대한 리포트를 생성하기 위해 설치 https://plugins.jenkins.io/warnings-ng/

docker pipeline https://plugins.jenkins.io/docker-workflow/

SSH Pipeline Steps

pipeline 내에서 ssh 명령어를 사용하기 위함 https://plugins.jenkins.io/ssh-steps/ Embeddable Build Status 빌드 상태 뱃지 등록을 위한 플러그인? https://plugins.jenkins.io/embeddable-build-status/ Slack Notification Plugin https://plugins.jenkins.io/slack/ Merics https://plugins.jenkins.io/metrics/

gloriaJun commented 2 years ago

Integrate GitHub Repository

Jenkins와 GitHub 연동을 위한 과정이다.

Configure OAuth with GitHub and Authorization

Installation Jenkins GitHub OAuth Plugin

GitHub Authentication를 설치하면 GitHub 계정과 연동하여 Jenkins 인증 처리를 할 수 있다.

github-oauth-plugin

Create GitHub OAuth Apps

GitHub 계정과 연동을 위해서는 GitHub OAuth 설정을 해주어야하는데, 해당 작업을 위해서 먼저 GitHub OAuth App을 등록한다. GitHub → Settings → Developer Settings → OAuth Apps

Configure GitHub OAuth Setting

Jenkins 관리 → Configure Global Security → Global GitHub OAuth Settings에서 GitHub OAuth 정보를 입력하여 설정한다.

github-oauth-setting

Authorization

로그인한 사용자에 대한 세부 권한 설정은 Authorization에서 다음과 같은 방법으로 정의한다.

github-oauth-setting

Configure Github Server

Add Credential

먼저, Settings - Developer Settings - Personal Access Token에서 아래와 같은 권한을 부여하여 token을 생성한다. image

그 다음, Jenkins 관리 -> Manage Credentials에서 GitHub 연동에 사용할 인증 정보를 등록한다.

Configure Github Server Information

Jenkins 관리 → 시스템 설정 → GitHub 에서 연동할 Github server 정보를 설정한다.

github-server

Configure GitHub Enterprise Servers

GitHub Enterpriese Server를 사용하는 경우, 아래와 같은 정보를 추가로 등록해준다.

github-server

Configure Github App for Credential

Jenkins에서 GitHub Repository 인증 등을 위해 GitHub App을 통하여 진행을 위해 GitHub에서 GitHub App을 생성한다.

Create GitHub App

GitHub → Settings → Developer Settings → GitHub Apps에서 신규로 생성한다.

github-apps

Generate Private key

생성한 GitHub App의 private key를 생성한다.

github-apps-private-key

private key 가 생성이 되면, PEM 포멧의 파일이 로컬의 ~/Download 경로에 다운로드 되어진다. Terminal을 이용하여 해당 경로로 이동 후, 아래와 같이 해당 파일의 포맷을 변경한다.

openssl pkcs8 -topk8 -inform PEM -outform PEM -in jenkins-app.2022-04-25.private-key.pem -out converted-jenkins-app.pem -nocrypt

Install App

해당 GitHub App을 사용할 repo를 선택하여 설치해준다.

organization의 경우에는 해당 owner의 승인이 필요하다.

github-apps-install

Add Credential for GitHub App

Jenkins 관리 -> Manage Credentials에서 GitHub App 인증 정보를 등록한다.

github-apps-credential
gloriaJun commented 2 years ago

Installation Jdk 11

Jenkins 관리 -> Global tool configuration에서 JAVA_HOME을 설정해준다. jdk-11

References

gloriaJun commented 2 years ago

Notification

빌드 결과나 특정 stage 결과에 대하여 slack, email 등과 같은 방법으로 알림을 발송하기 위한 설정이다.

Slack

Generate Slack Channel Token

  1. slack 채널에 앱을 설치하기 위한 화면으로는 다음과 같은 두 가지 방법을 이용할 수 있다. 1-1. Slack 메신저에서 이동

    1. slack 앱에서 jenkins 알림을 보내기 위해 More → Apps를 클릭한 뒤, 노출되는 Apps 리스트에서 jenkins를 검색하여 해당 app을 클릭한다.
    2. Jenkins app에 대한 화면에서 Configuration 버튼을 누르면, 웹페이지에서 slack app directory 화면이 노출되는데..여기서 다시 Add to Slack 버튼을 눌러 채널 설정을 위한 화면으로 이동한다. slack-app-dir-by-app

    1-2. 웹브라우저에 "https://(Slack Workspace 명).slack.com/apps"를 입력하여 이동 image

  2. slack 알람을 보내고자 하는 채널을 선택한다. image

Configure Jenkins

  1. "Jenkins 관리 → 플러그인 관리"에서 slack plugin을 설치한다.  jenkins_slack_plugin

  2. "Jenkins 관리 → Manage Credentials"에서 slack 연동을 위한 인증 정보를 등록한다. jenkins-slack-credentail

  3. "Jenkins 관리 → 시스템 설정" 에서 "Slack" 매뉴에서 연동을 위한 설정을 한다.

    • workspace: slack 토큰 생성 시 Setup Instructions의 "Team Subdomain"
    • Credentials: 앞에서 생성한 slack 인증 정보 image

Modify Jenkinsfiles for slack nofity

#!/usr/bin/env groovy

void notifySlack(String message, String color) {
  slackSend (channel: '<channel_name>', color: color, message: message + ": Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})")
}

pipeline {
  // ...SKIP

  stages {
    // ...SKIP
  }

  post {
    success {
      script {
        def previousResult = currentBuild.previousBuild?.result

        if (!previousResult || (previousResult && previousResult != currentBuild.result)) {
          notifySlack ('SUCCESS', '#00FF00')
        }
      }
    }
    unstable {
      notifySlack ('UNSTABLE', '#FFFF00')
    }
    failure {
      notifySlack ('FAILED', '#FF0000')
    }
  }
}