sync.yaml 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  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. # periodically refresh both node-config.yaml and relabel the node
  101. while true; do
  102. if ! oc extract "configmaps/${name}" -n openshift-node --to=/etc/origin/node --confirm --request-timeout=10s --config /etc/origin/node/node.kubeconfig "--token=$( cat /var/run/secrets/kubernetes.io/serviceaccount/token )" > /dev/null; then
  103. echo "error: Unable to retrieve latest config for node" 2>&1
  104. sleep 15 &
  105. wait $!
  106. continue
  107. fi
  108. # detect whether the node-config.yaml has changed, and if so trigger a restart of the kubelet.
  109. md5sum /etc/origin/node/node-config.yaml > /tmp/.new
  110. if [[ "$( cat /tmp/.old )" != "$( cat /tmp/.new )" ]]; then
  111. echo "info: Configuration changed, restarting kubelet" 2>&1
  112. # TODO: kubelet doesn't relabel nodes, best effort for now
  113. # https://github.com/kubernetes/kubernetes/issues/59314
  114. if args="$(openshift-node-config --config /etc/origin/node/node-config.yaml)"; then
  115. labels=$(tr ' ' '\n' <<<$args | sed -ne '/^--node-labels=/ { s/^--node-labels=//; p; }' | tr ',\n' ' ')
  116. if [[ -n "${labels}" ]]; then
  117. echo "info: Applying node labels $labels" 2>&1
  118. if ! oc label --config=/etc/origin/node/node.kubeconfig "node/${NODE_NAME}" ${labels} --overwrite; then
  119. echo "error: Unable to apply labels, will retry in 10" 2>&1
  120. sleep 10 &
  121. wait $!
  122. continue
  123. fi
  124. fi
  125. else
  126. echo "error: The downloaded node configuration is invalid, retrying later" 2>&1
  127. sleep 10 &
  128. wait $!
  129. continue
  130. fi
  131. if ! pkill -U 0 -f '(^|/)hyperkube kubelet '; then
  132. echo "error: Unable to restart Kubelet" 2>&1
  133. sleep 10 &
  134. wait $!
  135. continue
  136. fi
  137. fi
  138. # annotate node with md5sum of the config
  139. oc annotate --config=/etc/origin/node/node.kubeconfig "node/${NODE_NAME}" \
  140. node.openshift.io/md5sum="$( cat /tmp/.new | cut -d' ' -f1 )" --overwrite
  141. cp -f /tmp/.new /tmp/.old
  142. sleep 180 &
  143. wait $!
  144. done
  145. env:
  146. - name: NODE_NAME
  147. valueFrom:
  148. fieldRef:
  149. fieldPath: spec.nodeName
  150. securityContext:
  151. runAsUser: 0
  152. privileged: true
  153. volumeMounts:
  154. # Directory which contains the host configuration. We read from this directory
  155. - mountPath: /etc/origin/node/
  156. name: host-config
  157. - mountPath: /etc/sysconfig
  158. name: host-sysconfig-node
  159. readOnly: true
  160. volumes:
  161. # In bootstrap mode, the host config contains information not easily available
  162. # from other locations.
  163. - name: host-config
  164. hostPath:
  165. path: /etc/origin/node
  166. - name: host-sysconfig-node
  167. hostPath:
  168. path: /etc/sysconfig