configure.sh 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643
  1. #!/usr/bin/env bash
  2. # Copyright 2016 The Kubernetes Authors.
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. # Due to the GCE custom metadata size limit, we split the entire script into two
  16. # files configure.sh and configure-helper.sh. The functionality of downloading
  17. # kubernetes configuration, manifests, docker images, and binary files are
  18. # put in configure.sh, which is uploaded via GCE custom metadata.
  19. set -o errexit
  20. set -o nounset
  21. set -o pipefail
  22. ### Hardcoded constants
  23. DEFAULT_CNI_VERSION="v0.8.5"
  24. DEFAULT_CNI_SHA1="677d218b62c0ef941c1d0b606d6570faa5277ffd"
  25. DEFAULT_NPD_VERSION="v0.8.0"
  26. DEFAULT_NPD_SHA1="9406c975b1b035995a137029a004622b905b4e7f"
  27. DEFAULT_CRICTL_VERSION="v1.17.0"
  28. DEFAULT_CRICTL_SHA1="5c18f4e52ab524d429063b78d086dd18b894aae7"
  29. DEFAULT_MOUNTER_TAR_SHA="8003b798cf33c7f91320cd6ee5cec4fa22244571"
  30. ###
  31. # Use --retry-connrefused opt only if it's supported by curl.
  32. CURL_RETRY_CONNREFUSED=""
  33. if curl --help | grep -q -- '--retry-connrefused'; then
  34. CURL_RETRY_CONNREFUSED='--retry-connrefused'
  35. fi
  36. function set-broken-motd {
  37. cat > /etc/motd <<EOF
  38. Broken (or in progress) Kubernetes node setup! Check the cluster initialization status
  39. using the following commands.
  40. Master instance:
  41. - sudo systemctl status kube-master-installation
  42. - sudo systemctl status kube-master-configuration
  43. Node instance:
  44. - sudo systemctl status kube-node-installation
  45. - sudo systemctl status kube-node-configuration
  46. EOF
  47. }
  48. function download-kube-env {
  49. # Fetch kube-env from GCE metadata server.
  50. (
  51. umask 077
  52. local -r tmp_kube_env="/tmp/kube-env.yaml"
  53. curl --fail --retry 5 --retry-delay 3 ${CURL_RETRY_CONNREFUSED} --silent --show-error \
  54. -H "X-Google-Metadata-Request: True" \
  55. -o "${tmp_kube_env}" \
  56. http://metadata.google.internal/computeMetadata/v1/instance/attributes/kube-env
  57. # Convert the yaml format file into a shell-style file.
  58. eval $(${PYTHON} -c '''
  59. import pipes,sys,yaml
  60. # check version of python and call methods appropriate for that version
  61. if sys.version_info[0] < 3:
  62. items = yaml.load(sys.stdin).iteritems()
  63. else:
  64. items = yaml.load(sys.stdin, Loader=yaml.BaseLoader).items()
  65. for k, v in items:
  66. print("readonly {var}={value}".format(var=k, value=pipes.quote(str(v))))
  67. ''' < "${tmp_kube_env}" > "${KUBE_HOME}/kube-env")
  68. rm -f "${tmp_kube_env}"
  69. )
  70. }
  71. function download-kubelet-config {
  72. local -r dest="$1"
  73. echo "Downloading Kubelet config file, if it exists"
  74. # Fetch kubelet config file from GCE metadata server.
  75. (
  76. umask 077
  77. local -r tmp_kubelet_config="/tmp/kubelet-config.yaml"
  78. if curl --fail --retry 5 --retry-delay 3 ${CURL_RETRY_CONNREFUSED} --silent --show-error \
  79. -H "X-Google-Metadata-Request: True" \
  80. -o "${tmp_kubelet_config}" \
  81. http://metadata.google.internal/computeMetadata/v1/instance/attributes/kubelet-config; then
  82. # only write to the final location if curl succeeds
  83. mv "${tmp_kubelet_config}" "${dest}"
  84. elif [[ "${REQUIRE_METADATA_KUBELET_CONFIG_FILE:-false}" == "true" ]]; then
  85. echo "== Failed to download required Kubelet config file from metadata server =="
  86. exit 1
  87. fi
  88. )
  89. }
  90. function download-kube-master-certs {
  91. # Fetch kube-env from GCE metadata server.
  92. (
  93. umask 077
  94. local -r tmp_kube_master_certs="/tmp/kube-master-certs.yaml"
  95. curl --fail --retry 5 --retry-delay 3 ${CURL_RETRY_CONNREFUSED} --silent --show-error \
  96. -H "X-Google-Metadata-Request: True" \
  97. -o "${tmp_kube_master_certs}" \
  98. http://metadata.google.internal/computeMetadata/v1/instance/attributes/kube-master-certs
  99. # Convert the yaml format file into a shell-style file.
  100. eval $(${PYTHON} -c '''
  101. import pipes,sys,yaml
  102. # check version of python and call methods appropriate for that version
  103. if sys.version_info[0] < 3:
  104. items = yaml.load(sys.stdin).iteritems()
  105. else:
  106. items = yaml.load(sys.stdin, Loader=yaml.BaseLoader).items()
  107. for k, v in items:
  108. print("readonly {var}={value}".format(var=k, value=pipes.quote(str(v))))
  109. ''' < "${tmp_kube_master_certs}" > "${KUBE_HOME}/kube-master-certs")
  110. rm -f "${tmp_kube_master_certs}"
  111. )
  112. }
  113. function validate-hash {
  114. local -r file="$1"
  115. local -r expected="$2"
  116. actual=$(sha1sum ${file} | awk '{ print $1 }') || true
  117. if [[ "${actual}" != "${expected}" ]]; then
  118. echo "== ${file} corrupted, sha1 ${actual} doesn't match expected ${expected} =="
  119. return 1
  120. fi
  121. }
  122. # Get default service account credentials of the VM.
  123. GCE_METADATA_INTERNAL="http://metadata.google.internal/computeMetadata/v1/instance"
  124. function get-credentials {
  125. curl --fail --retry 5 --retry-delay 3 ${CURL_RETRY_CONNREFUSED} --silent --show-error "${GCE_METADATA_INTERNAL}/service-accounts/default/token" -H "Metadata-Flavor: Google" -s | ${PYTHON} -c \
  126. 'import sys; import json; print(json.loads(sys.stdin.read())["access_token"])'
  127. }
  128. function valid-storage-scope {
  129. curl --fail --retry 5 --retry-delay 3 ${CURL_RETRY_CONNREFUSED} --silent --show-error "${GCE_METADATA_INTERNAL}/service-accounts/default/scopes" -H "Metadata-Flavor: Google" -s | grep -E "auth/devstorage|auth/cloud-platform"
  130. }
  131. # Retry a download until we get it. Takes a hash and a set of URLs.
  132. #
  133. # $1 is the sha1 of the URL. Can be "" if the sha1 is unknown.
  134. # $2+ are the URLs to download.
  135. function download-or-bust {
  136. local -r hash="$1"
  137. shift 1
  138. local -r urls=( $* )
  139. while true; do
  140. for url in "${urls[@]}"; do
  141. local file="${url##*/}"
  142. rm -f "${file}"
  143. # if the url belongs to GCS API we should use oauth2_token in the headers
  144. local curl_headers=""
  145. if [[ "$url" =~ ^https://storage.googleapis.com.* ]] && valid-storage-scope ; then
  146. curl_headers="Authorization: Bearer $(get-credentials)"
  147. fi
  148. if ! curl ${curl_headers:+-H "${curl_headers}"} -f --ipv4 -Lo "${file}" --connect-timeout 20 --max-time 300 --retry 6 --retry-delay 10 ${CURL_RETRY_CONNREFUSED} "${url}"; then
  149. echo "== Failed to download ${url}. Retrying. =="
  150. elif [[ -n "${hash}" ]] && ! validate-hash "${file}" "${hash}"; then
  151. echo "== Hash validation of ${url} failed. Retrying. =="
  152. else
  153. if [[ -n "${hash}" ]]; then
  154. echo "== Downloaded ${url} (SHA1 = ${hash}) =="
  155. else
  156. echo "== Downloaded ${url} =="
  157. fi
  158. return
  159. fi
  160. done
  161. done
  162. }
  163. function is-preloaded {
  164. local -r key=$1
  165. local -r value=$2
  166. grep -qs "${key},${value}" "${KUBE_HOME}/preload_info"
  167. }
  168. function split-commas {
  169. echo $1 | tr "," "\n"
  170. }
  171. function remount-flexvolume-directory {
  172. local -r flexvolume_plugin_dir=$1
  173. mkdir -p $flexvolume_plugin_dir
  174. mount --bind $flexvolume_plugin_dir $flexvolume_plugin_dir
  175. mount -o remount,exec $flexvolume_plugin_dir
  176. }
  177. function install-gci-mounter-tools {
  178. CONTAINERIZED_MOUNTER_HOME="${KUBE_HOME}/containerized_mounter"
  179. local -r mounter_tar_sha="${DEFAULT_MOUNTER_TAR_SHA}"
  180. if is-preloaded "mounter" "${mounter_tar_sha}"; then
  181. echo "mounter is preloaded."
  182. return
  183. fi
  184. echo "Downloading gci mounter tools."
  185. mkdir -p "${CONTAINERIZED_MOUNTER_HOME}"
  186. chmod a+x "${CONTAINERIZED_MOUNTER_HOME}"
  187. mkdir -p "${CONTAINERIZED_MOUNTER_HOME}/rootfs"
  188. download-or-bust "${mounter_tar_sha}" "https://storage.googleapis.com/kubernetes-release/gci-mounter/mounter.tar"
  189. cp "${KUBE_HOME}/kubernetes/server/bin/mounter" "${CONTAINERIZED_MOUNTER_HOME}/mounter"
  190. chmod a+x "${CONTAINERIZED_MOUNTER_HOME}/mounter"
  191. mv "${KUBE_HOME}/mounter.tar" /tmp/mounter.tar
  192. tar xf /tmp/mounter.tar -C "${CONTAINERIZED_MOUNTER_HOME}/rootfs"
  193. rm /tmp/mounter.tar
  194. mkdir -p "${CONTAINERIZED_MOUNTER_HOME}/rootfs/var/lib/kubelet"
  195. }
  196. # Install node problem detector binary.
  197. function install-node-problem-detector {
  198. if [[ -n "${NODE_PROBLEM_DETECTOR_VERSION:-}" ]]; then
  199. local -r npd_version="${NODE_PROBLEM_DETECTOR_VERSION}"
  200. local -r npd_sha1="${NODE_PROBLEM_DETECTOR_TAR_HASH}"
  201. else
  202. local -r npd_version="${DEFAULT_NPD_VERSION}"
  203. local -r npd_sha1="${DEFAULT_NPD_SHA1}"
  204. fi
  205. local -r npd_tar="node-problem-detector-${npd_version}.tar.gz"
  206. if is-preloaded "${npd_tar}" "${npd_sha1}"; then
  207. echo "${npd_tar} is preloaded."
  208. return
  209. fi
  210. echo "Downloading ${npd_tar}."
  211. local -r npd_release_path="${NODE_PROBLEM_DETECTOR_RELEASE_PATH:-https://storage.googleapis.com/kubernetes-release}"
  212. download-or-bust "${npd_sha1}" "${npd_release_path}/node-problem-detector/${npd_tar}"
  213. local -r npd_dir="${KUBE_HOME}/node-problem-detector"
  214. mkdir -p "${npd_dir}"
  215. tar xzf "${KUBE_HOME}/${npd_tar}" -C "${npd_dir}" --overwrite
  216. mv "${npd_dir}/bin"/* "${KUBE_BIN}"
  217. chmod a+x "${KUBE_BIN}/node-problem-detector"
  218. rmdir "${npd_dir}/bin"
  219. rm -f "${KUBE_HOME}/${npd_tar}"
  220. }
  221. function install-cni-binaries {
  222. if [[ -n "${CNI_VERSION:-}" ]]; then
  223. local -r cni_version="${CNI_VERSION}"
  224. local -r cni_sha1="${CNI_SHA1}"
  225. else
  226. local -r cni_version="${DEFAULT_CNI_VERSION}"
  227. local -r cni_sha1="${DEFAULT_CNI_SHA1}"
  228. fi
  229. local -r cni_tar="${CNI_TAR_PREFIX}${cni_version}.tgz"
  230. local -r cni_url="${CNI_STORAGE_URL_BASE}/${cni_version}/${cni_tar}"
  231. if is-preloaded "${cni_tar}" "${cni_sha1}"; then
  232. echo "${cni_tar} is preloaded."
  233. return
  234. fi
  235. echo "Downloading cni binaries"
  236. download-or-bust "${cni_sha1}" "${cni_url}"
  237. local -r cni_dir="${KUBE_HOME}/cni"
  238. mkdir -p "${cni_dir}/bin"
  239. tar xzf "${KUBE_HOME}/${cni_tar}" -C "${cni_dir}/bin" --overwrite
  240. mv "${cni_dir}/bin"/* "${KUBE_BIN}"
  241. rmdir "${cni_dir}/bin"
  242. rm -f "${KUBE_HOME}/${cni_tar}"
  243. }
  244. # Install crictl binary.
  245. function install-crictl {
  246. if [[ -n "${CRICTL_VERSION:-}" ]]; then
  247. local -r crictl_version="${CRICTL_VERSION}"
  248. local -r crictl_sha1="${CRICTL_TAR_HASH}"
  249. else
  250. local -r crictl_version="${DEFAULT_CRICTL_VERSION}"
  251. local -r crictl_sha1="${DEFAULT_CRICTL_SHA1}"
  252. fi
  253. local -r crictl="crictl-${crictl_version}-linux-amd64"
  254. # Create crictl config file.
  255. cat > /etc/crictl.yaml <<EOF
  256. runtime-endpoint: ${CONTAINER_RUNTIME_ENDPOINT:-unix:///var/run/dockershim.sock}
  257. EOF
  258. if is-preloaded "${crictl}" "${crictl_sha1}"; then
  259. echo "crictl is preloaded"
  260. return
  261. fi
  262. echo "Downloading crictl"
  263. local -r crictl_path="https://storage.googleapis.com/kubernetes-release/crictl"
  264. download-or-bust "${crictl_sha1}" "${crictl_path}/${crictl}"
  265. mv "${KUBE_HOME}/${crictl}" "${KUBE_BIN}/crictl"
  266. chmod a+x "${KUBE_BIN}/crictl"
  267. }
  268. function install-exec-auth-plugin {
  269. if [[ ! "${EXEC_AUTH_PLUGIN_URL:-}" ]]; then
  270. return
  271. fi
  272. local -r plugin_url="${EXEC_AUTH_PLUGIN_URL}"
  273. local -r plugin_sha1="${EXEC_AUTH_PLUGIN_SHA1}"
  274. if is-preloaded "gke-exec-auth-plugin" "${plugin_sha1}"; then
  275. echo "gke-exec-auth-plugin is preloaded"
  276. return
  277. fi
  278. echo "Downloading gke-exec-auth-plugin binary"
  279. download-or-bust "${plugin_sha1}" "${plugin_url}"
  280. mv "${KUBE_HOME}/gke-exec-auth-plugin" "${KUBE_BIN}/gke-exec-auth-plugin"
  281. chmod a+x "${KUBE_BIN}/gke-exec-auth-plugin"
  282. if [[ ! "${EXEC_AUTH_PLUGIN_LICENSE_URL:-}" ]]; then
  283. return
  284. fi
  285. local -r license_url="${EXEC_AUTH_PLUGIN_LICENSE_URL}"
  286. echo "Downloading gke-exec-auth-plugin license"
  287. download-or-bust "" "${license_url}"
  288. mv "${KUBE_HOME}/LICENSE" "${KUBE_BIN}/gke-exec-auth-plugin-license"
  289. }
  290. function install-kube-manifests {
  291. # Put kube-system pods manifests in ${KUBE_HOME}/kube-manifests/.
  292. local dst_dir="${KUBE_HOME}/kube-manifests"
  293. mkdir -p "${dst_dir}"
  294. local -r manifests_tar_urls=( $(split-commas "${KUBE_MANIFESTS_TAR_URL}") )
  295. local -r manifests_tar="${manifests_tar_urls[0]##*/}"
  296. if [ -n "${KUBE_MANIFESTS_TAR_HASH:-}" ]; then
  297. local -r manifests_tar_hash="${KUBE_MANIFESTS_TAR_HASH}"
  298. else
  299. echo "Downloading k8s manifests sha1 (not found in env)"
  300. download-or-bust "" "${manifests_tar_urls[@]/.tar.gz/.tar.gz.sha1}"
  301. local -r manifests_tar_hash=$(cat "${manifests_tar}.sha1")
  302. fi
  303. if is-preloaded "${manifests_tar}" "${manifests_tar_hash}"; then
  304. echo "${manifests_tar} is preloaded."
  305. return
  306. fi
  307. echo "Downloading k8s manifests tar"
  308. download-or-bust "${manifests_tar_hash}" "${manifests_tar_urls[@]}"
  309. tar xzf "${KUBE_HOME}/${manifests_tar}" -C "${dst_dir}" --overwrite
  310. local -r kube_addon_registry="${KUBE_ADDON_REGISTRY:-k8s.gcr.io}"
  311. if [[ "${kube_addon_registry}" != "k8s.gcr.io" ]]; then
  312. find "${dst_dir}" -name \*.yaml -or -name \*.yaml.in | \
  313. xargs sed -ri "s@(image:\s.*)k8s.gcr.io@\1${kube_addon_registry}@"
  314. find "${dst_dir}" -name \*.manifest -or -name \*.json | \
  315. xargs sed -ri "s@(image\":\s+\")k8s.gcr.io@\1${kube_addon_registry}@"
  316. fi
  317. cp "${dst_dir}/kubernetes/gci-trusty/gci-configure-helper.sh" "${KUBE_BIN}/configure-helper.sh"
  318. cp "${dst_dir}/kubernetes/gci-trusty/configure-kubeapiserver.sh" "${KUBE_BIN}/configure-kubeapiserver.sh"
  319. if [[ -e "${dst_dir}/kubernetes/gci-trusty/gke-internal-configure-helper.sh" ]]; then
  320. cp "${dst_dir}/kubernetes/gci-trusty/gke-internal-configure-helper.sh" "${KUBE_BIN}/"
  321. fi
  322. cp "${dst_dir}/kubernetes/gci-trusty/health-monitor.sh" "${KUBE_BIN}/health-monitor.sh"
  323. rm -f "${KUBE_HOME}/${manifests_tar}"
  324. rm -f "${KUBE_HOME}/${manifests_tar}.sha1"
  325. }
  326. # A helper function for loading a docker image. It keeps trying up to 5 times.
  327. #
  328. # $1: Full path of the docker image
  329. function try-load-docker-image {
  330. local -r img=$1
  331. echo "Try to load docker image file ${img}"
  332. # Temporarily turn off errexit, because we don't want to exit on first failure.
  333. set +e
  334. local -r max_attempts=5
  335. local -i attempt_num=1
  336. until timeout 30 ${LOAD_IMAGE_COMMAND:-docker load -i} "${img}"; do
  337. if [[ "${attempt_num}" == "${max_attempts}" ]]; then
  338. echo "Fail to load docker image file ${img} after ${max_attempts} retries. Exit!!"
  339. exit 1
  340. else
  341. attempt_num=$((attempt_num+1))
  342. sleep 5
  343. fi
  344. done
  345. # Re-enable errexit.
  346. set -e
  347. }
  348. # Loads kube-system docker images. It is better to do it before starting kubelet,
  349. # as kubelet will restart docker daemon, which may interfere with loading images.
  350. function load-docker-images {
  351. echo "Start loading kube-system docker images"
  352. local -r img_dir="${KUBE_HOME}/kube-docker-files"
  353. if [[ "${KUBERNETES_MASTER:-}" == "true" ]]; then
  354. try-load-docker-image "${img_dir}/kube-apiserver.tar"
  355. try-load-docker-image "${img_dir}/kube-controller-manager.tar"
  356. try-load-docker-image "${img_dir}/kube-scheduler.tar"
  357. else
  358. try-load-docker-image "${img_dir}/kube-proxy.tar"
  359. fi
  360. }
  361. # If we are on ubuntu we can try to install docker
  362. function install-docker {
  363. # bailout if we are not on ubuntu
  364. if ! command -v apt-get >/dev/null 2>&1; then
  365. echo "Unable to automatically install docker. Bailing out..."
  366. return
  367. fi
  368. # Install Docker deps, some of these are already installed in the image but
  369. # that's fine since they won't re-install and we can reuse the code below
  370. # for another image someday.
  371. apt-get update
  372. apt-get install -y --no-install-recommends \
  373. apt-transport-https \
  374. ca-certificates \
  375. socat \
  376. curl \
  377. gnupg2 \
  378. software-properties-common \
  379. lsb-release
  380. # Add the Docker apt-repository
  381. curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg \
  382. | apt-key add -
  383. add-apt-repository \
  384. "deb [arch=amd64] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") \
  385. $(lsb_release -cs) stable"
  386. # Install Docker
  387. apt-get update && \
  388. apt-get install -y --no-install-recommends ${GCI_DOCKER_VERSION:-"docker-ce=5:19.03.*"}
  389. rm -rf /var/lib/apt/lists/*
  390. }
  391. # If we are on ubuntu we can try to install containerd
  392. function install-containerd-ubuntu {
  393. # bailout if we are not on ubuntu
  394. if [[ -z "$(command -v lsb_release)" || $(lsb_release -si) != "Ubuntu" ]]; then
  395. echo "Unable to automatically install containerd in non-ubuntu image. Bailing out..."
  396. exit 2
  397. fi
  398. if [[ $(dpkg --print-architecture) != "amd64" ]]; then
  399. echo "Unable to automatically install containerd in non-amd64 image. Bailing out..."
  400. exit 2
  401. fi
  402. # Install dependencies, some of these are already installed in the image but
  403. # that's fine since they won't re-install and we can reuse the code below
  404. # for another image someday.
  405. apt-get update
  406. apt-get install -y --no-install-recommends \
  407. apt-transport-https \
  408. ca-certificates \
  409. socat \
  410. curl \
  411. gnupg2 \
  412. software-properties-common \
  413. lsb-release
  414. # Add the Docker apt-repository (as we install containerd from there)
  415. curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg \
  416. | apt-key add -
  417. add-apt-repository \
  418. "deb [arch=amd64] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") \
  419. $(lsb_release -cs) stable"
  420. # Install containerd from Docker repo
  421. apt-get update && \
  422. apt-get install -y --no-install-recommends containerd
  423. rm -rf /var/lib/apt/lists/*
  424. # Override to latest versions of containerd and runc
  425. systemctl stop containerd
  426. if [[ ! -z "${UBUNTU_INSTALL_CONTAINERD_VERSION:-}" ]]; then
  427. curl -fsSL "https://github.com/containerd/containerd/releases/download/${UBUNTU_INSTALL_CONTAINERD_VERSION}/containerd-${UBUNTU_INSTALL_CONTAINERD_VERSION:1}.linux-amd64.tar.gz" | tar --overwrite -xzv -C /usr/
  428. fi
  429. if [[ ! -z "${UBUNTU_INSTALL_RUNC_VERSION:-}" ]]; then
  430. curl -fsSL "https://github.com/opencontainers/runc/releases/download/${UBUNTU_INSTALL_RUNC_VERSION}/runc.amd64" --output /usr/sbin/runc && chmod 755 /usr/sbin/runc
  431. fi
  432. sudo systemctl start containerd
  433. }
  434. function ensure-container-runtime {
  435. container_runtime="${CONTAINER_RUNTIME:-docker}"
  436. if [[ "${container_runtime}" == "docker" ]]; then
  437. if ! command -v docker >/dev/null 2>&1; then
  438. install-docker
  439. if ! command -v docker >/dev/null 2>&1; then
  440. echo "ERROR docker not found. Aborting."
  441. exit 2
  442. fi
  443. fi
  444. docker version
  445. elif [[ "${container_runtime}" == "containerd" ]]; then
  446. # Install containerd/runc if requested
  447. if [[ ! -z "${UBUNTU_INSTALL_CONTAINERD_VERSION:-}" || ! -z "${UBUNTU_INSTALL_RUNC_VERSION}" ]]; then
  448. install-containerd-ubuntu
  449. fi
  450. # Verify presence and print versions of ctr, containerd, runc
  451. if ! command -v ctr >/dev/null 2>&1; then
  452. echo "ERROR ctr not found. Aborting."
  453. exit 2
  454. fi
  455. ctr --version
  456. if ! command -v containerd >/dev/null 2>&1; then
  457. echo "ERROR containerd not found. Aborting."
  458. exit 2
  459. fi
  460. containerd --version
  461. if ! command -v runc >/dev/null 2>&1; then
  462. echo "ERROR runc not found. Aborting."
  463. exit 2
  464. fi
  465. runc --version
  466. fi
  467. }
  468. # Downloads kubernetes binaries and kube-system manifest tarball, unpacks them,
  469. # and places them into suitable directories. Files are placed in /home/kubernetes.
  470. function install-kube-binary-config {
  471. cd "${KUBE_HOME}"
  472. local -r server_binary_tar_urls=( $(split-commas "${SERVER_BINARY_TAR_URL}") )
  473. local -r server_binary_tar="${server_binary_tar_urls[0]##*/}"
  474. if [[ -n "${SERVER_BINARY_TAR_HASH:-}" ]]; then
  475. local -r server_binary_tar_hash="${SERVER_BINARY_TAR_HASH}"
  476. else
  477. echo "Downloading binary release sha1 (not found in env)"
  478. download-or-bust "" "${server_binary_tar_urls[@]/.tar.gz/.tar.gz.sha1}"
  479. local -r server_binary_tar_hash=$(cat "${server_binary_tar}.sha1")
  480. fi
  481. if is-preloaded "${server_binary_tar}" "${server_binary_tar_hash}"; then
  482. echo "${server_binary_tar} is preloaded."
  483. else
  484. echo "Downloading binary release tar"
  485. download-or-bust "${server_binary_tar_hash}" "${server_binary_tar_urls[@]}"
  486. tar xzf "${KUBE_HOME}/${server_binary_tar}" -C "${KUBE_HOME}" --overwrite
  487. # Copy docker_tag and image files to ${KUBE_HOME}/kube-docker-files.
  488. local -r src_dir="${KUBE_HOME}/kubernetes/server/bin"
  489. local dst_dir="${KUBE_HOME}/kube-docker-files"
  490. mkdir -p "${dst_dir}"
  491. cp "${src_dir}/"*.docker_tag "${dst_dir}"
  492. if [[ "${KUBERNETES_MASTER:-}" == "false" ]]; then
  493. cp "${src_dir}/kube-proxy.tar" "${dst_dir}"
  494. else
  495. cp "${src_dir}/kube-apiserver.tar" "${dst_dir}"
  496. cp "${src_dir}/kube-controller-manager.tar" "${dst_dir}"
  497. cp "${src_dir}/kube-scheduler.tar" "${dst_dir}"
  498. cp -r "${KUBE_HOME}/kubernetes/addons" "${dst_dir}"
  499. fi
  500. load-docker-images
  501. mv "${src_dir}/kubelet" "${KUBE_BIN}"
  502. mv "${src_dir}/kubectl" "${KUBE_BIN}"
  503. mv "${KUBE_HOME}/kubernetes/LICENSES" "${KUBE_HOME}"
  504. mv "${KUBE_HOME}/kubernetes/kubernetes-src.tar.gz" "${KUBE_HOME}"
  505. fi
  506. if [[ "${KUBERNETES_MASTER:-}" == "false" ]] && \
  507. [[ "${ENABLE_NODE_PROBLEM_DETECTOR:-}" == "standalone" ]]; then
  508. install-node-problem-detector
  509. fi
  510. if [[ "${NETWORK_PROVIDER:-}" == "kubenet" ]] || \
  511. [[ "${NETWORK_PROVIDER:-}" == "cni" ]]; then
  512. install-cni-binaries
  513. fi
  514. # Put kube-system pods manifests in ${KUBE_HOME}/kube-manifests/.
  515. install-kube-manifests
  516. chmod -R 755 "${KUBE_BIN}"
  517. # Install gci mounter related artifacts to allow mounting storage volumes in GCI
  518. install-gci-mounter-tools
  519. # Remount the Flexvolume directory with the "exec" option, if needed.
  520. if [[ "${REMOUNT_VOLUME_PLUGIN_DIR:-}" == "true" && -n "${VOLUME_PLUGIN_DIR:-}" ]]; then
  521. remount-flexvolume-directory "${VOLUME_PLUGIN_DIR}"
  522. fi
  523. # Install crictl on each node.
  524. install-crictl
  525. # TODO(awly): include the binary and license in the OS image.
  526. install-exec-auth-plugin
  527. # Clean up.
  528. rm -rf "${KUBE_HOME}/kubernetes"
  529. rm -f "${KUBE_HOME}/${server_binary_tar}"
  530. rm -f "${KUBE_HOME}/${server_binary_tar}.sha1"
  531. }
  532. ######### Main Function ##########
  533. echo "Start to install kubernetes files"
  534. # if install fails, message-of-the-day (motd) will warn at login shell
  535. set-broken-motd
  536. KUBE_HOME="/home/kubernetes"
  537. KUBE_BIN="${KUBE_HOME}/bin"
  538. PYTHON="python"
  539. if [[ "$(python -V 2>&1)" =~ "Python 2" ]]; then
  540. # found python2, just use that
  541. PYTHON="python"
  542. elif [[ -f "/usr/bin/python2.7" ]]; then
  543. # System python not defaulted to python 2 but using 2.7 during migration
  544. PYTHON="/usr/bin/python2.7"
  545. else
  546. # No python2 either by default, let's see if we can find python3
  547. PYTHON="python3"
  548. if ! command -v ${PYTHON} >/dev/null 2>&1; then
  549. echo "ERROR Python not found. Aborting."
  550. exit 2
  551. fi
  552. fi
  553. echo "Version : " $(${PYTHON} -V 2>&1)
  554. # download and source kube-env
  555. download-kube-env
  556. source "${KUBE_HOME}/kube-env"
  557. download-kubelet-config "${KUBE_HOME}/kubelet-config.yaml"
  558. # master certs
  559. if [[ "${KUBERNETES_MASTER:-}" == "true" ]]; then
  560. download-kube-master-certs
  561. fi
  562. # ensure chosen container runtime is present
  563. ensure-container-runtime
  564. # binaries and kube-system manifests
  565. install-kube-binary-config
  566. echo "Done for installing kubernetes files"