start-kubemark-master.sh 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780
  1. #!/usr/bin/env bash
  2. # Copyright 2015 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. # Script that starts kubelet on kubemark-master as a supervisord process
  16. # and then runs the master components as pods using kubelet.
  17. set -o errexit
  18. set -o nounset
  19. set -o pipefail
  20. # Define key path variables.
  21. KUBE_ROOT="/home/kubernetes"
  22. KUBE_BINDIR="${KUBE_ROOT}/kubernetes/server/bin"
  23. function config-ip-firewall {
  24. echo "Configuring IP firewall rules"
  25. # The GCI image has host firewall which drop most inbound/forwarded packets.
  26. # We need to add rules to accept all TCP/UDP/ICMP packets.
  27. if iptables -L INPUT | grep "Chain INPUT (policy DROP)" > /dev/null; then
  28. echo "Add rules to accept all inbound TCP/UDP/ICMP packets"
  29. iptables -A INPUT -w -p TCP -j ACCEPT
  30. iptables -A INPUT -w -p UDP -j ACCEPT
  31. iptables -A INPUT -w -p ICMP -j ACCEPT
  32. fi
  33. if iptables -L FORWARD | grep "Chain FORWARD (policy DROP)" > /dev/null; then
  34. echo "Add rules to accept all forwarded TCP/UDP/ICMP packets"
  35. iptables -A FORWARD -w -p TCP -j ACCEPT
  36. iptables -A FORWARD -w -p UDP -j ACCEPT
  37. iptables -A FORWARD -w -p ICMP -j ACCEPT
  38. fi
  39. }
  40. function create-dirs {
  41. echo "Creating required directories"
  42. mkdir -p /var/lib/kubelet
  43. mkdir -p /etc/kubernetes/manifests
  44. mkdir -p /etc/kubernetes/addons
  45. }
  46. # Setup working directory for kubelet.
  47. function setup-kubelet-dir {
  48. echo "Making /var/lib/kubelet executable for kubelet"
  49. mount -B /var/lib/kubelet /var/lib/kubelet/
  50. mount -B -o remount,exec,suid,dev /var/lib/kubelet
  51. }
  52. # Remove any default etcd config dirs/files.
  53. function delete-default-etcd-configs {
  54. if [[ -d /etc/etcd ]]; then
  55. rm -rf /etc/etcd
  56. fi
  57. if [[ -e /etc/default/etcd ]]; then
  58. rm -f /etc/default/etcd
  59. fi
  60. if [[ -e /etc/systemd/system/etcd.service ]]; then
  61. rm -f /etc/systemd/system/etcd.service
  62. fi
  63. if [[ -e /etc/init.d/etcd ]]; then
  64. rm -f /etc/init.d/etcd
  65. fi
  66. }
  67. # Compute etcd related variables.
  68. function compute-etcd-variables {
  69. ETCD_IMAGE="${ETCD_IMAGE:-}"
  70. ETCD_QUOTA_BYTES=""
  71. if [ "${ETCD_VERSION:0:2}" == "3." ]; then
  72. # TODO: Set larger quota to see if that helps with
  73. # 'mvcc: database space exceeded' errors. If so, pipe
  74. # though our setup scripts.
  75. ETCD_QUOTA_BYTES=" --quota-backend-bytes=4294967296 "
  76. fi
  77. }
  78. # Formats the given device ($1) if needed and mounts it at given mount point
  79. # ($2).
  80. function safe-format-and-mount() {
  81. device=$1
  82. mountpoint=$2
  83. # Format only if the disk is not already formatted.
  84. if ! tune2fs -l "${device}" ; then
  85. echo "Formatting '${device}'"
  86. mkfs.ext4 -F "${device}"
  87. fi
  88. echo "Mounting '${device}' at '${mountpoint}'"
  89. mount -o discard,defaults "${device}" "${mountpoint}"
  90. }
  91. # Finds a PD device with name '$1' attached to the master.
  92. function find-attached-pd() {
  93. local -r pd_name=$1
  94. if [[ ! -e /dev/disk/by-id/${pd_name} ]]; then
  95. echo ""
  96. fi
  97. device_info=$(ls -l "/dev/disk/by-id/${pd_name}")
  98. relative_path=${device_info##* }
  99. echo "/dev/disk/by-id/${relative_path}"
  100. }
  101. # Mounts a persistent disk (formatting if needed) to store the persistent data
  102. # on the master. safe-format-and-mount only formats an unformatted disk, and
  103. # mkdir -p will leave a directory be if it already exists.
  104. function mount-pd() {
  105. local -r pd_name=$1
  106. local -r mount_point=$2
  107. if [[ -z "${find-attached-pd ${pd_name}}" ]]; then
  108. echo "Can't find ${pd_name}. Skipping mount."
  109. return
  110. fi
  111. local -r pd_path="/dev/disk/by-id/${pd_name}"
  112. echo "Mounting PD '${pd_path}' at '${mount_point}'"
  113. # Format and mount the disk, create directories on it for all of the master's
  114. # persistent data, and link them to where they're used.
  115. mkdir -p "${mount_point}"
  116. safe-format-and-mount "${pd_path}" "${mount_point}"
  117. echo "Mounted PD '${pd_path}' at '${mount_point}'"
  118. # NOTE: These locations on the PD store persistent data, so to maintain
  119. # upgradeability, these locations should not change. If they do, take care
  120. # to maintain a migration path from these locations to whatever new
  121. # locations.
  122. }
  123. # Create kubeconfig for controller-manager's service account authentication.
  124. function create-kubecontrollermanager-kubeconfig {
  125. echo "Creating kube-controller-manager kubeconfig file"
  126. mkdir -p "${KUBE_ROOT}/k8s_auth_data/kube-controller-manager"
  127. cat <<EOF >"${KUBE_ROOT}/k8s_auth_data/kube-controller-manager/kubeconfig"
  128. apiVersion: v1
  129. kind: Config
  130. users:
  131. - name: kube-controller-manager
  132. user:
  133. token: ${KUBE_CONTROLLER_MANAGER_TOKEN}
  134. clusters:
  135. - name: local
  136. cluster:
  137. insecure-skip-tls-verify: true
  138. server: https://localhost:443
  139. contexts:
  140. - context:
  141. cluster: local
  142. user: kube-controller-manager
  143. name: service-account-context
  144. current-context: service-account-context
  145. EOF
  146. }
  147. function create-kubescheduler-kubeconfig {
  148. echo "Creating kube-scheduler kubeconfig file"
  149. mkdir -p "${KUBE_ROOT}/k8s_auth_data/kube-scheduler"
  150. cat <<EOF >"${KUBE_ROOT}/k8s_auth_data/kube-scheduler/kubeconfig"
  151. apiVersion: v1
  152. kind: Config
  153. users:
  154. - name: kube-scheduler
  155. user:
  156. token: ${KUBE_SCHEDULER_TOKEN}
  157. clusters:
  158. - name: local
  159. cluster:
  160. insecure-skip-tls-verify: true
  161. server: https://localhost:443
  162. contexts:
  163. - context:
  164. cluster: local
  165. user: kube-scheduler
  166. name: kube-scheduler
  167. current-context: kube-scheduler
  168. EOF
  169. }
  170. function create-addonmanager-kubeconfig {
  171. echo "Creating addonmanager kubeconfig file"
  172. mkdir -p "${KUBE_ROOT}/k8s_auth_data/addon-manager"
  173. cat <<EOF >"${KUBE_ROOT}/k8s_auth_data/addon-manager/kubeconfig"
  174. apiVersion: v1
  175. kind: Config
  176. users:
  177. - name: addon-manager
  178. user:
  179. token: ${ADDON_MANAGER_TOKEN}
  180. clusters:
  181. - name: local
  182. cluster:
  183. insecure-skip-tls-verify: true
  184. server: https://localhost:443
  185. contexts:
  186. - context:
  187. cluster: local
  188. user: addon-manager
  189. name: addon-manager
  190. current-context: addon-manager
  191. EOF
  192. }
  193. function assemble-docker-flags {
  194. echo "Assemble docker command line flags"
  195. local docker_opts="-p /var/run/docker.pid --iptables=false --ip-masq=false"
  196. docker_opts+=" --log-level=debug" # Since it's a test cluster
  197. # TODO(shyamjvs): Incorporate network plugin options, etc later.
  198. echo "DOCKER_OPTS=\"${docker_opts}\"" > /etc/default/docker
  199. echo "DOCKER_NOFILE=65536" >> /etc/default/docker # For setting ulimit -n
  200. systemctl restart docker
  201. }
  202. # A helper function for loading a docker image. It keeps trying up to 5 times.
  203. #
  204. # $1: Full path of the docker image
  205. function try-load-docker-image {
  206. local -r img=$1
  207. echo "Try to load docker image file ${img}"
  208. # Temporarily turn off errexit, because we don't want to exit on first failure.
  209. set +e
  210. local -r max_attempts=5
  211. local -i attempt_num=1
  212. until timeout 30 docker load -i "${img}"; do
  213. if [[ "${attempt_num}" == "${max_attempts}" ]]; then
  214. echo "Fail to load docker image file ${img} after ${max_attempts} retries. Exit!!"
  215. exit 1
  216. else
  217. attempt_num=$((attempt_num+1))
  218. sleep 5
  219. fi
  220. done
  221. # Re-enable errexit.
  222. set -e
  223. }
  224. # Loads kube-system docker images. It is better to do it before starting kubelet,
  225. # as kubelet will restart docker daemon, which may interfere with loading images.
  226. function load-docker-images {
  227. echo "Start loading kube-system docker images"
  228. local -r img_dir="${KUBE_BINDIR}"
  229. try-load-docker-image "${img_dir}/kube-apiserver.tar"
  230. try-load-docker-image "${img_dir}/kube-controller-manager.tar"
  231. try-load-docker-image "${img_dir}/kube-scheduler.tar"
  232. }
  233. # Computes command line arguments to be passed to kubelet.
  234. function compute-kubelet-params {
  235. local params="${KUBELET_TEST_ARGS:-}"
  236. params+=" --cgroup-root=/"
  237. params+=" --cloud-provider=gce"
  238. params+=" --pod-manifest-path=/etc/kubernetes/manifests"
  239. if [[ -n "${KUBELET_PORT:-}" ]]; then
  240. params+=" --port=${KUBELET_PORT}"
  241. fi
  242. params+=" --enable-debugging-handlers=false"
  243. params+=" --hairpin-mode=none"
  244. echo "${params}"
  245. }
  246. # Creates the systemd config file for kubelet.service.
  247. function create-kubelet-conf() {
  248. local -r kubelet_bin="$1"
  249. local -r kubelet_env_file="/etc/default/kubelet"
  250. local -r flags=$(compute-kubelet-params)
  251. echo "KUBELET_OPTS=\"${flags}\"" > "${kubelet_env_file}"
  252. # Write the systemd service file for kubelet.
  253. cat <<EOF >/etc/systemd/system/kubelet.service
  254. [Unit]
  255. Description=Kubermark kubelet
  256. Requires=network-online.target
  257. After=network-online.target
  258. [Service]
  259. Restart=always
  260. RestartSec=10
  261. EnvironmentFile=${kubelet_env_file}
  262. ExecStart=${kubelet_bin} \$KUBELET_OPTS
  263. [Install]
  264. WantedBy=multi-user.target
  265. EOF
  266. }
  267. # This function assembles the kubelet systemd service file and starts it using
  268. # systemctl, on the kubemark master.
  269. function start-kubelet {
  270. # Create systemd config.
  271. local -r kubelet_bin="/usr/bin/kubelet"
  272. create-kubelet-conf "${kubelet_bin}"
  273. # Flush iptables nat table
  274. iptables -t nat -F || true
  275. # Start the kubelet service.
  276. systemctl start kubelet.service
  277. }
  278. # Create the log file and set its properties.
  279. #
  280. # $1 is the file to create.
  281. function prepare-log-file {
  282. touch "$1"
  283. chmod 644 "$1"
  284. chown root:root "$1"
  285. }
  286. # A helper function for copying addon manifests and set dir/files
  287. # permissions.
  288. #
  289. # $1: addon category under /etc/kubernetes
  290. # $2: manifest source dir
  291. function setup-addon-manifests {
  292. local -r src_dir="${KUBE_ROOT}/$2"
  293. local -r dst_dir="/etc/kubernetes/$1/$2"
  294. if [[ ! -d "${dst_dir}" ]]; then
  295. mkdir -p "${dst_dir}"
  296. fi
  297. local files
  298. files=$(find "${src_dir}" -maxdepth 1 -name "*.yaml")
  299. if [[ -n "${files}" ]]; then
  300. cp "${src_dir}/"*.yaml "${dst_dir}"
  301. fi
  302. chown -R root:root "${dst_dir}"
  303. chmod 755 "${dst_dir}"
  304. chmod 644 "${dst_dir}"/*
  305. }
  306. # Write the config for the audit policy.
  307. # Note: This duplicates the function in cluster/gce/gci/configure-helper.sh.
  308. # TODO: Get rid of this function when #53321 is fixed.
  309. function create-master-audit-policy {
  310. local -r path="${1}"
  311. local -r policy="${2:-}"
  312. if [[ -n "${policy}" ]]; then
  313. echo "${policy}" > "${path}"
  314. return
  315. fi
  316. # Known api groups
  317. local -r known_apis='
  318. - group: "" # core
  319. - group: "admissionregistration.k8s.io"
  320. - group: "apiextensions.k8s.io"
  321. - group: "apiregistration.k8s.io"
  322. - group: "apps"
  323. - group: "authentication.k8s.io"
  324. - group: "authorization.k8s.io"
  325. - group: "autoscaling"
  326. - group: "batch"
  327. - group: "certificates.k8s.io"
  328. - group: "extensions"
  329. - group: "metrics"
  330. - group: "networking.k8s.io"
  331. - group: "policy"
  332. - group: "rbac.authorization.k8s.io"
  333. - group: "settings.k8s.io"
  334. - group: "storage.k8s.io"'
  335. cat <<EOF >"${path}"
  336. apiVersion: audit.k8s.io/v1
  337. kind: Policy
  338. rules:
  339. # The following requests were manually identified as high-volume and low-risk,
  340. # so drop them.
  341. - level: None
  342. users: ["system:kube-proxy"]
  343. verbs: ["watch"]
  344. resources:
  345. - group: "" # core
  346. resources: ["endpoints", "services", "services/status"]
  347. - level: None
  348. # Ingress controller reads 'configmaps/ingress-uid' through the unsecured port.
  349. # TODO(#46983): Change this to the ingress controller service account.
  350. users: ["system:unsecured"]
  351. namespaces: ["kube-system"]
  352. verbs: ["get"]
  353. resources:
  354. - group: "" # core
  355. resources: ["configmaps"]
  356. - level: None
  357. users: ["kubelet"] # legacy kubelet identity
  358. verbs: ["get"]
  359. resources:
  360. - group: "" # core
  361. resources: ["nodes", "nodes/status"]
  362. - level: None
  363. userGroups: ["system:nodes"]
  364. verbs: ["get"]
  365. resources:
  366. - group: "" # core
  367. resources: ["nodes", "nodes/status"]
  368. - level: None
  369. users:
  370. - system:kube-controller-manager
  371. - system:kube-scheduler
  372. - system:serviceaccount:kube-system:endpoint-controller
  373. verbs: ["get", "update"]
  374. namespaces: ["kube-system"]
  375. resources:
  376. - group: "" # core
  377. resources: ["endpoints"]
  378. - level: None
  379. users: ["system:apiserver"]
  380. verbs: ["get"]
  381. resources:
  382. - group: "" # core
  383. resources: ["namespaces", "namespaces/status", "namespaces/finalize"]
  384. # Don't log HPA fetching metrics.
  385. - level: None
  386. users:
  387. - system:kube-controller-manager
  388. verbs: ["get", "list"]
  389. resources:
  390. - group: "metrics"
  391. # Don't log these read-only URLs.
  392. - level: None
  393. nonResourceURLs:
  394. - /healthz*
  395. - /version
  396. - /swagger*
  397. # Don't log events requests.
  398. - level: None
  399. resources:
  400. - group: "" # core
  401. resources: ["events"]
  402. # node and pod status calls from nodes are high-volume and can be large, don't log responses for expected updates from nodes
  403. - level: Request
  404. users: ["kubelet", "system:node-problem-detector", "system:serviceaccount:kube-system:node-problem-detector"]
  405. verbs: ["update","patch"]
  406. resources:
  407. - group: "" # core
  408. resources: ["nodes/status", "pods/status"]
  409. omitStages:
  410. - "RequestReceived"
  411. - level: Request
  412. userGroups: ["system:nodes"]
  413. verbs: ["update","patch"]
  414. resources:
  415. - group: "" # core
  416. resources: ["nodes/status", "pods/status"]
  417. omitStages:
  418. - "RequestReceived"
  419. # deletecollection calls can be large, don't log responses for expected namespace deletions
  420. - level: Request
  421. users: ["system:serviceaccount:kube-system:namespace-controller"]
  422. verbs: ["deletecollection"]
  423. omitStages:
  424. - "RequestReceived"
  425. # Secrets, ConfigMaps, and TokenReviews can contain sensitive & binary data,
  426. # so only log at the Metadata level.
  427. - level: Metadata
  428. resources:
  429. - group: "" # core
  430. resources: ["secrets", "configmaps"]
  431. - group: authentication.k8s.io
  432. resources: ["tokenreviews"]
  433. omitStages:
  434. - "RequestReceived"
  435. # Get repsonses can be large; skip them.
  436. - level: Request
  437. verbs: ["get", "list", "watch"]
  438. resources: ${known_apis}
  439. omitStages:
  440. - "RequestReceived"
  441. # Default level for known APIs
  442. - level: RequestResponse
  443. resources: ${known_apis}
  444. omitStages:
  445. - "RequestReceived"
  446. # Default level for all other requests.
  447. - level: Metadata
  448. omitStages:
  449. - "RequestReceived"
  450. EOF
  451. }
  452. # Computes command line arguments to be passed to etcd.
  453. function compute-etcd-params {
  454. local params="${ETCD_TEST_ARGS:-}"
  455. params+=" --name=etcd-$(hostname -s)"
  456. params+=" --listen-peer-urls=http://127.0.0.1:2380"
  457. params+=" --advertise-client-urls=http://127.0.0.1:2379"
  458. params+=" --listen-client-urls=http://0.0.0.0:2379"
  459. # Enable apiserver->etcd auth.
  460. params+=" --client-cert-auth"
  461. params+=" --trusted-ca-file /etc/srv/kubernetes/etcd-apiserver-ca.crt"
  462. params+=" --cert-file /etc/srv/kubernetes/etcd-apiserver-server.crt"
  463. params+=" --key-file /etc/srv/kubernetes/etcd-apiserver-server.key"
  464. params+=" --data-dir=/var/etcd/data"
  465. params+=" ${ETCD_QUOTA_BYTES}"
  466. echo "${params}"
  467. }
  468. # Computes command line arguments to be passed to etcd-events.
  469. function compute-etcd-events-params {
  470. local params="${ETCD_TEST_ARGS:-}"
  471. params+=" --name=etcd-$(hostname -s)"
  472. params+=" --listen-peer-urls=http://127.0.0.1:2381"
  473. params+=" --advertise-client-urls=http://127.0.0.1:4002"
  474. params+=" --listen-client-urls=http://0.0.0.0:4002"
  475. params+=" --data-dir=/var/etcd/data-events"
  476. params+=" ${ETCD_QUOTA_BYTES}"
  477. echo "${params}"
  478. }
  479. # Computes command line arguments to be passed to apiserver.
  480. function compute-kube-apiserver-params {
  481. local params="--insecure-bind-address=0.0.0.0"
  482. params+=" --etcd-servers=${ETCD_SERVERS:-http://127.0.0.1:2379}"
  483. if [[ -z "${ETCD_SERVERS:-}" ]]; then
  484. params+=" --etcd-servers-overrides=${ETCD_SERVERS_OVERRIDES:-/events#${EVENT_STORE_URL}}"
  485. elif [[ -n "${ETCD_SERVERS_OVERRIDES:-}" ]]; then
  486. params+=" --etcd-servers-overrides=${ETCD_SERVERS_OVERRIDES:-}"
  487. fi
  488. # Enable apiserver->etcd auth.
  489. params+=" --etcd-cafile=/etc/srv/kubernetes/etcd-apiserver-ca.crt"
  490. params+=" --etcd-certfile=/etc/srv/kubernetes/etcd-apiserver-client.crt"
  491. params+=" --etcd-keyfile=/etc/srv/kubernetes/etcd-apiserver-client.key"
  492. params+=" --tls-cert-file=/etc/srv/kubernetes/server.cert"
  493. params+=" --tls-private-key-file=/etc/srv/kubernetes/server.key"
  494. params+=" --requestheader-client-ca-file=/etc/srv/kubernetes/aggr_ca.crt"
  495. params+=" --requestheader-allowed-names=aggregator"
  496. params+=" --requestheader-extra-headers-prefix=X-Remote-Extra-"
  497. params+=" --requestheader-group-headers=X-Remote-Group"
  498. params+=" --requestheader-username-headers=X-Remote-User"
  499. params+=" --proxy-client-cert-file=/etc/srv/kubernetes/proxy_client.crt"
  500. params+=" --proxy-client-key-file=/etc/srv/kubernetes/proxy_client.key"
  501. params+=" --enable-aggregator-routing=true"
  502. params+=" --client-ca-file=/etc/srv/kubernetes/ca.crt"
  503. params+=" --token-auth-file=/etc/srv/kubernetes/known_tokens.csv"
  504. params+=" --secure-port=443"
  505. params+=" --basic-auth-file=/etc/srv/kubernetes/basic_auth.csv"
  506. params+=" --target-ram-mb=$((NUM_NODES * 60))"
  507. params+=" --service-cluster-ip-range=${SERVICE_CLUSTER_IP_RANGE}"
  508. params+=" --admission-control=${CUSTOM_ADMISSION_PLUGINS}"
  509. params+=" --authorization-mode=Node,RBAC"
  510. params+=" --allow-privileged=true"
  511. if [[ -n "${STORAGE_BACKEND:-}" ]]; then
  512. params+=" --storage-backend=${STORAGE_BACKEND}"
  513. fi
  514. if [[ -n "${STORAGE_MEDIA_TYPE:-}" ]]; then
  515. params+=" --storage-media-type=${STORAGE_MEDIA_TYPE}"
  516. fi
  517. if [[ -n "${ETCD_COMPACTION_INTERVAL_SEC:-}" ]]; then
  518. params+=" --etcd-compaction-interval=${ETCD_COMPACTION_INTERVAL_SEC}s"
  519. fi
  520. if [[ -n "${KUBE_APISERVER_REQUEST_TIMEOUT:-}" ]]; then
  521. params+=" --min-request-timeout=${KUBE_APISERVER_REQUEST_TIMEOUT}"
  522. fi
  523. if [[ "${NUM_NODES}" -ge 3000 ]]; then
  524. params+=" --max-requests-inflight=3000 --max-mutating-requests-inflight=1000"
  525. elif [[ "${NUM_NODES}" -ge 1000 ]]; then
  526. params+=" --max-requests-inflight=1500 --max-mutating-requests-inflight=500"
  527. fi
  528. if [[ -n "${RUNTIME_CONFIG:-}" ]]; then
  529. params+=" --runtime-config=${RUNTIME_CONFIG}"
  530. fi
  531. if [[ -n "${FEATURE_GATES:-}" ]]; then
  532. params+=" --feature-gates=${FEATURE_GATES}"
  533. fi
  534. if [[ "${ENABLE_APISERVER_ADVANCED_AUDIT:-}" == "true" ]]; then
  535. # Create the audit policy file, and mount it into the apiserver pod.
  536. create-master-audit-policy "${audit_policy_file}" "${ADVANCED_AUDIT_POLICY:-}"
  537. # The config below matches the one in cluster/gce/gci/configure-helper.sh.
  538. # TODO: Currently supporting just log backend. Support webhook if needed.
  539. params+=" --audit-policy-file=${audit_policy_file}"
  540. params+=" --audit-log-path=/var/log/kube-apiserver-audit.log"
  541. params+=" --audit-log-maxage=0"
  542. params+=" --audit-log-maxbackup=0"
  543. params+=" --audit-log-maxsize=2000000000"
  544. fi
  545. # Append APISERVER_TEST_ARGS to the end, which will allow for
  546. # the above defaults to be overridden.
  547. params+=" ${APISERVER_TEST_ARGS:-}"
  548. echo "${params}"
  549. }
  550. # Computes command line arguments to be passed to controller-manager.
  551. function compute-kube-controller-manager-params {
  552. local params="${CONTROLLER_MANAGER_TEST_ARGS:-}"
  553. params+=" --use-service-account-credentials"
  554. params+=" --kubeconfig=/etc/srv/kubernetes/kube-controller-manager/kubeconfig"
  555. params+=" --service-account-private-key-file=/etc/srv/kubernetes/server.key"
  556. params+=" --root-ca-file=/etc/srv/kubernetes/ca.crt"
  557. params+=" --allocate-node-cidrs=${ALLOCATE_NODE_CIDRS}"
  558. params+=" --cluster-cidr=${CLUSTER_IP_RANGE}"
  559. params+=" --service-cluster-ip-range=${SERVICE_CLUSTER_IP_RANGE}"
  560. params+=" --terminated-pod-gc-threshold=${TERMINATED_POD_GC_THRESHOLD}"
  561. echo "${params}"
  562. }
  563. # Computes command line arguments to be passed to scheduler.
  564. function compute-kube-scheduler-params {
  565. local params="${SCHEDULER_TEST_ARGS:-}"
  566. params+=" --kubeconfig=/etc/srv/kubernetes/kube-scheduler/kubeconfig"
  567. echo "${params}"
  568. }
  569. # Computes command line arguments to be passed to addon-manager.
  570. function compute-kube-addon-manager-params {
  571. echo ""
  572. }
  573. # Start a kubernetes master component '$1' which can be any of the following:
  574. # 1. etcd
  575. # 2. etcd-events
  576. # 3. kube-apiserver
  577. # 4. kube-controller-manager
  578. # 5. kube-scheduler
  579. # 6. kube-addon-manager
  580. #
  581. # It prepares the log file, loads the docker tag, calculates variables, sets them
  582. # in the manifest file, and then copies the manifest file to /etc/kubernetes/manifests.
  583. #
  584. # Assumed vars:
  585. # DOCKER_REGISTRY
  586. function start-kubemaster-component() {
  587. echo "Start master component $1"
  588. local -r component=$1
  589. prepare-log-file /var/log/"${component}".log
  590. local -r src_file="${KUBE_ROOT}/${component}.yaml"
  591. local -r params=$("compute-${component}-params")
  592. # Evaluate variables.
  593. sed -i -e "s@{{params}}@${params}@g" "${src_file}"
  594. sed -i -e "s@{{kube_docker_registry}}@${DOCKER_REGISTRY}@g" "${src_file}"
  595. sed -i -e "s@{{instance_prefix}}@${INSTANCE_PREFIX}@g" "${src_file}"
  596. if [ "${component:0:4}" == "etcd" ]; then
  597. sed -i -e "s@{{etcd_image}}@${ETCD_IMAGE}@g" "${src_file}"
  598. elif [ "${component}" == "kube-addon-manager" ]; then
  599. setup-addon-manifests "addons" "kubemark-rbac-bindings"
  600. else
  601. local -r component_docker_tag=$(cat "${KUBE_BINDIR}/${component}.docker_tag")
  602. sed -i -e "s@{{${component}_docker_tag}}@${component_docker_tag}@g" "${src_file}"
  603. if [ "${component}" == "kube-apiserver" ]; then
  604. local audit_policy_config_mount=""
  605. local audit_policy_config_volume=""
  606. if [[ "${ENABLE_APISERVER_ADVANCED_AUDIT:-}" == "true" ]]; then
  607. read -r -d '' audit_policy_config_mount << EOF
  608. - name: auditpolicyconfigmount
  609. mountPath: ${audit_policy_file}
  610. readOnly: true
  611. EOF
  612. read -r -d '' audit_policy_config_volume << EOF
  613. - name: auditpolicyconfigmount
  614. hostPath:
  615. path: ${audit_policy_file}
  616. type: FileOrCreate
  617. EOF
  618. fi
  619. sed -i -e "s@{{audit_policy_config_mount}}@${audit_policy_config_mount}@g" "${src_file}"
  620. sed -i -e "s@{{audit_policy_config_volume}}@${audit_policy_config_volume}@g" "${src_file}"
  621. fi
  622. fi
  623. cp "${src_file}" /etc/kubernetes/manifests
  624. }
  625. ############################### Main Function ########################################
  626. echo "Start to configure master instance for kubemark"
  627. # Extract files from the server tar and setup master env variables.
  628. cd "${KUBE_ROOT}"
  629. if [[ ! -d "${KUBE_ROOT}/kubernetes" ]]; then
  630. tar xzf kubernetes-server-linux-amd64.tar.gz
  631. fi
  632. source "${KUBE_ROOT}/kubemark-master-env.sh"
  633. # Setup IP firewall rules, required directory structure and etcd config.
  634. config-ip-firewall
  635. create-dirs
  636. setup-kubelet-dir
  637. delete-default-etcd-configs
  638. compute-etcd-variables
  639. # Setup authentication tokens and kubeconfigs for kube-controller-manager and kube-scheduler,
  640. # only if their kubeconfigs don't already exist as this script could be running on reboot.
  641. if [[ ! -f "${KUBE_ROOT}/k8s_auth_data/kube-controller-manager/kubeconfig" ]]; then
  642. KUBE_CONTROLLER_MANAGER_TOKEN=$(dd if=/dev/urandom bs=128 count=1 2>/dev/null | base64 | tr -d "=+/" | dd bs=32 count=1 2>/dev/null)
  643. echo "${KUBE_CONTROLLER_MANAGER_TOKEN},system:kube-controller-manager,uid:system:kube-controller-manager" >> "${KUBE_ROOT}/k8s_auth_data/known_tokens.csv"
  644. create-kubecontrollermanager-kubeconfig
  645. fi
  646. if [[ ! -f "${KUBE_ROOT}/k8s_auth_data/kube-scheduler/kubeconfig" ]]; then
  647. KUBE_SCHEDULER_TOKEN=$(dd if=/dev/urandom bs=128 count=1 2>/dev/null | base64 | tr -d "=+/" | dd bs=32 count=1 2>/dev/null)
  648. echo "${KUBE_SCHEDULER_TOKEN},system:kube-scheduler,uid:system:kube-scheduler" >> "${KUBE_ROOT}/k8s_auth_data/known_tokens.csv"
  649. create-kubescheduler-kubeconfig
  650. fi
  651. ADDON_MANAGER_TOKEN=$(dd if=/dev/urandom bs=128 count=1 2>/dev/null | base64 | tr -d "=+/" | dd bs=32 count=1 2>/dev/null)
  652. echo "${ADDON_MANAGER_TOKEN},system:addon-manager,admin,system:masters" >> "${KUBE_ROOT}/k8s_auth_data/known_tokens.csv"
  653. create-addonmanager-kubeconfig
  654. # Mount master PD for etcd and create symbolic links to it.
  655. {
  656. main_etcd_mount_point="/mnt/disks/master-pd"
  657. mount-pd "google-master-pd" "${main_etcd_mount_point}"
  658. # Contains all the data stored in etcd.
  659. mkdir -p "${main_etcd_mount_point}/var/etcd"
  660. chmod 700 "${main_etcd_mount_point}/var/etcd"
  661. ln -s -f "${main_etcd_mount_point}/var/etcd" /var/etcd
  662. mkdir -p /etc/srv
  663. # Setup the dynamically generated apiserver auth certs and keys to pd.
  664. mkdir -p "${main_etcd_mount_point}/srv/kubernetes"
  665. ln -s -f "${main_etcd_mount_point}/srv/kubernetes" /etc/srv/kubernetes
  666. # Copy the files to the PD only if they don't exist (so we do it only the first time).
  667. if [[ "$(ls -A ${main_etcd_mount_point}/srv/kubernetes/)" == "" ]]; then
  668. cp -r "${KUBE_ROOT}"/k8s_auth_data/* "${main_etcd_mount_point}/srv/kubernetes/"
  669. fi
  670. # Directory for kube-apiserver to store SSH key (if necessary).
  671. mkdir -p "${main_etcd_mount_point}/srv/sshproxy"
  672. ln -s -f "${main_etcd_mount_point}/srv/sshproxy" /etc/srv/sshproxy
  673. }
  674. # Mount master PD for event-etcd (if required) and create symbolic links to it.
  675. {
  676. EVENT_STORE_IP="${EVENT_STORE_IP:-127.0.0.1}"
  677. EVENT_STORE_URL="${EVENT_STORE_URL:-http://${EVENT_STORE_IP}:4002}"
  678. if [ "${EVENT_PD:-}" == "true" ]; then
  679. event_etcd_mount_point="/mnt/disks/master-event-pd"
  680. mount-pd "google-master-event-pd" "${event_etcd_mount_point}"
  681. # Contains all the data stored in event etcd.
  682. mkdir -p "${event_etcd_mount_point}/var/etcd/events"
  683. chmod 700 "${event_etcd_mount_point}/var/etcd/events"
  684. ln -s -f "${event_etcd_mount_point}/var/etcd/events" /var/etcd/events
  685. fi
  686. }
  687. # Setup docker flags and load images of the master components.
  688. assemble-docker-flags
  689. DOCKER_REGISTRY="k8s.gcr.io"
  690. load-docker-images
  691. readonly audit_policy_file="/etc/audit_policy.config"
  692. # Start kubelet as a supervisord process and master components as pods.
  693. start-kubelet
  694. if [[ -z "${ETCD_SERVERS:-}" ]]; then
  695. start-kubemaster-component "etcd"
  696. if [ "${EVENT_STORE_IP:-}" == "127.0.0.1" ]; then
  697. start-kubemaster-component "etcd-events"
  698. fi
  699. fi
  700. start-kubemaster-component "kube-apiserver"
  701. start-kubemaster-component "kube-controller-manager"
  702. start-kubemaster-component "kube-scheduler"
  703. start-kubemaster-component "kube-addon-manager"
  704. # Wait till apiserver is working fine or timeout.
  705. echo -n "Waiting for apiserver to be healthy"
  706. start=$(date +%s)
  707. until [ "$(curl 127.0.0.1:8080/healthz 2> /dev/null)" == "ok" ]; do
  708. echo -n "."
  709. sleep 1
  710. now=$(date +%s)
  711. if [ $((now - start)) -gt 300 ]; then
  712. echo "Timeout!"
  713. exit 1
  714. fi
  715. done
  716. echo "Done for the configuration for kubermark master"