Jenkins

이진욱·2024년 10월 30일

깃허브에 새로운 커밋이 발생하면
젠킨스는 끌고와서 도커로 보낸다=dockerrunner

컨테이너 환경에서의 CI/CD
CI (Continuous Integration)
코드를 커밋하고 빌드했을 때 정상적으로 작동하는지 여부를 반복적으로 검증해 (sonaqube) 애플리케이션의 신뢰성을 높이는 작업
CI 과정을 마친 애플리케이션은 신뢰할 수 있는 상태가 된다
개발자가 소스를 커밋, 푸시하면 CI 단계로 진입 애플리케이션이 자동으로 빌드되고 테스트를 거쳐 배포할 수 있는 애플리케이션인지 여부를 확인) 통과시 CD 단계로 전환

CD (Continuous Deployment)
CI에서 생성된 신뢰할 수 있는 애플리케이션을 실제 환경에 자동으로 배포
미리 정의된 실수를 줄이고, 실제 적용 시간을 최소화할 수 있다
애플리케이션을 컨테이너 이미지로 만들어서 파드, 디플로이먼트, 스테이트풀셋 등 다양한 오브젝트 조건에 맞춰 미리 설정한 파일을 통해 배포

CI 에서는 개발자가 hub에 올려둔 코드를 pull하여 코드의 유효성을 검사하기 위한 테스트
단계를 거친다. 이때 sonaqube 와 같은 툴을 이용한다 코드가 문제가 없다면 이를 이미지로 생성한다.

CD
Delivery: 생성된 이미지를 hub에 push한다 > push된 이미지는 master 노드에 의해 각 node에 pull 된다 . 모든 node에 배치 된다 애플리케이션 배포직전단계
Deployment: 각 노드에 배치된 이미지를 이용하여 Pod를 배포하는 단계

위의 작업을 수동으로 배포하였으나 CI/CD에 대한 다양한 자동화 툴이 제공되어 현재는
모든과정을 자동화 시킬 수 있다.
개발자가 code를 push하고 부터 최종 애플리케이션 배포까지의 작업라인을 "pipeline" 이라 부른다.
물론 전체 자동화가 무조건 적으로 좋은것은 아니다 중간에 검증을 위해 이를 수동으로 배포할 수도 있고, code push -> 그 다음 pipeline ci가 돌아가기 직전,code repo를 지정된 시간에 pull 하여 배포가 되도록 할 수도 있다.
예를 들어 팀원들에게 오후5시까지 모든 코드를 push하도록 하고 끝나면 이를 6시까지 팀장이 이를 확인한다. 6시가 되면 자동으로 파이프라인이 동작하여 repo에 있는 (팀장이 검증을마친)
코드를 pull 한 뒤 이미지 생성-> 허브로 push-> 노드에 pull ->애플리케이션 배포가 될 수 있도록한다

Jenkins를 이용
-master node에 직접 설치하는 방법(bare metal)
-cluster 환경에 Pod로 배포하는방법
-원격지에 있는 리눅스 서버에 설치하여 운영하는 방법.

bare metal을 이용한 실습

ubuntu 22.04.dp jenkins 설치하기

sudo apt update
sudo apt install openjdk-11-jdk -y

curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key | sudo tee \
    /usr/share/keyrings/jenkins-keyring.asc > /dev/null

echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] \
    https://pkg.jenkins.io/debian-stable binary/ | sudo tee \
    /etc/apt/sources.list.d/jenkins.list > /dev/null

sudo apt update

sudo apt install jenkins -y

sudo systemctl enable jenkins --now
sudo systemctl status jenkins

이후 http://접속주소:8080

Install suggested plugins


프로젝트 생성방식
프리스타일은 명령어방식이다
코드 재사용은 불가

복잡한 내용은 pipelime =gitlabci.yml




vi /etc/sudoers 수정 
root@master:~/lab5# usermod -aG docker jenkins
root@master:~/lab5# 

저장후

플레이버튼 눌러준다

권한오류 sudo 추가 수정후 재시작


도커에 추가한 이미지 pull해서 deployment생성하기

root@master:~# java -version
openjdk version "11.0.24" 2024-07-16
OpenJDK Runtime Environment (build 11.0.24+8-post-Ubuntu-1ubuntu322.04)
OpenJDK 64-Bit Server VM (build 11.0.24+8-post-Ubuntu-1ubuntu322.04, mixed mode, sharing)
root@master:~# #bare metal로 다시 실행하려면 java 업데이트하라!

두번째 실습


1.shell yml 파일로 선언형 채택 지울 필요없이 업데이트 가능
규모가 큰곳에선 shell 중간에 문제가 발생하면 처리가 불가
2.젠킨스 파일에 넣는다
3.ansible 멱등성 적용

