Kubernetes – CI/CD 파이프라인 구성
소스 배포부터 k8s 클러스터 배포까지의 일련의 과정을 설치합니다.
. . . . . . . . . . . . . . . . . .
기본구조
사전 준비
k8s 클러스터 구성
Jenkins 설치
설치
여기 를 참조하여 Jenkins 를 설치합니다.
Jenkins 추가설정
아래 Jenkins Plugin 을 설치해 줍니다.
kubernetes
docker
아래 아이피로의 접근을 방화벽에서 허용해줍니다.(Github webhook)
접속하는 포트는 30088 입니다.
"192.30.252.0/22",
"185.199.108.0/22",
"140.82.112.0/20"
여기 를 참조하여 Personal Access Token 을 생성합니다.
Private Docker Repository 설치
여기 를 참조하여 Repository 를 설치합니다.
ArgoCD 설치
여기 를 참조하여 ArgoCD 를 설치합니다.
개발자가 소스 push
프로젝트 루트에 Dockerfile 을 추가하고 아래 내용을 추가합니다.
FROM openjdk:11.0.6-jre
EXPOSE 8080
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
Github 가 Jenkins 에 노티
Github Webhook 설정
Github private repo 로 이동 후,
Settings > Webhooks 으로 이동한다.
- Payload URL : http://worker public ip:30088/github-webhook/
- Content type : application/json
Jenkins 아이템 생성
젠킨스 아이템을 Pipeline 으로 생성하고 아래 script 를 입력합니다.
위에서 생성한 Personal Access Token 으로 접근합니다.
node {
stage("Get Source") {
git url: "https://ghp_a16NFKcFmOXXXXXXXXXXXXXX@github.com/skyer9/TestPrivate.git",
branch: "master"
}
}
Build now(지금 빌드) 를 클릭해서 소스를 가져오는지 확인합니다.
소스 빌드
node {
stage("Get Source") {
git url: "https://ghp_a16NFKcFmOXXXXXXXXXXXXXX@github.com/skyer9/TestPrivate.git",
branch: "master"
}
stage("Build") {
sh "chmod 700 gradlew"
sh "./gradlew clean"
sh "./gradlew bootJar"
}
}
빌드가 이루어지는지 확인합니다.
webhook 체크
젠킨스 아이템에 GitHub hook trigger for GITScm polling 을 체크해 줍니다.
소스를 Github 에 push 해서 정상적으로 빌드가 이루어지는지 확인합니다.
Jenkins 가 Docker image 생성 후 Private repo 에 배포
Kubernetes 플러그인 설정
여기 를 참조하여 플러그인을 설정해 줍니다.
Jenkins 아이템 수정
pipeline {
agent {
kubernetes {
defaultContainer 'jnlp'
yaml """
spec:
dnsPolicy: Default # 이게 왜 필요할까?
containers:
- name: docker
image: docker:latest
command:
- cat
tty: true
privileged: true
volumeMounts:
- name: dockersock
mountPath: /var/run/docker.sock
volumes:
- name: dockersock
hostPath:
path: /var/run/docker.sock
- name: m2
hostPath:
path: /root/.m2
"""
}
}
stages {
stage("Get Source") {
steps {
git url: "https://ghp_a16NFKXXXXXXXXXXXXXXXXX@github.com/skyer9/TestPrivate.git",
branch: "master"
}
}
stage("Build") {
steps {
sh "chmod 700 gradlew"
sh "./gradlew clean"
sh "./gradlew bootJar"
}
}
stage('Docker Build') {
steps {
container('docker') {
sh "docker build -t 10.101.46.90/skyer9/testprivate:0.1.${build_number} ."
sh "docker build -t 10.101.46.90/skyer9/testprivate:latest ."
}
}
}
}
}
docker build 시 아이피는 docker-repository 의 클러스터 아이피입니다.
Private Docker Repository 에 push
push 는 https 만 허용하므로 아래 설정변경을 통해,
http push 를 허용해 준다.
마스터 노드에서 클러스터 아이피를 확인한다.
kubectl get svc -n repository
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
docker-repository NodePort 10.105.115.134 <none> 80:30099/TCP 10m
워커 노드의 도커 서비스를 수정한다.
sudo vi /lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd ...... --insecure-registry 10.105.115.134
sudo systemctl daemon-reload
sudo systemctl restart docker
sudo docker info
stage('Docker Build') {
steps {
container('docker') {
sh "docker build -t 10.105.115.134/skyer9/testprivate:0.1.${build_number} ."
sh "docker build -t 10.105.115.134/skyer9/testprivate:latest ."
sh "docker info"
sh "docker push 10.105.115.134/skyer9/testprivate:0.1.${build_number}"
sh "docker push 10.105.115.134/skyer9/testprivate:latest"
}
}
}
아래 명령으로 업로드된 이미지를 확인할 수 있다.
curl http://localhost:30099/v2/_catalog
Private Docker Repository 에 https 적용
여기 를 참조하여 사설인증서를 생성합니다.
젠킨스 설정파일은 아래처럼 수정해 줍니다.
pipeline {
agent {
kubernetes {
defaultContainer 'jnlp'
yaml """
spec:
dnsPolicy: Default # 이게 왜 필요할까?
containers:
- name: docker
image: docker:latest
command:
- cat
tty: true
privileged: true
volumeMounts:
- name: private-rootca-crt
mountPath: /etc/docker/certs.d/docker-repository.repository.svc.cluster.local/ca.crt
subPath: rootCA.crt
readOnly: true
- name: dockersock
mountPath: /var/run/docker.sock
volumes:
- name: private-rootca-crt
configMap:
name: private-rootca.crt
- name: dockersock
hostPath:
path: /var/run/docker.sock
- name: m2
hostPath:
path: /root/.m2
"""
}
}
stages {
stage("Get Source") {
steps {
git url: "https://ghp_ttA52XKpXXXXXXXXXXXXXXX@github.com/skyer9/TestPrivate.git",
branch: "master"
}
}
stage("Build") {
steps {
sh "chmod 700 gradlew"
sh "./gradlew clean"
sh "./gradlew bootJar"
}
}
stage('Docker Build') {
steps {
container('docker') {
sh "docker build -t docker-repository.repository.svc.cluster.local/testprivate:0.1.${build_number} ."
sh "docker build -t docker-repository.repository.svc.cluster.local/testprivate:latest ."
sh "docker info"
// sh "apk update && apk add ca-certificates"
// sh "cp /etc/docker/certs.d/repository.repository.svc.cluster.local/ca.crt /usr/local/share/ca-certificates/my-cert.crt"
// sh "update-ca-certificates"
// sh "wget https://repository.repository.svc.cluster.local/v2/"
sh "docker push docker-repository.repository.svc.cluster.local/testprivate:0.1.${build_number}"
sh "docker push docker-repository.repository.svc.cluster.local/testprivate:latest"
}
}
}
}
}
운영자가 소스를 Github 에 push
여기 를 참조하여 Repo 를 설정합니다.
이미지 주소를 설정해 주면 됩니다.
Worker 노드에서 이미지를 땡겨 오기에,
Worker 노드에 루트인증서가 등록되어 있어야 합니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: testprivate
namespace: default
labels:
app: testprivate
spec:
replicas: 1
selector:
matchLabels:
app: testprivate
template:
metadata:
labels:
app: testprivate
spec:
containers:
- name: testprivate
image: docker-repository.repository.svc.cluster.local/testprivate:0.1.16
ports:
- containerPort: 8080
프로젝트 루트에 Dockerfile 을 추가하고 아래 내용을 추가합니다.
> 이 부분에 프로젝트 루트가 어딘지 모르겠습니다.
일단 깃허브에 Dockerfile 추가하고 소스 불러오는 것 까지는 됐는데
stage(“Build”) {
sh “chmod 700 gradlew”
sh “./gradlew clean”
sh “./gradlew bootJar”
}
}
이걸 추가했을때 gradlew가 없다고 에러가 나와서 진행을 못하고 있습니다…혹시 아시는 부분 있을까요??