2021-01-07 00:05:52 +08:00
|
|
|
#!/bin/bash
|
|
|
|
|
|
|
|
OPTION=$1
|
|
|
|
CURRENT_DIR=$(cd $(dirname $0); pwd)
|
|
|
|
TEMP_DIR="${CURRENT_DIR}/temp"
|
|
|
|
|
|
|
|
IMAGE_TAR_FILE="${CURRENT_DIR}/container-images.tar.gz"
|
|
|
|
IMAGE_DIR="${CURRENT_DIR}/container-images"
|
|
|
|
IMAGE_LIST="${IMAGE_DIR}/container-images.txt"
|
|
|
|
RETRY_COUNT=5
|
|
|
|
|
|
|
|
function create_container_image_tar() {
|
|
|
|
set -e
|
|
|
|
|
|
|
|
IMAGES=$(kubectl describe pods --all-namespaces | grep " Image:" | awk '{print $2}' | sort | uniq)
|
|
|
|
# NOTE: etcd and pause cannot be seen as pods.
|
|
|
|
# The pause image is used for --pod-infra-container-image option of kubelet.
|
2022-06-07 15:55:42 +08:00
|
|
|
EXT_IMAGES=$(kubectl cluster-info dump | egrep "quay.io/coreos/etcd:|registry.k8s.io/pause:" | sed s@\"@@g)
|
2021-01-07 00:05:52 +08:00
|
|
|
IMAGES="${IMAGES} ${EXT_IMAGES}"
|
|
|
|
|
|
|
|
rm -f ${IMAGE_TAR_FILE}
|
|
|
|
rm -rf ${IMAGE_DIR}
|
|
|
|
mkdir ${IMAGE_DIR}
|
|
|
|
cd ${IMAGE_DIR}
|
|
|
|
|
2023-12-21 23:45:09 +08:00
|
|
|
sudo ${runtime} pull registry:latest
|
|
|
|
sudo ${runtime} save -o registry-latest.tar registry:latest
|
2021-01-07 00:05:52 +08:00
|
|
|
|
|
|
|
for image in ${IMAGES}
|
|
|
|
do
|
|
|
|
FILE_NAME="$(echo ${image} | sed s@"/"@"-"@g | sed s/":"/"-"/g)".tar
|
|
|
|
set +e
|
|
|
|
for step in $(seq 1 ${RETRY_COUNT})
|
|
|
|
do
|
2023-12-21 23:45:09 +08:00
|
|
|
sudo ${runtime} pull ${image}
|
2021-01-07 00:05:52 +08:00
|
|
|
if [ $? -eq 0 ]; then
|
|
|
|
break
|
|
|
|
fi
|
|
|
|
echo "Failed to pull ${image} at step ${step}"
|
|
|
|
if [ ${step} -eq ${RETRY_COUNT} ]; then
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
set -e
|
2023-12-21 23:45:09 +08:00
|
|
|
sudo ${runtime} save -o ${FILE_NAME} ${image}
|
2021-01-07 00:05:52 +08:00
|
|
|
|
|
|
|
# NOTE: Here removes the following repo parts from each image
|
|
|
|
# so that these parts will be replaced with Kubespray.
|
2022-06-07 15:55:42 +08:00
|
|
|
# - kube_image_repo: "registry.k8s.io"
|
2021-01-07 00:05:52 +08:00
|
|
|
# - gcr_image_repo: "gcr.io"
|
|
|
|
# - docker_image_repo: "docker.io"
|
|
|
|
# - quay_image_repo: "quay.io"
|
|
|
|
FIRST_PART=$(echo ${image} | awk -F"/" '{print $1}')
|
2022-06-07 15:55:42 +08:00
|
|
|
if [ "${FIRST_PART}" = "registry.k8s.io" ] ||
|
2021-01-07 00:05:52 +08:00
|
|
|
[ "${FIRST_PART}" = "gcr.io" ] ||
|
|
|
|
[ "${FIRST_PART}" = "docker.io" ] ||
|
2022-05-13 14:23:14 +08:00
|
|
|
[ "${FIRST_PART}" = "quay.io" ] ||
|
|
|
|
[ "${FIRST_PART}" = "${PRIVATE_REGISTRY}" ]; then
|
2021-01-07 00:05:52 +08:00
|
|
|
image=$(echo ${image} | sed s@"${FIRST_PART}/"@@)
|
|
|
|
fi
|
|
|
|
echo "${FILE_NAME} ${image}" >> ${IMAGE_LIST}
|
|
|
|
done
|
|
|
|
|
|
|
|
cd ..
|
|
|
|
sudo chown ${USER} ${IMAGE_DIR}/*
|
|
|
|
tar -zcvf ${IMAGE_TAR_FILE} ./container-images
|
|
|
|
rm -rf ${IMAGE_DIR}
|
|
|
|
|
|
|
|
echo ""
|
|
|
|
echo "${IMAGE_TAR_FILE} is created to contain your container images."
|
|
|
|
echo "Please keep this file and bring it to your offline environment."
|
|
|
|
}
|
|
|
|
|
|
|
|
function register_container_images() {
|
|
|
|
if [ ! -f ${IMAGE_TAR_FILE} ]; then
|
|
|
|
echo "${IMAGE_TAR_FILE} should exist."
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
if [ ! -d ${TEMP_DIR} ]; then
|
|
|
|
mkdir ${TEMP_DIR}
|
|
|
|
fi
|
|
|
|
|
|
|
|
# To avoid "http: server gave http response to https client" error.
|
|
|
|
LOCALHOST_NAME=$(hostname)
|
|
|
|
if [ -d /etc/docker/ ]; then
|
|
|
|
set -e
|
|
|
|
# Ubuntu18.04, RHEL7/CentOS7
|
|
|
|
cp ${CURRENT_DIR}/docker-daemon.json ${TEMP_DIR}/docker-daemon.json
|
|
|
|
sed -i s@"HOSTNAME"@"${LOCALHOST_NAME}"@ ${TEMP_DIR}/docker-daemon.json
|
|
|
|
sudo cp ${TEMP_DIR}/docker-daemon.json /etc/docker/daemon.json
|
|
|
|
elif [ -d /etc/containers/ ]; then
|
|
|
|
set -e
|
|
|
|
# RHEL8/CentOS8
|
|
|
|
cp ${CURRENT_DIR}/registries.conf ${TEMP_DIR}/registries.conf
|
|
|
|
sed -i s@"HOSTNAME"@"${LOCALHOST_NAME}"@ ${TEMP_DIR}/registries.conf
|
|
|
|
sudo cp ${TEMP_DIR}/registries.conf /etc/containers/registries.conf
|
|
|
|
else
|
2023-12-21 23:45:09 +08:00
|
|
|
echo "runtime package(docker-ce, podman, nerctl, etc.) should be installed"
|
2021-01-07 00:05:52 +08:00
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
tar -zxvf ${IMAGE_TAR_FILE}
|
2023-12-21 23:45:09 +08:00
|
|
|
sudo ${runtime} load -i ${IMAGE_DIR}/registry-latest.tar
|
2021-01-07 00:05:52 +08:00
|
|
|
set +e
|
2023-12-21 23:45:09 +08:00
|
|
|
sudo ${runtime} container inspect registry >/dev/null 2>&1
|
2021-07-26 15:56:33 +08:00
|
|
|
if [ $? -ne 0 ]; then
|
2023-12-21 23:45:09 +08:00
|
|
|
sudo ${runtime} run --restart=always -d -p 5000:5000 --name registry registry:latest
|
2021-07-26 15:56:33 +08:00
|
|
|
fi
|
2021-01-07 00:05:52 +08:00
|
|
|
set -e
|
2021-07-26 15:56:33 +08:00
|
|
|
|
2021-01-07 00:05:52 +08:00
|
|
|
while read -r line; do
|
|
|
|
file_name=$(echo ${line} | awk '{print $1}')
|
2021-07-26 15:56:33 +08:00
|
|
|
raw_image=$(echo ${line} | awk '{print $2}')
|
|
|
|
new_image="${LOCALHOST_NAME}:5000/${raw_image}"
|
2023-12-21 23:45:09 +08:00
|
|
|
org_image=$(sudo ${runtime} load -i ${IMAGE_DIR}/${file_name} | head -n1 | awk '{print $3}')
|
|
|
|
image_id=$(sudo ${runtime} image inspect ${org_image} | grep "\"Id\":" | awk -F: '{print $3}'| sed s/'\",'//)
|
2021-07-19 08:58:51 +08:00
|
|
|
if [ -z "${file_name}" ]; then
|
|
|
|
echo "Failed to get file_name for line ${line}"
|
|
|
|
exit 1
|
|
|
|
fi
|
2021-07-26 15:56:33 +08:00
|
|
|
if [ -z "${raw_image}" ]; then
|
|
|
|
echo "Failed to get raw_image for line ${line}"
|
|
|
|
exit 1
|
|
|
|
fi
|
2021-07-19 08:58:51 +08:00
|
|
|
if [ -z "${org_image}" ]; then
|
|
|
|
echo "Failed to get org_image for line ${line}"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
if [ -z "${image_id}" ]; then
|
|
|
|
echo "Failed to get image_id for file ${file_name}"
|
|
|
|
exit 1
|
|
|
|
fi
|
2023-12-21 23:45:09 +08:00
|
|
|
sudo ${runtime} load -i ${IMAGE_DIR}/${file_name}
|
|
|
|
sudo ${runtime} tag ${image_id} ${new_image}
|
|
|
|
sudo ${runtime} push ${new_image}
|
2021-01-07 00:05:52 +08:00
|
|
|
done <<< "$(cat ${IMAGE_LIST})"
|
|
|
|
|
|
|
|
echo "Succeeded to register container images to local registry."
|
|
|
|
echo "Please specify ${LOCALHOST_NAME}:5000 for the following options in your inventry:"
|
|
|
|
echo "- kube_image_repo"
|
|
|
|
echo "- gcr_image_repo"
|
|
|
|
echo "- docker_image_repo"
|
|
|
|
echo "- quay_image_repo"
|
|
|
|
}
|
|
|
|
|
2023-12-21 23:45:09 +08:00
|
|
|
# get runtime command
|
|
|
|
if command -v nerdctl 1>/dev/null 2>&1; then
|
|
|
|
runtime="nerdctl"
|
|
|
|
elif command -v podman 1>/dev/null 2>&1; then
|
|
|
|
runtime="podman"
|
|
|
|
elif command -v docker 1>/dev/null 2>&1; then
|
|
|
|
runtime="docker"
|
|
|
|
else
|
|
|
|
echo "No supported container runtime found"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
2021-01-07 00:05:52 +08:00
|
|
|
if [ "${OPTION}" == "create" ]; then
|
|
|
|
create_container_image_tar
|
|
|
|
elif [ "${OPTION}" == "register" ]; then
|
|
|
|
register_container_images
|
|
|
|
else
|
|
|
|
echo "This script has two features:"
|
|
|
|
echo "(1) Get container images from an environment which is deployed online."
|
|
|
|
echo "(2) Deploy local container registry and register the container images to the registry."
|
|
|
|
echo ""
|
|
|
|
echo "Step(1) should be done online site as a preparation, then we bring"
|
2022-05-13 14:23:14 +08:00
|
|
|
echo "the gotten images to the target offline environment. if images are from"
|
|
|
|
echo "a private registry, you need to set PRIVATE_REGISTRY environment variable."
|
2021-01-07 00:05:52 +08:00
|
|
|
echo "Then we will run step(2) for registering the images to local registry."
|
|
|
|
echo ""
|
|
|
|
echo "${IMAGE_TAR_FILE} is created to contain your container images."
|
|
|
|
echo "Please keep this file and bring it to your offline environment."
|
|
|
|
echo ""
|
|
|
|
echo "Step(1) can be operated with:"
|
|
|
|
echo " $ ./manage-offline-container-images.sh create"
|
|
|
|
echo ""
|
|
|
|
echo "Step(2) can be operated with:"
|
|
|
|
echo " $ ./manage-offline-container-images.sh register"
|
|
|
|
echo ""
|
|
|
|
echo "Please specify 'create' or 'register'."
|
|
|
|
echo ""
|
|
|
|
exit 1
|
|
|
|
fi
|