모든 젠킨스 삭제

root@master:~# ls /var/lid/jenkins
root@master:~# rm -rf /etc/init.d/jenkins
root@master:~# rm -rf /var/log/jenkins
root@master:~# rm -rf /var/log/jenkins

원격지 ansible이용 실습

[user1@localhost ~]$ sudo echo "alias vi='vim'" >> /home/user1/.bashrc
[user1@localhost ~]$ source ~/.bashrc
[user1@localhost ~]$
[user1@localhost ~]$ sudo vi /etc/ansible/hosts

원격지에서 jenkins + ansible + k8s 을 이용한 CI/CD

ansible에서 각 노드에 접속하기 위한
keypair 생성후
각 노드들에게 퍼블릭키 제공

ssh-keygen -t rsa -b 4096 # 젠킨스 노드에 키생성 

ssh-copy-id root@211.183.3.100
ssh-copy-id user1@211.183.3.101
ssh-copy-id user1@211.183.3.102
ssh-copy-id user1@211.183.3.103


Ansible의 ansible.cfg 파일이나 플레이북에서 명시적으로 키 경로를 지정할 수 있습니다.
[root@localhost ~]# vi /etc/ansible/ansible.cfg



모니터링

컨테이너 인프라 환경 모니터링

  • 프로메테우스 서버

    -노드 익스포트 외 여러 대상에서 공개된 메트릭 수집해 오는 collector
    -수집한 시계열 메트릭 데이터를 저장하는 시계열 데이터베이스
    -저장된 데이터를 질의하거나 수집 대상의 상태를 확인할 수 있는 웹 UI

  • 노드 익스포터
    -설치된 노드에서 특정 파일들을 읽고 이를 프로메테우스 서버가 수집할 수 있는 매트릭 데이터로 변환한 후 노드 익스포터에서 HTTP 서버로 공개

kube-state-metrics
API 서버 쿠버네티스 클러스터의 여러 메트릭 데이터를 수집한 후, 이를 프로메테우스 서버가 수집할 수 있는 메트릭 데이터로 변환해 공개하는 역할

컨테이너 인프라 환경 모니터링 p498~

alertmanager

alert 규칙을 설정하고, 경보 이벤트가 발생하면 설정된 정보 메시지를 대상에게 전달
프로메테우스에 설치시 서버에서 주기적으로 경보를 보낼 대상을 감시해 시스템을 안정화
pushgateway

배치와 스케줄 작업 시 수행하는 일회성 작업들의 상태를 저장하고 모아서 프로메테우스가 주기적으로 가져갈 수 있도록 함
일반적으로 짧은 시간동안 실행되고 종료되는 배치성 프로그램의 메트릭을 저장하거나 외부망에서 접근할 수 없는 내부 시스템의 메트릭을 프로메테우스 형태로 제공하는 용도로 사용

helm 368p

다수의 yaml파일을 패키지 형태로 관리가능하다
helm chart
쿠버네티스 리소스 생성하기 위해 필요한 파일을 모아놓은 디렉토리
쿠버네티스 리소스 최적화 쉬움

헬름설치

wget  https://get.helm.sh/helm-v3.9.4-linux-amd64.tar.gz
tar xvfz helm-v3.9.4-linux-amd64.tar.gz
mv linux-amd64/helm /usr/local/bin

root@master:~# helm version
version.BuildInfo{Version:"v3.9.4", GitCommit:"dbc6d8e20fe1d58d50e6ed30f09a04a77e4c68db", GitTreeState:"clean", GoVersion:"go1.17.13"}
root@master:~# 
root@master:~# helm repo list 
Error: no repositories to show

helm repo 추가와 kube-prometheus-stack 다운로드

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm pull prometheus-community/kube-prometheus-stack

접속 패스워드 수정하기

root@master:~/kube-prometheus-stack# vi values.yaml

namespace 생성하고 해당 네임스페이스에 프로메테우스 등 설치하기

root@master:~/kube-prometheus-stack# kubectl create namespace monitoring
namespace/monitoring created
root@master:~/kube-prometheus-stack# helm install prometheus . -n monitoring -f values.yaml
NAME: prometheus
LAST DEPLOYED: Thu Oct 31 16:15:47 2024
NAMESPACE: monitoring
STATUS: deployed
REVISION: 1
NOTES:
kube-prometheus-stack has been installed. Check its status by running:
  kubectl --namespace monitoring get pods -l "release=prometheus"

Visit https://github.com/prometheus-operator/kube-prometheus for instructions on how to create & configure Alertmanager and Prometheus instances using the Operator.

