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.