[Sprint2] 배포 파이프라인 구축 후 마주하게 되는 고민들
Jenkins 설정
item name: 2224-deploy-helm
Copy from: 2223-deploy-helm
Sparse Checkout paths > Path: 2224
Script Path: 2224/Jenkinsfile
강사님 카페
https://cafe.naver.com/f-e/cafes/30725715/articles/104?menuid=13&referrerAllArticles=false
1. 중요 데이터 암호화 관리
문제
- docker-config.json 파일은 암호화가 되어있지 않기 때문에, 이 파일로 Docker username과 password르 볼 수 있다. (Base64 인코딩 되어있음)
- kubeconfig 파일(~/.kube/config)을 복사해가면 관리자 권한으로 쿠버네티스에 API를 보낼 수 있음
- 추후에 디스크를 교체할 때, 기존 디스크를 누군가 복원할 수 있음
=> 즉, ci-cd 서버에 접속만 할 수 있다면, 내 Docker hub와 kubernetes cluster가 위험해진다.
고민
- 보안 관리 필요
- 특정 파일에 아이디, 패스워드, 중요 인증서들이 방치되면 안됨
- 디스크에 암호화되지 않는 중요한 정보는 남기면 안됨
- Docker username과 password를 암호화하더라도(Jenkins credential), 로그인하면 config.json 파일이 만들어짐
해결
- Jenkins Credential에 Dockerhub username, password, kubeconfig 인증서를 등록한다.
(인증서를 암호화 시킨 상태로 사용하므로, 등록한 사람도 등록 이후에 내용을 볼 수 없음)
(Jenkins Credential을 사용할 수 있는 권한이 있는 사람만 사용이 가능하다
- 배포 시 Dockerhub로 업로드가 끝나면 로그아웃하는 명령어 넣기
(실무에서는 config.json 파일까지 암호화 하는 것이 좋다-Docker credential helpers)
▲ 바탕화면에 복붙 해놓기
▲--kubeconfig: default로 지정된 kubeconfig대신 KUBECONFIG변수 내용을 인증서로 사용 (암호화 되어있음)
Docker hub 로그아웃 및 kubeconfig 삭제
# Docker Hub Logout 하기(jenkins 로그인 상태)
docker logout
cat ~/.docker/config.json
# kubeconfig 파일명 변경하기(jenkins 로그인 상태)
mv ~/.kube/config ~/.kube/config_bak
kubectl get pods -A
# config 파일을 지워도 되지만 이름만 바꿈
▲ 이렇게 cicd server에는 어떤 정보도 남기지 않는 것이 좋다
2. Versioning
▲ 배포할 때마다 다른 값들이 변수로 들어감 (date+)
▲ TAG에는 두 변수가 합쳐져서 들어감(버전+날짜 값)
▲ --set: 동적으로 값 주입
▲ 실제 태그 값
같은 이미지에 두 가지 태그를 부여한 것이므로 두 가지 태그에 다 접근 가능함
중요!
이미지 태그
보통 api-tester:1.0.1 이런식으로 v 안씀
개발환경
- 잦은 배포 -> 버전 관리 의미가 없어짐
=> latest 태그 / pullPolicy: Always (항상 도커 허브에서 이미지 가져옴)
검증환경/운영환경
=> 태그 명시적 / pullPolicy: IfNotPresent (노드에 이미지가 있으면 그걸 사용)
운영 중에 Pod가 스케일링 될 때마다 새로 도커 허브에서 이미지를 받아오는 것은 비효율적
도커 허브에 연결이 안되는 상황이면 Pod가 만들어지지 않을 수도 있음
더 중요*************
태그 전략
개발 환경에서 latest로만 태그를 구성하면 롤백 요청에 대응하기 어려움
배포 시마다 새 태그 달기
image: api-tester:1.0.1-202505.31.15.19 / pullPolicy: IfNotPresent
(날짜 및 시간 활용)
annotation은 안 줘도 됨(배포할 때마다 태그가 바뀌니까)
=> 유즈케이스 많이 찾아보기!!
또 제3자 입장에선 latest 태그는 마지막 배포 버전이 아닌 최신 안정화 버전임을 기대한다!
보통 처음엔 개발환경에서 latest로 시작하고, 프로젝트가 커질수록 후자의 방식으로 바꿔감
3. 이미지 삭제 - cicd 환경
문제
- 빌드를 하다보면 cicd server에 컨테이너 이미지들이 쌓이는데, 서버가 다 차면 Jenkins가 죽을 수 있음
해결
- 이미지를 잘 삭제한다
▲ rmi 명령어로 이미지 삭제
4. Namespace 관리
문제
App들은 그룹 개념으로 namespace로 관리할 때 많으므로 배포와 별도로 구분하여야 함
helm uninstall시 namespace까지 지워주지는 않는다- 만약 지우면 다른 app까지 삭제될 수 있기 때문이다.
해결
▲ 실무에서는 namespace를 처음에 kubectl로 한번 만들고 잘 안건드리기 때문에 스크립트에는 아예 넣지 않아도 됨
혹은 namespace만 관리하는 배포 파이프라인을 구성해도 됨
5-1. Helm 부가기능 1 - annotations
문제
- tag를 latest로만 줄 경우 k8s는 templates 의 내용이 바뀌어야 업그레이드를 하는데, 그래서 배포 버튼을 누르기만하면 업그레이드가 동작하지 않음
해결
- metadata.annotations로 배포 시마다 랜덤 값을 생성해준다
▲ rollme 항상 랜덤값이 들어가서 배포됨
5-2. Helm 부가기능 2 - wait
문제
배포 후 Pod 업그레이드가 안 될수도 있음
해결
--wait : Pod가 정상적으로 기동이 되었는지 확인 후, 기동이 완료되었으면 성공적으로 프로세스를 종료
▲ --timeout=10m: 만약 계속 Pod에 에러가 나면 clash loopback 상태가 될 수 있기 때문
Jenkins에도 job을 실행시키는 스레드 개수 제한이 있음
6. 이미지 - infra 환경
문제
- 인프라 환경에서 사용하지 않는 이미지
해결
- kubernetes garbage collector가 자동으로 사용하지 않는 이미지 삭제해줌
config 파일 안의 내용을 바꾸고 kubelet을 restart 해주면 됨
▲ 실무에서- 강사님은 이 기본 설정을 바꿔본 적이 없다고 하심! 알아서 잘 해준다