configure-kubeapiserver.sh 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  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. # Configures etcd related flags of kube-apiserver.
  16. function configure-etcd-params {
  17. local -n params_ref=$1
  18. if [[ -n "${ETCD_APISERVER_CA_KEY:-}" && -n "${ETCD_APISERVER_CA_CERT:-}" && -n "${ETCD_APISERVER_SERVER_KEY:-}" && -n "${ETCD_APISERVER_SERVER_CERT:-}" && -n "${ETCD_APISERVER_CLIENT_KEY:-}" && -n "${ETCD_APISERVER_CLIENT_CERT:-}" ]]; then
  19. params_ref+=" --etcd-servers=${ETCD_SERVERS:-https://127.0.0.1:2379}"
  20. params_ref+=" --etcd-cafile=${ETCD_APISERVER_CA_CERT_PATH}"
  21. params_ref+=" --etcd-certfile=${ETCD_APISERVER_CLIENT_CERT_PATH}"
  22. params_ref+=" --etcd-keyfile=${ETCD_APISERVER_CLIENT_KEY_PATH}"
  23. elif [[ -z "${ETCD_APISERVER_CA_KEY:-}" && -z "${ETCD_APISERVER_CA_CERT:-}" && -z "${ETCD_APISERVER_SERVER_KEY:-}" && -z "${ETCD_APISERVER_SERVER_CERT:-}" && -z "${ETCD_APISERVER_CLIENT_KEY:-}" && -z "${ETCD_APISERVER_CLIENT_CERT:-}" ]]; then
  24. params_ref+=" --etcd-servers=${ETCD_SERVERS:-http://127.0.0.1:2379}"
  25. echo "WARNING: ALL of ETCD_APISERVER_CA_KEY, ETCD_APISERVER_CA_CERT, ETCD_APISERVER_SERVER_KEY, ETCD_APISERVER_SERVER_CERT, ETCD_APISERVER_CLIENT_KEY and ETCD_APISERVER_CLIENT_CERT are missing, mTLS between etcd server and kube-apiserver is not enabled."
  26. else
  27. echo "ERROR: Some of ETCD_APISERVER_CA_KEY, ETCD_APISERVER_CA_CERT, ETCD_APISERVER_SERVER_KEY, ETCD_APISERVER_SERVER_CERT, ETCD_APISERVER_CLIENT_KEY and ETCD_APISERVER_CLIENT_CERT are missing, mTLS between etcd server and kube-apiserver cannot be enabled. Please provide all mTLS credential."
  28. exit 1
  29. fi
  30. if [[ -z "${ETCD_SERVERS:-}" ]]; then
  31. params_ref+=" --etcd-servers-overrides=${ETCD_SERVERS_OVERRIDES:-/events#http://127.0.0.1:4002}"
  32. elif [[ -n "${ETCD_SERVERS_OVERRIDES:-}" ]]; then
  33. params_ref+=" --etcd-servers-overrides=${ETCD_SERVERS_OVERRIDES:-}"
  34. fi
  35. if [[ -n "${STORAGE_BACKEND:-}" ]]; then
  36. params_ref+=" --storage-backend=${STORAGE_BACKEND}"
  37. fi
  38. if [[ -n "${STORAGE_MEDIA_TYPE:-}" ]]; then
  39. params_ref+=" --storage-media-type=${STORAGE_MEDIA_TYPE}"
  40. fi
  41. if [[ -n "${ETCD_COMPACTION_INTERVAL_SEC:-}" ]]; then
  42. params_ref+=" --etcd-compaction-interval=${ETCD_COMPACTION_INTERVAL_SEC}s"
  43. fi
  44. }
  45. # Starts kubernetes apiserver.
  46. # It prepares the log file, loads the docker image, calculates variables, sets them
  47. # in the manifest file, and then copies the manifest file to /etc/kubernetes/manifests.
  48. #
  49. # Assumed vars (which are calculated in function compute-master-manifest-variables)
  50. # CLOUD_CONFIG_OPT
  51. # CLOUD_CONFIG_VOLUME
  52. # CLOUD_CONFIG_MOUNT
  53. # DOCKER_REGISTRY
  54. # INSECURE_PORT_MAPPING
  55. function start-kube-apiserver {
  56. echo "Start kubernetes api-server"
  57. prepare-log-file "${KUBE_API_SERVER_LOG_PATH:-/var/log/kube-apiserver.log}"
  58. prepare-log-file "${KUBE_API_SERVER_AUDIT_LOG_PATH:-/var/log/kube-apiserver-audit.log}"
  59. # Calculate variables and assemble the command line.
  60. local params="${API_SERVER_TEST_LOG_LEVEL:-"--v=2"} ${APISERVER_TEST_ARGS:-} ${CLOUD_CONFIG_OPT}"
  61. params+=" --address=127.0.0.1"
  62. params+=" --allow-privileged=true"
  63. params+=" --cloud-provider=gce"
  64. params+=" --client-ca-file=${CA_CERT_BUNDLE_PATH}"
  65. # params is passed by reference, so no "$"
  66. configure-etcd-params params
  67. params+=" --secure-port=443"
  68. if [[ "${ENABLE_APISERVER_INSECURE_PORT:-false}" != "true" ]]; then
  69. # Default is :8080
  70. params+=" --insecure-port=0"
  71. fi
  72. params+=" --tls-cert-file=${APISERVER_SERVER_CERT_PATH}"
  73. params+=" --tls-private-key-file=${APISERVER_SERVER_KEY_PATH}"
  74. params+=" --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname"
  75. if [[ -s "${REQUESTHEADER_CA_CERT_PATH:-}" ]]; then
  76. params+=" --requestheader-client-ca-file=${REQUESTHEADER_CA_CERT_PATH}"
  77. params+=" --requestheader-allowed-names=aggregator"
  78. params+=" --requestheader-extra-headers-prefix=X-Remote-Extra-"
  79. params+=" --requestheader-group-headers=X-Remote-Group"
  80. params+=" --requestheader-username-headers=X-Remote-User"
  81. params+=" --proxy-client-cert-file=${PROXY_CLIENT_CERT_PATH}"
  82. params+=" --proxy-client-key-file=${PROXY_CLIENT_KEY_PATH}"
  83. fi
  84. params+=" --enable-aggregator-routing=true"
  85. if [[ -e "${APISERVER_CLIENT_CERT_PATH}" ]] && [[ -e "${APISERVER_CLIENT_KEY_PATH}" ]]; then
  86. params+=" --kubelet-client-certificate=${APISERVER_CLIENT_CERT_PATH}"
  87. params+=" --kubelet-client-key=${APISERVER_CLIENT_KEY_PATH}"
  88. fi
  89. if [[ -n "${SERVICEACCOUNT_CERT_PATH:-}" ]]; then
  90. params+=" --service-account-key-file=${SERVICEACCOUNT_CERT_PATH}"
  91. fi
  92. params+=" --token-auth-file=/etc/srv/kubernetes/known_tokens.csv"
  93. if [[ -n "${KUBE_PASSWORD:-}" && -n "${KUBE_USER:-}" ]]; then
  94. params+=" --basic-auth-file=/etc/srv/kubernetes/basic_auth.csv"
  95. fi
  96. if [[ -n "${KUBE_APISERVER_REQUEST_TIMEOUT_SEC:-}" ]]; then
  97. params+=" --request-timeout=${KUBE_APISERVER_REQUEST_TIMEOUT_SEC}s"
  98. fi
  99. if [[ -n "${ENABLE_GARBAGE_COLLECTOR:-}" ]]; then
  100. params+=" --enable-garbage-collector=${ENABLE_GARBAGE_COLLECTOR}"
  101. fi
  102. if [[ -n "${NUM_NODES:-}" ]]; then
  103. # If the cluster is large, increase max-requests-inflight limit in apiserver.
  104. if [[ "${NUM_NODES}" -gt 3000 ]]; then
  105. params+=" --max-requests-inflight=3000 --max-mutating-requests-inflight=1000"
  106. elif [[ "${NUM_NODES}" -gt 500 ]]; then
  107. params+=" --max-requests-inflight=1500 --max-mutating-requests-inflight=500"
  108. fi
  109. # Set amount of memory available for apiserver based on number of nodes.
  110. # TODO: Once we start setting proper requests and limits for apiserver
  111. # we should reuse the same logic here instead of current heuristic.
  112. params+=" --target-ram-mb=$((NUM_NODES * 60))"
  113. fi
  114. if [[ -n "${SERVICE_CLUSTER_IP_RANGE:-}" ]]; then
  115. params+=" --service-cluster-ip-range=${SERVICE_CLUSTER_IP_RANGE}"
  116. fi
  117. params+=" --service-account-issuer=${SERVICEACCOUNT_ISSUER}"
  118. params+=" --service-account-api-audiences=${SERVICEACCOUNT_ISSUER}"
  119. params+=" --service-account-signing-key-file=${SERVICEACCOUNT_KEY_PATH}"
  120. local audit_policy_config_mount=""
  121. local audit_policy_config_volume=""
  122. local audit_webhook_config_mount=""
  123. local audit_webhook_config_volume=""
  124. if [[ "${ENABLE_APISERVER_ADVANCED_AUDIT:-}" == "true" ]]; then
  125. local -r audit_policy_file="/etc/audit_policy.config"
  126. params+=" --audit-policy-file=${audit_policy_file}"
  127. # Create the audit policy file, and mount it into the apiserver pod.
  128. create-master-audit-policy "${audit_policy_file}" "${ADVANCED_AUDIT_POLICY:-}"
  129. audit_policy_config_mount="{\"name\": \"auditpolicyconfigmount\",\"mountPath\": \"${audit_policy_file}\", \"readOnly\": true},"
  130. audit_policy_config_volume="{\"name\": \"auditpolicyconfigmount\",\"hostPath\": {\"path\": \"${audit_policy_file}\", \"type\": \"FileOrCreate\"}},"
  131. if [[ "${ADVANCED_AUDIT_BACKEND:-log}" == *"log"* ]]; then
  132. # The advanced audit log backend config matches the basic audit log config.
  133. params+=" --audit-log-path=/var/log/kube-apiserver-audit.log"
  134. params+=" --audit-log-maxage=0"
  135. params+=" --audit-log-maxbackup=0"
  136. # Lumberjack doesn't offer any way to disable size-based rotation. It also
  137. # has an in-memory counter that doesn't notice if you truncate the file.
  138. # 2000000000 (in MiB) is a large number that fits in 31 bits. If the log
  139. # grows at 10MiB/s (~30K QPS), it will rotate after ~6 years if apiserver
  140. # never restarts. Please manually restart apiserver before this time.
  141. params+=" --audit-log-maxsize=2000000000"
  142. # Batching parameters
  143. if [[ -n "${ADVANCED_AUDIT_LOG_MODE:-}" ]]; then
  144. params+=" --audit-log-mode=${ADVANCED_AUDIT_LOG_MODE}"
  145. fi
  146. if [[ -n "${ADVANCED_AUDIT_LOG_BUFFER_SIZE:-}" ]]; then
  147. params+=" --audit-log-batch-buffer-size=${ADVANCED_AUDIT_LOG_BUFFER_SIZE}"
  148. fi
  149. if [[ -n "${ADVANCED_AUDIT_LOG_MAX_BATCH_SIZE:-}" ]]; then
  150. params+=" --audit-log-batch-max-size=${ADVANCED_AUDIT_LOG_MAX_BATCH_SIZE}"
  151. fi
  152. if [[ -n "${ADVANCED_AUDIT_LOG_MAX_BATCH_WAIT:-}" ]]; then
  153. params+=" --audit-log-batch-max-wait=${ADVANCED_AUDIT_LOG_MAX_BATCH_WAIT}"
  154. fi
  155. if [[ -n "${ADVANCED_AUDIT_LOG_THROTTLE_QPS:-}" ]]; then
  156. params+=" --audit-log-batch-throttle-qps=${ADVANCED_AUDIT_LOG_THROTTLE_QPS}"
  157. fi
  158. if [[ -n "${ADVANCED_AUDIT_LOG_THROTTLE_BURST:-}" ]]; then
  159. params+=" --audit-log-batch-throttle-burst=${ADVANCED_AUDIT_LOG_THROTTLE_BURST}"
  160. fi
  161. if [[ -n "${ADVANCED_AUDIT_LOG_INITIAL_BACKOFF:-}" ]]; then
  162. params+=" --audit-log-initial-backoff=${ADVANCED_AUDIT_LOG_INITIAL_BACKOFF}"
  163. fi
  164. # Truncating backend parameters
  165. if [[ -n "${ADVANCED_AUDIT_TRUNCATING_BACKEND:-}" ]]; then
  166. params+=" --audit-log-truncate-enabled=${ADVANCED_AUDIT_TRUNCATING_BACKEND}"
  167. fi
  168. fi
  169. if [[ "${ADVANCED_AUDIT_BACKEND:-}" == *"webhook"* ]]; then
  170. # Create the audit webhook config file, and mount it into the apiserver pod.
  171. local -r audit_webhook_config_file="/etc/audit_webhook.config"
  172. params+=" --audit-webhook-config-file=${audit_webhook_config_file}"
  173. create-master-audit-webhook-config "${audit_webhook_config_file}"
  174. audit_webhook_config_mount="{\"name\": \"auditwebhookconfigmount\",\"mountPath\": \"${audit_webhook_config_file}\", \"readOnly\": true},"
  175. audit_webhook_config_volume="{\"name\": \"auditwebhookconfigmount\",\"hostPath\": {\"path\": \"${audit_webhook_config_file}\", \"type\": \"FileOrCreate\"}},"
  176. # Batching parameters
  177. if [[ -n "${ADVANCED_AUDIT_WEBHOOK_MODE:-}" ]]; then
  178. params+=" --audit-webhook-mode=${ADVANCED_AUDIT_WEBHOOK_MODE}"
  179. else
  180. params+=" --audit-webhook-mode=batch"
  181. fi
  182. if [[ -n "${ADVANCED_AUDIT_WEBHOOK_BUFFER_SIZE:-}" ]]; then
  183. params+=" --audit-webhook-batch-buffer-size=${ADVANCED_AUDIT_WEBHOOK_BUFFER_SIZE}"
  184. fi
  185. if [[ -n "${ADVANCED_AUDIT_WEBHOOK_MAX_BATCH_SIZE:-}" ]]; then
  186. params+=" --audit-webhook-batch-max-size=${ADVANCED_AUDIT_WEBHOOK_MAX_BATCH_SIZE}"
  187. fi
  188. if [[ -n "${ADVANCED_AUDIT_WEBHOOK_MAX_BATCH_WAIT:-}" ]]; then
  189. params+=" --audit-webhook-batch-max-wait=${ADVANCED_AUDIT_WEBHOOK_MAX_BATCH_WAIT}"
  190. fi
  191. if [[ -n "${ADVANCED_AUDIT_WEBHOOK_THROTTLE_QPS:-}" ]]; then
  192. params+=" --audit-webhook-batch-throttle-qps=${ADVANCED_AUDIT_WEBHOOK_THROTTLE_QPS}"
  193. fi
  194. if [[ -n "${ADVANCED_AUDIT_WEBHOOK_THROTTLE_BURST:-}" ]]; then
  195. params+=" --audit-webhook-batch-throttle-burst=${ADVANCED_AUDIT_WEBHOOK_THROTTLE_BURST}"
  196. fi
  197. if [[ -n "${ADVANCED_AUDIT_WEBHOOK_INITIAL_BACKOFF:-}" ]]; then
  198. params+=" --audit-webhook-initial-backoff=${ADVANCED_AUDIT_WEBHOOK_INITIAL_BACKOFF}"
  199. fi
  200. # Truncating backend parameters
  201. if [[ -n "${ADVANCED_AUDIT_TRUNCATING_BACKEND:-}" ]]; then
  202. params+=" --audit-webhook-truncate-enabled=${ADVANCED_AUDIT_TRUNCATING_BACKEND}"
  203. fi
  204. fi
  205. fi
  206. if [[ "${ENABLE_APISERVER_DYNAMIC_AUDIT:-}" == "true" ]]; then
  207. params+=" --audit-dynamic-configuration"
  208. RUNTIME_CONFIG="${RUNTIME_CONFIG},auditconfiguration.k8s.io/v1alpha1=true"
  209. fi
  210. if [[ "${ENABLE_APISERVER_LOGS_HANDLER:-}" == "false" ]]; then
  211. params+=" --enable-logs-handler=false"
  212. fi
  213. if [[ "${APISERVER_SET_KUBELET_CA:-false}" == "true" ]]; then
  214. params+=" --kubelet-certificate-authority=${CA_CERT_BUNDLE_PATH}"
  215. fi
  216. if [[ -n "${ADMISSION_CONTROL:-}" ]]; then
  217. params+=" --enable-admission-plugins=${ADMISSION_CONTROL}"
  218. params+=" --admission-control-config-file=/etc/srv/kubernetes/admission_controller_config.yaml"
  219. fi
  220. # If GKE exec auth support is requested for webhooks, then
  221. # gke-exec-auth-plugin needs to be mounted into the kube-apiserver container.
  222. local webhook_exec_auth_plugin_mount=""
  223. local webhook_exec_auth_plugin_volume=""
  224. if [[ -n "${WEBHOOK_GKE_EXEC_AUTH:-}" ]]; then
  225. webhook_exec_auth_plugin_mount='{"name": "gkeauth", "mountPath": "/usr/bin/gke-exec-auth-plugin", "readOnly": true},'
  226. webhook_exec_auth_plugin_volume='{"name": "gkeauth", "hostPath": {"path": "/home/kubernetes/bin/gke-exec-auth-plugin", "type": "File"}},'
  227. fi
  228. if [[ -n "${KUBE_APISERVER_REQUEST_TIMEOUT:-}" ]]; then
  229. params+=" --min-request-timeout=${KUBE_APISERVER_REQUEST_TIMEOUT}"
  230. fi
  231. if [[ -n "${RUNTIME_CONFIG:-}" ]]; then
  232. params+=" --runtime-config=${RUNTIME_CONFIG}"
  233. fi
  234. if [[ -n "${FEATURE_GATES:-}" ]]; then
  235. params+=" --feature-gates=${FEATURE_GATES}"
  236. fi
  237. if [[ "${FEATURE_GATES:-}" =~ "RuntimeClass=true" ]]; then
  238. params+=" --runtime-config=node.k8s.io/v1alpha1=true"
  239. fi
  240. if [[ -n "${MASTER_ADVERTISE_ADDRESS:-}" ]]; then
  241. params+=" --advertise-address=${MASTER_ADVERTISE_ADDRESS}"
  242. if [[ -n "${PROXY_SSH_USER:-}" ]]; then
  243. params+=" --ssh-user=${PROXY_SSH_USER}"
  244. params+=" --ssh-keyfile=/etc/srv/sshproxy/.sshkeyfile"
  245. fi
  246. elif [[ -n "${PROJECT_ID:-}" && -n "${TOKEN_URL:-}" && -n "${TOKEN_BODY:-}" && -n "${NODE_NETWORK:-}" ]]; then
  247. local -r vm_external_ip=$(get-metadata-value "instance/network-interfaces/0/access-configs/0/external-ip")
  248. if [[ -n "${PROXY_SSH_USER:-}" ]]; then
  249. params+=" --advertise-address=${vm_external_ip}"
  250. params+=" --ssh-user=${PROXY_SSH_USER}"
  251. params+=" --ssh-keyfile=/etc/srv/sshproxy/.sshkeyfile"
  252. fi
  253. fi
  254. local webhook_authn_config_mount=""
  255. local webhook_authn_config_volume=""
  256. if [[ -n "${GCP_AUTHN_URL:-}" ]]; then
  257. params+=" --authentication-token-webhook-config-file=/etc/gcp_authn.config"
  258. webhook_authn_config_mount="{\"name\": \"webhookauthnconfigmount\",\"mountPath\": \"/etc/gcp_authn.config\", \"readOnly\": false},"
  259. webhook_authn_config_volume="{\"name\": \"webhookauthnconfigmount\",\"hostPath\": {\"path\": \"/etc/gcp_authn.config\", \"type\": \"FileOrCreate\"}},"
  260. if [[ -n "${GCP_AUTHN_CACHE_TTL:-}" ]]; then
  261. params+=" --authentication-token-webhook-cache-ttl=${GCP_AUTHN_CACHE_TTL}"
  262. fi
  263. fi
  264. local authorization_mode="RBAC"
  265. local -r src_dir="${KUBE_HOME}/kube-manifests/kubernetes/gci-trusty"
  266. # Enable ABAC mode unless the user explicitly opts out with ENABLE_LEGACY_ABAC=false
  267. if [[ "${ENABLE_LEGACY_ABAC:-}" != "false" ]]; then
  268. echo "Warning: Enabling legacy ABAC policy. All service accounts will have superuser API access. Set ENABLE_LEGACY_ABAC=false to disable this."
  269. # Create the ABAC file if it doesn't exist yet, or if we have a KUBE_USER set (to ensure the right user is given permissions)
  270. if [[ -n "${KUBE_USER:-}" || ! -e /etc/srv/kubernetes/abac-authz-policy.jsonl ]]; then
  271. local -r abac_policy_json="${src_dir}/abac-authz-policy.jsonl"
  272. if [[ -n "${KUBE_USER:-}" ]]; then
  273. sed -i -e "s/{{kube_user}}/${KUBE_USER}/g" "${abac_policy_json}"
  274. else
  275. sed -i -e "/{{kube_user}}/d" "${abac_policy_json}"
  276. fi
  277. cp "${abac_policy_json}" /etc/srv/kubernetes/
  278. fi
  279. params+=" --authorization-policy-file=/etc/srv/kubernetes/abac-authz-policy.jsonl"
  280. authorization_mode+=",ABAC"
  281. fi
  282. local webhook_config_mount=""
  283. local webhook_config_volume=""
  284. if [[ -n "${GCP_AUTHZ_URL:-}" ]]; then
  285. authorization_mode="${authorization_mode},Webhook"
  286. params+=" --authorization-webhook-config-file=/etc/gcp_authz.config"
  287. webhook_config_mount="{\"name\": \"webhookconfigmount\",\"mountPath\": \"/etc/gcp_authz.config\", \"readOnly\": false},"
  288. webhook_config_volume="{\"name\": \"webhookconfigmount\",\"hostPath\": {\"path\": \"/etc/gcp_authz.config\", \"type\": \"FileOrCreate\"}},"
  289. if [[ -n "${GCP_AUTHZ_CACHE_AUTHORIZED_TTL:-}" ]]; then
  290. params+=" --authorization-webhook-cache-authorized-ttl=${GCP_AUTHZ_CACHE_AUTHORIZED_TTL}"
  291. fi
  292. if [[ -n "${GCP_AUTHZ_CACHE_UNAUTHORIZED_TTL:-}" ]]; then
  293. params+=" --authorization-webhook-cache-unauthorized-ttl=${GCP_AUTHZ_CACHE_UNAUTHORIZED_TTL}"
  294. fi
  295. fi
  296. authorization_mode="Node,${authorization_mode}"
  297. params+=" --authorization-mode=${authorization_mode}"
  298. local csc_config_mount=""
  299. local csc_config_volume=""
  300. local default_konnectivity_socket_vol=""
  301. local default_konnectivity_socket_mnt=""
  302. if [[ "${ENABLE_EGRESS_VIA_KONNECTIVITY_SERVICE:-false}" == "true" ]]; then
  303. # Create the EgressSelectorConfiguration yaml file to control the Egress Selector.
  304. csc_config_mount="{\"name\": \"cscconfigmount\",\"mountPath\": \"/etc/srv/kubernetes/egress_selector_configuration.yaml\", \"readOnly\": false},"
  305. csc_config_volume="{\"name\": \"cscconfigmount\",\"hostPath\": {\"path\": \"/etc/srv/kubernetes/egress_selector_configuration.yaml\", \"type\": \"FileOrCreate\"}},"
  306. params+=" --egress-selector-config-file=/etc/srv/kubernetes/egress_selector_configuration.yaml"
  307. # UDS socket for communication between apiserver and konnectivity-server
  308. local default_konnectivity_socket_path="/etc/srv/kubernetes/konnectivity"
  309. default_konnectivity_socket_vol="{ \"name\": \"konnectivity-socket\", \"hostPath\": {\"path\": \"${default_konnectivity_socket_path}\", \"type\": \"DirectoryOrCreate\"}},"
  310. default_konnectivity_socket_mnt="{ \"name\": \"konnectivity-socket\", \"mountPath\": \"${default_konnectivity_socket_path}\", \"readOnly\": false},"
  311. fi
  312. local container_env=""
  313. if [[ -n "${ENABLE_CACHE_MUTATION_DETECTOR:-}" ]]; then
  314. container_env+="{\"name\": \"KUBE_CACHE_MUTATION_DETECTOR\", \"value\": \"${ENABLE_CACHE_MUTATION_DETECTOR}\"}"
  315. fi
  316. if [[ -n "${ENABLE_PATCH_CONVERSION_DETECTOR:-}" ]]; then
  317. if [[ -n "${container_env}" ]]; then
  318. container_env="${container_env}, "
  319. fi
  320. container_env+="{\"name\": \"KUBE_PATCH_CONVERSION_DETECTOR\", \"value\": \"${ENABLE_PATCH_CONVERSION_DETECTOR}\"}"
  321. fi
  322. if [[ -n "${container_env}" ]]; then
  323. container_env="\"env\":[${container_env}],"
  324. fi
  325. local -r src_file="${src_dir}/kube-apiserver.manifest"
  326. # params is passed by reference, so no "$"
  327. setup-etcd-encryption "${src_file}" params
  328. # Evaluate variables.
  329. local -r kube_apiserver_docker_tag="${KUBE_API_SERVER_DOCKER_TAG:-$(cat /home/kubernetes/kube-docker-files/kube-apiserver.docker_tag)}"
  330. sed -i -e "s@{{params}}@${params}@g" "${src_file}"
  331. sed -i -e "s@{{container_env}}@${container_env}@g" "${src_file}"
  332. sed -i -e "s@{{srv_sshproxy_path}}@/etc/srv/sshproxy@g" "${src_file}"
  333. sed -i -e "s@{{cloud_config_mount}}@${CLOUD_CONFIG_MOUNT}@g" "${src_file}"
  334. sed -i -e "s@{{cloud_config_volume}}@${CLOUD_CONFIG_VOLUME}@g" "${src_file}"
  335. sed -i -e "s@{{pillar\['kube_docker_registry'\]}}@${DOCKER_REGISTRY}@g" "${src_file}"
  336. sed -i -e "s@{{pillar\['kube-apiserver_docker_tag'\]}}@${kube_apiserver_docker_tag}@g" "${src_file}"
  337. sed -i -e "s@{{pillar\['allow_privileged'\]}}@true@g" "${src_file}"
  338. sed -i -e "s@{{liveness_probe_initial_delay}}@${KUBE_APISERVER_LIVENESS_PROBE_INITIAL_DELAY_SEC:-15}@g" "${src_file}"
  339. sed -i -e "s@{{secure_port}}@443@g" "${src_file}"
  340. sed -i -e "s@{{insecure_port_mapping}}@${INSECURE_PORT_MAPPING}@g" "${src_file}"
  341. sed -i -e "s@{{additional_cloud_config_mount}}@@g" "${src_file}"
  342. sed -i -e "s@{{additional_cloud_config_volume}}@@g" "${src_file}"
  343. sed -i -e "s@{{webhook_authn_config_mount}}@${webhook_authn_config_mount}@g" "${src_file}"
  344. sed -i -e "s@{{webhook_authn_config_volume}}@${webhook_authn_config_volume}@g" "${src_file}"
  345. sed -i -e "s@{{webhook_config_mount}}@${webhook_config_mount}@g" "${src_file}"
  346. sed -i -e "s@{{webhook_config_volume}}@${webhook_config_volume}@g" "${src_file}"
  347. sed -i -e "s@{{csc_config_mount}}@${csc_config_mount}@g" "${src_file}"
  348. sed -i -e "s@{{csc_config_volume}}@${csc_config_volume}@g" "${src_file}"
  349. sed -i -e "s@{{audit_policy_config_mount}}@${audit_policy_config_mount}@g" "${src_file}"
  350. sed -i -e "s@{{audit_policy_config_volume}}@${audit_policy_config_volume}@g" "${src_file}"
  351. sed -i -e "s@{{audit_webhook_config_mount}}@${audit_webhook_config_mount}@g" "${src_file}"
  352. sed -i -e "s@{{audit_webhook_config_volume}}@${audit_webhook_config_volume}@g" "${src_file}"
  353. sed -i -e "s@{{webhook_exec_auth_plugin_mount}}@${webhook_exec_auth_plugin_mount}@g" "${src_file}"
  354. sed -i -e "s@{{webhook_exec_auth_plugin_volume}}@${webhook_exec_auth_plugin_volume}@g" "${src_file}"
  355. sed -i -e "s@{{konnectivity_socket_mount}}@${default_konnectivity_socket_mnt}@g" "${src_file}"
  356. sed -i -e "s@{{konnectivity_socket_volume}}@${default_konnectivity_socket_vol}@g" "${src_file}"
  357. cp "${src_file}" "${ETC_MANIFESTS:-/etc/kubernetes/manifests}"
  358. }
  359. # Sets-up etcd encryption.
  360. # Configuration of etcd level encryption consists of the following steps:
  361. # 1. Writing encryption provider config to disk
  362. # 2. Adding encryption-provider-config flag to kube-apiserver
  363. # 3. Add kms-socket-vol and kms-socket-vol-mnt to enable communication with kms-plugin (if requested)
  364. #
  365. # Expects parameters:
  366. # $1 - path to kube-apiserver template
  367. # $2 - kube-apiserver startup flags (must be passed by reference)
  368. #
  369. # Assumes vars (supplied via kube-env):
  370. # ENCRYPTION_PROVIDER_CONFIG
  371. # CLOUD_KMS_INTEGRATION
  372. # ENCRYPTION_PROVIDER_CONFIG_PATH (will default to /etc/srv/kubernetes/encryption-provider-config.yml)
  373. function setup-etcd-encryption {
  374. local kube_apiserver_template_path
  375. local -n kube_api_server_params
  376. local default_encryption_provider_config_vol
  377. local default_encryption_provider_config_vol_mnt
  378. local encryption_provider_config_vol_mnt
  379. local encryption_provider_config_vol
  380. local default_kms_socket_dir
  381. local default_kms_socket_vol_mnt
  382. local default_kms_socket_vol
  383. local kms_socket_vol_mnt
  384. local kms_socket_vol
  385. local encryption_provider_config_path
  386. kube_apiserver_template_path="$1"
  387. if [[ -z "${ENCRYPTION_PROVIDER_CONFIG:-}" ]]; then
  388. sed -i -e " {
  389. s@{{encryption_provider_mount}}@@
  390. s@{{encryption_provider_volume}}@@
  391. s@{{kms_socket_mount}}@@
  392. s@{{kms_socket_volume}}@@
  393. } " "${kube_apiserver_template_path}"
  394. return
  395. fi
  396. kube_api_server_params="$2"
  397. encryption_provider_config_path=${ENCRYPTION_PROVIDER_CONFIG_PATH:-/etc/srv/kubernetes/encryption-provider-config.yml}
  398. echo "${ENCRYPTION_PROVIDER_CONFIG}" | base64 --decode > "${encryption_provider_config_path}"
  399. kube_api_server_params+=" --encryption-provider-config=${encryption_provider_config_path}"
  400. default_encryption_provider_config_vol=$(echo "{ \"name\": \"encryptionconfig\", \"hostPath\": {\"path\": \"${encryption_provider_config_path}\", \"type\": \"File\"}}" | base64 | tr -d '\r\n')
  401. default_encryption_provider_config_vol_mnt=$(echo "{ \"name\": \"encryptionconfig\", \"mountPath\": \"${encryption_provider_config_path}\", \"readOnly\": true}" | base64 | tr -d '\r\n')
  402. encryption_provider_config_vol_mnt=$(echo "${ENCRYPTION_PROVIDER_CONFIG_VOL_MNT:-"${default_encryption_provider_config_vol_mnt}"}" | base64 --decode)
  403. encryption_provider_config_vol=$(echo "${ENCRYPTION_PROVIDER_CONFIG_VOL:-"${default_encryption_provider_config_vol}"}" | base64 --decode)
  404. sed -i -e " {
  405. s@{{encryption_provider_mount}}@${encryption_provider_config_vol_mnt},@
  406. s@{{encryption_provider_volume}}@${encryption_provider_config_vol},@
  407. } " "${kube_apiserver_template_path}"
  408. if [[ -n "${CLOUD_KMS_INTEGRATION:-}" ]]; then
  409. default_kms_socket_dir="/var/run/kmsplugin"
  410. default_kms_socket_vol_mnt=$(echo "{ \"name\": \"kmssocket\", \"mountPath\": \"${default_kms_socket_dir}\", \"readOnly\": false}" | base64 | tr -d '\r\n')
  411. default_kms_socket_vol=$(echo "{ \"name\": \"kmssocket\", \"hostPath\": {\"path\": \"${default_kms_socket_dir}\", \"type\": \"DirectoryOrCreate\"}}" | base64 | tr -d '\r\n')
  412. kms_socket_vol_mnt=$(echo "${KMS_PLUGIN_SOCKET_VOL_MNT:-"${default_kms_socket_vol_mnt}"}" | base64 --decode)
  413. kms_socket_vol=$(echo "${KMS_PLUGIN_SOCKET_VOL:-"${default_kms_socket_vol}"}" | base64 --decode)
  414. sed -i -e " {
  415. s@{{kms_socket_mount}}@${kms_socket_vol_mnt},@
  416. s@{{kms_socket_volume}}@${kms_socket_vol},@
  417. } " "${kube_apiserver_template_path}"
  418. else
  419. sed -i -e " {
  420. s@{{kms_socket_mount}}@@
  421. s@{{kms_socket_volume}}@@
  422. } " "${kube_apiserver_template_path}"
  423. fi
  424. }