본문 바로가기

개발하자

어떻게 하면 쿠버네티스가 이미지를 다시 끌어오도록 할 수 있을까요?

반응형

어떻게 하면 쿠버네티스가 이미지를 다시 끌어오도록 할 수 있을까요?

GKE의 Kubernetes에는 다음과 같은 복제 컨트롤러가 있습니다.

apiVersion: v1
kind: ReplicationController
metadata:
  name: myapp
  labels:
    app: myapp
spec:
  replicas: 2
  selector:
    app: myapp
    deployment: initial
  template:
    metadata:
      labels:
        app: myapp
        deployment: initial
    spec:
      containers:
      - name: myapp
        image: myregistry.com/myapp:5c3dda6b
        ports:
        - containerPort: 80
      imagePullPolicy: Always
      imagePullSecrets:
        - name: myregistry.com-registry-key

이제, 내가 말한다면

kubectl rolling-update myapp --image=us.gcr.io/project-107012/myapp:5c3dda6b

롤링 업데이트가 수행되지만 다시 당기지는 않습니다. 왜죠?




이미지 인수가 지정된 경우 현재 복제 컨트롤러에 존재하는 것보다 롤링 업데이트 명령이 더 큽니다.




규격 데이터 내부가 아닌 컨테이너 데이터 내부로 그룹화해야 합니다. 하지만, 저는 이것이 이상하다고 생각해서 이것에 대해 서류를 제출했습니다. 게다가, 오류 메시지는 없습니다.

따라서 이 규격의 스니펫은 다음과 같이 작동합니다.

spec:
  containers:
  - name: myapp
    image: myregistry.com/myapp:5c3dda6b
    ports:
    - containerPort: 80
    imagePullPolicy: Always
  imagePullSecrets:
    - name: myregistry.com-registry-key



