run_test.sh 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  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 only for demonstrating how to use the node test container. In
  16. # production environment, kubelet bootstrap will be more complicated, user
  17. # should configure the node test container accordingly.
  18. # In addition, this script will also be used in the node e2e test to let it use
  19. # the containerized test suite.
  20. # TODO(random-liu): Use standard installer to install kubelet.
  21. # TODO(random-liu): Use standard tool to start kubelet in production way (such
  22. # as systemd, supervisord etc.)
  23. # Refresh sudo credentials if needed
  24. if ping -c 1 -q metadata.google.internal &> /dev/null; then
  25. echo 'Running on GCE, not asking for sudo credentials'
  26. elif sudo --non-interactive "$(which bash)" -c true 2> /dev/null; then
  27. # if we can run bash without a password, it's a pretty safe bet that either
  28. # we can run any command without a password, or that sudo credentials
  29. # are already cached - and they've just been re-cached
  30. echo 'No need to refresh sudo credentials'
  31. else
  32. echo 'Updating sudo credentials'
  33. sudo -v || exit 1
  34. fi
  35. # FOCUS is ginkgo focus to select which tests to run. By default, FOCUS is
  36. # initialized as "\[Conformance\]" in the test container to run all conformance
  37. # test.
  38. FOCUS=${FOCUS:-""}
  39. # SKIP is ginkgo skip to select which tests to skip. By default, SKIP is
  40. # initialized as "\[Flaky\]|\[Serial\]" in the test container skipping all
  41. # flaky and serial test.
  42. SKIP=${SKIP:-""}
  43. # TEST_ARGS is the test arguments. It could be used to override default test
  44. # arguments in the container.
  45. TEST_ARGS=${TEST_ARGS:-""}
  46. # REGISTRY is the image registry for node test image.
  47. REGISTRY=${REGISTRY:-"k8s.gcr.io"}
  48. # ARCH is the architecture of current machine, the script will use this to
  49. # select corresponding test container image.
  50. ARCH=${ARCH:-"amd64"}
  51. # VERSION is the version of the test container image.
  52. VERSION=${VERSION:-"0.2"}
  53. # KUBELET_BIN is the kubelet binary name. If it is not specified, use the
  54. # default binary name "kubelet".
  55. KUBELET_BIN=${KUBELET_BIN:-"kubelet"}
  56. # KUBELET is the kubelet binary path. If it is not specified, assume kubelet is
  57. # in PATH.
  58. KUBELET=${KUBELET:-"$(which "$KUBELET_BIN")"}
  59. # LOG_DIR is the absolute path of the directory where the test will collect all
  60. # logs to. By default, use the current directory.
  61. LOG_DIR=${LOG_DIR:-$(pwd)}
  62. mkdir -p "$LOG_DIR"
  63. # NETWORK_PLUGIN is the network plugin used by kubelet. Do not use network
  64. # plugin by default.
  65. NETWORK_PLUGIN=${NETWORK_PLUGIN:-""}
  66. # CNI_CONF_DIR is the path to network plugin binaries.
  67. CNI_CONF_DIR=${CNI_CONF_DIR:-""}
  68. # CNI_BIN_DIR is the path to network plugin config files.
  69. CNI_BIN_DIR=${CNI_BIN_DIR:-""}
  70. # KUBELET_KUBECONFIG is the path to a kubeconfig file, specifying how to connect to the API server.
  71. KUBELET_KUBECONFIG=${KUBELET_KUBECONFIG:-"/var/lib/kubelet/kubeconfig"}
  72. # Creates a kubeconfig file for the kubelet.
  73. # Args: address (e.g. "http://localhost:8080"), destination file path
  74. function create-kubelet-kubeconfig() {
  75. local api_addr="${1}"
  76. local dest="${2}"
  77. local dest_dir
  78. dest_dir="$(dirname "${dest}")"
  79. mkdir -p "${dest_dir}" &>/dev/null || sudo mkdir -p "${dest_dir}"
  80. sudo=$(test -w "${dest_dir}" || echo "sudo -E")
  81. cat <<EOF | ${sudo} tee "${dest}" > /dev/null
  82. apiVersion: v1
  83. kind: Config
  84. clusters:
  85. - cluster:
  86. server: ${api_addr}
  87. name: local
  88. contexts:
  89. - context:
  90. cluster: local
  91. name: local
  92. current-context: local
  93. EOF
  94. }
  95. # start_kubelet starts kubelet and redirect kubelet log to $LOG_DIR/kubelet.log.
  96. kubelet_log=kubelet.log
  97. start_kubelet() {
  98. echo "Creating kubelet.kubeconfig"
  99. create-kubelet-kubeconfig "http://localhost:8080" "${KUBELET_KUBECONFIG}"
  100. echo "Starting kubelet..."
  101. # we want to run this command as root but log the file to a normal user file
  102. # (so disable SC2024)
  103. # shellcheck disable=SC2024
  104. if ! sudo -b "${KUBELET}" "$@" &>"${LOG_DIR}/${kubelet_log}"; then
  105. echo "Failed to start kubelet"
  106. exit 1
  107. fi
  108. }
  109. # wait_kubelet retries for 10 times for kubelet to be ready by checking http://127.0.0.1:10255/healthz.
  110. wait_kubelet() {
  111. echo "Health checking kubelet..."
  112. healthCheckURL=http://127.0.0.1:10255/healthz
  113. local maxRetry=10
  114. local cur=1
  115. while [ $cur -le $maxRetry ]; do
  116. if curl -s $healthCheckURL > /dev/null; then
  117. echo "Kubelet is ready"
  118. break
  119. fi
  120. if [ $cur -eq $maxRetry ]; then
  121. echo "Health check exceeds max retry"
  122. exit 1
  123. fi
  124. echo "Kubelet is not ready"
  125. sleep 1
  126. ((cur++))
  127. done
  128. }
  129. # kill_kubelet kills kubelet.
  130. kill_kubelet() {
  131. echo "Stopping kubelet..."
  132. if ! sudo pkill "${KUBELET_BIN}"; then
  133. echo "Failed to stop kubelet."
  134. exit 1
  135. fi
  136. }
  137. # run_test runs the node test container.
  138. run_test() {
  139. env=""
  140. if [ -n "$FOCUS" ]; then
  141. env="$env -e FOCUS=\"$FOCUS\""
  142. fi
  143. if [ -n "$SKIP" ]; then
  144. env="$env -e SKIP=\"$SKIP\""
  145. fi
  146. if [ -n "$TEST_ARGS" ]; then
  147. env="$env -e TEST_ARGS=\"$TEST_ARGS\""
  148. fi
  149. # The test assumes that inside the container:
  150. # * kubelet manifest path is mounted to the same path;
  151. # * log collect directory is mounted to /var/result;
  152. # * root file system is mounted to /rootfs.
  153. sudo sh -c "docker run -it --rm --privileged=true --net=host -v /:/rootfs \
  154. -v $config_dir:$config_dir -v $LOG_DIR:/var/result ${env} $REGISTRY/node-test-$ARCH:$VERSION"
  155. }
  156. # Check whether kubelet is running. If kubelet is running, tell the user to stop
  157. # it before running the test.
  158. pid=$(pidof "${KUBELET_BIN}")
  159. if [ -n "$pid" ]; then
  160. echo "Kubelet is running (pid=$pid), please stop it before running the test."
  161. exit 1
  162. fi
  163. volume_stats_agg_period=10s
  164. serialize_image_pulls=false
  165. config_dir=$(mktemp -d)
  166. file_check_frequency=10s
  167. pod_cidr=10.100.0.0/24
  168. log_level=4
  169. start_kubelet --kubeconfig "${KUBELET_KUBECONFIG}" \
  170. --volume-stats-agg-period $volume_stats_agg_period \
  171. --serialize-image-pulls=$serialize_image_pulls \
  172. --pod-manifest-path "${config_dir}" \
  173. --file-check-frequency $file_check_frequency \
  174. --pod-cidr=$pod_cidr \
  175. --runtime-cgroups=/docker-daemon \
  176. --kubelet-cgroups=/kubelet \
  177. --system-cgroups=/system \
  178. --cgroup-root=/ \
  179. "--network-plugin=${NETWORK_PLUGIN}" \
  180. "--cni-conf-dir=${CNI_CONF_DIR}" \
  181. "--cni-bin-dir=${CNI_BIN_DIR}" \
  182. --v=$log_level \
  183. --logtostderr
  184. wait_kubelet
  185. run_test
  186. kill_kubelet
  187. # Clean up the kubelet config directory
  188. sudo rm -rf "${config_dir}"