...
1#!/usr/bin/env bash
2
3# Copyright 2014 The Kubernetes Authors.
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17# Bring up a Kubernetes cluster.
18# Usage:
19# wget -q -O - https://get.k8s.io | bash
20# or
21# curl -fsSL https://get.k8s.io | bash
22#
23# Advanced options
24# Set KUBERNETES_PROVIDER to choose between different providers:
25# Google Compute Engine [default]
26# * export KUBERNETES_PROVIDER=gce; wget -q -O - https://get.k8s.io | bash
27#
28# Set KUBERNETES_RELEASE to choose a specific release instead of the current
29# stable release, (e.g. 'v1.3.7').
30# See https://github.com/kubernetes/kubernetes/releases for release options.
31# Set KUBERNETES_RELEASE_URL to choose where to download binaries from.
32# (Defaults to https://dl.k8s.io/release).
33#
34# Set KUBERNETES_SERVER_ARCH to choose the server (Kubernetes cluster)
35# architecture to download:
36# * amd64 [default]
37# * arm
38# * arm64
39# * ppc64le
40#
41# Set KUBERNETES_NODE_PLATFORM to choose the platform for which to download
42# the node binaries. If none of KUBERNETES_NODE_PLATFORM and
43# KUBERNETES_NODE_ARCH is set, no node binaries will be downloaded. If only
44# one of the two is set, the other will be defaulted to the
45# KUBERNETES_SERVER_PLATFORM/ARCH.
46# * linux
47# * windows
48#
49# Set KUBERNETES_NODE_ARCH to choose the node architecture to download the
50# node binaries. If none of KUBERNETES_NODE_PLATFORM and
51# KUBERNETES_NODE_ARCH is set, no node binaries will be downloaded. If only
52# one of the two is set, the other will be defaulted to the
53# KUBERNETES_SERVER_PLATFORM/ARCH.
54# * amd64 [default]
55# * arm
56# * arm64
57# * ppc64le
58#
59# Set KUBERNETES_SKIP_DOWNLOAD to skip downloading a release.
60# Set KUBERNETES_SKIP_CONFIRM to skip the installation confirmation prompt.
61# Set KUBERNETES_SKIP_CREATE_CLUSTER to skip starting a cluster.
62# Set KUBERNETES_SKIP_RELEASE_VALIDATION to skip trying to validate the
63# Kubernetes release string. This implies that you know what you're doing
64# and have set KUBERNETES_RELEASE and KUBERNETES_RELEASE_URL properly.
65
66set -o errexit
67set -o nounset
68set -o pipefail
69
70# If KUBERNETES_RELEASE_URL is overridden but KUBERNETES_CI_RELEASE_URL is not then set KUBERNETES_CI_RELEASE_URL to KUBERNETES_RELEASE_URL.
71KUBERNETES_CI_RELEASE_URL="${KUBERNETES_CI_RELEASE_URL:-${KUBERNETES_RELEASE_URL:-https://dl.k8s.io/ci}}"
72KUBERNETES_RELEASE_URL="${KUBERNETES_RELEASE_URL:-https://dl.k8s.io}"
73
74KUBE_RELEASE_VERSION_REGEX="^v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(-([a-zA-Z0-9]+)\\.(0|[1-9][0-9]*))?$"
75# v1 .26 .0 -(rc .0 .)?0 ( +014f )?
76KUBE_CI_VERSION_REGEX="^v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)-([a-zA-Z0-9]+\\.(0|[1-9][0-9]*)\\.)?(0|[1-9][0-9]*)(\\+[-0-9a-z]*)?$"
77
78# Sets KUBE_VERSION variable if an explicit version number was provided (e.g. "v1.0.6",
79# "v1.2.0-alpha.1.881+376438b69c7612", or "v1.2.0-881+376438b69c7612") or resolves the "published" version
80# <path>/<version> (e.g. "release/stable",' "ci/latest-1") by reading from GCS.
81#
82# See the docs on getting builds for more information about version
83# publication.
84#
85# Args:
86# $1 version string from command line
87# Vars set:
88# KUBE_VERSION
89function set_binary_version() {
90 if [[ "${1}" =~ "/" ]]; then
91 KUBE_VERSION=$(curl -fsSL --retry 5 "https://dl.k8s.io/${1}.txt")
92 else
93 KUBE_VERSION=${1}
94 fi
95 export KUBE_VERSION
96}
97
98# Use the script from inside the Kubernetes tarball to fetch the client and
99# server binaries (if not included in kubernetes.tar.gz).
100function download_kube_binaries {
101 (
102 cd kubernetes
103 if [[ -x ./cluster/get-kube-binaries.sh ]]; then
104 # Make sure to use the same download URL in get-kube-binaries.sh
105 KUBERNETES_RELEASE_URL="${KUBERNETES_RELEASE_URL}" \
106 ./cluster/get-kube-binaries.sh
107 fi
108 )
109}
110
111function create_cluster {
112 if [[ -n "${KUBERNETES_SKIP_CREATE_CLUSTER-}" ]]; then
113 exit 0
114 fi
115 echo "Creating a kubernetes on ${KUBERNETES_PROVIDER:-gce}..."
116 (
117 cd kubernetes
118 ./cluster/kube-up.sh
119 echo "Kubernetes binaries at ${PWD}/cluster/"
120 if [[ ":$PATH:" != *":${PWD}/cluster:"* ]]; then
121 echo "You may want to add this directory to your PATH in \$HOME/.profile"
122 fi
123
124 echo "Installation successful!"
125 )
126}
127
128function valid-storage-scope {
129 curl "${GCE_METADATA_INTERNAL}/service-accounts/default/scopes" -H "Metadata-Flavor: Google" -s | grep -E "auth/devstorage|auth/cloud-platform"
130}
131
132if [[ -n "${KUBERNETES_SKIP_DOWNLOAD-}" ]]; then
133 create_cluster
134 exit 0
135fi
136
137if [[ -d "./kubernetes" ]]; then
138 if [[ -z "${KUBERNETES_SKIP_CONFIRM-}" ]]; then
139 echo "'kubernetes' directory already exists. Should we skip download step and start to create cluster based on it? [Y]/n"
140 read -r confirm
141 if [[ ! "${confirm}" =~ ^[nN]$ ]]; then
142 echo "Skipping download step."
143 create_cluster
144 exit 0
145 fi
146 fi
147fi
148
149# TODO: remove client checks once kubernetes.tar.gz no longer includes client
150# binaries by default.
151kernel=$(uname -s)
152case "${kernel}" in
153 Darwin)
154 ;;
155 Linux)
156 ;;
157 *)
158 echo "Unknown, unsupported platform: ${kernel}." >&2
159 echo "Supported platforms: Linux, Darwin." >&2
160 echo "Bailing out." >&2
161 exit 2
162esac
163
164machine=$(uname -m)
165case "${machine}" in
166 x86_64*|i?86_64*|amd64*)
167 ;;
168 aarch64*|arm64*)
169 ;;
170 ppc64le*)
171 ;;
172 arm*)
173 ;;
174 i?86*)
175 ;;
176 *)
177 echo "Unknown, unsupported architecture (${machine})." >&2
178 echo "Supported architectures x86_64, i686, arm, arm64, ppc64le." >&2
179 echo "Bailing out." >&2
180 exit 3
181 ;;
182esac
183
184file=kubernetes.tar.gz
185release=${KUBERNETES_RELEASE:-"release/stable"}
186
187# Validate Kubernetes release version.
188# Translate a published version <bucket>/<version> (e.g. "release/stable") to version number.
189set_binary_version "${release}"
190if [[ -z "${KUBERNETES_SKIP_RELEASE_VALIDATION-}" ]]; then
191 if [[ ${KUBE_VERSION} =~ ${KUBE_RELEASE_VERSION_REGEX} ]]; then
192 # Use KUBERNETES_RELEASE_URL for Releases and Pre-Releases
193 # ie. 1.18.0 or 1.19.0-beta.0
194 # shellcheck disable=SC2269 # this line is a noop but it helps with reading
195 KUBERNETES_RELEASE_URL="${KUBERNETES_RELEASE_URL}"
196 elif [[ ${KUBE_VERSION} =~ ${KUBE_CI_VERSION_REGEX} ]]; then
197 # Override KUBERNETES_RELEASE_URL to point to the CI bucket;
198 # this will be used by get-kube-binaries.sh.
199 # ie. v1.19.0-beta.0.318+b618411f1edb98 and v1.19.0-318+b618411f1edb98
200 KUBERNETES_RELEASE_URL="${KUBERNETES_CI_RELEASE_URL}"
201 else
202 echo "Version doesn't match regexp" >&2
203 exit 1
204 fi
205fi
206kubernetes_tar_url="${KUBERNETES_RELEASE_URL}/${KUBE_VERSION}/${file}"
207
208need_download=true
209if [[ -r "${PWD}/${file}" ]]; then
210 downloaded_version=$(tar -xzOf "${PWD}/${file}" kubernetes/version 2>/dev/null || true)
211 echo "Found preexisting ${file}, release ${downloaded_version}"
212 if [[ "${downloaded_version}" == "${KUBE_VERSION}" ]]; then
213 echo "Using preexisting kubernetes.tar.gz"
214 need_download=false
215 fi
216fi
217
218if "${need_download}"; then
219 echo "Downloading kubernetes release ${KUBE_VERSION}"
220 echo " from ${kubernetes_tar_url}"
221 echo " to ${PWD}/${file}"
222fi
223
224if [[ -e "${PWD}/kubernetes" ]]; then
225 # Let's try not to accidentally nuke something that isn't a kubernetes
226 # release dir.
227 if [[ ! -f "${PWD}/kubernetes/version" ]]; then
228 echo "${PWD}/kubernetes exists but does not look like a Kubernetes release."
229 echo "Aborting!"
230 exit 5
231 fi
232 echo "Will also delete preexisting 'kubernetes' directory."
233fi
234
235if [[ -z "${KUBERNETES_SKIP_CONFIRM-}" ]]; then
236 echo "Is this ok? [Y]/n"
237 read -r confirm
238 if [[ "${confirm}" =~ ^[nN]$ ]]; then
239 echo "Aborting."
240 exit 0
241 fi
242fi
243
244if "${need_download}"; then
245 if [[ $(which gsutil) ]] && [[ "$kubernetes_tar_url" =~ ^https://storage.googleapis.com/.* ]]; then
246 gsutil cp "${kubernetes_tar_url//'https://storage.googleapis.com/'/gs://}" "${file}"
247 elif [[ $(which curl) ]]; then
248 # if the url belongs to GCS API we should use oauth2_token in the headers
249 curl_headers=""
250 if { [[ "${KUBERNETES_PROVIDER:-gce}" == "gce" ]] || [[ "${KUBERNETES_PROVIDER}" == "gke" ]] ; } &&
251 [[ "$kubernetes_tar_url" =~ ^https://storage.googleapis.com.* ]] ; then
252 curl_headers="Authorization: Bearer $(gcloud auth print-access-token)"
253 fi
254 curl ${curl_headers:+-H "${curl_headers}"} -fL --retry 3 --keepalive-time 2 "${kubernetes_tar_url}" -o "${file}"
255 elif [[ $(which wget) ]]; then
256 wget "${kubernetes_tar_url}"
257 else
258 echo "Couldn't find gsutil, curl, or wget. Bailing out."
259 exit 1
260 fi
261fi
262
263echo "Unpacking kubernetes release ${KUBE_VERSION}"
264rm -rf "${PWD}/kubernetes"
265tar -xzf ${file}
266
267download_kube_binaries
268create_cluster
View as plain text