반응형
쿠버네티스에 이미지를 배포할때 imagePullPolicy를 보통 IfNotPresent로 하게 된다. 이때 만약 부득이한 상황으로 이미지 태그를 업데이트하지 않고 다시 빌드해서 레지스트리에 올렸을 때, 정상적으로 이미지가 재배포되지 않는다. 개발용으로 빌드할때도 이런 경우를 마주할수 있는데, 모든 워커노드에서 다운로드된 특정 컨테이너 이미지를 찾아서 삭제해주는 방법을 공유한다.
이 방식은 Containerd를 런타임으로 사용하는 쿠버네티스 1.24 버전부터 사용가능하다.
먼저, crictl (Containerd ctl) 을 가지고 이미지를 만들어야 한다.
FROM alpine:latest
ARG CRICTL_VERSION="v1.31.1"
# https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.31.1/crictl-v1.31.1-linux-amd64.tar.gz
RUN wget https://github.com/kubernetes-sigs/cri-tools/releases/download/${CRICTL_VERSION}/crictl-${CRICTL_VERSION}-linux-amd64.tar.gz && \
tar zxvf crictl-${CRICTL_VERSION}-linux-amd64.tar.gz -C /usr/local/bin
ENTRYPOINT crictl
해당 이미지를 가진 Job 매니페스트는 다음과 같다.
apiVersion: batch/v1
kind: Job
metadata:
name: {{JOB_NAME}}
spec:
parallelism: {{PARALLELISM}}
completions: {{PARALLELISM}}
template:
metadata:
labels:
job-name: {{JOB_NAME}}
spec:
nodeSelector:
node-role.kubernetes.io/worker: "true"
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
job-name: {{JOB_NAME}}
topologyKey: "kubernetes.io/hostname"
containers:
- name: delete-image
image: crictl:1.31.1
imagePullPolicy: Always
command:
- sh
- -c
- |
# List images and delete the specified image
crictl images
crictl -t 300s rmi {{IMAGE_NAME}} || true
env:
- name: CONTAINER_RUNTIME_ENDPOINT
value: unix:///run/containerd/containerd.sock
- name: IMAGE_SERVICE_ENDPOINT
value: unix:///run/containerd/containerd.sock
securityContext:
privileged: true
volumeMounts:
- name: containerd
mountPath: /run/containerd/containerd.sock
restartPolicy: Never
volumes:
- name: containerd
hostPath:
path: /run/containerd/containerd.sock
type: Socket
해당 Job을 돌려주는 쉘스크립트는 다음과 같다.
반응형
#!/bin/bash
# Exit immediately if a command exits with a non-zero status
set -e
# Function to display usage
usage() {
echo "Usage: $0 -n|--name <image-name>"
echo
echo "Options:"
echo " -n, --name Name of the image to delete"
echo " -h, --help Display this help message"
exit 1
}
# Parse arguments
IMAGE_NAME=""
while [[ $# -gt 0 ]]; do
key="$1"
case $key in
-n|--name)
IMAGE_NAME="$2"
shift # past argument
shift # past value
;;
-h|--help)
usage
;;
*) # unknown option
echo "Unknown option: $1"
usage
;;
esac
done
if [[ -z "$IMAGE_NAME" ]]; then
echo "Error: Image name is required."
usage
fi
# Get the number of worker nodes with label node-role.kubernetes.io/worker=true
NODE_COUNT=$(kubectl get nodes -l node-role.kubernetes.io/worker=true --no-headers | wc -l)
if [[ "$NODE_COUNT" -eq 0 ]]; then
echo "No worker nodes with label 'node-role.kubernetes.io/worker=true' found in the cluster."
exit 1
fi
echo "Found $NODE_COUNT worker nodes."
# Generate a unique job name
JOB_NAME="cleanup-image-job-$(date +%s)"
# Generate the Job manifest by replacing placeholders
sed "s/{{JOB_NAME}}/$JOB_NAME/g; s/{{PARALLELISM}}/$NODE_COUNT/g; s|{{IMAGE_NAME}}|$IMAGE_NAME|g" job.yaml.tpl | kubectl apply -f -
echo "Job '$JOB_NAME' has been created to delete image '$IMAGE_NAME' across all worker nodes."
echo "Delete the job after finished"
사용방법은 다음과 같다.
$ bash ./cleanup-image.sh -n {이미지이름(태그포함)}
그러면 워커노드별로 파드가 하나씩 뜨면서 노드에 저정된 해당 이미지를 삭제한다.
반응형
'Development' 카테고리의 다른 글
데이터 엔지니어링 로드맵 (0) | 2024.11.17 |
---|---|
devops problem solving(이슈해결 역량 기르기 팁) (0) | 2024.11.14 |
GPT와 개발 (0) | 2024.11.02 |
Jupyterhub with spark on k8s 설치 삽질기 & 팁 (0) | 2024.10.26 |
Prometheus TSDB 분석 (0) | 2024.01.28 |