Kubernetes를 배포하여 이미지를 업데이트하는 방법


131

다음과 같은 사용자 지정 도커 이미지를 사용하여 단일 포드로 배포했습니다.

containers:
  - name: mycontainer
    image: myimage:latest

개발 중에 새로운 최신 버전을 푸시하고 배포를 업데이트하고 싶습니다. 태그 / 버전을 명시 적으로 정의하고 각 빌드에 대해 증분하지 않고는 방법을 찾을 수 없습니다.

kubectl set image deployment/my-deployment mycontainer=myimage:1.9.1

답변:


151

유예 기간 (예 : 컨테이너 시작 시간 및 이미지 크기에 따라 30 초 이상)으로 포드를 구성하고 "imagePullPolicy: "Always". 그리고 kubectl delete pod pod_name. 새 컨테이너가 생성되고 최신 이미지가 자동으로 다운로드 된 다음 이전 컨테이너가 종료됩니다.

예:

spec:
  terminationGracePeriodSeconds: 30
  containers:
  - name: my_container
    image: my_image:latest
    imagePullPolicy: "Always"

현재 자동화 된 빌드 및 이미지 태그 지정을 위해 Jenkins를 사용하고 있으며 다음과 같이 보입니다.

kubectl --user="kube-user" --server="https://kubemaster.example.com"  --token=$ACCESS_TOKEN set image deployment/my-deployment mycontainer=myimage:"$BUILD_NUMBER-$SHORT_GIT_COMMIT"

또 다른 트릭은 처음에 다음을 실행하는 것입니다.

kubectl set image deployment/my-deployment mycontainer=myimage:latest

그리고:

kubectl set image deployment/my-deployment mycontainer=myimage

실제로 롤링 업데이트를 트리거하지만 imagePullPolicy: "Always"설정 했는지 확인하십시오 .

최신 정보:

이미지 이름을 변경할 필요가없는 또 다른 트릭은 .NET과 같은 롤링 업데이트를 트리거 할 필드의 값을 변경하는 것 terminationGracePeriodSeconds입니다. 이 사용 할 수있는 kubectl edit deployment your_deployment하거나 kubectl apply -f your_deployment.yaml또는이 같은 패치를 사용하여 :

kubectl patch deployment your_deployment -p \
  '{"spec":{"template":{"spec":{"terminationGracePeriodSeconds":31}}}}'

항상 숫자 값을 변경했는지 확인하십시오.


1
myimage : lastet과 myimage를 기본적으로 똑같은 것으로 고려하면 실제로 당신의 트릭은 나쁘지 않습니다. 감사합니다!
— abovesun 2011

1
이 트릭은 버그처럼 보이지만 왜 두 번 지정해야하는지 확실하지 않습니다.
— speedplane

2
kubernetes 배포가 동일한 이미지를 사용하여 새 포드를 시작하도록하려면 (이 트릭은 "latest"태그에서만 작동 함) 태그없이 지정해야합니다. 다음에 "최신"태그를 추가하면 업데이트가 트리거됩니다. 순서가 바뀌어도 상관 없습니다. 프로덕션에서는 "최신"태그를 사용하지 않지만 개발 목적으로 때때로 이점을 누릴 수 있습니다.
— Camil

2
최신 버전에서만 작동합니다. 기본적으로 적어도 도커 허브에서는 이미지에 태그를 지정하지 않으면 "최신"태그로 간주됩니다. 그러나 그것 없이도 작동합니다. 이 예제는 프로덕션 환경에서 원하는 것이 아니며 개발에서도 이점을 얻을 수있는 사용 사례가 많지 않습니다. CI / CD 도구를 사용하여 이미지를 자동으로 업데이트하는 더 좋은 방법이 있습니다.
— Camil

11
태그를 변경하고 kubectl set image명령을 실행할 때마다 kubernetes는 롤링 업데이트를 수행합니다. 예를 들어 "repo / myimage : latest"를 배포했다고 가정 해 보겠습니다. 그동안 이미지가 변경되어 "v0.2"태그가있는 저장소로 푸시되었습니다. kubectl set image deployment/my-deployment mycontainer=myimage:v0.2이 이미지에는 "latest"태그도 있습니다. 를 실행하여 업데이트를 수행 할 수 있습니다 .
— Camil

73

업데이트 2019-06-24

1.15버전 이있는 경우 @Jodiug 주석을 기반으로 다음 명령을 사용할 수 있습니다.

kubectl rollout restart deployment/demo

문제에 대해 자세히 알아보십시오.

https://github.com/kubernetes/kubernetes/issues/13488


kubernetes GitHub 프로젝트에서이 주제에 대한 흥미로운 토론이 있습니다. 문제보기 : https://github.com/kubernetes/kubernetes/issues/33664

