configure-helper.sh 106 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864
  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. proxyProtocol: HTTPConnect
  718. transport:
  719. uds:
  720. udsName: /etc/srv/kubernetes/konnectivity/konnectivity-server.socket
  721. - name: master
  722. connection:
  723. proxyProtocol: Direct
  724. - name: etcd
  725. connection:
  726. proxyProtocol: Direct
  727. EOF
  728. fi
  729. if [[ -n "${WEBHOOK_GKE_EXEC_AUTH:-}" ]]; then
  730. if [[ -z "${EXEC_AUTH_PLUGIN_URL:-}" ]]; then
  731. 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."
  732. exit 1
  733. fi
  734. if [[ -z "${TOKEN_URL:-}" || -z "${TOKEN_BODY:-}" || -z "${TOKEN_BODY_UNQUOTED:-}" ]]; then
  735. 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."
  736. exit 1
  737. fi
  738. # kubeconfig to be used by webhooks with GKE exec auth support. Note that
  739. # the path to gke-exec-auth-plugin is the path when mounted inside the
  740. # kube-apiserver pod.
  741. cat <<EOF >/etc/srv/kubernetes/webhook.kubeconfig
  742. apiVersion: v1
  743. kind: Config
  744. users:
  745. - name: '*.googleapis.com'
  746. user:
  747. exec:
  748. apiVersion: "client.authentication.k8s.io/v1alpha1"
  749. command: /usr/bin/gke-exec-auth-plugin
  750. args:
  751. - --mode=alt-token
  752. - --alt-token-url=${TOKEN_URL}
  753. - --alt-token-body=${TOKEN_BODY_UNQUOTED}
  754. EOF
  755. fi
  756. if [[ -n "${ADMISSION_CONTROL:-}" ]]; then
  757. # Emit a basic admission control configuration file, with no plugins specified.
  758. cat <<EOF >/etc/srv/kubernetes/admission_controller_config.yaml
  759. apiVersion: apiserver.k8s.io/v1alpha1
  760. kind: AdmissionConfiguration
  761. plugins:
  762. EOF
  763. if [[ "${ADMISSION_CONTROL:-}" == *"ImagePolicyWebhook"* ]]; then
  764. if [[ -z "${GCP_IMAGE_VERIFICATION_URL:-}" ]]; then
  765. 1>&2 echo "The ImagePolicyWebhook admission control plugin was requested, but GCP_IMAGE_VERIFICATION_URL was not provided."
  766. exit 1
  767. fi
  768. 1>&2 echo "ImagePolicyWebhook admission control plugin requested. Configuring it to point at ${GCP_IMAGE_VERIFICATION_URL}"
  769. # ImagePolicyWebhook does not use gke-exec-auth-plugin for authenticating
  770. # to the webhook endpoint. Emit its special kubeconfig.
  771. cat <<EOF >/etc/srv/kubernetes/gcp_image_review.kubeconfig
  772. clusters:
  773. - name: gcp-image-review-server
  774. cluster:
  775. server: ${GCP_IMAGE_VERIFICATION_URL}
  776. users:
  777. - name: kube-apiserver
  778. user:
  779. auth-provider:
  780. name: gcp
  781. current-context: webhook
  782. contexts:
  783. - context:
  784. cluster: gcp-image-review-server
  785. user: kube-apiserver
  786. name: webhook
  787. EOF
  788. # Append config for ImagePolicyWebhook to the shared admission controller
  789. # configuration file.
  790. cat <<EOF >>/etc/srv/kubernetes/admission_controller_config.yaml
  791. - name: ImagePolicyWebhook
  792. configuration:
  793. imagePolicy:
  794. kubeConfigFile: /etc/srv/kubernetes/gcp_image_review.kubeconfig
  795. allowTTL: 30
  796. denyTTL: 30
  797. retryBackoff: 500
  798. defaultAllow: true
  799. EOF
  800. fi
  801. # If GKE exec auth for webhooks has been requested, then
  802. # ValidatingAdmissionWebhook should use it. Otherwise, run with the default
  803. # config.
  804. if [[ "${ADMISSION_CONTROL:-}" == *"ValidatingAdmissionWebhook"* && -n "${WEBHOOK_GKE_EXEC_AUTH:-}" ]]; then
  805. 1>&2 echo "ValidatingAdmissionWebhook requested, and WEBHOOK_GKE_EXEC_AUTH specified. Configuring ValidatingAdmissionWebhook to use gke-exec-auth-plugin."
  806. # Append config for ValidatingAdmissionWebhook to the shared admission
  807. # controller configuration file.
  808. cat <<EOF >>/etc/srv/kubernetes/admission_controller_config.yaml
  809. - name: ValidatingAdmissionWebhook
  810. configuration:
  811. apiVersion: apiserver.config.k8s.io/v1alpha1
  812. kind: WebhookAdmission
  813. kubeConfigFile: /etc/srv/kubernetes/webhook.kubeconfig
  814. EOF
  815. fi
  816. fi
  817. }
  818. # Write the config for the audit policy.
  819. function create-master-audit-policy {
  820. local -r path="${1}"
  821. local -r policy="${2:-}"
  822. if [[ -n "${policy}" ]]; then
  823. echo "${policy}" > "${path}"
  824. return
  825. fi
  826. # Known api groups
  827. local -r known_apis='
  828. - group: "" # core
  829. - group: "admissionregistration.k8s.io"
  830. - group: "apiextensions.k8s.io"
  831. - group: "apiregistration.k8s.io"
  832. - group: "apps"
  833. - group: "authentication.k8s.io"
  834. - group: "authorization.k8s.io"
  835. - group: "autoscaling"
  836. - group: "batch"
  837. - group: "certificates.k8s.io"
  838. - group: "extensions"
  839. - group: "metrics.k8s.io"
  840. - group: "networking.k8s.io"
  841. - group: "node.k8s.io"
  842. - group: "policy"
  843. - group: "rbac.authorization.k8s.io"
  844. - group: "scheduling.k8s.io"
  845. - group: "settings.k8s.io"
  846. - group: "storage.k8s.io"'
  847. cat <<EOF >"${path}"
  848. apiVersion: audit.k8s.io/v1
  849. kind: Policy
  850. rules:
  851. # The following requests were manually identified as high-volume and low-risk,
  852. # so drop them.
  853. - level: None
  854. users: ["system:kube-proxy"]
  855. verbs: ["watch"]
  856. resources:
  857. - group: "" # core
  858. resources: ["endpoints", "services", "services/status"]
  859. - level: None
  860. # Ingress controller reads 'configmaps/ingress-uid' through the unsecured port.
  861. # TODO(#46983): Change this to the ingress controller service account.
  862. users: ["system:unsecured"]
  863. namespaces: ["kube-system"]
  864. verbs: ["get"]
  865. resources:
  866. - group: "" # core
  867. resources: ["configmaps"]
  868. - level: None
  869. users: ["kubelet"] # legacy kubelet identity
  870. verbs: ["get"]
  871. resources:
  872. - group: "" # core
  873. resources: ["nodes", "nodes/status"]
  874. - level: None
  875. userGroups: ["system:nodes"]
  876. verbs: ["get"]
  877. resources:
  878. - group: "" # core
  879. resources: ["nodes", "nodes/status"]
  880. - level: None
  881. users:
  882. - system:kube-controller-manager
  883. - system:kube-scheduler
  884. - system:serviceaccount:kube-system:endpoint-controller
  885. verbs: ["get", "update"]
  886. namespaces: ["kube-system"]
  887. resources:
  888. - group: "" # core
  889. resources: ["endpoints"]
  890. - level: None
  891. users: ["system:apiserver"]
  892. verbs: ["get"]
  893. resources:
  894. - group: "" # core
  895. resources: ["namespaces", "namespaces/status", "namespaces/finalize"]
  896. - level: None
  897. users: ["cluster-autoscaler"]
  898. verbs: ["get", "update"]
  899. namespaces: ["kube-system"]
  900. resources:
  901. - group: "" # core
  902. resources: ["configmaps", "endpoints"]
  903. # Don't log HPA fetching metrics.
  904. - level: None
  905. users:
  906. - system:kube-controller-manager
  907. verbs: ["get", "list"]
  908. resources:
  909. - group: "metrics.k8s.io"
  910. # Don't log these read-only URLs.
  911. - level: None
  912. nonResourceURLs:
  913. - /healthz*
  914. - /version
  915. - /swagger*
  916. # Don't log events requests.
  917. - level: None
  918. resources:
  919. - group: "" # core
  920. resources: ["events"]
  921. # node and pod status calls from nodes are high-volume and can be large, don't log responses for expected updates from nodes
  922. - level: Request
  923. users: ["kubelet", "system:node-problem-detector", "system:serviceaccount:kube-system:node-problem-detector"]
  924. verbs: ["update","patch"]
  925. resources:
  926. - group: "" # core
  927. resources: ["nodes/status", "pods/status"]
  928. omitStages:
  929. - "RequestReceived"
  930. - level: Request
  931. userGroups: ["system:nodes"]
  932. verbs: ["update","patch"]
  933. resources:
  934. - group: "" # core
  935. resources: ["nodes/status", "pods/status"]
  936. omitStages:
  937. - "RequestReceived"
  938. # deletecollection calls can be large, don't log responses for expected namespace deletions
  939. - level: Request
  940. users: ["system:serviceaccount:kube-system:namespace-controller"]
  941. verbs: ["deletecollection"]
  942. omitStages:
  943. - "RequestReceived"
  944. # Secrets, ConfigMaps, and TokenReviews can contain sensitive & binary data,
  945. # so only log at the Metadata level.
  946. - level: Metadata
  947. resources:
  948. - group: "" # core
  949. resources: ["secrets", "configmaps"]
  950. - group: authentication.k8s.io
  951. resources: ["tokenreviews"]
  952. omitStages:
  953. - "RequestReceived"
  954. # Get repsonses can be large; skip them.
  955. - level: Request
  956. verbs: ["get", "list", "watch"]
  957. resources: ${known_apis}
  958. omitStages:
  959. - "RequestReceived"
  960. # Default level for known APIs
  961. - level: RequestResponse
  962. resources: ${known_apis}
  963. omitStages:
  964. - "RequestReceived"
  965. # Default level for all other requests.
  966. - level: Metadata
  967. omitStages:
  968. - "RequestReceived"
  969. EOF
  970. }
  971. # Writes the configuration file used by the webhook advanced auditing backend.
  972. function create-master-audit-webhook-config {
  973. local -r path="${1}"
  974. if [[ -n "${GCP_AUDIT_URL:-}" ]]; then
  975. # The webhook config file is a kubeconfig file describing the webhook endpoint.
  976. cat <<EOF >"${path}"
  977. clusters:
  978. - name: gcp-audit-server
  979. cluster:
  980. server: ${GCP_AUDIT_URL}
  981. users:
  982. - name: kube-apiserver
  983. user:
  984. auth-provider:
  985. name: gcp
  986. current-context: webhook
  987. contexts:
  988. - context:
  989. cluster: gcp-audit-server
  990. user: kube-apiserver
  991. name: webhook
  992. EOF
  993. fi
  994. }
  995. function create-kubeconfig {
  996. local component=$1
  997. local token=$2
  998. echo "Creating kubeconfig file for component ${component}"
  999. mkdir -p /etc/srv/kubernetes/${component}
  1000. cat <<EOF >/etc/srv/kubernetes/${component}/kubeconfig
  1001. apiVersion: v1
  1002. kind: Config
  1003. users:
  1004. - name: ${component}
  1005. user:
  1006. token: ${token}
  1007. clusters:
  1008. - name: local
  1009. cluster:
  1010. insecure-skip-tls-verify: true
  1011. server: https://localhost:443
  1012. contexts:
  1013. - context:
  1014. cluster: local
  1015. user: ${component}
  1016. name: ${component}
  1017. current-context: ${component}
  1018. EOF
  1019. }
  1020. # Arg 1: the IP address of the API server
  1021. function create-kubelet-kubeconfig() {
  1022. local apiserver_address="${1}"
  1023. if [[ -z "${apiserver_address}" ]]; then
  1024. echo "Must provide API server address to create Kubelet kubeconfig file!"
  1025. exit 1
  1026. fi
  1027. if [[ "${CREATE_BOOTSTRAP_KUBECONFIG:-true}" == "true" ]]; then
  1028. echo "Creating kubelet bootstrap-kubeconfig file"
  1029. cat <<EOF >/var/lib/kubelet/bootstrap-kubeconfig
  1030. apiVersion: v1
  1031. kind: Config
  1032. users:
  1033. - name: kubelet
  1034. user:
  1035. client-certificate: ${KUBELET_CERT_PATH}
  1036. client-key: ${KUBELET_KEY_PATH}
  1037. clusters:
  1038. - name: local
  1039. cluster:
  1040. server: https://${apiserver_address}
  1041. certificate-authority: ${CA_CERT_BUNDLE_PATH}
  1042. contexts:
  1043. - context:
  1044. cluster: local
  1045. user: kubelet
  1046. name: service-account-context
  1047. current-context: service-account-context
  1048. EOF
  1049. elif [[ "${FETCH_BOOTSTRAP_KUBECONFIG:-false}" == "true" ]]; then
  1050. echo "Fetching kubelet bootstrap-kubeconfig file from metadata"
  1051. get-metadata-value "instance/attributes/bootstrap-kubeconfig" >/var/lib/kubelet/bootstrap-kubeconfig
  1052. else
  1053. echo "Fetching kubelet kubeconfig file from metadata"
  1054. get-metadata-value "instance/attributes/kubeconfig" >/var/lib/kubelet/kubeconfig
  1055. fi
  1056. }
  1057. # Uses KUBELET_CA_CERT (falling back to CA_CERT), KUBELET_CERT, and KUBELET_KEY
  1058. # to generate a kubeconfig file for the kubelet to securely connect to the apiserver.
  1059. # Set REGISTER_MASTER_KUBELET to true if kubelet on the master node
  1060. # should register to the apiserver.
  1061. function create-master-kubelet-auth {
  1062. # Only configure the kubelet on the master if the required variables are
  1063. # set in the environment.
  1064. if [[ -n "${KUBELET_APISERVER:-}" && -n "${KUBELET_CERT:-}" && -n "${KUBELET_KEY:-}" ]]; then
  1065. REGISTER_MASTER_KUBELET="true"
  1066. create-kubelet-kubeconfig ${KUBELET_APISERVER}
  1067. fi
  1068. }
  1069. function create-kubeproxy-user-kubeconfig {
  1070. echo "Creating kube-proxy user kubeconfig file"
  1071. cat <<EOF >/var/lib/kube-proxy/kubeconfig
  1072. apiVersion: v1
  1073. kind: Config
  1074. users:
  1075. - name: kube-proxy
  1076. user:
  1077. token: ${KUBE_PROXY_TOKEN}
  1078. clusters:
  1079. - name: local
  1080. cluster:
  1081. certificate-authority-data: ${CA_CERT_BUNDLE}
  1082. contexts:
  1083. - context:
  1084. cluster: local
  1085. user: kube-proxy
  1086. name: service-account-context
  1087. current-context: service-account-context
  1088. EOF
  1089. }
  1090. function create-kubescheduler-policy-config {
  1091. echo "Creating kube-scheduler policy config file"
  1092. mkdir -p /etc/srv/kubernetes/kube-scheduler
  1093. cat <<EOF >/etc/srv/kubernetes/kube-scheduler/policy-config
  1094. ${SCHEDULER_POLICY_CONFIG}
  1095. EOF
  1096. }
  1097. function create-node-problem-detector-kubeconfig {
  1098. local apiserver_address="${1}"
  1099. if [[ -z "${apiserver_address}" ]]; then
  1100. echo "Must provide API server address to create node-problem-detector kubeconfig file!"
  1101. exit 1
  1102. fi
  1103. echo "Creating node-problem-detector kubeconfig file"
  1104. mkdir -p /var/lib/node-problem-detector
  1105. cat <<EOF >/var/lib/node-problem-detector/kubeconfig
  1106. apiVersion: v1
  1107. kind: Config
  1108. users:
  1109. - name: node-problem-detector
  1110. user:
  1111. token: ${NODE_PROBLEM_DETECTOR_TOKEN}
  1112. clusters:
  1113. - name: local
  1114. cluster:
  1115. server: https://${apiserver_address}
  1116. certificate-authority-data: ${CA_CERT}
  1117. contexts:
  1118. - context:
  1119. cluster: local
  1120. user: node-problem-detector
  1121. name: service-account-context
  1122. current-context: service-account-context
  1123. EOF
  1124. }
  1125. function create-node-problem-detector-kubeconfig-from-kubelet {
  1126. echo "Creating node-problem-detector kubeconfig from /var/lib/kubelet/kubeconfig"
  1127. mkdir -p /var/lib/node-problem-detector
  1128. cp /var/lib/kubelet/kubeconfig /var/lib/node-problem-detector/kubeconfig
  1129. }
  1130. function create-master-etcd-auth {
  1131. if [[ -n "${ETCD_CA_CERT:-}" && -n "${ETCD_PEER_KEY:-}" && -n "${ETCD_PEER_CERT:-}" ]]; then
  1132. local -r auth_dir="/etc/srv/kubernetes"
  1133. echo "${ETCD_CA_CERT}" | base64 --decode | gunzip > "${auth_dir}/etcd-ca.crt"
  1134. echo "${ETCD_PEER_KEY}" | base64 --decode > "${auth_dir}/etcd-peer.key"
  1135. echo "${ETCD_PEER_CERT}" | base64 --decode | gunzip > "${auth_dir}/etcd-peer.crt"
  1136. fi
  1137. }
  1138. function create-master-etcd-apiserver-auth {
  1139. 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
  1140. local -r auth_dir="/etc/srv/kubernetes/pki"
  1141. ETCD_APISERVER_CA_KEY_PATH="${auth_dir}/etcd-apiserver-ca.key"
  1142. echo "${ETCD_APISERVER_CA_KEY}" | base64 --decode > "${ETCD_APISERVER_CA_KEY_PATH}"
  1143. # Keep in sync with add-replica-to-etcd/remove-replica-from-etcd in util.sh.
  1144. ETCD_APISERVER_CA_CERT_PATH="${auth_dir}/etcd-apiserver-ca.crt"
  1145. echo "${ETCD_APISERVER_CA_CERT}" | base64 --decode | gunzip > "${ETCD_APISERVER_CA_CERT_PATH}"
  1146. ETCD_APISERVER_SERVER_KEY_PATH="${auth_dir}/etcd-apiserver-server.key"
  1147. echo "${ETCD_APISERVER_SERVER_KEY}" | base64 --decode > "${ETCD_APISERVER_SERVER_KEY_PATH}"
  1148. ETCD_APISERVER_SERVER_CERT_PATH="${auth_dir}/etcd-apiserver-server.crt"
  1149. echo "${ETCD_APISERVER_SERVER_CERT}" | base64 --decode | gunzip > "${ETCD_APISERVER_SERVER_CERT_PATH}"
  1150. # Keep in sync with add-replica-to-etcd/remove-replica-from-etcd in util.sh.
  1151. ETCD_APISERVER_CLIENT_KEY_PATH="${auth_dir}/etcd-apiserver-client.key"
  1152. echo "${ETCD_APISERVER_CLIENT_KEY}" | base64 --decode > "${ETCD_APISERVER_CLIENT_KEY_PATH}"
  1153. # Keep in sync with add-replica-to-etcd/remove-replica-from-etcd in util.sh.
  1154. ETCD_APISERVER_CLIENT_CERT_PATH="${auth_dir}/etcd-apiserver-client.crt"
  1155. echo "${ETCD_APISERVER_CLIENT_CERT}" | base64 --decode | gunzip > "${ETCD_APISERVER_CLIENT_CERT_PATH}"
  1156. fi
  1157. }
  1158. function create-master-konnectivity-server-apiserver-auth {
  1159. echo TODO: implement create-master-konnectivity-server-apiserver-auth
  1160. }
  1161. function assemble-docker-flags {
  1162. echo "Assemble docker command line flags"
  1163. local docker_opts="-p /var/run/docker.pid --iptables=false --ip-masq=false"
  1164. if [[ "${TEST_CLUSTER:-}" == "true" ]]; then
  1165. docker_opts+=" --log-level=debug"
  1166. else
  1167. docker_opts+=" --log-level=warn"
  1168. fi
  1169. local use_net_plugin="true"
  1170. if [[ "${NETWORK_PROVIDER:-}" == "kubenet" || "${NETWORK_PROVIDER:-}" == "cni" ]]; then
  1171. # set docker0 cidr to private ip address range to avoid conflict with cbr0 cidr range
  1172. docker_opts+=" --bip=169.254.123.1/24"
  1173. else
  1174. use_net_plugin="false"
  1175. docker_opts+=" --bridge=cbr0"
  1176. fi
  1177. # Decide whether to enable a docker registry mirror. This is taken from
  1178. # the "kube-env" metadata value.
  1179. if [[ -n "${DOCKER_REGISTRY_MIRROR_URL:-}" ]]; then
  1180. echo "Enable docker registry mirror at: ${DOCKER_REGISTRY_MIRROR_URL}"
  1181. docker_opts+=" --registry-mirror=${DOCKER_REGISTRY_MIRROR_URL}"
  1182. fi
  1183. # Configure docker logging
  1184. docker_opts+=" --log-driver=${DOCKER_LOG_DRIVER:-json-file}"
  1185. docker_opts+=" --log-opt=max-size=${DOCKER_LOG_MAX_SIZE:-10m}"
  1186. docker_opts+=" --log-opt=max-file=${DOCKER_LOG_MAX_FILE:-5}"
  1187. # Disable live-restore if the environment variable is set.
  1188. if [[ "${DISABLE_DOCKER_LIVE_RESTORE:-false}" == "true" ]]; then
  1189. docker_opts+=" --live-restore=false"
  1190. fi
  1191. echo "DOCKER_OPTS=\"${docker_opts} ${EXTRA_DOCKER_OPTS:-}\"" > /etc/default/docker
  1192. # Ensure TasksMax is sufficient for docker.
  1193. # (https://github.com/kubernetes/kubernetes/issues/51977)
  1194. echo "Extend the docker.service configuration to set a higher pids limit"
  1195. mkdir -p /etc/systemd/system/docker.service.d
  1196. cat <<EOF >/etc/systemd/system/docker.service.d/01tasksmax.conf
  1197. [Service]
  1198. TasksMax=infinity
  1199. EOF
  1200. systemctl daemon-reload
  1201. echo "Docker command line is updated. Restart docker to pick it up"
  1202. systemctl restart docker
  1203. }
  1204. # This function assembles the kubelet systemd service file and starts it
  1205. # using systemctl.
  1206. function start-kubelet {
  1207. echo "Start kubelet"
  1208. # TODO(#60123): The kubelet should create the cert-dir directory if it doesn't exist
  1209. mkdir -p /var/lib/kubelet/pki/
  1210. local kubelet_bin="${KUBE_HOME}/bin/kubelet"
  1211. local -r version="$("${kubelet_bin}" --version=true | cut -f2 -d " ")"
  1212. local -r builtin_kubelet="/usr/bin/kubelet"
  1213. if [[ "${TEST_CLUSTER:-}" == "true" ]]; then
  1214. # Determine which binary to use on test clusters. We use the built-in
  1215. # version only if the downloaded version is the same as the built-in
  1216. # version. This allows GCI to run some of the e2e tests to qualify the
  1217. # built-in kubelet.
  1218. if [[ -x "${builtin_kubelet}" ]]; then
  1219. local -r builtin_version="$("${builtin_kubelet}" --version=true | cut -f2 -d " ")"
  1220. if [[ "${builtin_version}" == "${version}" ]]; then
  1221. kubelet_bin="${builtin_kubelet}"
  1222. fi
  1223. fi
  1224. fi
  1225. echo "Using kubelet binary at ${kubelet_bin}"
  1226. local -r kubelet_env_file="/etc/default/kubelet"
  1227. local kubelet_opts="${KUBELET_ARGS} ${KUBELET_CONFIG_FILE_ARG:-}"
  1228. echo "KUBELET_OPTS=\"${kubelet_opts}\"" > "${kubelet_env_file}"
  1229. echo "KUBE_COVERAGE_FILE=\"/var/log/kubelet.cov\"" >> "${kubelet_env_file}"
  1230. # Write the systemd service file for kubelet.
  1231. cat <<EOF >/etc/systemd/system/kubelet.service
  1232. [Unit]
  1233. Description=Kubernetes kubelet
  1234. Requires=network-online.target
  1235. After=network-online.target
  1236. [Service]
  1237. Restart=always
  1238. RestartSec=10
  1239. EnvironmentFile=${kubelet_env_file}
  1240. ExecStart=${kubelet_bin} \$KUBELET_OPTS
  1241. [Install]
  1242. WantedBy=multi-user.target
  1243. EOF
  1244. systemctl daemon-reload
  1245. systemctl start kubelet.service
  1246. }
  1247. # This function assembles the node problem detector systemd service file and
  1248. # starts it using systemctl.
  1249. function start-node-problem-detector {
  1250. echo "Start node problem detector"
  1251. local -r npd_bin="${KUBE_HOME}/bin/node-problem-detector"
  1252. echo "Using node problem detector binary at ${npd_bin}"
  1253. local flags="${NODE_PROBLEM_DETECTOR_CUSTOM_FLAGS:-}"
  1254. if [[ -z "${flags}" ]]; then
  1255. local -r km_config="${KUBE_HOME}/node-problem-detector/config/kernel-monitor.json"
  1256. # TODO(random-liu): Handle this for alternative container runtime.
  1257. local -r dm_config="${KUBE_HOME}/node-problem-detector/config/docker-monitor.json"
  1258. local -r sm_config="${KUBE_HOME}/node-problem-detector/config/systemd-monitor.json"
  1259. local -r ssm_config="${KUBE_HOME}/node-problem-detector/config/system-stats-monitor.json"
  1260. local -r custom_km_config="${KUBE_HOME}/node-problem-detector/config/kernel-monitor-counter.json"
  1261. local -r custom_sm_config="${KUBE_HOME}/node-problem-detector/config/systemd-monitor-counter.json"
  1262. flags="${NPD_TEST_LOG_LEVEL:-"--v=2"} ${NPD_TEST_ARGS:-}"
  1263. flags+=" --logtostderr"
  1264. flags+=" --config.system-log-monitor=${km_config},${dm_config},${sm_config}"
  1265. flags+=" --config.system-stats-monitor=${ssm_config}"
  1266. flags+=" --config.custom-plugin-monitor=${custom_km_config},${custom_sm_config}"
  1267. local -r npd_port=${NODE_PROBLEM_DETECTOR_PORT:-20256}
  1268. flags+=" --port=${npd_port}"
  1269. if [[ -n "${EXTRA_NPD_ARGS:-}" ]]; then
  1270. flags+=" ${EXTRA_NPD_ARGS}"
  1271. fi
  1272. fi
  1273. flags+=" --apiserver-override=https://${KUBERNETES_MASTER_NAME}?inClusterConfig=false&auth=/var/lib/node-problem-detector/kubeconfig"
  1274. # Write the systemd service file for node problem detector.
  1275. cat <<EOF >/etc/systemd/system/node-problem-detector.service
  1276. [Unit]
  1277. Description=Kubernetes node problem detector
  1278. Requires=network-online.target
  1279. After=network-online.target
  1280. [Service]
  1281. Restart=always
  1282. RestartSec=10
  1283. ExecStart=${npd_bin} ${flags}
  1284. [Install]
  1285. WantedBy=multi-user.target
  1286. EOF
  1287. systemctl start node-problem-detector.service
  1288. }
  1289. # Create the log file and set its properties.
  1290. #
  1291. # $1 is the file to create.
  1292. # $2: the log owner uid to set for the log file.
  1293. # $3: the log owner gid to set for the log file.
  1294. function prepare-log-file {
  1295. touch $1
  1296. chmod 644 $1
  1297. chown "${2:-${LOG_OWNER_USER:-root}}":"${3:-${LOG_OWNER_GROUP:-root}}" $1
  1298. }
  1299. # Prepares parameters for kube-proxy manifest.
  1300. # $1 source path of kube-proxy manifest.
  1301. function prepare-kube-proxy-manifest-variables {
  1302. local -r src_file=$1;
  1303. local -r kubeconfig="--kubeconfig=/var/lib/kube-proxy/kubeconfig"
  1304. local kube_docker_registry="k8s.gcr.io"
  1305. if [[ -n "${KUBE_DOCKER_REGISTRY:-}" ]]; then
  1306. kube_docker_registry=${KUBE_DOCKER_REGISTRY}
  1307. fi
  1308. local -r kube_proxy_docker_tag=$(cat /home/kubernetes/kube-docker-files/kube-proxy.docker_tag)
  1309. local api_servers="--master=https://${KUBERNETES_MASTER_NAME}"
  1310. local params="${KUBEPROXY_TEST_LOG_LEVEL:-"--v=2"}"
  1311. if [[ -n "${FEATURE_GATES:-}" ]]; then
  1312. params+=" --feature-gates=${FEATURE_GATES}"
  1313. fi
  1314. if [[ "${KUBE_PROXY_MODE:-}" == "ipvs" ]];then
  1315. sudo modprobe -a ip_vs ip_vs_rr ip_vs_wrr ip_vs_sh nf_conntrack_ipv4
  1316. if [[ $? -eq 0 ]];
  1317. then
  1318. params+=" --proxy-mode=ipvs"
  1319. else
  1320. # If IPVS modules are not present, make sure the node does not come up as
  1321. # healthy.
  1322. exit 1
  1323. fi
  1324. fi
  1325. params+=" --iptables-sync-period=1m --iptables-min-sync-period=10s --ipvs-sync-period=1m --ipvs-min-sync-period=10s"
  1326. if [[ -n "${KUBEPROXY_TEST_ARGS:-}" ]]; then
  1327. params+=" ${KUBEPROXY_TEST_ARGS}"
  1328. fi
  1329. local container_env=""
  1330. local kube_cache_mutation_detector_env_name=""
  1331. local kube_cache_mutation_detector_env_value=""
  1332. if [[ -n "${ENABLE_CACHE_MUTATION_DETECTOR:-}" ]]; then
  1333. container_env="env:"
  1334. kube_cache_mutation_detector_env_name="- name: KUBE_CACHE_MUTATION_DETECTOR"
  1335. kube_cache_mutation_detector_env_value="value: \"${ENABLE_CACHE_MUTATION_DETECTOR}\""
  1336. fi
  1337. sed -i -e "s@{{kubeconfig}}@${kubeconfig}@g" ${src_file}
  1338. sed -i -e "s@{{pillar\['kube_docker_registry'\]}}@${kube_docker_registry}@g" ${src_file}
  1339. sed -i -e "s@{{pillar\['kube-proxy_docker_tag'\]}}@${kube_proxy_docker_tag}@g" ${src_file}
  1340. sed -i -e "s@{{params}}@${params}@g" ${src_file}
  1341. sed -i -e "s@{{container_env}}@${container_env}@g" ${src_file}
  1342. sed -i -e "s@{{kube_cache_mutation_detector_env_name}}@${kube_cache_mutation_detector_env_name}@g" ${src_file}
  1343. sed -i -e "s@{{kube_cache_mutation_detector_env_value}}@${kube_cache_mutation_detector_env_value}@g" ${src_file}
  1344. sed -i -e "s@{{ cpurequest }}@100m@g" ${src_file}
  1345. sed -i -e "s@{{api_servers_with_port}}@${api_servers}@g" ${src_file}
  1346. sed -i -e "s@{{kubernetes_service_host_env_value}}@${KUBERNETES_MASTER_NAME}@g" ${src_file}
  1347. if [[ -n "${CLUSTER_IP_RANGE:-}" ]]; then
  1348. sed -i -e "s@{{cluster_cidr}}@--cluster-cidr=${CLUSTER_IP_RANGE}@g" ${src_file}
  1349. fi
  1350. }
  1351. # Starts kube-proxy static pod.
  1352. function start-kube-proxy {
  1353. echo "Start kube-proxy static pod"
  1354. prepare-log-file /var/log/kube-proxy.log
  1355. local -r src_file="${KUBE_HOME}/kube-manifests/kubernetes/gci-trusty/kube-proxy.manifest"
  1356. prepare-kube-proxy-manifest-variables "${src_file}"
  1357. cp "${src_file}" /etc/kubernetes/manifests
  1358. }
  1359. # Replaces the variables in the etcd manifest file with the real values, and then
  1360. # copy the file to the manifest dir
  1361. # $1: value for variable 'suffix'
  1362. # $2: value for variable 'port'
  1363. # $3: value for variable 'server_port'
  1364. # $4: value for variable 'cpulimit'
  1365. # $5: pod name, which should be either etcd or etcd-events
  1366. function prepare-etcd-manifest {
  1367. local host_name=${ETCD_HOSTNAME:-$(hostname -s)}
  1368. local host_ip=$(${PYTHON} -c "import socket;print(socket.gethostbyname(\"${host_name}\"))")
  1369. local etcd_cluster=""
  1370. local cluster_state="new"
  1371. local etcd_protocol="http"
  1372. local etcd_apiserver_protocol="http"
  1373. local etcd_creds=""
  1374. local etcd_apiserver_creds="${ETCD_APISERVER_CREDS:-}"
  1375. local etcd_extra_args="${ETCD_EXTRA_ARGS:-}"
  1376. local suffix="$1"
  1377. local etcd_livenessprobe_port="$2"
  1378. if [[ -n "${INITIAL_ETCD_CLUSTER_STATE:-}" ]]; then
  1379. cluster_state="${INITIAL_ETCD_CLUSTER_STATE}"
  1380. fi
  1381. if [[ -n "${ETCD_CA_CERT:-}" && -n "${ETCD_PEER_KEY:-}" && -n "${ETCD_PEER_CERT:-}" ]]; then
  1382. 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 "
  1383. etcd_protocol="https"
  1384. fi
  1385. # mTLS should only be enabled for etcd server but not etcd-events. if $1 suffix is empty, it's etcd server.
  1386. 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
  1387. 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} "
  1388. etcd_apiserver_protocol="https"
  1389. etcd_livenessprobe_port="2382"
  1390. etcd_extra_args+=" --listen-metrics-urls=http://${ETCD_LISTEN_CLIENT_IP:-127.0.0.1}:${etcd_livenessprobe_port} "
  1391. fi
  1392. for host in $(echo "${INITIAL_ETCD_CLUSTER:-${host_name}}" | tr "," "\n"); do
  1393. etcd_host="etcd-${host}=${etcd_protocol}://${host}:$3"
  1394. if [[ -n "${etcd_cluster}" ]]; then
  1395. etcd_cluster+=","
  1396. fi
  1397. etcd_cluster+="${etcd_host}"
  1398. done
  1399. local -r temp_file="/tmp/$5"
  1400. cp "${KUBE_HOME}/kube-manifests/kubernetes/gci-trusty/etcd.manifest" "${temp_file}"
  1401. sed -i -e "s@{{ *suffix *}}@$1@g" "${temp_file}"
  1402. sed -i -e "s@{{ *port *}}@$2@g" "${temp_file}"
  1403. sed -i -e "s@{{ *server_port *}}@$3@g" "${temp_file}"
  1404. sed -i -e "s@{{ *cpulimit *}}@\"$4\"@g" "${temp_file}"
  1405. sed -i -e "s@{{ *hostname *}}@$host_name@g" "${temp_file}"
  1406. sed -i -e "s@{{ *host_ip *}}@$host_ip@g" "${temp_file}"
  1407. sed -i -e "s@{{ *etcd_cluster *}}@$etcd_cluster@g" "${temp_file}"
  1408. sed -i -e "s@{{ *liveness_probe_initial_delay *}}@${ETCD_LIVENESS_PROBE_INITIAL_DELAY_SEC:-15}@g" "${temp_file}"
  1409. sed -i -e "s@{{ *listen_client_ip *}}@${ETCD_LISTEN_CLIENT_IP:-127.0.0.1}@g" "${temp_file}"
  1410. # Get default storage backend from manifest file.
  1411. local -r default_storage_backend=$(cat "${temp_file}" | \
  1412. grep -o "{{ *pillar\.get('storage_backend', '\(.*\)') *}}" | \
  1413. sed -e "s@{{ *pillar\.get('storage_backend', '\(.*\)') *}}@\1@g")
  1414. if [[ -n "${STORAGE_BACKEND:-}" ]]; then
  1415. sed -i -e "s@{{ *pillar\.get('storage_backend', '\(.*\)') *}}@${STORAGE_BACKEND}@g" "${temp_file}"
  1416. else
  1417. sed -i -e "s@{{ *pillar\.get('storage_backend', '\(.*\)') *}}@\1@g" "${temp_file}"
  1418. fi
  1419. if [[ "${STORAGE_BACKEND:-${default_storage_backend}}" == "etcd3" ]]; then
  1420. sed -i -e "s@{{ *quota_bytes *}}@--quota-backend-bytes=${ETCD_QUOTA_BACKEND_BYTES:-4294967296}@g" "${temp_file}"
  1421. else
  1422. sed -i -e "s@{{ *quota_bytes *}}@@g" "${temp_file}"
  1423. fi
  1424. sed -i -e "s@{{ *cluster_state *}}@$cluster_state@g" "${temp_file}"
  1425. if [[ -n "${ETCD_IMAGE:-}" ]]; then
  1426. sed -i -e "s@{{ *pillar\.get('etcd_docker_tag', '\(.*\)') *}}@${ETCD_IMAGE}@g" "${temp_file}"
  1427. else
  1428. sed -i -e "s@{{ *pillar\.get('etcd_docker_tag', '\(.*\)') *}}@\1@g" "${temp_file}"
  1429. fi
  1430. if [[ -n "${ETCD_DOCKER_REPOSITORY:-}" ]]; then
  1431. sed -i -e "s@{{ *pillar\.get('etcd_docker_repository', '\(.*\)') *}}@${ETCD_DOCKER_REPOSITORY}@g" "${temp_file}"
  1432. else
  1433. sed -i -e "s@{{ *pillar\.get('etcd_docker_repository', '\(.*\)') *}}@\1@g" "${temp_file}"
  1434. fi
  1435. sed -i -e "s@{{ *etcd_protocol *}}@$etcd_protocol@g" "${temp_file}"
  1436. sed -i -e "s@{{ *etcd_apiserver_protocol *}}@$etcd_apiserver_protocol@g" "${temp_file}"
  1437. sed -i -e "s@{{ *etcd_creds *}}@$etcd_creds@g" "${temp_file}"
  1438. sed -i -e "s@{{ *etcd_apiserver_creds *}}@$etcd_apiserver_creds@g" "${temp_file}"
  1439. sed -i -e "s@{{ *etcd_extra_args *}}@$etcd_extra_args@g" "${temp_file}"
  1440. sed -i -e "s@{{ *etcd_livenessprobe_port *}}@$etcd_livenessprobe_port@g" "${temp_file}"
  1441. if [[ -n "${ETCD_VERSION:-}" ]]; then
  1442. sed -i -e "s@{{ *pillar\.get('etcd_version', '\(.*\)') *}}@${ETCD_VERSION}@g" "${temp_file}"
  1443. else
  1444. sed -i -e "s@{{ *pillar\.get('etcd_version', '\(.*\)') *}}@\1@g" "${temp_file}"
  1445. fi
  1446. # Replace the volume host path.
  1447. sed -i -e "s@/mnt/master-pd/var/etcd@/mnt/disks/master-pd/var/etcd@g" "${temp_file}"
  1448. mv "${temp_file}" /etc/kubernetes/manifests
  1449. }
  1450. function start-etcd-empty-dir-cleanup-pod {
  1451. local -r src_file="${KUBE_HOME}/kube-manifests/kubernetes/gci-trusty/etcd-empty-dir-cleanup.yaml"
  1452. cp "${src_file}" "/etc/kubernetes/manifests"
  1453. }
  1454. # Starts etcd server pod (and etcd-events pod if needed).
  1455. # More specifically, it prepares dirs and files, sets the variable value
  1456. # in the manifests, and copies them to /etc/kubernetes/manifests.
  1457. function start-etcd-servers {
  1458. echo "Start etcd pods"
  1459. if [[ -d /etc/etcd ]]; then
  1460. rm -rf /etc/etcd
  1461. fi
  1462. if [[ -e /etc/default/etcd ]]; then
  1463. rm -f /etc/default/etcd
  1464. fi
  1465. if [[ -e /etc/systemd/system/etcd.service ]]; then
  1466. rm -f /etc/systemd/system/etcd.service
  1467. fi
  1468. if [[ -e /etc/init.d/etcd ]]; then
  1469. rm -f /etc/init.d/etcd
  1470. fi
  1471. prepare-log-file /var/log/etcd.log
  1472. prepare-etcd-manifest "" "2379" "2380" "200m" "etcd.manifest"
  1473. prepare-log-file /var/log/etcd-events.log
  1474. prepare-etcd-manifest "-events" "4002" "2381" "100m" "etcd-events.manifest"
  1475. }
  1476. # Replaces the variables in the konnectivity-server manifest file with the real values, and then
  1477. # copy the file to the manifest dir
  1478. # $1: value for variable "agent_port"
  1479. # $2: value for bariable "admin_port"
  1480. function prepare-konnectivity-server-manifest {
  1481. local -r temp_file="/tmp/konnectivity-server.yaml"
  1482. params=()
  1483. cp "${KUBE_HOME}/kube-manifests/kubernetes/gci-trusty/konnectivity-server.yaml" "${temp_file}"
  1484. params+=("--log-file=/var/log/konnectivity-server.log")
  1485. params+=("--logtostderr=false")
  1486. params+=("--log-file-max-size=0")
  1487. params+=("--uds-name=/etc/srv/kubernetes/konnectivity/konnectivity-server.socket")
  1488. params+=("--cluster-cert=/etc/srv/kubernetes/pki/apiserver.crt")
  1489. params+=("--cluster-key=/etc/srv/kubernetes/pki/apiserver.key")
  1490. params+=("--mode=http-connect")
  1491. params+=("--server-port=0")
  1492. params+=("--agent-port=$1")
  1493. params+=("--admin-port=$2")
  1494. konnectivity_args=""
  1495. for param in "${params[@]}"; do
  1496. konnectivity_args+=", \"${param}\""
  1497. done
  1498. sed -i -e "s@{{ *konnectivity_args *}}@${konnectivity_args}@g" "${temp_file}"
  1499. sed -i -e "s@{{ *agent_port *}}@$1@g" "${temp_file}"
  1500. sed -i -e "s@{{ *admin_port *}}@$2@g" "${temp_file}"
  1501. sed -i -e "s@{{ *liveness_probe_initial_delay *}}@30@g" "${temp_file}"
  1502. mv "${temp_file}" /etc/kubernetes/manifests
  1503. }
  1504. # Starts konnectivity server pod.
  1505. # More specifically, it prepares dirs and files, sets the variable value
  1506. # in the manifests, and copies them to /etc/kubernetes/manifests.
  1507. function start-konnectivity-server {
  1508. echo "Start konnectivity server pods"
  1509. prepare-log-file /var/log/konnectivity-server.log
  1510. prepare-konnectivity-server-manifest "8132" "8133"
  1511. }
  1512. # Calculates the following variables based on env variables, which will be used
  1513. # by the manifests of several kube-master components.
  1514. # CLOUD_CONFIG_OPT
  1515. # CLOUD_CONFIG_VOLUME
  1516. # CLOUD_CONFIG_MOUNT
  1517. # DOCKER_REGISTRY
  1518. # FLEXVOLUME_HOSTPATH_MOUNT
  1519. # FLEXVOLUME_HOSTPATH_VOLUME
  1520. # INSECURE_PORT_MAPPING
  1521. function compute-master-manifest-variables {
  1522. CLOUD_CONFIG_OPT=""
  1523. CLOUD_CONFIG_VOLUME=""
  1524. CLOUD_CONFIG_MOUNT=""
  1525. if [[ -f /etc/gce.conf ]]; then
  1526. CLOUD_CONFIG_OPT="--cloud-config=/etc/gce.conf"
  1527. CLOUD_CONFIG_VOLUME="{\"name\": \"cloudconfigmount\",\"hostPath\": {\"path\": \"/etc/gce.conf\", \"type\": \"FileOrCreate\"}},"
  1528. CLOUD_CONFIG_MOUNT="{\"name\": \"cloudconfigmount\",\"mountPath\": \"/etc/gce.conf\", \"readOnly\": true},"
  1529. fi
  1530. DOCKER_REGISTRY="k8s.gcr.io"
  1531. if [[ -n "${KUBE_DOCKER_REGISTRY:-}" ]]; then
  1532. DOCKER_REGISTRY="${KUBE_DOCKER_REGISTRY}"
  1533. fi
  1534. FLEXVOLUME_HOSTPATH_MOUNT=""
  1535. FLEXVOLUME_HOSTPATH_VOLUME=""
  1536. if [[ -n "${VOLUME_PLUGIN_DIR:-}" ]]; then
  1537. FLEXVOLUME_HOSTPATH_MOUNT="{ \"name\": \"flexvolumedir\", \"mountPath\": \"${VOLUME_PLUGIN_DIR}\", \"readOnly\": true},"
  1538. FLEXVOLUME_HOSTPATH_VOLUME="{ \"name\": \"flexvolumedir\", \"hostPath\": {\"path\": \"${VOLUME_PLUGIN_DIR}\"}},"
  1539. fi
  1540. INSECURE_PORT_MAPPING=""
  1541. if [[ "${ENABLE_APISERVER_INSECURE_PORT:-false}" == "true" ]]; then
  1542. INSECURE_PORT_MAPPING="{ \"name\": \"local\", \"containerPort\": 8080, \"hostPort\": 8080},"
  1543. fi
  1544. }
  1545. # A helper function that bind mounts kubelet dirs for running mount in a chroot
  1546. function prepare-mounter-rootfs {
  1547. echo "Prepare containerized mounter"
  1548. mount --bind "${CONTAINERIZED_MOUNTER_HOME}" "${CONTAINERIZED_MOUNTER_HOME}"
  1549. mount -o remount,exec "${CONTAINERIZED_MOUNTER_HOME}"
  1550. CONTAINERIZED_MOUNTER_ROOTFS="${CONTAINERIZED_MOUNTER_HOME}/rootfs"
  1551. mount --rbind /var/lib/kubelet/ "${CONTAINERIZED_MOUNTER_ROOTFS}/var/lib/kubelet"
  1552. mount --make-rshared "${CONTAINERIZED_MOUNTER_ROOTFS}/var/lib/kubelet"
  1553. mount --bind -o ro /proc "${CONTAINERIZED_MOUNTER_ROOTFS}/proc"
  1554. mount --bind -o ro /dev "${CONTAINERIZED_MOUNTER_ROOTFS}/dev"
  1555. cp /etc/resolv.conf "${CONTAINERIZED_MOUNTER_ROOTFS}/etc/"
  1556. }
  1557. # Updates node labels used by addons.
  1558. function update-legacy-addon-node-labels() {
  1559. # need kube-apiserver to be ready
  1560. until kubectl get nodes; do
  1561. sleep 5
  1562. done
  1563. update-node-label "beta.kubernetes.io/metadata-proxy-ready=true,cloud.google.com/metadata-proxy-ready!=true" "cloud.google.com/metadata-proxy-ready=true"
  1564. 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"
  1565. 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"
  1566. }
  1567. # A helper function for labeling all nodes matching a given selector.
  1568. # Runs: kubectl label --overwrite nodes -l "${1}" "${2}"
  1569. # Retries on failure
  1570. #
  1571. # $1: label selector of nodes
  1572. # $2: label to apply
  1573. function update-node-label() {
  1574. local selector="$1"
  1575. local label="$2"
  1576. local retries=5
  1577. until (( retries == 0 )); do
  1578. if kubectl label --overwrite nodes -l "${selector}" "${label}"; then
  1579. break
  1580. fi
  1581. (( retries-- ))
  1582. sleep 3
  1583. done
  1584. }
  1585. # Starts kubernetes controller manager.
  1586. # It prepares the log file, loads the docker image, calculates variables, sets them
  1587. # in the manifest file, and then copies the manifest file to /etc/kubernetes/manifests.
  1588. #
  1589. # Assumed vars (which are calculated in function compute-master-manifest-variables)
  1590. # CLOUD_CONFIG_OPT
  1591. # CLOUD_CONFIG_VOLUME
  1592. # CLOUD_CONFIG_MOUNT
  1593. # DOCKER_REGISTRY
  1594. function start-kube-controller-manager {
  1595. echo "Start kubernetes controller-manager"
  1596. create-kubeconfig "kube-controller-manager" ${KUBE_CONTROLLER_MANAGER_TOKEN}
  1597. prepare-log-file /var/log/kube-controller-manager.log
  1598. # Calculate variables and assemble the command line.
  1599. local params="${CONTROLLER_MANAGER_TEST_LOG_LEVEL:-"--v=2"} ${CONTROLLER_MANAGER_TEST_ARGS:-} ${CLOUD_CONFIG_OPT}"
  1600. params+=" --use-service-account-credentials"
  1601. params+=" --cloud-provider=gce"
  1602. params+=" --kubeconfig=/etc/srv/kubernetes/kube-controller-manager/kubeconfig"
  1603. params+=" --root-ca-file=${CA_CERT_BUNDLE_PATH}"
  1604. params+=" --service-account-private-key-file=${SERVICEACCOUNT_KEY_PATH}"
  1605. if [[ -n "${ENABLE_GARBAGE_COLLECTOR:-}" ]]; then
  1606. params+=" --enable-garbage-collector=${ENABLE_GARBAGE_COLLECTOR}"
  1607. fi
  1608. if [[ -n "${INSTANCE_PREFIX:-}" ]]; then
  1609. params+=" --cluster-name=${INSTANCE_PREFIX}"
  1610. fi
  1611. if [[ -n "${CLUSTER_IP_RANGE:-}" ]]; then
  1612. params+=" --cluster-cidr=${CLUSTER_IP_RANGE}"
  1613. fi
  1614. if [[ -n "${CA_KEY:-}" ]]; then
  1615. params+=" --cluster-signing-cert-file=${CA_CERT_PATH}"
  1616. params+=" --cluster-signing-key-file=${CA_KEY_PATH}"
  1617. fi
  1618. if [[ -n "${SERVICE_CLUSTER_IP_RANGE:-}" ]]; then
  1619. params+=" --service-cluster-ip-range=${SERVICE_CLUSTER_IP_RANGE}"
  1620. fi
  1621. if [[ -n "${CONCURRENT_SERVICE_SYNCS:-}" ]]; then
  1622. params+=" --concurrent-service-syncs=${CONCURRENT_SERVICE_SYNCS}"
  1623. fi
  1624. if [[ "${NETWORK_PROVIDER:-}" == "kubenet" ]]; then
  1625. params+=" --allocate-node-cidrs=true"
  1626. elif [[ -n "${ALLOCATE_NODE_CIDRS:-}" ]]; then
  1627. params+=" --allocate-node-cidrs=${ALLOCATE_NODE_CIDRS}"
  1628. fi
  1629. if [[ -n "${TERMINATED_POD_GC_THRESHOLD:-}" ]]; then
  1630. params+=" --terminated-pod-gc-threshold=${TERMINATED_POD_GC_THRESHOLD}"
  1631. fi
  1632. if [[ "${ENABLE_IP_ALIASES:-}" == 'true' ]]; then
  1633. params+=" --cidr-allocator-type=${NODE_IPAM_MODE}"
  1634. params+=" --configure-cloud-routes=false"
  1635. fi
  1636. if [[ -n "${FEATURE_GATES:-}" ]]; then
  1637. params+=" --feature-gates=${FEATURE_GATES}"
  1638. fi
  1639. if [[ -n "${VOLUME_PLUGIN_DIR:-}" ]]; then
  1640. params+=" --flex-volume-plugin-dir=${VOLUME_PLUGIN_DIR}"
  1641. fi
  1642. if [[ -n "${CLUSTER_SIGNING_DURATION:-}" ]]; then
  1643. params+=" --experimental-cluster-signing-duration=$CLUSTER_SIGNING_DURATION"
  1644. fi
  1645. # Disable using HPA metrics REST clients if metrics-server isn't enabled,
  1646. # or if we want to explicitly disable it by setting HPA_USE_REST_CLIENT.
  1647. if [[ "${ENABLE_METRICS_SERVER:-}" != "true" ]] ||
  1648. [[ "${HPA_USE_REST_CLIENTS:-}" == "false" ]]; then
  1649. params+=" --horizontal-pod-autoscaler-use-rest-clients=false"
  1650. fi
  1651. if [[ -n "${PV_RECYCLER_OVERRIDE_TEMPLATE:-}" ]]; then
  1652. params+=" --pv-recycler-pod-template-filepath-nfs=$PV_RECYCLER_OVERRIDE_TEMPLATE"
  1653. params+=" --pv-recycler-pod-template-filepath-hostpath=$PV_RECYCLER_OVERRIDE_TEMPLATE"
  1654. fi
  1655. if [[ -n "${RUN_CONTROLLERS:-}" ]]; then
  1656. params+=" --controllers=${RUN_CONTROLLERS}"
  1657. fi
  1658. local -r kube_rc_docker_tag=$(cat /home/kubernetes/kube-docker-files/kube-controller-manager.docker_tag)
  1659. local container_env=""
  1660. if [[ -n "${ENABLE_CACHE_MUTATION_DETECTOR:-}" ]]; then
  1661. container_env="\"env\":[{\"name\": \"KUBE_CACHE_MUTATION_DETECTOR\", \"value\": \"${ENABLE_CACHE_MUTATION_DETECTOR}\"}],"
  1662. fi
  1663. local -r src_file="${KUBE_HOME}/kube-manifests/kubernetes/gci-trusty/kube-controller-manager.manifest"
  1664. # Evaluate variables.
  1665. sed -i -e "s@{{pillar\['kube_docker_registry'\]}}@${DOCKER_REGISTRY}@g" "${src_file}"
  1666. sed -i -e "s@{{pillar\['kube-controller-manager_docker_tag'\]}}@${kube_rc_docker_tag}@g" "${src_file}"
  1667. sed -i -e "s@{{params}}@${params}@g" "${src_file}"
  1668. sed -i -e "s@{{container_env}}@${container_env}@g" ${src_file}
  1669. sed -i -e "s@{{cloud_config_mount}}@${CLOUD_CONFIG_MOUNT}@g" "${src_file}"
  1670. sed -i -e "s@{{cloud_config_volume}}@${CLOUD_CONFIG_VOLUME}@g" "${src_file}"
  1671. sed -i -e "s@{{additional_cloud_config_mount}}@@g" "${src_file}"
  1672. sed -i -e "s@{{additional_cloud_config_volume}}@@g" "${src_file}"
  1673. sed -i -e "s@{{pv_recycler_mount}}@${PV_RECYCLER_MOUNT}@g" "${src_file}"
  1674. sed -i -e "s@{{pv_recycler_volume}}@${PV_RECYCLER_VOLUME}@g" "${src_file}"
  1675. sed -i -e "s@{{flexvolume_hostpath_mount}}@${FLEXVOLUME_HOSTPATH_MOUNT}@g" "${src_file}"
  1676. sed -i -e "s@{{flexvolume_hostpath}}@${FLEXVOLUME_HOSTPATH_VOLUME}@g" "${src_file}"
  1677. sed -i -e "s@{{cpurequest}}@${KUBE_CONTROLLER_MANAGER_CPU_REQUEST}@g" "${src_file}"
  1678. cp "${src_file}" /etc/kubernetes/manifests
  1679. }
  1680. # Starts kubernetes scheduler.
  1681. # It prepares the log file, loads the docker image, calculates variables, sets them
  1682. # in the manifest file, and then copies the manifest file to /etc/kubernetes/manifests.
  1683. #
  1684. # Assumed vars (which are calculated in compute-master-manifest-variables)
  1685. # DOCKER_REGISTRY
  1686. function start-kube-scheduler {
  1687. echo "Start kubernetes scheduler"
  1688. create-kubeconfig "kube-scheduler" ${KUBE_SCHEDULER_TOKEN}
  1689. prepare-log-file /var/log/kube-scheduler.log
  1690. # Calculate variables and set them in the manifest.
  1691. params="${SCHEDULER_TEST_LOG_LEVEL:-"--v=2"} ${SCHEDULER_TEST_ARGS:-}"
  1692. params+=" --kubeconfig=/etc/srv/kubernetes/kube-scheduler/kubeconfig"
  1693. if [[ -n "${FEATURE_GATES:-}" ]]; then
  1694. params+=" --feature-gates=${FEATURE_GATES}"
  1695. fi
  1696. if [[ -n "${SCHEDULING_ALGORITHM_PROVIDER:-}" ]]; then
  1697. params+=" --algorithm-provider=${SCHEDULING_ALGORITHM_PROVIDER}"
  1698. fi
  1699. if [[ -n "${SCHEDULER_POLICY_CONFIG:-}" ]]; then
  1700. create-kubescheduler-policy-config
  1701. params+=" --use-legacy-policy-config"
  1702. params+=" --policy-config-file=/etc/srv/kubernetes/kube-scheduler/policy-config"
  1703. fi
  1704. local -r kube_scheduler_docker_tag=$(cat "${KUBE_HOME}/kube-docker-files/kube-scheduler.docker_tag")
  1705. # Remove salt comments and replace variables with values.
  1706. local -r src_file="${KUBE_HOME}/kube-manifests/kubernetes/gci-trusty/kube-scheduler.manifest"
  1707. sed -i -e "s@{{params}}@${params}@g" "${src_file}"
  1708. sed -i -e "s@{{pillar\['kube_docker_registry'\]}}@${DOCKER_REGISTRY}@g" "${src_file}"
  1709. sed -i -e "s@{{pillar\['kube-scheduler_docker_tag'\]}}@${kube_scheduler_docker_tag}@g" "${src_file}"
  1710. sed -i -e "s@{{cpurequest}}@${KUBE_SCHEDULER_CPU_REQUEST}@g" "${src_file}"
  1711. cp "${src_file}" /etc/kubernetes/manifests
  1712. }
  1713. # Starts cluster autoscaler.
  1714. # Assumed vars (which are calculated in function compute-master-manifest-variables)
  1715. # CLOUD_CONFIG_OPT
  1716. # CLOUD_CONFIG_VOLUME
  1717. # CLOUD_CONFIG_MOUNT
  1718. function start-cluster-autoscaler {
  1719. if [[ "${ENABLE_CLUSTER_AUTOSCALER:-}" == "true" ]]; then
  1720. echo "Start kubernetes cluster autoscaler"
  1721. setup-addon-manifests "addons" "rbac/cluster-autoscaler"
  1722. create-kubeconfig "cluster-autoscaler" ${KUBE_CLUSTER_AUTOSCALER_TOKEN}
  1723. prepare-log-file /var/log/cluster-autoscaler.log
  1724. # Remove salt comments and replace variables with values
  1725. local -r src_file="${KUBE_HOME}/kube-manifests/kubernetes/gci-trusty/cluster-autoscaler.manifest"
  1726. local params="${AUTOSCALER_MIG_CONFIG} ${CLOUD_CONFIG_OPT} ${AUTOSCALER_EXPANDER_CONFIG:---expander=price}"
  1727. params+=" --kubeconfig=/etc/srv/kubernetes/cluster-autoscaler/kubeconfig"
  1728. # split the params into separate arguments passed to binary
  1729. local params_split
  1730. params_split=$(eval "for param in $params; do echo -n \\\"\$param\\\",; done")
  1731. params_split=${params_split%?}
  1732. sed -i -e "s@{{params}}@${params_split}@g" "${src_file}"
  1733. sed -i -e "s@{{cloud_config_mount}}@${CLOUD_CONFIG_MOUNT}@g" "${src_file}"
  1734. sed -i -e "s@{{cloud_config_volume}}@${CLOUD_CONFIG_VOLUME}@g" "${src_file}"
  1735. sed -i -e "s@{%.*%}@@g" "${src_file}"
  1736. cp "${src_file}" /etc/kubernetes/manifests
  1737. fi
  1738. }
  1739. # A helper function for setting up addon manifests.
  1740. #
  1741. # $1: addon category under /etc/kubernetes
  1742. # $2: manifest source dir
  1743. # $3: (optional) auxiliary manifest source dir
  1744. function setup-addon-manifests {
  1745. local -r src_dir="${KUBE_HOME}/kube-manifests/kubernetes/gci-trusty"
  1746. local -r dst_dir="/etc/kubernetes/$1/$2"
  1747. copy-manifests "${src_dir}/$2" "${dst_dir}"
  1748. # If the PodSecurityPolicy admission controller is enabled,
  1749. # set up the corresponding addon policies.
  1750. if [[ "${ENABLE_POD_SECURITY_POLICY:-}" == "true" ]]; then
  1751. local -r psp_dir="${src_dir}/${3:-$2}/podsecuritypolicies"
  1752. if [[ -d "${psp_dir}" ]]; then
  1753. copy-manifests "${psp_dir}" "${dst_dir}"
  1754. fi
  1755. fi
  1756. if [[ "${ENABLE_NODE_TERMINATION_HANDLER:-}" == "true" ]]; then
  1757. local -r nth_dir="${src_dir}/${3:-$2}/node-termination-handler"
  1758. if [[ -d "${nth_dir}" ]]; then
  1759. copy-manifests "${nth_dir}" "${dst_dir}"
  1760. fi
  1761. fi
  1762. }
  1763. # A function that downloads extra addons from a URL and puts them in the GCI
  1764. # manifests directory.
  1765. function download-extra-addons {
  1766. local -r out_dir="${KUBE_HOME}/kube-manifests/kubernetes/gci-trusty/gce-extras"
  1767. mkdir -p "${out_dir}"
  1768. local curl_cmd=(
  1769. "curl"
  1770. "--fail"
  1771. "--retry" "5"
  1772. "--retry-delay" "3"
  1773. "--silent"
  1774. "--show-error"
  1775. )
  1776. if [[ -n "${CURL_RETRY_CONNREFUSED:-}" ]]; then
  1777. curl_cmd+=("${CURL_RETRY_CONNREFUSED}")
  1778. fi
  1779. if [[ -n "${EXTRA_ADDONS_HEADER:-}" ]]; then
  1780. curl_cmd+=("-H" "${EXTRA_ADDONS_HEADER}")
  1781. fi
  1782. curl_cmd+=("-o" "${out_dir}/extras.json")
  1783. curl_cmd+=("${EXTRA_ADDONS_URL}")
  1784. "${curl_cmd[@]}"
  1785. }
  1786. # A function that fetches a GCE metadata value and echoes it out.
  1787. #
  1788. # $1: URL path after /computeMetadata/v1/ (without heading slash).
  1789. function get-metadata-value {
  1790. curl \
  1791. --retry 5 \
  1792. --retry-delay 3 \
  1793. ${CURL_RETRY_CONNREFUSED} \
  1794. --fail \
  1795. --silent \
  1796. -H 'Metadata-Flavor: Google' \
  1797. "http://metadata/computeMetadata/v1/${1}"
  1798. }
  1799. # A helper function for copying manifests and setting dir/files
  1800. # permissions.
  1801. #
  1802. # $1: absolute source dir
  1803. # $2: absolute destination dir
  1804. function copy-manifests {
  1805. local -r src_dir="$1"
  1806. local -r dst_dir="$2"
  1807. if [[ ! -d "${dst_dir}" ]]; then
  1808. mkdir -p "${dst_dir}"
  1809. fi
  1810. local files=$(find "${src_dir}" -maxdepth 1 -name "*.yaml")
  1811. if [[ -n "${files}" ]]; then
  1812. cp "${src_dir}/"*.yaml "${dst_dir}"
  1813. fi
  1814. files=$(find "${src_dir}" -maxdepth 1 -name "*.json")
  1815. if [[ -n "${files}" ]]; then
  1816. cp "${src_dir}/"*.json "${dst_dir}"
  1817. fi
  1818. files=$(find "${src_dir}" -maxdepth 1 -name "*.yaml.in")
  1819. if [[ -n "${files}" ]]; then
  1820. cp "${src_dir}/"*.yaml.in "${dst_dir}"
  1821. fi
  1822. chown -R root:root "${dst_dir}"
  1823. chmod 755 "${dst_dir}"
  1824. chmod 644 "${dst_dir}"/*
  1825. }
  1826. # Fluentd resources are modified using ScalingPolicy CR, which may not be
  1827. # available at this point. Run this as a background process.
  1828. function wait-for-apiserver-and-update-fluentd {
  1829. local any_overrides=false
  1830. if [[ -n "${FLUENTD_GCP_MEMORY_LIMIT:-}" ]]; then
  1831. any_overrides=true
  1832. fi
  1833. if [[ -n "${FLUENTD_GCP_CPU_REQUEST:-}" ]]; then
  1834. any_overrides=true
  1835. fi
  1836. if [[ -n "${FLUENTD_GCP_MEMORY_REQUEST:-}" ]]; then
  1837. any_overrides=true
  1838. fi
  1839. if ! $any_overrides; then
  1840. # Nothing to do here.
  1841. exit
  1842. fi
  1843. # Wait until ScalingPolicy CRD is in place.
  1844. until kubectl get scalingpolicies.scalingpolicy.kope.io
  1845. do
  1846. sleep 10
  1847. done
  1848. # Single-shot, not managed by addon manager. Can be later modified or removed
  1849. # at will.
  1850. cat <<EOF | kubectl apply -f -
  1851. apiVersion: scalingpolicy.kope.io/v1alpha1
  1852. kind: ScalingPolicy
  1853. metadata:
  1854. name: fluentd-gcp-scaling-policy
  1855. namespace: kube-system
  1856. spec:
  1857. containers:
  1858. - name: fluentd-gcp
  1859. resources:
  1860. requests:
  1861. - resource: cpu
  1862. base: ${FLUENTD_GCP_CPU_REQUEST:-}
  1863. - resource: memory
  1864. base: ${FLUENTD_GCP_MEMORY_REQUEST:-}
  1865. limits:
  1866. - resource: memory
  1867. base: ${FLUENTD_GCP_MEMORY_LIMIT:-}
  1868. EOF
  1869. }
  1870. # Trigger background process that will ultimately update fluentd resource
  1871. # requirements.
  1872. function start-fluentd-resource-update {
  1873. wait-for-apiserver-and-update-fluentd &
  1874. }
  1875. # VolumeSnapshot CRDs and controller are installed by cluster addon manager,
  1876. # which may not be available at this point. Run this as a background process.
  1877. function wait-for-volumesnapshot-crd-and-controller {
  1878. # Wait until volumesnapshot CRDs and controller are in place.
  1879. echo "Wait until volume snapshot CRDs are installed"
  1880. until kubectl get volumesnapshotclasses.snapshot.storage.k8s.io
  1881. do
  1882. sleep 10
  1883. done
  1884. until kubectl get volumesnapshotcontents.snapshot.storage.k8s.io
  1885. do
  1886. sleep 10
  1887. done
  1888. until kubectl get volumesnapshots.snapshot.storage.k8s.io
  1889. do
  1890. sleep 10
  1891. done
  1892. echo "Wait until volume snapshot RBAC rules are installed"
  1893. until kubectl get clusterrolebinding volume-snapshot-controller-role
  1894. do
  1895. sleep 10
  1896. done
  1897. echo "Wait until volume snapshot controller is installed"
  1898. until kubectl get statefulset volume-snapshot-controller | grep volume-snapshot-controller | grep "1/1"
  1899. do
  1900. sleep 10
  1901. done
  1902. }
  1903. # Trigger background process that will wait for volumesnapshot CRDs
  1904. # and snapshot-controller to be installed
  1905. function start-volumesnapshot-crd-and-controller {
  1906. wait-for-volumesnapshot-crd-and-controller &
  1907. }
  1908. # Update {{ fluentd_container_runtime_service }} with actual container runtime name,
  1909. # and {{ container_runtime_endpoint }} with actual container runtime
  1910. # endpoint.
  1911. function update-container-runtime {
  1912. local -r file="$1"
  1913. local -r container_runtime_endpoint="${CONTAINER_RUNTIME_ENDPOINT:-unix:///var/run/dockershim.sock}"
  1914. sed -i \
  1915. -e "s@{{ *fluentd_container_runtime_service *}}@${FLUENTD_CONTAINER_RUNTIME_SERVICE:-${CONTAINER_RUNTIME_NAME:-docker}}@g" \
  1916. -e "s@{{ *container_runtime_endpoint *}}@${container_runtime_endpoint#unix://}@g" \
  1917. "${file}"
  1918. }
  1919. # Remove configuration in yaml file if node journal is not enabled.
  1920. function update-node-journal {
  1921. local -r configmap_yaml="$1"
  1922. if [[ "${ENABLE_NODE_JOURNAL:-}" != "true" ]]; then
  1923. # Removes all lines between two patterns (throws away node-journal)
  1924. sed -i -e "/# BEGIN_NODE_JOURNAL/,/# END_NODE_JOURNAL/d" "${configmap_yaml}"
  1925. fi
  1926. }
  1927. # Updates parameters in yaml file for prometheus-to-sd configuration, or
  1928. # removes component if it is disabled.
  1929. function update-prometheus-to-sd-parameters {
  1930. if [[ "${ENABLE_PROMETHEUS_TO_SD:-}" == "true" ]]; then
  1931. sed -i -e "s@{{ *prometheus_to_sd_prefix *}}@${PROMETHEUS_TO_SD_PREFIX}@g" "$1"
  1932. sed -i -e "s@{{ *prometheus_to_sd_endpoint *}}@${PROMETHEUS_TO_SD_ENDPOINT}@g" "$1"
  1933. else
  1934. # Removes all lines between two patterns (throws away prometheus-to-sd)
  1935. sed -i -e "/# BEGIN_PROMETHEUS_TO_SD/,/# END_PROMETHEUS_TO_SD/d" "$1"
  1936. fi
  1937. }
  1938. # Updates parameters in yaml file for prometheus-to-sd configuration in daemon sets, or
  1939. # removes component if it is disabled.
  1940. function update-daemon-set-prometheus-to-sd-parameters {
  1941. if [[ "${DISABLE_PROMETHEUS_TO_SD_IN_DS:-}" == "true" ]]; then
  1942. # Removes all lines between two patterns (throws away prometheus-to-sd)
  1943. sed -i -e "/# BEGIN_PROMETHEUS_TO_SD/,/# END_PROMETHEUS_TO_SD/d" "$1"
  1944. else
  1945. update-prometheus-to-sd-parameters $1
  1946. fi
  1947. }
  1948. # Updates parameters in yaml file for event-exporter configuration
  1949. function update-event-exporter {
  1950. local -r stackdriver_resource_model="${LOGGING_STACKDRIVER_RESOURCE_TYPES:-old}"
  1951. sed -i -e "s@{{ exporter_sd_resource_model }}@${stackdriver_resource_model}@g" "$1"
  1952. sed -i -e "s@{{ exporter_sd_endpoint }}@${STACKDRIVER_ENDPOINT:-}@g" "$1"
  1953. }
  1954. function update-dashboard-deployment {
  1955. if [ -n "${CUSTOM_KUBE_DASHBOARD_BANNER:-}" ]; then
  1956. sed -i -e "s@\( \+\)# PLATFORM-SPECIFIC ARGS HERE@\1- --system-banner=${CUSTOM_KUBE_DASHBOARD_BANNER}\n\1- --system-banner-severity=WARNING@" "$1"
  1957. fi
  1958. }
  1959. # Sets up the manifests of coreDNS for k8s addons.
  1960. function setup-coredns-manifest {
  1961. setup-addon-manifests "addons" "0-dns/coredns"
  1962. local -r coredns_file="${dst_dir}/0-dns/coredns/coredns.yaml"
  1963. mv "${dst_dir}/0-dns/coredns/coredns.yaml.in" "${coredns_file}"
  1964. # Replace the salt configurations with variable values.
  1965. sed -i -e "s@{{ *pillar\['dns_domain'\] *}}@${DNS_DOMAIN}@g" "${coredns_file}"
  1966. sed -i -e "s@{{ *pillar\['dns_server'\] *}}@${DNS_SERVER_IP}@g" "${coredns_file}"
  1967. sed -i -e "s@{{ *pillar\['service_cluster_ip_range'\] *}}@${SERVICE_CLUSTER_IP_RANGE}@g" "${coredns_file}"
  1968. sed -i -e "s@{{ *pillar\['dns_memory_limit'\] *}}@${DNS_MEMORY_LIMIT:-170Mi}@g" "${coredns_file}"
  1969. if [[ "${ENABLE_DNS_HORIZONTAL_AUTOSCALER:-}" == "true" ]]; then
  1970. setup-addon-manifests "addons" "dns-horizontal-autoscaler" "gce"
  1971. local -r dns_autoscaler_file="${dst_dir}/dns-horizontal-autoscaler/dns-horizontal-autoscaler.yaml"
  1972. sed -i'' -e "s@{{.Target}}@${COREDNS_AUTOSCALER}@g" "${dns_autoscaler_file}"
  1973. fi
  1974. }
  1975. # Sets up the manifests of Fluentd configmap and yamls for k8s addons.
  1976. function setup-fluentd {
  1977. local -r dst_dir="$1"
  1978. local -r fluentd_gcp_yaml="${dst_dir}/fluentd-gcp/fluentd-gcp-ds.yaml"
  1979. local -r fluentd_gcp_scaler_yaml="${dst_dir}/fluentd-gcp/scaler-deployment.yaml"
  1980. # Ingest logs against new resources like "k8s_container" and "k8s_node" if
  1981. # LOGGING_STACKDRIVER_RESOURCE_TYPES is "new".
  1982. # Ingest logs against old resources like "gke_container" and "gce_instance" if
  1983. # LOGGING_STACKDRIVER_RESOURCE_TYPES is "old".
  1984. if [[ "${LOGGING_STACKDRIVER_RESOURCE_TYPES:-old}" == "new" ]]; then
  1985. local -r fluentd_gcp_configmap_yaml="${dst_dir}/fluentd-gcp/fluentd-gcp-configmap.yaml"
  1986. fluentd_gcp_configmap_name="fluentd-gcp-config"
  1987. else
  1988. local -r fluentd_gcp_configmap_yaml="${dst_dir}/fluentd-gcp/fluentd-gcp-configmap-old.yaml"
  1989. fluentd_gcp_configmap_name="fluentd-gcp-config-old"
  1990. fi
  1991. sed -i -e "s@{{ fluentd_gcp_configmap_name }}@${fluentd_gcp_configmap_name}@g" "${fluentd_gcp_yaml}"
  1992. fluentd_gcp_yaml_version="${FLUENTD_GCP_YAML_VERSION:-v3.2.0}"
  1993. sed -i -e "s@{{ fluentd_gcp_yaml_version }}@${fluentd_gcp_yaml_version}@g" "${fluentd_gcp_yaml}"
  1994. sed -i -e "s@{{ fluentd_gcp_yaml_version }}@${fluentd_gcp_yaml_version}@g" "${fluentd_gcp_scaler_yaml}"
  1995. fluentd_gcp_version="${FLUENTD_GCP_VERSION:-1.6.17}"
  1996. sed -i -e "s@{{ fluentd_gcp_version }}@${fluentd_gcp_version}@g" "${fluentd_gcp_yaml}"
  1997. update-daemon-set-prometheus-to-sd-parameters ${fluentd_gcp_yaml}
  1998. start-fluentd-resource-update ${fluentd_gcp_yaml}
  1999. update-container-runtime ${fluentd_gcp_configmap_yaml}
  2000. update-node-journal ${fluentd_gcp_configmap_yaml}
  2001. }
  2002. # Sets up the manifests of kube-dns for k8s addons.
  2003. function setup-kube-dns-manifest {
  2004. setup-addon-manifests "addons" "0-dns/kube-dns"
  2005. local -r kubedns_file="${dst_dir}/0-dns/kube-dns/kube-dns.yaml"
  2006. mv "${dst_dir}/0-dns/kube-dns/kube-dns.yaml.in" "${kubedns_file}"
  2007. if [ -n "${CUSTOM_KUBE_DNS_YAML:-}" ]; then
  2008. # Replace with custom GKE kube-dns deployment.
  2009. cat > "${kubedns_file}" <<EOF
  2010. $CUSTOM_KUBE_DNS_YAML
  2011. EOF
  2012. update-prometheus-to-sd-parameters ${kubedns_file}
  2013. fi
  2014. # Replace the salt configurations with variable values.
  2015. sed -i -e "s@{{ *pillar\['dns_domain'\] *}}@${DNS_DOMAIN}@g" "${kubedns_file}"
  2016. sed -i -e "s@{{ *pillar\['dns_server'\] *}}@${DNS_SERVER_IP}@g" "${kubedns_file}"
  2017. sed -i -e "s@{{ *pillar\['dns_memory_limit'\] *}}@${DNS_MEMORY_LIMIT:-170Mi}@g" "${kubedns_file}"
  2018. if [[ "${ENABLE_DNS_HORIZONTAL_AUTOSCALER:-}" == "true" ]]; then
  2019. setup-addon-manifests "addons" "dns-horizontal-autoscaler" "gce"
  2020. local -r dns_autoscaler_file="${dst_dir}/dns-horizontal-autoscaler/dns-horizontal-autoscaler.yaml"
  2021. sed -i'' -e "s@{{.Target}}@${KUBEDNS_AUTOSCALER}@g" "${dns_autoscaler_file}"
  2022. fi
  2023. }
  2024. # Sets up the manifests of local dns cache agent for k8s addons.
  2025. function setup-nodelocaldns-manifest {
  2026. setup-addon-manifests "addons" "0-dns/nodelocaldns"
  2027. local -r localdns_file="${dst_dir}/0-dns/nodelocaldns/nodelocaldns.yaml"
  2028. setup-addon-custom-yaml "addons" "0-dns/nodelocaldns" "nodelocaldns.yaml" "${CUSTOM_NODELOCAL_DNS_YAML:-}"
  2029. # Replace the sed configurations with variable values.
  2030. sed -i -e "s/__PILLAR__DNS__DOMAIN__/${DNS_DOMAIN}/g" "${localdns_file}"
  2031. sed -i -e "s/__PILLAR__DNS__SERVER__/${DNS_SERVER_IP}/g" "${localdns_file}"
  2032. sed -i -e "s/__PILLAR__LOCAL__DNS__/${LOCAL_DNS_IP}/g" "${localdns_file}"
  2033. }
  2034. # Sets up the manifests of netd for k8s addons.
  2035. function setup-netd-manifest {
  2036. local -r netd_file="${dst_dir}/netd/netd.yaml"
  2037. mkdir -p "${dst_dir}/netd"
  2038. touch "${netd_file}"
  2039. if [ -n "${CUSTOM_NETD_YAML:-}" ]; then
  2040. # Replace with custom GCP netd deployment.
  2041. cat > "${netd_file}" <<EOF
  2042. $CUSTOM_NETD_YAML
  2043. EOF
  2044. fi
  2045. }
  2046. # A helper function to set up a custom yaml for a k8s addon.
  2047. #
  2048. # $1: addon category under /etc/kubernetes
  2049. # $2: manifest source dir
  2050. # $3: manifest file
  2051. # $4: custom yaml
  2052. function setup-addon-custom-yaml {
  2053. local -r manifest_path="/etc/kubernetes/$1/$2/$3"
  2054. local -r custom_yaml="$4"
  2055. if [ -n "${custom_yaml:-}" ]; then
  2056. # Replace with custom manifest.
  2057. cat > "${manifest_path}" <<EOF
  2058. $custom_yaml
  2059. EOF
  2060. fi
  2061. }
  2062. # Prepares the manifests of k8s addons, and starts the addon manager.
  2063. # Vars assumed:
  2064. # CLUSTER_NAME
  2065. function start-kube-addons {
  2066. echo "Prepare kube-addons manifests and start kube addon manager"
  2067. local -r src_dir="${KUBE_HOME}/kube-manifests/kubernetes/gci-trusty"
  2068. local -r dst_dir="/etc/kubernetes/addons"
  2069. create-kubeconfig "addon-manager" ${ADDON_MANAGER_TOKEN}
  2070. # prep addition kube-up specific rbac objects
  2071. setup-addon-manifests "addons" "rbac/kubelet-api-auth"
  2072. setup-addon-manifests "addons" "rbac/kubelet-cert-rotation"
  2073. if [[ "${REGISTER_MASTER_KUBELET:-false}" == "true" ]]; then
  2074. setup-addon-manifests "addons" "rbac/legacy-kubelet-user"
  2075. else
  2076. setup-addon-manifests "addons" "rbac/legacy-kubelet-user-disable"
  2077. fi
  2078. if [[ "${ENABLE_POD_SECURITY_POLICY:-}" == "true" ]]; then
  2079. setup-addon-manifests "addons" "podsecuritypolicies"
  2080. fi
  2081. # Set up manifests of other addons.
  2082. if [[ "${KUBE_PROXY_DAEMONSET:-}" == "true" ]]; then
  2083. if [ -n "${CUSTOM_KUBE_PROXY_YAML:-}" ]; then
  2084. # Replace with custom GKE kube proxy.
  2085. cat > "$src_dir/kube-proxy/kube-proxy-ds.yaml" <<EOF
  2086. $CUSTOM_KUBE_PROXY_YAML
  2087. EOF
  2088. update-daemon-set-prometheus-to-sd-parameters "$src_dir/kube-proxy/kube-proxy-ds.yaml"
  2089. fi
  2090. prepare-kube-proxy-manifest-variables "$src_dir/kube-proxy/kube-proxy-ds.yaml"
  2091. setup-addon-manifests "addons" "kube-proxy"
  2092. fi
  2093. if ([[ "${ENABLE_CLUSTER_LOGGING:-}" == "true" ]] &&
  2094. [[ "${LOGGING_DESTINATION:-}" == "gcp" ]]); then
  2095. if [[ "${ENABLE_METADATA_AGENT:-}" == "stackdriver" ]]; then
  2096. metadata_agent_cpu_request="${METADATA_AGENT_CPU_REQUEST:-40m}"
  2097. metadata_agent_memory_request="${METADATA_AGENT_MEMORY_REQUEST:-50Mi}"
  2098. metadata_agent_cluster_level_cpu_request="${METADATA_AGENT_CLUSTER_LEVEL_CPU_REQUEST:-40m}"
  2099. metadata_agent_cluster_level_memory_request="${METADATA_AGENT_CLUSTER_LEVEL_MEMORY_REQUEST:-50Mi}"
  2100. setup-addon-manifests "addons" "metadata-agent/stackdriver"
  2101. metadata_agent_yaml="${dst_dir}/metadata-agent/stackdriver/metadata-agent.yaml"
  2102. sed -i -e "s@{{ metadata_agent_cpu_request }}@${metadata_agent_cpu_request}@g" "${metadata_agent_yaml}"
  2103. sed -i -e "s@{{ metadata_agent_memory_request }}@${metadata_agent_memory_request}@g" "${metadata_agent_yaml}"
  2104. sed -i -e "s@{{ metadata_agent_cluster_level_cpu_request }}@${metadata_agent_cluster_level_cpu_request}@g" "${metadata_agent_yaml}"
  2105. sed -i -e "s@{{ metadata_agent_cluster_level_memory_request }}@${metadata_agent_cluster_level_memory_request}@g" "${metadata_agent_yaml}"
  2106. fi
  2107. fi
  2108. if [[ "${ENABLE_METRICS_SERVER:-}" == "true" ]]; then
  2109. setup-addon-manifests "addons" "metrics-server"
  2110. base_metrics_server_cpu="40m"
  2111. base_metrics_server_memory="40Mi"
  2112. metrics_server_memory_per_node="4"
  2113. metrics_server_min_cluster_size="16"
  2114. if [[ "${ENABLE_SYSTEM_ADDON_RESOURCE_OPTIMIZATIONS:-}" == "true" ]]; then
  2115. base_metrics_server_cpu="40m"
  2116. base_metrics_server_memory="35Mi"
  2117. metrics_server_memory_per_node="4"
  2118. metrics_server_min_cluster_size="5"
  2119. fi
  2120. local -r metrics_server_yaml="${dst_dir}/metrics-server/metrics-server-deployment.yaml"
  2121. sed -i -e "s@{{ base_metrics_server_cpu }}@${base_metrics_server_cpu}@g" "${metrics_server_yaml}"
  2122. sed -i -e "s@{{ base_metrics_server_memory }}@${base_metrics_server_memory}@g" "${metrics_server_yaml}"
  2123. sed -i -e "s@{{ metrics_server_memory_per_node }}@${metrics_server_memory_per_node}@g" "${metrics_server_yaml}"
  2124. sed -i -e "s@{{ metrics_server_min_cluster_size }}@${metrics_server_min_cluster_size}@g" "${metrics_server_yaml}"
  2125. fi
  2126. if [[ "${ENABLE_NVIDIA_GPU_DEVICE_PLUGIN:-}" == "true" ]]; then
  2127. setup-addon-manifests "addons" "device-plugins/nvidia-gpu"
  2128. fi
  2129. if [[ "${ENABLE_NODE_TERMINATION_HANDLER:-}" == "true" ]]; then
  2130. setup-addon-manifests "addons" "node-termination-handler"
  2131. setup-node-termination-handler-manifest
  2132. fi
  2133. # Setting up the konnectivity-agent daemonset
  2134. if [[ "${ENABLE_EGRESS_VIA_KONNECTIVITY_SERVICE:-false}" == "true" ]]; then
  2135. setup-addon-manifests "addons" "konnectivity-agent"
  2136. setup-konnectivity-agent-manifest
  2137. fi
  2138. if [[ "${ENABLE_CLUSTER_DNS:-}" == "true" ]]; then
  2139. # Create a new directory for the DNS addon and prepend a "0" on the name.
  2140. # Prepending "0" to the directory ensures that add-on manager
  2141. # creates the dns service first. This ensures no other add-on
  2142. # can "steal" the designated DNS clusterIP.
  2143. BASE_ADDON_DIR=${KUBE_HOME}/kube-manifests/kubernetes/gci-trusty
  2144. BASE_DNS_DIR=${BASE_ADDON_DIR}/dns
  2145. NEW_DNS_DIR=${BASE_ADDON_DIR}/0-dns
  2146. mkdir ${NEW_DNS_DIR} && mv ${BASE_DNS_DIR}/* ${NEW_DNS_DIR} && rm -r ${BASE_DNS_DIR}
  2147. if [[ "${CLUSTER_DNS_CORE_DNS:-}" == "true" ]]; then
  2148. setup-coredns-manifest
  2149. else
  2150. setup-kube-dns-manifest
  2151. fi
  2152. if [[ "${ENABLE_NODELOCAL_DNS:-}" == "true" ]]; then
  2153. setup-nodelocaldns-manifest
  2154. fi
  2155. fi
  2156. if [[ "${ENABLE_NETD:-}" == "true" ]]; then
  2157. setup-netd-manifest
  2158. fi
  2159. if [[ "${ENABLE_NODE_LOGGING:-}" == "true" ]] && \
  2160. [[ "${LOGGING_DESTINATION:-}" == "elasticsearch" ]] && \
  2161. [[ "${ENABLE_CLUSTER_LOGGING:-}" == "true" ]]; then
  2162. setup-addon-manifests "addons" "fluentd-elasticsearch"
  2163. local -r fluentd_es_configmap_yaml="${dst_dir}/fluentd-elasticsearch/fluentd-es-configmap.yaml"
  2164. update-container-runtime ${fluentd_es_configmap_yaml}
  2165. fi
  2166. if [[ "${ENABLE_NODE_LOGGING:-}" == "true" ]] && \
  2167. [[ "${LOGGING_DESTINATION:-}" == "gcp" ]]; then
  2168. setup-addon-manifests "addons" "fluentd-gcp"
  2169. setup-fluentd ${dst_dir}
  2170. local -r event_exporter_yaml="${dst_dir}/fluentd-gcp/event-exporter.yaml"
  2171. update-event-exporter ${event_exporter_yaml}
  2172. update-prometheus-to-sd-parameters ${event_exporter_yaml}
  2173. fi
  2174. if [[ "${ENABLE_CLUSTER_UI:-}" == "true" ]]; then
  2175. setup-addon-manifests "addons" "dashboard"
  2176. local -r dashboard_deployment_yaml="${dst_dir}/dashboard/dashboard-deployment.yaml"
  2177. update-dashboard-deployment ${dashboard_deployment_yaml}
  2178. fi
  2179. if [[ "${ENABLE_NODE_PROBLEM_DETECTOR:-}" == "daemonset" ]]; then
  2180. setup-addon-manifests "addons" "node-problem-detector"
  2181. fi
  2182. if [[ "${ENABLE_NODE_PROBLEM_DETECTOR:-}" == "standalone" ]]; then
  2183. # Setup role binding(s) for standalone node problem detector.
  2184. if [[ -n "${NODE_PROBLEM_DETECTOR_TOKEN:-}" ]]; then
  2185. setup-addon-manifests "addons" "node-problem-detector/standalone"
  2186. fi
  2187. setup-addon-manifests "addons" "node-problem-detector/kubelet-user-standalone" "node-problem-detector"
  2188. fi
  2189. if echo "${ADMISSION_CONTROL:-}" | grep -q "LimitRanger"; then
  2190. setup-addon-manifests "admission-controls" "limit-range" "gce"
  2191. fi
  2192. if [[ "${NETWORK_POLICY_PROVIDER:-}" == "calico" ]]; then
  2193. setup-addon-manifests "addons" "calico-policy-controller"
  2194. setup-addon-custom-yaml "addons" "calico-policy-controller" "calico-node-daemonset.yaml" "${CUSTOM_CALICO_NODE_DAEMONSET_YAML:-}"
  2195. setup-addon-custom-yaml "addons" "calico-policy-controller" "typha-deployment.yaml" "${CUSTOM_TYPHA_DEPLOYMENT_YAML:-}"
  2196. # Configure Calico CNI directory.
  2197. local -r ds_file="${dst_dir}/calico-policy-controller/calico-node-daemonset.yaml"
  2198. sed -i -e "s@__CALICO_CNI_DIR__@/home/kubernetes/bin@g" "${ds_file}"
  2199. fi
  2200. if [[ "${ENABLE_DEFAULT_STORAGE_CLASS:-}" == "true" ]]; then
  2201. setup-addon-manifests "addons" "storage-class/gce"
  2202. fi
  2203. if [[ "${ENABLE_VOLUME_SNAPSHOTS:-}" == "true" ]]; then
  2204. setup-addon-manifests "addons" "volumesnapshots/crd"
  2205. setup-addon-manifests "addons" "volumesnapshots/volume-snapshot-controller"
  2206. start-volumesnapshot-crd-and-controller
  2207. fi
  2208. if [[ "${ENABLE_IP_MASQ_AGENT:-}" == "true" ]]; then
  2209. setup-addon-manifests "addons" "ip-masq-agent"
  2210. fi
  2211. if [[ "${ENABLE_METADATA_CONCEALMENT:-}" == "true" ]]; then
  2212. setup-addon-manifests "addons" "metadata-proxy/gce"
  2213. local -r metadata_proxy_yaml="${dst_dir}/metadata-proxy/gce/metadata-proxy.yaml"
  2214. update-daemon-set-prometheus-to-sd-parameters ${metadata_proxy_yaml}
  2215. fi
  2216. if [[ "${ENABLE_ISTIO:-}" == "true" ]]; then
  2217. if [[ "${ISTIO_AUTH_TYPE:-}" == "MUTUAL_TLS" ]]; then
  2218. setup-addon-manifests "addons" "istio/auth"
  2219. else
  2220. setup-addon-manifests "addons" "istio/noauth"
  2221. fi
  2222. fi
  2223. if [[ -n "${EXTRA_ADDONS_URL:-}" ]]; then
  2224. download-extra-addons
  2225. setup-addon-manifests "addons" "gce-extras"
  2226. fi
  2227. # Place addon manager pod manifest.
  2228. src_file="${src_dir}/kube-addon-manager.yaml"
  2229. sed -i -e "s@{{kubectl_extra_prune_whitelist}}@${ADDON_MANAGER_PRUNE_WHITELIST:-}@g" "${src_file}"
  2230. cp "${src_file}" /etc/kubernetes/manifests
  2231. }
  2232. function setup-node-termination-handler-manifest {
  2233. local -r nth_manifest="/etc/kubernetes/$1/$2/daemonset.yaml"
  2234. if [[ -n "${NODE_TERMINATION_HANDLER_IMAGE}" ]]; then
  2235. sed -i "s|image:.*|image: ${NODE_TERMINATION_HANDLER_IMAGE}|" "${nth_manifest}"
  2236. fi
  2237. }
  2238. function setup-konnectivity-agent-manifest {
  2239. local -r manifest="/etc/kubernetes/addons/konnectivity-agent/daemonset.yaml"
  2240. sed -i "s|__APISERVER_IP__|${KUBERNETES_MASTER_NAME}|g" "${manifest}"
  2241. }
  2242. # Setups manifests for ingress controller and gce-specific policies for service controller.
  2243. function start-lb-controller {
  2244. setup-addon-manifests "addons" "loadbalancing"
  2245. # Starts a l7 loadbalancing controller for ingress.
  2246. if [[ "${ENABLE_L7_LOADBALANCING:-}" == "glbc" ]]; then
  2247. echo "Start GCE L7 pod"
  2248. prepare-log-file /var/log/glbc.log
  2249. setup-addon-manifests "addons" "cluster-loadbalancing/glbc"
  2250. setup-addon-manifests "addons" "rbac/cluster-loadbalancing/glbc"
  2251. create-kubeconfig "l7-lb-controller" ${GCE_GLBC_TOKEN}
  2252. local -r src_manifest="${KUBE_HOME}/kube-manifests/kubernetes/gci-trusty/glbc.manifest"
  2253. local -r dest_manifest="/etc/kubernetes/manifests/glbc.manifest"
  2254. if [[ -n "${CUSTOM_INGRESS_YAML:-}" ]]; then
  2255. echo "${CUSTOM_INGRESS_YAML}" > "${dest_manifest}"
  2256. else
  2257. cp "${src_manifest}" "${dest_manifest}"
  2258. fi
  2259. # Override the glbc image if GCE_GLBC_IMAGE is specified.
  2260. if [[ -n "${GCE_GLBC_IMAGE:-}" ]]; then
  2261. sed -i "s|image:.*|image: ${GCE_GLBC_IMAGE}|" "${dest_manifest}"
  2262. fi
  2263. fi
  2264. }
  2265. # Setup working directory for kubelet.
  2266. function setup-kubelet-dir {
  2267. echo "Making /var/lib/kubelet executable for kubelet"
  2268. mount -B /var/lib/kubelet /var/lib/kubelet/
  2269. mount -B -o remount,exec,suid,dev /var/lib/kubelet
  2270. }
  2271. # Override for GKE custom master setup scripts (no-op outside of GKE).
  2272. function gke-master-start {
  2273. if [[ -e "${KUBE_HOME}/bin/gke-internal-configure-helper.sh" ]]; then
  2274. echo "Running GKE internal configuration script"
  2275. . "${KUBE_HOME}/bin/gke-internal-configure-helper.sh"
  2276. gke-internal-master-start
  2277. fi
  2278. }
  2279. function reset-motd {
  2280. # kubelet is installed both on the master and nodes, and the version is easy to parse (unlike kubectl)
  2281. local -r version="$("${KUBE_HOME}"/bin/kubelet --version=true | cut -f2 -d " ")"
  2282. # This logic grabs either a release tag (v1.2.1 or v1.2.1-alpha.1),
  2283. # or the git hash that's in the build info.
  2284. local gitref="$(echo "${version}" | sed -r "s/(v[0-9]+\.[0-9]+\.[0-9]+)(-[a-z]+\.[0-9]+)?.*/\1\2/g")"
  2285. local devel=""
  2286. if [[ "${gitref}" != "${version}" ]]; then
  2287. devel="
  2288. Note: This looks like a development version, which might not be present on GitHub.
  2289. If it isn't, the closest tag is at:
  2290. https://github.com/kubernetes/kubernetes/tree/${gitref}
  2291. "
  2292. gitref="${version//*+/}"
  2293. fi
  2294. cat > /etc/motd <<EOF
  2295. Welcome to Kubernetes ${version}!
  2296. You can find documentation for Kubernetes at:
  2297. http://docs.kubernetes.io/
  2298. The source for this release can be found at:
  2299. /home/kubernetes/kubernetes-src.tar.gz
  2300. Or you can download it at:
  2301. https://storage.googleapis.com/kubernetes-release/release/${version}/kubernetes-src.tar.gz
  2302. It is based on the Kubernetes source at:
  2303. https://github.com/kubernetes/kubernetes/tree/${gitref}
  2304. ${devel}
  2305. For Kubernetes copyright and licensing information, see:
  2306. /home/kubernetes/LICENSES
  2307. EOF
  2308. }
  2309. function override-kubectl {
  2310. echo "overriding kubectl"
  2311. echo "export PATH=${KUBE_HOME}/bin:\$PATH" > /etc/profile.d/kube_env.sh
  2312. # source the file explicitly otherwise we have
  2313. # issues on a ubuntu OS image finding the kubectl
  2314. source /etc/profile.d/kube_env.sh
  2315. # Add ${KUBE_HOME}/bin into sudoer secure path.
  2316. local sudo_path
  2317. sudo_path=$(sudo env | grep "^PATH=")
  2318. if [[ -n "${sudo_path}" ]]; then
  2319. sudo_path=${sudo_path#PATH=}
  2320. (
  2321. umask 027
  2322. echo "Defaults secure_path=\"${KUBE_HOME}/bin:${sudo_path}\"" > /etc/sudoers.d/kube_secure_path
  2323. )
  2324. fi
  2325. }
  2326. function override-pv-recycler {
  2327. if [[ -z "${PV_RECYCLER_OVERRIDE_TEMPLATE:-}" ]]; then
  2328. echo "PV_RECYCLER_OVERRIDE_TEMPLATE is not set"
  2329. exit 1
  2330. fi
  2331. PV_RECYCLER_VOLUME="{\"name\": \"pv-recycler-mount\",\"hostPath\": {\"path\": \"${PV_RECYCLER_OVERRIDE_TEMPLATE}\", \"type\": \"FileOrCreate\"}},"
  2332. PV_RECYCLER_MOUNT="{\"name\": \"pv-recycler-mount\",\"mountPath\": \"${PV_RECYCLER_OVERRIDE_TEMPLATE}\", \"readOnly\": true},"
  2333. cat > ${PV_RECYCLER_OVERRIDE_TEMPLATE} <<EOF
  2334. version: v1
  2335. kind: Pod
  2336. metadata:
  2337. generateName: pv-recycler-
  2338. namespace: default
  2339. spec:
  2340. activeDeadlineSeconds: 60
  2341. restartPolicy: Never
  2342. volumes:
  2343. - name: vol
  2344. containers:
  2345. - name: pv-recycler
  2346. image: k8s.gcr.io/busybox:1.27
  2347. command:
  2348. - /bin/sh
  2349. args:
  2350. - -c
  2351. - test -e /scrub && rm -rf /scrub/..?* /scrub/.[!.]* /scrub/* && test -z $(ls -A /scrub) || exit 1
  2352. volumeMounts:
  2353. - name: vol
  2354. mountPath: /scrub
  2355. EOF
  2356. }
  2357. function wait-till-apiserver-ready() {
  2358. until kubectl get nodes; do
  2359. sleep 5
  2360. done
  2361. }
  2362. function ensure-master-bootstrap-kubectl-auth {
  2363. # By default, `kubectl` uses http://localhost:8080
  2364. # If the insecure port is disabled, kubectl will need to use an admin-authenticated kubeconfig.
  2365. if [[ -n "${KUBE_BOOTSTRAP_TOKEN:-}" ]]; then
  2366. create-kubeconfig "kube-bootstrap" "${KUBE_BOOTSTRAP_TOKEN}"
  2367. export KUBECONFIG=/etc/srv/kubernetes/kube-bootstrap/kubeconfig
  2368. fi
  2369. }
  2370. function setup-containerd {
  2371. echo "Generate containerd config"
  2372. local config_path="${CONTAINERD_CONFIG_PATH:-"/etc/containerd/config.toml"}"
  2373. mkdir -p "$(dirname "${config_path}")"
  2374. local cni_template_path="${KUBE_HOME}/cni.template"
  2375. cat > "${cni_template_path}" <<EOF
  2376. {
  2377. "name": "k8s-pod-network",
  2378. "cniVersion": "0.3.1",
  2379. "plugins": [
  2380. {
  2381. "type": "ptp",
  2382. "mtu": 1460,
  2383. "ipam": {
  2384. "type": "host-local",
  2385. "subnet": "{{.PodCIDR}}",
  2386. "routes": [
  2387. {
  2388. "dst": "0.0.0.0/0"
  2389. }
  2390. ]
  2391. }
  2392. },
  2393. {
  2394. "type": "portmap",
  2395. "capabilities": {
  2396. "portMappings": true
  2397. }
  2398. }
  2399. ]
  2400. }
  2401. EOF
  2402. if [[ "${KUBERNETES_MASTER:-}" != "true" ]]; then
  2403. if [[ "${NETWORK_POLICY_PROVIDER:-"none"}" != "none" || "${ENABLE_NETD:-}" == "true" ]]; then
  2404. # Use Kubernetes cni daemonset on node if network policy provider is specified
  2405. # or netd is enabled.
  2406. cni_template_path=""
  2407. fi
  2408. fi
  2409. cat > "${config_path}" <<EOF
  2410. # Kubernetes doesn't use containerd restart manager.
  2411. disabled_plugins = ["restart"]
  2412. oom_score = -999
  2413. [debug]
  2414. level = "${CONTAINERD_LOG_LEVEL:-"info"}"
  2415. [plugins.cri]
  2416. stream_server_address = "127.0.0.1"
  2417. max_container_log_line_size = ${CONTAINERD_MAX_CONTAINER_LOG_LINE:-262144}
  2418. [plugins.cri.cni]
  2419. bin_dir = "${KUBE_HOME}/bin"
  2420. conf_dir = "/etc/cni/net.d"
  2421. conf_template = "${cni_template_path}"
  2422. [plugins.cri.registry.mirrors."docker.io"]
  2423. endpoint = ["https://mirror.gcr.io","https://registry-1.docker.io"]
  2424. EOF
  2425. if [[ "${CONTAINER_RUNTIME_TEST_HANDLER:-}" == "true" ]]; then
  2426. cat >> "${config_path}" <<EOF
  2427. # Setup a runtime with the magic name ("test-handler") used for Kubernetes
  2428. # runtime class tests ...
  2429. [plugins.cri.containerd.runtimes.test-handler]
  2430. runtime_type = "io.containerd.runtime.v1.linux"
  2431. EOF
  2432. fi
  2433. # Reuse docker group for containerd.
  2434. local containerd_gid="$(cat /etc/group | grep ^docker: | cut -d: -f 3)"
  2435. if [[ ! -z "${containerd_gid:-}" ]]; then
  2436. cat >> "${config_path}" <<EOF
  2437. # reuse id of the docker group
  2438. [grpc]
  2439. gid = ${containerd_gid}
  2440. EOF
  2441. fi
  2442. chmod 644 "${config_path}"
  2443. echo "Restart containerd to load the config change"
  2444. systemctl restart containerd
  2445. }
  2446. ########### Main Function ###########
  2447. function main() {
  2448. echo "Start to configure instance for kubernetes"
  2449. readonly UUID_MNT_PREFIX="/mnt/disks/by-uuid/google-local-ssds"
  2450. readonly UUID_BLOCK_PREFIX="/dev/disk/by-uuid/google-local-ssds"
  2451. readonly COREDNS_AUTOSCALER="Deployment/coredns"
  2452. readonly KUBEDNS_AUTOSCALER="Deployment/kube-dns"
  2453. # Resource requests of master components.
  2454. KUBE_CONTROLLER_MANAGER_CPU_REQUEST="${KUBE_CONTROLLER_MANAGER_CPU_REQUEST:-200m}"
  2455. KUBE_SCHEDULER_CPU_REQUEST="${KUBE_SCHEDULER_CPU_REQUEST:-75m}"
  2456. # Use --retry-connrefused opt only if it's supported by curl.
  2457. CURL_RETRY_CONNREFUSED=""
  2458. if curl --help | grep -q -- '--retry-connrefused'; then
  2459. CURL_RETRY_CONNREFUSED='--retry-connrefused'
  2460. fi
  2461. KUBE_HOME="/home/kubernetes"
  2462. KUBE_BIN=${KUBE_HOME}/bin
  2463. CONTAINERIZED_MOUNTER_HOME="${KUBE_HOME}/containerized_mounter"
  2464. PV_RECYCLER_OVERRIDE_TEMPLATE="${KUBE_HOME}/kube-manifests/kubernetes/pv-recycler-template.yaml"
  2465. if [[ "$(python -V 2>&1)" =~ "Python 2" ]]; then
  2466. # found python2, just use that
  2467. PYTHON="python"
  2468. elif [[ -f "/usr/bin/python2.7" ]]; then
  2469. # System python not defaulted to python 2 but using 2.7 during migration
  2470. PYTHON="/usr/bin/python2.7"
  2471. else
  2472. # No python2 either by default, let's see if we can find python3
  2473. PYTHON="python3"
  2474. if ! command -v ${PYTHON} >/dev/null 2>&1; then
  2475. echo "ERROR Python not found. Aborting."
  2476. exit 2
  2477. fi
  2478. fi
  2479. echo "Version : " $(${PYTHON} -V 2>&1)
  2480. if [[ ! -e "${KUBE_HOME}/kube-env" ]]; then
  2481. echo "The ${KUBE_HOME}/kube-env file does not exist!! Terminate cluster initialization."
  2482. exit 1
  2483. fi
  2484. source "${KUBE_HOME}/kube-env"
  2485. if [[ -f "${KUBE_HOME}/kubelet-config.yaml" ]]; then
  2486. echo "Found Kubelet config file at ${KUBE_HOME}/kubelet-config.yaml"
  2487. KUBELET_CONFIG_FILE_ARG="--config ${KUBE_HOME}/kubelet-config.yaml"
  2488. fi
  2489. if [[ -e "${KUBE_HOME}/kube-master-certs" ]]; then
  2490. source "${KUBE_HOME}/kube-master-certs"
  2491. fi
  2492. if [[ -n "${KUBE_USER:-}" ]]; then
  2493. if ! [[ "${KUBE_USER}" =~ ^[-._@a-zA-Z0-9]+$ ]]; then
  2494. echo "Bad KUBE_USER format."
  2495. exit 1
  2496. fi
  2497. fi
  2498. KUBE_CONTROLLER_MANAGER_TOKEN="$(secure_random 32)"
  2499. KUBE_SCHEDULER_TOKEN="$(secure_random 32)"
  2500. KUBE_CLUSTER_AUTOSCALER_TOKEN="$(secure_random 32)"
  2501. if [[ "${ENABLE_L7_LOADBALANCING:-}" == "glbc" ]]; then
  2502. GCE_GLBC_TOKEN="$(secure_random 32)"
  2503. fi
  2504. ADDON_MANAGER_TOKEN="$(secure_random 32)"
  2505. if [[ "${ENABLE_APISERVER_INSECURE_PORT:-false}" != "true" ]]; then
  2506. KUBE_BOOTSTRAP_TOKEN="$(secure_random 32)"
  2507. fi
  2508. setup-os-params
  2509. config-ip-firewall
  2510. create-dirs
  2511. setup-kubelet-dir
  2512. ensure-local-ssds
  2513. setup-logrotate
  2514. if [[ "${KUBERNETES_MASTER:-}" == "true" ]]; then
  2515. mount-master-pd
  2516. create-node-pki
  2517. create-master-pki
  2518. create-master-auth
  2519. ensure-master-bootstrap-kubectl-auth
  2520. if [[ "${ENABLE_EGRESS_VIA_KONNECTIVITY_SERVICE:-false}" == "true" ]]; then
  2521. create-master-konnectivity-server-apiserver-auth
  2522. fi
  2523. create-master-kubelet-auth
  2524. create-master-etcd-auth
  2525. create-master-etcd-apiserver-auth
  2526. override-pv-recycler
  2527. gke-master-start
  2528. else
  2529. create-node-pki
  2530. create-kubelet-kubeconfig ${KUBERNETES_MASTER_NAME}
  2531. if [[ "${KUBE_PROXY_DAEMONSET:-}" != "true" ]]; then
  2532. create-kubeproxy-user-kubeconfig
  2533. fi
  2534. if [[ "${ENABLE_NODE_PROBLEM_DETECTOR:-}" == "standalone" ]]; then
  2535. if [[ -n "${NODE_PROBLEM_DETECTOR_TOKEN:-}" ]]; then
  2536. create-node-problem-detector-kubeconfig ${KUBERNETES_MASTER_NAME}
  2537. elif [[ -f "/var/lib/kubelet/kubeconfig" ]]; then
  2538. create-node-problem-detector-kubeconfig-from-kubelet
  2539. else
  2540. echo "Either NODE_PROBLEM_DETECTOR_TOKEN or /var/lib/kubelet/kubeconfig must be set"
  2541. exit 1
  2542. fi
  2543. fi
  2544. fi
  2545. override-kubectl
  2546. container_runtime="${CONTAINER_RUNTIME:-docker}"
  2547. # Run the containerized mounter once to pre-cache the container image.
  2548. if [[ "${container_runtime}" == "docker" ]]; then
  2549. assemble-docker-flags
  2550. elif [[ "${container_runtime}" == "containerd" ]]; then
  2551. setup-containerd
  2552. fi
  2553. start-kubelet
  2554. if [[ "${KUBERNETES_MASTER:-}" == "true" ]]; then
  2555. compute-master-manifest-variables
  2556. if [[ -z "${ETCD_SERVERS:-}" ]]; then
  2557. start-etcd-servers
  2558. start-etcd-empty-dir-cleanup-pod
  2559. fi
  2560. source ${KUBE_BIN}/configure-kubeapiserver.sh
  2561. start-kube-apiserver
  2562. if [[ "${ENABLE_EGRESS_VIA_KONNECTIVITY_SERVICE:-false}" == "true" ]]; then
  2563. start-konnectivity-server
  2564. fi
  2565. start-kube-controller-manager
  2566. start-kube-scheduler
  2567. wait-till-apiserver-ready
  2568. start-kube-addons
  2569. start-cluster-autoscaler
  2570. start-lb-controller
  2571. update-legacy-addon-node-labels &
  2572. else
  2573. if [[ "${KUBE_PROXY_DAEMONSET:-}" != "true" ]]; then
  2574. start-kube-proxy
  2575. fi
  2576. if [[ "${ENABLE_NODE_PROBLEM_DETECTOR:-}" == "standalone" ]]; then
  2577. start-node-problem-detector
  2578. fi
  2579. fi
  2580. reset-motd
  2581. prepare-mounter-rootfs
  2582. modprobe configs
  2583. echo "Done for the configuration for kubernetes"
  2584. }
  2585. if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
  2586. main "${@}"
  2587. fi