找回密码
 立即注册
首页 业界区 安全 K3S 安装 - 详细操作指南

K3S 安装 - 详细操作指南

森萌黠 5 天前
K3S 安装 - 详细操作指南

编写脚本

install.sh
  1. #!/bin/sh
  2. set -e
  3. set -o noglob
  4. # Usage:
  5. #   curl ... | ENV_VAR=... sh -
  6. #       or
  7. #   ENV_VAR=... ./install.sh
  8. #
  9. # Example:
  10. #   Installing a server without traefik:
  11. #     curl ... | INSTALL_K3S_EXEC="--disable=traefik" sh -
  12. #   Installing an agent to point at a server:
  13. #     curl ... | K3S_TOKEN=xxx K3S_URL=https://server-url:6443 sh -
  14. #
  15. # Environment variables:
  16. #   - K3S_*
  17. #     Environment variables which begin with K3S_ will be preserved for the
  18. #     systemd service to use. Setting K3S_URL without explicitly setting
  19. #     a systemd exec command will default the command to "agent", and we
  20. #     enforce that K3S_TOKEN is also set.
  21. #
  22. #   - INSTALL_K3S_SKIP_DOWNLOAD
  23. #     If set to true will not download k3s hash or binary.
  24. #
  25. #   - INSTALL_K3S_FORCE_RESTART
  26. #     If set to true will always restart the K3s service
  27. #
  28. #   - INSTALL_K3S_SYMLINK
  29. #     If set to 'skip' will not create symlinks, 'force' will overwrite,
  30. #     default will symlink if command does not exist in path.
  31. #
  32. #   - INSTALL_K3S_SKIP_ENABLE
  33. #     If set to true will not enable or start k3s service.
  34. #
  35. #   - INSTALL_K3S_SKIP_START
  36. #     If set to true will not start k3s service.
  37. #
  38. #   - INSTALL_K3S_VERSION
  39. #     Version of k3s to download from github. Will attempt to download from the
  40. #     stable channel if not specified.
  41. #
  42. #   - INSTALL_K3S_COMMIT
  43. #     Commit of k3s to download from temporary cloud storage.
  44. #     * (for developer & QA use)
  45. #
  46. #   - INSTALL_K3S_PR
  47. #     PR build of k3s to download from Github Artifacts.
  48. #     * (for developer & QA use)
  49. #
  50. #   - INSTALL_K3S_BIN_DIR
  51. #     Directory to install k3s binary, links, and uninstall script to, or use
  52. #     /usr/local/bin as the default
  53. #
  54. #   - INSTALL_K3S_BIN_DIR_READ_ONLY
  55. #     If set to true will not write files to INSTALL_K3S_BIN_DIR, forces
  56. #     setting INSTALL_K3S_SKIP_DOWNLOAD=true
  57. #
  58. #   - INSTALL_K3S_SYSTEMD_DIR
  59. #     Directory to install systemd service and environment files to, or use
  60. #     /etc/systemd/system as the default
  61. #
  62. #   - INSTALL_K3S_EXEC or script arguments
  63. #     Command with flags to use for launching k3s in the systemd service, if
  64. #     the command is not specified will default to "agent" if K3S_URL is set
  65. #     or "server" if not. The final systemd command resolves to a combination
  66. #     of EXEC and script args ($@).
  67. #
  68. #     The following commands result in the same behavior:
  69. #       curl ... | INSTALL_K3S_EXEC="--disable=traefik" sh -s -
  70. #       curl ... | INSTALL_K3S_EXEC="server --disable=traefik" sh -s -
  71. #       curl ... | INSTALL_K3S_EXEC="server" sh -s - --disable=traefik
  72. #       curl ... | sh -s - server --disable=traefik
  73. #       curl ... | sh -s - --disable=traefik
  74. #
  75. #   - INSTALL_K3S_NAME
  76. #     Name of systemd service to create, will default from the k3s exec command
  77. #     if not specified. If specified the name will be prefixed with 'k3s-'.
  78. #
  79. #   - INSTALL_K3S_TYPE
  80. #     Type of systemd service to create, will default from the k3s exec command
  81. #     if not specified.
  82. #
  83. #   - INSTALL_K3S_SELINUX_WARN
  84. #     If set to true will continue if k3s-selinux policy is not found.
  85. #
  86. #   - INSTALL_K3S_SKIP_SELINUX_RPM
  87. #     If set to true will skip automatic installation of the k3s RPM.
  88. #
  89. #   - INSTALL_K3S_CHANNEL_URL
  90. #     Channel URL for fetching k3s download URL.
  91. #     Defaults to 'https://update.k3s.io/v1-release/channels'.
  92. #
  93. #   - INSTALL_K3S_CHANNEL
  94. #     Channel to use for fetching k3s download URL.
  95. #     Defaults to 'stable'.
  96. GITHUB_URL=${GITHUB_URL:-https://github.com/k3s-io/k3s/releases}
  97. GITHUB_PR_URL=""
  98. STORAGE_URL=https://k3s-ci-builds.s3.amazonaws.com
  99. DOWNLOADER=
  100. # --- helper functions for logs ---
  101. info()
  102. {
  103.     echo '[INFO] ' "$@"
  104. }
  105. warn()
  106. {
  107.     echo '[WARN] ' "$@" >&2
  108. }
  109. fatal()
  110. {
  111.     echo '[ERROR] ' "$@" >&2
  112.     exit 1
  113. }
  114. # --- fatal if no systemd or openrc ---
  115. verify_system() {
  116.     if [ -x /sbin/openrc-run ]; then
  117.         HAS_OPENRC=true
  118.         return
  119.     fi
  120.     if [ -x /bin/systemctl ] || type systemctl > /dev/null 2>&1; then
  121.         HAS_SYSTEMD=true
  122.         return
  123.     fi
  124.     fatal 'Can not find systemd or openrc to use as a process supervisor for k3s'
  125. }
  126. # --- add quotes to command arguments ---
  127. quote() {
  128.     for arg in "$@"; do
  129.         printf '%s\n' "$arg" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/'/"
  130.     done
  131. }
  132. # --- add indentation and trailing slash to quoted args ---
  133. quote_indent() {
  134.     printf ' \\\n'
  135.     for arg in "$@"; do
  136.         printf '\t%s \\\n' "$(quote "$arg")"
  137.     done
  138. }
  139. # --- escape most punctuation characters, except quotes, forward slash, and space ---
  140. escape() {
  141.     printf '%s' "$@" | sed -e 's/\([][!#$%&()*;<=>?\_`{|}]\)/\\\1/g;'
  142. }
  143. # --- escape double quotes ---
  144. escape_dq() {
  145.     printf '%s' "$@" | sed -e 's/"/\"/g'
  146. }
  147. # --- ensures $K3S_URL is empty or begins with https://, exiting fatally otherwise ---
  148. verify_k3s_url() {
  149.     case "${K3S_URL}" in
  150.         "")
  151.             ;;
  152.         https://*)
  153.             ;;
  154.         *)
  155.             fatal "Only https:// URLs are supported for K3S_URL (have ${K3S_URL})"
  156.             ;;
  157.     esac
  158. }
  159. # --- define needed environment variables ---
  160. setup_env() {
  161.     # --- use command args if passed or create default ---
  162.     case "$1" in
  163.         # --- if we only have flags discover if command should be server or agent ---
  164.         (-*|"")
  165.             if [ -z "${K3S_URL}" ]; then
  166.                 CMD_K3S=server
  167.             else
  168.                 if [ -z "${K3S_TOKEN}" ] && [ -z "${K3S_TOKEN_FILE}" ]; then
  169.                     fatal "Defaulted k3s exec command to 'agent' because K3S_URL is defined, but K3S_TOKEN or K3S_TOKEN_FILE is not defined."
  170.                 fi
  171.                 CMD_K3S=agent
  172.             fi
  173.         ;;
  174.         # --- command is provided ---
  175.         (*)
  176.             CMD_K3S=$1
  177.             shift
  178.         ;;
  179.     esac
  180.     verify_k3s_url
  181.     CMD_K3S_EXEC="${CMD_K3S}$(quote_indent "$@")"
  182.     # --- use systemd name if defined or create default ---
  183.     if [ -n "${INSTALL_K3S_NAME}" ]; then
  184.         SYSTEM_NAME=k3s-${INSTALL_K3S_NAME}
  185.     else
  186.         if [ "${CMD_K3S}" = server ]; then
  187.             SYSTEM_NAME=k3s
  188.         else
  189.             SYSTEM_NAME=k3s-${CMD_K3S}
  190.         fi
  191.     fi
  192.     # --- check for invalid characters in system name ---
  193.     valid_chars=$(printf '%s' "${SYSTEM_NAME}" | sed -e 's/[][!#$%&()*;<=>?\_`{|}/[:space:]]/^/g;' )
  194.     if [ "${SYSTEM_NAME}" != "${valid_chars}"  ]; then
  195.         invalid_chars=$(printf '%s' "${valid_chars}" | sed -e 's/[^^]/ /g')
  196.         fatal "Invalid characters for system name:
  197.             ${SYSTEM_NAME}
  198.             ${invalid_chars}"
  199.     fi
  200.     # --- use sudo if we are not already root ---
  201.     SUDO=sudo
  202.     if [ $(id -u) -eq 0 ]; then
  203.         SUDO=
  204.     fi
  205.     # --- use systemd type if defined or create default ---
  206.     if [ -n "${INSTALL_K3S_TYPE}" ]; then
  207.         SYSTEMD_TYPE=${INSTALL_K3S_TYPE}
  208.     else
  209.         SYSTEMD_TYPE=notify
  210.     fi
  211.     # --- use binary install directory if defined or create default ---
  212.     if [ -n "${INSTALL_K3S_BIN_DIR}" ]; then
  213.         BIN_DIR=${INSTALL_K3S_BIN_DIR}
  214.     else
  215.         # --- use /usr/local/bin if root can write to it, otherwise use /opt/bin if it exists
  216.         BIN_DIR=/usr/local/bin
  217.         if ! $SUDO sh -c "touch ${BIN_DIR}/k3s-ro-test && rm -rf ${BIN_DIR}/k3s-ro-test"; then
  218.             if [ -d /opt/bin ]; then
  219.                 BIN_DIR=/opt/bin
  220.             fi
  221.         fi
  222.     fi
  223.     # --- use systemd directory if defined or create default ---
  224.     if [ -n "${INSTALL_K3S_SYSTEMD_DIR}" ]; then
  225.         SYSTEMD_DIR="${INSTALL_K3S_SYSTEMD_DIR}"
  226.     else
  227.         SYSTEMD_DIR=/etc/systemd/system
  228.     fi
  229.     # --- set related files from system name ---
  230.     SERVICE_K3S=${SYSTEM_NAME}.service
  231.     UNINSTALL_K3S_SH=${UNINSTALL_K3S_SH:-${BIN_DIR}/${SYSTEM_NAME}-uninstall.sh}
  232.     KILLALL_K3S_SH=${KILLALL_K3S_SH:-${BIN_DIR}/k3s-killall.sh}
  233.     # --- use service or environment location depending on systemd/openrc ---
  234.     if [ "${HAS_SYSTEMD}" = true ]; then
  235.         FILE_K3S_SERVICE=${SYSTEMD_DIR}/${SERVICE_K3S}
  236.         FILE_K3S_ENV=${SYSTEMD_DIR}/${SERVICE_K3S}.env
  237.     elif [ "${HAS_OPENRC}" = true ]; then
  238.         $SUDO mkdir -p /etc/rancher/k3s
  239.         FILE_K3S_SERVICE=/etc/init.d/${SYSTEM_NAME}
  240.         FILE_K3S_ENV=/etc/rancher/k3s/${SYSTEM_NAME}.env
  241.     fi
  242.     # --- get hash of config & exec for currently installed k3s ---
  243.     PRE_INSTALL_HASHES=$(get_installed_hashes)
  244.     # --- if bin directory is read only skip download ---
  245.     if [ "${INSTALL_K3S_BIN_DIR_READ_ONLY}" = true ]; then
  246.         INSTALL_K3S_SKIP_DOWNLOAD=true
  247.     fi
  248.     # --- setup channel values
  249.     INSTALL_K3S_CHANNEL_URL=${INSTALL_K3S_CHANNEL_URL:-'https://update.k3s.io/v1-release/channels'}
  250.     INSTALL_K3S_CHANNEL=${INSTALL_K3S_CHANNEL:-'stable'}
  251. }
  252. # --- check if skip download environment variable set ---
  253. can_skip_download_binary() {
  254.     if [ "${INSTALL_K3S_SKIP_DOWNLOAD}" != true ] && [ "${INSTALL_K3S_SKIP_DOWNLOAD}" != binary ]; then
  255.         return 1
  256.     fi
  257. }
  258. can_skip_download_selinux() {
  259.     if [ "${INSTALL_K3S_SKIP_DOWNLOAD}" != true ] && [ "${INSTALL_K3S_SKIP_DOWNLOAD}" != selinux ]; then
  260.         return 1
  261.     fi
  262. }
  263. # --- verify an executable k3s binary is installed ---
  264. verify_k3s_is_executable() {
  265.     if [ ! -x ${BIN_DIR}/k3s ]; then
  266.         fatal "Executable k3s binary not found at ${BIN_DIR}/k3s"
  267.     fi
  268. }
  269. # --- set arch and suffix, fatal if architecture not supported ---
  270. setup_verify_arch() {
  271.     if [ -z "$ARCH" ]; then
  272.         ARCH=$(uname -m)
  273.     fi
  274.     case $ARCH in
  275.         amd64)
  276.             ARCH=amd64
  277.             SUFFIX=
  278.             ;;
  279.         x86_64)
  280.             ARCH=amd64
  281.             SUFFIX=
  282.             ;;
  283.         arm64)
  284.             ARCH=arm64
  285.             SUFFIX=-${ARCH}
  286.             ;;
  287.         s390x)
  288.             ARCH=s390x
  289.             SUFFIX=-${ARCH}
  290.             ;;
  291.         aarch64)
  292.             ARCH=arm64
  293.             SUFFIX=-${ARCH}
  294.             ;;
  295.         arm*)
  296.             ARCH=arm
  297.             SUFFIX=-${ARCH}hf
  298.             ;;
  299.         *)
  300.             fatal "Unsupported architecture $ARCH"
  301.     esac
  302. }
  303. # --- verify existence of network downloader executable ---
  304. verify_downloader() {
  305.     # Return failure if it doesn't exist or is no executable
  306.     [ -x "$(command -v $1)" ] || return 1
  307.     # Set verified executable as our downloader program and return success
  308.     DOWNLOADER=$1
  309.     return 0
  310. }
  311. # --- create temporary directory and cleanup when done ---
  312. setup_tmp() {
  313.     TMP_DIR=$(mktemp -d -t k3s-install.XXXXXXXXXX)
  314.     TMP_HASH=${TMP_DIR}/k3s.hash
  315.     TMP_ZIP=${TMP_DIR}/k3s.zip
  316.     TMP_BIN=${TMP_DIR}/k3s.bin
  317.     cleanup() {
  318.         code=$?
  319.         set +e
  320.         trap - EXIT
  321.         rm -rf ${TMP_DIR}
  322.         exit $code
  323.     }
  324.     trap cleanup INT EXIT
  325. }
  326. # --- use desired k3s version if defined or find version from channel ---
  327. get_release_version() {
  328.     if [ -n "${INSTALL_K3S_PR}" ]; then
  329.         VERSION_K3S="PR ${INSTALL_K3S_PR}"
  330.         get_pr_artifact_url
  331.     elif [ -n "${INSTALL_K3S_COMMIT}" ]; then
  332.         VERSION_K3S="commit ${INSTALL_K3S_COMMIT}"
  333.     elif [ -n "${INSTALL_K3S_VERSION}" ]; then
  334.         VERSION_K3S=${INSTALL_K3S_VERSION}
  335.     else
  336.         info "Finding release for channel ${INSTALL_K3S_CHANNEL}"
  337.         version_url="${INSTALL_K3S_CHANNEL_URL}/${INSTALL_K3S_CHANNEL}"
  338.         case $DOWNLOADER in
  339.             curl)
  340.                 VERSION_K3S=$(curl -w '%{url_effective}' -L -s -S ${version_url} -o /dev/null | sed -e 's|.*/||')
  341.                 ;;
  342.             wget)
  343.                 VERSION_K3S=$(wget -SqO /dev/null ${version_url} 2>&1 | grep -i Location | sed -e 's|.*/||')
  344.                 ;;
  345.             *)
  346.                 fatal "Incorrect downloader executable '$DOWNLOADER'"
  347.                 ;;
  348.         esac
  349.     fi
  350.     info "Using ${VERSION_K3S} as release"
  351. }
  352. # --- get k3s-selinux version ---
  353. get_k3s_selinux_version() {
  354.     available_version="k3s-selinux-1.2-2.${rpm_target}.noarch.rpm"
  355.     info "Finding available k3s-selinux versions"
  356.     # run verify_downloader in case it binary installation was skipped
  357.     verify_downloader curl || verify_downloader wget || fatal 'Can not find curl or wget for downloading files'
  358.     case $DOWNLOADER in
  359.         curl)
  360.             DOWNLOADER_OPTS="-s"
  361.             ;;
  362.         wget)
  363.             DOWNLOADER_OPTS="-q -O -"
  364.             ;;
  365.         *)
  366.             fatal "Incorrect downloader executable '$DOWNLOADER'"
  367.             ;;
  368.     esac
  369.     for i in {1..3}; do
  370.         set +e
  371.         if [ "${rpm_channel}" = "testing" ]; then
  372.             version=$(timeout 5 ${DOWNLOADER} ${DOWNLOADER_OPTS} https://api.github.com/repos/k3s-io/k3s-selinux/releases |  grep browser_download_url | awk '{ print $2 }' | grep -oE "[^\/]+${rpm_target}\.noarch\.rpm" | head -n 1)
  373.         else
  374.             version=$(timeout 5 ${DOWNLOADER} ${DOWNLOADER_OPTS} https://api.github.com/repos/k3s-io/k3s-selinux/releases/latest |  grep browser_download_url | awk '{ print $2 }' | grep -oE "[^\/]+${rpm_target}\.noarch\.rpm")
  375.         fi
  376.         set -e
  377.         if [ "${version}" != "" ]; then
  378.             break
  379.         fi
  380.         sleep 1
  381.     done
  382.     if [ "${version}" == "" ]; then
  383.         warn "Failed to get available versions of k3s-selinux..defaulting to ${available_version}"
  384.         return
  385.     fi
  386.     available_version=${version}
  387. }
  388. # --- download from github url ---
  389. download() {
  390.     [ $# -eq 2 ] || fatal 'download needs exactly 2 arguments'
  391.     # Disable exit-on-error so we can do custom error messages on failure
  392.     set +e
  393.     # Default to a failure status
  394.     status=1
  395.     case $DOWNLOADER in
  396.         curl)
  397.             curl -o $1 -sfL $2
  398.             status=$?
  399.             ;;
  400.         wget)
  401.             wget -qO $1 $2
  402.             status=$?
  403.             ;;
  404.         *)
  405.             # Enable exit-on-error for fatal to execute
  406.             set -e
  407.             fatal "Incorrect executable '$DOWNLOADER'"
  408.             ;;
  409.     esac
  410.     # Re-enable exit-on-error
  411.     set -e
  412.     # Abort if download command failed
  413.     [ $status -eq 0 ] || fatal 'Download failed'
  414. }
  415. # --- download hash from github url ---
  416. download_hash() {
  417.     if [ -n "${INSTALL_K3S_PR}" ]; then
  418.         info "Downloading hash ${GITHUB_PR_URL}"
  419.         curl -s -o ${TMP_ZIP} -H "Authorization: Bearer $GITHUB_TOKEN" -L ${GITHUB_PR_URL}
  420.         unzip -p ${TMP_ZIP} k3s.sha256sum > ${TMP_HASH}
  421.     else
  422.         if [ -n "${INSTALL_K3S_COMMIT}" ]; then
  423.             HASH_URL=${STORAGE_URL}/k3s${SUFFIX}-${INSTALL_K3S_COMMIT}.sha256sum
  424.         else
  425.             HASH_URL=${GITHUB_URL}/download/${VERSION_K3S}/sha256sum-${ARCH}.txt
  426.         fi
  427.         info "Downloading hash ${HASH_URL}"
  428.         download ${TMP_HASH} ${HASH_URL}
  429.     fi
  430.     HASH_EXPECTED=$(grep " k3s${SUFFIX}$" ${TMP_HASH})
  431.     HASH_EXPECTED=${HASH_EXPECTED%%[[:blank:]]*}
  432. }
  433. # --- check hash against installed version ---
  434. installed_hash_matches() {
  435.     if [ -x ${BIN_DIR}/k3s ]; then
  436.         HASH_INSTALLED=$(sha256sum ${BIN_DIR}/k3s)
  437.         HASH_INSTALLED=${HASH_INSTALLED%%[[:blank:]]*}
  438.         if [ "${HASH_EXPECTED}" = "${HASH_INSTALLED}" ]; then
  439.             return
  440.         fi
  441.     fi
  442.     return 1
  443. }
  444. # Use the GitHub API to identify the artifact associated with a given PR
  445. get_pr_artifact_url() {
  446.     github_api_url=https://api.github.com/repos/k3s-io/k3s
  447.     # Check if jq is installed
  448.     if ! [ -x "$(command -v jq)" ]; then
  449.         fatal "Installing PR builds requires jq"
  450.     fi
  451.     # Check if unzip is installed
  452.     if ! [ -x "$(command -v unzip)" ]; then
  453.         fatal "Installing PR builds requires unzip"
  454.     fi
  455.     if [ -z "${GITHUB_TOKEN}" ]; then
  456.         fatal "Installing PR builds requires GITHUB_TOKEN with k3s-io/k3s repo permissions"
  457.     fi
  458.     # GET request to the GitHub API to retrieve the latest commit SHA from the pull request
  459.     set +e
  460.     commit_id=$(curl -f -s -H "Authorization: Bearer ${GITHUB_TOKEN}" "${github_api_url}/pulls/${INSTALL_K3S_PR}" | jq -r '.head.sha')
  461.     set -e
  462.     if [ -z "${commit_id}" ]; then
  463.         fatal "Installing PR builds requires GITHUB_TOKEN with k3s-io/k3s repo permissions"
  464.     fi
  465.     # GET request to the GitHub API to retrieve the Build workflow associated with the commit
  466.     run_id=$(curl -s -H "Authorization: Bearer ${GITHUB_TOKEN}" "${github_api_url}/commits/${commit_id}/check-runs?check_name=build%20%2F%20Build" | jq -r '[.check_runs | sort_by(.id) | .[].details_url | split("/")[7]] | last')
  467.     # Extract the artifact ID for the "k3s" (old) or "k3s-amd64" (new) artifact
  468.     GITHUB_PR_URL=$(curl -s -H "Authorization: Bearer ${GITHUB_TOKEN}" "${github_api_url}/actions/runs/${run_id}/artifacts" | jq -r '.artifacts[] | select(.name == "k3s" or .name == "k3s-amd64") | .archive_download_url')
  469. }
  470. # --- download binary from github url ---
  471. download_binary() {
  472.     if [ -n "${INSTALL_K3S_PR}" ]; then
  473.         # Since Binary and Hash are zipped together, check if TMP_ZIP already exists
  474.         if ! [ -f ${TMP_ZIP} ]; then
  475.             info "Downloading K3s artifact ${GITHUB_PR_URL}"
  476.             curl -s -f -o ${TMP_ZIP} -H "Authorization: Bearer $GITHUB_TOKEN" -L ${GITHUB_PR_URL}
  477.         fi
  478.         # extract k3s binary from zip
  479.         unzip -p ${TMP_ZIP} k3s > ${TMP_BIN}
  480.         return
  481.     elif [ -n "${INSTALL_K3S_COMMIT}" ]; then
  482.         BIN_URL=${STORAGE_URL}/k3s${SUFFIX}-${INSTALL_K3S_COMMIT}
  483.     else
  484.         BIN_URL=${GITHUB_URL}/download/${VERSION_K3S}/k3s${SUFFIX}
  485.     fi
  486.     info "Downloading binary ${BIN_URL}"
  487.     download ${TMP_BIN} ${BIN_URL}
  488. }
  489. # --- verify downloaded binary hash ---
  490. verify_binary() {
  491.     info "Verifying binary download"
  492.     HASH_BIN=$(sha256sum ${TMP_BIN})
  493.     HASH_BIN=${HASH_BIN%%[[:blank:]]*}
  494.     if [ "${HASH_EXPECTED}" != "${HASH_BIN}" ]; then
  495.         fatal "Download sha256 does not match ${HASH_EXPECTED}, got ${HASH_BIN}"
  496.     fi
  497. }
  498. # --- setup permissions and move binary to system directory ---
  499. setup_binary() {
  500.     chmod 755 ${TMP_BIN}
  501.     info "Installing k3s to ${BIN_DIR}/k3s"
  502.     $SUDO chown root:root ${TMP_BIN}
  503.     $SUDO mv -f ${TMP_BIN} ${BIN_DIR}/k3s
  504. }
  505. # --- setup selinux policy ---
  506. setup_selinux() {
  507.     case ${INSTALL_K3S_CHANNEL} in
  508.         *testing)
  509.             rpm_channel=testing
  510.             ;;
  511.         *latest)
  512.             rpm_channel=latest
  513.             ;;
  514.         *)
  515.             rpm_channel=stable
  516.             ;;
  517.     esac
  518.     rpm_site="rpm.rancher.io"
  519.     if [ "${rpm_channel}" = "testing" ]; then
  520.         rpm_site="rpm-testing.rancher.io"
  521.     fi
  522.     [ -r /etc/os-release ] && . /etc/os-release
  523.     if [ `expr "${ID_LIKE}" : ".*suse.*"` != 0 ]; then
  524.         rpm_target=sle
  525.         rpm_site_infix=microos
  526.         package_installer=zypper
  527.         if [ "${ID_LIKE:-}" = suse ] && ( [ "${VARIANT_ID:-}" = sle-micro ] || [ "${ID:-}" = sle-micro ] ); then
  528.             rpm_target=sle
  529.             rpm_site_infix=slemicro
  530.             package_installer=zypper
  531.         fi
  532.     elif [ "${ID_LIKE:-}" = coreos ] || [ "${VARIANT_ID:-}" = coreos ] || [ "${VARIANT_ID:-}" = "iot" ] || \
  533.          { { [ "${ID:-}" = fedora ] || [ "${ID_LIKE:-}" = fedora ]; } && [ -n "${OSTREE_VERSION:-}" ]; }; then
  534.         rpm_target=coreos
  535.         rpm_site_infix=coreos
  536.         package_installer=rpm-ostree
  537.     elif [ ! -n "${VERSION_ID}" ] || [ "${VERSION_ID%%.*}" = "7" ] || ( [ "${ID:-}" = amzn ] && [ "${VERSION_ID%%.*}" = "2" ] ); then
  538.         rpm_target=el7
  539.         rpm_site_infix=centos/7
  540.         package_installer=yum
  541.     elif [ ! -n "${VERSION_ID}" ] || [ "${VERSION_ID%%.*}" = "8" ] || [ "${VERSION_ID%%.*}" = "V10" ] || [ "${VERSION_ID%%.*}" -gt "36" ]; then
  542.         rpm_target=el8
  543.         rpm_site_infix=centos/8
  544.         package_installer=yum
  545.     else
  546.         rpm_target=el9
  547.         rpm_site_infix=centos/9
  548.         package_installer=yum
  549.     fi
  550.     if [ "${package_installer}" = "rpm-ostree" ] && [ -x /bin/yum ]; then
  551.         package_installer=yum
  552.     fi
  553.     if [ "${package_installer}" = "yum" ] && [ -x /usr/bin/dnf ]; then
  554.         package_installer=dnf
  555.     fi
  556.     if [ "$INSTALL_K3S_SKIP_SELINUX_RPM" = true ] || can_skip_download_selinux || [ ! -d /usr/share/selinux ]; then
  557.         info "Skipping installation of SELinux RPM"
  558.         return
  559.     fi
  560.     get_k3s_selinux_version
  561.     policy_hint="please install:
  562.     ${package_installer} install -y container-selinux
  563.     ${package_installer} install -y https://${rpm_site}/k3s/${rpm_channel}/common/${rpm_site_infix}/noarch/${available_version}
  564. "
  565.     install_selinux_rpm ${rpm_site} ${rpm_channel} ${rpm_target} ${rpm_site_infix}
  566.     policy_error=fatal
  567.     if [ "$INSTALL_K3S_SELINUX_WARN" = true ] || [ "${ID_LIKE:-}" = coreos ] ||
  568.        [ "${VARIANT_ID:-}" = coreos ] || [ "${VARIANT_ID:-}" = iot ]; then
  569.         policy_error=warn
  570.     fi
  571.     if ! $SUDO chcon -u system_u -r object_r -t container_runtime_exec_t ${BIN_DIR}/k3s >/dev/null 2>&1; then
  572.         if $SUDO grep '^\s*SELINUX=enforcing' /etc/selinux/config >/dev/null 2>&1; then
  573.             $policy_error "Failed to apply container_runtime_exec_t to ${BIN_DIR}/k3s, ${policy_hint}"
  574.         fi
  575.     elif [ ! -f /usr/share/selinux/packages/k3s.pp ]; then
  576.         if [ -x /usr/sbin/transactional-update ] || [ "${ID_LIKE:-}" = coreos ] || \
  577.             { { [ "${ID:-}" = fedora ] || [ "${ID_LIKE:-}" = fedora ]; } && [ -n "${OSTREE_VERSION:-}" ]; }; then
  578.             warn "Please reboot your machine to activate the changes and avoid data loss."
  579.         else
  580.             $policy_error "Failed to find the k3s-selinux policy, ${policy_hint}"
  581.         fi
  582.     fi
  583. }
  584. install_selinux_rpm() {
  585.     if [ -r /etc/redhat-release ] || [ -r /etc/centos-release ] || [ -r /etc/oracle-release ] ||
  586.        [ -r /etc/fedora-release ] || [ -r /etc/system-release ] || [ "${ID_LIKE%%[ ]*}" = "suse" ]; then
  587.         repodir=/etc/yum.repos.d
  588.         if [ -d /etc/zypp/repos.d ]; then
  589.             repodir=/etc/zypp/repos.d
  590.         fi
  591.         set +o noglob
  592.         $SUDO rm -f ${repodir}/rancher-k3s-common*.repo
  593.         set -o noglob
  594.         if [ -r /etc/redhat-release ] && [ "${3}" = "el7" ]; then
  595.             $SUDO yum install -y yum-utils
  596.             $SUDO yum-config-manager --enable rhel-7-server-extras-rpms
  597.         fi
  598.         $SUDO tee ${repodir}/rancher-k3s-common.repo >/dev/null << EOF
  599. [rancher-k3s-common-${2}]
  600. name=Rancher K3s Common (${2})
  601. baseurl=https://${1}/k3s/${2}/common/${4}/noarch
  602. enabled=1
  603. gpgcheck=1
  604. repo_gpgcheck=0
  605. gpgkey=https://${1}/public.key
  606. EOF
  607.         case ${3} in
  608.         sle)
  609.             rpm_installer="zypper --gpg-auto-import-keys"
  610.             if [ "${TRANSACTIONAL_UPDATE=false}" != "true" ] && [ -x /usr/sbin/transactional-update ]; then
  611.                 transactional_update_run="transactional-update --no-selfupdate -d run"
  612.                 rpm_installer="transactional-update --no-selfupdate -d run ${rpm_installer}"
  613.                 : "${INSTALL_K3S_SKIP_START:=true}"
  614.             fi
  615.             # create the /var/lib/rpm-state in SLE systems to fix the prein selinux macro
  616.             $SUDO ${transactional_update_run} mkdir -p /var/lib/rpm-state
  617.             ;;
  618.         coreos)
  619.             rpm_installer="rpm-ostree --idempotent"
  620.             # rpm_install_extra_args="--apply-live"
  621.             : "${INSTALL_K3S_SKIP_START:=true}"
  622.             ;;
  623.         *)
  624.             rpm_installer="yum"
  625.             ;;
  626.         esac
  627.         if [ "${rpm_installer}" = "yum" ] && [ -x /usr/bin/dnf ]; then
  628.             rpm_installer=dnf
  629.         fi
  630.             if rpm -q --quiet k3s-selinux; then
  631.             # remove k3s-selinux module before upgrade to allow container-selinux to upgrade safely
  632.             if check_available_upgrades container-selinux ${3} && check_available_upgrades k3s-selinux ${3}; then
  633.                 MODULE_PRIORITY=$($SUDO semodule --list=full | grep k3s | cut -f1 -d" ")
  634.                 if [ -n "${MODULE_PRIORITY}" ]; then
  635.                     $SUDO semodule -X $MODULE_PRIORITY -r k3s || true
  636.                 fi
  637.             fi
  638.         fi
  639.         # shellcheck disable=SC2086
  640.         $SUDO ${rpm_installer} install -y "k3s-selinux"
  641.     fi
  642.     return
  643. }
  644. check_available_upgrades() {
  645.     set +e
  646.     case ${2} in
  647.         sle)
  648.             available_upgrades=$($SUDO zypper -q -t -s 11 se -s -u --type package $1 | tail -n 1 | grep -v "No matching" | awk '{print $3}')
  649.             ;;
  650.         coreos)
  651.             # currently rpm-ostree does not support search functionality https://github.com/coreos/rpm-ostree/issues/1877
  652.             ;;
  653.         *)
  654.             available_upgrades=$($SUDO yum -q --refresh list $1 --upgrades | tail -n 1 | awk '{print $2}')
  655.             ;;
  656.     esac
  657.     set -e
  658.     if [ -n "${available_upgrades}" ]; then
  659.         return 0
  660.     fi
  661.     return 1
  662. }
  663. # --- download and verify k3s ---
  664. download_and_verify() {
  665.     if can_skip_download_binary; then
  666.        info 'Skipping k3s download and verify'
  667.        verify_k3s_is_executable
  668.        return
  669.     fi
  670.     setup_verify_arch
  671.     verify_downloader curl || verify_downloader wget || fatal 'Can not find curl or wget for downloading files'
  672.     setup_tmp
  673.     get_release_version
  674.     download_hash
  675.     if installed_hash_matches; then
  676.         info 'Skipping binary downloaded, installed k3s matches hash'
  677.         return
  678.     fi
  679.     download_binary
  680.     verify_binary
  681.     setup_binary
  682. }
  683. # --- add additional utility links ---
  684. create_symlinks() {
  685.     [ "${INSTALL_K3S_BIN_DIR_READ_ONLY}" = true ] && return
  686.     [ "${INSTALL_K3S_SYMLINK}" = skip ] && return
  687.     for cmd in kubectl crictl ctr; do
  688.         if [ ! -e ${BIN_DIR}/${cmd} ] || [ "${INSTALL_K3S_SYMLINK}" = force ]; then
  689.             which_cmd=$(command -v ${cmd} 2>/dev/null || true)
  690.             if [ -z "${which_cmd}" ] || [ "${INSTALL_K3S_SYMLINK}" = force ]; then
  691.                 info "Creating ${BIN_DIR}/${cmd} symlink to k3s"
  692.                 $SUDO ln -sf k3s ${BIN_DIR}/${cmd}
  693.             else
  694.                 info "Skipping ${BIN_DIR}/${cmd} symlink to k3s, command exists in PATH at ${which_cmd}"
  695.             fi
  696.         else
  697.             info "Skipping ${BIN_DIR}/${cmd} symlink to k3s, already exists"
  698.         fi
  699.     done
  700. }
  701. # --- create killall script ---
  702. create_killall() {
  703.     [ "${INSTALL_K3S_BIN_DIR_READ_ONLY}" = true ] && return
  704.     info "Creating killall script ${KILLALL_K3S_SH}"
  705.     $SUDO tee ${KILLALL_K3S_SH} >/dev/null << \EOF
  706. #!/bin/sh
  707. [ $(id -u) -eq 0 ] || exec sudo --preserve-env=K3S_DATA_DIR $0 $@
  708. K3S_DATA_DIR=${K3S_DATA_DIR:-/var/lib/rancher/k3s}
  709. for bin in ${K3S_DATA_DIR}/data/**/bin/; do
  710.     [ -d $bin ] && export PATH=$PATH:$bin:$bin/aux
  711. done
  712. set -x
  713. for service in /etc/systemd/system/k3s*.service; do
  714.     [ -s $service ] && systemctl stop $(basename $service)
  715. done
  716. for service in /etc/init.d/k3s*; do
  717.     [ -x $service ] && $service stop
  718. done
  719. pschildren() {
  720.     ps -e -o ppid= -o pid= | \
  721.     sed -e 's/^\s*//g; s/\s\s*/\t/g;' | \
  722.     grep -w "^$1" | \
  723.     cut -f2
  724. }
  725. pstree() {
  726.     for pid in $@; do
  727.         echo $pid
  728.         for child in $(pschildren $pid); do
  729.             pstree $child
  730.         done
  731.     done
  732. }
  733. killtree() {
  734.     kill -9 $(
  735.         { set +x; } 2>/dev/null;
  736.         pstree $@;
  737.         set -x;
  738.     ) 2>/dev/null
  739. }
  740. remove_interfaces() {
  741.     # Delete network interface(s) that match 'master cni0'
  742.     ip link show 2>/dev/null | grep 'master cni0' | while read ignore iface ignore; do
  743.         iface=${iface%%@*}
  744.         [ -z "$iface" ] || ip link delete $iface
  745.     done
  746.     # Delete cni related interfaces
  747.     ip link delete cni0
  748.     ip link delete flannel.1
  749.     ip link delete flannel-v6.1
  750.     ip link delete kube-ipvs0
  751.     ip link delete flannel-wg
  752.     ip link delete flannel-wg-v6
  753.     # Restart tailscale
  754.     if [ -n "$(command -v tailscale)" ]; then
  755.         tailscale set --advertise-routes=
  756.     fi
  757. }
  758. getshims() {
  759.     ps -e -o pid= -o args= | sed -e 's/^ *//; s/\s\s*/\t/;' | grep -w "${K3S_DATA_DIR}"'/data/[^/]*/bin/containerd-shim' | cut -f1
  760. }
  761. killtree $({ set +x; } 2>/dev/null; getshims; set -x)
  762. do_unmount_and_remove() {
  763.     set +x
  764.     while read -r _ path _; do
  765.         case "$path" in $1*) echo "$path" ;; esac
  766.     done < /proc/self/mounts | sort -r | xargs -r -t -n 1 sh -c 'umount -f "$0" && rm -rf "$0"'
  767.     set -x
  768. }
  769. do_unmount_and_remove '/run/k3s'
  770. do_unmount_and_remove '/var/lib/kubelet/pods'
  771. do_unmount_and_remove '/var/lib/kubelet/plugins'
  772. do_unmount_and_remove '/run/netns/cni-'
  773. # Remove CNI namespaces
  774. ip netns show 2>/dev/null | grep cni- | xargs -r -t -n 1 ip netns delete
  775. remove_interfaces
  776. rm -rf /var/lib/cni/
  777. iptables-save | grep -v KUBE- | grep -v CNI- | grep -iv flannel | iptables-restore
  778. ip6tables-save | grep -v KUBE- | grep -v CNI- | grep -iv flannel | ip6tables-restore
  779. EOF
  780.     $SUDO chmod 755 ${KILLALL_K3S_SH}
  781.     $SUDO chown root:root ${KILLALL_K3S_SH}
  782. }
  783. # --- create uninstall script ---
  784. create_uninstall() {
  785.     [ "${INSTALL_K3S_BIN_DIR_READ_ONLY}" = true ] && return
  786.     info "Creating uninstall script ${UNINSTALL_K3S_SH}"
  787.     $SUDO tee ${UNINSTALL_K3S_SH} >/dev/null << EOF
  788. #!/bin/sh
  789. set -x
  790. [ \$(id -u) -eq 0 ] || exec sudo --preserve-env=K3S_DATA_DIR \$0 \$@
  791. K3S_DATA_DIR=\${K3S_DATA_DIR:-/var/lib/rancher/k3s}
  792. ${KILLALL_K3S_SH}
  793. if command -v systemctl; then
  794.     systemctl disable ${SYSTEM_NAME}
  795.     systemctl reset-failed ${SYSTEM_NAME}
  796.     systemctl daemon-reload
  797. fi
  798. if command -v rc-update; then
  799.     rc-update delete ${SYSTEM_NAME} default
  800. fi
  801. rm -f ${FILE_K3S_SERVICE}
  802. rm -f ${FILE_K3S_ENV}
  803. remove_uninstall() {
  804.     rm -f ${UNINSTALL_K3S_SH}
  805. }
  806. trap remove_uninstall EXIT
  807. if (ls ${SYSTEMD_DIR}/k3s*.service || ls /etc/init.d/k3s*) >/dev/null 2>&1; then
  808.     set +x; echo 'Additional k3s services installed, skipping uninstall of k3s'; set -x
  809.     exit
  810. fi
  811. for cmd in kubectl crictl ctr; do
  812.     if [ -L ${BIN_DIR}/\$cmd ]; then
  813.         rm -f ${BIN_DIR}/\$cmd
  814.     fi
  815. done
  816. clean_mounted_directory() {
  817.     if ! grep -q " \$1" /proc/mounts; then
  818.         rm -rf "\$1"
  819.         return 0
  820.     fi
  821.     for path in "\$1"/*; do
  822.         if [ -d "\$path" ]; then
  823.             if grep -q " \$path" /proc/mounts; then
  824.                 clean_mounted_directory "\$path"
  825.             else
  826.                 rm -rf "\$path"
  827.             fi
  828.         else
  829.             rm "\$path"
  830.         fi
  831.      done
  832. }
  833. rm -rf /etc/rancher/k3s
  834. rm -rf /run/k3s
  835. rm -rf /run/flannel
  836. clean_mounted_directory \${K3S_DATA_DIR}
  837. rm -rf /var/lib/kubelet
  838. rm -f ${BIN_DIR}/k3s
  839. rm -f ${KILLALL_K3S_SH}
  840. if type yum >/dev/null 2>&1; then
  841.     yum remove -y k3s-selinux
  842.     rm -f /etc/yum.repos.d/rancher-k3s-common*.repo
  843. elif type rpm-ostree >/dev/null 2>&1; then
  844.     rpm-ostree uninstall k3s-selinux
  845.     rm -f /etc/yum.repos.d/rancher-k3s-common*.repo
  846. elif type zypper >/dev/null 2>&1; then
  847.     uninstall_cmd="zypper remove -y k3s-selinux"
  848.     if [ "\${TRANSACTIONAL_UPDATE=false}" != "true" ] && [ -x /usr/sbin/transactional-update ]; then
  849.         uninstall_cmd="transactional-update --no-selfupdate -d run \$uninstall_cmd"
  850.     fi
  851.     $SUDO \$uninstall_cmd
  852.     rm -f /etc/zypp/repos.d/rancher-k3s-common*.repo
  853. fi
  854. EOF
  855.     $SUDO chmod 755 ${UNINSTALL_K3S_SH}
  856.     $SUDO chown root:root ${UNINSTALL_K3S_SH}
  857. }
  858. # --- disable current service if loaded --
  859. systemd_disable() {
  860.     $SUDO systemctl disable ${SYSTEM_NAME} >/dev/null 2>&1 || true
  861.     $SUDO rm -f /etc/systemd/system/${SERVICE_K3S} || true
  862.     $SUDO rm -f /etc/systemd/system/${SERVICE_K3S}.env || true
  863. }
  864. # --- capture current env and create file containing k3s_ variables ---
  865. create_env_file() {
  866.     info "env: Creating environment file ${FILE_K3S_ENV}"
  867.     $SUDO touch ${FILE_K3S_ENV}
  868.     $SUDO chmod 0600 ${FILE_K3S_ENV}
  869.     sh -c export | while read x v; do echo $v; done | grep -E '^(K3S|CONTAINERD)_' | $SUDO tee ${FILE_K3S_ENV} >/dev/null
  870.     sh -c export | while read x v; do echo $v; done | grep -Ei '^(NO|HTTP|HTTPS)_PROXY' | $SUDO tee -a ${FILE_K3S_ENV} >/dev/null
  871. }
  872. # --- write systemd service file ---
  873. create_systemd_service_file() {
  874.     info "systemd: Creating service file ${FILE_K3S_SERVICE}"
  875.     $SUDO tee ${FILE_K3S_SERVICE} >/dev/null << EOF
  876. [Unit]
  877. Description=Lightweight Kubernetes
  878. Documentation=https://k3s.io
  879. Wants=network-online.target
  880. After=network-online.target
  881. [Install]
  882. WantedBy=multi-user.target
  883. [Service]
  884. Type=${SYSTEMD_TYPE}
  885. EnvironmentFile=-/etc/default/%N
  886. EnvironmentFile=-/etc/sysconfig/%N
  887. EnvironmentFile=-${FILE_K3S_ENV}
  888. KillMode=process
  889. Delegate=yes
  890. User=root
  891. # Having non-zero Limit*s causes performance problems due to accounting overhead
  892. # in the kernel. We recommend using cgroups to do container-local accounting.
  893. LimitNOFILE=1048576
  894. LimitNPROC=infinity
  895. LimitCORE=infinity
  896. TasksMax=infinity
  897. TimeoutStartSec=0
  898. Restart=always
  899. RestartSec=5s
  900. ExecStartPre=-/sbin/modprobe br_netfilter
  901. ExecStartPre=-/sbin/modprobe overlay
  902. ExecStart=${BIN_DIR}/k3s \\
  903.     ${CMD_K3S_EXEC}
  904. EOF
  905. }
  906. # --- write openrc service file ---
  907. create_openrc_service_file() {
  908.     LOG_FILE=/var/log/${SYSTEM_NAME}.log
  909.     info "openrc: Creating service file ${FILE_K3S_SERVICE}"
  910.     $SUDO tee ${FILE_K3S_SERVICE} >/dev/null << EOF
  911. #!/sbin/openrc-run
  912. depend() {
  913.     after network-online
  914.     want cgroups
  915. }
  916. start_pre() {
  917.     rm -f /tmp/k3s.*
  918. }
  919. supervisor=supervise-daemon
  920. name=${SYSTEM_NAME}
  921. command="${BIN_DIR}/k3s"
  922. command_args="$(escape_dq "${CMD_K3S_EXEC}")
  923.     >>${LOG_FILE} 2>&1"
  924. output_log=${LOG_FILE}
  925. error_log=${LOG_FILE}
  926. pidfile="/var/run/${SYSTEM_NAME}.pid"
  927. respawn_delay=5
  928. respawn_max=0
  929. set -o allexport
  930. if [ -f /etc/environment ]; then . /etc/environment; fi
  931. if [ -f ${FILE_K3S_ENV} ]; then . ${FILE_K3S_ENV}; fi
  932. set +o allexport
  933. EOF
  934.     $SUDO chmod 0755 ${FILE_K3S_SERVICE}
  935.     $SUDO tee /etc/logrotate.d/${SYSTEM_NAME} >/dev/null << EOF
  936. ${LOG_FILE} {
  937.         missingok
  938.         notifempty
  939.         copytruncate
  940. }
  941. EOF
  942. }
  943. # --- write systemd or openrc service file ---
  944. create_service_file() {
  945.     [ "${HAS_SYSTEMD}" = true ] && create_systemd_service_file && restore_systemd_service_file_context
  946.     [ "${HAS_OPENRC}" = true ] && create_openrc_service_file
  947.     return 0
  948. }
  949. restore_systemd_service_file_context() {
  950.     $SUDO restorecon -R -i ${FILE_K3S_SERVICE} 2>/dev/null || true
  951.     $SUDO restorecon -R -i ${FILE_K3S_ENV} 2>/dev/null || true
  952. }
  953. # --- get hashes of the current k3s bin and service files
  954. get_installed_hashes() {
  955.     $SUDO sha256sum ${BIN_DIR}/k3s ${FILE_K3S_SERVICE} ${FILE_K3S_ENV} 2>&1 || true
  956. }
  957. # --- enable and start systemd service ---
  958. systemd_enable() {
  959.     info "systemd: Enabling ${SYSTEM_NAME} unit"
  960.     $SUDO systemctl enable ${FILE_K3S_SERVICE} >/dev/null
  961.     $SUDO systemctl daemon-reload >/dev/null
  962. }
  963. systemd_start() {
  964.     info "systemd: Starting ${SYSTEM_NAME}"
  965.     $SUDO systemctl restart ${SYSTEM_NAME}
  966. }
  967. # --- enable and start openrc service ---
  968. openrc_enable() {
  969.     info "openrc: Enabling ${SYSTEM_NAME} service for default runlevel"
  970.     $SUDO rc-update add ${SYSTEM_NAME} default >/dev/null
  971. }
  972. openrc_start() {
  973.     info "openrc: Starting ${SYSTEM_NAME}"
  974.     $SUDO ${FILE_K3S_SERVICE} restart
  975. }
  976. has_working_xtables() {
  977.     if $SUDO sh -c "command -v "$1-save"" 1> /dev/null && $SUDO sh -c "command -v "$1-restore"" 1> /dev/null; then
  978.         if $SUDO $1-save 2>/dev/null | grep -q '^-A CNI-HOSTPORT-MASQ -j MASQUERADE$'; then
  979.             warn "Host $1-save/$1-restore tools are incompatible with existing rules"
  980.         else
  981.             return 0
  982.         fi
  983.     else
  984.         info "Host $1-save/$1-restore tools not found"
  985.     fi
  986.     return 1
  987. }
  988. # --- startup systemd or openrc service ---
  989. service_enable_and_start() {
  990.     if ! grep -qs memory /sys/fs/cgroup/cgroup.controllers && ! [ "$(grep -s memory /proc/cgroups | while read -r n n n enabled; do echo $enabled; done)" = "1" ]; then
  991.         info 'Failed to find memory cgroup, you may need to add "cgroup_memory=1 cgroup_enable=memory" to your linux cmdline (/boot/firmware/cmdline.txt on a Raspberry Pi)'
  992.     fi
  993.     [ "${INSTALL_K3S_SKIP_ENABLE}" = true ] && return
  994.     [ "${HAS_SYSTEMD}" = true ] && systemd_enable
  995.     [ "${HAS_OPENRC}" = true ] && openrc_enable
  996.     [ "${INSTALL_K3S_SKIP_START}" = true ] && return
  997.     POST_INSTALL_HASHES=$(get_installed_hashes)
  998.     if [ "${PRE_INSTALL_HASHES}" = "${POST_INSTALL_HASHES}" ] && [ "${INSTALL_K3S_FORCE_RESTART}" != true ]; then
  999.         info 'No change detected so skipping service start'
  1000.         return
  1001.     fi
  1002.     for XTABLES in iptables ip6tables; do
  1003.         if has_working_xtables ${XTABLES}; then
  1004.             $SUDO ${XTABLES}-save 2>/dev/null | grep -v KUBE- | grep -iv flannel | $SUDO ${XTABLES}-restore
  1005.         fi
  1006.     done
  1007.     [ "${HAS_SYSTEMD}" = true ] && systemd_start
  1008.     [ "${HAS_OPENRC}" = true ] && openrc_start
  1009.     return 0
  1010. }
  1011. # --- re-evaluate args to include env command ---
  1012. eval set -- $(escape "${INSTALL_K3S_EXEC}") $(quote "$@")
  1013. # --- run the install process --
  1014. {
  1015.     verify_system
  1016.     setup_env "$@"
  1017.     download_and_verify
  1018.     setup_selinux
  1019.     create_symlinks
  1020.     create_killall
  1021.     create_uninstall
  1022.     systemd_disable
  1023.     create_env_file
  1024.     create_service_file
  1025.     service_enable_and_start
  1026. }
复制代码
server-install.sh
  1. #!/bin/bash
  2. # K3s 服务器端安装脚本
  3. # 此脚本将在服务器上执行 k3s 安装
  4. set -e
  5. echo "=== K3s 离线安装脚本 ==="
  6. echo ""
  7. # 检查是否为 root 或有 sudo 权限
  8. if [ "$EUID" -ne 0 ] && ! sudo -n true 2>/dev/null; then
  9.     echo "错误: 需要 root 权限或 sudo 权限"
  10.     exit 1
  11. fi
  12. # 安装目录
  13. INSTALL_DIR="/tmp/k3s-install"
  14. echo "1. 检查文件..."
  15. cd "$INSTALL_DIR"
  16. if [ ! -f "k3s" ]; then
  17.     echo "错误: k3s 二进制文件不存在"
  18.     exit 1
  19. fi
  20. if [ ! -f "install.sh" ]; then
  21.     echo "错误: install.sh 不存在"
  22.     exit 1
  23. fi
  24. echo "✓ k3s: $(ls -lh k3s | awk '{print $5}')"
  25. echo "✓ install.sh: $(ls -lh install.sh | awk '{print $5}')"
  26. if [ -f "k3s-airgap-images-amd64.tar.gz" ]; then
  27.     echo "✓ k3s-airgap-images-amd64.tar.gz: $(ls -lh k3s-airgap-images-amd64.tar.gz | awk '{print $5}')"
  28.     HAS_IMAGES=true
  29. else
  30.     echo "⚠ 警告: 未找到镜像包,将使用在线模式(需要从网络拉取镜像)"
  31.     HAS_IMAGES=false
  32. fi
  33. echo ""
  34. echo "2. 准备安装..."
  35. # 创建镜像目录
  36. sudo mkdir -p /var/lib/rancher/k3s/agent/images/
  37. # 如果有镜像包,复制到指定位置
  38. if [ "$HAS_IMAGES" = true ]; then
  39.     echo "复制镜像包..."
  40.     sudo cp k3s-airgap-images-amd64.tar.gz /var/lib/rancher/k3s/agent/images/
  41. fi
  42. # 安装 k3s 二进制文件
  43. echo "安装 k3s 二进制文件..."
  44. sudo cp k3s /usr/local/bin/
  45. sudo chmod +x /usr/local/bin/k3s
  46. # 设置安装脚本权限
  47. chmod +x install.sh
  48. echo ""
  49. echo "3. 执行安装..."
  50. echo ""
  51. # 执行安装
  52. sudo INSTALL_K3S_SKIP_DOWNLOAD=true ./install.sh
  53. echo ""
  54. echo "=== 安装完成 ==="
  55. echo ""
  56. # 等待服务启动
  57. echo "等待 k3s 服务启动..."
  58. sleep 5
  59. # 检查服务状态
  60. echo ""
  61. echo "4. 验证安装..."
  62. echo ""
  63. sudo systemctl status k3s --no-pager || true
  64. echo ""
  65. echo "5. 检查节点状态..."
  66. echo ""
  67. sudo k3s kubectl get nodes
  68. echo ""
  69. echo "=== K3s 安装成功! ==="
  70. echo ""
  71. echo "常用命令:"
  72. echo "  查看服务状态: sudo systemctl status k3s"
  73. echo "  查看节点: sudo k3s kubectl get nodes"
  74. echo "  查看 pods: sudo k3s kubectl get pods -A"
  75. echo "  查看日志: sudo journalctl -u k3s -f"
  76. echo ""
复制代码
✅ 文件检查完成

所有文件已准备就绪:
文件名大小状态k3s66.12 MB✅ 完整install.sh0.03 MB✅ 完整server-install.sh0.00 MB✅ 完整k3s-airgap-images-amd64.tar.gz169.17 MB✅ 完整文件位置:D:\Documents\k3s-offline-install

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册