[24단계 실습으로 정복하는 쿠버네티스] 책으로 스터디를 진행하였다.
Push 기반 파이프라인 구성
이전 스터디에서 사용한 구성을 기반으로 GitOps 도구를 추가 배포하였다.
Jenkins 구축
GitLab은 Git 기반의 웹 기반 Git 저장소 관리 서비스로, GitHub과 유사한 기능을 제공한다.
GitHub과 다른점은 GitLab은 로컬에 직접 구축할 수가 있다는 점이다.
나만의 Git 저장소를 구축하고자할 때 많이 사용하는 오픈소스이며, 무료로 사용할 수 있는 CE(Community Edition) 버전과 유료로 구매해야하는 EE(Enterprise Edition) 버전으로 나뉜다.
Jenkins 설치
// Jenkins Chart 저장소 추가 및 최신화
(ersia:default) [root@kops-ec2 ~]# helm repo add jenkins https://charts.jenkins.io
"jenkins" has been added to your repositories
(ersia:default) [root@kops-ec2 ~]#
(ersia:default) [root@kops-ec2 ~]# helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "jenkins" chart repository
...Successfully got an update from the "harbor" chart repository
...Successfully got an update from the "gitlab" chart repository
Update Complete. ⎈Happy Helming!⎈
// Jenkins Helm Chart 버전 확인
(ersia:default) [root@kops-ec2 ~]# helm search repo jenkins -l | head -n 10
NAME CHART VERSION APP VERSION DESCRIPTION
jenkins/jenkins 4.3.9 2.387.1 Jenkins - Build great things at any scale! The ...
jenkins/jenkins 4.3.8 2.387.1 Jenkins - Build great things at any scale! The ...
jenkins/jenkins 4.3.7 2.387.1 Jenkins - Build great things at any scale! The ...
jenkins/jenkins 4.3.6 2.387.1 Jenkins - Build great things at any scale! The ...
jenkins/jenkins 4.3.5 2.375.3 Jenkins - Build great things at any scale! The ...
jenkins/jenkins 4.3.4 2.375.3 Jenkins - Build great things at any scale! The ...
jenkins/jenkins 4.3.3 2.375.2 Jenkins - Build great things at any scale! The ...
jenkins/jenkins 4.3.2 2.375.2 Jenkins - Build great things at any scale! The ...
jenkins/jenkins 4.3.1 2.375.2 Jenkins - Build great things at any scale! The ...
// 추가 설정을 위해 로컬에 Jenkins chart 다운로드
(ersia:default) [root@kops-ec2 ~]# helm fetch jenkins/jenkins --untar --version 4.3.9
(ersia:default) [root@kops-ec2 ~]# tree jenkins -L 1
jenkins
├── CHANGELOG.md
├── Chart.yaml
├── README.md
├── templates
├── VALUES_SUMMARY.md
└── values.yaml
1 directory, 5 files
// 아래의 내용을 수정
(ersia:default) [root@kops-ec2 ~]# vim jenkins/values.yaml
---------------------------------------------------------
48 adminUser: "admin" ## admin 계정
49 # adminPassword: <defaults to random> ## admin 패스워드
98 jenkinsUriPrefix: "/jenkins" ## Ingress Controller에서 사용할 도메인 Prefix
440 ingress:
441 enabled: true ## Ingress Controller(ALB)를 사용하기 때문에 true로 설정
454 apiVersion: "networking.k8s.io/v1" ## Ingress Controller(ALB)를 사용할 버전
456 annotations:
457 alb.ingress.kubernetes.io/scheme: internet-facing
458 alb.ingress.kubernetes.io/target-type: ip
459 alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
460 alb.ingress.kubernetes.io/certificate-arn: 'arn:aws:acm:ap-northeast-2:411158671563:certificate/859d1e7f-5fc8-4e05-9da5-75a4d542ef1c'
461 alb.ingress.kubernetes.io/healthcheck-path: /login ## TargetGroup의 Healthcheck 경로 추가
462 kubernetes.io/ingress.class: alb
466 ingressClassName: alb
470 hostName: jenkins.ersia.net ## ingress path를 "/" 로 사용하는 도메인
---------------------------------------------------------
// Jenkins용 namespace 생성
(ersia:default) [root@kops-ec2 ~]# kubectl create ns jenkins
namespace/jenkins created
// 수정한 helm chart로 Jenkins 설치
(ersia:default) [root@kops-ec2 ~]# helm install jenkins jenkins/jenkins -f ~/jenkins/values.yaml --namespace jenkins --version 4.3.9
NAME: jenkins
LAST DEPLOYED: Fri Mar 24 03:39:24 2023
NAMESPACE: jenkins
STATUS: deployed
REVISION: 1
NOTES:
1. Get your 'admin' user password by running:
kubectl exec --namespace jenkins -it svc/jenkins -c jenkins -- /bin/cat /run/secrets/additional/chart-admin-password && echo
2. Visit http://jekins.ersia.net
3. Login with the password from step 1 and the username: admin
...
...
// 설치 확인
(ersia:default) [root@kops-ec2 ~]# helm list -n jenkins
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
jenkins jenkins 1 2023-03-24 03:31:08.418133193 +0900 KST deployed jenkins-4.3.9 2.387.1
참고 : https://github.com/jenkinsci/helm-charts/blob/main/charts/jenkins/VALUES_SUMMARY.md
Node의 사양이 낮으면 TargetGroup 활성화까지 5분 가량 소요되는 것으로 보인다.
정상적으로 설치가 완료되면 Ingress Controller(ALB) 1개가 생성된 것과 설정한 hostname이 ALB 규칙에 host로 입력된 것을 확인할 수 있다.
(ersia:default) [root@kops-ec2 ~]# kubectl get ingress -n jenkins
NAME CLASS HOSTS ADDRESS PORTS AGE
jenkins <none> jenkins.ersia.net k8s-jenkins-jenkins-b4abd65e2d-1673322677.ap-northeast-2.elb.amazonaws.com 80 4m24s
Jenkins 설치 후 웹페이지 접속
설치 시 입력한 hostname URL로 접속하면 로그인 가능한 웹페이지를 확인할 수 있다. (예시 : jenkins.ersia.net)
만약 helm chart에서 ingress path와 jenkinsUriPrefix를 별도로 설정해주었다면 URL Path를 붙여서 접속하면 된다. (jenkins.ersia.net/jenkins)
기본 사용자와 패스워드는 adminUser 설정으로 생성한 사용자명과 임의로 생성된 초기 패스워드 이며, 패스워드는 쿠버네티스안의 jenkins service에 아래의 명령어를 수행해 확인할 수 있다.
// Jenkins 설치 시 임의로 생성되는 초기 패스워드
(ersia:default) [root@kops-ec2 ~]# kubectl exec --namespace jenkins -it svc/jenkins -c jenkins -- /bin/cat /run/secrets/additional/chart-admin-password && echo
mm3VzumMqCH0hXMwspetwp
Jenkins사용자 생성
최초 admin 계정으로 로그인 후 Dashboard -> Jenkins 관리 -> Jenkins’ own user database 페이지에서 사용자 계정을 생성할 수 있다.
일반적으로 root 계정으로 직접 작업하기보다 사용자 계정을 생성하고 계정 별 권한을 분리해 작업하는게 보안상 권장된다.
Build를 위한 Kubernetes용 Jenkins 노드(k8s node가 아님) 생성
Dashboard -> Jenkins 관리 -> 노드관리 -> Configure Clouds 페이지에서 Kubernetes에 접속할 수 있도록 설정한다.
Kubernetes URL은 kubeconfig에서 확인되는 api 서버 URL을 입력한다.
(ersia:default) [root@kops-ec2 ~]# cat ~/.kube/config
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: ~~~~~~
server: https://api.ersia.net
name: ersia.net
Jenkins에서 kubernetes에 접근하기위해 인증정보가 필요하므로 Credentials을 새로 등록한다.
Jenkins 전역에서 사용하도록 Global 설정을 선택하고, Jenkins에서 구분할 임의의 Credentials이름을 입력해준 후 kubeconfig 파일을 업로드한다.
정상적으로 설정되었다면 Test Connection 시 Kubernetes에 접속되었다고 확인된다.
Jenkins URL에는 Jenkins host 도메인을 입력한다.
[추가사항] Jenkins Kubernetes Plugin Update
굉장히 오래 삽질을 했는데, 파이프라인 빌드 테스트 시 아래의 에러가 계속 발생했다.
Started by user Jenkins Admin
[Pipeline] Start of Pipeline (hide)
[Pipeline] podTemplate
[Pipeline] // podTemplate
[Pipeline] End of Pipeline
hudson.remoting.ProxyException: io.fabric8.kubernetes.client.KubernetesClientException: name not specified for an operation requiring one.
at io.fabric8.kubernetes.client.dsl.internal.BaseOperation.requireFromServer(BaseOperation.java:182)
at io.fabric8.kubernetes.client.dsl.internal.BaseOperation.get(BaseOperation.java:142)
at io.fabric8.kubernetes.client.dsl.internal.BaseOperation.get(BaseOperation.java:93)
at org.csanchez.jenkins.plugins.kubernetes.PodTemplateUtils.parseFromYaml(PodTemplateUtils.java:610)
at org.csanchez.jenkins.plugins.kubernetes.PodTemplateUtils.validateYamlContainerNames(PodTemplateUtils.java:639)
at org.csanchez.jenkins.plugins.kubernetes.PodTemplateUtils.validateYamlContainerNames(PodTemplateUtils.java:629)
at org.csanchez.jenkins.plugins.kubernetes.pipeline.PodTemplateStepExecution.start(PodTemplateStepExecution.java:145)
at org.jenkinsci.plugins.workflow.cps.DSL.invokeStep(DSL.java:322)
at org.jenkinsci.plugins.workflow.cps.DSL.invokeMethod(DSL.java:196)
at org.jenkinsci.plugins.workflow.cps.CpsScript.invokeMethod(CpsScript.java:124)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:47)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at com.cloudbees.groovy.cps.sandbox.DefaultInvoker.methodCall(DefaultInvoker.java:20)
Caused: hudson.remoting.ProxyException: java.lang.RuntimeException: Failed to parse yaml: "
apiVersion: v1
kind: Pod
도저히 문제를 찾지 못하다가 Kubernetes Plugin을 update하니 그냥 해결되었다.
정확하진 않으나 아래 버전에서 해결된 이슈로 보인다.
참조 : https://github.com/jenkinsci/kubernetes-plugin/releases/tag/3743.v1fa_4c724c3b_7
Jenkins Job 생성 후 PipeLine 빌드 테스트
생성한 계정으로 로그인 후 웹페이지에서 Create Job을 선택한다.
가장 하단의 PipeLine Script에서 Kubernetes용 테스트 PipeLine을 선택하고 저장한다.
Job의 수행 테스트
빌드 버튼을 클릭해 테스트 출력이 정상동작하는지 확인한다.
구축한 Jenkins 삭제
(ersia:default) [root@kops-ec2 ~]# helm uninstall -n jenkins jenkins
(ersia:default) [root@kops-ec2 ~]# kubectl delete ns jenkins
// jenkins에서는 테스트용으로 따로 구성하지 않아 별도로 필요하지 않음
// 만약 helm chart에서 PVC 구성을 한다면 아래의 작업이 필요
(ersia:default) [root@kops-ec2 ~]# kubectl delete pvc --all -n jenkins
참고자료
- GitLab의 권한관리와 설정방법 : https://github.com/jenkinsci/helm-charts/blob/main/charts/jenkins/VALUES_SUMMARY.md
- Jenkins-Kubernetes CI/CD (with Nexus) : https://velog.io/@seokbin/Jenkins-Kubernetes-배포-with-Nexus
- [Jenkins] 역방향 프록시 설정이 잘못된 것으로 파악되었습니다. : https://binit.tistory.com/41