내부 주기 : 로컬 개발
외부 주기 : 배포를 위한 CI/CD
도커 개발 워크플로
필요한 것
- Dockerfile 스크립트
- 도커 컴포즈 파일
- 쿠버네티스 매니페스트
docker-compose -f bulletin-board/docker-compose.yaml build docker-compose -f bulletin-board/docker-compose.yaml up -d docker-compose -f bulletin-board/docker-compose.yaml down kubectl apply -f bulletin-board/kubernetes/
쿠버네티스는 로컬에서 빌드한 이미지나 도커가 내려받은 이미지도 문제없이 사용할 수 있음
하지만 로컬 이미지와 레지스트리에서 내려받은 이미지를 구분하는 몇 가지 규칙을 지켜야 함
- 이미지 태그가 명시적으로 지정되지 않았다면 쿠버네티스는 무조건 이미지 내려받기를 먼저 시도함
spec: containers: - name: bulletin-board image: kiamol/ch11-bulletin-board:dev imagePullPolicy: IfNotPresent # 로컬 이미지가 있다면 로컬 이미지 사용
문제점
도커컴포즈 명령으로 이미지 빌드 다시 하여도, kubectl 명령 다시 입력 시 애플리케이션에 변경한 내용이 반영되지 않음
rm bulletin-board/src/backend/event.js cp bulletin-board/src/backend/event-update.js bulletin-board/src/backend/event.js # 컴포즈로 이미지를 다시 빌드 docker-compose -f bulletin-board/docker-compose.yaml build # kubectl 을 사용하여 애플리케이션을 다시 배치 kubectl apply -f bulletin-board/kubernetes/ # 기존 파드 삭제하여 강제로 파드 교체 kubectl delete pod -l app=bulletin-board
- 이미지를 다시 빌드해도 이미지 태그가 변경되지 않았기에 kubectl 로 다시 배치하여도 변경이 없게 되는 것
- 파드 강제 삭제하고 생성하면 변경된 이미지로 컨테이너 생성되기에 변경사항이 반영됨
⇒ 대안으로 모든 컨테이너 관련 기술 사항을 CI/CD 파이프라인을 관장하는 팀에 맡겨 두고 개발 팀은 이 파이프라인을 이용하여 애플리케이션을 배포하도록 하는 방법이 있음
쿠버네티스 개발 워크플로
모든 테스트 환경과 CI/CD서비스를 호스팅하는 클러스터를 운영하며 컨테이너 실행과 관련된 모든 일을 이 클러스터에 맡김
컨테이너는 외부 주기에서만 이용
- 개발자가 변경 사항을 형상 관리 도구에 커밋
- 빌드 유발
- 빌드에서 컨테이너 이미지 생성
- 레지스트리 푸시
- 새로운 버전의 애플리케이션이 클러스터 속 테스트 환경에 배치
장점
- 개발 워크플로를 바꾸거나 개발 팀 모두가 도커나 컴포즈를 배우지 않고도 쿠버네티스로 이주가 가능
- 전체 시스템을 구성하는 팀만 컨테이너를 다룰 수 있으면 됨
- gogs (로컬 형상관리 서버)
- 빌드킷 (도커 엔진의 이미지 빌드 기능 대체)
- Dockerfile 없이 이미지 빌드 가능
- 소스코드에서 곧바로 컨테이너 이미지를 빌드 (BuildPack)
- 팩을 사용하려면 도커가 필요한데, 여기서는 도커를 배제한 파이프라인을 만들기 위해 팩을 대신해 빌드팩을 빌드킷에 통합하여 사용
kubectl exec -it deploy/buildkitd -- sh cd ~ git clone https://gogs:3000/kiamol/kiamol.git # 빌드킷으로 애플리케이션 빌드 & 레지스트리에 푸시
컨텍스트와 네임스페이스 이용하여 워크로드 분리하기
kubectl create namespace kiamol-ch11-test kubectl apply -f sleep.yaml --namespace kiamol-ch11-test
apiVersion: v1 kind: Namespace metadata: name: kiamol-ch11-uat --- apiVersion: apps/v1 kind: Deployment metadata: name: sleep namespace: kiamol-ch11-uat labels: app: sleep spec: selector: matchLabels: app: sleep template: metadata: labels: app: sleep spec: containers: - name: sleep image: kiamol/ch03-sleep
- metadata 에 namespace 를 명시해서 Deployment 생성
- 쿠버네티스 네트워크는 계층이 없으므로 서비스를 통하며 네임스페이스를 가로질러 통신이 가능하지만, 컨트롤러는 자신의 네임스페이스 안에서만 관리 대상 파드를 찾음
kubectl apply -f sleep-uat.yaml kubectl get deploy -l app=sleep --all-namespaces NAMESPACE NAME READY UP-TO-DATE AVAILABLE AGE default sleep 1/1 1 1 5s kiamol-ch11-uat sleep 1/1 1 1 32s kubectl delete namespace kiamol-ch11-uat kubectl get deploy -l app=sleep --all-namespaces NAMESPACE NAME READY UP-TO-DATE AVAILABLE AGE default sleep 1/1 1 1 57s
- namespace 삭제 시 그 아래에 있는 리소스도 다 같이 삭제 됨
컨텍스트
- 컨텍스트 세부 정보 : ~/.kube/config 파일에 저장
- kubectl 명령의 플래그를 사용하여 네임스페이스를 지정하는 방법은 시간도 낭비되고 실수가 쉽기에 kubectl 에는 컨텍스트 기능이 있음
컨텍스트
:작업 대상 쿠버네티스 클러스터
와 kubectl 명령에서 사용할기본 네임스페이스
를 정의한 것
# 컨텍스트의 목록을 확인 kubectl config get-contexts # 현재 컨텍스트의 기본 네임스페이스를 변경 kubectl config set-context --current --namespace=kiamol-ch11-test # 현재 컨텍스트의 네임스페이스를 default 로 변경 kubectl config set-context --current --namespace= # 설정 파일에서 클러스터 접속 정보를 확인 kubectl config view
kubectl config use-context
명령어로 컨텍스트 전환가능
도커를 배제한 쿠버네티스의 지속적 전달
- kubectl 로 레지스트리 인증정보를 secret 객체로 생성
- 젠킨스 서버 배치
- 위의 레지스트리 인증정보를 젠킨스 서버에서 이용하여 레지스트리에 로그인하고, 빌드된 이미지를 푸시
- 젠킨스 서버가 곡스 서버에서 애플리케이션 코드를 받아 오고
- 빌드킷 서버에 컨테이너 이미지를 빌드, 레지스트리에 푸시
buildctl --addr tcp://buildkitd:1234 build --frontend=gateway.v0 --opt source=kiamol/buildkit-buildpacks --local context=src --output type=image,name=${REGISTRY_SERVER}/${REGISTRY_USER}/bulletin-board: ${BUILD_NUMBER}-kiamol,push=true
- 최신 버전의 애플리케이션을 클러스터의 테스트 네임스페이스에 배치
helm upgrade --install --atomic --set registryServer=${REGISTRY_SERVER}, registryUser=${REGISTRY_USER}, imageBuildNumber=${BUILD_NUMBER} --namespace kiamol-ch11-test bulletin-board helm/bulletin-board