configure-helper.sh 106 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862
  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. # This script is for configuring kubernetes master and node instances. It is
  16. # uploaded in the manifests tar ball.
  17. # TODO: this script duplicates templating logic from cluster/saltbase/salt
  18. # using sed. It should use an actual template parser on the manifest
  19. # files.
  20. set -o errexit
  21. set -o nounset
  22. set -o pipefail
  23. function setup-os-params {
  24. # Reset core_pattern. On GCI, the default core_pattern pipes the core dumps to
  25. # /sbin/crash_reporter which is more restrictive in saving crash dumps. So for
  26. # now, set a generic core_pattern that users can work with.
  27. echo "/core.%e.%p.%t" > /proc/sys/kernel/core_pattern
  28. }
  29. # secure_random generates a secure random string of bytes. This function accepts
  30. # a number of secure bytes desired and returns a base64 encoded string with at
  31. # least the requested entropy. Rather than directly reading from /dev/urandom,
  32. # we use uuidgen which calls getrandom(2). getrandom(2) verifies that the
  33. # entropy pool has been initialized sufficiently for the desired operation
  34. # before reading from /dev/urandom.
  35. #
  36. # ARGS:
  37. # #1: number of secure bytes to generate. We round up to the nearest factor of 32.
  38. function secure_random {
  39. local infobytes="${1}"
  40. if ((infobytes <= 0)); then
  41. echo "Invalid argument to secure_random: infobytes='${infobytes}'" 1>&2
  42. return 1
  43. fi
  44. local out=""
  45. for (( i = 0; i < "${infobytes}"; i += 32 )); do
  46. # uuids have 122 random bits, sha256 sums have 256 bits, so concatenate
  47. # three uuids and take their sum. The sum is encoded in ASCII hex, hence the
  48. # 64 character cut.
  49. out+="$(
  50. (
  51. uuidgen --random;
  52. uuidgen --random;
  53. uuidgen --random;
  54. ) | sha256sum \
  55. | head -c 64
  56. )";
  57. done
  58. # Finally, convert the ASCII hex to base64 to increase the density.
  59. echo -n "${out}" | xxd -r -p | base64 -w 0
  60. }
  61. function config-ip-firewall {
  62. echo "Configuring IP firewall rules"
  63. # Do not consider loopback addresses as martian source or destination while
  64. # routing. This enables the use of 127/8 for local routing purposes.
  65. sysctl -w net.ipv4.conf.all.route_localnet=1
  66. # The GCI image has host firewall which drop most inbound/forwarded packets.
  67. # We need to add rules to accept all TCP/UDP/ICMP/SCTP packets.
  68. if iptables -w -L INPUT | grep "Chain INPUT (policy DROP)" > /dev/null; then
  69. echo "Add rules to accept all inbound TCP/UDP/ICMP packets"
  70. iptables -A INPUT -w -p TCP -j ACCEPT
  71. iptables -A INPUT -w -p UDP -j ACCEPT
  72. iptables -A INPUT -w -p ICMP -j ACCEPT
  73. iptables -A INPUT -w -p SCTP -j ACCEPT
  74. fi
  75. if iptables -w -L FORWARD | grep "Chain FORWARD (policy DROP)" > /dev/null; then
  76. echo "Add rules to accept all forwarded TCP/UDP/ICMP/SCTP packets"
  77. iptables -A FORWARD -w -p TCP -j ACCEPT
  78. iptables -A FORWARD -w -p UDP -j ACCEPT
  79. iptables -A FORWARD -w -p ICMP -j ACCEPT
  80. iptables -A FORWARD -w -p SCTP -j ACCEPT
  81. fi
  82. # Flush iptables nat table
  83. iptables -w -t nat -F || true
  84. if [[ "${NON_MASQUERADE_CIDR:-}" == "0.0.0.0/0" ]]; then
  85. echo "Add rules for ip masquerade"
  86. iptables -w -t nat -N IP-MASQ
  87. iptables -w -t nat -A POSTROUTING -m comment --comment "ip-masq: ensure nat POSTROUTING directs all non-LOCAL destination traffic to our custom IP-MASQ chain" -m addrtype ! --dst-type LOCAL -j IP-MASQ
  88. iptables -w -t nat -A IP-MASQ -d 169.254.0.0/16 -m comment --comment "ip-masq: local traffic is not subject to MASQUERADE" -j RETURN
  89. iptables -w -t nat -A IP-MASQ -d 10.0.0.0/8 -m comment --comment "ip-masq: RFC 1918 reserved range is not subject to MASQUERADE" -j RETURN
  90. iptables -w -t nat -A IP-MASQ -d 172.16.0.0/12 -m comment --comment "ip-masq: RFC 1918 reserved range is not subject to MASQUERADE" -j RETURN
  91. iptables -w -t nat -A IP-MASQ -d 192.168.0.0/16 -m comment --comment "ip-masq: RFC 1918 reserved range is not subject to MASQUERADE" -j RETURN
  92. iptables -w -t nat -A IP-MASQ -d 240.0.0.0/4 -m comment --comment "ip-masq: RFC 5735 reserved range is not subject to MASQUERADE" -j RETURN
  93. iptables -w -t nat -A IP-MASQ -d 192.0.2.0/24 -m comment --comment "ip-masq: RFC 5737 reserved range is not subject to MASQUERADE" -j RETURN
  94. iptables -w -t nat -A IP-MASQ -d 198.51.100.0/24 -m comment --comment "ip-masq: RFC 5737 reserved range is not subject to MASQUERADE" -j RETURN
  95. iptables -w -t nat -A IP-MASQ -d 203.0.113.0/24 -m comment --comment "ip-masq: RFC 5737 reserved range is not subject to MASQUERADE" -j RETURN
  96. iptables -w -t nat -A IP-MASQ -d 100.64.0.0/10 -m comment --comment "ip-masq: RFC 6598 reserved range is not subject to MASQUERADE" -j RETURN
  97. iptables -w -t nat -A IP-MASQ -d 198.18.0.0/15 -m comment --comment "ip-masq: RFC 6815 reserved range is not subject to MASQUERADE" -j RETURN
  98. iptables -w -t nat -A IP-MASQ -d 192.0.0.0/24 -m comment --comment "ip-masq: RFC 6890 reserved range is not subject to MASQUERADE" -j RETURN
  99. iptables -w -t nat -A IP-MASQ -d 192.88.99.0/24 -m comment --comment "ip-masq: RFC 7526 reserved range is not subject to MASQUERADE" -j RETURN
  100. iptables -w -t nat -A IP-MASQ -m comment --comment "ip-masq: outbound traffic is subject to MASQUERADE (must be last in chain)" -j MASQUERADE
  101. fi
  102. # If METADATA_CONCEALMENT_NO_FIREWALL is set, don't create a firewall on this
  103. # node because we don't expect the daemonset to run on this node.
  104. if [[ "${ENABLE_METADATA_CONCEALMENT:-}" == "true" ]] && [[ ! "${METADATA_CONCEALMENT_NO_FIREWALL:-}" == "true" ]]; then
  105. echo "Add rule for metadata concealment"
  106. iptables -w -t nat -I PREROUTING -p tcp -d 169.254.169.254 --dport 80 -m comment --comment "metadata-concealment: bridge traffic to metadata server goes to metadata proxy" -j DNAT --to-destination 127.0.0.1:988
  107. fi
  108. }
  109. function create-dirs {
  110. echo "Creating required directories"
  111. mkdir -p /var/lib/kubelet
  112. mkdir -p /etc/kubernetes/manifests
  113. if [[ "${KUBERNETES_MASTER:-}" == "false" ]]; then
  114. mkdir -p /var/lib/kube-proxy
  115. fi
  116. }
  117. # Gets the total number of $(1) and $(2) type disks specified
  118. # by the user in ${NODE_LOCAL_SSDS_EXT}
  119. function get-local-disk-num() {
  120. local interface="${1}"
  121. local format="${2}"
  122. localdisknum=0
  123. if [[ ! -z "${NODE_LOCAL_SSDS_EXT:-}" ]]; then
  124. IFS=";" read -r -a ssdgroups <<< "${NODE_LOCAL_SSDS_EXT:-}"
  125. for ssdgroup in "${ssdgroups[@]}"; do
  126. IFS="," read -r -a ssdopts <<< "${ssdgroup}"
  127. local opnum="${ssdopts[0]}"
  128. local opinterface="${ssdopts[1]}"
  129. local opformat="${ssdopts[2]}"
  130. if [[ "${opformat,,}" == "${format,,}" && "${opinterface,,}" == "${interface,,}" ]]; then
  131. localdisknum=$((localdisknum+opnum))
  132. fi
  133. done
  134. fi
  135. }
  136. # Creates a symlink for a ($1) so that it may be used as block storage
  137. function safe-block-symlink(){
  138. local device="${1}"
  139. local symdir="${2}"
  140. mkdir -p "${symdir}"
  141. get-or-generate-uuid "${device}"
  142. local myuuid="${retuuid}"
  143. local sym="${symdir}/local-ssd-${myuuid}"
  144. # Do not "mkdir -p ${sym}" as that will cause unintended symlink behavior
  145. ln -s "${device}" "${sym}"
  146. echo "Created a symlink for SSD $ssd at ${sym}"
  147. chmod a+w "${sym}"
  148. }
  149. # Gets a pregenerated UUID from ${ssdmap} if it exists, otherwise generates a new
  150. # UUID and places it inside ${ssdmap}
  151. function get-or-generate-uuid(){
  152. local device="${1}"
  153. local ssdmap="/home/kubernetes/localssdmap.txt"
  154. echo "Generating or getting UUID from ${ssdmap}"
  155. if [[ ! -e "${ssdmap}" ]]; then
  156. touch "${ssdmap}"
  157. chmod +w "${ssdmap}"
  158. fi
  159. # each line of the ssdmap looks like "${device} persistent-uuid"
  160. if [[ ! -z $(grep ${device} ${ssdmap}) ]]; then
  161. #create symlink based on saved uuid
  162. local myuuid=$(grep ${device} ${ssdmap} | cut -d ' ' -f 2)
  163. else
  164. # generate new uuid and add it to the map
  165. local myuuid=$(uuidgen)
  166. if [[ ! ${?} -eq 0 ]]; then
  167. echo "Failed to generate valid UUID with uuidgen" >&2
  168. exit 2
  169. fi
  170. echo "${device} ${myuuid}" >> "${ssdmap}"
  171. fi
  172. if [[ -z "${myuuid}" ]]; then
  173. echo "Failed to get a uuid for device ${device} when symlinking." >&2
  174. exit 2
  175. fi
  176. retuuid="${myuuid}"
  177. }
  178. #Formats the given device ($1) if needed and mounts it at given mount point
  179. # ($2).
  180. function safe-format-and-mount() {
  181. local device="${1}"
  182. local mountpoint="${2}"
  183. # Format only if the disk is not already formatted.
  184. if ! tune2fs -l "${device}" ; then
  185. echo "Formatting '${device}'"
  186. mkfs.ext4 -F "${device}"
  187. fi
  188. mkdir -p "${mountpoint}"
  189. echo "Mounting '${device}' at '${mountpoint}'"
  190. mount -o discard,defaults "${device}" "${mountpoint}"
  191. chmod a+w "${mountpoint}"
  192. }
  193. # Gets a devices UUID and bind mounts the device to mount location in
  194. # /mnt/disks/by-id/
  195. function unique-uuid-bind-mount(){
  196. local mountpoint="${1}"
  197. local actual_device="${2}"
  198. # Trigger udev refresh so that newly formatted devices are propagated in by-uuid
  199. udevadm control --reload-rules
  200. udevadm trigger
  201. udevadm settle
  202. # grep the exact match of actual device, prevents substring matching
  203. local myuuid=$(ls -l /dev/disk/by-uuid/ | grep "/${actual_device}$" | tr -s ' ' | cut -d ' ' -f 9)
  204. # myuuid should be the uuid of the device as found in /dev/disk/by-uuid/
  205. if [[ -z "${myuuid}" ]]; then
  206. echo "Failed to get a uuid for device ${actual_device} when mounting." >&2
  207. exit 2
  208. fi
  209. # bindpoint should be the full path of the to-be-bound device
  210. local bindpoint="${UUID_MNT_PREFIX}-${interface}-fs/local-ssd-${myuuid}"
  211. safe-bind-mount "${mountpoint}" "${bindpoint}"
  212. }
  213. # Bind mounts device at mountpoint to bindpoint
  214. function safe-bind-mount(){
  215. local mountpoint="${1}"
  216. local bindpoint="${2}"
  217. # Mount device to the mountpoint
  218. mkdir -p "${bindpoint}"
  219. echo "Binding '${mountpoint}' at '${bindpoint}'"
  220. mount --bind "${mountpoint}" "${bindpoint}"
  221. chmod a+w "${bindpoint}"
  222. }
  223. # Mounts, bindmounts, or symlinks depending on the interface and format
  224. # of the incoming device
  225. function mount-ext(){
  226. local ssd="${1}"
  227. local devicenum="${2}"
  228. local interface="${3}"
  229. local format="${4}"
  230. if [[ -z "${devicenum}" ]]; then
  231. echo "Failed to get the local disk number for device ${ssd}" >&2
  232. exit 2
  233. fi
  234. # TODO: Handle partitioned disks. Right now this code just ignores partitions
  235. if [[ "${format}" == "fs" ]]; then
  236. if [[ "${interface}" == "scsi" ]]; then
  237. local actual_device=$(readlink -f "${ssd}" | cut -d '/' -f 3)
  238. # Error checking
  239. if [[ "${actual_device}" != sd* ]]; then
  240. echo "'actual_device' is not of the correct format. It must be the kernel name of the device, got ${actual_device} instead" >&2
  241. exit 1
  242. fi
  243. local mountpoint="/mnt/disks/ssd${devicenum}"
  244. else
  245. # This path is required because the existing Google images do not
  246. # expose NVMe devices in /dev/disk/by-id so we are using the /dev/nvme instead
  247. local actual_device=$(echo ${ssd} | cut -d '/' -f 3)
  248. # Error checking
  249. if [[ "${actual_device}" != nvme* ]]; then
  250. echo "'actual_device' is not of the correct format. It must be the kernel name of the device, got ${actual_device} instead" >&2
  251. exit 1
  252. fi
  253. local mountpoint="/mnt/disks/ssd-nvme${devicenum}"
  254. fi
  255. safe-format-and-mount "${ssd}" "${mountpoint}"
  256. # We only do the bindmount if users are using the new local ssd request method
  257. # see https://github.com/kubernetes/kubernetes/pull/53466#discussion_r146431894
  258. if [[ ! -z "${NODE_LOCAL_SSDS_EXT:-}" ]]; then
  259. unique-uuid-bind-mount "${mountpoint}" "${actual_device}"
  260. fi
  261. elif [[ "${format}" == "block" ]]; then
  262. local symdir="${UUID_BLOCK_PREFIX}-${interface}-block"
  263. safe-block-symlink "${ssd}" "${symdir}"
  264. else
  265. echo "Disk format must be either fs or block, got ${format}"
  266. fi
  267. }
  268. # Local ssds, if present, are mounted or symlinked to their appropriate
  269. # locations
  270. function ensure-local-ssds() {
  271. get-local-disk-num "scsi" "block"
  272. local scsiblocknum="${localdisknum}"
  273. local i=0
  274. for ssd in /dev/disk/by-id/google-local-ssd-*; do
  275. if [ -e "${ssd}" ]; then
  276. local devicenum=`echo ${ssd} | sed -e 's/\/dev\/disk\/by-id\/google-local-ssd-\([0-9]*\)/\1/'`
  277. if [[ "${i}" -lt "${scsiblocknum}" ]]; then
  278. mount-ext "${ssd}" "${devicenum}" "scsi" "block"
  279. else
  280. # GKE does not set NODE_LOCAL_SSDS so all non-block devices
  281. # are assumed to be filesystem devices
  282. mount-ext "${ssd}" "${devicenum}" "scsi" "fs"
  283. fi
  284. i=$((i+1))
  285. else
  286. echo "No local SCSI SSD disks found."
  287. fi
  288. done
  289. # The following mounts or symlinks NVMe devices
  290. get-local-disk-num "nvme" "block"
  291. local nvmeblocknum="${localdisknum}"
  292. local i=0
  293. for ssd in /dev/nvme*; do
  294. if [ -e "${ssd}" ]; then
  295. # This workaround to find if the NVMe device is a disk is required because
  296. # the existing Google images does not expose NVMe devices in /dev/disk/by-id
  297. if [[ `udevadm info --query=property --name=${ssd} | grep DEVTYPE | sed "s/DEVTYPE=//"` == "disk" ]]; then
  298. local devicenum=`echo ${ssd} | sed -e 's/\/dev\/nvme0n\([0-9]*\)/\1/'`
  299. if [[ "${i}" -lt "${nvmeblocknum}" ]]; then
  300. mount-ext "${ssd}" "${devicenum}" "nvme" "block"
  301. else
  302. mount-ext "${ssd}" "${devicenum}" "nvme" "fs"
  303. fi
  304. i=$((i+1))
  305. fi
  306. else
  307. echo "No local NVMe SSD disks found."
  308. fi
  309. done
  310. }
  311. # Installs logrotate configuration files
  312. function setup-logrotate() {
  313. mkdir -p /etc/logrotate.d/
  314. # Configure log rotation for all logs in /var/log, which is where k8s services
  315. # are configured to write their log files. Whenever logrotate is ran, this
  316. # config will:
  317. # * rotate the log file if its size is > 100Mb OR if one day has elapsed
  318. # * save rotated logs into a gzipped timestamped backup
  319. # * log file timestamp (controlled by 'dateformat') includes seconds too. This
  320. # ensures that logrotate can generate unique logfiles during each rotation
  321. # (otherwise it skips rotation if 'maxsize' is reached multiple times in a
  322. # day).
  323. # * keep only 5 old (rotated) logs, and will discard older logs.
  324. cat > /etc/logrotate.d/allvarlogs <<EOF
  325. /var/log/*.log {
  326. rotate ${LOGROTATE_FILES_MAX_COUNT:-5}
  327. copytruncate
  328. missingok
  329. notifempty
  330. compress
  331. maxsize ${LOGROTATE_MAX_SIZE:-100M}
  332. daily
  333. dateext
  334. dateformat -%Y%m%d-%s
  335. create 0644 root root
  336. }
  337. EOF
  338. # Configure log rotation for pod logs in /var/log/pods/NAMESPACE_NAME_UID.
  339. cat > /etc/logrotate.d/allpodlogs <<EOF
  340. /var/log/pods/*/*.log {
  341. rotate ${POD_LOG_MAX_FILE:-5}
  342. copytruncate
  343. missingok
  344. notifempty
  345. compress
  346. maxsize ${POD_LOG_MAX_SIZE:-5M}
  347. daily
  348. dateext
  349. dateformat -%Y%m%d-%s
  350. create 0644 root root
  351. }
  352. EOF
  353. }
  354. # Finds the master PD device; returns it in MASTER_PD_DEVICE
  355. function find-master-pd {
  356. MASTER_PD_DEVICE=""
  357. if [[ ! -e /dev/disk/by-id/google-master-pd ]]; then
  358. return
  359. fi
  360. device_info=$(ls -l /dev/disk/by-id/google-master-pd)
  361. relative_path=${device_info##* }
  362. MASTER_PD_DEVICE="/dev/disk/by-id/${relative_path}"
  363. }
  364. # Mounts a persistent disk (formatting if needed) to store the persistent data
  365. # on the master -- etcd's data, a few settings, and security certs/keys/tokens.
  366. # safe-format-and-mount only formats an unformatted disk, and mkdir -p will
  367. # leave a directory be if it already exists.
  368. function mount-master-pd {
  369. find-master-pd
  370. if [[ -z "${MASTER_PD_DEVICE:-}" ]]; then
  371. return
  372. fi
  373. echo "Mounting master-pd"
  374. local -r pd_path="/dev/disk/by-id/google-master-pd"
  375. local -r mount_point="/mnt/disks/master-pd"
  376. # Format and mount the disk, create directories on it for all of the master's
  377. # persistent data, and link them to where they're used.
  378. mkdir -p "${mount_point}"
  379. safe-format-and-mount "${pd_path}" "${mount_point}"
  380. echo "Mounted master-pd '${pd_path}' at '${mount_point}'"
  381. # NOTE: These locations on the PD store persistent data, so to maintain
  382. # upgradeability, these locations should not change. If they do, take care
  383. # to maintain a migration path from these locations to whatever new
  384. # locations.
  385. # Contains all the data stored in etcd.
  386. mkdir -m 700 -p "${mount_point}/var/etcd"
  387. ln -s -f "${mount_point}/var/etcd" /var/etcd
  388. mkdir -p /etc/srv
  389. # Contains the dynamically generated apiserver auth certs and keys.
  390. mkdir -p "${mount_point}/srv/kubernetes"
  391. ln -s -f "${mount_point}/srv/kubernetes" /etc/srv/kubernetes
  392. # Directory for kube-apiserver to store SSH key (if necessary).
  393. mkdir -p "${mount_point}/srv/sshproxy"
  394. ln -s -f "${mount_point}/srv/sshproxy" /etc/srv/sshproxy
  395. if ! id etcd &>/dev/null; then
  396. useradd -s /sbin/nologin -d /var/etcd etcd
  397. fi
  398. chown -R etcd "${mount_point}/var/etcd"
  399. chgrp -R etcd "${mount_point}/var/etcd"
  400. }
  401. # append_or_replace_prefixed_line ensures:
  402. # 1. the specified file exists
  403. # 2. existing lines with the specified ${prefix} are removed
  404. # 3. a new line with the specified ${prefix}${suffix} is appended
  405. function append_or_replace_prefixed_line {
  406. local -r file="${1:-}"
  407. local -r prefix="${2:-}"
  408. local -r suffix="${3:-}"
  409. local -r dirname="$(dirname ${file})"
  410. local -r tmpfile="$(mktemp -t filtered.XXXX --tmpdir=${dirname})"
  411. touch "${file}"
  412. awk "substr(\$0,0,length(\"${prefix}\")) != \"${prefix}\" { print }" "${file}" > "${tmpfile}"
  413. echo "${prefix}${suffix}" >> "${tmpfile}"
  414. mv "${tmpfile}" "${file}"
  415. }
  416. function write-pki-data {
  417. local data="${1}"
  418. local path="${2}"
  419. (umask 077; echo "${data}" | base64 --decode > "${path}")
  420. }
  421. function create-node-pki {
  422. echo "Creating node pki files"
  423. local -r pki_dir="/etc/srv/kubernetes/pki"
  424. mkdir -p "${pki_dir}"
  425. if [[ -z "${CA_CERT_BUNDLE:-}" ]]; then
  426. CA_CERT_BUNDLE="${CA_CERT}"
  427. fi
  428. CA_CERT_BUNDLE_PATH="${pki_dir}/ca-certificates.crt"
  429. write-pki-data "${CA_CERT_BUNDLE}" "${CA_CERT_BUNDLE_PATH}"
  430. if [[ ! -z "${KUBELET_CERT:-}" && ! -z "${KUBELET_KEY:-}" ]]; then
  431. KUBELET_CERT_PATH="${pki_dir}/kubelet.crt"
  432. write-pki-data "${KUBELET_CERT}" "${KUBELET_CERT_PATH}"
  433. KUBELET_KEY_PATH="${pki_dir}/kubelet.key"
  434. write-pki-data "${KUBELET_KEY}" "${KUBELET_KEY_PATH}"
  435. fi
  436. if [[ "${ENABLE_EGRESS_VIA_KONNECTIVITY_SERVICE:-false}" == "true" ]]; then
  437. mkdir -p "${pki_dir}/konnectivity-agent"
  438. KONNECTIVITY_AGENT_CA_CERT_PATH="${pki_dir}/konnectivity-agent/ca.crt"
  439. KONNECTIVITY_AGENT_CLIENT_KEY_PATH="${pki_dir}/konnectivity-agent/client.key"
  440. KONNECTIVITY_AGENT_CLIENT_CERT_PATH="${pki_dir}/konnectivity-agent/client.crt"
  441. write-pki-data "${KONNECTIVITY_AGENT_CA_CERT}" "${KONNECTIVITY_AGENT_CA_CERT_PATH}"
  442. write-pki-data "${KONNECTIVITY_AGENT_CLIENT_KEY}" "${KONNECTIVITY_AGENT_CLIENT_KEY_PATH}"
  443. write-pki-data "${KONNECTIVITY_AGENT_CLIENT_CERT}" "${KONNECTIVITY_AGENT_CLIENT_CERT_PATH}"
  444. fi
  445. }
  446. function create-master-pki {
  447. echo "Creating master pki files"
  448. local -r pki_dir="/etc/srv/kubernetes/pki"
  449. mkdir -p "${pki_dir}"
  450. CA_CERT_PATH="${pki_dir}/ca.crt"
  451. write-pki-data "${CA_CERT}" "${CA_CERT_PATH}"
  452. # this is not true on GKE
  453. if [[ ! -z "${CA_KEY:-}" ]]; then
  454. CA_KEY_PATH="${pki_dir}/ca.key"
  455. write-pki-data "${CA_KEY}" "${CA_KEY_PATH}"
  456. fi
  457. if [[ -z "${APISERVER_SERVER_CERT:-}" || -z "${APISERVER_SERVER_KEY:-}" ]]; then
  458. APISERVER_SERVER_CERT="${MASTER_CERT}"
  459. APISERVER_SERVER_KEY="${MASTER_KEY}"
  460. fi
  461. APISERVER_SERVER_CERT_PATH="${pki_dir}/apiserver.crt"
  462. write-pki-data "${APISERVER_SERVER_CERT}" "${APISERVER_SERVER_CERT_PATH}"
  463. APISERVER_SERVER_KEY_PATH="${pki_dir}/apiserver.key"
  464. write-pki-data "${APISERVER_SERVER_KEY}" "${APISERVER_SERVER_KEY_PATH}"
  465. if [[ -z "${APISERVER_CLIENT_CERT:-}" || -z "${APISERVER_CLIENT_KEY:-}" ]]; then
  466. APISERVER_CLIENT_CERT="${KUBEAPISERVER_CERT}"
  467. APISERVER_CLIENT_KEY="${KUBEAPISERVER_KEY}"
  468. fi
  469. APISERVER_CLIENT_CERT_PATH="${pki_dir}/apiserver-client.crt"
  470. write-pki-data "${APISERVER_CLIENT_CERT}" "${APISERVER_CLIENT_CERT_PATH}"
  471. APISERVER_CLIENT_KEY_PATH="${pki_dir}/apiserver-client.key"
  472. write-pki-data "${APISERVER_CLIENT_KEY}" "${APISERVER_CLIENT_KEY_PATH}"
  473. if [[ -z "${SERVICEACCOUNT_CERT:-}" || -z "${SERVICEACCOUNT_KEY:-}" ]]; then
  474. SERVICEACCOUNT_CERT="${MASTER_CERT}"
  475. SERVICEACCOUNT_KEY="${MASTER_KEY}"
  476. fi
  477. SERVICEACCOUNT_CERT_PATH="${pki_dir}/serviceaccount.crt"
  478. write-pki-data "${SERVICEACCOUNT_CERT}" "${SERVICEACCOUNT_CERT_PATH}"
  479. SERVICEACCOUNT_KEY_PATH="${pki_dir}/serviceaccount.key"
  480. write-pki-data "${SERVICEACCOUNT_KEY}" "${SERVICEACCOUNT_KEY_PATH}"
  481. if [[ ! -z "${REQUESTHEADER_CA_CERT:-}" ]]; then
  482. REQUESTHEADER_CA_CERT_PATH="${pki_dir}/aggr_ca.crt"
  483. write-pki-data "${REQUESTHEADER_CA_CERT}" "${REQUESTHEADER_CA_CERT_PATH}"
  484. PROXY_CLIENT_KEY_PATH="${pki_dir}/proxy_client.key"
  485. write-pki-data "${PROXY_CLIENT_KEY}" "${PROXY_CLIENT_KEY_PATH}"
  486. PROXY_CLIENT_CERT_PATH="${pki_dir}/proxy_client.crt"
  487. write-pki-data "${PROXY_CLIENT_CERT}" "${PROXY_CLIENT_CERT_PATH}"
  488. fi
  489. if [[ ! -z "${KONNECTIVITY_SERVER_CA_CERT:-}" ]]; then
  490. mkdir -p "${pki_dir}"/konnectivity-server
  491. #KONNECTIVITY_SERVER_CA_KEY_PATH="${pki_dir}/konnectivity-server/ca.key"
  492. #write-pki-data "${KONNECTIVITY_SERVER_CA_KEY}" "${KONNECTIVITY_SERVER_CA_KEY_PATH}"
  493. KONNECTIVITY_SERVER_CA_CERT_PATH="${pki_dir}/konnectivity-server/ca.crt"
  494. write-pki-data "${KONNECTIVITY_SERVER_CA_CERT}" "${KONNECTIVITY_SERVER_CA_CERT_PATH}"
  495. KONNECTIVITY_SERVER_KEY_PATH="${pki_dir}/konnectivity-server/server.key"
  496. write-pki-data "${KONNECTIVITY_SERVER_KEY}" "${KONNECTIVITY_SERVER_KEY_PATH}"
  497. KONNECTIVITY_SERVER_CERT_PATH="${pki_dir}/konnectivity-server/server.crt"
  498. write-pki-data "${KONNECTIVITY_SERVER_CERT}" "${KONNECTIVITY_SERVER_CERT_PATH}"
  499. KONNECTIVITY_SERVER_CLIENT_KEY_PATH="${pki_dir}/konnectivity-server/client.key"
  500. write-pki-data "${KONNECTIVITY_SERVER_CLIENT_KEY}" "${KONNECTIVITY_SERVER_CLIENT_KEY_PATH}"
  501. KONNECTIVITY_SERVER_CLIENT_CERT_PATH="${pki_dir}/konnectivity-server/client.crt"
  502. write-pki-data "${KONNECTIVITY_SERVER_CLIENT_CERT}" "${KONNECTIVITY_SERVER_CLIENT_CERT_PATH}"
  503. fi
  504. if [[ ! -z "${KONNECTIVITY_AGENT_CA_CERT:-}" ]]; then
  505. mkdir -p "${pki_dir}"/konnectivity-agent
  506. KONNECTIVITY_AGENT_CA_KEY_PATH="${pki_dir}/konnectivity-agent/ca.key"
  507. write-pki-data "${KONNECTIVITY_AGENT_CA_KEY}" "${KONNECTIVITY_AGENT_CA_KEY_PATH}"
  508. KONNECTIVITY_AGENT_CA_CERT_PATH="${pki_dir}/konnectivity-agent/ca.crt"
  509. write-pki-data "${KONNECTIVITY_AGENT_CA_CERT}" "${KONNECTIVITY_AGENT_CA_CERT_PATH}"
  510. KONNECTIVITY_AGENT_KEY_PATH="${pki_dir}/konnectivity-agent/server.key"
  511. write-pki-data "${KONNECTIVITY_AGENT_KEY}" "${KONNECTIVITY_AGENT_KEY_PATH}"
  512. KONNECTIVITY_AGENT_CERT_PATH="${pki_dir}/konnectivity-agent/server.crt"
  513. write-pki-data "${KONNECTIVITY_AGENT_CERT}" "${KONNECTIVITY_AGENT_CERT_PATH}"
  514. fi
  515. }
  516. # After the first boot and on upgrade, these files exist on the master-pd
  517. # and should never be touched again (except perhaps an additional service
  518. # account, see NB below.) One exception is if METADATA_CLOBBERS_CONFIG is
  519. # enabled. In that case the basic_auth.csv file will be rewritten to make
  520. # sure it matches the metadata source of truth.
  521. function create-master-auth {
  522. echo "Creating master auth files"
  523. local -r auth_dir="/etc/srv/kubernetes"
  524. local -r basic_auth_csv="${auth_dir}/basic_auth.csv"
  525. if [[ -n "${KUBE_PASSWORD:-}" && -n "${KUBE_USER:-}" ]]; then
  526. if [[ -e "${basic_auth_csv}" && "${METADATA_CLOBBERS_CONFIG:-false}" == "true" ]]; then
  527. # If METADATA_CLOBBERS_CONFIG is true, we want to rewrite the file
  528. # completely, because if we're changing KUBE_USER and KUBE_PASSWORD, we
  529. # have nothing to match on. The file is replaced just below with
  530. # append_or_replace_prefixed_line.
  531. rm "${basic_auth_csv}"
  532. fi
  533. append_or_replace_prefixed_line "${basic_auth_csv}" "${KUBE_PASSWORD},${KUBE_USER}," "admin,system:masters"
  534. fi
  535. local -r known_tokens_csv="${auth_dir}/known_tokens.csv"
  536. if [[ -e "${known_tokens_csv}" && "${METADATA_CLOBBERS_CONFIG:-false}" == "true" ]]; then
  537. rm "${known_tokens_csv}"
  538. fi
  539. if [[ -n "${KUBE_BEARER_TOKEN:-}" ]]; then
  540. append_or_replace_prefixed_line "${known_tokens_csv}" "${KUBE_BEARER_TOKEN}," "admin,admin,system:masters"
  541. fi
  542. if [[ -n "${KUBE_BOOTSTRAP_TOKEN:-}" ]]; then
  543. append_or_replace_prefixed_line "${known_tokens_csv}" "${KUBE_BOOTSTRAP_TOKEN}," "gcp:kube-bootstrap,uid:gcp:kube-bootstrap,system:masters"
  544. fi
  545. if [[ -n "${KUBE_CONTROLLER_MANAGER_TOKEN:-}" ]]; then
  546. append_or_replace_prefixed_line "${known_tokens_csv}" "${KUBE_CONTROLLER_MANAGER_TOKEN}," "system:kube-controller-manager,uid:system:kube-controller-manager"
  547. fi
  548. if [[ -n "${KUBE_SCHEDULER_TOKEN:-}" ]]; then
  549. append_or_replace_prefixed_line "${known_tokens_csv}" "${KUBE_SCHEDULER_TOKEN}," "system:kube-scheduler,uid:system:kube-scheduler"
  550. fi
  551. if [[ -n "${KUBE_CLUSTER_AUTOSCALER_TOKEN:-}" ]]; then
  552. append_or_replace_prefixed_line "${known_tokens_csv}" "${KUBE_CLUSTER_AUTOSCALER_TOKEN}," "cluster-autoscaler,uid:cluster-autoscaler"
  553. fi
  554. if [[ -n "${KUBE_PROXY_TOKEN:-}" ]]; then
  555. append_or_replace_prefixed_line "${known_tokens_csv}" "${KUBE_PROXY_TOKEN}," "system:kube-proxy,uid:kube_proxy"
  556. fi
  557. if [[ -n "${NODE_PROBLEM_DETECTOR_TOKEN:-}" ]]; then
  558. append_or_replace_prefixed_line "${known_tokens_csv}" "${NODE_PROBLEM_DETECTOR_TOKEN}," "system:node-problem-detector,uid:node-problem-detector"
  559. fi
  560. if [[ -n "${GCE_GLBC_TOKEN:-}" ]]; then
  561. append_or_replace_prefixed_line "${known_tokens_csv}" "${GCE_GLBC_TOKEN}," "system:controller:glbc,uid:system:controller:glbc"
  562. fi
  563. if [[ -n "${ADDON_MANAGER_TOKEN:-}" ]]; then
  564. append_or_replace_prefixed_line "${known_tokens_csv}" "${ADDON_MANAGER_TOKEN}," "system:addon-manager,uid:system:addon-manager,system:masters"
  565. fi
  566. if [[ -n "${EXTRA_STATIC_AUTH_COMPONENTS:-}" ]]; then
  567. # Create a static Bearer token and kubeconfig for extra, comma-separated components.
  568. IFS="," read -r -a extra_components <<< "${EXTRA_STATIC_AUTH_COMPONENTS:-}"
  569. for extra_component in "${extra_components[@]}"; do
  570. local token="$(secure_random 32)"
  571. append_or_replace_prefixed_line "${known_tokens_csv}" "${token}," "system:${extra_component},uid:system:${extra_component}"
  572. create-kubeconfig "${extra_component}" "${token}"
  573. done
  574. fi
  575. local use_cloud_config="false"
  576. cat <<EOF >/etc/gce.conf
  577. [global]
  578. EOF
  579. if [[ -n "${GCE_API_ENDPOINT:-}" ]]; then
  580. cat <<EOF >>/etc/gce.conf
  581. api-endpoint = ${GCE_API_ENDPOINT}
  582. EOF
  583. fi
  584. if [[ -n "${TOKEN_URL:-}" && -n "${TOKEN_BODY:-}" ]]; then
  585. use_cloud_config="true"
  586. cat <<EOF >>/etc/gce.conf
  587. token-url = ${TOKEN_URL}
  588. token-body = ${TOKEN_BODY}
  589. EOF
  590. fi
  591. if [[ -n "${CONTAINER_API_ENDPOINT:-}" ]]; then
  592. use_cloud_config="true"
  593. cat <<EOF >>/etc/gce.conf
  594. container-api-endpoint = ${CONTAINER_API_ENDPOINT}
  595. EOF
  596. fi
  597. if [[ -n "${PROJECT_ID:-}" ]]; then
  598. use_cloud_config="true"
  599. cat <<EOF >>/etc/gce.conf
  600. project-id = ${PROJECT_ID}
  601. EOF
  602. fi
  603. if [[ -n "${NETWORK_PROJECT_ID:-}" ]]; then
  604. use_cloud_config="true"
  605. cat <<EOF >>/etc/gce.conf
  606. network-project-id = ${NETWORK_PROJECT_ID}
  607. EOF
  608. fi
  609. if [[ -n "${NODE_NETWORK:-}" ]]; then
  610. use_cloud_config="true"
  611. cat <<EOF >>/etc/gce.conf
  612. network-name = ${NODE_NETWORK}
  613. EOF
  614. fi
  615. if [[ -n "${NODE_SUBNETWORK:-}" ]]; then
  616. use_cloud_config="true"
  617. cat <<EOF >>/etc/gce.conf
  618. subnetwork-name = ${NODE_SUBNETWORK}
  619. EOF
  620. fi
  621. if [[ -n "${NODE_INSTANCE_PREFIX:-}" ]]; then
  622. use_cloud_config="true"
  623. if [[ -n "${NODE_TAGS:-}" ]]; then
  624. # split NODE_TAGS into an array by comma.
  625. IFS=',' read -r -a node_tags <<< ${NODE_TAGS}
  626. else
  627. local -r node_tags="${NODE_INSTANCE_PREFIX}"
  628. fi
  629. cat <<EOF >>/etc/gce.conf
  630. node-instance-prefix = ${NODE_INSTANCE_PREFIX}
  631. EOF
  632. for tag in ${node_tags[@]}; do
  633. cat <<EOF >>/etc/gce.conf
  634. node-tags = ${tag}
  635. EOF
  636. done
  637. fi
  638. if [[ -n "${MULTIZONE:-}" ]]; then
  639. use_cloud_config="true"
  640. cat <<EOF >>/etc/gce.conf
  641. multizone = ${MULTIZONE}
  642. EOF
  643. fi
  644. # Multimaster indicates that the cluster is HA.
  645. # Currently the only HA clusters are regional.
  646. # If we introduce zonal multimaster this will need to be revisited.
  647. if [[ -n "${MULTIMASTER:-}" ]]; then
  648. use_cloud_config="true"
  649. cat <<EOF >>/etc/gce.conf
  650. regional = ${MULTIMASTER}
  651. EOF
  652. fi
  653. if [[ -n "${GCE_ALPHA_FEATURES:-}" ]]; then
  654. use_cloud_config="true"
  655. # split GCE_ALPHA_FEATURES into an array by comma.
  656. IFS=',' read -r -a alpha_features <<< ${GCE_ALPHA_FEATURES}
  657. for feature in ${alpha_features[@]}; do
  658. cat <<EOF >>/etc/gce.conf
  659. alpha-features = ${feature}
  660. EOF
  661. done
  662. fi
  663. if [[ -n "${SECONDARY_RANGE_NAME:-}" ]]; then
  664. use_cloud_config="true"
  665. cat <<EOF >> /etc/gce.conf
  666. secondary-range-name = ${SECONDARY_RANGE_NAME}
  667. EOF
  668. fi
  669. if [[ "${use_cloud_config}" != "true" ]]; then
  670. rm -f /etc/gce.conf
  671. fi
  672. if [[ -n "${GCP_AUTHN_URL:-}" ]]; then
  673. cat <<EOF >/etc/gcp_authn.config
  674. clusters:
  675. - name: gcp-authentication-server
  676. cluster:
  677. server: ${GCP_AUTHN_URL}
  678. users:
  679. - name: kube-apiserver
  680. user:
  681. auth-provider:
  682. name: gcp
  683. current-context: webhook
  684. contexts:
  685. - context:
  686. cluster: gcp-authentication-server
  687. user: kube-apiserver
  688. name: webhook
  689. EOF
  690. fi
  691. if [[ -n "${GCP_AUTHZ_URL:-}" ]]; then
  692. cat <<EOF >/etc/gcp_authz.config
  693. clusters:
  694. - name: gcp-authorization-server
  695. cluster:
  696. server: ${GCP_AUTHZ_URL}
  697. users:
  698. - name: kube-apiserver
  699. user:
  700. auth-provider:
  701. name: gcp
  702. current-context: webhook
  703. contexts:
  704. - context:
  705. cluster: gcp-authorization-server
  706. user: kube-apiserver
  707. name: webhook
  708. EOF
  709. fi
  710. if [[ "${ENABLE_EGRESS_VIA_KONNECTIVITY_SERVICE:-false}" == "true" ]]; then
  711. cat <<EOF >/etc/srv/kubernetes/egress_selector_configuration.yaml
  712. apiVersion: apiserver.k8s.io/v1alpha1
  713. kind: EgressSelectorConfiguration
  714. egressSelections:
  715. - name: cluster
  716. connection:
  717. type: http-connect
  718. httpConnect:
  719. url: https://127.0.0.1:8131
  720. caBundle: /etc/srv/kubernetes/pki/konnectivity-server/ca.crt
  721. clientKey: /etc/srv/kubernetes/pki/konnectivity-server/client.key
  722. clientCert: /etc/srv/kubernetes/pki/konnectivity-server/client.crt
  723. - name: master
  724. connection:
  725. type: direct
  726. - name: etcd
  727. connection:
  728. type: direct
  729. EOF
  730. fi
  731. if [[ -n "${WEBHOOK_GKE_EXEC_AUTH:-}" ]]; then
  732. if [[ -z "${EXEC_AUTH_PLUGIN_URL:-}" ]]; then
  733. 1>&2 echo "You requested GKE exec auth support for webhooks, but EXEC_AUTH_PLUGIN_URL was not specified. This configuration depends on gke-exec-auth-plugin for authenticating to the webhook endpoint."
  734. exit 1
  735. fi
  736. if [[ -z "${TOKEN_URL:-}" || -z "${TOKEN_BODY:-}" || -z "${TOKEN_BODY_UNQUOTED:-}" ]]; then
  737. 1>&2 echo "You requested GKE exec auth support for webhooks, but TOKEN_URL, TOKEN_BODY, and TOKEN_BODY_UNQUOTED were not provided. gke-exec-auth-plugin requires these values for its configuration."
  738. exit 1
  739. fi
  740. # kubeconfig to be used by webhooks with GKE exec auth support. Note that
  741. # the path to gke-exec-auth-plugin is the path when mounted inside the
  742. # kube-apiserver pod.
  743. cat <<EOF >/etc/srv/kubernetes/webhook.kubeconfig
  744. apiVersion: v1
  745. kind: Config
  746. users:
  747. - name: '*.googleapis.com'
  748. user:
  749. exec:
  750. apiVersion: "client.authentication.k8s.io/v1alpha1"
  751. command: /usr/bin/gke-exec-auth-plugin
  752. args:
  753. - --mode=alt-token
  754. - --alt-token-url=${TOKEN_URL}
  755. - --alt-token-body=${TOKEN_BODY_UNQUOTED}
  756. EOF
  757. fi
  758. if [[ -n "${ADMISSION_CONTROL:-}" ]]; then
  759. # Emit a basic admission control configuration file, with no plugins specified.
  760. cat <<EOF >/etc/srv/kubernetes/admission_controller_config.yaml
  761. apiVersion: apiserver.k8s.io/v1alpha1
  762. kind: AdmissionConfiguration
  763. plugins:
  764. EOF
  765. if [[ "${ADMISSION_CONTROL:-}" == *"ImagePolicyWebhook"* ]]; then
  766. if [[ -z "${GCP_IMAGE_VERIFICATION_URL:-}" ]]; then
  767. 1>&2 echo "The ImagePolicyWebhook admission control plugin was requested, but GCP_IMAGE_VERIFICATION_URL was not provided."
  768. exit 1
  769. fi
  770. 1>&2 echo "ImagePolicyWebhook admission control plugin requested. Configuring it to point at ${GCP_IMAGE_VERIFICATION_URL}"
  771. # ImagePolicyWebhook does not use gke-exec-auth-plugin for authenticating
  772. # to the webhook endpoint. Emit its special kubeconfig.
  773. cat <<EOF >/etc/srv/kubernetes/gcp_image_review.kubeconfig
  774. clusters:
  775. - name: gcp-image-review-server
  776. cluster:
  777. server: ${GCP_IMAGE_VERIFICATION_URL}
  778. users:
  779. - name: kube-apiserver
  780. user:
  781. auth-provider:
  782. name: gcp
  783. current-context: webhook
  784. contexts:
  785. - context:
  786. cluster: gcp-image-review-server
  787. user: kube-apiserver
  788. name: webhook
  789. EOF
  790. # Append config for ImagePolicyWebhook to the shared admission controller
  791. # configuration file.
  792. cat <<EOF >>/etc/srv/kubernetes/admission_controller_config.yaml
  793. - name: ImagePolicyWebhook
  794. configuration:
  795. imagePolicy:
  796. kubeConfigFile: /etc/srv/kubernetes/gcp_image_review.kubeconfig
  797. allowTTL: 30
  798. denyTTL: 30
  799. retryBackoff: 500
  800. defaultAllow: true
  801. EOF
  802. fi
  803. # If GKE exec auth for webhooks has been requested, then
  804. # ValidatingAdmissionWebhook should use it. Otherwise, run with the default
  805. # config.
  806. if [[ "${ADMISSION_CONTROL:-}" == *"ValidatingAdmissionWebhook"* && -n "${WEBHOOK_GKE_EXEC_AUTH:-}" ]]; then
  807. 1>&2 echo "ValidatingAdmissionWebhook requested, and WEBHOOK_GKE_EXEC_AUTH specified. Configuring ValidatingAdmissionWebhook to use gke-exec-auth-plugin."
  808. # Append config for ValidatingAdmissionWebhook to the shared admission
  809. # controller configuration file.
  810. cat <<EOF >>/etc/srv/kubernetes/admission_controller_config.yaml
  811. - name: ValidatingAdmissionWebhook
  812. configuration:
  813. apiVersion: apiserver.config.k8s.io/v1alpha1
  814. kind: WebhookAdmission
  815. kubeConfigFile: /etc/srv/kubernetes/webhook.kubeconfig
  816. EOF
  817. fi
  818. fi
  819. }
  820. # Write the config for the audit policy.
  821. function create-master-audit-policy {
  822. local -r path="${1}"
  823. local -r policy="${2:-}"
  824. if [[ -n "${policy}" ]]; then
  825. echo "${policy}" > "${path}"
  826. return
  827. fi
  828. # Known api groups
  829. local -r known_apis='
  830. - group: "" # core
  831. - group: "admissionregistration.k8s.io"
  832. - group: "apiextensions.k8s.io"
  833. - group: "apiregistration.k8s.io"
  834. - group: "apps"
  835. - group: "authentication.k8s.io"
  836. - group: "authorization.k8s.io"
  837. - group: "autoscaling"
  838. - group: "batch"
  839. - group: "certificates.k8s.io"
  840. - group: "extensions"
  841. - group: "metrics.k8s.io"
  842. - group: "networking.k8s.io"
  843. - group: "node.k8s.io"
  844. - group: "policy"
  845. - group: "rbac.authorization.k8s.io"
  846. - group: "scheduling.k8s.io"
  847. - group: "settings.k8s.io"
  848. - group: "storage.k8s.io"'
  849. cat <<EOF >"${path}"
  850. apiVersion: audit.k8s.io/v1
  851. kind: Policy
  852. rules:
  853. # The following requests were manually identified as high-volume and low-risk,
  854. # so drop them.
  855. - level: None
  856. users: ["system:kube-proxy"]
  857. verbs: ["watch"]
  858. resources:
  859. - group: "" # core
  860. resources: ["endpoints", "services", "services/status"]
  861. - level: None
  862. # Ingress controller reads 'configmaps/ingress-uid' through the unsecured port.
  863. # TODO(#46983): Change this to the ingress controller service account.
  864. users: ["system:unsecured"]
  865. namespaces: ["kube-system"]
  866. verbs: ["get"]
  867. resources:
  868. - group: "" # core
  869. resources: ["configmaps"]
  870. - level: None
  871. users: ["kubelet"] # legacy kubelet identity
  872. verbs: ["get"]
  873. resources:
  874. - group: "" # core
  875. resources: ["nodes", "nodes/status"]
  876. - level: None
  877. userGroups: ["system:nodes"]
  878. verbs: ["get"]
  879. resources:
  880. - group: "" # core
  881. resources: ["nodes", "nodes/status"]
  882. - level: None
  883. users:
  884. - system:kube-controller-manager
  885. - system:kube-scheduler
  886. - system:serviceaccount:kube-system:endpoint-controller
  887. verbs: ["get", "update"]
  888. namespaces: ["kube-system"]
  889. resources:
  890. - group: "" # core
  891. resources: ["endpoints"]
  892. - level: None
  893. users: ["system:apiserver"]
  894. verbs: ["get"]
  895. resources:
  896. - group: "" # core
  897. resources: ["namespaces", "namespaces/status", "namespaces/finalize"]
  898. - level: None
  899. users: ["cluster-autoscaler"]
  900. verbs: ["get", "update"]
  901. namespaces: ["kube-system"]
  902. resources:
  903. - group: "" # core
  904. resources: ["configmaps", "endpoints"]
  905. # Don't log HPA fetching metrics.
  906. - level: None
  907. users:
  908. - system:kube-controller-manager
  909. verbs: ["get", "list"]
  910. resources:
  911. - group: "metrics.k8s.io"
  912. # Don't log these read-only URLs.
  913. - level: None
  914. nonResourceURLs:
  915. - /healthz*
  916. - /version
  917. - /swagger*
  918. # Don't log events requests.
  919. - level: None
  920. resources:
  921. - group: "" # core
  922. resources: ["events"]
  923. # node and pod status calls from nodes are high-volume and can be large, don't log responses for expected updates from nodes
  924. - level: Request
  925. users: ["kubelet", "system:node-problem-detector", "system:serviceaccount:kube-system:node-problem-detector"]
  926. verbs: ["update","patch"]
  927. resources:
  928. - group: "" # core
  929. resources: ["nodes/status", "pods/status"]
  930. omitStages:
  931. - "RequestReceived"
  932. - level: Request
  933. userGroups: ["system:nodes"]
  934. verbs: ["update","patch"]
  935. resources:
  936. - group: "" # core
  937. resources: ["nodes/status", "pods/status"]
  938. omitStages:
  939. - "RequestReceived"
  940. # deletecollection calls can be large, don't log responses for expected namespace deletions
  941. - level: Request
  942. users: ["system:serviceaccount:kube-system:namespace-controller"]
  943. verbs: ["deletecollection"]
  944. omitStages:
  945. - "RequestReceived"
  946. # Secrets, ConfigMaps, and TokenReviews can contain sensitive & binary data,
  947. # so only log at the Metadata level.
  948. - level: Metadata
  949. resources:
  950. - group: "" # core
  951. resources: ["secrets", "configmaps"]
  952. - group: authentication.k8s.io
  953. resources: ["tokenreviews"]
  954. omitStages:
  955. - "RequestReceived"
  956. # Get repsonses can be large; skip them.
  957. - level: Request
  958. verbs: ["get", "list", "watch"]
  959. resources: ${known_apis}
  960. omitStages:
  961. - "RequestReceived"
  962. # Default level for known APIs
  963. - level: RequestResponse
  964. resources: ${known_apis}
  965. omitStages:
  966. - "RequestReceived"
  967. # Default level for all other requests.
  968. - level: Metadata
  969. omitStages:
  970. - "RequestReceived"
  971. EOF
  972. }
  973. # Writes the configuration file used by the webhook advanced auditing backend.
  974. function create-master-audit-webhook-config {
  975. local -r path="${1}"
  976. if [[ -n "${GCP_AUDIT_URL:-}" ]]; then
  977. # The webhook config file is a kubeconfig file describing the webhook endpoint.
  978. cat <<EOF >"${path}"
  979. clusters:
  980. - name: gcp-audit-server
  981. cluster:
  982. server: ${GCP_AUDIT_URL}
  983. users:
  984. - name: kube-apiserver
  985. user:
  986. auth-provider:
  987. name: gcp
  988. current-context: webhook
  989. contexts:
  990. - context:
  991. cluster: gcp-audit-server
  992. user: kube-apiserver
  993. name: webhook
  994. EOF
  995. fi
  996. }
  997. function create-kubeconfig {
  998. local component=$1
  999. local token=$2
  1000. echo "Creating kubeconfig file for component ${component}"
  1001. mkdir -p /etc/srv/kubernetes/${component}
  1002. cat <<EOF >/etc/srv/kubernetes/${component}/kubeconfig
  1003. apiVersion: v1
  1004. kind: Config
  1005. users:
  1006. - name: ${component}
  1007. user:
  1008. token: ${token}
  1009. clusters:
  1010. - name: local
  1011. cluster:
  1012. insecure-skip-tls-verify: true
  1013. server: https://localhost:443
  1014. contexts:
  1015. - context:
  1016. cluster: local
  1017. user: ${component}
  1018. name: ${component}
  1019. current-context: ${component}
  1020. EOF
  1021. }
  1022. # Arg 1: the IP address of the API server
  1023. function create-kubelet-kubeconfig() {
  1024. local apiserver_address="${1}"
  1025. if [[ -z "${apiserver_address}" ]]; then
  1026. echo "Must provide API server address to create Kubelet kubeconfig file!"
  1027. exit 1
  1028. fi
  1029. if [[ "${CREATE_BOOTSTRAP_KUBECONFIG:-true}" == "true" ]]; then
  1030. echo "Creating kubelet bootstrap-kubeconfig file"
  1031. cat <<EOF >/var/lib/kubelet/bootstrap-kubeconfig
  1032. apiVersion: v1
  1033. kind: Config
  1034. users:
  1035. - name: kubelet
  1036. user:
  1037. client-certificate: ${KUBELET_CERT_PATH}
  1038. client-key: ${KUBELET_KEY_PATH}
  1039. clusters:
  1040. - name: local
  1041. cluster:
  1042. server: https://${apiserver_address}
  1043. certificate-authority: ${CA_CERT_BUNDLE_PATH}
  1044. contexts:
  1045. - context:
  1046. cluster: local
  1047. user: kubelet
  1048. name: service-account-context
  1049. current-context: service-account-context
  1050. EOF
  1051. elif [[ "${FETCH_BOOTSTRAP_KUBECONFIG:-false}" == "true" ]]; then
  1052. echo "Fetching kubelet bootstrap-kubeconfig file from metadata"
  1053. get-metadata-value "instance/attributes/bootstrap-kubeconfig" >/var/lib/kubelet/bootstrap-kubeconfig
  1054. else
  1055. echo "Fetching kubelet kubeconfig file from metadata"
  1056. get-metadata-value "instance/attributes/kubeconfig" >/var/lib/kubelet/kubeconfig
  1057. fi
  1058. }
  1059. # Uses KUBELET_CA_CERT (falling back to CA_CERT), KUBELET_CERT, and KUBELET_KEY
  1060. # to generate a kubeconfig file for the kubelet to securely connect to the apiserver.
  1061. # Set REGISTER_MASTER_KUBELET to true if kubelet on the master node
  1062. # should register to the apiserver.
  1063. function create-master-kubelet-auth {
  1064. # Only configure the kubelet on the master if the required variables are
  1065. # set in the environment.
  1066. if [[ -n "${KUBELET_APISERVER:-}" && -n "${KUBELET_CERT:-}" && -n "${KUBELET_KEY:-}" ]]; then
  1067. REGISTER_MASTER_KUBELET="true"
  1068. create-kubelet-kubeconfig ${KUBELET_APISERVER}
  1069. fi
  1070. }
  1071. function create-kubeproxy-user-kubeconfig {
  1072. echo "Creating kube-proxy user kubeconfig file"
  1073. cat <<EOF >/var/lib/kube-proxy/kubeconfig
  1074. apiVersion: v1
  1075. kind: Config
  1076. users:
  1077. - name: kube-proxy
  1078. user:
  1079. token: ${KUBE_PROXY_TOKEN}
  1080. clusters:
  1081. - name: local
  1082. cluster:
  1083. certificate-authority-data: ${CA_CERT_BUNDLE}
  1084. contexts:
  1085. - context:
  1086. cluster: local
  1087. user: kube-proxy
  1088. name: service-account-context
  1089. current-context: service-account-context
  1090. EOF
  1091. }
  1092. function create-kubescheduler-policy-config {
  1093. echo "Creating kube-scheduler policy config file"
  1094. mkdir -p /etc/srv/kubernetes/kube-scheduler
  1095. cat <<EOF >/etc/srv/kubernetes/kube-scheduler/policy-config
  1096. ${SCHEDULER_POLICY_CONFIG}
  1097. EOF
  1098. }
  1099. function create-node-problem-detector-kubeconfig {
  1100. local apiserver_address="${1}"
  1101. if [[ -z "${apiserver_address}" ]]; then
  1102. echo "Must provide API server address to create node-problem-detector kubeconfig file!"
  1103. exit 1
  1104. fi
  1105. echo "Creating node-problem-detector kubeconfig file"
  1106. mkdir -p /var/lib/node-problem-detector
  1107. cat <<EOF >/var/lib/node-problem-detector/kubeconfig
  1108. apiVersion: v1
  1109. kind: Config
  1110. users:
  1111. - name: node-problem-detector
  1112. user:
  1113. token: ${NODE_PROBLEM_DETECTOR_TOKEN}
  1114. clusters:
  1115. - name: local
  1116. cluster:
  1117. server: https://${apiserver_address}
  1118. certificate-authority-data: ${CA_CERT}
  1119. contexts:
  1120. - context:
  1121. cluster: local
  1122. user: node-problem-detector
  1123. name: service-account-context
  1124. current-context: service-account-context
  1125. EOF
  1126. }
  1127. function create-node-problem-detector-kubeconfig-from-kubelet {
  1128. echo "Creating node-problem-detector kubeconfig from /var/lib/kubelet/kubeconfig"
  1129. mkdir -p /var/lib/node-problem-detector
  1130. cp /var/lib/kubelet/kubeconfig /var/lib/node-problem-detector/kubeconfig
  1131. }
  1132. function create-master-etcd-auth {
  1133. if [[ -n "${ETCD_CA_CERT:-}" && -n "${ETCD_PEER_KEY:-}" && -n "${ETCD_PEER_CERT:-}" ]]; then
  1134. local -r auth_dir="/etc/srv/kubernetes"
  1135. echo "${ETCD_CA_CERT}" | base64 --decode | gunzip > "${auth_dir}/etcd-ca.crt"
  1136. echo "${ETCD_PEER_KEY}" | base64 --decode > "${auth_dir}/etcd-peer.key"
  1137. echo "${ETCD_PEER_CERT}" | base64 --decode | gunzip > "${auth_dir}/etcd-peer.crt"
  1138. fi
  1139. }
  1140. function create-master-etcd-apiserver-auth {
  1141. if [[ -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
  1142. local -r auth_dir="/etc/srv/kubernetes/pki"
  1143. ETCD_APISERVER_CA_KEY_PATH="${auth_dir}/etcd-apiserver-ca.key"
  1144. echo "${ETCD_APISERVER_CA_KEY}" | base64 --decode > "${ETCD_APISERVER_CA_KEY_PATH}"
  1145. # Keep in sync with add-replica-to-etcd/remove-replica-from-etcd in util.sh.
  1146. ETCD_APISERVER_CA_CERT_PATH="${auth_dir}/etcd-apiserver-ca.crt"
  1147. echo "${ETCD_APISERVER_CA_CERT}" | base64 --decode | gunzip > "${ETCD_APISERVER_CA_CERT_PATH}"
  1148. ETCD_APISERVER_SERVER_KEY_PATH="${auth_dir}/etcd-apiserver-server.key"
  1149. echo "${ETCD_APISERVER_SERVER_KEY}" | base64 --decode > "${ETCD_APISERVER_SERVER_KEY_PATH}"
  1150. ETCD_APISERVER_SERVER_CERT_PATH="${auth_dir}/etcd-apiserver-server.crt"
  1151. echo "${ETCD_APISERVER_SERVER_CERT}" | base64 --decode | gunzip > "${ETCD_APISERVER_SERVER_CERT_PATH}"
  1152. # Keep in sync with add-replica-to-etcd/remove-replica-from-etcd in util.sh.
  1153. ETCD_APISERVER_CLIENT_KEY_PATH="${auth_dir}/etcd-apiserver-client.key"
  1154. echo "${ETCD_APISERVER_CLIENT_KEY}" | base64 --decode > "${ETCD_APISERVER_CLIENT_KEY_PATH}"
  1155. # Keep in sync with add-replica-to-etcd/remove-replica-from-etcd in util.sh.
  1156. ETCD_APISERVER_CLIENT_CERT_PATH="${auth_dir}/etcd-apiserver-client.crt"
  1157. echo "${ETCD_APISERVER_CLIENT_CERT}" | base64 --decode | gunzip > "${ETCD_APISERVER_CLIENT_CERT_PATH}"
  1158. fi
  1159. }
  1160. function create-master-konnectivity-server-apiserver-auth {
  1161. echo TODO: implement create-master-konnectivity-server-apiserver-auth
  1162. }
  1163. function assemble-docker-flags {
  1164. echo "Assemble docker command line flags"
  1165. local docker_opts="-p /var/run/docker.pid --iptables=false --ip-masq=false"
  1166. if [[ "${TEST_CLUSTER:-}" == "true" ]]; then
  1167. docker_opts+=" --log-level=debug"
  1168. else
  1169. docker_opts+=" --log-level=warn"
  1170. fi
  1171. local use_net_plugin="true"
  1172. if [[ "${NETWORK_PROVIDER:-}" == "kubenet" || "${NETWORK_PROVIDER:-}" == "cni" ]]; then
  1173. # set docker0 cidr to private ip address range to avoid conflict with cbr0 cidr range
  1174. docker_opts+=" --bip=169.254.123.1/24"
  1175. else
  1176. use_net_plugin="false"
  1177. docker_opts+=" --bridge=cbr0"
  1178. fi
  1179. # Decide whether to enable a docker registry mirror. This is taken from
  1180. # the "kube-env" metadata value.
  1181. if [[ -n "${DOCKER_REGISTRY_MIRROR_URL:-}" ]]; then
  1182. echo "Enable docker registry mirror at: ${DOCKER_REGISTRY_MIRROR_URL}"
  1183. docker_opts+=" --registry-mirror=${DOCKER_REGISTRY_MIRROR_URL}"
  1184. fi
  1185. # Configure docker logging
  1186. docker_opts+=" --log-driver=${DOCKER_LOG_DRIVER:-json-file}"
  1187. docker_opts+=" --log-opt=max-size=${DOCKER_LOG_MAX_SIZE:-10m}"
  1188. docker_opts+=" --log-opt=max-file=${DOCKER_LOG_MAX_FILE:-5}"
  1189. # Disable live-restore if the environment variable is set.
  1190. if [[ "${DISABLE_DOCKER_LIVE_RESTORE:-false}" == "true" ]]; then
  1191. docker_opts+=" --live-restore=false"
  1192. fi
  1193. echo "DOCKER_OPTS=\"${docker_opts} ${EXTRA_DOCKER_OPTS:-}\"" > /etc/default/docker
  1194. # Ensure TasksMax is sufficient for docker.
  1195. # (https://github.com/kubernetes/kubernetes/issues/51977)
  1196. echo "Extend the docker.service configuration to set a higher pids limit"
  1197. mkdir -p /etc/systemd/system/docker.service.d
  1198. cat <<EOF >/etc/systemd/system/docker.service.d/01tasksmax.conf
  1199. [Service]
  1200. TasksMax=infinity
  1201. EOF
  1202. systemctl daemon-reload
  1203. echo "Docker command line is updated. Restart docker to pick it up"
  1204. systemctl restart docker
  1205. }
  1206. # This function assembles the kubelet systemd service file and starts it
  1207. # using systemctl.
  1208. function start-kubelet {
  1209. echo "Start kubelet"
  1210. # TODO(#60123): The kubelet should create the cert-dir directory if it doesn't exist
  1211. mkdir -p /var/lib/kubelet/pki/
  1212. local kubelet_bin="${KUBE_HOME}/bin/kubelet"
  1213. local -r version="$("${kubelet_bin}" --version=true | cut -f2 -d " ")"
  1214. local -r builtin_kubelet="/usr/bin/kubelet"
  1215. if [[ "${TEST_CLUSTER:-}" == "true" ]]; then
  1216. # Determine which binary to use on test clusters. We use the built-in
  1217. # version only if the downloaded version is the same as the built-in
  1218. # version. This allows GCI to run some of the e2e tests to qualify the
  1219. # built-in kubelet.
  1220. if [[ -x "${builtin_kubelet}" ]]; then
  1221. local -r builtin_version="$("${builtin_kubelet}" --version=true | cut -f2 -d " ")"
  1222. if [[ "${builtin_version}" == "${version}" ]]; then
  1223. kubelet_bin="${builtin_kubelet}"
  1224. fi
  1225. fi
  1226. fi
  1227. echo "Using kubelet binary at ${kubelet_bin}"
  1228. local -r kubelet_env_file="/etc/default/kubelet"
  1229. local kubelet_opts="${KUBELET_ARGS} ${KUBELET_CONFIG_FILE_ARG:-}"
  1230. echo "KUBELET_OPTS=\"${kubelet_opts}\"" > "${kubelet_env_file}"
  1231. echo "KUBE_COVERAGE_FILE=\"/var/log/kubelet.cov\"" >> "${kubelet_env_file}"
  1232. # Write the systemd service file for kubelet.
  1233. cat <<EOF >/etc/systemd/system/kubelet.service
  1234. [Unit]
  1235. Description=Kubernetes kubelet
  1236. Requires=network-online.target
  1237. After=network-online.target
  1238. [Service]
  1239. Restart=always
  1240. RestartSec=10
  1241. EnvironmentFile=${kubelet_env_file}
  1242. ExecStart=${kubelet_bin} \$KUBELET_OPTS
  1243. [Install]
  1244. WantedBy=multi-user.target
  1245. EOF
  1246. systemctl daemon-reload
  1247. systemctl start kubelet.service
  1248. }
  1249. # This function assembles the node problem detector systemd service file and
  1250. # starts it using systemctl.
  1251. function start-node-problem-detector {
  1252. echo "Start node problem detector"
  1253. local -r npd_bin="${KUBE_HOME}/bin/node-problem-detector"
  1254. echo "Using node problem detector binary at ${npd_bin}"
  1255. local flags="${NODE_PROBLEM_DETECTOR_CUSTOM_FLAGS:-}"
  1256. if [[ -z "${flags}" ]]; then
  1257. local -r km_config="${KUBE_HOME}/node-problem-detector/config/kernel-monitor.json"
  1258. # TODO(random-liu): Handle this for alternative container runtime.
  1259. local -r dm_config="${KUBE_HOME}/node-problem-detector/config/docker-monitor.json"
  1260. local -r sm_config="${KUBE_HOME}/node-problem-detector/config/systemd-monitor.json"
  1261. local -r ssm_config="${KUBE_HOME}/node-problem-detector/config/system-stats-monitor.json"
  1262. local -r custom_km_config="${KUBE_HOME}/node-problem-detector/config/kernel-monitor-counter.json"
  1263. local -r custom_sm_config="${KUBE_HOME}/node-problem-detector/config/systemd-monitor-counter.json"
  1264. flags="${NPD_TEST_LOG_LEVEL:-"--v=2"} ${NPD_TEST_ARGS:-}"
  1265. flags+=" --logtostderr"
  1266. flags+=" --config.system-log-monitor=${km_config},${dm_config},${sm_config}"
  1267. flags+=" --config.system-stats-monitor=${ssm_config}"
  1268. flags+=" --config.custom-plugin-monitor=${custom_km_config},${custom_sm_config}"
  1269. local -r npd_port=${NODE_PROBLEM_DETECTOR_PORT:-20256}
  1270. flags+=" --port=${npd_port}"
  1271. if [[ -n "${EXTRA_NPD_ARGS:-}" ]]; then
  1272. flags+=" ${EXTRA_NPD_ARGS}"
  1273. fi
  1274. fi
  1275. flags+=" --apiserver-override=https://${KUBERNETES_MASTER_NAME}?inClusterConfig=false&auth=/var/lib/node-problem-detector/kubeconfig"
  1276. # Write the systemd service file for node problem detector.
  1277. cat <<EOF >/etc/systemd/system/node-problem-detector.service
  1278. [Unit]
  1279. Description=Kubernetes node problem detector
  1280. Requires=network-online.target
  1281. After=network-online.target
  1282. [Service]
  1283. Restart=always
  1284. RestartSec=10
  1285. ExecStart=${npd_bin} ${flags}
  1286. [Install]
  1287. WantedBy=multi-user.target
  1288. EOF
  1289. systemctl start node-problem-detector.service
  1290. }
  1291. # Create the log file and set its properties.
  1292. #
  1293. # $1 is the file to create.
  1294. # $2: the log owner uid to set for the log file.
  1295. # $3: the log owner gid to set for the log file.
  1296. function prepare-log-file {
  1297. touch $1
  1298. chmod 644 $1
  1299. chown "${2:-${LOG_OWNER_USER:-root}}":"${3:-${LOG_OWNER_GROUP:-root}}" $1
  1300. }
  1301. # Prepares parameters for kube-proxy manifest.
  1302. # $1 source path of kube-proxy manifest.
  1303. function prepare-kube-proxy-manifest-variables {
  1304. local -r src_file=$1;
  1305. local -r kubeconfig="--kubeconfig=/var/lib/kube-proxy/kubeconfig"
  1306. local kube_docker_registry="k8s.gcr.io"
  1307. if [[ -n "${KUBE_DOCKER_REGISTRY:-}" ]]; then
  1308. kube_docker_registry=${KUBE_DOCKER_REGISTRY}
  1309. fi
  1310. local -r kube_proxy_docker_tag=$(cat /home/kubernetes/kube-docker-files/kube-proxy.docker_tag)
  1311. local api_servers="--master=https://${KUBERNETES_MASTER_NAME}"
  1312. local params="${KUBEPROXY_TEST_LOG_LEVEL:-"--v=2"}"
  1313. if [[ -n "${FEATURE_GATES:-}" ]]; then
  1314. params+=" --feature-gates=${FEATURE_GATES}"
  1315. fi
  1316. if [[ "${KUBE_PROXY_MODE:-}" == "ipvs" ]];then
  1317. sudo modprobe -a ip_vs ip_vs_rr ip_vs_wrr ip_vs_sh nf_conntrack_ipv4
  1318. if [[ $? -eq 0 ]];
  1319. then
  1320. params+=" --proxy-mode=ipvs"
  1321. else
  1322. # If IPVS modules are not present, make sure the node does not come up as
  1323. # healthy.
  1324. exit 1
  1325. fi
  1326. fi
  1327. params+=" --iptables-sync-period=1m --iptables-min-sync-period=10s --ipvs-sync-period=1m --ipvs-min-sync-period=10s"
  1328. if [[ -n "${KUBEPROXY_TEST_ARGS:-}" ]]; then
  1329. params+=" ${KUBEPROXY_TEST_ARGS}"
  1330. fi
  1331. local container_env=""
  1332. local kube_cache_mutation_detector_env_name=""
  1333. local kube_cache_mutation_detector_env_value=""
  1334. if [[ -n "${ENABLE_CACHE_MUTATION_DETECTOR:-}" ]]; then
  1335. container_env="env:"
  1336. kube_cache_mutation_detector_env_name="- name: KUBE_CACHE_MUTATION_DETECTOR"
  1337. kube_cache_mutation_detector_env_value="value: \"${ENABLE_CACHE_MUTATION_DETECTOR}\""
  1338. fi
  1339. sed -i -e "s@{{kubeconfig}}@${kubeconfig}@g" ${src_file}
  1340. sed -i -e "s@{{pillar\['kube_docker_registry'\]}}@${kube_docker_registry}@g" ${src_file}
  1341. sed -i -e "s@{{pillar\['kube-proxy_docker_tag'\]}}@${kube_proxy_docker_tag}@g" ${src_file}
  1342. sed -i -e "s@{{params}}@${params}@g" ${src_file}
  1343. sed -i -e "s@{{container_env}}@${container_env}@g" ${src_file}
  1344. sed -i -e "s@{{kube_cache_mutation_detector_env_name}}@${kube_cache_mutation_detector_env_name}@g" ${src_file}
  1345. sed -i -e "s@{{kube_cache_mutation_detector_env_value}}@${kube_cache_mutation_detector_env_value}@g" ${src_file}
  1346. sed -i -e "s@{{ cpurequest }}@100m@g" ${src_file}
  1347. sed -i -e "s@{{api_servers_with_port}}@${api_servers}@g" ${src_file}
  1348. sed -i -e "s@{{kubernetes_service_host_env_value}}@${KUBERNETES_MASTER_NAME}@g" ${src_file}
  1349. if [[ -n "${CLUSTER_IP_RANGE:-}" ]]; then
  1350. sed -i -e "s@{{cluster_cidr}}@--cluster-cidr=${CLUSTER_IP_RANGE}@g" ${src_file}
  1351. fi
  1352. }
  1353. # Starts kube-proxy static pod.
  1354. function start-kube-proxy {
  1355. echo "Start kube-proxy static pod"
  1356. prepare-log-file /var/log/kube-proxy.log
  1357. local -r src_file="${KUBE_HOME}/kube-manifests/kubernetes/gci-trusty/kube-proxy.manifest"
  1358. prepare-kube-proxy-manifest-variables "${src_file}"
  1359. cp "${src_file}" /etc/kubernetes/manifests
  1360. }
  1361. # Replaces the variables in the etcd manifest file with the real values, and then
  1362. # copy the file to the manifest dir
  1363. # $1: value for variable 'suffix'
  1364. # $2: value for variable 'port'
  1365. # $3: value for variable 'server_port'
  1366. # $4: value for variable 'cpulimit'
  1367. # $5: pod name, which should be either etcd or etcd-events
  1368. function prepare-etcd-manifest {
  1369. local host_name=${ETCD_HOSTNAME:-$(hostname -s)}
  1370. local host_ip=$(${PYTHON} -c "import socket;print(socket.gethostbyname(\"${host_name}\"))")
  1371. local etcd_cluster=""
  1372. local cluster_state="new"
  1373. local etcd_protocol="http"
  1374. local etcd_apiserver_protocol="http"
  1375. local etcd_creds=""
  1376. local etcd_apiserver_creds="${ETCD_APISERVER_CREDS:-}"
  1377. local etcd_extra_args="${ETCD_EXTRA_ARGS:-}"
  1378. local suffix="$1"
  1379. local etcd_livenessprobe_port="$2"
  1380. if [[ -n "${INITIAL_ETCD_CLUSTER_STATE:-}" ]]; then
  1381. cluster_state="${INITIAL_ETCD_CLUSTER_STATE}"
  1382. fi
  1383. if [[ -n "${ETCD_CA_CERT:-}" && -n "${ETCD_PEER_KEY:-}" && -n "${ETCD_PEER_CERT:-}" ]]; then
  1384. etcd_creds=" --peer-trusted-ca-file /etc/srv/kubernetes/etcd-ca.crt --peer-cert-file /etc/srv/kubernetes/etcd-peer.crt --peer-key-file /etc/srv/kubernetes/etcd-peer.key -peer-client-cert-auth "
  1385. etcd_protocol="https"
  1386. fi
  1387. # mTLS should only be enabled for etcd server but not etcd-events. if $1 suffix is empty, it's etcd server.
  1388. if [[ -z "${suffix}" && -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
  1389. etcd_apiserver_creds=" --client-cert-auth --trusted-ca-file ${ETCD_APISERVER_CA_CERT_PATH} --cert-file ${ETCD_APISERVER_SERVER_CERT_PATH} --key-file ${ETCD_APISERVER_SERVER_KEY_PATH} "
  1390. etcd_apiserver_protocol="https"
  1391. etcd_livenessprobe_port="2382"
  1392. etcd_extra_args+=" --listen-metrics-urls=http://${ETCD_LISTEN_CLIENT_IP:-127.0.0.1}:${etcd_livenessprobe_port} "
  1393. fi
  1394. for host in $(echo "${INITIAL_ETCD_CLUSTER:-${host_name}}" | tr "," "\n"); do
  1395. etcd_host="etcd-${host}=${etcd_protocol}://${host}:$3"
  1396. if [[ -n "${etcd_cluster}" ]]; then
  1397. etcd_cluster+=","
  1398. fi
  1399. etcd_cluster+="${etcd_host}"
  1400. done
  1401. local -r temp_file="/tmp/$5"
  1402. cp "${KUBE_HOME}/kube-manifests/kubernetes/gci-trusty/etcd.manifest" "${temp_file}"
  1403. sed -i -e "s@{{ *suffix *}}@$1@g" "${temp_file}"
  1404. sed -i -e "s@{{ *port *}}@$2@g" "${temp_file}"
  1405. sed -i -e "s@{{ *server_port *}}@$3@g" "${temp_file}"
  1406. sed -i -e "s@{{ *cpulimit *}}@\"$4\"@g" "${temp_file}"
  1407. sed -i -e "s@{{ *hostname *}}@$host_name@g" "${temp_file}"
  1408. sed -i -e "s@{{ *host_ip *}}@$host_ip@g" "${temp_file}"
  1409. sed -i -e "s@{{ *etcd_cluster *}}@$etcd_cluster@g" "${temp_file}"
  1410. sed -i -e "s@{{ *liveness_probe_initial_delay *}}@${ETCD_LIVENESS_PROBE_INITIAL_DELAY_SEC:-15}@g" "${temp_file}"
  1411. sed -i -e "s@{{ *listen_client_ip *}}@${ETCD_LISTEN_CLIENT_IP:-127.0.0.1}@g" "${temp_file}"
  1412. # Get default storage backend from manifest file.
  1413. local -r default_storage_backend=$(cat "${temp_file}" | \
  1414. grep -o "{{ *pillar\.get('storage_backend', '\(.*\)') *}}" | \
  1415. sed -e "s@{{ *pillar\.get('storage_backend', '\(.*\)') *}}@\1@g")
  1416. if [[ -n "${STORAGE_BACKEND:-}" ]]; then
  1417. sed -i -e "s@{{ *pillar\.get('storage_backend', '\(.*\)') *}}@${STORAGE_BACKEND}@g" "${temp_file}"
  1418. else
  1419. sed -i -e "s@{{ *pillar\.get('storage_backend', '\(.*\)') *}}@\1@g" "${temp_file}"
  1420. fi
  1421. if [[ "${STORAGE_BACKEND:-${default_storage_backend}}" == "etcd3" ]]; then
  1422. sed -i -e "s@{{ *quota_bytes *}}@--quota-backend-bytes=${ETCD_QUOTA_BACKEND_BYTES:-4294967296}@g" "${temp_file}"
  1423. else
  1424. sed -i -e "s@{{ *quota_bytes *}}@@g" "${temp_file}"
  1425. fi
  1426. sed -i -e "s@{{ *cluster_state *}}@$cluster_state@g" "${temp_file}"
  1427. if [[ -n "${ETCD_IMAGE:-}" ]]; then
  1428. sed -i -e "s@{{ *pillar\.get('etcd_docker_tag', '\(.*\)') *}}@${ETCD_IMAGE}@g" "${temp_file}"
  1429. else
  1430. sed -i -e "s@{{ *pillar\.get('etcd_docker_tag', '\(.*\)') *}}@\1@g" "${temp_file}"
  1431. fi
  1432. if [[ -n "${ETCD_DOCKER_REPOSITORY:-}" ]]; then
  1433. sed -i -e "s@{{ *pillar\.get('etcd_docker_repository', '\(.*\)') *}}@${ETCD_DOCKER_REPOSITORY}@g" "${temp_file}"
  1434. else
  1435. sed -i -e "s@{{ *pillar\.get('etcd_docker_repository', '\(.*\)') *}}@\1@g" "${temp_file}"
  1436. fi
  1437. sed -i -e "s@{{ *etcd_protocol *}}@$etcd_protocol@g" "${temp_file}"
  1438. sed -i -e "s@{{ *etcd_apiserver_protocol *}}@$etcd_apiserver_protocol@g" "${temp_file}"
  1439. sed -i -e "s@{{ *etcd_creds *}}@$etcd_creds@g" "${temp_file}"
  1440. sed -i -e "s@{{ *etcd_apiserver_creds *}}@$etcd_apiserver_creds@g" "${temp_file}"
  1441. sed -i -e "s@{{ *etcd_extra_args *}}@$etcd_extra_args@g" "${temp_file}"
  1442. sed -i -e "s@{{ *etcd_livenessprobe_port *}}@$etcd_livenessprobe_port@g" "${temp_file}"
  1443. if [[ -n "${ETCD_VERSION:-}" ]]; then
  1444. sed -i -e "s@{{ *pillar\.get('etcd_version', '\(.*\)') *}}@${ETCD_VERSION}@g" "${temp_file}"
  1445. else
  1446. sed -i -e "s@{{ *pillar\.get('etcd_version', '\(.*\)') *}}@\1@g" "${temp_file}"
  1447. fi
  1448. # Replace the volume host path.
  1449. sed -i -e "s@/mnt/master-pd/var/etcd@/mnt/disks/master-pd/var/etcd@g" "${temp_file}"
  1450. mv "${temp_file}" /etc/kubernetes/manifests
  1451. }
  1452. function start-etcd-empty-dir-cleanup-pod {
  1453. local -r src_file="${KUBE_HOME}/kube-manifests/kubernetes/gci-trusty/etcd-empty-dir-cleanup.yaml"
  1454. cp "${src_file}" "/etc/kubernetes/manifests"
  1455. }
  1456. # Starts etcd server pod (and etcd-events pod if needed).
  1457. # More specifically, it prepares dirs and files, sets the variable value
  1458. # in the manifests, and copies them to /etc/kubernetes/manifests.
  1459. function start-etcd-servers {
  1460. echo "Start etcd pods"
  1461. if [[ -d /etc/etcd ]]; then
  1462. rm -rf /etc/etcd
  1463. fi
  1464. if [[ -e /etc/default/etcd ]]; then
  1465. rm -f /etc/default/etcd
  1466. fi
  1467. if [[ -e /etc/systemd/system/etcd.service ]]; then
  1468. rm -f /etc/systemd/system/etcd.service
  1469. fi
  1470. if [[ -e /etc/init.d/etcd ]]; then
  1471. rm -f /etc/init.d/etcd
  1472. fi
  1473. prepare-log-file /var/log/etcd.log
  1474. prepare-etcd-manifest "" "2379" "2380" "200m" "etcd.manifest"
  1475. prepare-log-file /var/log/etcd-events.log
  1476. prepare-etcd-manifest "-events" "4002" "2381" "100m" "etcd-events.manifest"
  1477. }
  1478. # Replaces the variables in the konnectivity-server manifest file with the real values, and then
  1479. # copy the file to the manifest dir
  1480. # $1: value for variable "server_port"
  1481. # $2: value for variable "agent_port"
  1482. # $3: value for bariable "admin_port"
  1483. function prepare-konnectivity-server-manifest {
  1484. local -r temp_file="/tmp/konnectivity-server.yaml"
  1485. params=()
  1486. cp "${KUBE_HOME}/kube-manifests/kubernetes/gci-trusty/konnectivity-server.yaml" "${temp_file}"
  1487. params+=("--log-file=/var/log/konnectivity-server.log")
  1488. params+=("--logtostderr=false")
  1489. params+=("--log-file-max-size=0")
  1490. params+=("--server-ca-cert=${KONNECTIVITY_SERVER_CA_CERT_PATH}")
  1491. params+=("--server-cert=${KONNECTIVITY_SERVER_CERT_PATH}")
  1492. params+=("--server-key=${KONNECTIVITY_SERVER_KEY_PATH}")
  1493. params+=("--cluster-ca-cert=${KONNECTIVITY_AGENT_CA_CERT_PATH}")
  1494. params+=("--cluster-cert=${KONNECTIVITY_AGENT_CERT_PATH}")
  1495. params+=("--cluster-key=${KONNECTIVITY_AGENT_KEY_PATH}")
  1496. params+=("--mode=http-connect")
  1497. params+=("--server-port=$1")
  1498. params+=("--agent-port=$2")
  1499. params+=("--admin-port=$3")
  1500. konnectivity_args=""
  1501. for param in "${params[@]}"; do
  1502. konnectivity_args+=", \"${param}\""
  1503. done
  1504. sed -i -e "s@{{ *konnectivity_args *}}@${konnectivity_args}@g" "${temp_file}"
  1505. sed -i -e "s@{{ *server_port *}}@$1@g" "${temp_file}"
  1506. sed -i -e "s@{{ *agent_port *}}@$2@g" "${temp_file}"
  1507. sed -i -e "s@{{ *admin_port *}}@$3@g" "${temp_file}"
  1508. sed -i -e "s@{{ *liveness_probe_initial_delay *}}@30@g" "${temp_file}"
  1509. mv "${temp_file}" /etc/kubernetes/manifests
  1510. }
  1511. # Starts konnectivity server pod.
  1512. # More specifically, it prepares dirs and files, sets the variable value
  1513. # in the manifests, and copies them to /etc/kubernetes/manifests.
  1514. function start-konnectivity-server {
  1515. echo "Start konnectivity server pods"
  1516. prepare-log-file /var/log/konnectivity-server.log
  1517. prepare-konnectivity-server-manifest "8131" "8132" "8133"
  1518. }
  1519. # Calculates the following variables based on env variables, which will be used
  1520. # by the manifests of several kube-master components.
  1521. # CLOUD_CONFIG_OPT
  1522. # CLOUD_CONFIG_VOLUME
  1523. # CLOUD_CONFIG_MOUNT
  1524. # DOCKER_REGISTRY
  1525. # FLEXVOLUME_HOSTPATH_MOUNT
  1526. # FLEXVOLUME_HOSTPATH_VOLUME
  1527. # INSECURE_PORT_MAPPING
  1528. function compute-master-manifest-variables {
  1529. CLOUD_CONFIG_OPT=""
  1530. CLOUD_CONFIG_VOLUME=""
  1531. CLOUD_CONFIG_MOUNT=""
  1532. if [[ -f /etc/gce.conf ]]; then
  1533. CLOUD_CONFIG_OPT="--cloud-config=/etc/gce.conf"
  1534. CLOUD_CONFIG_VOLUME="{\"name\": \"cloudconfigmount\",\"hostPath\": {\"path\": \"/etc/gce.conf\", \"type\": \"FileOrCreate\"}},"
  1535. CLOUD_CONFIG_MOUNT="{\"name\": \"cloudconfigmount\",\"mountPath\": \"/etc/gce.conf\", \"readOnly\": true},"
  1536. fi
  1537. DOCKER_REGISTRY="k8s.gcr.io"
  1538. if [[ -n "${KUBE_DOCKER_REGISTRY:-}" ]]; then
  1539. DOCKER_REGISTRY="${KUBE_DOCKER_REGISTRY}"
  1540. fi
  1541. FLEXVOLUME_HOSTPATH_MOUNT=""
  1542. FLEXVOLUME_HOSTPATH_VOLUME=""
  1543. if [[ -n "${VOLUME_PLUGIN_DIR:-}" ]]; then
  1544. FLEXVOLUME_HOSTPATH_MOUNT="{ \"name\": \"flexvolumedir\", \"mountPath\": \"${VOLUME_PLUGIN_DIR}\", \"readOnly\": true},"
  1545. FLEXVOLUME_HOSTPATH_VOLUME="{ \"name\": \"flexvolumedir\", \"hostPath\": {\"path\": \"${VOLUME_PLUGIN_DIR}\"}},"
  1546. fi
  1547. INSECURE_PORT_MAPPING=""
  1548. if [[ "${ENABLE_APISERVER_INSECURE_PORT:-false}" == "true" ]]; then
  1549. INSECURE_PORT_MAPPING="{ \"name\": \"local\", \"containerPort\": 8080, \"hostPort\": 8080},"
  1550. fi
  1551. }
  1552. # A helper function that bind mounts kubelet dirs for running mount in a chroot
  1553. function prepare-mounter-rootfs {
  1554. echo "Prepare containerized mounter"
  1555. mount --bind "${CONTAINERIZED_MOUNTER_HOME}" "${CONTAINERIZED_MOUNTER_HOME}"
  1556. mount -o remount,exec "${CONTAINERIZED_MOUNTER_HOME}"
  1557. CONTAINERIZED_MOUNTER_ROOTFS="${CONTAINERIZED_MOUNTER_HOME}/rootfs"
  1558. mount --rbind /var/lib/kubelet/ "${CONTAINERIZED_MOUNTER_ROOTFS}/var/lib/kubelet"
  1559. mount --make-rshared "${CONTAINERIZED_MOUNTER_ROOTFS}/var/lib/kubelet"
  1560. mount --bind -o ro /proc "${CONTAINERIZED_MOUNTER_ROOTFS}/proc"
  1561. mount --bind -o ro /dev "${CONTAINERIZED_MOUNTER_ROOTFS}/dev"
  1562. cp /etc/resolv.conf "${CONTAINERIZED_MOUNTER_ROOTFS}/etc/"
  1563. }
  1564. # Updates node labels used by addons.
  1565. function update-legacy-addon-node-labels() {
  1566. # need kube-apiserver to be ready
  1567. until kubectl get nodes; do
  1568. sleep 5
  1569. done
  1570. update-node-label "beta.kubernetes.io/metadata-proxy-ready=true,cloud.google.com/metadata-proxy-ready!=true" "cloud.google.com/metadata-proxy-ready=true"
  1571. update-node-label "beta.kubernetes.io/kube-proxy-ds-ready=true,node.kubernetes.io/kube-proxy-ds-ready!=true" "node.kubernetes.io/kube-proxy-ds-ready=true"
  1572. update-node-label "beta.kubernetes.io/masq-agent-ds-ready=true,node.kubernetes.io/masq-agent-ds-ready!=true" "node.kubernetes.io/masq-agent-ds-ready=true"
  1573. }
  1574. # A helper function for labeling all nodes matching a given selector.
  1575. # Runs: kubectl label --overwrite nodes -l "${1}" "${2}"
  1576. # Retries on failure
  1577. #
  1578. # $1: label selector of nodes
  1579. # $2: label to apply
  1580. function update-node-label() {
  1581. local selector="$1"
  1582. local label="$2"
  1583. local retries=5
  1584. until (( retries == 0 )); do
  1585. if kubectl label --overwrite nodes -l "${selector}" "${label}"; then
  1586. break
  1587. fi
  1588. (( retries-- ))
  1589. sleep 3
  1590. done
  1591. }
  1592. # Starts kubernetes controller manager.
  1593. # It prepares the log file, loads the docker image, calculates variables, sets them
  1594. # in the manifest file, and then copies the manifest file to /etc/kubernetes/manifests.
  1595. #
  1596. # Assumed vars (which are calculated in function compute-master-manifest-variables)
  1597. # CLOUD_CONFIG_OPT
  1598. # CLOUD_CONFIG_VOLUME
  1599. # CLOUD_CONFIG_MOUNT
  1600. # DOCKER_REGISTRY
  1601. function start-kube-controller-manager {
  1602. echo "Start kubernetes controller-manager"
  1603. create-kubeconfig "kube-controller-manager" ${KUBE_CONTROLLER_MANAGER_TOKEN}
  1604. prepare-log-file /var/log/kube-controller-manager.log
  1605. # Calculate variables and assemble the command line.
  1606. local params="${CONTROLLER_MANAGER_TEST_LOG_LEVEL:-"--v=2"} ${CONTROLLER_MANAGER_TEST_ARGS:-} ${CLOUD_CONFIG_OPT}"
  1607. params+=" --use-service-account-credentials"
  1608. params+=" --cloud-provider=gce"
  1609. params+=" --kubeconfig=/etc/srv/kubernetes/kube-controller-manager/kubeconfig"
  1610. params+=" --root-ca-file=${CA_CERT_BUNDLE_PATH}"
  1611. params+=" --service-account-private-key-file=${SERVICEACCOUNT_KEY_PATH}"
  1612. if [[ -n "${ENABLE_GARBAGE_COLLECTOR:-}" ]]; then
  1613. params+=" --enable-garbage-collector=${ENABLE_GARBAGE_COLLECTOR}"
  1614. fi
  1615. if [[ -n "${INSTANCE_PREFIX:-}" ]]; then
  1616. params+=" --cluster-name=${INSTANCE_PREFIX}"
  1617. fi
  1618. if [[ -n "${CLUSTER_IP_RANGE:-}" ]]; then
  1619. params+=" --cluster-cidr=${CLUSTER_IP_RANGE}"
  1620. fi
  1621. if [[ -n "${CA_KEY:-}" ]]; then
  1622. params+=" --cluster-signing-cert-file=${CA_CERT_PATH}"
  1623. params+=" --cluster-signing-key-file=${CA_KEY_PATH}"
  1624. fi
  1625. if [[ -n "${SERVICE_CLUSTER_IP_RANGE:-}" ]]; then
  1626. params+=" --service-cluster-ip-range=${SERVICE_CLUSTER_IP_RANGE}"
  1627. fi
  1628. if [[ -n "${CONCURRENT_SERVICE_SYNCS:-}" ]]; then
  1629. params+=" --concurrent-service-syncs=${CONCURRENT_SERVICE_SYNCS}"
  1630. fi
  1631. if [[ "${NETWORK_PROVIDER:-}" == "kubenet" ]]; then
  1632. params+=" --allocate-node-cidrs=true"
  1633. elif [[ -n "${ALLOCATE_NODE_CIDRS:-}" ]]; then
  1634. params+=" --allocate-node-cidrs=${ALLOCATE_NODE_CIDRS}"
  1635. fi
  1636. if [[ -n "${TERMINATED_POD_GC_THRESHOLD:-}" ]]; then
  1637. params+=" --terminated-pod-gc-threshold=${TERMINATED_POD_GC_THRESHOLD}"
  1638. fi
  1639. if [[ "${ENABLE_IP_ALIASES:-}" == 'true' ]]; then
  1640. params+=" --cidr-allocator-type=${NODE_IPAM_MODE}"
  1641. params+=" --configure-cloud-routes=false"
  1642. fi
  1643. if [[ -n "${FEATURE_GATES:-}" ]]; then
  1644. params+=" --feature-gates=${FEATURE_GATES}"
  1645. fi
  1646. if [[ -n "${VOLUME_PLUGIN_DIR:-}" ]]; then
  1647. params+=" --flex-volume-plugin-dir=${VOLUME_PLUGIN_DIR}"
  1648. fi
  1649. if [[ -n "${CLUSTER_SIGNING_DURATION:-}" ]]; then
  1650. params+=" --experimental-cluster-signing-duration=$CLUSTER_SIGNING_DURATION"
  1651. fi
  1652. # Disable using HPA metrics REST clients if metrics-server isn't enabled,
  1653. # or if we want to explicitly disable it by setting HPA_USE_REST_CLIENT.
  1654. if [[ "${ENABLE_METRICS_SERVER:-}" != "true" ]] ||
  1655. [[ "${HPA_USE_REST_CLIENTS:-}" == "false" ]]; then
  1656. params+=" --horizontal-pod-autoscaler-use-rest-clients=false"
  1657. fi
  1658. if [[ -n "${PV_RECYCLER_OVERRIDE_TEMPLATE:-}" ]]; then
  1659. params+=" --pv-recycler-pod-template-filepath-nfs=$PV_RECYCLER_OVERRIDE_TEMPLATE"
  1660. params+=" --pv-recycler-pod-template-filepath-hostpath=$PV_RECYCLER_OVERRIDE_TEMPLATE"
  1661. fi
  1662. if [[ -n "${RUN_CONTROLLERS:-}" ]]; then
  1663. params+=" --controllers=${RUN_CONTROLLERS}"
  1664. fi
  1665. local -r kube_rc_docker_tag=$(cat /home/kubernetes/kube-docker-files/kube-controller-manager.docker_tag)
  1666. local container_env=""
  1667. if [[ -n "${ENABLE_CACHE_MUTATION_DETECTOR:-}" ]]; then
  1668. container_env="\"env\":[{\"name\": \"KUBE_CACHE_MUTATION_DETECTOR\", \"value\": \"${ENABLE_CACHE_MUTATION_DETECTOR}\"}],"
  1669. fi
  1670. local -r src_file="${KUBE_HOME}/kube-manifests/kubernetes/gci-trusty/kube-controller-manager.manifest"
  1671. # Evaluate variables.
  1672. sed -i -e "s@{{pillar\['kube_docker_registry'\]}}@${DOCKER_REGISTRY}@g" "${src_file}"
  1673. sed -i -e "s@{{pillar\['kube-controller-manager_docker_tag'\]}}@${kube_rc_docker_tag}@g" "${src_file}"
  1674. sed -i -e "s@{{params}}@${params}@g" "${src_file}"
  1675. sed -i -e "s@{{container_env}}@${container_env}@g" ${src_file}
  1676. sed -i -e "s@{{cloud_config_mount}}@${CLOUD_CONFIG_MOUNT}@g" "${src_file}"
  1677. sed -i -e "s@{{cloud_config_volume}}@${CLOUD_CONFIG_VOLUME}@g" "${src_file}"
  1678. sed -i -e "s@{{additional_cloud_config_mount}}@@g" "${src_file}"
  1679. sed -i -e "s@{{additional_cloud_config_volume}}@@g" "${src_file}"
  1680. sed -i -e "s@{{pv_recycler_mount}}@${PV_RECYCLER_MOUNT}@g" "${src_file}"
  1681. sed -i -e "s@{{pv_recycler_volume}}@${PV_RECYCLER_VOLUME}@g" "${src_file}"
  1682. sed -i -e "s@{{flexvolume_hostpath_mount}}@${FLEXVOLUME_HOSTPATH_MOUNT}@g" "${src_file}"
  1683. sed -i -e "s@{{flexvolume_hostpath}}@${FLEXVOLUME_HOSTPATH_VOLUME}@g" "${src_file}"
  1684. sed -i -e "s@{{cpurequest}}@${KUBE_CONTROLLER_MANAGER_CPU_REQUEST}@g" "${src_file}"
  1685. cp "${src_file}" /etc/kubernetes/manifests
  1686. }
  1687. # Starts kubernetes scheduler.
  1688. # It prepares the log file, loads the docker image, calculates variables, sets them
  1689. # in the manifest file, and then copies the manifest file to /etc/kubernetes/manifests.
  1690. #
  1691. # Assumed vars (which are calculated in compute-master-manifest-variables)
  1692. # DOCKER_REGISTRY
  1693. function start-kube-scheduler {
  1694. echo "Start kubernetes scheduler"
  1695. create-kubeconfig "kube-scheduler" ${KUBE_SCHEDULER_TOKEN}
  1696. prepare-log-file /var/log/kube-scheduler.log
  1697. # Calculate variables and set them in the manifest.
  1698. params="${SCHEDULER_TEST_LOG_LEVEL:-"--v=2"} ${SCHEDULER_TEST_ARGS:-}"
  1699. params+=" --kubeconfig=/etc/srv/kubernetes/kube-scheduler/kubeconfig"
  1700. if [[ -n "${FEATURE_GATES:-}" ]]; then
  1701. params+=" --feature-gates=${FEATURE_GATES}"
  1702. fi
  1703. if [[ -n "${SCHEDULING_ALGORITHM_PROVIDER:-}" ]]; then
  1704. params+=" --algorithm-provider=${SCHEDULING_ALGORITHM_PROVIDER}"
  1705. fi
  1706. if [[ -n "${SCHEDULER_POLICY_CONFIG:-}" ]]; then
  1707. create-kubescheduler-policy-config
  1708. params+=" --use-legacy-policy-config"
  1709. params+=" --policy-config-file=/etc/srv/kubernetes/kube-scheduler/policy-config"
  1710. fi
  1711. local -r kube_scheduler_docker_tag=$(cat "${KUBE_HOME}/kube-docker-files/kube-scheduler.docker_tag")
  1712. # Remove salt comments and replace variables with values.
  1713. local -r src_file="${KUBE_HOME}/kube-manifests/kubernetes/gci-trusty/kube-scheduler.manifest"
  1714. sed -i -e "s@{{params}}@${params}@g" "${src_file}"
  1715. sed -i -e "s@{{pillar\['kube_docker_registry'\]}}@${DOCKER_REGISTRY}@g" "${src_file}"
  1716. sed -i -e "s@{{pillar\['kube-scheduler_docker_tag'\]}}@${kube_scheduler_docker_tag}@g" "${src_file}"
  1717. sed -i -e "s@{{cpurequest}}@${KUBE_SCHEDULER_CPU_REQUEST}@g" "${src_file}"
  1718. cp "${src_file}" /etc/kubernetes/manifests
  1719. }
  1720. # Starts cluster autoscaler.
  1721. # Assumed vars (which are calculated in function compute-master-manifest-variables)
  1722. # CLOUD_CONFIG_OPT
  1723. # CLOUD_CONFIG_VOLUME
  1724. # CLOUD_CONFIG_MOUNT
  1725. function start-cluster-autoscaler {
  1726. if [[ "${ENABLE_CLUSTER_AUTOSCALER:-}" == "true" ]]; then
  1727. echo "Start kubernetes cluster autoscaler"
  1728. setup-addon-manifests "addons" "rbac/cluster-autoscaler"
  1729. create-kubeconfig "cluster-autoscaler" ${KUBE_CLUSTER_AUTOSCALER_TOKEN}
  1730. prepare-log-file /var/log/cluster-autoscaler.log
  1731. # Remove salt comments and replace variables with values
  1732. local -r src_file="${KUBE_HOME}/kube-manifests/kubernetes/gci-trusty/cluster-autoscaler.manifest"
  1733. local params="${AUTOSCALER_MIG_CONFIG} ${CLOUD_CONFIG_OPT} ${AUTOSCALER_EXPANDER_CONFIG:---expander=price}"
  1734. params+=" --kubeconfig=/etc/srv/kubernetes/cluster-autoscaler/kubeconfig"
  1735. # split the params into separate arguments passed to binary
  1736. local params_split
  1737. params_split=$(eval "for param in $params; do echo -n \\\"\$param\\\",; done")
  1738. params_split=${params_split%?}
  1739. sed -i -e "s@{{params}}@${params_split}@g" "${src_file}"
  1740. sed -i -e "s@{{cloud_config_mount}}@${CLOUD_CONFIG_MOUNT}@g" "${src_file}"
  1741. sed -i -e "s@{{cloud_config_volume}}@${CLOUD_CONFIG_VOLUME}@g" "${src_file}"
  1742. sed -i -e "s@{%.*%}@@g" "${src_file}"
  1743. cp "${src_file}" /etc/kubernetes/manifests
  1744. fi
  1745. }
  1746. # A helper function for setting up addon manifests.
  1747. #
  1748. # $1: addon category under /etc/kubernetes
  1749. # $2: manifest source dir
  1750. # $3: (optional) auxiliary manifest source dir
  1751. function setup-addon-manifests {
  1752. local -r src_dir="${KUBE_HOME}/kube-manifests/kubernetes/gci-trusty"
  1753. local -r dst_dir="/etc/kubernetes/$1/$2"
  1754. copy-manifests "${src_dir}/$2" "${dst_dir}"
  1755. # If the PodSecurityPolicy admission controller is enabled,
  1756. # set up the corresponding addon policies.
  1757. if [[ "${ENABLE_POD_SECURITY_POLICY:-}" == "true" ]]; then
  1758. local -r psp_dir="${src_dir}/${3:-$2}/podsecuritypolicies"
  1759. if [[ -d "${psp_dir}" ]]; then
  1760. copy-manifests "${psp_dir}" "${dst_dir}"
  1761. fi
  1762. fi
  1763. if [[ "${ENABLE_NODE_TERMINATION_HANDLER:-}" == "true" ]]; then
  1764. local -r nth_dir="${src_dir}/${3:-$2}/node-termination-handler"
  1765. if [[ -d "${nth_dir}" ]]; then
  1766. copy-manifests "${nth_dir}" "${dst_dir}"
  1767. fi
  1768. fi
  1769. }
  1770. # A function that downloads extra addons from a URL and puts them in the GCI
  1771. # manifests directory.
  1772. function download-extra-addons {
  1773. local -r out_dir="${KUBE_HOME}/kube-manifests/kubernetes/gci-trusty/gce-extras"
  1774. mkdir -p "${out_dir}"
  1775. local curl_cmd=(
  1776. "curl"
  1777. "--fail"
  1778. "--retry" "5"
  1779. "--retry-delay" "3"
  1780. "--silent"
  1781. "--show-error"
  1782. )
  1783. if [[ -n "${CURL_RETRY_CONNREFUSED:-}" ]]; then
  1784. curl_cmd+=("${CURL_RETRY_CONNREFUSED}")
  1785. fi
  1786. if [[ -n "${EXTRA_ADDONS_HEADER:-}" ]]; then
  1787. curl_cmd+=("-H" "${EXTRA_ADDONS_HEADER}")
  1788. fi
  1789. curl_cmd+=("-o" "${out_dir}/extras.json")
  1790. curl_cmd+=("${EXTRA_ADDONS_URL}")
  1791. "${curl_cmd[@]}"
  1792. }
  1793. # A function that fetches a GCE metadata value and echoes it out.
  1794. #
  1795. # $1: URL path after /computeMetadata/v1/ (without heading slash).
  1796. function get-metadata-value {
  1797. curl \
  1798. --retry 5 \
  1799. --retry-delay 3 \
  1800. ${CURL_RETRY_CONNREFUSED} \
  1801. --fail \
  1802. --silent \
  1803. -H 'Metadata-Flavor: Google' \
  1804. "http://metadata/computeMetadata/v1/${1}"
  1805. }
  1806. # A helper function for copying manifests and setting dir/files
  1807. # permissions.
  1808. #
  1809. # $1: absolute source dir
  1810. # $2: absolute destination dir
  1811. function copy-manifests {
  1812. local -r src_dir="$1"
  1813. local -r dst_dir="$2"
  1814. if [[ ! -d "${dst_dir}" ]]; then
  1815. mkdir -p "${dst_dir}"
  1816. fi
  1817. local files=$(find "${src_dir}" -maxdepth 1 -name "*.yaml")
  1818. if [[ -n "${files}" ]]; then
  1819. cp "${src_dir}/"*.yaml "${dst_dir}"
  1820. fi
  1821. files=$(find "${src_dir}" -maxdepth 1 -name "*.json")
  1822. if [[ -n "${files}" ]]; then
  1823. cp "${src_dir}/"*.json "${dst_dir}"
  1824. fi
  1825. files=$(find "${src_dir}" -maxdepth 1 -name "*.yaml.in")
  1826. if [[ -n "${files}" ]]; then
  1827. cp "${src_dir}/"*.yaml.in "${dst_dir}"
  1828. fi
  1829. chown -R root:root "${dst_dir}"
  1830. chmod 755 "${dst_dir}"
  1831. chmod 644 "${dst_dir}"/*
  1832. }
  1833. # Fluentd resources are modified using ScalingPolicy CR, which may not be
  1834. # available at this point. Run this as a background process.
  1835. function wait-for-apiserver-and-update-fluentd {
  1836. local any_overrides=false
  1837. if [[ -n "${FLUENTD_GCP_MEMORY_LIMIT:-}" ]]; then
  1838. any_overrides=true
  1839. fi
  1840. if [[ -n "${FLUENTD_GCP_CPU_REQUEST:-}" ]]; then
  1841. any_overrides=true
  1842. fi
  1843. if [[ -n "${FLUENTD_GCP_MEMORY_REQUEST:-}" ]]; then
  1844. any_overrides=true
  1845. fi
  1846. if ! $any_overrides; then
  1847. # Nothing to do here.
  1848. exit
  1849. fi
  1850. # Wait until ScalingPolicy CRD is in place.
  1851. until kubectl get scalingpolicies.scalingpolicy.kope.io
  1852. do
  1853. sleep 10
  1854. done
  1855. # Single-shot, not managed by addon manager. Can be later modified or removed
  1856. # at will.
  1857. cat <<EOF | kubectl apply -f -
  1858. apiVersion: scalingpolicy.kope.io/v1alpha1
  1859. kind: ScalingPolicy
  1860. metadata:
  1861. name: fluentd-gcp-scaling-policy
  1862. namespace: kube-system
  1863. spec:
  1864. containers:
  1865. - name: fluentd-gcp
  1866. resources:
  1867. requests:
  1868. - resource: cpu
  1869. base: ${FLUENTD_GCP_CPU_REQUEST:-}
  1870. - resource: memory
  1871. base: ${FLUENTD_GCP_MEMORY_REQUEST:-}
  1872. limits:
  1873. - resource: memory
  1874. base: ${FLUENTD_GCP_MEMORY_LIMIT:-}
  1875. EOF
  1876. }
  1877. # Trigger background process that will ultimately update fluentd resource
  1878. # requirements.
  1879. function start-fluentd-resource-update {
  1880. wait-for-apiserver-and-update-fluentd &
  1881. }
  1882. # VolumeSnapshot CRDs and controller are installed by cluster addon manager,
  1883. # which may not be available at this point. Run this as a background process.
  1884. function wait-for-volumesnapshot-crd-and-controller {
  1885. # Wait until volumesnapshot CRDs and controller are in place.
  1886. echo "Wait until volume snapshot CRDs are installed"
  1887. until kubectl get volumesnapshotclasses.snapshot.storage.k8s.io
  1888. do
  1889. sleep 10
  1890. done
  1891. until kubectl get volumesnapshotcontents.snapshot.storage.k8s.io
  1892. do
  1893. sleep 10
  1894. done
  1895. until kubectl get volumesnapshots.snapshot.storage.k8s.io
  1896. do
  1897. sleep 10
  1898. done
  1899. echo "Wait until volume snapshot RBAC rules are installed"
  1900. until kubectl get clusterrolebinding volume-snapshot-controller-role
  1901. do
  1902. sleep 10
  1903. done
  1904. echo "Wait until volume snapshot controller is installed"
  1905. until kubectl get statefulset volume-snapshot-controller | grep volume-snapshot-controller | grep "1/1"
  1906. do
  1907. sleep 10
  1908. done
  1909. }
  1910. # Trigger background process that will wait for volumesnapshot CRDs
  1911. # and snapshot-controller to be installed
  1912. function start-volumesnapshot-crd-and-controller {
  1913. wait-for-volumesnapshot-crd-and-controller &
  1914. }
  1915. # Update {{ fluentd_container_runtime_service }} with actual container runtime name,
  1916. # and {{ container_runtime_endpoint }} with actual container runtime
  1917. # endpoint.
  1918. function update-container-runtime {
  1919. local -r file="$1"
  1920. local -r container_runtime_endpoint="${CONTAINER_RUNTIME_ENDPOINT:-unix:///var/run/dockershim.sock}"
  1921. sed -i \
  1922. -e "s@{{ *fluentd_container_runtime_service *}}@${FLUENTD_CONTAINER_RUNTIME_SERVICE:-${CONTAINER_RUNTIME_NAME:-docker}}@g" \
  1923. -e "s@{{ *container_runtime_endpoint *}}@${container_runtime_endpoint#unix://}@g" \
  1924. "${file}"
  1925. }
  1926. # Remove configuration in yaml file if node journal is not enabled.
  1927. function update-node-journal {
  1928. local -r configmap_yaml="$1"
  1929. if [[ "${ENABLE_NODE_JOURNAL:-}" != "true" ]]; then
  1930. # Removes all lines between two patterns (throws away node-journal)
  1931. sed -i -e "/# BEGIN_NODE_JOURNAL/,/# END_NODE_JOURNAL/d" "${configmap_yaml}"
  1932. fi
  1933. }
  1934. # Updates parameters in yaml file for prometheus-to-sd configuration, or
  1935. # removes component if it is disabled.
  1936. function update-prometheus-to-sd-parameters {
  1937. if [[ "${ENABLE_PROMETHEUS_TO_SD:-}" == "true" ]]; then
  1938. sed -i -e "s@{{ *prometheus_to_sd_prefix *}}@${PROMETHEUS_TO_SD_PREFIX}@g" "$1"
  1939. sed -i -e "s@{{ *prometheus_to_sd_endpoint *}}@${PROMETHEUS_TO_SD_ENDPOINT}@g" "$1"
  1940. else
  1941. # Removes all lines between two patterns (throws away prometheus-to-sd)
  1942. sed -i -e "/# BEGIN_PROMETHEUS_TO_SD/,/# END_PROMETHEUS_TO_SD/d" "$1"
  1943. fi
  1944. }
  1945. # Updates parameters in yaml file for prometheus-to-sd configuration in daemon sets, or
  1946. # removes component if it is disabled.
  1947. function update-daemon-set-prometheus-to-sd-parameters {
  1948. if [[ "${DISABLE_PROMETHEUS_TO_SD_IN_DS:-}" == "true" ]]; then
  1949. # Removes all lines between two patterns (throws away prometheus-to-sd)
  1950. sed -i -e "/# BEGIN_PROMETHEUS_TO_SD/,/# END_PROMETHEUS_TO_SD/d" "$1"
  1951. else
  1952. update-prometheus-to-sd-parameters $1
  1953. fi
  1954. }
  1955. # Updates parameters in yaml file for event-exporter configuration
  1956. function update-event-exporter {
  1957. local -r stackdriver_resource_model="${LOGGING_STACKDRIVER_RESOURCE_TYPES:-old}"
  1958. sed -i -e "s@{{ exporter_sd_resource_model }}@${stackdriver_resource_model}@g" "$1"
  1959. sed -i -e "s@{{ exporter_sd_endpoint }}@${STACKDRIVER_ENDPOINT:-}@g" "$1"
  1960. }
  1961. function update-dashboard-deployment {
  1962. if [ -n "${CUSTOM_KUBE_DASHBOARD_BANNER:-}" ]; then
  1963. sed -i -e "s@\( \+\)# PLATFORM-SPECIFIC ARGS HERE@\1- --system-banner=${CUSTOM_KUBE_DASHBOARD_BANNER}\n\1- --system-banner-severity=WARNING@" "$1"
  1964. fi
  1965. }
  1966. # Sets up the manifests of coreDNS for k8s addons.
  1967. function setup-coredns-manifest {
  1968. setup-addon-manifests "addons" "0-dns/coredns"
  1969. local -r coredns_file="${dst_dir}/0-dns/coredns/coredns.yaml"
  1970. mv "${dst_dir}/0-dns/coredns/coredns.yaml.in" "${coredns_file}"
  1971. # Replace the salt configurations with variable values.
  1972. sed -i -e "s@{{ *pillar\['dns_domain'\] *}}@${DNS_DOMAIN}@g" "${coredns_file}"
  1973. sed -i -e "s@{{ *pillar\['dns_server'\] *}}@${DNS_SERVER_IP}@g" "${coredns_file}"
  1974. sed -i -e "s@{{ *pillar\['service_cluster_ip_range'\] *}}@${SERVICE_CLUSTER_IP_RANGE}@g" "${coredns_file}"
  1975. sed -i -e "s@{{ *pillar\['dns_memory_limit'\] *}}@${DNS_MEMORY_LIMIT:-170Mi}@g" "${coredns_file}"
  1976. if [[ "${ENABLE_DNS_HORIZONTAL_AUTOSCALER:-}" == "true" ]]; then
  1977. setup-addon-manifests "addons" "dns-horizontal-autoscaler" "gce"
  1978. local -r dns_autoscaler_file="${dst_dir}/dns-horizontal-autoscaler/dns-horizontal-autoscaler.yaml"
  1979. sed -i'' -e "s@{{.Target}}@${COREDNS_AUTOSCALER}@g" "${dns_autoscaler_file}"
  1980. fi
  1981. }
  1982. # Sets up the manifests of Fluentd configmap and yamls for k8s addons.
  1983. function setup-fluentd {
  1984. local -r dst_dir="$1"
  1985. local -r fluentd_gcp_yaml="${dst_dir}/fluentd-gcp/fluentd-gcp-ds.yaml"
  1986. local -r fluentd_gcp_scaler_yaml="${dst_dir}/fluentd-gcp/scaler-deployment.yaml"
  1987. # Ingest logs against new resources like "k8s_container" and "k8s_node" if
  1988. # LOGGING_STACKDRIVER_RESOURCE_TYPES is "new".
  1989. # Ingest logs against old resources like "gke_container" and "gce_instance" if
  1990. # LOGGING_STACKDRIVER_RESOURCE_TYPES is "old".
  1991. if [[ "${LOGGING_STACKDRIVER_RESOURCE_TYPES:-old}" == "new" ]]; then
  1992. local -r fluentd_gcp_configmap_yaml="${dst_dir}/fluentd-gcp/fluentd-gcp-configmap.yaml"
  1993. fluentd_gcp_configmap_name="fluentd-gcp-config"
  1994. else
  1995. local -r fluentd_gcp_configmap_yaml="${dst_dir}/fluentd-gcp/fluentd-gcp-configmap-old.yaml"
  1996. fluentd_gcp_configmap_name="fluentd-gcp-config-old"
  1997. fi
  1998. sed -i -e "s@{{ fluentd_gcp_configmap_name }}@${fluentd_gcp_configmap_name}@g" "${fluentd_gcp_yaml}"
  1999. fluentd_gcp_yaml_version="${FLUENTD_GCP_YAML_VERSION:-v3.2.0}"
  2000. sed -i -e "s@{{ fluentd_gcp_yaml_version }}@${fluentd_gcp_yaml_version}@g" "${fluentd_gcp_yaml}"
  2001. sed -i -e "s@{{ fluentd_gcp_yaml_version }}@${fluentd_gcp_yaml_version}@g" "${fluentd_gcp_scaler_yaml}"
  2002. fluentd_gcp_version="${FLUENTD_GCP_VERSION:-1.6.17}"
  2003. sed -i -e "s@{{ fluentd_gcp_version }}@${fluentd_gcp_version}@g" "${fluentd_gcp_yaml}"
  2004. update-daemon-set-prometheus-to-sd-parameters ${fluentd_gcp_yaml}
  2005. start-fluentd-resource-update ${fluentd_gcp_yaml}
  2006. update-container-runtime ${fluentd_gcp_configmap_yaml}
  2007. update-node-journal ${fluentd_gcp_configmap_yaml}
  2008. }
  2009. # Sets up the manifests of kube-dns for k8s addons.
  2010. function setup-kube-dns-manifest {
  2011. setup-addon-manifests "addons" "0-dns/kube-dns"
  2012. local -r kubedns_file="${dst_dir}/0-dns/kube-dns/kube-dns.yaml"
  2013. mv "${dst_dir}/0-dns/kube-dns/kube-dns.yaml.in" "${kubedns_file}"
  2014. if [ -n "${CUSTOM_KUBE_DNS_YAML:-}" ]; then
  2015. # Replace with custom GKE kube-dns deployment.
  2016. cat > "${kubedns_file}" <<EOF
  2017. $CUSTOM_KUBE_DNS_YAML
  2018. EOF
  2019. update-prometheus-to-sd-parameters ${kubedns_file}
  2020. fi
  2021. # Replace the salt configurations with variable values.
  2022. sed -i -e "s@{{ *pillar\['dns_domain'\] *}}@${DNS_DOMAIN}@g" "${kubedns_file}"
  2023. sed -i -e "s@{{ *pillar\['dns_server'\] *}}@${DNS_SERVER_IP}@g" "${kubedns_file}"
  2024. sed -i -e "s@{{ *pillar\['dns_memory_limit'\] *}}@${DNS_MEMORY_LIMIT:-170Mi}@g" "${kubedns_file}"
  2025. if [[ "${ENABLE_DNS_HORIZONTAL_AUTOSCALER:-}" == "true" ]]; then
  2026. setup-addon-manifests "addons" "dns-horizontal-autoscaler" "gce"
  2027. local -r dns_autoscaler_file="${dst_dir}/dns-horizontal-autoscaler/dns-horizontal-autoscaler.yaml"
  2028. sed -i'' -e "s@{{.Target}}@${KUBEDNS_AUTOSCALER}@g" "${dns_autoscaler_file}"
  2029. fi
  2030. }
  2031. # Sets up the manifests of local dns cache agent for k8s addons.
  2032. function setup-nodelocaldns-manifest {
  2033. setup-addon-manifests "addons" "0-dns/nodelocaldns"
  2034. local -r localdns_file="${dst_dir}/0-dns/nodelocaldns/nodelocaldns.yaml"
  2035. setup-addon-custom-yaml "addons" "0-dns/nodelocaldns" "nodelocaldns.yaml" "${CUSTOM_NODELOCAL_DNS_YAML:-}"
  2036. # Replace the sed configurations with variable values.
  2037. sed -i -e "s/__PILLAR__DNS__DOMAIN__/${DNS_DOMAIN}/g" "${localdns_file}"
  2038. sed -i -e "s/__PILLAR__DNS__SERVER__/${DNS_SERVER_IP}/g" "${localdns_file}"
  2039. sed -i -e "s/__PILLAR__LOCAL__DNS__/${LOCAL_DNS_IP}/g" "${localdns_file}"
  2040. }
  2041. # Sets up the manifests of netd for k8s addons.
  2042. function setup-netd-manifest {
  2043. local -r netd_file="${dst_dir}/netd/netd.yaml"
  2044. mkdir -p "${dst_dir}/netd"
  2045. touch "${netd_file}"
  2046. if [ -n "${CUSTOM_NETD_YAML:-}" ]; then
  2047. # Replace with custom GCP netd deployment.
  2048. cat > "${netd_file}" <<EOF
  2049. $CUSTOM_NETD_YAML
  2050. EOF
  2051. fi
  2052. }
  2053. # A helper function to set up a custom yaml for a k8s addon.
  2054. #
  2055. # $1: addon category under /etc/kubernetes
  2056. # $2: manifest source dir
  2057. # $3: manifest file
  2058. # $4: custom yaml
  2059. function setup-addon-custom-yaml {
  2060. local -r manifest_path="/etc/kubernetes/$1/$2/$3"
  2061. local -r custom_yaml="$4"
  2062. if [ -n "${custom_yaml:-}" ]; then
  2063. # Replace with custom manifest.
  2064. cat > "${manifest_path}" <<EOF
  2065. $custom_yaml
  2066. EOF
  2067. fi
  2068. }
  2069. # Prepares the manifests of k8s addons, and starts the addon manager.
  2070. # Vars assumed:
  2071. # CLUSTER_NAME
  2072. function start-kube-addons {
  2073. echo "Prepare kube-addons manifests and start kube addon manager"
  2074. local -r src_dir="${KUBE_HOME}/kube-manifests/kubernetes/gci-trusty"
  2075. local -r dst_dir="/etc/kubernetes/addons"
  2076. create-kubeconfig "addon-manager" ${ADDON_MANAGER_TOKEN}
  2077. # prep addition kube-up specific rbac objects
  2078. setup-addon-manifests "addons" "rbac/kubelet-api-auth"
  2079. setup-addon-manifests "addons" "rbac/kubelet-cert-rotation"
  2080. if [[ "${REGISTER_MASTER_KUBELET:-false}" == "true" ]]; then
  2081. setup-addon-manifests "addons" "rbac/legacy-kubelet-user"
  2082. else
  2083. setup-addon-manifests "addons" "rbac/legacy-kubelet-user-disable"
  2084. fi
  2085. if [[ "${ENABLE_POD_SECURITY_POLICY:-}" == "true" ]]; then
  2086. setup-addon-manifests "addons" "podsecuritypolicies"
  2087. fi
  2088. # Set up manifests of other addons.
  2089. if [[ "${KUBE_PROXY_DAEMONSET:-}" == "true" ]]; then
  2090. if [ -n "${CUSTOM_KUBE_PROXY_YAML:-}" ]; then
  2091. # Replace with custom GKE kube proxy.
  2092. cat > "$src_dir/kube-proxy/kube-proxy-ds.yaml" <<EOF
  2093. $CUSTOM_KUBE_PROXY_YAML
  2094. EOF
  2095. update-daemon-set-prometheus-to-sd-parameters "$src_dir/kube-proxy/kube-proxy-ds.yaml"
  2096. fi
  2097. prepare-kube-proxy-manifest-variables "$src_dir/kube-proxy/kube-proxy-ds.yaml"
  2098. setup-addon-manifests "addons" "kube-proxy"
  2099. fi
  2100. if ([[ "${ENABLE_CLUSTER_LOGGING:-}" == "true" ]] &&
  2101. [[ "${LOGGING_DESTINATION:-}" == "gcp" ]]); then
  2102. if [[ "${ENABLE_METADATA_AGENT:-}" == "stackdriver" ]]; then
  2103. metadata_agent_cpu_request="${METADATA_AGENT_CPU_REQUEST:-40m}"
  2104. metadata_agent_memory_request="${METADATA_AGENT_MEMORY_REQUEST:-50Mi}"
  2105. metadata_agent_cluster_level_cpu_request="${METADATA_AGENT_CLUSTER_LEVEL_CPU_REQUEST:-40m}"
  2106. metadata_agent_cluster_level_memory_request="${METADATA_AGENT_CLUSTER_LEVEL_MEMORY_REQUEST:-50Mi}"
  2107. setup-addon-manifests "addons" "metadata-agent/stackdriver"
  2108. metadata_agent_yaml="${dst_dir}/metadata-agent/stackdriver/metadata-agent.yaml"
  2109. sed -i -e "s@{{ metadata_agent_cpu_request }}@${metadata_agent_cpu_request}@g" "${metadata_agent_yaml}"
  2110. sed -i -e "s@{{ metadata_agent_memory_request }}@${metadata_agent_memory_request}@g" "${metadata_agent_yaml}"
  2111. sed -i -e "s@{{ metadata_agent_cluster_level_cpu_request }}@${metadata_agent_cluster_level_cpu_request}@g" "${metadata_agent_yaml}"
  2112. sed -i -e "s@{{ metadata_agent_cluster_level_memory_request }}@${metadata_agent_cluster_level_memory_request}@g" "${metadata_agent_yaml}"
  2113. fi
  2114. fi
  2115. if [[ "${ENABLE_METRICS_SERVER:-}" == "true" ]]; then
  2116. setup-addon-manifests "addons" "metrics-server"
  2117. base_metrics_server_cpu="40m"
  2118. base_metrics_server_memory="40Mi"
  2119. metrics_server_memory_per_node="4"
  2120. metrics_server_min_cluster_size="16"
  2121. if [[ "${ENABLE_SYSTEM_ADDON_RESOURCE_OPTIMIZATIONS:-}" == "true" ]]; then
  2122. base_metrics_server_cpu="40m"
  2123. base_metrics_server_memory="35Mi"
  2124. metrics_server_memory_per_node="4"
  2125. metrics_server_min_cluster_size="5"
  2126. fi
  2127. local -r metrics_server_yaml="${dst_dir}/metrics-server/metrics-server-deployment.yaml"
  2128. sed -i -e "s@{{ base_metrics_server_cpu }}@${base_metrics_server_cpu}@g" "${metrics_server_yaml}"
  2129. sed -i -e "s@{{ base_metrics_server_memory }}@${base_metrics_server_memory}@g" "${metrics_server_yaml}"
  2130. sed -i -e "s@{{ metrics_server_memory_per_node }}@${metrics_server_memory_per_node}@g" "${metrics_server_yaml}"
  2131. sed -i -e "s@{{ metrics_server_min_cluster_size }}@${metrics_server_min_cluster_size}@g" "${metrics_server_yaml}"
  2132. fi
  2133. if [[ "${ENABLE_NVIDIA_GPU_DEVICE_PLUGIN:-}" == "true" ]]; then
  2134. setup-addon-manifests "addons" "device-plugins/nvidia-gpu"
  2135. fi
  2136. if [[ "${ENABLE_NODE_TERMINATION_HANDLER:-}" == "true" ]]; then
  2137. setup-addon-manifests "addons" "node-termination-handler"
  2138. setup-node-termination-handler-manifest
  2139. fi
  2140. # Setting up the konnectivity-agent daemonset
  2141. if [[ "${ENABLE_EGRESS_VIA_KONNECTIVITY_SERVICE:-false}" == "true" ]]; then
  2142. setup-addon-manifests "addons" "konnectivity-agent"
  2143. setup-konnectivity-agent-manifest
  2144. fi
  2145. if [[ "${ENABLE_CLUSTER_DNS:-}" == "true" ]]; then
  2146. # Create a new directory for the DNS addon and prepend a "0" on the name.
  2147. # Prepending "0" to the directory ensures that add-on manager
  2148. # creates the dns service first. This ensures no other add-on
  2149. # can "steal" the designated DNS clusterIP.
  2150. BASE_ADDON_DIR=${KUBE_HOME}/kube-manifests/kubernetes/gci-trusty
  2151. BASE_DNS_DIR=${BASE_ADDON_DIR}/dns
  2152. NEW_DNS_DIR=${BASE_ADDON_DIR}/0-dns
  2153. mkdir ${NEW_DNS_DIR} && mv ${BASE_DNS_DIR}/* ${NEW_DNS_DIR} && rm -r ${BASE_DNS_DIR}
  2154. if [[ "${CLUSTER_DNS_CORE_DNS:-}" == "true" ]]; then
  2155. setup-coredns-manifest
  2156. else
  2157. setup-kube-dns-manifest
  2158. fi
  2159. if [[ "${ENABLE_NODELOCAL_DNS:-}" == "true" ]]; then
  2160. setup-nodelocaldns-manifest
  2161. fi
  2162. fi
  2163. if [[ "${ENABLE_NETD:-}" == "true" ]]; then
  2164. setup-netd-manifest
  2165. fi
  2166. if [[ "${ENABLE_NODE_LOGGING:-}" == "true" ]] && \
  2167. [[ "${LOGGING_DESTINATION:-}" == "elasticsearch" ]] && \
  2168. [[ "${ENABLE_CLUSTER_LOGGING:-}" == "true" ]]; then
  2169. setup-addon-manifests "addons" "fluentd-elasticsearch"
  2170. local -r fluentd_es_configmap_yaml="${dst_dir}/fluentd-elasticsearch/fluentd-es-configmap.yaml"
  2171. update-container-runtime ${fluentd_es_configmap_yaml}
  2172. fi
  2173. if [[ "${ENABLE_NODE_LOGGING:-}" == "true" ]] && \
  2174. [[ "${LOGGING_DESTINATION:-}" == "gcp" ]]; then
  2175. setup-addon-manifests "addons" "fluentd-gcp"
  2176. setup-fluentd ${dst_dir}
  2177. local -r event_exporter_yaml="${dst_dir}/fluentd-gcp/event-exporter.yaml"
  2178. update-event-exporter ${event_exporter_yaml}
  2179. update-prometheus-to-sd-parameters ${event_exporter_yaml}
  2180. fi
  2181. if [[ "${ENABLE_CLUSTER_UI:-}" == "true" ]]; then
  2182. setup-addon-manifests "addons" "dashboard"
  2183. local -r dashboard_deployment_yaml="${dst_dir}/dashboard/dashboard-deployment.yaml"
  2184. update-dashboard-deployment ${dashboard_deployment_yaml}
  2185. fi
  2186. if [[ "${ENABLE_NODE_PROBLEM_DETECTOR:-}" == "daemonset" ]]; then
  2187. setup-addon-manifests "addons" "node-problem-detector"
  2188. fi
  2189. if [[ "${ENABLE_NODE_PROBLEM_DETECTOR:-}" == "standalone" ]]; then
  2190. # Setup role binding(s) for standalone node problem detector.
  2191. if [[ -n "${NODE_PROBLEM_DETECTOR_TOKEN:-}" ]]; then
  2192. setup-addon-manifests "addons" "node-problem-detector/standalone"
  2193. fi
  2194. setup-addon-manifests "addons" "node-problem-detector/kubelet-user-standalone" "node-problem-detector"
  2195. fi
  2196. if echo "${ADMISSION_CONTROL:-}" | grep -q "LimitRanger"; then
  2197. setup-addon-manifests "admission-controls" "limit-range" "gce"
  2198. fi
  2199. if [[ "${NETWORK_POLICY_PROVIDER:-}" == "calico" ]]; then
  2200. setup-addon-manifests "addons" "calico-policy-controller"
  2201. setup-addon-custom-yaml "addons" "calico-policy-controller" "calico-node-daemonset.yaml" "${CUSTOM_CALICO_NODE_DAEMONSET_YAML:-}"
  2202. setup-addon-custom-yaml "addons" "calico-policy-controller" "typha-deployment.yaml" "${CUSTOM_TYPHA_DEPLOYMENT_YAML:-}"
  2203. # Configure Calico CNI directory.
  2204. local -r ds_file="${dst_dir}/calico-policy-controller/calico-node-daemonset.yaml"
  2205. sed -i -e "s@__CALICO_CNI_DIR__@/home/kubernetes/bin@g" "${ds_file}"
  2206. fi
  2207. if [[ "${ENABLE_DEFAULT_STORAGE_CLASS:-}" == "true" ]]; then
  2208. setup-addon-manifests "addons" "storage-class/gce"
  2209. fi
  2210. if [[ "${ENABLE_VOLUME_SNAPSHOTS:-}" == "true" ]]; then
  2211. setup-addon-manifests "addons" "volumesnapshots/crd"
  2212. setup-addon-manifests "addons" "volumesnapshots/volume-snapshot-controller"
  2213. start-volumesnapshot-crd-and-controller
  2214. fi
  2215. if [[ "${ENABLE_IP_MASQ_AGENT:-}" == "true" ]]; then
  2216. setup-addon-manifests "addons" "ip-masq-agent"
  2217. fi
  2218. if [[ "${ENABLE_METADATA_CONCEALMENT:-}" == "true" ]]; then
  2219. setup-addon-manifests "addons" "metadata-proxy/gce"
  2220. local -r metadata_proxy_yaml="${dst_dir}/metadata-proxy/gce/metadata-proxy.yaml"
  2221. update-daemon-set-prometheus-to-sd-parameters ${metadata_proxy_yaml}
  2222. fi
  2223. if [[ "${ENABLE_ISTIO:-}" == "true" ]]; then
  2224. if [[ "${ISTIO_AUTH_TYPE:-}" == "MUTUAL_TLS" ]]; then
  2225. setup-addon-manifests "addons" "istio/auth"
  2226. else
  2227. setup-addon-manifests "addons" "istio/noauth"
  2228. fi
  2229. fi
  2230. if [[ -n "${EXTRA_ADDONS_URL:-}" ]]; then
  2231. download-extra-addons
  2232. setup-addon-manifests "addons" "gce-extras"
  2233. fi
  2234. # Place addon manager pod manifest.
  2235. src_file="${src_dir}/kube-addon-manager.yaml"
  2236. sed -i -e "s@{{kubectl_extra_prune_whitelist}}@${ADDON_MANAGER_PRUNE_WHITELIST:-}@g" "${src_file}"
  2237. cp "${src_file}" /etc/kubernetes/manifests
  2238. }
  2239. function setup-node-termination-handler-manifest {
  2240. local -r nth_manifest="/etc/kubernetes/$1/$2/daemonset.yaml"
  2241. if [[ -n "${NODE_TERMINATION_HANDLER_IMAGE}" ]]; then
  2242. sed -i "s|image:.*|image: ${NODE_TERMINATION_HANDLER_IMAGE}|" "${nth_manifest}"
  2243. fi
  2244. }
  2245. function setup-konnectivity-agent-manifest {
  2246. local -r manifest="/etc/kubernetes/addons/konnectivity-agent/daemonset.yaml"
  2247. sed -i "s|__APISERVER_IP__|${KUBERNETES_MASTER_NAME}|g" "${manifest}"
  2248. }
  2249. # Setups manifests for ingress controller and gce-specific policies for service controller.
  2250. function start-lb-controller {
  2251. setup-addon-manifests "addons" "loadbalancing"
  2252. # Starts a l7 loadbalancing controller for ingress.
  2253. if [[ "${ENABLE_L7_LOADBALANCING:-}" == "glbc" ]]; then
  2254. echo "Start GCE L7 pod"
  2255. prepare-log-file /var/log/glbc.log
  2256. setup-addon-manifests "addons" "cluster-loadbalancing/glbc"
  2257. setup-addon-manifests "addons" "rbac/cluster-loadbalancing/glbc"
  2258. create-kubeconfig "l7-lb-controller" ${GCE_GLBC_TOKEN}
  2259. local -r src_manifest="${KUBE_HOME}/kube-manifests/kubernetes/gci-trusty/glbc.manifest"
  2260. local -r dest_manifest="/etc/kubernetes/manifests/glbc.manifest"
  2261. if [[ -n "${CUSTOM_INGRESS_YAML:-}" ]]; then
  2262. echo "${CUSTOM_INGRESS_YAML}" > "${dest_manifest}"
  2263. else
  2264. cp "${src_manifest}" "${dest_manifest}"
  2265. fi
  2266. # Override the glbc image if GCE_GLBC_IMAGE is specified.
  2267. if [[ -n "${GCE_GLBC_IMAGE:-}" ]]; then
  2268. sed -i "s|image:.*|image: ${GCE_GLBC_IMAGE}|" "${dest_manifest}"
  2269. fi
  2270. fi
  2271. }
  2272. # Setup working directory for kubelet.
  2273. function setup-kubelet-dir {
  2274. echo "Making /var/lib/kubelet executable for kubelet"
  2275. mount -B /var/lib/kubelet /var/lib/kubelet/
  2276. mount -B -o remount,exec,suid,dev /var/lib/kubelet
  2277. }
  2278. # Override for GKE custom master setup scripts (no-op outside of GKE).
  2279. function gke-master-start {
  2280. if [[ -e "${KUBE_HOME}/bin/gke-internal-configure-helper.sh" ]]; then
  2281. echo "Running GKE internal configuration script"
  2282. . "${KUBE_HOME}/bin/gke-internal-configure-helper.sh"
  2283. gke-internal-master-start
  2284. fi
  2285. }
  2286. function reset-motd {
  2287. # kubelet is installed both on the master and nodes, and the version is easy to parse (unlike kubectl)
  2288. local -r version="$("${KUBE_HOME}"/bin/kubelet --version=true | cut -f2 -d " ")"
  2289. # This logic grabs either a release tag (v1.2.1 or v1.2.1-alpha.1),
  2290. # or the git hash that's in the build info.
  2291. local gitref="$(echo "${version}" | sed -r "s/(v[0-9]+\.[0-9]+\.[0-9]+)(-[a-z]+\.[0-9]+)?.*/\1\2/g")"
  2292. local devel=""
  2293. if [[ "${gitref}" != "${version}" ]]; then
  2294. devel="
  2295. Note: This looks like a development version, which might not be present on GitHub.
  2296. If it isn't, the closest tag is at:
  2297. https://github.com/kubernetes/kubernetes/tree/${gitref}
  2298. "
  2299. gitref="${version//*+/}"
  2300. fi
  2301. cat > /etc/motd <<EOF
  2302. Welcome to Kubernetes ${version}!
  2303. You can find documentation for Kubernetes at:
  2304. http://docs.kubernetes.io/
  2305. The source for this release can be found at:
  2306. /home/kubernetes/kubernetes-src.tar.gz
  2307. Or you can download it at:
  2308. https://storage.googleapis.com/kubernetes-release/release/${version}/kubernetes-src.tar.gz
  2309. It is based on the Kubernetes source at:
  2310. https://github.com/kubernetes/kubernetes/tree/${gitref}
  2311. ${devel}
  2312. For Kubernetes copyright and licensing information, see:
  2313. /home/kubernetes/LICENSES
  2314. EOF
  2315. }
  2316. function override-kubectl {
  2317. echo "overriding kubectl"
  2318. echo "export PATH=${KUBE_HOME}/bin:\$PATH" > /etc/profile.d/kube_env.sh
  2319. # source the file explicitly otherwise we have
  2320. # issues on a ubuntu OS image finding the kubectl
  2321. source /etc/profile.d/kube_env.sh
  2322. # Add ${KUBE_HOME}/bin into sudoer secure path.
  2323. local sudo_path
  2324. sudo_path=$(sudo env | grep "^PATH=")
  2325. if [[ -n "${sudo_path}" ]]; then
  2326. sudo_path=${sudo_path#PATH=}
  2327. (
  2328. umask 027
  2329. echo "Defaults secure_path=\"${KUBE_HOME}/bin:${sudo_path}\"" > /etc/sudoers.d/kube_secure_path
  2330. )
  2331. fi
  2332. }
  2333. function override-pv-recycler {
  2334. if [[ -z "${PV_RECYCLER_OVERRIDE_TEMPLATE:-}" ]]; then
  2335. echo "PV_RECYCLER_OVERRIDE_TEMPLATE is not set"
  2336. exit 1
  2337. fi
  2338. PV_RECYCLER_VOLUME="{\"name\": \"pv-recycler-mount\",\"hostPath\": {\"path\": \"${PV_RECYCLER_OVERRIDE_TEMPLATE}\", \"type\": \"FileOrCreate\"}},"
  2339. PV_RECYCLER_MOUNT="{\"name\": \"pv-recycler-mount\",\"mountPath\": \"${PV_RECYCLER_OVERRIDE_TEMPLATE}\", \"readOnly\": true},"
  2340. cat > ${PV_RECYCLER_OVERRIDE_TEMPLATE} <<EOF
  2341. version: v1
  2342. kind: Pod
  2343. metadata:
  2344. generateName: pv-recycler-
  2345. namespace: default
  2346. spec:
  2347. activeDeadlineSeconds: 60
  2348. restartPolicy: Never
  2349. volumes:
  2350. - name: vol
  2351. containers:
  2352. - name: pv-recycler
  2353. image: k8s.gcr.io/busybox:1.27
  2354. command:
  2355. - /bin/sh
  2356. args:
  2357. - -c
  2358. - test -e /scrub && rm -rf /scrub/..?* /scrub/.[!.]* /scrub/* && test -z $(ls -A /scrub) || exit 1
  2359. volumeMounts:
  2360. - name: vol
  2361. mountPath: /scrub
  2362. EOF
  2363. }
  2364. function wait-till-apiserver-ready() {
  2365. until kubectl get nodes; do
  2366. sleep 5
  2367. done
  2368. }
  2369. function ensure-master-bootstrap-kubectl-auth {
  2370. # By default, `kubectl` uses http://localhost:8080
  2371. # If the insecure port is disabled, kubectl will need to use an admin-authenticated kubeconfig.
  2372. if [[ -n "${KUBE_BOOTSTRAP_TOKEN:-}" ]]; then
  2373. create-kubeconfig "kube-bootstrap" "${KUBE_BOOTSTRAP_TOKEN}"
  2374. export KUBECONFIG=/etc/srv/kubernetes/kube-bootstrap/kubeconfig
  2375. fi
  2376. }
  2377. function setup-containerd {
  2378. echo "Generate containerd config"
  2379. local config_path="${CONTAINERD_CONFIG_PATH:-"/etc/containerd/config.toml"}"
  2380. mkdir -p "$(dirname "${config_path}")"
  2381. local cni_template_path="${KUBE_HOME}/cni.template"
  2382. cat > "${cni_template_path}" <<EOF
  2383. {
  2384. "name": "k8s-pod-network",
  2385. "cniVersion": "0.3.1",
  2386. "plugins": [
  2387. {
  2388. "type": "ptp",
  2389. "mtu": 1460,
  2390. "ipam": {
  2391. "type": "host-local",
  2392. "subnet": "{{.PodCIDR}}",
  2393. "routes": [
  2394. {
  2395. "dst": "0.0.0.0/0"
  2396. }
  2397. ]
  2398. }
  2399. },
  2400. {
  2401. "type": "portmap",
  2402. "capabilities": {
  2403. "portMappings": true
  2404. }
  2405. }
  2406. ]
  2407. }
  2408. EOF
  2409. if [[ "${KUBERNETES_MASTER:-}" != "true" ]]; then
  2410. if [[ "${NETWORK_POLICY_PROVIDER:-"none"}" != "none" || "${ENABLE_NETD:-}" == "true" ]]; then
  2411. # Use Kubernetes cni daemonset on node if network policy provider is specified
  2412. # or netd is enabled.
  2413. cni_template_path=""
  2414. fi
  2415. fi
  2416. cat > "${config_path}" <<EOF
  2417. # Kubernetes doesn't use containerd restart manager.
  2418. disabled_plugins = ["restart"]
  2419. oom_score = -999
  2420. [debug]
  2421. level = "${CONTAINERD_LOG_LEVEL:-"info"}"
  2422. [plugins.cri]
  2423. stream_server_address = "127.0.0.1"
  2424. max_container_log_line_size = ${CONTAINERD_MAX_CONTAINER_LOG_LINE:-262144}
  2425. [plugins.cri.cni]
  2426. bin_dir = "${KUBE_HOME}/bin"
  2427. conf_dir = "/etc/cni/net.d"
  2428. conf_template = "${cni_template_path}"
  2429. [plugins.cri.registry.mirrors."docker.io"]
  2430. endpoint = ["https://mirror.gcr.io","https://registry-1.docker.io"]
  2431. EOF
  2432. # Reuse docker group for containerd.
  2433. local containerd_gid="$(cat /etc/group | grep ^docker: | cut -d: -f 3)"
  2434. if [[ ! -z "${containerd_gid:-}" ]]; then
  2435. cat >> "${config_path}" <<EOF
  2436. # reuse id of the docker group
  2437. [grpc]
  2438. gid = ${containerd_gid}
  2439. EOF
  2440. fi
  2441. chmod 644 "${config_path}"
  2442. echo "Restart containerd to load the config change"
  2443. systemctl restart containerd
  2444. }
  2445. ########### Main Function ###########
  2446. function main() {
  2447. echo "Start to configure instance for kubernetes"
  2448. readonly UUID_MNT_PREFIX="/mnt/disks/by-uuid/google-local-ssds"
  2449. readonly UUID_BLOCK_PREFIX="/dev/disk/by-uuid/google-local-ssds"
  2450. readonly COREDNS_AUTOSCALER="Deployment/coredns"
  2451. readonly KUBEDNS_AUTOSCALER="Deployment/kube-dns"
  2452. # Resource requests of master components.
  2453. KUBE_CONTROLLER_MANAGER_CPU_REQUEST="${KUBE_CONTROLLER_MANAGER_CPU_REQUEST:-200m}"
  2454. KUBE_SCHEDULER_CPU_REQUEST="${KUBE_SCHEDULER_CPU_REQUEST:-75m}"
  2455. # Use --retry-connrefused opt only if it's supported by curl.
  2456. CURL_RETRY_CONNREFUSED=""
  2457. if curl --help | grep -q -- '--retry-connrefused'; then
  2458. CURL_RETRY_CONNREFUSED='--retry-connrefused'
  2459. fi
  2460. KUBE_HOME="/home/kubernetes"
  2461. KUBE_BIN=${KUBE_HOME}/bin
  2462. CONTAINERIZED_MOUNTER_HOME="${KUBE_HOME}/containerized_mounter"
  2463. PV_RECYCLER_OVERRIDE_TEMPLATE="${KUBE_HOME}/kube-manifests/kubernetes/pv-recycler-template.yaml"
  2464. if [[ "$(python -V 2>&1)" =~ "Python 2" ]]; then
  2465. # found python2, just use that
  2466. PYTHON="python"
  2467. elif [[ -f "/usr/bin/python2.7" ]]; then
  2468. # System python not defaulted to python 2 but using 2.7 during migration
  2469. PYTHON="/usr/bin/python2.7"
  2470. else
  2471. # No python2 either by default, let's see if we can find python3
  2472. PYTHON="python3"
  2473. if ! command -v ${PYTHON} >/dev/null 2>&1; then
  2474. echo "ERROR Python not found. Aborting."
  2475. exit 2
  2476. fi
  2477. fi
  2478. echo "Version : " $(${PYTHON} -V 2>&1)
  2479. if [[ ! -e "${KUBE_HOME}/kube-env" ]]; then
  2480. echo "The ${KUBE_HOME}/kube-env file does not exist!! Terminate cluster initialization."
  2481. exit 1
  2482. fi
  2483. source "${KUBE_HOME}/kube-env"
  2484. if [[ -f "${KUBE_HOME}/kubelet-config.yaml" ]]; then
  2485. echo "Found Kubelet config file at ${KUBE_HOME}/kubelet-config.yaml"
  2486. KUBELET_CONFIG_FILE_ARG="--config ${KUBE_HOME}/kubelet-config.yaml"
  2487. fi
  2488. if [[ -e "${KUBE_HOME}/kube-master-certs" ]]; then
  2489. source "${KUBE_HOME}/kube-master-certs"
  2490. fi
  2491. if [[ -n "${KUBE_USER:-}" ]]; then
  2492. if ! [[ "${KUBE_USER}" =~ ^[-._@a-zA-Z0-9]+$ ]]; then
  2493. echo "Bad KUBE_USER format."
  2494. exit 1
  2495. fi
  2496. fi
  2497. KUBE_CONTROLLER_MANAGER_TOKEN="$(secure_random 32)"
  2498. KUBE_SCHEDULER_TOKEN="$(secure_random 32)"
  2499. KUBE_CLUSTER_AUTOSCALER_TOKEN="$(secure_random 32)"
  2500. if [[ "${ENABLE_L7_LOADBALANCING:-}" == "glbc" ]]; then
  2501. GCE_GLBC_TOKEN="$(secure_random 32)"
  2502. fi
  2503. ADDON_MANAGER_TOKEN="$(secure_random 32)"
  2504. if [[ "${ENABLE_APISERVER_INSECURE_PORT:-false}" != "true" ]]; then
  2505. KUBE_BOOTSTRAP_TOKEN="$(secure_random 32)"
  2506. fi
  2507. setup-os-params
  2508. config-ip-firewall
  2509. create-dirs
  2510. setup-kubelet-dir
  2511. ensure-local-ssds
  2512. setup-logrotate
  2513. if [[ "${KUBERNETES_MASTER:-}" == "true" ]]; then
  2514. mount-master-pd
  2515. create-node-pki
  2516. create-master-pki
  2517. create-master-auth
  2518. ensure-master-bootstrap-kubectl-auth
  2519. if [[ "${ENABLE_EGRESS_VIA_KONNECTIVITY_SERVICE:-false}" == "true" ]]; then
  2520. create-master-konnectivity-server-apiserver-auth
  2521. fi
  2522. create-master-kubelet-auth
  2523. create-master-etcd-auth
  2524. create-master-etcd-apiserver-auth
  2525. override-pv-recycler
  2526. gke-master-start
  2527. else
  2528. create-node-pki
  2529. create-kubelet-kubeconfig ${KUBERNETES_MASTER_NAME}
  2530. if [[ "${KUBE_PROXY_DAEMONSET:-}" != "true" ]]; then
  2531. create-kubeproxy-user-kubeconfig
  2532. fi
  2533. if [[ "${ENABLE_NODE_PROBLEM_DETECTOR:-}" == "standalone" ]]; then
  2534. if [[ -n "${NODE_PROBLEM_DETECTOR_TOKEN:-}" ]]; then
  2535. create-node-problem-detector-kubeconfig ${KUBERNETES_MASTER_NAME}
  2536. elif [[ -f "/var/lib/kubelet/kubeconfig" ]]; then
  2537. create-node-problem-detector-kubeconfig-from-kubelet
  2538. else
  2539. echo "Either NODE_PROBLEM_DETECTOR_TOKEN or /var/lib/kubelet/kubeconfig must be set"
  2540. exit 1
  2541. fi
  2542. fi
  2543. fi
  2544. override-kubectl
  2545. container_runtime="${CONTAINER_RUNTIME:-docker}"
  2546. # Run the containerized mounter once to pre-cache the container image.
  2547. if [[ "${container_runtime}" == "docker" ]]; then
  2548. assemble-docker-flags
  2549. elif [[ "${container_runtime}" == "containerd" ]]; then
  2550. setup-containerd
  2551. fi
  2552. start-kubelet
  2553. if [[ "${KUBERNETES_MASTER:-}" == "true" ]]; then
  2554. compute-master-manifest-variables
  2555. if [[ -z "${ETCD_SERVERS:-}" ]]; then
  2556. start-etcd-servers
  2557. start-etcd-empty-dir-cleanup-pod
  2558. fi
  2559. source ${KUBE_BIN}/configure-kubeapiserver.sh
  2560. start-kube-apiserver
  2561. if [[ "${ENABLE_EGRESS_VIA_KONNECTIVITY_SERVICE:-false}" == "true" ]]; then
  2562. start-konnectivity-server
  2563. fi
  2564. start-kube-controller-manager
  2565. start-kube-scheduler
  2566. wait-till-apiserver-ready
  2567. start-kube-addons
  2568. start-cluster-autoscaler
  2569. start-lb-controller
  2570. update-legacy-addon-node-labels &
  2571. else
  2572. if [[ "${KUBE_PROXY_DAEMONSET:-}" != "true" ]]; then
  2573. start-kube-proxy
  2574. fi
  2575. if [[ "${ENABLE_NODE_PROBLEM_DETECTOR:-}" == "standalone" ]]; then
  2576. start-node-problem-detector
  2577. fi
  2578. fi
  2579. reset-motd
  2580. prepare-mounter-rootfs
  2581. modprobe configs
  2582. echo "Done for the configuration for kubernetes"
  2583. }
  2584. if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
  2585. main "${@}"
  2586. fi