bin: improve manage-offline-container-images script (#10857)
Fixes bug for retrieving images with tags containing image digests. Script now gets images from jobs and cronjobs as well. New env variable DESTINATION_REGISTRY to push to another registry instead of local registry. New env variable IMAGES_FROM_FILE to pull images listed in a file instead of getting images from a running k8s environment. New env variable REGISTRY_PORT to override port (default is 5000).pull/10943/head
parent
65b0604db7
commit
8fa5ae1865
|
@ -3,6 +3,8 @@
|
||||||
**/vagrant_ansible_inventory
|
**/vagrant_ansible_inventory
|
||||||
*.iml
|
*.iml
|
||||||
temp
|
temp
|
||||||
|
contrib/offline/container-images
|
||||||
|
contrib/offline/container-images.tar.gz
|
||||||
contrib/offline/offline-files
|
contrib/offline/offline-files
|
||||||
contrib/offline/offline-files.tar.gz
|
contrib/offline/offline-files.tar.gz
|
||||||
.idea
|
.idea
|
||||||
|
|
|
@ -5,15 +5,17 @@
|
||||||
Container image collecting script for offline deployment
|
Container image collecting script for offline deployment
|
||||||
|
|
||||||
This script has two features:
|
This script has two features:
|
||||||
|
(1) Get container images from an environment which is deployed online, or set IMAGES_FROM_FILE
|
||||||
(1) Get container images from an environment which is deployed online.
|
environment variable to get images from a file (e.g. temp/images.list after running the
|
||||||
|
./generate_list.sh script).
|
||||||
(2) Deploy local container registry and register the container images to the registry.
|
(2) Deploy local container registry and register the container images to the registry.
|
||||||
|
|
||||||
Step(1) should be done online site as a preparation, then we bring the gotten images
|
Step(1) should be done online site as a preparation, then we bring the gotten images
|
||||||
to the target offline environment. if images are from a private registry,
|
to the target offline environment. if images are from a private registry,
|
||||||
you need to set `PRIVATE_REGISTRY` environment variable.
|
you need to set `PRIVATE_REGISTRY` environment variable.
|
||||||
Then we will run step(2) for registering the images to local registry.
|
Then we will run step(2) for registering the images to local registry, or to an existing
|
||||||
|
registry set by the `DESTINATION_REGISTRY` environment variable. By default, the local registry
|
||||||
|
will run on port 5000. This can be changed with the `REGISTRY_PORT` environment variable
|
||||||
|
|
||||||
Step(1) can be operated with:
|
Step(1) can be operated with:
|
||||||
|
|
||||||
|
|
|
@ -12,11 +12,24 @@ RETRY_COUNT=5
|
||||||
function create_container_image_tar() {
|
function create_container_image_tar() {
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
IMAGES=$(kubectl describe pods --all-namespaces | grep " Image:" | awk '{print $2}' | sort | uniq)
|
if [ -z "${IMAGES_FROM_FILE}" ]; then
|
||||||
# NOTE: etcd and pause cannot be seen as pods.
|
echo "Getting images from current \"$(kubectl config current-context)\""
|
||||||
# The pause image is used for --pod-infra-container-image option of kubelet.
|
|
||||||
EXT_IMAGES=$(kubectl cluster-info dump | egrep "quay.io/coreos/etcd:|registry.k8s.io/pause:" | sed s@\"@@g)
|
IMAGES=$(mktemp --suffix=-images)
|
||||||
IMAGES="${IMAGES} ${EXT_IMAGES}"
|
trap 'rm -f "${IMAGES}"' EXIT
|
||||||
|
|
||||||
|
kubectl describe cronjobs,jobs,pods --all-namespaces | grep " Image:" | awk '{print $2}' | sort | uniq > "${IMAGES}"
|
||||||
|
# NOTE: etcd and pause cannot be seen as pods.
|
||||||
|
# The pause image is used for --pod-infra-container-image option of kubelet.
|
||||||
|
kubectl cluster-info dump | grep -E "quay.io/coreos/etcd:|registry.k8s.io/pause:" | sed s@\"@@g >> "${IMAGES}"
|
||||||
|
else
|
||||||
|
echo "Getting images from file \"${IMAGES_FROM_FILE}\""
|
||||||
|
if [ ! -f "${IMAGES_FROM_FILE}" ]; then
|
||||||
|
echo "${IMAGES_FROM_FILE} is not a file"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
IMAGES=$(realpath $IMAGES_FROM_FILE)
|
||||||
|
fi
|
||||||
|
|
||||||
rm -f ${IMAGE_TAR_FILE}
|
rm -f ${IMAGE_TAR_FILE}
|
||||||
rm -rf ${IMAGE_DIR}
|
rm -rf ${IMAGE_DIR}
|
||||||
|
@ -26,9 +39,9 @@ function create_container_image_tar() {
|
||||||
sudo ${runtime} pull registry:latest
|
sudo ${runtime} pull registry:latest
|
||||||
sudo ${runtime} save -o registry-latest.tar registry:latest
|
sudo ${runtime} save -o registry-latest.tar registry:latest
|
||||||
|
|
||||||
for image in ${IMAGES}
|
while read -r image
|
||||||
do
|
do
|
||||||
FILE_NAME="$(echo ${image} | sed s@"/"@"-"@g | sed s/":"/"-"/g)".tar
|
FILE_NAME="$(echo ${image} | sed s@"/"@"-"@g | sed s/":"/"-"/g | sed -E 's/\@.*//g')".tar
|
||||||
set +e
|
set +e
|
||||||
for step in $(seq 1 ${RETRY_COUNT})
|
for step in $(seq 1 ${RETRY_COUNT})
|
||||||
do
|
do
|
||||||
|
@ -48,18 +61,20 @@ function create_container_image_tar() {
|
||||||
# so that these parts will be replaced with Kubespray.
|
# so that these parts will be replaced with Kubespray.
|
||||||
# - kube_image_repo: "registry.k8s.io"
|
# - kube_image_repo: "registry.k8s.io"
|
||||||
# - gcr_image_repo: "gcr.io"
|
# - gcr_image_repo: "gcr.io"
|
||||||
|
# - ghcr_image_repo: "ghcr.io"
|
||||||
# - docker_image_repo: "docker.io"
|
# - docker_image_repo: "docker.io"
|
||||||
# - quay_image_repo: "quay.io"
|
# - quay_image_repo: "quay.io"
|
||||||
FIRST_PART=$(echo ${image} | awk -F"/" '{print $1}')
|
FIRST_PART=$(echo ${image} | awk -F"/" '{print $1}')
|
||||||
if [ "${FIRST_PART}" = "registry.k8s.io" ] ||
|
if [ "${FIRST_PART}" = "registry.k8s.io" ] ||
|
||||||
[ "${FIRST_PART}" = "gcr.io" ] ||
|
[ "${FIRST_PART}" = "gcr.io" ] ||
|
||||||
|
[ "${FIRST_PART}" = "ghcr.io" ] ||
|
||||||
[ "${FIRST_PART}" = "docker.io" ] ||
|
[ "${FIRST_PART}" = "docker.io" ] ||
|
||||||
[ "${FIRST_PART}" = "quay.io" ] ||
|
[ "${FIRST_PART}" = "quay.io" ] ||
|
||||||
[ "${FIRST_PART}" = "${PRIVATE_REGISTRY}" ]; then
|
[ "${FIRST_PART}" = "${PRIVATE_REGISTRY}" ]; then
|
||||||
image=$(echo ${image} | sed s@"${FIRST_PART}/"@@)
|
image=$(echo ${image} | sed s@"${FIRST_PART}/"@@ | sed -E 's/\@.*/\n/g')
|
||||||
fi
|
fi
|
||||||
echo "${FILE_NAME} ${image}" >> ${IMAGE_LIST}
|
echo "${FILE_NAME} ${image}" >> ${IMAGE_LIST}
|
||||||
done
|
done < "${IMAGES}"
|
||||||
|
|
||||||
cd ..
|
cd ..
|
||||||
sudo chown ${USER} ${IMAGE_DIR}/*
|
sudo chown ${USER} ${IMAGE_DIR}/*
|
||||||
|
@ -72,6 +87,16 @@ function create_container_image_tar() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function register_container_images() {
|
function register_container_images() {
|
||||||
|
create_registry=false
|
||||||
|
REGISTRY_PORT=${REGISTRY_PORT:-"5000"}
|
||||||
|
|
||||||
|
if [ -z "${DESTINATION_REGISTRY}" ]; then
|
||||||
|
echo "DESTINATION_REGISTRY not set, will create local registry"
|
||||||
|
create_registry=true
|
||||||
|
DESTINATION_REGISTRY="$(hostname):${REGISTRY_PORT}"
|
||||||
|
fi
|
||||||
|
echo "Images will be pushed to ${DESTINATION_REGISTRY}"
|
||||||
|
|
||||||
if [ ! -f ${IMAGE_TAR_FILE} ]; then
|
if [ ! -f ${IMAGE_TAR_FILE} ]; then
|
||||||
echo "${IMAGE_TAR_FILE} should exist."
|
echo "${IMAGE_TAR_FILE} should exist."
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -81,18 +106,17 @@ function register_container_images() {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# To avoid "http: server gave http response to https client" error.
|
# To avoid "http: server gave http response to https client" error.
|
||||||
LOCALHOST_NAME=$(hostname)
|
|
||||||
if [ -d /etc/docker/ ]; then
|
if [ -d /etc/docker/ ]; then
|
||||||
set -e
|
set -e
|
||||||
# Ubuntu18.04, RHEL7/CentOS7
|
# Ubuntu18.04, RHEL7/CentOS7
|
||||||
cp ${CURRENT_DIR}/docker-daemon.json ${TEMP_DIR}/docker-daemon.json
|
cp ${CURRENT_DIR}/docker-daemon.json ${TEMP_DIR}/docker-daemon.json
|
||||||
sed -i s@"HOSTNAME"@"${LOCALHOST_NAME}"@ ${TEMP_DIR}/docker-daemon.json
|
sed -i s@"HOSTNAME"@"$(hostname)"@ ${TEMP_DIR}/docker-daemon.json
|
||||||
sudo cp ${TEMP_DIR}/docker-daemon.json /etc/docker/daemon.json
|
sudo cp ${TEMP_DIR}/docker-daemon.json /etc/docker/daemon.json
|
||||||
elif [ -d /etc/containers/ ]; then
|
elif [ -d /etc/containers/ ]; then
|
||||||
set -e
|
set -e
|
||||||
# RHEL8/CentOS8
|
# RHEL8/CentOS8
|
||||||
cp ${CURRENT_DIR}/registries.conf ${TEMP_DIR}/registries.conf
|
cp ${CURRENT_DIR}/registries.conf ${TEMP_DIR}/registries.conf
|
||||||
sed -i s@"HOSTNAME"@"${LOCALHOST_NAME}"@ ${TEMP_DIR}/registries.conf
|
sed -i s@"HOSTNAME"@"$(hostname)"@ ${TEMP_DIR}/registries.conf
|
||||||
sudo cp ${TEMP_DIR}/registries.conf /etc/containers/registries.conf
|
sudo cp ${TEMP_DIR}/registries.conf /etc/containers/registries.conf
|
||||||
else
|
else
|
||||||
echo "runtime package(docker-ce, podman, nerctl, etc.) should be installed"
|
echo "runtime package(docker-ce, podman, nerctl, etc.) should be installed"
|
||||||
|
@ -100,19 +124,28 @@ function register_container_images() {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
tar -zxvf ${IMAGE_TAR_FILE}
|
tar -zxvf ${IMAGE_TAR_FILE}
|
||||||
sudo ${runtime} load -i ${IMAGE_DIR}/registry-latest.tar
|
|
||||||
set +e
|
if [ "${create_registry}" ]; then
|
||||||
sudo ${runtime} container inspect registry >/dev/null 2>&1
|
sudo ${runtime} load -i ${IMAGE_DIR}/registry-latest.tar
|
||||||
if [ $? -ne 0 ]; then
|
set +e
|
||||||
sudo ${runtime} run --restart=always -d -p 5000:5000 --name registry registry:latest
|
|
||||||
|
sudo ${runtime} container inspect registry >/dev/null 2>&1
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
sudo ${runtime} run --restart=always -d -p "${REGISTRY_PORT}":"${REGISTRY_PORT}" --name registry registry:latest
|
||||||
|
fi
|
||||||
|
set -e
|
||||||
fi
|
fi
|
||||||
set -e
|
|
||||||
|
|
||||||
while read -r line; do
|
while read -r line; do
|
||||||
file_name=$(echo ${line} | awk '{print $1}')
|
file_name=$(echo ${line} | awk '{print $1}')
|
||||||
raw_image=$(echo ${line} | awk '{print $2}')
|
raw_image=$(echo ${line} | awk '{print $2}')
|
||||||
new_image="${LOCALHOST_NAME}:5000/${raw_image}"
|
new_image="${DESTINATION_REGISTRY}/${raw_image}"
|
||||||
org_image=$(sudo ${runtime} load -i ${IMAGE_DIR}/${file_name} | head -n1 | awk '{print $3}')
|
load_image=$(sudo ${runtime} load -i ${IMAGE_DIR}/${file_name} | head -n1)
|
||||||
|
org_image=$(echo "${load_image}" | awk '{print $3}')
|
||||||
|
# special case for tags containing the digest when using docker or podman as the container runtime
|
||||||
|
if [ "${org_image}" == "ID:" ]; then
|
||||||
|
org_image=$(echo "${load_image}" | awk '{print $4}')
|
||||||
|
fi
|
||||||
image_id=$(sudo ${runtime} image inspect ${org_image} | grep "\"Id\":" | awk -F: '{print $3}'| sed s/'\",'//)
|
image_id=$(sudo ${runtime} image inspect ${org_image} | grep "\"Id\":" | awk -F: '{print $3}'| sed s/'\",'//)
|
||||||
if [ -z "${file_name}" ]; then
|
if [ -z "${file_name}" ]; then
|
||||||
echo "Failed to get file_name for line ${line}"
|
echo "Failed to get file_name for line ${line}"
|
||||||
|
@ -136,7 +169,7 @@ function register_container_images() {
|
||||||
done <<< "$(cat ${IMAGE_LIST})"
|
done <<< "$(cat ${IMAGE_LIST})"
|
||||||
|
|
||||||
echo "Succeeded to register container images to local registry."
|
echo "Succeeded to register container images to local registry."
|
||||||
echo "Please specify ${LOCALHOST_NAME}:5000 for the following options in your inventry:"
|
echo "Please specify \"${DESTINATION_REGISTRY}\" for the following options in your inventry:"
|
||||||
echo "- kube_image_repo"
|
echo "- kube_image_repo"
|
||||||
echo "- gcr_image_repo"
|
echo "- gcr_image_repo"
|
||||||
echo "- docker_image_repo"
|
echo "- docker_image_repo"
|
||||||
|
@ -161,13 +194,17 @@ elif [ "${OPTION}" == "register" ]; then
|
||||||
register_container_images
|
register_container_images
|
||||||
else
|
else
|
||||||
echo "This script has two features:"
|
echo "This script has two features:"
|
||||||
echo "(1) Get container images from an environment which is deployed online."
|
echo "(1) Get container images from an environment which is deployed online, or set IMAGES_FROM_FILE"
|
||||||
|
echo " environment variable to get images from a file (e.g. temp/images.list after running the"
|
||||||
|
echo " ./generate_list.sh script)."
|
||||||
echo "(2) Deploy local container registry and register the container images to the registry."
|
echo "(2) Deploy local container registry and register the container images to the registry."
|
||||||
echo ""
|
echo ""
|
||||||
echo "Step(1) should be done online site as a preparation, then we bring"
|
echo "Step(1) should be done online site as a preparation, then we bring"
|
||||||
echo "the gotten images to the target offline environment. if images are from"
|
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."
|
echo "a private registry, you need to set PRIVATE_REGISTRY environment variable."
|
||||||
echo "Then we will run step(2) for registering the images to local registry."
|
echo "Then we will run step(2) for registering the images to local registry, or to an existing"
|
||||||
|
echo "registry set by the DESTINATION_REGISTRY environment variable. By default, the local registry"
|
||||||
|
echo "will run on port 5000. This can be changed with the REGISTRY_PORT environment variable"
|
||||||
echo ""
|
echo ""
|
||||||
echo "${IMAGE_TAR_FILE} is created to contain your container images."
|
echo "${IMAGE_TAR_FILE} is created to contain your container images."
|
||||||
echo "Please keep this file and bring it to your offline environment."
|
echo "Please keep this file and bring it to your offline environment."
|
||||||
|
|
Loading…
Reference in New Issue