[Jenkins] 젠킨스에서 도커 이미지를 빌드할 때 발생하는 이슈들
작업 환경
젠킨스를 통해 깃허브에서 도커 이미지를 빌드하여 이미지 저장소로 올리는 과정에서 발생하는 이슈들을 다룹니다.
이 글은 CI 파이프라인 구축을 설명하고 있지 않습니다. 환경 구축은 아래 출처를 참고해주세요.
● Jenkins로 Docker 이미지 빌드하기
● 젠킨스 연동 및 push 하기
설정 파일
젠킨스가 깃허브에서 코드를 받아와서 도커 이미지를 빌드할 때 필요로 하는 파일이 두 가지 존재한다. 하나는 Jenkinsfile이고 나머지는 Dockerfile이다. 두 파일은 코드의 루트 경로에 위치하고 있어야 한다.
처음 작성할 때 막막했던 기억이 있어 누군가는 필요할 것 같아 첨부해 둔다.
📌 Jenkinsfile
def app
node {
stage('Checkout'){
checkout scm
}
stage('Build image'){
app = docker.build("[저장소도메인]/[프로젝트명]/[이미지명]")
# 예를 들면 "harbor.test.io/example-project/test-image"
# 하버의 경우 프로젝트는 사전에 생성해 놓아야하지만 이미지는 자동 생성된다.
}
# withRegistry 안에는 저장소 도메인과 젠킨스에 미리 등록해 놓은 Credential의 ID를 적어준다.
# 예를 들면 docker.withRegistry('https://harbor.test.io', 'Harbor')
stage('Push image'){
docker.withRegistry('https://[저장소도메인]', '[CredID]'){
app.push("${env.BUILD_NUMBER}")
app.push("latest")
}
}
}
모든 이미지에는 젠킨스 프로세스 번호가 붙고 가장 최근에 올라간 도커 이미지에만 latest 태그가 붙는다.
📌 Dockerfile
Dockerfile은 구축하고자 하는 환경에 따라 이미지 파일이 다를 수 있다. 본인의 환경에 맞는 이미지를 가져오자.
아래는 python이 깔려있는 nodeJS 이미지를 이용하여 서버를 실행하는 예시이다.
FROM nikolaik/python-nodejs:python3.8-nodejs16
WORKDIR /app
COPY . /app
RUN npm install && pip install -r requirements.txt
EXPOSE 8080
CMD [ "node", "app.js" ]
COPY를 할 때에는 COPY [복사해 올 곳] [복사해 갈 곳] 순으로 적는데 복사해 올 곳은 상대경로로, 복사해 갈 곳은 절대경로로 적는 것이 원칙이다. 꼭 지키지 않아도 동작에는 이상이 없긴 하다.
에러
다음은 위의 구축 과정에서 발생하기 쉬운 에러와 그 해결 방안을 설명한다.
🔒 에러 1
groovy.lang.missingpropertyexception: No such property: docker for class: groovy.lang.Binding
🔑 해결: Jenkins에서 Docker Pipeline 플러그인 설치 (참고)
🔒 에러 2
/var/run/docker.sock: connect: permission denied
🔑 해결: 모든 노드에서 sudo chmod 666 /var/run/docker.sock로 접근 권한 허용(참고)
🔒 에러 3
script.sh 1 docker not found
🔑 해결: jenkins deployment 파일에서 volume mount를 추가 (참고)
apiVersion: apps/v1
kind: Deployment
metadata:
name: jenkins
namespace: jenkins
spec:
replicas: 1
selector:
matchLabels:
app: jenkins
template:
metadata:
labels:
app: jenkins
spec:
containers:
- name: jenkins
image: jenkins/jenkins:lts
ports:
- name: httpe-port
containerPort: 8080
- name: jnlp-port
containerPort: 50000
volumeMounts:
- name: jenkins-data
mountPath: /var/jenkins_home
- name: docker-socket
mountPath: /var/run/docker.sock
- name: docker-bin
mountPath: /usr/bin/docker
volumes:
- name: jenkins-data
persistentVolumeClaim:
claimName: jenkins-pvc
- name: docker-socket
hostPath:
path: /var/run/docker.sock
type: Socket
- name: docker-bin
hostPath:
path: /usr/bin/docker
type: File
🔒 에러 4
stat /var/lib/docker/tmp: no such file or directory
🔑 해결: Jenkins 파드가 돌고 있는 노드에 도커가 제대로 실행되고 있지 않는 상태일 가능성이 높다. 해당 노드에서 sudo service docker restart를 한 뒤 /var/lib/docker 파일 안에 파일이 제대로 생성되어 있는지 확인한다. docker파일은 sudo chmod 755 docker로 접근 권한을 주어야 확인이 가능하다.
결과
33번만에 성공했다.