local-up-cluster.sh 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061
  1. #!/usr/bin/env bash
  2. # Copyright 2014 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. KUBE_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
  16. # This command builds and runs a local kubernetes cluster.
  17. # You may need to run this as root to allow kubelet to open docker's socket,
  18. # and to write the test CA in /var/run/kubernetes.
  19. DOCKER_OPTS=${DOCKER_OPTS:-""}
  20. export DOCKER=(docker "${DOCKER_OPTS[@]}")
  21. DOCKER_ROOT=${DOCKER_ROOT:-""}
  22. ALLOW_PRIVILEGED=${ALLOW_PRIVILEGED:-""}
  23. DENY_SECURITY_CONTEXT_ADMISSION=${DENY_SECURITY_CONTEXT_ADMISSION:-""}
  24. PSP_ADMISSION=${PSP_ADMISSION:-""}
  25. NODE_ADMISSION=${NODE_ADMISSION:-""}
  26. RUNTIME_CONFIG=${RUNTIME_CONFIG:-""}
  27. KUBELET_AUTHORIZATION_WEBHOOK=${KUBELET_AUTHORIZATION_WEBHOOK:-""}
  28. KUBELET_AUTHENTICATION_WEBHOOK=${KUBELET_AUTHENTICATION_WEBHOOK:-""}
  29. POD_MANIFEST_PATH=${POD_MANIFEST_PATH:-"/var/run/kubernetes/static-pods"}
  30. KUBELET_FLAGS=${KUBELET_FLAGS:-""}
  31. KUBELET_IMAGE=${KUBELET_IMAGE:-""}
  32. # many dev environments run with swap on, so we don't fail in this env
  33. FAIL_SWAP_ON=${FAIL_SWAP_ON:-"false"}
  34. # Name of the network plugin, eg: "kubenet"
  35. NET_PLUGIN=${NET_PLUGIN:-""}
  36. # Place the config files and binaries required by NET_PLUGIN in these directory,
  37. # eg: "/etc/cni/net.d" for config files, and "/opt/cni/bin" for binaries.
  38. CNI_CONF_DIR=${CNI_CONF_DIR:-""}
  39. CNI_BIN_DIR=${CNI_BIN_DIR:-""}
  40. SERVICE_CLUSTER_IP_RANGE=${SERVICE_CLUSTER_IP_RANGE:-10.0.0.0/24}
  41. FIRST_SERVICE_CLUSTER_IP=${FIRST_SERVICE_CLUSTER_IP:-10.0.0.1}
  42. # if enabled, must set CGROUP_ROOT
  43. CGROUPS_PER_QOS=${CGROUPS_PER_QOS:-true}
  44. # name of the cgroup driver, i.e. cgroupfs or systemd
  45. CGROUP_DRIVER=${CGROUP_DRIVER:-""}
  46. # if cgroups per qos is enabled, optionally change cgroup root
  47. CGROUP_ROOT=${CGROUP_ROOT:-""}
  48. # owner of client certs, default to current user if not specified
  49. USER=${USER:-$(whoami)}
  50. # enables testing eviction scenarios locally.
  51. EVICTION_HARD=${EVICTION_HARD:-"memory.available<100Mi,nodefs.available<10%,nodefs.inodesFree<5%"}
  52. EVICTION_SOFT=${EVICTION_SOFT:-""}
  53. EVICTION_PRESSURE_TRANSITION_PERIOD=${EVICTION_PRESSURE_TRANSITION_PERIOD:-"1m"}
  54. # This script uses docker0 (or whatever container bridge docker is currently using)
  55. # and we don't know the IP of the DNS pod to pass in as --cluster-dns.
  56. # To set this up by hand, set this flag and change DNS_SERVER_IP.
  57. # Note also that you need API_HOST (defined above) for correct DNS.
  58. KUBE_PROXY_MODE=${KUBE_PROXY_MODE:-""}
  59. ENABLE_CLUSTER_DNS=${KUBE_ENABLE_CLUSTER_DNS:-true}
  60. ENABLE_NODELOCAL_DNS=${KUBE_ENABLE_NODELOCAL_DNS:-false}
  61. DNS_SERVER_IP=${KUBE_DNS_SERVER_IP:-10.0.0.10}
  62. LOCAL_DNS_IP=${KUBE_LOCAL_DNS_IP:-169.254.20.10}
  63. DNS_MEMORY_LIMIT=${KUBE_DNS_MEMORY_LIMIT:-170Mi}
  64. DNS_DOMAIN=${KUBE_DNS_NAME:-"cluster.local"}
  65. KUBECTL=${KUBECTL:-"${KUBE_ROOT}/cluster/kubectl.sh"}
  66. WAIT_FOR_URL_API_SERVER=${WAIT_FOR_URL_API_SERVER:-60}
  67. MAX_TIME_FOR_URL_API_SERVER=${MAX_TIME_FOR_URL_API_SERVER:-1}
  68. ENABLE_DAEMON=${ENABLE_DAEMON:-false}
  69. HOSTNAME_OVERRIDE=${HOSTNAME_OVERRIDE:-"127.0.0.1"}
  70. EXTERNAL_CLOUD_PROVIDER=${EXTERNAL_CLOUD_PROVIDER:-false}
  71. EXTERNAL_CLOUD_PROVIDER_BINARY=${EXTERNAL_CLOUD_PROVIDER_BINARY:-""}
  72. CLOUD_PROVIDER=${CLOUD_PROVIDER:-""}
  73. CLOUD_CONFIG=${CLOUD_CONFIG:-""}
  74. FEATURE_GATES=${FEATURE_GATES:-"AllAlpha=false"}
  75. STORAGE_BACKEND=${STORAGE_BACKEND:-"etcd3"}
  76. STORAGE_MEDIA_TYPE=${STORAGE_MEDIA_TYPE:-""}
  77. # preserve etcd data. you also need to set ETCD_DIR.
  78. PRESERVE_ETCD="${PRESERVE_ETCD:-false}"
  79. # enable Pod priority and preemption
  80. ENABLE_POD_PRIORITY_PREEMPTION=${ENABLE_POD_PRIORITY_PREEMPTION:-""}
  81. # enable kubernetes dashboard
  82. ENABLE_CLUSTER_DASHBOARD=${KUBE_ENABLE_CLUSTER_DASHBOARD:-false}
  83. # RBAC Mode options
  84. AUTHORIZATION_MODE=${AUTHORIZATION_MODE:-"Node,RBAC"}
  85. KUBECONFIG_TOKEN=${KUBECONFIG_TOKEN:-""}
  86. AUTH_ARGS=${AUTH_ARGS:-""}
  87. # Install a default storage class (enabled by default)
  88. DEFAULT_STORAGE_CLASS=${KUBE_DEFAULT_STORAGE_CLASS:-true}
  89. # Do not run the mutation detector by default on a local cluster.
  90. # It is intended for a specific type of testing and inherently leaks memory.
  91. KUBE_CACHE_MUTATION_DETECTOR="${KUBE_CACHE_MUTATION_DETECTOR:-false}"
  92. export KUBE_CACHE_MUTATION_DETECTOR
  93. # panic the server on watch decode errors since they are considered coder mistakes
  94. KUBE_PANIC_WATCH_DECODE_ERROR="${KUBE_PANIC_WATCH_DECODE_ERROR:-true}"
  95. export KUBE_PANIC_WATCH_DECODE_ERROR
  96. # Default list of admission Controllers to invoke prior to persisting objects in cluster
  97. # The order defined here does not matter.
  98. ENABLE_ADMISSION_PLUGINS=${ENABLE_ADMISSION_PLUGINS:-"NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota"}
  99. DISABLE_ADMISSION_PLUGINS=${DISABLE_ADMISSION_PLUGINS:-""}
  100. ADMISSION_CONTROL_CONFIG_FILE=${ADMISSION_CONTROL_CONFIG_FILE:-""}
  101. # START_MODE can be 'all', 'kubeletonly', 'nokubelet', or 'nokubeproxy'
  102. START_MODE=${START_MODE:-"all"}
  103. # A list of controllers to enable
  104. KUBE_CONTROLLERS="${KUBE_CONTROLLERS:-"*"}"
  105. # Audit policy
  106. AUDIT_POLICY_FILE=${AUDIT_POLICY_FILE:-""}
  107. # sanity check for OpenStack provider
  108. if [ "${CLOUD_PROVIDER}" == "openstack" ]; then
  109. if [ "${CLOUD_CONFIG}" == "" ]; then
  110. echo "Missing CLOUD_CONFIG env for OpenStack provider!"
  111. exit 1
  112. fi
  113. if [ ! -f "${CLOUD_CONFIG}" ]; then
  114. echo "Cloud config ${CLOUD_CONFIG} doesn't exist"
  115. exit 1
  116. fi
  117. fi
  118. # set feature gates if enable Pod priority and preemption
  119. if [ "${ENABLE_POD_PRIORITY_PREEMPTION}" == true ]; then
  120. FEATURE_GATES="${FEATURE_GATES},PodPriority=true"
  121. fi
  122. # warn if users are running with swap allowed
  123. if [ "${FAIL_SWAP_ON}" == "false" ]; then
  124. echo "WARNING : The kubelet is configured to not fail even if swap is enabled; production deployments should disable swap."
  125. fi
  126. if [ "$(id -u)" != "0" ]; then
  127. echo "WARNING : This script MAY be run as root for docker socket / iptables functionality; if failures occur, retry as root." 2>&1
  128. fi
  129. # Stop right away if the build fails
  130. set -e
  131. source "${KUBE_ROOT}/hack/lib/init.sh"
  132. kube::util::ensure-gnu-sed
  133. function usage {
  134. echo "This script starts a local kube cluster. "
  135. echo "Example 0: hack/local-up-cluster.sh -h (this 'help' usage description)"
  136. echo "Example 1: hack/local-up-cluster.sh -o _output/dockerized/bin/linux/amd64/ (run from docker output)"
  137. echo "Example 2: hack/local-up-cluster.sh -O (auto-guess the bin path for your platform)"
  138. echo "Example 3: hack/local-up-cluster.sh (build a local copy of the source)"
  139. }
  140. # This function guesses where the existing cached binary build is for the `-O`
  141. # flag
  142. function guess_built_binary_path {
  143. local hyperkube_path
  144. hyperkube_path=$(kube::util::find-binary "hyperkube")
  145. if [[ -z "${hyperkube_path}" ]]; then
  146. return
  147. fi
  148. echo -n "$(dirname "${hyperkube_path}")"
  149. }
  150. ### Allow user to supply the source directory.
  151. GO_OUT=${GO_OUT:-}
  152. while getopts "ho:O" OPTION
  153. do
  154. case ${OPTION} in
  155. o)
  156. echo "skipping build"
  157. GO_OUT="${OPTARG}"
  158. echo "using source ${GO_OUT}"
  159. ;;
  160. O)
  161. GO_OUT=$(guess_built_binary_path)
  162. if [ "${GO_OUT}" == "" ]; then
  163. echo "Could not guess the correct output directory to use."
  164. exit 1
  165. fi
  166. ;;
  167. h)
  168. usage
  169. exit
  170. ;;
  171. ?)
  172. usage
  173. exit
  174. ;;
  175. esac
  176. done
  177. if [ "x${GO_OUT}" == "x" ]; then
  178. make -C "${KUBE_ROOT}" WHAT="cmd/kubectl cmd/hyperkube"
  179. else
  180. echo "skipped the build."
  181. fi
  182. # Shut down anyway if there's an error.
  183. set +e
  184. API_PORT=${API_PORT:-8080}
  185. API_SECURE_PORT=${API_SECURE_PORT:-6443}
  186. # WARNING: For DNS to work on most setups you should export API_HOST as the docker0 ip address,
  187. API_HOST=${API_HOST:-localhost}
  188. API_HOST_IP=${API_HOST_IP:-"127.0.0.1"}
  189. ADVERTISE_ADDRESS=${ADVERTISE_ADDRESS:-""}
  190. NODE_PORT_RANGE=${NODE_PORT_RANGE:-""}
  191. API_BIND_ADDR=${API_BIND_ADDR:-"0.0.0.0"}
  192. EXTERNAL_HOSTNAME=${EXTERNAL_HOSTNAME:-localhost}
  193. KUBELET_HOST=${KUBELET_HOST:-"127.0.0.1"}
  194. # By default only allow CORS for requests on localhost
  195. API_CORS_ALLOWED_ORIGINS=${API_CORS_ALLOWED_ORIGINS:-/127.0.0.1(:[0-9]+)?$,/localhost(:[0-9]+)?$}
  196. KUBELET_PORT=${KUBELET_PORT:-10250}
  197. LOG_LEVEL=${LOG_LEVEL:-3}
  198. # Use to increase verbosity on particular files, e.g. LOG_SPEC=token_controller*=5,other_controller*=4
  199. LOG_SPEC=${LOG_SPEC:-""}
  200. LOG_DIR=${LOG_DIR:-"/tmp"}
  201. CONTAINER_RUNTIME=${CONTAINER_RUNTIME:-"docker"}
  202. CONTAINER_RUNTIME_ENDPOINT=${CONTAINER_RUNTIME_ENDPOINT:-""}
  203. RUNTIME_REQUEST_TIMEOUT=${RUNTIME_REQUEST_TIMEOUT:-"2m"}
  204. IMAGE_SERVICE_ENDPOINT=${IMAGE_SERVICE_ENDPOINT:-""}
  205. CHAOS_CHANCE=${CHAOS_CHANCE:-0.0}
  206. CPU_CFS_QUOTA=${CPU_CFS_QUOTA:-true}
  207. ENABLE_HOSTPATH_PROVISIONER=${ENABLE_HOSTPATH_PROVISIONER:-"false"}
  208. CLAIM_BINDER_SYNC_PERIOD=${CLAIM_BINDER_SYNC_PERIOD:-"15s"} # current k8s default
  209. ENABLE_CONTROLLER_ATTACH_DETACH=${ENABLE_CONTROLLER_ATTACH_DETACH:-"true"} # current default
  210. # This is the default dir and filename where the apiserver will generate a self-signed cert
  211. # which should be able to be used as the CA to verify itself
  212. CERT_DIR=${CERT_DIR:-"/var/run/kubernetes"}
  213. ROOT_CA_FILE=${CERT_DIR}/server-ca.crt
  214. ROOT_CA_KEY=${CERT_DIR}/server-ca.key
  215. CLUSTER_SIGNING_CERT_FILE=${CLUSTER_SIGNING_CERT_FILE:-"${ROOT_CA_FILE}"}
  216. CLUSTER_SIGNING_KEY_FILE=${CLUSTER_SIGNING_KEY_FILE:-"${ROOT_CA_KEY}"}
  217. # Reuse certs will skip generate new ca/cert files under CERT_DIR
  218. # it's useful with PRESERVE_ETCD=true because new ca will make existed service account secrets invalided
  219. REUSE_CERTS=${REUSE_CERTS:-false}
  220. # name of the cgroup driver, i.e. cgroupfs or systemd
  221. if [[ ${CONTAINER_RUNTIME} == "docker" ]]; then
  222. # default cgroup driver to match what is reported by docker to simplify local development
  223. if [[ -z ${CGROUP_DRIVER} ]]; then
  224. # match driver with docker runtime reported value (they must match)
  225. CGROUP_DRIVER=$(docker info | grep "Cgroup Driver:" | sed -e 's/^[[:space:]]*//'|cut -f3- -d' ')
  226. echo "Kubelet cgroup driver defaulted to use: ${CGROUP_DRIVER}"
  227. fi
  228. if [[ -f /var/log/docker.log && ! -f "${LOG_DIR}/docker.log" ]]; then
  229. ln -s /var/log/docker.log "${LOG_DIR}/docker.log"
  230. fi
  231. fi
  232. # Ensure CERT_DIR is created for auto-generated crt/key and kubeconfig
  233. mkdir -p "${CERT_DIR}" &>/dev/null || sudo mkdir -p "${CERT_DIR}"
  234. CONTROLPLANE_SUDO=$(test -w "${CERT_DIR}" || echo "sudo -E")
  235. function test_apiserver_off {
  236. # For the common local scenario, fail fast if server is already running.
  237. # this can happen if you run local-up-cluster.sh twice and kill etcd in between.
  238. if [[ "${API_PORT}" -gt "0" ]]; then
  239. if ! curl --silent -g "${API_HOST}:${API_PORT}" ; then
  240. echo "API SERVER insecure port is free, proceeding..."
  241. else
  242. echo "ERROR starting API SERVER, exiting. Some process on ${API_HOST} is serving already on ${API_PORT}"
  243. exit 1
  244. fi
  245. fi
  246. if ! curl --silent -k -g "${API_HOST}:${API_SECURE_PORT}" ; then
  247. echo "API SERVER secure port is free, proceeding..."
  248. else
  249. echo "ERROR starting API SERVER, exiting. Some process on ${API_HOST} is serving already on ${API_SECURE_PORT}"
  250. exit 1
  251. fi
  252. }
  253. function detect_binary {
  254. # Detect the OS name/arch so that we can find our binary
  255. case "$(uname -s)" in
  256. Darwin)
  257. host_os=darwin
  258. ;;
  259. Linux)
  260. host_os=linux
  261. ;;
  262. *)
  263. echo "Unsupported host OS. Must be Linux or Mac OS X." >&2
  264. exit 1
  265. ;;
  266. esac
  267. case "$(uname -m)" in
  268. x86_64*)
  269. host_arch=amd64
  270. ;;
  271. i?86_64*)
  272. host_arch=amd64
  273. ;;
  274. amd64*)
  275. host_arch=amd64
  276. ;;
  277. aarch64*)
  278. host_arch=arm64
  279. ;;
  280. arm64*)
  281. host_arch=arm64
  282. ;;
  283. arm*)
  284. host_arch=arm
  285. ;;
  286. i?86*)
  287. host_arch=x86
  288. ;;
  289. s390x*)
  290. host_arch=s390x
  291. ;;
  292. ppc64le*)
  293. host_arch=ppc64le
  294. ;;
  295. *)
  296. echo "Unsupported host arch. Must be x86_64, 386, arm, arm64, s390x or ppc64le." >&2
  297. exit 1
  298. ;;
  299. esac
  300. GO_OUT="${KUBE_ROOT}/_output/local/bin/${host_os}/${host_arch}"
  301. }
  302. cleanup()
  303. {
  304. echo "Cleaning up..."
  305. # delete running images
  306. # if [[ "${ENABLE_CLUSTER_DNS}" == true ]]; then
  307. # Still need to figure why this commands throw an error: Error from server: client: etcd cluster is unavailable or misconfigured
  308. # ${KUBECTL} --namespace=kube-system delete service kube-dns
  309. # And this one hang forever:
  310. # ${KUBECTL} --namespace=kube-system delete rc kube-dns-v10
  311. # fi
  312. # Check if the API server is still running
  313. [[ -n "${APISERVER_PID-}" ]] && mapfile -t APISERVER_PIDS < <(pgrep -P "${APISERVER_PID}" ; ps -o pid= -p "${APISERVER_PID}")
  314. [[ -n "${APISERVER_PIDS-}" ]] && sudo kill "${APISERVER_PIDS[@]}" 2>/dev/null
  315. # Check if the controller-manager is still running
  316. [[ -n "${CTLRMGR_PID-}" ]] && mapfile -t CTLRMGR_PIDS < <(pgrep -P "${CTLRMGR_PID}" ; ps -o pid= -p "${CTLRMGR_PID}")
  317. [[ -n "${CTLRMGR_PIDS-}" ]] && sudo kill "${CTLRMGR_PIDS[@]}" 2>/dev/null
  318. # Check if the kubelet is still running
  319. [[ -n "${KUBELET_PID-}" ]] && mapfile -t KUBELET_PIDS < <(pgrep -P "${KUBELET_PID}" ; ps -o pid= -p "${KUBELET_PID}")
  320. [[ -n "${KUBELET_PIDS-}" ]] && sudo kill "${KUBELET_PIDS[@]}" 2>/dev/null
  321. # Check if the proxy is still running
  322. [[ -n "${PROXY_PID-}" ]] && mapfile -t PROXY_PIDS < <(pgrep -P "${PROXY_PID}" ; ps -o pid= -p "${PROXY_PID}")
  323. [[ -n "${PROXY_PIDS-}" ]] && sudo kill "${PROXY_PIDS[@]}" 2>/dev/null
  324. # Check if the scheduler is still running
  325. [[ -n "${SCHEDULER_PID-}" ]] && mapfile -t SCHEDULER_PIDS < <(pgrep -P "${SCHEDULER_PID}" ; ps -o pid= -p "${SCHEDULER_PID}")
  326. [[ -n "${SCHEDULER_PIDS-}" ]] && sudo kill "${SCHEDULER_PIDS[@]}" 2>/dev/null
  327. # Check if the etcd is still running
  328. [[ -n "${ETCD_PID-}" ]] && kube::etcd::stop
  329. if [[ "${PRESERVE_ETCD}" == "false" ]]; then
  330. [[ -n "${ETCD_DIR-}" ]] && kube::etcd::clean_etcd_dir
  331. fi
  332. exit 0
  333. }
  334. # Check if all processes are still running. Prints a warning once each time
  335. # a process dies unexpectedly.
  336. function healthcheck {
  337. if [[ -n "${APISERVER_PID-}" ]] && ! sudo kill -0 "${APISERVER_PID}" 2>/dev/null; then
  338. warning_log "API server terminated unexpectedly, see ${APISERVER_LOG}"
  339. APISERVER_PID=
  340. fi
  341. if [[ -n "${CTLRMGR_PID-}" ]] && ! sudo kill -0 "${CTLRMGR_PID}" 2>/dev/null; then
  342. warning_log "kube-controller-manager terminated unexpectedly, see ${CTLRMGR_LOG}"
  343. CTLRMGR_PID=
  344. fi
  345. if [[ -n "${KUBELET_PID-}" ]] && ! sudo kill -0 "${KUBELET_PID}" 2>/dev/null; then
  346. warning_log "kubelet terminated unexpectedly, see ${KUBELET_LOG}"
  347. KUBELET_PID=
  348. fi
  349. if [[ -n "${PROXY_PID-}" ]] && ! sudo kill -0 "${PROXY_PID}" 2>/dev/null; then
  350. warning_log "kube-proxy terminated unexpectedly, see ${PROXY_LOG}"
  351. PROXY_PID=
  352. fi
  353. if [[ -n "${SCHEDULER_PID-}" ]] && ! sudo kill -0 "${SCHEDULER_PID}" 2>/dev/null; then
  354. warning_log "scheduler terminated unexpectedly, see ${SCHEDULER_LOG}"
  355. SCHEDULER_PID=
  356. fi
  357. if [[ -n "${ETCD_PID-}" ]] && ! sudo kill -0 "${ETCD_PID}" 2>/dev/null; then
  358. warning_log "etcd terminated unexpectedly"
  359. ETCD_PID=
  360. fi
  361. }
  362. function print_color {
  363. message=$1
  364. prefix=${2:+$2: } # add colon only if defined
  365. color=${3:-1} # default is red
  366. echo -n "$(tput bold)$(tput setaf "${color}")"
  367. echo "${prefix}${message}"
  368. echo -n "$(tput sgr0)"
  369. }
  370. function warning_log {
  371. print_color "$1" "W$(date "+%m%d %H:%M:%S")]" 1
  372. }
  373. function start_etcd {
  374. echo "Starting etcd"
  375. export ETCD_LOGFILE=${LOG_DIR}/etcd.log
  376. kube::etcd::start
  377. }
  378. function set_service_accounts {
  379. SERVICE_ACCOUNT_LOOKUP=${SERVICE_ACCOUNT_LOOKUP:-true}
  380. SERVICE_ACCOUNT_KEY=${SERVICE_ACCOUNT_KEY:-/tmp/kube-serviceaccount.key}
  381. # Generate ServiceAccount key if needed
  382. if [[ ! -f "${SERVICE_ACCOUNT_KEY}" ]]; then
  383. mkdir -p "$(dirname "${SERVICE_ACCOUNT_KEY}")"
  384. openssl genrsa -out "${SERVICE_ACCOUNT_KEY}" 2048 2>/dev/null
  385. fi
  386. }
  387. function generate_certs {
  388. # Create CA signers
  389. if [[ "${ENABLE_SINGLE_CA_SIGNER:-}" = true ]]; then
  390. kube::util::create_signing_certkey "${CONTROLPLANE_SUDO}" "${CERT_DIR}" server '"client auth","server auth"'
  391. sudo cp "${CERT_DIR}/server-ca.key" "${CERT_DIR}/client-ca.key"
  392. sudo cp "${CERT_DIR}/server-ca.crt" "${CERT_DIR}/client-ca.crt"
  393. sudo cp "${CERT_DIR}/server-ca-config.json" "${CERT_DIR}/client-ca-config.json"
  394. else
  395. kube::util::create_signing_certkey "${CONTROLPLANE_SUDO}" "${CERT_DIR}" server '"server auth"'
  396. kube::util::create_signing_certkey "${CONTROLPLANE_SUDO}" "${CERT_DIR}" client '"client auth"'
  397. fi
  398. # Create auth proxy client ca
  399. kube::util::create_signing_certkey "${CONTROLPLANE_SUDO}" "${CERT_DIR}" request-header '"client auth"'
  400. # serving cert for kube-apiserver
  401. kube::util::create_serving_certkey "${CONTROLPLANE_SUDO}" "${CERT_DIR}" "server-ca" kube-apiserver kubernetes.default kubernetes.default.svc "localhost" "${API_HOST_IP}" "${API_HOST}" "${FIRST_SERVICE_CLUSTER_IP}"
  402. # Create client certs signed with client-ca, given id, given CN and a number of groups
  403. kube::util::create_client_certkey "${CONTROLPLANE_SUDO}" "${CERT_DIR}" 'client-ca' controller system:kube-controller-manager
  404. kube::util::create_client_certkey "${CONTROLPLANE_SUDO}" "${CERT_DIR}" 'client-ca' scheduler system:kube-scheduler
  405. kube::util::create_client_certkey "${CONTROLPLANE_SUDO}" "${CERT_DIR}" 'client-ca' admin system:admin system:masters
  406. kube::util::create_client_certkey "${CONTROLPLANE_SUDO}" "${CERT_DIR}" 'client-ca' kube-apiserver kube-apiserver
  407. # Create matching certificates for kube-aggregator
  408. kube::util::create_serving_certkey "${CONTROLPLANE_SUDO}" "${CERT_DIR}" "server-ca" kube-aggregator api.kube-public.svc "localhost" "${API_HOST_IP}"
  409. kube::util::create_client_certkey "${CONTROLPLANE_SUDO}" "${CERT_DIR}" request-header-ca auth-proxy system:auth-proxy
  410. # TODO remove masters and add rolebinding
  411. kube::util::create_client_certkey "${CONTROLPLANE_SUDO}" "${CERT_DIR}" 'client-ca' kube-aggregator system:kube-aggregator system:masters
  412. kube::util::write_client_kubeconfig "${CONTROLPLANE_SUDO}" "${CERT_DIR}" "${ROOT_CA_FILE}" "${API_HOST}" "${API_SECURE_PORT}" kube-aggregator
  413. }
  414. function generate_kubeproxy_certs {
  415. kube::util::create_client_certkey "${CONTROLPLANE_SUDO}" "${CERT_DIR}" 'client-ca' kube-proxy system:kube-proxy system:nodes
  416. kube::util::write_client_kubeconfig "${CONTROLPLANE_SUDO}" "${CERT_DIR}" "${ROOT_CA_FILE}" "${API_HOST}" "${API_SECURE_PORT}" kube-proxy
  417. }
  418. function generate_kubelet_certs {
  419. kube::util::create_client_certkey "${CONTROLPLANE_SUDO}" "${CERT_DIR}" 'client-ca' kubelet "system:node:${HOSTNAME_OVERRIDE}" system:nodes
  420. kube::util::write_client_kubeconfig "${CONTROLPLANE_SUDO}" "${CERT_DIR}" "${ROOT_CA_FILE}" "${API_HOST}" "${API_SECURE_PORT}" kubelet
  421. }
  422. function start_apiserver {
  423. security_admission=""
  424. if [[ -n "${DENY_SECURITY_CONTEXT_ADMISSION}" ]]; then
  425. security_admission=",SecurityContextDeny"
  426. fi
  427. if [[ -n "${PSP_ADMISSION}" ]]; then
  428. security_admission=",PodSecurityPolicy"
  429. fi
  430. if [[ -n "${NODE_ADMISSION}" ]]; then
  431. security_admission=",NodeRestriction"
  432. fi
  433. if [ "${ENABLE_POD_PRIORITY_PREEMPTION}" == true ]; then
  434. security_admission=",Priority"
  435. if [[ -n "${RUNTIME_CONFIG}" ]]; then
  436. RUNTIME_CONFIG+=","
  437. fi
  438. RUNTIME_CONFIG+="scheduling.k8s.io/v1alpha1=true"
  439. fi
  440. # Append security_admission plugin
  441. ENABLE_ADMISSION_PLUGINS="${ENABLE_ADMISSION_PLUGINS}${security_admission}"
  442. authorizer_arg=""
  443. if [[ -n "${AUTHORIZATION_MODE}" ]]; then
  444. authorizer_arg="--authorization-mode=${AUTHORIZATION_MODE}"
  445. fi
  446. priv_arg=""
  447. if [[ -n "${ALLOW_PRIVILEGED}" ]]; then
  448. priv_arg="--allow-privileged=${ALLOW_PRIVILEGED}"
  449. fi
  450. runtime_config=""
  451. if [[ -n "${RUNTIME_CONFIG}" ]]; then
  452. runtime_config="--runtime-config=${RUNTIME_CONFIG}"
  453. fi
  454. # Let the API server pick a default address when API_HOST_IP
  455. # is set to 127.0.0.1
  456. advertise_address=""
  457. if [[ "${API_HOST_IP}" != "127.0.0.1" ]]; then
  458. advertise_address="--advertise-address=${API_HOST_IP}"
  459. fi
  460. if [[ "${ADVERTISE_ADDRESS}" != "" ]] ; then
  461. advertise_address="--advertise-address=${ADVERTISE_ADDRESS}"
  462. fi
  463. node_port_range=""
  464. if [[ "${NODE_PORT_RANGE}" != "" ]] ; then
  465. node_port_range="--service-node-port-range=${NODE_PORT_RANGE}"
  466. fi
  467. if [[ "${REUSE_CERTS}" != true ]]; then
  468. # Create Certs
  469. generate_certs
  470. fi
  471. cloud_config_arg="--cloud-provider=${CLOUD_PROVIDER} --cloud-config=${CLOUD_CONFIG}"
  472. if [[ "${EXTERNAL_CLOUD_PROVIDER:-}" == "true" ]]; then
  473. cloud_config_arg="--cloud-provider=external"
  474. fi
  475. if [[ -n "${AUDIT_POLICY_FILE}" ]]; then
  476. cat <<EOF > /tmp/kube-audit-policy-file
  477. # Log all requests at the Metadata level.
  478. apiVersion: audit.k8s.io/v1
  479. kind: Policy
  480. rules:
  481. - level: Metadata
  482. EOF
  483. AUDIT_POLICY_FILE="/tmp/kube-audit-policy-file"
  484. fi
  485. APISERVER_LOG=${LOG_DIR}/kube-apiserver.log
  486. ${CONTROLPLANE_SUDO} "${GO_OUT}/hyperkube" kube-apiserver "${authorizer_arg}" "${priv_arg}" ${runtime_config} \
  487. ${cloud_config_arg} \
  488. "${advertise_address}" \
  489. "${node_port_range}" \
  490. --v="${LOG_LEVEL}" \
  491. --vmodule="${LOG_SPEC}" \
  492. --audit-policy-file="${AUDIT_POLICY_FILE}" \
  493. --audit-log-path="${LOG_DIR}/kube-apiserver-audit.log" \
  494. --cert-dir="${CERT_DIR}" \
  495. --client-ca-file="${CERT_DIR}/client-ca.crt" \
  496. --kubelet-client-certificate="${CERT_DIR}/client-kube-apiserver.crt" \
  497. --kubelet-client-key="${CERT_DIR}/client-kube-apiserver.key" \
  498. --service-account-key-file="${SERVICE_ACCOUNT_KEY}" \
  499. --service-account-lookup="${SERVICE_ACCOUNT_LOOKUP}" \
  500. --enable-admission-plugins="${ENABLE_ADMISSION_PLUGINS}" \
  501. --disable-admission-plugins="${DISABLE_ADMISSION_PLUGINS}" \
  502. --admission-control-config-file="${ADMISSION_CONTROL_CONFIG_FILE}" \
  503. --bind-address="${API_BIND_ADDR}" \
  504. --secure-port="${API_SECURE_PORT}" \
  505. --tls-cert-file="${CERT_DIR}/serving-kube-apiserver.crt" \
  506. --tls-private-key-file="${CERT_DIR}/serving-kube-apiserver.key" \
  507. --insecure-bind-address="${API_HOST_IP}" \
  508. --insecure-port="${API_PORT}" \
  509. --storage-backend="${STORAGE_BACKEND}" \
  510. --storage-media-type="${STORAGE_MEDIA_TYPE}" \
  511. --etcd-servers="http://${ETCD_HOST}:${ETCD_PORT}" \
  512. --service-cluster-ip-range="${SERVICE_CLUSTER_IP_RANGE}" \
  513. --feature-gates="${FEATURE_GATES}" \
  514. --external-hostname="${EXTERNAL_HOSTNAME}" \
  515. --requestheader-username-headers=X-Remote-User \
  516. --requestheader-group-headers=X-Remote-Group \
  517. --requestheader-extra-headers-prefix=X-Remote-Extra- \
  518. --requestheader-client-ca-file="${CERT_DIR}/request-header-ca.crt" \
  519. --requestheader-allowed-names=system:auth-proxy \
  520. --proxy-client-cert-file="${CERT_DIR}/client-auth-proxy.crt" \
  521. --proxy-client-key-file="${CERT_DIR}/client-auth-proxy.key" \
  522. --cors-allowed-origins="${API_CORS_ALLOWED_ORIGINS}" >"${APISERVER_LOG}" 2>&1 &
  523. APISERVER_PID=$!
  524. # Wait for kube-apiserver to come up before launching the rest of the components.
  525. echo "Waiting for apiserver to come up"
  526. kube::util::wait_for_url "https://${API_HOST_IP}:${API_SECURE_PORT}/healthz" "apiserver: " 1 "${WAIT_FOR_URL_API_SERVER}" "${MAX_TIME_FOR_URL_API_SERVER}" \
  527. || { echo "check apiserver logs: ${APISERVER_LOG}" ; exit 1 ; }
  528. # Create kubeconfigs for all components, using client certs
  529. kube::util::write_client_kubeconfig "${CONTROLPLANE_SUDO}" "${CERT_DIR}" "${ROOT_CA_FILE}" "${API_HOST}" "${API_SECURE_PORT}" admin
  530. ${CONTROLPLANE_SUDO} chown "${USER}" "${CERT_DIR}/client-admin.key" # make readable for kubectl
  531. kube::util::write_client_kubeconfig "${CONTROLPLANE_SUDO}" "${CERT_DIR}" "${ROOT_CA_FILE}" "${API_HOST}" "${API_SECURE_PORT}" controller
  532. kube::util::write_client_kubeconfig "${CONTROLPLANE_SUDO}" "${CERT_DIR}" "${ROOT_CA_FILE}" "${API_HOST}" "${API_SECURE_PORT}" scheduler
  533. if [[ -z "${AUTH_ARGS}" ]]; then
  534. AUTH_ARGS="--client-key=${CERT_DIR}/client-admin.key --client-certificate=${CERT_DIR}/client-admin.crt"
  535. fi
  536. # Grant apiserver permission to speak to the kubelet
  537. ${KUBECTL} --kubeconfig "${CERT_DIR}/admin.kubeconfig" create clusterrolebinding kube-apiserver-kubelet-admin --clusterrole=system:kubelet-api-admin --user=kube-apiserver
  538. ${CONTROLPLANE_SUDO} cp "${CERT_DIR}/admin.kubeconfig" "${CERT_DIR}/admin-kube-aggregator.kubeconfig"
  539. ${CONTROLPLANE_SUDO} chown "$(whoami)" "${CERT_DIR}/admin-kube-aggregator.kubeconfig"
  540. ${KUBECTL} config set-cluster local-up-cluster --kubeconfig="${CERT_DIR}/admin-kube-aggregator.kubeconfig" --server="https://${API_HOST_IP}:31090"
  541. echo "use 'kubectl --kubeconfig=${CERT_DIR}/admin-kube-aggregator.kubeconfig' to use the aggregated API server"
  542. }
  543. function start_controller_manager {
  544. node_cidr_args=()
  545. if [[ "${NET_PLUGIN}" == "kubenet" ]]; then
  546. node_cidr_args=("--allocate-node-cidrs=true" "--cluster-cidr=10.1.0.0/16")
  547. fi
  548. cloud_config_arg=("--cloud-provider=${CLOUD_PROVIDER}" "--cloud-config=${CLOUD_CONFIG}")
  549. if [[ "${EXTERNAL_CLOUD_PROVIDER:-}" == "true" ]]; then
  550. cloud_config_arg=("--cloud-provider=external")
  551. cloud_config_arg+=("--external-cloud-volume-plugin=${CLOUD_PROVIDER}")
  552. cloud_config_arg+=("--cloud-config=${CLOUD_CONFIG}")
  553. fi
  554. CTLRMGR_LOG=${LOG_DIR}/kube-controller-manager.log
  555. ${CONTROLPLANE_SUDO} "${GO_OUT}/hyperkube" kube-controller-manager \
  556. --v="${LOG_LEVEL}" \
  557. --vmodule="${LOG_SPEC}" \
  558. --service-account-private-key-file="${SERVICE_ACCOUNT_KEY}" \
  559. --root-ca-file="${ROOT_CA_FILE}" \
  560. --cluster-signing-cert-file="${CLUSTER_SIGNING_CERT_FILE}" \
  561. --cluster-signing-key-file="${CLUSTER_SIGNING_KEY_FILE}" \
  562. --enable-hostpath-provisioner="${ENABLE_HOSTPATH_PROVISIONER}" \
  563. ${node_cidr_args[@]+"${node_cidr_args[@]}"} \
  564. --pvclaimbinder-sync-period="${CLAIM_BINDER_SYNC_PERIOD}" \
  565. --feature-gates="${FEATURE_GATES}" \
  566. "${cloud_config_arg[@]}" \
  567. --kubeconfig "${CERT_DIR}"/controller.kubeconfig \
  568. --use-service-account-credentials \
  569. --controllers="${KUBE_CONTROLLERS}" \
  570. --leader-elect=false \
  571. --cert-dir="${CERT_DIR}" \
  572. --master="https://${API_HOST}:${API_SECURE_PORT}" >"${CTLRMGR_LOG}" 2>&1 &
  573. CTLRMGR_PID=$!
  574. }
  575. function start_cloud_controller_manager {
  576. if [ -z "${CLOUD_CONFIG}" ]; then
  577. echo "CLOUD_CONFIG cannot be empty!"
  578. exit 1
  579. fi
  580. if [ ! -f "${CLOUD_CONFIG}" ]; then
  581. echo "Cloud config ${CLOUD_CONFIG} doesn't exist"
  582. exit 1
  583. fi
  584. node_cidr_args=()
  585. if [[ "${NET_PLUGIN}" == "kubenet" ]]; then
  586. node_cidr_args=("--allocate-node-cidrs=true" "--cluster-cidr=10.1.0.0/16")
  587. fi
  588. CLOUD_CTLRMGR_LOG=${LOG_DIR}/cloud-controller-manager.log
  589. ${CONTROLPLANE_SUDO} "${EXTERNAL_CLOUD_PROVIDER_BINARY:-"${GO_OUT}/hyperkube" cloud-controller-manager}" \
  590. --v="${LOG_LEVEL}" \
  591. --vmodule="${LOG_SPEC}" \
  592. "${node_cidr_args[@]:-}" \
  593. --feature-gates="${FEATURE_GATES}" \
  594. --cloud-provider="${CLOUD_PROVIDER}" \
  595. --cloud-config="${CLOUD_CONFIG}" \
  596. --kubeconfig "${CERT_DIR}"/controller.kubeconfig \
  597. --use-service-account-credentials \
  598. --leader-elect=false \
  599. --master="https://${API_HOST}:${API_SECURE_PORT}" >"${CLOUD_CTLRMGR_LOG}" 2>&1 &
  600. export CLOUD_CTLRMGR_PID=$!
  601. }
  602. function start_kubelet {
  603. KUBELET_LOG=${LOG_DIR}/kubelet.log
  604. mkdir -p "${POD_MANIFEST_PATH}" &>/dev/null || sudo mkdir -p "${POD_MANIFEST_PATH}"
  605. cloud_config_arg=("--cloud-provider=${CLOUD_PROVIDER}" "--cloud-config=${CLOUD_CONFIG}")
  606. if [[ "${EXTERNAL_CLOUD_PROVIDER:-}" == "true" ]]; then
  607. cloud_config_arg=("--cloud-provider=external")
  608. cloud_config_arg+=("--provider-id=$(hostname)")
  609. fi
  610. mkdir -p "/var/lib/kubelet" &>/dev/null || sudo mkdir -p "/var/lib/kubelet"
  611. # Enable dns
  612. if [[ "${ENABLE_CLUSTER_DNS}" = true ]]; then
  613. if [[ "${ENABLE_NODELOCAL_DNS:-}" == "true" ]]; then
  614. dns_args=("--cluster-dns=${LOCAL_DNS_IP}" "--cluster-domain=${DNS_DOMAIN}")
  615. else
  616. dns_args=("--cluster-dns=${DNS_SERVER_IP}" "--cluster-domain=${DNS_DOMAIN}")
  617. fi
  618. else
  619. # To start a private DNS server set ENABLE_CLUSTER_DNS and
  620. # DNS_SERVER_IP/DOMAIN. This will at least provide a working
  621. # DNS server for real world hostnames.
  622. dns_args=("--cluster-dns=8.8.8.8")
  623. fi
  624. net_plugin_args=()
  625. if [[ -n "${NET_PLUGIN}" ]]; then
  626. net_plugin_args=("--network-plugin=${NET_PLUGIN}")
  627. fi
  628. auth_args=()
  629. if [[ "${KUBELET_AUTHORIZATION_WEBHOOK:-}" != "false" ]]; then
  630. auth_args+=("--authorization-mode=Webhook")
  631. fi
  632. if [[ "${KUBELET_AUTHENTICATION_WEBHOOK:-}" != "false" ]]; then
  633. auth_args+=("--authentication-token-webhook")
  634. fi
  635. if [[ -n "${CLIENT_CA_FILE:-}" ]]; then
  636. auth_args+=("--client-ca-file=${CLIENT_CA_FILE}")
  637. else
  638. auth_args+=("--client-ca-file=${CERT_DIR}/client-ca.crt")
  639. fi
  640. cni_conf_dir_args=()
  641. if [[ -n "${CNI_CONF_DIR}" ]]; then
  642. cni_conf_dir_args=("--cni-conf-dir=${CNI_CONF_DIR}")
  643. fi
  644. cni_bin_dir_args=()
  645. if [[ -n "${CNI_BIN_DIR}" ]]; then
  646. cni_bin_dir_args=("--cni-bin-dir=${CNI_BIN_DIR}")
  647. fi
  648. container_runtime_endpoint_args=()
  649. if [[ -n "${CONTAINER_RUNTIME_ENDPOINT}" ]]; then
  650. container_runtime_endpoint_args=("--container-runtime-endpoint=${CONTAINER_RUNTIME_ENDPOINT}")
  651. fi
  652. image_service_endpoint_args=()
  653. if [[ -n "${IMAGE_SERVICE_ENDPOINT}" ]]; then
  654. image_service_endpoint_args=("--image-service-endpoint=${IMAGE_SERVICE_ENDPOINT}")
  655. fi
  656. # shellcheck disable=SC2206
  657. all_kubelet_flags=(
  658. "--v=${LOG_LEVEL}"
  659. "--vmodule=${LOG_SPEC}"
  660. "--chaos-chance=${CHAOS_CHANCE}"
  661. "--container-runtime=${CONTAINER_RUNTIME}"
  662. "--hostname-override=${HOSTNAME_OVERRIDE}"
  663. "${cloud_config_arg[@]}"
  664. "--address=${KUBELET_HOST}"
  665. --kubeconfig "${CERT_DIR}"/kubelet.kubeconfig
  666. "--feature-gates=${FEATURE_GATES}"
  667. "--cpu-cfs-quota=${CPU_CFS_QUOTA}"
  668. "--enable-controller-attach-detach=${ENABLE_CONTROLLER_ATTACH_DETACH}"
  669. "--cgroups-per-qos=${CGROUPS_PER_QOS}"
  670. "--cgroup-driver=${CGROUP_DRIVER}"
  671. "--cgroup-root=${CGROUP_ROOT}"
  672. "--eviction-hard=${EVICTION_HARD}"
  673. "--eviction-soft=${EVICTION_SOFT}"
  674. "--eviction-pressure-transition-period=${EVICTION_PRESSURE_TRANSITION_PERIOD}"
  675. "--pod-manifest-path=${POD_MANIFEST_PATH}"
  676. "--fail-swap-on=${FAIL_SWAP_ON}"
  677. ${auth_args[@]+"${auth_args[@]}"}
  678. ${dns_args[@]+"${dns_args[@]}"}
  679. ${cni_conf_dir_args[@]+"${cni_conf_dir_args[@]}"}
  680. ${cni_bin_dir_args[@]+"${cni_bin_dir_args[@]}"}
  681. ${net_plugin_args[@]+"${net_plugin_args[@]}"}
  682. ${container_runtime_endpoint_args[@]+"${container_runtime_endpoint_args[@]}"}
  683. ${image_service_endpoint_args[@]+"${image_service_endpoint_args[@]}"}
  684. "--runtime-request-timeout=${RUNTIME_REQUEST_TIMEOUT}"
  685. "--port=${KUBELET_PORT}"
  686. ${KUBELET_FLAGS}
  687. )
  688. if [[ "${REUSE_CERTS}" != true ]]; then
  689. generate_kubelet_certs
  690. fi
  691. # shellcheck disable=SC2024
  692. sudo -E "${GO_OUT}/hyperkube" kubelet "${all_kubelet_flags[@]}" >"${KUBELET_LOG}" 2>&1 &
  693. KUBELET_PID=$!
  694. # Quick check that kubelet is running.
  695. if [ -n "${KUBELET_PID}" ] && ps -p ${KUBELET_PID} > /dev/null; then
  696. echo "kubelet ( ${KUBELET_PID} ) is running."
  697. else
  698. cat "${KUBELET_LOG}" ; exit 1
  699. fi
  700. }
  701. function start_kubeproxy {
  702. PROXY_LOG=${LOG_DIR}/kube-proxy.log
  703. cat <<EOF > /tmp/kube-proxy.yaml
  704. apiVersion: kubeproxy.config.k8s.io/v1alpha1
  705. kind: KubeProxyConfiguration
  706. clientConnection:
  707. kubeconfig: ${CERT_DIR}/kube-proxy.kubeconfig
  708. hostnameOverride: ${HOSTNAME_OVERRIDE}
  709. mode: ${KUBE_PROXY_MODE}
  710. EOF
  711. if [[ -n ${FEATURE_GATES} ]]; then
  712. echo "featureGates:"
  713. # Convert from foo=true,bar=false to
  714. # foo: true
  715. # bar: false
  716. for gate in $(echo "${FEATURE_GATES}" | tr ',' ' '); do
  717. echo "${gate}" | ${SED} -e 's/\(.*\)=\(.*\)/ \1: \2/'
  718. done
  719. fi >>/tmp/kube-proxy.yaml
  720. if [[ "${REUSE_CERTS}" != true ]]; then
  721. generate_kubeproxy_certs
  722. fi
  723. # shellcheck disable=SC2024
  724. sudo "${GO_OUT}/hyperkube" kube-proxy \
  725. --v="${LOG_LEVEL}" \
  726. --config=/tmp/kube-proxy.yaml \
  727. --master="https://${API_HOST}:${API_SECURE_PORT}" >"${PROXY_LOG}" 2>&1 &
  728. PROXY_PID=$!
  729. }
  730. function start_kubescheduler {
  731. SCHEDULER_LOG=${LOG_DIR}/kube-scheduler.log
  732. ${CONTROLPLANE_SUDO} "${GO_OUT}/hyperkube" kube-scheduler \
  733. --v="${LOG_LEVEL}" \
  734. --leader-elect=false \
  735. --kubeconfig "${CERT_DIR}"/scheduler.kubeconfig \
  736. --feature-gates="${FEATURE_GATES}" \
  737. --master="https://${API_HOST}:${API_SECURE_PORT}" >"${SCHEDULER_LOG}" 2>&1 &
  738. SCHEDULER_PID=$!
  739. }
  740. function start_kubedns {
  741. if [[ "${ENABLE_CLUSTER_DNS}" = true ]]; then
  742. cp "${KUBE_ROOT}/cluster/addons/dns/kube-dns/kube-dns.yaml.in" kube-dns.yaml
  743. ${SED} -i -e "s/{{ pillar\['dns_domain'\] }}/${DNS_DOMAIN}/g" kube-dns.yaml
  744. ${SED} -i -e "s/{{ pillar\['dns_server'\] }}/${DNS_SERVER_IP}/g" kube-dns.yaml
  745. ${SED} -i -e "s/{{ pillar\['dns_memory_limit'\] }}/${DNS_MEMORY_LIMIT}/g" kube-dns.yaml
  746. # TODO update to dns role once we have one.
  747. # use kubectl to create kubedns addon
  748. ${KUBECTL} --kubeconfig="${CERT_DIR}/admin.kubeconfig" --namespace=kube-system create -f kube-dns.yaml
  749. echo "Kube-dns addon successfully deployed."
  750. rm kube-dns.yaml
  751. fi
  752. }
  753. function start_nodelocaldns {
  754. cp "${KUBE_ROOT}/cluster/addons/dns/nodelocaldns/nodelocaldns.yaml" nodelocaldns.yaml
  755. sed -i -e "s/__PILLAR__DNS__DOMAIN__/${DNS_DOMAIN}/g" nodelocaldns.yaml
  756. sed -i -e "s/__PILLAR__DNS__SERVER__/${DNS_SERVER_IP}/g" nodelocaldns.yaml
  757. sed -i -e "s/__PILLAR__LOCAL__DNS__/${LOCAL_DNS_IP}/g" nodelocaldns.yaml
  758. # use kubectl to create nodelocaldns addon
  759. ${KUBECTL} --kubeconfig="${CERT_DIR}/admin.kubeconfig" --namespace=kube-system create -f nodelocaldns.yaml
  760. echo "NodeLocalDNS addon successfully deployed."
  761. rm nodelocaldns.yaml
  762. }
  763. function start_kubedashboard {
  764. if [[ "${ENABLE_CLUSTER_DASHBOARD}" = true ]]; then
  765. echo "Creating kubernetes-dashboard"
  766. # use kubectl to create the dashboard
  767. ${KUBECTL} --kubeconfig="${CERT_DIR}/admin.kubeconfig" apply -f "${KUBE_ROOT}/cluster/addons/dashboard/dashboard-secret.yaml"
  768. ${KUBECTL} --kubeconfig="${CERT_DIR}/admin.kubeconfig" apply -f "${KUBE_ROOT}/cluster/addons/dashboard/dashboard-configmap.yaml"
  769. ${KUBECTL} --kubeconfig="${CERT_DIR}/admin.kubeconfig" apply -f "${KUBE_ROOT}/cluster/addons/dashboard/dashboard-rbac.yaml"
  770. ${KUBECTL} --kubeconfig="${CERT_DIR}/admin.kubeconfig" apply -f "${KUBE_ROOT}/cluster/addons/dashboard/dashboard-controller.yaml"
  771. ${KUBECTL} --kubeconfig="${CERT_DIR}/admin.kubeconfig" apply -f "${KUBE_ROOT}/cluster/addons/dashboard/dashboard-service.yaml"
  772. echo "kubernetes-dashboard deployment and service successfully deployed."
  773. fi
  774. }
  775. function create_psp_policy {
  776. echo "Create podsecuritypolicy policies for RBAC."
  777. ${KUBECTL} --kubeconfig="${CERT_DIR}/admin.kubeconfig" create -f "${KUBE_ROOT}/examples/podsecuritypolicy/rbac/policies.yaml"
  778. ${KUBECTL} --kubeconfig="${CERT_DIR}/admin.kubeconfig" create -f "${KUBE_ROOT}/examples/podsecuritypolicy/rbac/roles.yaml"
  779. ${KUBECTL} --kubeconfig="${CERT_DIR}/admin.kubeconfig" create -f "${KUBE_ROOT}/examples/podsecuritypolicy/rbac/bindings.yaml"
  780. }
  781. function create_storage_class {
  782. if [ -z "${CLOUD_PROVIDER}" ]; then
  783. CLASS_FILE=${KUBE_ROOT}/cluster/addons/storage-class/local/default.yaml
  784. else
  785. CLASS_FILE=${KUBE_ROOT}/cluster/addons/storage-class/${CLOUD_PROVIDER}/default.yaml
  786. fi
  787. if [ -e "${CLASS_FILE}" ]; then
  788. echo "Create default storage class for ${CLOUD_PROVIDER}"
  789. ${KUBECTL} --kubeconfig="${CERT_DIR}/admin.kubeconfig" create -f "${CLASS_FILE}"
  790. else
  791. echo "No storage class available for ${CLOUD_PROVIDER}."
  792. fi
  793. }
  794. function print_success {
  795. if [[ "${START_MODE}" != "kubeletonly" ]]; then
  796. if [[ "${ENABLE_DAEMON}" = false ]]; then
  797. echo "Local Kubernetes cluster is running. Press Ctrl-C to shut it down."
  798. else
  799. echo "Local Kubernetes cluster is running."
  800. fi
  801. cat <<EOF
  802. Logs:
  803. ${APISERVER_LOG:-}
  804. ${CTLRMGR_LOG:-}
  805. ${CLOUD_CTLRMGR_LOG:-}
  806. ${PROXY_LOG:-}
  807. ${SCHEDULER_LOG:-}
  808. EOF
  809. fi
  810. if [[ "${START_MODE}" == "all" ]]; then
  811. echo " ${KUBELET_LOG}"
  812. elif [[ "${START_MODE}" == "nokubelet" ]]; then
  813. echo
  814. echo "No kubelet was started because you set START_MODE=nokubelet"
  815. echo "Run this script again with START_MODE=kubeletonly to run a kubelet"
  816. fi
  817. if [[ "${START_MODE}" != "kubeletonly" ]]; then
  818. echo
  819. if [[ "${ENABLE_DAEMON}" = false ]]; then
  820. echo "To start using your cluster, you can open up another terminal/tab and run:"
  821. else
  822. echo "To start using your cluster, run:"
  823. fi
  824. cat <<EOF
  825. export KUBECONFIG=${CERT_DIR}/admin.kubeconfig
  826. cluster/kubectl.sh
  827. Alternatively, you can write to the default kubeconfig:
  828. export KUBERNETES_PROVIDER=local
  829. cluster/kubectl.sh config set-cluster local --server=https://${API_HOST}:${API_SECURE_PORT} --certificate-authority=${ROOT_CA_FILE}
  830. cluster/kubectl.sh config set-credentials myself ${AUTH_ARGS}
  831. cluster/kubectl.sh config set-context local --cluster=local --user=myself
  832. cluster/kubectl.sh config use-context local
  833. cluster/kubectl.sh
  834. EOF
  835. else
  836. cat <<EOF
  837. The kubelet was started.
  838. Logs:
  839. ${KUBELET_LOG}
  840. EOF
  841. fi
  842. }
  843. # If we are running in the CI, we need a few more things before we can start
  844. if [[ "${KUBETEST_IN_DOCKER:-}" == "true" ]]; then
  845. echo "Preparing to test ..."
  846. "${KUBE_ROOT}"/hack/install-etcd.sh
  847. export PATH="${KUBE_ROOT}/third_party/etcd:${PATH}"
  848. KUBE_FASTBUILD=true make ginkgo cross
  849. apt-get update && apt-get install -y sudo
  850. apt-get remove -y systemd
  851. # configure shared mounts to prevent failure in DIND scenarios
  852. mount --make-rshared /
  853. # kubekins has a special directory for docker root
  854. DOCKER_ROOT="/docker-graph"
  855. fi
  856. # validate that etcd is: not running, in path, and has minimum required version.
  857. if [[ "${START_MODE}" != "kubeletonly" ]]; then
  858. kube::etcd::validate
  859. fi
  860. if [ "${CONTAINER_RUNTIME}" == "docker" ] && ! kube::util::ensure_docker_daemon_connectivity; then
  861. exit 1
  862. fi
  863. if [[ "${START_MODE}" != "kubeletonly" ]]; then
  864. test_apiserver_off
  865. fi
  866. kube::util::test_openssl_installed
  867. kube::util::ensure-cfssl
  868. ### IF the user didn't supply an output/ for the build... Then we detect.
  869. if [ "${GO_OUT}" == "" ]; then
  870. detect_binary
  871. fi
  872. echo "Detected host and ready to start services. Doing some housekeeping first..."
  873. echo "Using GO_OUT ${GO_OUT}"
  874. export KUBELET_CIDFILE=/tmp/kubelet.cid
  875. if [[ "${ENABLE_DAEMON}" = false ]]; then
  876. trap cleanup EXIT
  877. fi
  878. echo "Starting services now!"
  879. if [[ "${START_MODE}" != "kubeletonly" ]]; then
  880. start_etcd
  881. set_service_accounts
  882. start_apiserver
  883. start_controller_manager
  884. if [[ "${EXTERNAL_CLOUD_PROVIDER:-}" == "true" ]]; then
  885. start_cloud_controller_manager
  886. fi
  887. if [[ "${START_MODE}" != "nokubeproxy" ]]; then
  888. start_kubeproxy
  889. fi
  890. start_kubescheduler
  891. start_kubedns
  892. if [[ "${ENABLE_NODELOCAL_DNS:-}" == "true" ]]; then
  893. start_nodelocaldns
  894. fi
  895. start_kubedashboard
  896. fi
  897. if [[ "${START_MODE}" != "nokubelet" ]]; then
  898. ## TODO remove this check if/when kubelet is supported on darwin
  899. # Detect the OS name/arch and display appropriate error.
  900. case "$(uname -s)" in
  901. Darwin)
  902. print_color "kubelet is not currently supported in darwin, kubelet aborted."
  903. KUBELET_LOG=""
  904. ;;
  905. Linux)
  906. start_kubelet
  907. ;;
  908. *)
  909. print_color "Unsupported host OS. Must be Linux or Mac OS X, kubelet aborted."
  910. ;;
  911. esac
  912. fi
  913. if [[ -n "${PSP_ADMISSION}" && "${AUTHORIZATION_MODE}" = *RBAC* ]]; then
  914. create_psp_policy
  915. fi
  916. if [[ "${DEFAULT_STORAGE_CLASS}" = "true" ]]; then
  917. create_storage_class
  918. fi
  919. print_success
  920. if [[ "${ENABLE_DAEMON}" = false ]]; then
  921. while true; do sleep 1; healthcheck; done
  922. fi
  923. if [[ "${KUBETEST_IN_DOCKER:-}" == "true" ]]; then
  924. cluster/kubectl.sh config set-cluster local --server=https://localhost:6443 --certificate-authority=/var/run/kubernetes/server-ca.crt
  925. cluster/kubectl.sh config set-credentials myself --client-key=/var/run/kubernetes/client-admin.key --client-certificate=/var/run/kubernetes/client-admin.crt
  926. cluster/kubectl.sh config set-context local --cluster=local --user=myself
  927. cluster/kubectl.sh config use-context local
  928. fi