0부터 시작하는 Jenkins & GitLab 공부 - Jenkins & Kustomize & Helm

Jaehong Lee·2022년 10월 27일
post-thumbnail

Jenkins

출처 : 컨테이너 인프라 환경 구축을 위한 쿠버네티스 / 도커 p.279

파이프라인 & CI / CD

아래와 같은 과정을 파이프라인 이라고 한다

  1. 깃허브와 같은 저장소에 저장해둔 애플리케이션 소스 코드를 내려 받아 도커 컨테이너 이미지로 빌드
  2. 빌드한 컨테이너 이미지를 K8S 에서 사용할 수 있게 레지스트리에 등록
  3. 레지스트리에 등록된 이미지를 통해 K8S 오브젝트 생성
  4. 생성한 오브젝트를 서비스를 서비스 형태로 외부에 노출
  5. Service Mash 에 등록

이러한 파이프라인을 도구를 통해 자동화할 수 있다. 자동화는 CI 와 CD ( 지속적 통합과 지속적 배포 ) 로 정의된다


Jenkins

CI / CD 도구 중에서 Jenkins 는 CI / CD 도구의 대명사라고 해도 무리가 아니다

  • Jenkins 는 작업 내용을 Item 단위로 정의하고, 조건에 따라 자동으로 작업을 수행한다

소스 코드를 저장소에 Push 하면, 쿠버네티스 내부에 설치된 Jenkins 는 해당 코드로 애플리케이션을 빌드하고, 레지스트리에 푸시한 후에 쿠버네티스 오브젝트로 배포한다

  • 컨테이너 인프라 환경에서 Jenkins 를 사용하는 주된 이유는 애플리케이션을 컨테이너로 만들고, 배포하는 과정을 자동화하기 위함이다

  • Jenkins 에서 master 에게 전달할 때의 계정과 master 가 worker 에게 전달할 때의 계정이 다르므로 권한 문제가 있을 수 있다
  • Jenkins 를 Pod 형태로 배포하므로, 언제든 삭제될 수 있다. 따라서 영구적으로 Data 를 저장할 Volume 을 Master Node 에 두고 사용해야 한다
  • Jenkins Controller 가 명령을 내리면, Node 위에 Agent 파드가 생긴다. 해당 Pod 는 명령 수행 후 Controller 에게 보고하고, 보고 후 Agent 파드는 삭제된다

Jenkins Controller 가 단독으로 설치되면 모든 작업을 Jenkins Controller 단일 Node 에서 수행한다. 만약 Jenkins Controller - Agent 로 설치를 한다면, Jenkins 자체의 관리 및 CI / CD 와 관련된 설정은 Controller 에서 하고, 실제 Build 작업은 Agent 에서 실행한다

  • Control : Jenkins 관리 & 작업 설정
  • Agent : 작업 실행

실습 Code 가져오기

git clone https://github.com/beomtaek/cicd_samplecode.git
  • CI / CD Sample Code 를 git 에서 다운 받자

Kustomize

MetalLB 설치 Code 가져오기

mv kustomize-install.sh metallb.yaml metallb-l2config.yaml namespace.yaml metallb/

root@master:~/lab2/cicd_samplecode/metallb# ls
kustomize-install.sh  metallb-l2config.yaml  metallb.yaml  namespace.yaml
  • 사용할 4 개의 파일을 옮기자

Kustomize 로 MetalLB 구축

Kustomize 의 배포 대상은 Kustomize 파일 이다

sh kustomize-install.sh
  • Kustomize 를 설치하자
 kustomize create --namespace=metallb-system --resources namespace.yaml,metallb.yaml,metallb-l2config.yaml
  • kustomize create 를 이용해 kustomization.yaml 파일을 만들자. namespace 는 작업의 namespace 를 정의하며, resource 는 kustomization.yaml 를 만들기 위한 소스 파일들을 정의한다
root@master:~/lab2/cicd_samplecode/metallb# cat kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- metallb.yaml
- metallb-l2config.yaml
namespace: metallb-system
  • 만들어진 kustomization.yaml 확인
kustomize build | kubectl apply -f -
  • kustomization.yaml 을 이용해 매니페스트를 build 하고 이를 바로 배포하자. kubectl apply -f - 를 통해 빌드한 결과를 바로 전달하여 배포되게 한다
  • build 는 배포를 위한 매니페스트 파일을 만들어준다
docker pull metallb/speaker:v0.8.2
docker pull metallb/controller:v0.8.2

