sync.yaml 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. kind: DaemonSet
  2. apiVersion: apps/v1
  3. metadata:
  4. name: sync
  5. namespace: openshift-node
  6. annotations:
  7. kubernetes.io/description: |
  8. This daemon set provides dynamic configuration of nodes and relabels nodes as appropriate.
  9. image.openshift.io/triggers: |
  10. [
  11. {"from":{"kind":"ImageStreamTag","name":"node:v3.11"},"fieldPath":"spec.template.spec.containers[?(@.name==\"sync\")].image"}
  12. ]
  13. spec:
  14. selector:
  15. matchLabels:
  16. app: sync
  17. updateStrategy:
  18. type: RollingUpdate
  19. rollingUpdate:
  20. maxUnavailable: 50%
  21. template:
  22. metadata:
  23. labels:
  24. app: sync
  25. component: network
  26. type: infra
  27. openshift.io/component: sync
  28. annotations:
  29. scheduler.alpha.kubernetes.io/critical-pod: ''
  30. spec:
  31. serviceAccountName: sync
  32. terminationGracePeriodSeconds: 1
  33. # Must be hostPID because it invokes operations on processes in the host space.
  34. hostPID: true
  35. # Must be hostNetwork in order to schedule before any network plugins are loaded.
  36. hostNetwork: true
  37. priorityClassName: system-node-critical
  38. containers:
  39. # The sync container is a temporary config loop until Kubelet dynamic config is implemented. It refreshes
  40. # the contents of /etc/origin/node/ with the config map ${BOOTSTRAP_CONFIG_NAME} from the openshift-node
  41. # namespace. It will restart the Kubelet on the host if it detects the node-config.yaml has changed.
  42. #
  43. # 1. Dynamic Kubelet config must pull down a full configmap
  44. # 2. Nodes must relabel themselves https://github.com/kubernetes/kubernetes/issues/59314
  45. #
  46. - name: sync
  47. image: " "
  48. command:
  49. - /bin/bash
  50. - -c
  51. - |
  52. #!/bin/bash
  53. set -euo pipefail
  54. # set by the node image
  55. unset KUBECONFIG
  56. trap 'kill $(jobs -p); exit 0' TERM
  57. # track the current state of the config
  58. if [[ -f /etc/origin/node/node-config.yaml ]]; then
  59. md5sum /etc/origin/node/node-config.yaml > /tmp/.old
  60. else
  61. touch /tmp/.old
  62. fi
  63. # loop until BOOTSTRAP_CONFIG_NAME is set
  64. while true; do
  65. file=/etc/sysconfig/origin-node
  66. if [[ -f /etc/sysconfig/atomic-openshift-node ]]; then
  67. file=/etc/sysconfig/atomic-openshift-node
  68. elif [[ -f /etc/sysconfig/origin-node ]]; then
  69. file=/etc/sysconfig/origin-node
  70. else
  71. echo "info: Waiting for the node sysconfig file to be created" 2>&1
  72. sleep 15 & wait
  73. continue
  74. fi
  75. name="$(sed -nE 's|^BOOTSTRAP_CONFIG_NAME=([^#].+)|\1|p' "${file}" | head -1)"
  76. if [[ -z "${name}" ]]; then
  77. echo "info: Waiting for BOOTSTRAP_CONFIG_NAME to be set" 2>&1
  78. sleep 15 & wait
  79. continue
  80. fi
  81. # in the background check to see if the value changes and exit if so
  82. pid=$BASHPID
  83. (
  84. while true; do
  85. if ! updated="$(sed -nE 's|^BOOTSTRAP_CONFIG_NAME=([^#].+)|\1|p' "${file}" | head -1)"; then
  86. echo "error: Unable to check for bootstrap config, exiting" 2>&1
  87. kill $pid
  88. exit 1
  89. fi
  90. if [[ "${updated}" != "${name}" ]]; then
  91. echo "info: Bootstrap configuration profile name changed, exiting" 2>&1
  92. kill $pid
  93. exit 0
  94. fi
  95. sleep 15
  96. done
  97. ) &
  98. break
  99. done
  100. mkdir -p /etc/origin/node/tmp
  101. # periodically refresh both node-config.yaml and relabel the node
  102. while true; do
  103. if ! oc extract "configmaps/${name}" -n openshift-node --to=/etc/origin/node/tmp --confirm --request-timeout=10s --config /etc/origin/node/node.kubeconfig "--token=$( cat /var/run/secrets/kubernetes.io/serviceaccount/token )" > /dev/null; then
  104. echo "error: Unable to retrieve latest config for node" 2>&1
  105. sleep 15 &
  106. wait $!
  107. continue
  108. fi
  109. KUBELET_HOSTNAME_OVERRIDE=$(cat /etc/sysconfig/KUBELET_HOSTNAME_OVERRIDE) || :
  110. if ! [[ -z "$KUBELET_HOSTNAME_OVERRIDE" ]]; then
  111. #Patching node-config for hostname override
  112. echo "nodeName: $KUBELET_HOSTNAME_OVERRIDE" >> /etc/origin/node/tmp/node-config.yaml
  113. fi
  114. # detect whether the node-config.yaml has changed, and if so trigger a restart of the kubelet.
  115. md5sum /etc/origin/node/tmp/node-config.yaml > /tmp/.new
  116. if [[ "$( cat /tmp/.old )" != "$( cat /tmp/.new )" ]]; then
  117. mv /etc/origin/node/tmp/node-config.yaml /etc/origin/node/node-config.yaml
  118. SYSTEMD_IGNORE_CHROOT=1 systemctl restart tuned || :
  119. echo "info: Configuration changed, restarting kubelet" 2>&1
  120. # TODO: kubelet doesn't relabel nodes, best effort for now
  121. # https://github.com/kubernetes/kubernetes/issues/59314
  122. if args="$(openshift-node-config --config /etc/origin/node/node-config.yaml)"; then
  123. labels=$(tr ' ' '\n' <<<$args | sed -ne '/^--node-labels=/ { s/^--node-labels=//; p; }' | tr ',\n' ' ')
  124. if [[ -n "${labels}" ]]; then
  125. echo "info: Applying node labels $labels" 2>&1
  126. if ! oc label --config=/etc/origin/node/node.kubeconfig "node/${NODE_NAME}" ${labels} --overwrite; then
  127. echo "error: Unable to apply labels, will retry in 10" 2>&1
  128. sleep 10 &
  129. wait $!
  130. continue
  131. fi
  132. fi
  133. else
  134. echo "error: The downloaded node configuration is invalid, retrying later" 2>&1
  135. sleep 10 &
  136. wait $!
  137. continue
  138. fi
  139. if ! pkill -U 0 -f '(^|/)hyperkube kubelet '; then
  140. echo "error: Unable to restart Kubelet" 2>&1
  141. sleep 10 &
  142. wait $!
  143. continue
  144. fi
  145. fi
  146. # annotate node with md5sum of the config
  147. oc annotate --config=/etc/origin/node/node.kubeconfig "node/${NODE_NAME}" \
  148. node.openshift.io/md5sum="$( cat /tmp/.new | cut -d' ' -f1 )" --overwrite
  149. cp -f /tmp/.new /tmp/.old
  150. sleep 180 &
  151. wait $!
  152. done
  153. env:
  154. - name: NODE_NAME
  155. valueFrom:
  156. fieldRef:
  157. fieldPath: spec.nodeName
  158. securityContext:
  159. runAsUser: 0
  160. privileged: true
  161. volumeMounts:
  162. # Directory which contains the host configuration. We read from this directory
  163. - mountPath: /etc/origin/node/
  164. name: host-config
  165. - mountPath: /etc/sysconfig
  166. name: host-sysconfig-node
  167. readOnly: true
  168. - mountPath: /var/run/dbus
  169. name: var-run-dbus
  170. readOnly: true
  171. - mountPath: /run/systemd/system
  172. name: run-systemd-system
  173. readOnly: true
  174. volumes:
  175. # In bootstrap mode, the host config contains information not easily available
  176. # from other locations.
  177. - name: host-config
  178. hostPath:
  179. path: /etc/origin/node
  180. - name: host-sysconfig-node
  181. hostPath:
  182. path: /etc/sysconfig
  183. - hostPath:
  184. path: /var/run/dbus
  185. name: var-run-dbus
  186. - hostPath:
  187. path: /run/systemd/system
  188. name: run-systemd-system