diff --git a/contrib/offline/README.md b/contrib/offline/README.md
index 0252e5079a42113d8cfd30e3f4018238569e2403..3f3b8f9ec9abd1fc9fa7207ff0d49dcf51e13042 100644
--- a/contrib/offline/README.md
+++ b/contrib/offline/README.md
@@ -1,4 +1,8 @@
-# Container image collecting script for offline deployment
+# Offline deployment
+
+## manage-offline-container-images.sh
+
+Container image collecting script for offline deployment
 
 This script has two features:
 (1) Get container images from an environment which is deployed online.
@@ -19,3 +23,21 @@ Step(2) can be operated with:
 ```shell
 manage-offline-container-images.sh   register
 ```
+
+## generate_list.sh
+
+This script generates the list of downloaded files and the list of container images by `roles/download/defaults/main.yml` file.
+
+Run this script will generates three files, all downloaded files url in files.list, all container images in images.list, all component version in generate.sh.
+
+```shell
+bash generate_list.sh
+tree temp
+temp
+├── files.list
+├── generate.sh
+└── images.list
+0 directories, 3 files
+```
+
+In some cases you may want to update some component version, you can edit `generate.sh` file, then run `bash generate.sh | grep 'https' > files.list` to update file.list or run `bash generate.sh | grep -v 'https'> images.list` to update images.list.
diff --git a/contrib/offline/generate_list.sh b/contrib/offline/generate_list.sh
new file mode 100644
index 0000000000000000000000000000000000000000..7d77d81355c62b379de9325e04bfc561336d4a6a
--- /dev/null
+++ b/contrib/offline/generate_list.sh
@@ -0,0 +1,57 @@
+#!/bin/bash
+set -eo pipefail
+
+CURRENT_DIR=$(cd $(dirname $0); pwd)
+TEMP_DIR="${CURRENT_DIR}/temp"
+REPO_ROOT_DIR="${CURRENT_DIR%/contrib/offline}"
+
+: ${IMAGE_ARCH:="amd64"}
+: ${ANSIBLE_SYSTEM:="linux"}
+: ${ANSIBLE_ARCHITECTURE:="x86_64"}
+: ${DOWNLOAD_YML:="roles/download/defaults/main.yml"}
+: ${KUBE_VERSION_YAML:="roles/kubespray-defaults/defaults/main.yaml"}
+
+mkdir -p ${TEMP_DIR}
+
+# ARCH used in convert {%- if image_arch != 'amd64' -%}-{{ image_arch }}{%- endif -%} to {{arch}}
+if [ "${IMAGE_ARCH}" != "amd64" ]; then ARCH="${IMAGE_ARCH}"; fi
+
+cat > ${TEMP_DIR}/generate.sh << EOF
+arch=${ARCH}
+image_arch=${IMAGE_ARCH}
+ansible_system=${ANSIBLE_SYSTEM}
+ansible_architecture=${ANSIBLE_ARCHITECTURE}
+EOF
+
+# generate all component version by $DOWNLOAD_YML
+grep 'kube_version:' ${REPO_ROOT_DIR}/${KUBE_VERSION_YAML} \
+| sed 's/: /=/g' >> ${TEMP_DIR}/generate.sh
+grep '_version:' ${REPO_ROOT_DIR}/${DOWNLOAD_YML} \
+| sed 's/: /=/g;s/{{/${/g;s/}}/}/g' | tr -d ' ' >> ${TEMP_DIR}/generate.sh
+sed -i 's/kube_major_version=.*/kube_major_version=${kube_version%.*}/g' ${TEMP_DIR}/generate.sh
+sed -i 's/crictl_version=.*/crictl_version=${kube_version%.*}.0/g' ${TEMP_DIR}/generate.sh
+
+# generate all download files url
+grep 'download_url:' ${REPO_ROOT_DIR}/${DOWNLOAD_YML} \
+| sed 's/: /=/g;s/ //g;s/{{/${/g;s/}}/}/g;s/|lower//g;s/^.*_url=/echo /g' >> ${TEMP_DIR}/generate.sh
+
+# generate all images list
+grep -E '_repo:|_tag:' ${REPO_ROOT_DIR}/${DOWNLOAD_YML} \
+| sed "s#{%- if image_arch != 'amd64' -%}-{{ image_arch }}{%- endif -%}#{{arch}}#g" \
+| sed 's/: /=/g;s/{{/${/g;s/}}/}/g' | tr -d ' ' >> ${TEMP_DIR}/generate.sh
+sed -n '/^downloads:/,/download_defaults:/p' ${REPO_ROOT_DIR}/${DOWNLOAD_YML} \
+| sed -n "s/repo: //p;s/tag: //p" | tr -d ' ' | sed 's/{{/${/g;s/}}/}/g' \
+| sed 'N;s#\n# #g' | tr ' ' ':' | sed 's/^/echo /g' >> ${TEMP_DIR}/generate.sh
+
+# special handling for https://github.com/kubernetes-sigs/kubespray/pull/7570
+sed -i 's#^coredns_image_repo=.*#coredns_image_repo=${kube_image_repo}$(if printf "%s\\n%s\\n" v1.21 ${kube_version%.*} | sort --check=quiet --version-sort; then echo -n /coredns/coredns;else echo -n /coredns; fi)#' ${TEMP_DIR}/generate.sh
+sed -i 's#^coredns_image_tag=.*#coredns_image_tag=$(if printf "%s\\n%s\\n" v1.21 ${kube_version%.*} | sort --check=quiet --version-sort; then echo -n ${coredns_version};else echo -n ${coredns_version/v/}; fi)#' ${TEMP_DIR}/generate.sh
+
+# add kube-* images to images list
+KUBE_IMAGES="kube-apiserver kube-controller-manager kube-scheduler kube-proxy"
+echo "${KUBE_IMAGES}" | tr ' ' '\n' | xargs -L1 -I {} \
+echo 'echo ${kube_image_repo}/{}:${kube_version}' >> ${TEMP_DIR}/generate.sh
+
+# print files.list and images.list
+bash ${TEMP_DIR}/generate.sh | grep 'https' | sort > ${TEMP_DIR}/files.list
+bash ${TEMP_DIR}/generate.sh | grep -v 'https' | sort > ${TEMP_DIR}/images.list