```shell
root@master:~/lab2/cicd_samplecode/metallb# k get pod -n metallb-system -o wide
NAME                          READY   STATUS             RESTARTS   AGE     IP              NODE      NOMINATED NODE   READINESS GATES
controller-675d6c9976-wlqx9   0/1     ImagePullBackOff   0          4m23s   172.16.182.17   worker3   <none>           <none>
speaker-2qszc                 1/1     Running            0          4m23s   192.168.8.101   worker1   <none>           <none>
speaker-9dn7m                 1/1     Running            0          4m23s   192.168.8.102   worker2   <none>           <none>
speaker-qp446                 1/1     Running            0          4m23s   192.168.8.100   master    <none>           <none>
speaker-v8nh4                 1/1     Running            0          4m23s   192.168.8.103   worker3   <none>           <none>
  • 잘 배포되었다

Helm

Helm 설치

  • Helm 기본 저장소 ( 아티팩트허브 ) : https://artifacthub.io/
  • 차트란? 다양한 요구 조건을 처리할 수 있는 패키지
  • Helm 의 배포 대상은 차트 ( 패키지 ) 이다
root@master:~/lab2/cicd_samplecode# chmod +x helm-install.sh
root@master:~/lab2/cicd_samplecode# ./helm-install.sh
  • 파일 권한을 설정하고, Helm 을 설치하자
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
chmod 700 get_helm.sh
export DESIRED_VERSION=v3.2.1
./get_helm.sh
  • Helm 을 설치하자
helm repo add edu https://iac-source.github.io/helm-charts
  • helm repo 를 등록하자
root@master:~/lab2/cicd_samplecode# helm repo list
NAME    URL
edu     https://iac-source.github.io/helm-charts
  • helm repo 가 잘 등록됬는지 확인하자
helm repo update
  • 저장소를 update 해주자

Helm 으로 MetalLB 구축

helm install metallb edu/metallb \
--namespace=metallb-system \
--create-namespace \
--set controller.tag=v0.8.3 \
--set speaker.tag=v0.8.3 \
--set configmap.ipRange=192.168.8.201-192.168.8.239
  • 위 명령어를 통해 MetalLB 구축이 가능하다

Jenkins 설치 - Kubernetes

Kubernetes로 Jenkins를 설치하자

p. 303

사설 저장소 구축

docker container run -d --restart=always --name registry -p 5000:5000 registry
docker run -d -p 8888:8080 --restart always --name registry-web --link registry -e REGISTRY_URL=http://192.168.8.100:5000/v2 -e REGISTRY_NAME=192.168.8.100:5000 hyper/docker-registry-web
  • 사설 저장소를 설치하고, 해당 저장소를 Web 에서 확인할 수 있게 구축하자

  • 8888 Port 로 잘 접속된다

허나 접속은 https 가 아닌 http 로의 접속이므로 이를 허용해 주어야 한다. 아랴와 같이 비 보안 접속 허용을 위한 구성을 모든 노드에 적용해 둔다

root@master:~/cicd/green# vi /etc/docker/daemon.json
{
	"insecure-registries" : [ "192.168.8.100:5000" ]
}
root@master:~/cicd/green# systemctl restart docker
  • 위 내용을 모든 노드에 적용하자

사설 저장소에 Image Push

root@worker1:~# docker image ls | grep brian24
brian24/testweb                      green      59c366d9922b   10 days ago     142MB
brian24/testweb                      blue       de012d57031e   10 days ago     142MB
  • 현재 다운 받은 Image 를 확인하자
root@worker1:~# docker tag brian24/testweb:green 192.168.8.100:5000/green:1.0
root@worker1:~# docker tag brian24/testweb:blue 192.168.8.100:5000/blue:1.0
root@worker1:~# docker push 192.168.8.100:5000/blue:1.0
root@worker1:~# docker push 192.168.8.100:5000/green:1.0
  • 해당 Image 를 192.168.8.100:5000/blue:1.0 과 green:1.0 으로 이름을 변경하여 사설 저장소에 Push 하자

  • 잘 Push 되었다

NFS 설치 및 설정

Helm 으로 설치되는 Jenkins 는 파드에서 동작하기에 PV 를 Mount 하지 않으면 Pod 가 다시 시작할 때 내부에 저장된 모든 Data 가 삭제된다. 따라서 PV 를 Mount 해야 한다

Jenkins Controller 의 Data 와 Pod 들의 Data 를 저장하기 위해 PV / PVC 를 사용해야 한다. 따라서 모든 노드에 NFS 를 설치하자. Worker Node 에도 설치하는 이유는 생성되는 Pod 들을 PV 와 Mount 시키기 위해서 이다

apt install -y nfs-server
  • master 에 nfs-server 를 설치하자
apt install -y nfs-common
  • 모든 Node 에 nfs-common 을 설치하자
systemctl enable nfs-server --now
  • nfs-server 를 실행하자
#!/usr/bin/env bash
nfsdir=/nfs_shared/$1
if [ $# -eq 0 ]; then
  echo "usage: nfs-exporter.sh <name>"; exit 0
fi

if [[ ! -d $nfsdir ]]; then
  mkdir -p $nfsdir
  echo "$nfsdir 192.168.8.0/24(rw,sync,no_root_squash)" >> /etc/exports
  if [[ $(systemctl is-enabled nfs) -eq "disabled" ]]; then
    systemctl enable nfs
  fi
    systemctl restart nfs
fi
  • 위 파일을 작성하여 실행하자. NFS 설정과 jenkins 디렉토리를 생성해준다
chmod +x nfs-exporter.sh
./nfs-exporter.sh jenkins
  • 파일을 실행하자
root@master:~/lab2/cicd_samplecode# ls -nl /nfs_shared/
total 4
drwxr-xr-x 2 0 0 4096 1027 16:23 jenkins
  • jenkins 를 위한 디렉토리가 공유 디렉토리에 생성되었다. 허나, Jenkins 에서는 1000 번으로 작업을 하므로 권한을 1000:1000 으로 변경해야 한다
chown 1000:1000 /nfs_shared/jenkins/
  • 해당 디렉토리에 권한을 변경해주자

PV & PVC 구성

Jenkins 는 사용자가 배포를 위해 생성한 내용과 사용자의 계정 정보와 같은 Data 를 저장하기 위해 PV 와 PVC 의 구성이 필요하다

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: jenkins
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  nfs:
    server: 192.168.8.100
    path: /nfs_shared/jenkins
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: jenkins
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi
  • PV 와 PVC 배포를 위한 yaml 파일 작성
kubectl apply -f jenkins-volume.yaml
  • 배포해주자
root@master:~/lab2/cicd_samplecode# k get pv,pvc
NAME                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM             STORAGECLASS   REASON   AGE
persistentvolume/jenkins   5Gi        RWX            Retain           Bound    default/jenkins                           38s

NAME                            STATUS   VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/jenkins   Bound    jenkins   5Gi        RWX                           38s
  • 배포한 PV 와 PVC 가 Bound 되었는지 확인하자

Jenkins 설치

root@master:~/lab2/cicd_samplecode# chmod +x jenkins-install.sh
root@master:~/lab2/cicd_samplecode# ./jenkins-install.sh
  • 다운 받은 파일중 Jenkins 설치 파일을 실행하자
root@master:~/lab2/cicd_samplecode# k get svc
NAME            TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)        AGE
jenkins         LoadBalancer   10.98.38.220    192.168.8.201   80:31457/TCP   4m56s
jenkins-agent   ClusterIP      10.111.60.164   <none>          50000/TCP      4m56s
kubernetes      ClusterIP      10.96.0.1       <none>          443/TCP        7h7m
  • 서비스에 jenkins 가 배포되었는지 확인하자
docker pull jenkins/inbound-agent:4.3-4
docker pull jenkins/jenkins:2.249.3-lts-centos7
docker pull kiwigrid/k8s-sidecar:0.1.193
  • 만약, 설치가 잘 안된다면 이미지 파일이 다운로드 되지 않는 문제일 수 있다. 위 이미지 3 개를 수동으로 다운 받자
root@master:~/lab2/cicd_samplecode# k get pod
NAME                       READY   STATUS    RESTARTS   AGE
jenkins-6f46869d7b-ncnsb   2/2     Running   0          11m
root@master:~/lab2/cicd_samplecode# ls /nfs_shared/jenkins/
casc_configs                                                              jobs
config.xml                                                                labels
copy_reference_file.log                                                   logs
hudson.model.UpdateCenter.xml                                             nodeMonitors.xml
hudson.plugins.git.GitSCM.xml                                             nodes
hudson.plugins.git.GitTool.xml                                            org.jenkinsci.main.modules.sshd.SSHD.xml
hudson.tasks.Mailer.xml                                                   plugins
hudson.triggers.SCMTrigger.xml                                            plugins.txt
identity.key.enc                                                          queue.xml.bak
io.jenkins.plugins.junit.storage.JunitTestResultStorageConfiguration.xml  secret.key
jenkins.fingerprints.GlobalFingerprintConfiguration.xml                   secret.key.not-so-secret
jenkins.install.InstallUtil.lastExecVersion                               secrets
jenkins.install.UpgradeWizard.state                                       updates
jenkins.model.GlobalBuildDiscarderConfiguration.xml                       userContent
jenkins.model.JenkinsLocationConfiguration.xml                            users
jenkins.security.apitoken.ApiTokenPropertyConfiguration.xml               war
jenkins.telemetry.Correlator.xml                                          workflow-libs
  • 잘 설치됬는지 확인하자

Jenkins 플러그인 설치

192.168.8.201 에 접속하여 admin/admin 으로 로그인하자

  • 플러그인 관리에 들어가자

  • Compatible 을 누르고 다운로드를 누르자

  • 재시작을 체크해주자

Jenkins 설정

  • Jenkins 관리의 시스템 설정에 들어가자. Jenkins URL 의 주소가 맞는지 확인하자

  • Jenkins 관리에서 Node 관리에 들어가자

  • Configure Clouds 에 들어가자

  • Pod Templates 를 누르자

  • Pod Template details 에 들어가자

  • Value 에서 주소를 201 로 수정

-/usr/bin/docker 로 수정하고, apply 및 save 하자

profile
멋진 엔지니어가 될 때까지

0개의 댓글