kubectl edit service -n monitoring prometheus-grafana

kubectl edit service -n monitoring prometheus-kube-prometheus-prometheus

cAdvisor를 통한 메트릭 수집

root@master:~/kube-prometheus-stack# k create deploy nginx --image=nginx
deployment.apps/nginx created

그라파나에서 대시보드 만들어보기

프로메테우스 메트릭 데이터를 그라파나의 소스 데이터로 구성하기

es,os 차이

임포트 패널

남들거 가져와서 나의 내용추가해가지고
새로운 패널 생성

대시보드 가져오기

남들이 만들어놓은 템플릿가져와서 데이터만 뿌리기



다양한 차트로 변경가능하다 .

특정 네임스페이스에서의 실행중인 파드갯수

default 네임스페이스의 Pod별 메모리 사용량

외부에 공개

sonaqube 사용

SonarQube는 코드 품질 관리를 위한 오픈소스 도구로, 버그, 보안 취약점,
코드 스멜을 감지해줍니다.
주요 기능: 버그 및 보안 취약점 감지, 코드 스멜 분석, 코드 커버리지 확인,
품질 게이트 설정
지원 언어: Java, JavaScript, Python, PHP 등 다양한 언어
CI/CD 통합: Jenkins, GitLab, GitHub Actions와 연동 가능
목적: 코드 품질을 자동으로 검사해 안정적이고 깨끗한 코드 유지 지원
SonarQube는 지속적인 코드 품질 관리와 보안 강화를 위해 사용됩니다.

https://github.com/SonarSource/sonar-scanning-examples.git

여기서 테스트할 코드를 내 깃허브로 포크하기
젠킨스에서 코드를 끌어와 검사를 하고 배포를 한다 .
젠킨스와 소나큐브의 연결할 플러그인을 설치한다

jenkins 설치
sonarqube 설치
jenkins 에서 sonarqube 연결을 위한 plug-in 설치
plug-in 이용하여 sonar 연결
github 에 코드 commit -> push
jenkins 에서 pipeline 또는 freestyle 이용하여 stages 시작. 결과
결과 리포트 확인

1.젠킨스 설치

자바 설치

apt install openjdk-21-jdk -y 

자바의 경로를 PATH 변수 안에 포함시켜준다

PATH=$PATH:/usr/lib/jvm/java-21-openjdk-amd64/bin/    # 경로에 파일  있는지 여부 미리 확인하고 작성

젠킨스 repo. 등록하고 설치

wget -p -O - https://pkg.jenkins.io/debian/jenkins.io.key | sudo apt-key add -
sh -c 'echo deb http://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'
apt update
apt install jenkins -y

젠킨스 실행

systemctl enable jenkins
systemctl start jenkins
systemctl status jenkins

2. sonarqube 설치

결과 리포트를 저장하기 위해 별도의 DBMS 가 필요하다. 이를 위해 postgreSQL 을 설치한다.

postgreSQL 설치

#저장소, 공개키 추가, 설치
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt/ `lsb_release -cs`-pgdg main" >> /etc/apt/sources.list.d/pgdg.list'

wget -q https://www.postgresql.org/media/keys/ACCC4CF8.asc -O - | sudo apt-key add -

sudo apt install -y postgresql postgresql-contrib

sudo systemctl enable postgresql

sudo systemctl start postgresql

postgreSQL 이 정상적으로 설치되면 로컬에 아래와 같이 postgres 라는 사용자가 생성된다

postgreSQL 에서 sonarqube 를 위한 DB, 사용자(소나큐브 사용할 수 있는 사용자) 등 생성

su - postgres
createuser sonar
psql   # postgreSQL 로 진입

ALTER USER sonar WITH ENCRYPTED password 'test123';
CREATE DATABASE sonarqube OWNER sonar;
GRANT ALL PRIVILEGES ON DATABASE sonarqube to sonar;
\q

소나큐브 설치

sudo apt install -y zip
wget https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-9.0.1.46107.zip
unzip sonarqube-9.0.1.46107.zip
rm -rf sonarqube-9.0.1.46107.zip
mv sonarqube-9.0.1.46107 /opt/sonarqube

sonarqube 사용자 그룹 생성


sudo groupadd sonar
sudo useradd -d /opt/sonarqube -g sonar sonar
sudo chown sonar:sonar /opt/sonarqube -R  # /opt/sonarqube 하위의 모든 파일과 디렉토리를 sonar 그룹, sonar 사용자에게 소유권을 부여한다.

3. 소나 큐브 구성하기

파일 내용 수정하기

vi /opt/sonarqube/conf/sonar.properties