쿠버네티스는 다음 중 하나에 해당하는 경우 포드 생성을 수행합니다( 참조:

  • 태그가 지정된 이미지 사용
  • 지정됨

당신이 항상 당기길 원한다면 이것은 훌륭하다. 그러나 만약 당신이 그것을 하고 싶다면: 예를 들어, 당신이 그것을 요청할 때 새로운 버전을 수동으로 끌어오고 싶을 때. 현재 사용할 수 있는 기능:

  • 또는 로 설정 및 : 각 클러스터 노드에서 수동으로 이미지를 가져와 최신 버전이 캐시되도록 한 다음 또는 유사한 작업을 수행하여 포드를 다시 시작합니다(못생기게 쉽게 부서지는 해킹!).
  • 변경, 실행, 포드 재시작(예: 되돌리기, 다시 실행)
  • 개인 저장소로 이동하여 (헤비!)를 수행합니다.

온 디맨드 인력을 위한 좋은 솔루션이 없습니다. 변경 사항이 있으면 댓글을 달아 주십시오. 이 답변을 업데이트하겠습니다.




이제 기존 컨테이너 이미지와 동일한 인수를 사용하여 롤링 업데이트를 실행할 때도 를 지정해야 합니다. 다음 명령은 용기 이미지와 동일한 경우 이미지를 강제로 당겨야 합니다.

kubectl rolling-update myapp --image=us.gcr.io/project-107012/myapp:5c3dda6b --image-pull-policy Always




개발 중의 내 해킹은 내 배포 매니페스트를 최신 태그를 추가하도록 변경하고 항상 그렇게 당기는 것이다.

image: etoews/my-image:latest
imagePullPolicy: Always

그런 다음 포드를 수동으로 삭제합니다.

kubectl delete pod my-app-3498980157-2zxhd

배포이기 때문에 Kubernetes는 자동으로 포드를 다시 만들고 최신 이미지를 가져옵니다.




A에서는 더미 주석(또는 레이블)을 사용하여 배포를 패치합니다.

kubectl patch deployment <name> -p \
  "{\"spec\":{\"template\":{\"metadata\":{\"annotations\":{\"date\":\"`date +'%s'`\"}}}}}"

배포를 가정하면 K8이 새 이미지를 가져오고 다시 배포합니다.




이를 직접 수행하기 위한 명령이 있습니다.

배포를 롤링 재시작하는 새 명령을 생성합니다.

병합되었습니다. 버전() 이상의 일부입니다.




배포 파일에 정의할 수 있습니다.




이제 정책과 결합된 명령을 사용하여 이미지의 최신 버전으로 모든 포드를 다시 시작할 수 있습니다.




# Linux

kubectl patch deployment <name> -p "{\"spec\":{\"template\":{\"metadata\":{\"annotations\":{\"date\":\"`date +'%s'`\"}}}}}"

# windows

kubectl patch deployment <name> -p (-join("{\""spec\"":{\""template\"":{\""metadata\"":{\""annotations\"":{\""date\"":\""" , $(Get-Date -Format o).replace(':','-').replace('+','_') , "\""}}}}}"))



이미지 꺼내기 정책은 실제로 새 포드가 생성될 때마다 이미지를 꺼내는 데 항상 도움이 됩니다(이는 어떤 경우에도 복제본 크기 조정, 포드 다이 및 새 포드가 생성될 수 있음).

그러나 현재 실행 중인 포드의 이미지를 업데이트하려면 배포하는 것이 가장 좋습니다. 문제 없이 완벽한 업데이트를 유지합니다(주로 포드에 지속적인 볼륨이 연결되어 있을 때) :).




  1. 전략을 다음과 같이 지정합니다.
  strategy: 
    type: Recreate
    rollingUpdate: null
  1. 각 배포에 대해 서로 다른 주석이 있는지 확인하십시오. 헬름은 다음과 같이 한다.
  template:
    metadata:
      labels:
        app.kubernetes.io/name: AppName
        app.kubernetes.io/instance: ReleaseName
      annotations:
        rollme: {{ randAlphaNum 5 | quote }}
  1. 이미지 꺼내기 정책 지정 - 항상
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          imagePullPolicy: Always



이 대답은 노드가 동일한 이름의 이미지를 이미 다운로드한 상황에서 이미지를 강제로 끌어오기 위한 것이므로 컨테이너 레지스트리에 새 이미지를 푸시하더라도 일부 포드를 회전시키면 포드가 "이미지가 이미 있습니다"라고 표시됩니다.

Azure Container Registry의 경우(아마도 AWS와 GCP도 이를 제공합니다):

  1. 당신은 당신의 Azure 컨테이너 레지스트리를 볼 수 있고 매니페스트 생성 날짜를 확인함으로써 당신은 가장 최근의 이미지가 무엇인지 식별할 수 있다.

  2. Then, copy its digest hash (which has a format of sha256:xxx...xxx).

  3. You can scale down your current replica by running command below. Note that this will obviously stop your container and cause downtime.

kubectl scale --replicas=0 deployment <deployment-name> -n <namespace-name>
  1. Then you can get the copy of the deployment.yaml by running:
kubectl get deployments.apps <deployment-name> -o yaml > deployment.yaml
  1. Then change the line with image field from <image-name>:<tag> to <image-name>@sha256:xxx...xxx, save the file.

  2. Now you can scale up your replicas again. New image will be pulled with its unique digest.

Note: It is assumed that, imagePullPolicy: Always field is present in the container.




Having gone through all the other answers and not being satisfied, I found much better solution here: https://cloud.google.com/kubernetes-engine/docs/how-to/updating-apps

It works without using latest tag or imagePullPolicy: Always. It also works if you push new image to the same tag by specifying image sha256 digest.

Steps:

  1. get image SHA256 from docker hub (see image below)
  2. kubectl set image deployment/<your-deployment> <your_container_name>=<some/image>@sha256:<your sha>
  3. kubectl scale deployment <your-deployment>--replicas=0
  4. kubectl scale deployment <your-deployment>--replicas=original replicas count

Note: Rollout might also work instead of scale but in my case we don't have enough hardware resources to create another instance and k8s gets stuck.

docker hub sha256 location




if you want to perform a direct image update on a specific pod, you can use kubectl set image also.

https://kubernetes.io/docs/concepts/workloads/controllers/deployment/




either you have deleted all the pods manually to get it recreated with pulling the image again.

or

run this below command kubectl rollout restart deployment/deployment_name kubectl rollout restart deployment/nginx

this command should recreate all the pods.

for both scenarios imagepullPolicy should be set as Always.




I have used kubectl rollout restart for my springboot api and it works.

kubectl rollout restart -f pod-staging.yml --namespace test

Yaml for the Deployment:

apiVersion: "apps/v1"
kind: "Deployment"
metadata:
    name: "my-api"
    labels:
      app: "my-api"
spec:
  replicas: 1
  selector:
    matchLabels:
      app: "my-api"
  template:
    metadata:
      labels:
        app: "my-api"
    spec:
      containers:
        - name: my-api
          image: harbor.url.com/mycompany/my-api:staging
          ports:
            - containerPort: 8099
              protocol: TCP
          imagePullPolicy: Always
          livenessProbe:
            httpGet:
              path: /actuator/health/liveness
              port: 8099
            initialDelaySeconds: 90
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /actuator/health/readiness
              port: 8099
            initialDelaySeconds: 90
            periodSeconds: 5
          envFrom:
            - configMapRef:
                name: "my-api-configmap"
          env:
            - name: "TOKEN_VALUE"
              valueFrom:
                secretKeyRef:
                  name: "my-api-secret"
                  key: "TOKEN_VALUE"
          resources:
            requests:
              memory: "512Mi"
              cpu: "500m"
            limits:
              memory: "2048Mi"
              cpu: "1000m"
      imagePullSecrets:
        - name: "my-ci-user"



The below solved my problem:

kubectl rollout restart

반응형