본문 바로가기

Container/Kubernetes

[ Kubernetes ] 배포 파이프라인 구축시 고려해봐야 할 부분

728x90
반응형

 

1. 중요 데이터 암호화 관리

- Dockerhub 접속정보 (config.json)와 Kubernetes 인증서에 대한 보안문제

- Jenkins credential로 보완

- script 종료 후 dockerhub 로그아웃

- docker-credential-helpers를 이용하여 암호화

 

2. image tag 관련

- 개발환경 : 잦은 배포, versioning 무의미

## 일반적인 개발환경
image : api-tester:latest # 가장 최신버전으로 image를 가져오고자 latest를 사용하지만, "helm 배포해도 업그레이드가 안되는경우" 가 될 수 있기때문에 주의 해야함
pullPolicy :Always # 항상 dockerhub에서 image를 가져옴, hub 미연동시 Pod 생성 에러
## 버전별 관리가 필요한 개발환경 - rollback
image : api-tester:1.0.1-202312.181512 # 배포시 마다 새 태그 달기 - 날짜, Git커밋 No, Jenkins 빌드 Seq
pullPolicy :IfNotPresent

 

- 검증, 운영환경 : 계획된 배포, versioning 필수

image : api-tester:1.0.1
pullPolicy : IfNotPresent # node에 해당 이미지가 있으면 먼저 사용, 없으면 hub 확인

 

* latest는 일반적으로 단순 마지막 버전이 아닌, 최신 안정화 버전

 

3. 빌드 컨테이너 이미지 ( in CI/CD 서버 )

- 누적된 이미지 용량으로 디스크 용량 부족이 발생

- 이미지 생성/push 후 local에 존재하는 이미지 삭제

 

4. Namespace 별도 관리

- 하나의 namespace에 여러개의 app 배포할 경우 namespace의 관리가 어려워짐

- helm의 uninstall시 namespace는 지워지지 않음

- helm(app 배포)와 namespace는 별도로 관리하는 것이 좋음

 

5. helm의 부가기능

- helm command -wait : 배포후 pod가 정상적으로 기동 되었는지 확인할때 사용

- 배포해도 pod 업그레이드 진행이 되지 않는 경우

  ㄴ template 하위에 변경사항이 있어야 업그레이드 되는데 그부분을 인식 못하는 경우가 있음

  ㄴ metadata.annotations로 극복가능

 

 

 

6. 배포 컨테이너 이미지 ( in worker-node)

- 배포시 다운받는 이미지들이 계속 누적되나, kubernetes가 자동으로 관리함.

 


 

> 실습

1. pipeline 생성 및 config 설정

Enter an item name에 [2224-deploy-helm] 입력
Copy form에 [2223-deploy-helm] 입력
[OK] 버튼 클릭

Definition > SCM > Branches to build > Additional Behaviours > Sparse Checkout paths > Path : 2224
Definition > Script Path : 2224/Jenkinsfile

 


1) 중요 데이터 암호화 관리

- dockerhub 접속정보 및 kubernetes confg를 위한 credential 생성

Dashboard > Jenkins 관리 > Credentials > System > Global credentials (unrestricted) 에서 Add Credentials 클릭

Dockerhub 등록

 

Kubernetes config 파일 등록

* 파일 선택을 위해 사전에 CI/CD Server에 있는 config 파일을 내 PC로 복사해놓아야 함.

# config 파일 위치
[jenkins@cicd-server .kube]$ pwd
/var/lib/jenkins/.kube
[jenkins@cicd-server .kube]$ ls
cache  config

 

- Jenkinsfile 내용