sonar 에서 postgre 접속을 위한 연결 내용 추가

sonar.jdbc.url=jdbc:postgresql://localhost:5432/sonarqube

스크립트를 수정하여 sonarqube 를 실행하는 사용자를 sonar 로 변경한다.

vi /opt/sonarqube/bin/linux-x86-64/sonar.sh

systemctl start sonar 와 같이 sonarqube 를 실행,중지,enable 할 수 있도록 서비스로 등록한다.

vi /etc/systemd/system/sonar.service 

아래 내용을 추가한다.

[Unit]
Description=SonarQube service
After=syslog.target network.target

[Service]
Type=forking

ExecStart=/opt/sonarqube/bin/linux-x86-64/sonar.sh start
ExecStop=/opt/sonarqube/bin/linux-x86-64/sonar.sh stop

User=sonar
Group=sonar
Restart=always

LimitNOFILE=65536
LimitNPROC=4096

[Install]
WantedBy=multi-user.target

서비스를 시작한다.

sudo systemctl enable sonar
sudo systemctl start sonar
sudo systemctl status sonar

커널 시스템 코드를 일부 수정하여 최대 사용가능한 파일수, 크기 등을 변경한다. why? git 으로 부터 많은양의 파일을 clone 하여 scan 할 수 있도록.

vi /etc/sysctl.conf 에 아래 내용을 추가한다.

vm.max_map_count=262144
fs.file-max=65536
ulimit -n 65536
ulimit -u 4096

변경된 내용을 반영할 수 있도록 재부팅 한다.

init 6

재부팅 이후 systemctl status sonar

웹을 통한 접속 확인 및 사용자 생성
http://211.183.3.100:9000

4. sonarscanner 설정하기

sudo mkdir /opt/sonarscanner

cd /opt/sonarscanner

sudo wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.6.2.2472-linux.zip

sudo unzip sonar-scanner-cli-4.6.2.2472-linux.zip

sudo rm sonar-scanner-cli-4.6.2.2472-linux.zip

vi sonar-scanner-4.6.2.2472-linux/conf/sonar-scanner.properties

sudo ln -s /opt/sonarscanner/sonar-scanner-4.6.2.2472-linux/bin/sonar-scanner /usr/local/bin/sonar-scanner

sonar-scanner 하고 그냥 엔터하면 동작하는지 여부까지만 확인!!!

4. 분석된 결과를 jenkins 로 통보하기 위해 webhook 을 등록한다.

5. jenkins 에서 plug-in 추가하여 sonar-qube 설정하기

플러그인 추가하기

SonarQube Server 등록하기
대시보드 > Jenkins 관리 > System 에서 SonarQube servers 항목으로 들어간 뒤, 아래와 같이 소나큐브의 서버정보를 등록한다. 이름과 주소는 이후 파이프라인을 동작시킬 때 사용하므로 별도로 복사해 둔다. 토큰은 서버 등록 이후 다시 돌아와서 등록할 수 있으므로 일단 이름, 주소만 등록하고 저장한다.

Name: sonarQube-Server, Server URL : http://211.183.3.100:9000


Global Tools Configuration (scanner 등록하기 - 스캐너 버전을 선택하여 어떤 스캐너를 동작시킬 것인지 선택할 수 있다.)

6. pipeline 동작 시키기

item 누르고 들어와서

script 동작시키기

pipeline {
    agent any
    stages {
        stage('SCM') {
            steps {
                git branch: "master",
                    url: "https://github.com/jinwuk97/sonar-scanning-examples.git"
            }
        }

        stage('SonarQube analysis') {
            steps {
                withSonarQubeEnv('sonarQube-Server') {
                    // sonar-scanner 실행
                    sh '''
                        cd ./sonar-scanner
                        sonar-scanner \
                          -Dsonar.projectKey=test \
                          -Dsonar.sources=. \
                          -Dsonar.host.url=http://211.183.3.100:9000 \
                          -Dsonar.login=36388a365ca95c39a205a2f6d0fa9fb92d510e36
                    '''
                }
            }
        }

        stage('결과 출력') {
            steps {
                script {
                    def scannerResult = sh(
                        script: 'sonar-scanner -Dsonar.projectKey=test -Dsonar.sources=. -Dsonar.host.url=http://211.183.3.100:9000 -Dsonar.login=36388a365ca95c39a205a2f6d0fa9fb92d510e36',
                        returnStatus: true
                    )

                    if (scannerResult == 0) {
                        echo "작업이 정상적으로 마무리 되었음"
                    } else {
                        echo "오류 발생"
                    }
                }
            }
        }
    }
}

profile
클라우드 엔지니어가 되어보자!

0개의 댓글