거기에 설명 된 솔루션에서 두 가지 중 하나를 제안합니다.

먼저

1. 배포 준비

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: demo
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: demo
    spec:
      containers:
      - name: demo
        image: registry.example.com/apps/demo:master
        imagePullPolicy: Always
        env:
        - name: FOR_GODS_SAKE_PLEASE_REDEPLOY
          value: 'THIS_STRING_IS_REPLACED_DURING_BUILD'

2. 배포

sed -ie "s/THIS_STRING_IS_REPLACED_DURING_BUILD/$(date)/g" deployment.yml
kubectl apply -f deployment.yml

두 번째 (하나의 라이너) :

kubectl patch deployment web -p \
  "{\"spec\":{\"template\":{\"metadata\":{\"labels\":{\"date\":\"`date +'%s'`\"}}}}}"

물론 imagePullPolicy: Always두 경우 모두 필수입니다.


다른 관련 트릭을 찾았습니다. 특정 배포 이름을 지정하지 않고 "kubectl rollout restart deployment"만 수행하면 "모든"작업이 수행됩니다.
— Lennart Rolland

21
kubectl rollout restart deployment myapp

이것은 롤백 업데이트를 트리거하고 kubectl rollout같은 롤백에서 제공하는 다른 작업을 위해 이전 복제본 세트를 그대로 두는 현재 방법 입니다.


@Prathameshdhanawade 패치 작업에는 undo명령이나 동등한 기능 이 없습니다 .
— Martin Peter 19

7

Gitlab-CI를 사용하여 이미지를 빌드 한 다음 GCK에 직접 배포합니다. 컨테이너의 실제 설정을 변경하지 않고 롤링 업데이트를 달성하기 위해 깔끔한 트릭을 사용하면 레이블이 현재 commit-short-sha로 변경됩니다.

내 명령은 다음과 같습니다.

kubectl patch deployment my-deployment -p "{\"spec\":{\"template\":{\"metadata\":{\"labels\":{\"build\":\"$CI_COMMIT_SHORT_SHA\"}}}}}}"

각 빌드마다 변경되는 한 레이블의 이름과 값을 사용할 수 있습니다.

즐기세요!


6

k8s는 모든 배포에 대해 다른 이미지 태그를 제공 할 것으로 예상하는 것 같습니다. 내 기본 전략은 CI 시스템이 Docker 이미지를 생성하고 푸시하여 빌드 번호로 태그를 지정하는 것입니다.xpmatteo/foobar:456 .

로컬 개발의 경우 다음과 같이 스크립트 또는 메이크 파일을 사용하는 것이 편리 할 수 ​​있습니다.

# create a unique tag    
VERSION:=$(shell date +%Y%m%d%H%M%S)
TAG=xpmatteo/foobar:$(VERSION)

deploy:
    npm run-script build
    docker build -t $(TAG) . 
    docker push $(TAG)
    sed s%IMAGE_TAG_PLACEHOLDER%$(TAG)% foobar-deployment.yaml | kubectl apply -f - --record

이 sed명령은 배포 문서의 자리 표시자를 실제 생성 된 이미지 태그로 바꿉니다.


kubernetes는 이미지의 최신 버전을 가져 오기 위해 새 태그로 배포를 업데이트 할 필요가 없습니다. 가장 일반적인 예는 "최신"입니다.
— Dave White

1

Azure DevOps를 사용하여 컨테이너화 애플리케이션을 배포하고 있으며 빌드 ID를 사용하여이 문제를 쉽게 극복 할 수 있습니다.

빌드 할 때마다 새 빌드 ID를 생성 할 때마다이 빌드 ID를 도커 이미지의 태그로 사용합니다.

이미지 이름 : buildID

이미지가 성공적으로 빌드 (CI)되면 배포 yml 파일의 CD 파이프 라인에서 이미지 이름을 다음과 같이 제공합니다.

이미지 이름 : env : buildID

여기서 evn : buildid는 빌드 ID의 값을 갖는 azure devops 변수입니다.

이제 빌드 (CI) 및 배포 (CD)에 대한 새로운 변경 사항이있을 때마다.

CI / CD에 대한 빌드 정의가 필요한 경우 의견을 보내주십시오.


매니페스트는 저장소의 일부입니다. 이에 대한 모범 사례가 무엇인지 이해하지 못합니다. 파이프 라인에서 이미지를 빌드하는 경우 업데이트 된 매니페스트를 마스터하도록 푸시해야합니까? 또는 아티팩트에 업데이트 된 매니페스트를 생성해야합니까 (따라서 리포지토리의 매니페스트는 실제 태그가 지정된 이미지가없는 템플릿 일뿐입니다)?
— pablete
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.