// Docker 사용
steps {
  script{
    withCredentials([usernamePassword(credentialsId: 'docker_password', passwordVariable: 'PASSWORD', usernameVariable: 'USERNAME')]) {
    sh "echo " + '${PASSWORD}' + " | docker login -u " + '${USERNAME}' + " --password-stdin"

// Kubernetes config 사용
steps {
  withCredentials([file(credentialsId: 'k8s_master_config', variable: 'KUBECONFIG')]) {    // 암호화로 관리된 config가 들어감
    sh "kubectl apply -f ./2224/deploy/kubectl/namespace-dev.yaml --kubeconfig " + '${KUBECONFIG}'
    sh "helm upgrade api-tester-2224 ./2224/deploy/helm/api-tester -f ./2224/deploy/helm/api-tester/values-dev.yaml" +
        " -n anotherclass-222-dev --install --kubeconfig " + '${KUBECONFIG}'

 

- CI/CD Server에서 Docker Logout 및 kubeconfig 삭제

# Docker Hub Logout 하기
[jenkins@cicd-server ~]$ docker logout
Removing login credentials for https://index.docker.io/v1/
[jenkins@cicd-server .docker]$ cat ~/.docker/config.json
{
        "auths": {}
}

# kubeconfig 파일명 변경하기
[jenkins@cicd-server ~]$ mv ~/.kube/config ~/.kube/config_bak
[jenkins@cicd-server ~]$ kubectl get pods -A
E1219 17:16:27.450820    3778 memcache.go:265] couldn't get current server API group list: <html>...

 

 

 

2) 잦은 배포 - Versioning 무의미, 계획된 배포 - Versioning 필수 - Jenkinsfile 내용

environment {
  APP_VERSION = '1.0.1'
  BUILD_DATE = sh(script: "echo `date +%y%m%d.%d%H%M`", returnStdout: true).trim()
  TAG = "${APP_VERSION}-" + "${BUILD_DATA}"

stage('컨테이너 빌드 및 업로드') {
  steps {
	script{
	  // 도커 빌드
      sh "docker build ./2224/build/docker -t 1pro/api-tester:${TAG}"
      sh "docker push 1pro/api-tester:${TAG}"

stage('헬름 배포') {
  steps {
    withCredentials([file(credentialsId: 'k8s_master_config', variable: 'KUBECONFIG')]) {
      sh "helm upgrade api-tester-2224 ./2224/deploy/helm/api-tester -f ./2224/deploy/helm/api-tester/values-dev.yaml" +
         ...
         " --set image.tag=${TAG}"   // Deployment의 Image에 태그 값 주입

 

* docker tag 변경이 필요할때 ( to latest )

docker tag 1pro/api-tester:1.0.1-231220.171834 1pro/api-tester:latest
docker push 1pro/api-tester:latest

 

 

3) 업로드 후 CI/CD Server에 만들어진 이미지 삭제 - Jenkinsfile 내용

stage('컨테이너 빌드 및 업로드') {
  steps {
	script{
	  // 도커 빌드
      sh "docker build ./${CLASS_NUM}/build/docker -t ${DOCKERHUB_USERNAME}/api-tester:${TAG}"
      sh "docker push ${DOCKERHUB_USERNAME}/api-tester:${TAG}"
      sh "docker rmi ${DOCKERHUB_USERNAME}/api-tester:${TAG}"   // 이미지 삭제

 

 

4) 네임스페이스는 배포와 별도 관리 - Jenkinsfile 내용

stage('네임스페이스 생성') {  // 배포시 apply로 Namespace 생성 or 배포와 별개로 미리 생성 (추후 삭제시 별도 삭제)
  steps {
    withCredentials([file(credentialsId: 'k8s_master_config', variable: 'KUBECONFIG')]) {
      sh "kubectl apply -f ./2224/deploy/kubectl/namespace-dev.yaml --kubeconfig " + '"${KUBECONFIG}"'
...
stage('헬름 배포') {
  steps {

 

 

5) Helm 부가기능 ( 배포 후 Pod 업그레이드가 안될 수 있음 ) - deployment.yaml 내용

apiVersion: apps/v1
kind: Deployment
spec:
  template:
    metadata:      
      annotations:  
        rollme: {{ randAlphaNum 5 | quote }} // 항상 새 배포를 위해 랜덤값 적용

 

 

6) Helm 부가기능 (Pod가 완전 기동 될때까지 결과값 기다림) - helm command 명령어 내용

stage('헬름 배포') {
  steps {
    withCredentials([file(credentialsId: 'k8s_master_config', variable: 'KUBECONFIG')]) {
      sh "helm upgrade api-tester-2224 ./2224/deploy/helm/api-tester -f ./2224/deploy/helm/api-tester/values-dev.yaml" +
         ...
         " --wait --timeout=10m" +  // 최대 10분으로 설정

 

 

7) 사용 안하는 이미지는 자동 삭제됨 - config.yaml 내용

// GC 속성 추가하기
[root@k8s-master ~]# vi /var/lib/kubelet/config.yaml
-----------------------------------
imageMinimumGCAge : 3m // 이미지 생성 후 해당 시간이 지나야 GC 대상이 됨 (Default : 2m)
imageGCHighThresholdPercent : 80 // Disk가 80% 위로 올라가면 GC 수행 (Default : 85)
imageGCLowThresholdPercent : 70 // Disk가 70% 밑으로 떨어지면 GC 수행 안함(Default : 80)
-----------------------------------

// kubelet 재시작
[root@k8s-master ~]# systemctl restart kubelet

 

 


 

2. 파라미터와 함께 빌드 실행 후 PROFILE을 dev로 선택하고 빌드하기 클릭

 

 

3. 실습 후 정리

# helm 조회
helm list -n anotherclass-222

# helm 삭제
helm uninstall -n anotherclass-222-dev api-tester-2224
helm uninstall -n anotherclass-222-qa api-tester-2224
helm uninstall -n anotherclass-222-prod api-tester-2224

# namespace 삭제
kubectl delete ns anotherclass-222-dev
kubectl delete ns anotherclass-222-qa
kubectl delete ns anotherclass-222-prod
728x90
반응형