123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- #!/usr/bin/env bash
- # Copyright 2016 The Kubernetes Authors.
- #
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
- # This script is only for demonstrating how to use the node test container. In
- # production environment, kubelet bootstrap will be more complicated, user
- # should configure the node test container accordingly.
- # In addition, this script will also be used in the node e2e test to let it use
- # the containerized test suite.
- # TODO(random-liu): Use standard installer to install kubelet.
- # TODO(random-liu): Use standard tool to start kubelet in production way (such
- # as systemd, supervisord etc.)
- # Refresh sudo credentials if needed
- if ping -c 1 -q metadata.google.internal &> /dev/null; then
- echo 'Running on CGE, not asking for sudo credentials'
- elif sudo --non-interactive "$(which bash)" -c true 2> /dev/null; then
- # if we can run bash without a password, it's a pretty safe bet that either
- # we can run any command without a password, or that sudo credentials
- # are already cached - and they've just been re-cached
- echo 'No need to refresh sudo credentials'
- else
- echo 'Updating sudo credentials'
- sudo --validate || exit 1
- fi
- # FOCUS is ginkgo focus to select which tests to run. By default, FOCUS is
- # initialized as "\[Conformance\]" in the test container to run all conformance
- # test.
- FOCUS=${FOCUS:-""}
- # SKIP is ginkgo skip to select which tests to skip. By default, SKIP is
- # initialized as "\[Flaky\]|\[Serial\]" in the test container skipping all
- # flaky and serial test.
- SKIP=${SKIP:-""}
- # TEST_ARGS is the test arguments. It could be used to override default test
- # arguments in the container.
- TEST_ARGS=${TEST_ARGS:-""}
- # REGISTRY is the image registry for node test image.
- REGISTRY=${REGISTRY:-"k8s.gcr.io"}
- # ARCH is the architecture of current machine, the script will use this to
- # select corresponding test container image.
- ARCH=${ARCH:-"amd64"}
- # VERSION is the version of the test container image.
- VERSION=${VERSION:-"0.2"}
- # KUBELET_BIN is the kubelet binary name. If it is not specified, use the
- # default binary name "kubelet".
- KUBELET_BIN=${KUBELET_BIN:-"kubelet"}
- # KUBELET is the kubelet binary path. If it is not specified, assume kubelet is
- # in PATH.
- KUBELET=${KUBELET:-"`which $KUBELET_BIN`"}
- # LOG_DIR is the absolute path of the directory where the test will collect all
- # logs to. By default, use the current directory.
- LOG_DIR=${LOG_DIR:-`pwd`}
- mkdir -p $LOG_DIR
- # NETWORK_PLUGIN is the network plugin used by kubelet. Do not use network
- # plugin by default.
- NETWORK_PLUGIN=${NETWORK_PLUGIN:-""}
- # CNI_CONF_DIR is the path to network plugin binaries.
- CNI_CONF_DIR=${CNI_CONF_DIR:-""}
- # CNI_BIN_DIR is the path to network plugin config files.
- CNI_BIN_DIR=${CNI_BIN_DIR:-""}
- # KUBELET_KUBECONFIG is the path to a kubeconfig file, specifying how to connect to the API server.
- KUBELET_KUBECONFIG=${KUBELET_KUBECONFIG:-"/var/lib/kubelet/kubeconfig"}
- # Creates a kubeconfig file for the kubelet.
- # Args: address (e.g. "http://localhost:8080"), destination file path
- function create-kubelet-kubeconfig() {
- local api_addr="${1}"
- local dest="${2}"
- local dest_dir="$(dirname "${dest}")"
- mkdir -p "${dest_dir}" &>/dev/null || sudo mkdir -p "${dest_dir}"
- sudo=$(test -w "${dest_dir}" || echo "sudo -E")
- cat <<EOF | ${sudo} tee "${dest}" > /dev/null
- apiVersion: v1
- kind: Config
- clusters:
- - cluster:
- server: ${api_addr}
- name: local
- contexts:
- - context:
- cluster: local
- name: local
- current-context: local
- EOF
- }
- # start_kubelet starts kubelet and redirect kubelet log to $LOG_DIR/kubelet.log.
- kubelet_log=kubelet.log
- start_kubelet() {
- echo "Creating kubelet.kubeconfig"
- create-kubelet-kubeconfig "http://localhost:8080" $KUBELET_KUBECONFIG
- echo "Starting kubelet..."
- sudo -b $KUBELET $@ &>$LOG_DIR/$kubelet_log
- if [ $? -ne 0 ]; then
- echo "Failed to start kubelet"
- exit 1
- fi
- }
- # wait_kubelet retries for 10 times for kubelet to be ready by checking http://127.0.0.1:10255/healthz.
- wait_kubelet() {
- echo "Health checking kubelet..."
- healthCheckURL=http://127.0.0.1:10255/healthz
- local maxRetry=10
- local cur=1
- while [ $cur -le $maxRetry ]; do
- curl -s $healthCheckURL > /dev/null
- if [ $? -eq 0 ]; then
- echo "Kubelet is ready"
- break
- fi
- if [ $cur -eq $maxRetry ]; then
- echo "Health check exceeds max retry"
- exit 1
- fi
- echo "Kubelet is not ready"
- sleep 1
- ((cur++))
- done
- }
- # kill_kubelet kills kubelet.
- kill_kubelet() {
- echo "Stopping kubelet..."
- sudo pkill $KUBELET_BIN
- if [ $? -ne 0 ]; then
- echo "Failed to stop kubelet."
- exit 1
- fi
- }
- # run_test runs the node test container.
- run_test() {
- env=""
- if [ ! -z "$FOCUS" ]; then
- env="$env -e FOCUS=\"$FOCUS\""
- fi
- if [ ! -z "$SKIP" ]; then
- env="$env -e SKIP=\"$SKIP\""
- fi
- if [ ! -z "$TEST_ARGS" ]; then
- env="$env -e TEST_ARGS=\"$TEST_ARGS\""
- fi
- # The test assumes that inside the container:
- # * kubelet manifest path is mounted to the same path;
- # * log collect directory is mounted to /var/result;
- # * root file system is mounted to /rootfs.
- sudo sh -c "docker run -it --rm --privileged=true --net=host -v /:/rootfs \
- -v $config_dir:$config_dir -v $LOG_DIR:/var/result ${env} $REGISTRY/node-test-$ARCH:$VERSION"
- }
- # Check whether kubelet is running. If kubelet is running, tell the user to stop
- # it before running the test.
- pid=`pidof $KUBELET_BIN`
- if [ ! -z $pid ]; then
- echo "Kubelet is running (pid=$pid), please stop it before running the test."
- exit 1
- fi
- volume_stats_agg_period=10s
- serialize_image_pulls=false
- config_dir=`mktemp -d`
- file_check_frequency=10s
- pod_cidr=10.100.0.0/24
- log_level=4
- start_kubelet --kubeconfig ${KUBELET_KUBECONFIG} \
- --volume-stats-agg-period $volume_stats_agg_period \
- --serialize-image-pulls=$serialize_image_pulls \
- --pod-manifest-path $config_dir \
- --file-check-frequency $file_check_frequency \
- --pod-cidr=$pod_cidr \
- --runtime-cgroups=/docker-daemon \
- --kubelet-cgroups=/kubelet \
- --system-cgroups=/system \
- --cgroup-root=/ \
- --network-plugin=$NETWORK_PLUGIN \
- --cni-conf-dir=$CNI_CONF_DIR \
- --cni-bin-dir=$CNI_BIN_DIR \
- --v=$log_level \
- --logtostderr
- wait_kubelet
- run_test
- kill_kubelet
- # Clean up the kubelet config directory
- sudo rm -rf $config_dir
|