├── .vscode └── settings.json ├── scripts ├── install_deno.sh ├── centos-update-kernel.sh ├── requirement.sh ├── k3s_agent.sh ├── k3s_server.sh ├── start.sh └── setup.sh ├── LICENSE ├── README.md └── ingress-nginx └── controller-v1.3.0.yaml /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "deno.enable": true, 3 | "deno.lint": true, 4 | } 5 | -------------------------------------------------------------------------------- /scripts/install_deno.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | ldd=$(ldd --version | grep 'ldd (GNU libc) ' | head -n 1) 4 | lddver=${ldd:15} 5 | 6 | function version_lt() { test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" != "$1"; } 7 | 8 | if version_lt $lddver '2.18'; then 9 | mkdir /temp_down -p && cd /temp_down 10 | # wget https://ftp.gnu.org/gnu/glibc/glibc-2.18.tar.gz 11 | wget https://aliuq.oss-cn-beijing.aliyuncs.com/deno/glibc-2.18.tar.gz 12 | tar -zxvf glibc-2.18.tar.gz 13 | 14 | cd glibc-2.18 && mkdir build 15 | cd build 16 | ../configure --prefix=/usr --disable-profile --enable-add-ons --with-headers=/usr/include --with-binutils=/usr/bin 17 | make && make install 18 | 19 | cd ~ 20 | rm -rf /temp_down 21 | fi 22 | 23 | # curl -fsSL https://deno.land/x/install/install.sh | sh 24 | curl -fsSL https://x.deno.js.cn/install.sh | sh 25 | 26 | export DENO_INSTALL="/root/.deno" 27 | export PATH="$DENO_INSTALL/bin:$PATH" 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 liuq 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /scripts/centos-update-kernel.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | set -e 3 | # 4 | # Update kernel version 5 | # 6 | 7 | log() { 8 | echo -e "[INFO] [$(date "+%Y-%m-%d %H:%M:%S")] $1" 9 | } 10 | 11 | version_lt() { 12 | test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" != "$1"; 13 | } 14 | 15 | KERNEL_LIMIT_VERSION=5.4.205 16 | kernel_ver=$(uname -r | grep -oP "^[\d.]+") 17 | if version_lt $kernel_ver $KERNEL_LIMIT_VERSION; then 18 | log "The current version v$kernel_ver is less than v$KERNEL_LIMIT_VERSION" 19 | log "Start to update kernel" 20 | rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org 21 | rpm -Uvh https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm 22 | yum --disablerepo=\* --enablerepo=elrepo-kernel repolist 23 | yum --disablerepo=\"*\" --enablerepo=\"elrepo-kernel\" list available 24 | yum --disablerepo=\* --enablerepo=elrepo-kernel install kernel-ml -y 25 | sed -i \"s/GRUB_DEFAULT=saved/GRUB_DEFAULT=0/g\" /etc/default/grub 26 | grub2-mkconfig -o /boot/grub2/grub.cfg 27 | yum remove -y kernel-tools-libs.x86_64 kernel-tools.x86_64 28 | yum --disablerepo=\* --enablerepo=elrepo-kernel install -y kernel-ml-tools.x86_64 29 | reboot 30 | else 31 | log "The current version v$kernel_ver is greater than v$KERNEL_LIMIT_VERSION" 32 | log "No need to update kernel" 33 | fi 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # k3sup 2 | 3 | [WIP] 快速安装跨云厂商 K3S 集群 4 | 5 | ## 安装 6 | 7 | 默认 K3S 安装版本为 `v1.23.9+k3s1` 8 | 9 | ```bash 10 | # 安装 k3s server 11 | sh <(curl -fsSL https://raw.githubusercontent.com/aliuq/k3sup/master/scripts/start.sh) install \ 12 | --node-name server1 --verbose 13 | # 添加 K3S 节点 agent 14 | sh <(curl -fsSL https://raw.githubusercontent.com/aliuq/k3sup/master/scripts/start.sh) join \ 15 | --ip --node-name node1 --password --verbose 16 | # 添加 K3S 节点 server 17 | sh <(curl -fsSL https://raw.githubusercontent.com/aliuq/k3sup/master/scripts/start.sh) join \ 18 | --server --ip --node-name server2 --password --verbose 19 | 20 | # === 国内安装 === 21 | 22 | # 安装 k3s server 23 | sh <(curl -fsSL https://raw.llll.host/aliuq/k3sup/master/scripts/start.sh) install \ 24 | --node-name server1 --mirror --verbose 25 | # 添加 K3S 节点 agent 26 | sh <(curl -fsSL https://raw.llll.host/aliuq/k3sup/master/scripts/start.sh) join \ 27 | --ip --node-name node1 --password --mirror --verbose 28 | # 添加 K3S 节点 server 29 | sh <(curl -fsSL https://raw.llll.host/aliuq/k3sup/master/scripts/start.sh) join \ 30 | --server --ip --node-name server2 --password --mirror --verbose 31 | ``` 32 | 33 | ## Options 34 | 35 | ### install options 36 | 37 | * `--ip`: (可选)节点 IP 38 | * `--node-name`: (可选)节点名称 39 | * `--kernel`: (可选)内核版本, 默认为 `ml` 版本 40 | * `--k3s-version`: (可选)k3s 版本, 默认为标准版本 41 | * `--kilo-location`: (可选)kilo 区域, 默认为 `node-name` 42 | * `--mirror`: (可选)使用镜像 43 | * `--cri-dockerd`: (可选)启用 cri-dockerd,使用该选项时,需指定 `--k3s-version` 且需要大于 v1.24.0 版本 44 | * `--disable-docker`: (可选)禁用 docker 45 | * `--verbose`: (可选)显示详细信息 46 | * `--dry-run`: (可选)仅打印 k3s 安装命令 47 | * `-y`: (可选)确认所有选项 48 | 49 | ### join options 50 | 51 | * `--ip`: 节点 IP 52 | * `--node-name`: 节点名称 53 | * `--password`: 节点密码 54 | * `--server-ip`: (可选)k3s 服务器 IP 55 | * `--user`: (可选)节点用户名,默认为 `root` 56 | * `--ssh-key`: (可选)使用 ssh key 57 | * `--kernel`: (可选)内核版本, 默认为 `ml` 版本 58 | * `--k3s-version`: (可选)k3s 版本, 默认为标准版本 59 | * `--mirror`: (可选)使用镜像 60 | * `--server`: (可选)将节点作为 k3s server 61 | * `--cri-dockerd`: (可选)启用 cri-dockerd,使用该选项时,需指定 `--k3s-version` 且需要大于 v1.24.0 版本 62 | * `--disable-docker`: (可选)禁用 docker 63 | * `--verbose`: (可选)显示详细信息 64 | * `--dry-run`: (可选)仅打印 k3s 安装命令 65 | * `-y`: (可选)确认所有选项 66 | 67 | ## FAQ 68 | 69 | 安装过程根据网络情况,可能会花费一定时间,5~10分钟左右为正常现象,如果超过这个时间,请退出安装程序,并添加 `--verbose` 查看详细信息,如果确有错误信息,请提交 issue 70 | 71 | 由于国内网络问题,截止到2022/08/05,如果使用 `v1.24` 以上版本,此后的版本无法拉取镜像`k8s.gcr.io/pause:xxx`,所以会导致安装命令一直在等待中,此时推荐在等待10s之后关闭安装程序,然后执行以下命令 72 | 73 | ```bash 74 | # 首先需要知道是哪个版本的镜像无法拉取 75 | kubectl get pod -n kube-system | grep kilo- | awk '{print $1}' | xargs kubectl describe -n kube-system pod | grep 'failed pulling image' 76 | # 出现下面的错误,则说明镜像拉取失败,需要手动拉取镜像,保证版本一致 77 | # error: code = Unknown desc = failed pulling image "k8s.gcr.io/pause:3.6" 78 | 79 | # 利用镜像拉取 pause 80 | docker pull registry.aliyuncs.com/google_containers/pause:3.6 81 | # 镜像重命名 82 | docker tag registry.aliyuncs.com/google_containers/pause:3.6 k8s.gcr.io/pause:3.6 83 | # 删除旧镜像 84 | docker rmi registry.aliyuncs.com/google_containers/pause:3.6 85 | ``` 86 | 87 | ## 参考链接 88 | 89 | * [跨云厂商部署 k3s 集群](https://icloudnative.io/posts/deploy-k3s-cross-public-cloud) 90 | * [基于 K3S+WireGuard+Kilo 搭建跨多云的统一 K8S 集群](https://cloud.tencent.com/developer/article/1985806) 91 | 92 | ## License 93 | 94 | [MIT](./LICENSE) 95 | -------------------------------------------------------------------------------- /scripts/requirement.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | set -e 3 | 4 | # Check requirements for server and agent 5 | # kernel(minimum version: 5.4.205)、docker、kubectl、wireguard 6 | # 7 | # Usage: 8 | # curl -fsSL https://raw.githubusercontent.com/aliuq/k3sup/master/scripts/requirement.sh | sh 9 | # 10 | # Mirror of China: 11 | # curl -fsSL https://raw.fastgit.org/aliuq/k3sup/master/scripts/requirement.sh | sh -s - --mirror 12 | # 13 | 14 | verbose=false 15 | mirror=false 16 | kernel="ml" 17 | while [ $# -gt 0 ]; do 18 | case "$1" in 19 | --mirror) mirror=true ;; 20 | --verbose) verbose=true ;; 21 | --kernel) kernel="$2" shift ;; 22 | --*) echo "Illegal option $1" ;; 23 | esac 24 | shift $(($# > 0 ? 1 : 0)) 25 | done 26 | 27 | log() { 28 | echo -e "\033[36m[INFO] $(date "+%Y-%m-%d %H:%M:%S")\033[0m $@" 29 | } 30 | 31 | echo_title() { 32 | echo -e "\033[36m[INFO] $(date "+%Y-%m-%d %H:%M:%S")\033[0m \033[92m===== $@ =====\033[0m" 33 | } 34 | 35 | command_exists() { 36 | command -v "$@" >/dev/null 2>&1 37 | } 38 | 39 | version_lt() { 40 | test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" != "$1"; 41 | } 42 | 43 | set_var() { 44 | user="$(id -un 2>/dev/null || true)" 45 | sh_c="sh -c" 46 | if [ "$user" != "root" ]; then 47 | if command_exists sudo; then 48 | sh_c="sudo -E sh -c" 49 | elif command_exists su; then 50 | sh_c="su -c" 51 | else 52 | cat >&2 <<-EOF 53 | Error: this installer needs the ability to run commands as root. 54 | We are unable to find either "sudo" or "su" available to make this happen. 55 | EOF 56 | exit 1 57 | fi 58 | fi 59 | 60 | if [ $kernel != "ml" ] && [ $kernel != "lt" ]; then 61 | kernel="ml" 62 | fi 63 | 64 | suf="" 65 | if ! $verbose; then 66 | suf=">/dev/null 2>&1" 67 | else 68 | set -x 69 | fi 70 | } 71 | 72 | # Update kernel to required version(minimum v5.4.205) 73 | # When updated, it will be reboot the system 74 | update_kernel() { 75 | echo_title "Update Kernel" 76 | KERNEL_LIMIT_VERSION=5.4.205 77 | kernel_ver=$(uname -r | grep -oP '^[\d.]+') 78 | if version_lt $kernel_ver $KERNEL_LIMIT_VERSION; then 79 | log "Your kernel version is $kernel_ver, we need $KERNEL_LIMIT_VERSION or above" 80 | log "Start Updating, please wait...(\033[5mneed few minutes and reboot required\033[0m)" 81 | $sh_c "rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org $suf" 82 | $sh_c "rpm -Uvh https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm $suf" 83 | $sh_c "yum --disablerepo=\* --enablerepo=elrepo-kernel install kernel-$kernel -y $suf" 84 | $sh_c "sed -i 's/GRUB_DEFAULT=saved/GRUB_DEFAULT=0/g' /etc/default/grub $suf" 85 | $sh_c "grub2-mkconfig -o /boot/grub2/grub.cfg $suf" 86 | $sh_c "yum remove -y kernel-tools-libs.x86_64 kernel-tools.x86_64 $suf" 87 | $sh_c "yum --disablerepo=\* --enablerepo=elrepo-kernel install -y kernel-$kernel-tools.x86_64 $suf" 88 | log "Successfully updated kernel, after rebooted, rerun this script" 89 | $sh_c "reboot" 90 | else 91 | log "No need to update kernel, your kernel version is v$kernel_ver" 92 | fi 93 | } 94 | 95 | # Install docker 96 | install_doker() { 97 | echo_title "Install Docker" 98 | if command_exists docker; then 99 | docker_version=$(docker version | grep -oP 'Version:\s+\K[\d.]+' | head -n 1) 100 | log "Docker already installed with version v$docker_version" 101 | else 102 | log "Start installing docker" 103 | if $mirror; then 104 | # $sh_c "curl -fsSL https://get.daocloud.io/docker | sh $suf" 105 | $sh_c "curl -fsSL https://get.docker.com | sh -s - --mirror Aliyun $suf" 106 | else 107 | $sh_c "curl -fsSL https://get.docker.com | sh $suf" 108 | fi 109 | $sh_c "systemctl enable --now docker $suf" 110 | $sh_c "docker version $suf" 111 | docker_version=$(docker version | grep -oP 'Version:\s+\K[\d.]+' | head -n 1) 112 | log "Successfully installed docker, version v$docker_version" 113 | fi 114 | } 115 | 116 | # Install kubectl 117 | install_kubectl() { 118 | echo_title "Install Kubectl" 119 | if command_exists kubectl; then 120 | kubectl_version=$(kubectl version --client --output=yaml | grep -oP 'gitVersion:\s+v\K[\d.]+') 121 | log "Kubectl already installed with version v$kubectl_version" 122 | else 123 | log "Start installing kubectl" 124 | kubectl_latest=$(curl -fsSL https://dl.k8s.io/release/stable.txt) 125 | $sh_c "curl -fsSLO https://dl.k8s.io/release/$kubectl_latest/bin/linux/amd64/kubectl $suf" 126 | $sh_c "curl -fsSLO https://dl.k8s.io/$kubectl_latest/bin/linux/amd64/kubectl.sha256 $suf" 127 | $sh_c "echo \"$(cat kubectl.sha256) kubectl\" | sha256sum --check $suf" 128 | $sh_c "sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl $suf" 129 | $sh_c "kubectl version --client --output=yaml $suf" 130 | kubectl_version=$(kubectl version --client --output=yaml | grep -oP 'gitVersion:\s+v\K[\d.]+') 131 | log "Successfully installed kubectl, version v$kubectl_version" 132 | fi 133 | } 134 | 135 | # Install wireguard(CNI plugin) 136 | install_wireguard() { 137 | echo_title "Install Wireguard" 138 | if command_exists wg; then 139 | wg_version=$(wg --version | grep -oP 'v\K[\d.]+') 140 | log "Wireguard already installed with version v$wg_version" 141 | else 142 | log "Start installing wireguard" 143 | $sh_c "yum install epel-release https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm -y $suf" 144 | $sh_c "yum install yum-plugin-elrepo -y $suf" 145 | $sh_c "yum install kmod-wireguard wireguard-tools -y $suf" 146 | wg_version=$(wg --version | grep -oP 'v\K[\d.]+') 147 | log "Successfully installed wireguard, version v$wg_version" 148 | fi 149 | } 150 | 151 | do_start() { 152 | set_var 153 | update_kernel 154 | install_doker 155 | install_kubectl 156 | install_wireguard 157 | log "Successfully installed all requirements" 158 | } 159 | 160 | do_start 161 | -------------------------------------------------------------------------------- /scripts/k3s_agent.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | set -e 3 | 4 | # Install k3s agent 5 | # This script is mainly executed after ssh remote login, and is not recommended to be used alone. 6 | # 7 | 8 | verbose=false 9 | mirror=false 10 | use_docker=true 11 | cri_dockerd=false 12 | dry_run=false 13 | as_server=false 14 | k3s_version="v1.23.9+k3s1" 15 | node_name="" 16 | ip="" 17 | k3s_url="" 18 | k3s_token="" 19 | while [ $# -gt 0 ]; do 20 | case "$1" in 21 | --mirror) mirror=true ;; 22 | --verbose) verbose=true ;; 23 | --disable-docker) use_docker=false ;; 24 | --cri-dockerd) cri_dockerd=true ;; 25 | --dry-run) dry_run=true ;; 26 | --ip) ip="$2" shift ;; 27 | --server) as_server=true ;; 28 | --k3s-version) k3s_version="$2" shift ;; 29 | --node-name) node_name="$2" shift ;; 30 | --k3s-url) k3s_url="$2" shift ;; 31 | --k3s-token) k3s_token="$2" shift ;; 32 | --*) echo "Illegal option $1" ;; 33 | esac 34 | shift $(($# > 0 ? 1 : 0)) 35 | done 36 | 37 | if $mirror; then 38 | HUB_URL=${HUB_URL:-"https://hub.llll.host"} 39 | RAW_URL=${RAW_URL:-"https://raw.llll.host"} 40 | else 41 | HUB_URL="https://github.com" 42 | RAW_URL="https://raw.githubusercontent.com" 43 | fi 44 | 45 | log() { 46 | echo -e "\033[36m[INFO] $(date "+%Y-%m-%d %H:%M:%S")\033[0m $@" 47 | } 48 | 49 | echo_title() { 50 | echo -e "\033[36m[INFO] $(date "+%Y-%m-%d %H:%M:%S")\033[0m \033[92m===== $@ =====\033[0m" 51 | } 52 | 53 | command_exists() { 54 | command -v "$@" >/dev/null 2>&1 55 | } 56 | 57 | set_var() { 58 | user="$(id -un 2>/dev/null || true)" 59 | sh_c="sh -c" 60 | if [ "$user" != "root" ]; then 61 | if command_exists sudo; then 62 | sh_c="sudo -E sh -c" 63 | elif command_exists su; then 64 | sh_c="su -c" 65 | else 66 | cat >&2 <<-EOF 67 | Error: this installer needs the ability to run commands as root. 68 | We are unable to find either "sudo" or "su" available to make this happen. 69 | EOF 70 | exit 1 71 | fi 72 | fi 73 | 74 | suf="" 75 | if ! $verbose; then 76 | suf=">/dev/null 2>&1" 77 | else 78 | set -x 79 | fi 80 | } 81 | 82 | waitNodeReady() { 83 | starting=true; 84 | while $starting; do 85 | [[ $(k3s kubectl get nodes "$1" | awk '$2 == "Ready" {print $2}') == "Ready" ]] && starting=false; 86 | sleep 1; 87 | done 88 | } 89 | 90 | # Install cri-dockerd, k3s 1.24.0+ required 91 | # https://github.com/Mirantis/cri-dockerd 92 | install_cri_dockerd() { 93 | echo_title "Install cri-dockerd" 94 | if command_exists cri-dockerd; then 95 | cri_version=$(cri-dockerd --version 2>&1 | awk '{print $2}') 96 | log "cri-dockerd already installed with version v$cri_version" 97 | else 98 | lt_version=$(curl --connect-timeout 5 -m 5 -fsSL https://api.github.com/repos/Mirantis/cri-dockerd/releases/latest | grep -oP 'tag_name": "v\K[\d.]+' || echo "0.2.3") 99 | log "Start installing cri-dockerd" 100 | $sh_c "wget $HUB_URL/Mirantis/cri-dockerd/releases/download/v$lt_version/cri-dockerd-$lt_version.amd64.tgz -O cri-dockerd.tgz $suf" 101 | $sh_c "tar -xvf cri-dockerd.tgz $suf" 102 | $sh_c "cp ./cri-dockerd/cri-dockerd /usr/local/bin/" 103 | if [ $? != 0 ]; then 104 | log "\033[0;31mFailed to install cri-dockerd\033[0m" 105 | exit 1 106 | fi 107 | $sh_c "wget $RAW_URL/Mirantis/cri-dockerd/master/packaging/systemd/cri-docker.service $suf" 108 | $sh_c "wget $RAW_URL/Mirantis/cri-dockerd/master/packaging/systemd/cri-docker.socket $suf" 109 | $sh_c "cp -a cri-docker.* /etc/systemd/system/" 110 | $sh_c "sed -i -e 's,/usr/bin/cri-dockerd,/usr/local/bin/cri-dockerd,' /etc/systemd/system/cri-docker.service" 111 | $sh_c "systemctl daemon-reload" 112 | $sh_c "systemctl enable --now cri-docker.service $suf" 113 | $sh_c "systemctl enable --now cri-docker.socket $suf" 114 | cri_version=$(cri-dockerd --version 2>&1 | awk '{print $2}') 115 | log "Successfully installed cri-dockerd, version v$cri_version" 116 | fi 117 | } 118 | 119 | # Install k3s as a agent ndoe 120 | install_k3s_agent() { 121 | echo_title "Install K3S as a agent" 122 | if command_exists k3s; then 123 | log "K3S already installed with version v$(k3s -v | grep -oP 'k3s version\s+v\K.*')" 124 | else 125 | log "Start installing k3s" 126 | k3s_run_str="curl -fsSL" 127 | if $mirror; then 128 | k3s_run_str="$k3s_run_str https://rancher-mirror.oss-cn-beijing.aliyuncs.com/k3s/k3s-install.sh" 129 | k3s_run_str="$k3s_run_str | INSTALL_K3S_MIRROR=cn" 130 | else 131 | k3s_run_str="$k3s_run_str https://get.k3s.io |" 132 | fi 133 | k3s_run_str="$k3s_run_str INSTALL_K3S_VERSION=$k3s_version K3S_URL=$k3s_url K3S_TOKEN=$k3s_token sh -s -" 134 | if $as_server; then 135 | k3s_run_str="$k3s_run_str server --cluster-init" 136 | else 137 | k3s_run_str="$k3s_run_str agent" 138 | fi 139 | agent_name="$(hostname)" 140 | if [ $node_name ]; then 141 | agent_name="$node_name" 142 | fi 143 | k3s_run_str="$k3s_run_str --node-name $agent_name" 144 | if $use_docker; then 145 | if $cri_dockerd; then 146 | if ! $dry_run; then 147 | install_cri_dockerd 148 | fi 149 | k3s_run_str="$k3s_run_str --container-runtime-endpoint unix:///var/run/cri-dockerd.sock" 150 | else 151 | k3s_run_str="$k3s_run_str --docker" 152 | fi 153 | fi 154 | if $as_server; then 155 | k3s_run_str="$k3s_run_str --tls-san $ip --flannel-backend none" 156 | fi 157 | k3s_run_str="$k3s_run_str --node-external-ip $ip --kube-proxy-arg metrics-bind-address=0.0.0.0" 158 | if $dry_run; then 159 | log "k3s run command: \033[33m$k3s_run_str\033[0m" 160 | exit 2 161 | else 162 | $sh_c "$k3s_run_str $suf" 163 | if [ $? != 0 ]; then 164 | log "\033[31mFailed to start k3s agent service, please rerun this script with --verbose to see details info\033[0m" 165 | exit 1 166 | fi 167 | fi 168 | log "Successfully installed k3s" 169 | if $as_server; then 170 | $sh_c "mkdir ~/.kube -p && ln /etc/rancher/k3s/k3s.yaml ~/.kube/config && chmod 600 ~/.kube/config $suf" 171 | log "Successfully added k3s to the PATH" 172 | fi 173 | fi 174 | } 175 | 176 | do_start() { 177 | set_var 178 | install_k3s_agent 179 | } 180 | 181 | do_start 182 | -------------------------------------------------------------------------------- /scripts/k3s_server.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | set -e 3 | 4 | # Install k3s server 5 | 6 | GET_IP_URL=${GET_IP_URL:-"ip.llll.host"} 7 | 8 | verbose=false 9 | mirror=false 10 | use_docker=true 11 | cri_dockerd=false 12 | kilo_location="" 13 | k3s_version="v1.23.9+k3s1" 14 | node_name="" 15 | ip="" 16 | dry_run=false 17 | while [ $# -gt 0 ]; do 18 | case "$1" in 19 | --mirror) mirror=true ;; 20 | --verbose) verbose=true ;; 21 | --disable-docker) use_docker=false ;; 22 | --cri-dockerd) cri_dockerd=true ;; 23 | --dry-run) dry_run=true ;; 24 | --ip) ip="$2" shift ;; 25 | --k3s-version) k3s_version="$2" shift ;; 26 | --node-name) node_name="$2" shift ;; 27 | --kilo-location) kilo_location="$2" shift ;; 28 | --*) echo "Illegal option $1" ;; 29 | esac 30 | shift $(($# > 0 ? 1 : 0)) 31 | done 32 | 33 | if [ ! $ip ]; then 34 | ip=$(curl -fsSL $GET_IP_URL) 35 | if [ $? != 0 ]; then 36 | echo "Failed to get ip from $GET_IP_URL, please input ip manually!" 37 | exit 1 38 | fi 39 | fi 40 | 41 | if $mirror; then 42 | HUB_URL=${HUB_URL:-"https://hub.llll.host"} 43 | RAW_URL=${RAW_URL:-"https://raw.llll.host"} 44 | else 45 | HUB_URL="https://github.com" 46 | RAW_URL="https://raw.githubusercontent.com" 47 | fi 48 | 49 | log() { 50 | echo -e "\033[36m[INFO] $(date "+%Y-%m-%d %H:%M:%S")\033[0m $@" 51 | } 52 | 53 | echo_title() { 54 | echo -e "\033[36m[INFO] $(date "+%Y-%m-%d %H:%M:%S")\033[0m \033[92m===== $@ =====\033[0m" 55 | } 56 | 57 | command_exists() { 58 | command -v "$@" >/dev/null 2>&1 59 | } 60 | 61 | set_var() { 62 | user="$(id -un 2>/dev/null || true)" 63 | sh_c="sh -c" 64 | if [ "$user" != "root" ]; then 65 | if command_exists sudo; then 66 | sh_c="sudo -E sh -c" 67 | elif command_exists su; then 68 | sh_c="su -c" 69 | else 70 | cat >&2 <<-EOF 71 | Error: this installer needs the ability to run commands as root. 72 | We are unable to find either "sudo" or "su" available to make this happen. 73 | EOF 74 | exit 1 75 | fi 76 | fi 77 | 78 | suf="" 79 | if ! $verbose; then 80 | suf=">/dev/null 2>&1" 81 | else 82 | set -x 83 | fi 84 | } 85 | 86 | waitNodeReady() { 87 | starting=true; 88 | while $starting; do 89 | [[ $(k3s kubectl get nodes "$1" | awk '$2 == "Ready" {print $2}') == "Ready" ]] && starting=false; 90 | sleep 1; 91 | done 92 | } 93 | 94 | # Install cri-dockerd, k3s 1.24.0+ required 95 | # https://github.com/Mirantis/cri-dockerd 96 | install_cri_dockerd() { 97 | echo_title "Install cri-dockerd" 98 | if command_exists cri-dockerd; then 99 | cri_version=$(cri-dockerd --version 2>&1 | awk '{print $2}') 100 | log "cri-dockerd already installed with version v$cri_version" 101 | else 102 | lt_version=$(curl --connect-timeout 5 -m 5 -fsSL https://api.github.com/repos/Mirantis/cri-dockerd/releases/latest | grep -oP 'tag_name": "v\K[\d.]+' || echo "0.2.3") 103 | log "Start installing cri-dockerd" 104 | $sh_c "wget $HUB_URL/Mirantis/cri-dockerd/releases/download/v$lt_version/cri-dockerd-$lt_version.amd64.tgz -O cri-dockerd.tgz $suf" 105 | $sh_c "tar -xvf cri-dockerd.tgz $suf" 106 | $sh_c "cp ./cri-dockerd/cri-dockerd /usr/local/bin/" 107 | if [ $? != 0 ]; then 108 | log "\033[0;31mFailed to install cri-dockerd\033[0m" 109 | exit 1 110 | fi 111 | $sh_c "wget $RAW_URL/Mirantis/cri-dockerd/master/packaging/systemd/cri-docker.service $suf" 112 | $sh_c "wget $RAW_URL/Mirantis/cri-dockerd/master/packaging/systemd/cri-docker.socket $suf" 113 | $sh_c "cp -a cri-docker.* /etc/systemd/system/" 114 | $sh_c "sed -i -e 's,/usr/bin/cri-dockerd,/usr/local/bin/cri-dockerd,' /etc/systemd/system/cri-docker.service" 115 | $sh_c "systemctl daemon-reload" 116 | $sh_c "systemctl enable --now cri-docker.service $suf" 117 | $sh_c "systemctl enable --now cri-docker.socket $suf" 118 | cri_version=$(cri-dockerd --version 2>&1 | awk '{print $2}') 119 | log "Successfully installed cri-dockerd, version v$cri_version" 120 | fi 121 | } 122 | 123 | # Install k3s as a server ndoe 124 | install_k3s_server() { 125 | echo_title "Install K3S server" 126 | if command_exists k3s; then 127 | log "K3S already installed with version v$(k3s -v | grep -oP 'k3s version\s+v\K.*')" 128 | else 129 | log "Start installing k3s" 130 | k3s_run_str="curl -fsSL" 131 | if $mirror; then 132 | k3s_run_str="$k3s_run_str https://rancher-mirror.oss-cn-beijing.aliyuncs.com/k3s/k3s-install.sh" 133 | k3s_run_str="$k3s_run_str | INSTALL_K3S_MIRROR=cn" 134 | else 135 | k3s_run_str="$k3s_run_str https://get.k3s.io |" 136 | fi 137 | k3s_run_str="$k3s_run_str INSTALL_K3S_VERSION=$k3s_version sh -s - server --cluster-init" 138 | 139 | master_name="$(hostname)" 140 | if [ $node_name ]; then 141 | master_name="$node_name" 142 | fi 143 | k3s_run_str="$k3s_run_str --node-name $master_name" 144 | if $use_docker; then 145 | if $cri_dockerd; then 146 | if ! $dry_run; then 147 | install_cri_dockerd 148 | fi 149 | k3s_run_str="$k3s_run_str --container-runtime-endpoint unix:///var/run/cri-dockerd.sock" 150 | else 151 | k3s_run_str="$k3s_run_str --docker" 152 | fi 153 | fi 154 | k3s_run_str="$k3s_run_str --tls-san $ip --node-external-ip $ip --flannel-backend none" 155 | k3s_run_str="$k3s_run_str --kube-proxy-arg metrics-bind-address=0.0.0.0" 156 | if $dry_run; then 157 | log "k3s run command: \033[33m$k3s_run_str\033[0m" 158 | exit 2 159 | else 160 | $sh_c "$k3s_run_str $suf" 161 | if [ $? != 0 ]; then 162 | log "\033[31mFailed to start k3s service, please rerun this script with --verbose to see details info\033[0m" 163 | exit 1 164 | fi 165 | fi 166 | sleep 10 167 | log "Successfully installed k3s" 168 | $sh_c "mkdir ~/.kube -p && ln /etc/rancher/k3s/k3s.yaml ~/.kube/config && chmod 600 ~/.kube/config $suf" 169 | log "Successfully added k3s to the PATH" 170 | k_loc=$master_name 171 | if [ $kilo_location ]; then k_loc=$kilo_location; fi 172 | $sh_c "k3s kubectl annotate node $master_name kilo.squat.ai/location=$k_loc $suf" 173 | $sh_c "k3s kubectl annotate node $master_name kilo.squat.ai/force-endpoint=$ip:51820 $suf" 174 | $sh_c "k3s kubectl annotate node $master_name kilo.squat.ai/persistent-keepalive=20 $suf" 175 | log "Successfully added kilo annotates" 176 | $sh_c "k3s kubectl apply -f $RAW_URL/squat/kilo/main/manifests/crds.yaml $suf" 177 | $sh_c "k3s kubectl apply -f $RAW_URL/squat/kilo/main/manifests/kilo-k3s.yaml $suf" 178 | log "Successfully applied kilo manifests" 179 | log "Waiting for k3s to be ready" 180 | waitNodeReady $master_name 181 | fi 182 | } 183 | 184 | do_start() { 185 | set_var 186 | install_k3s_server 187 | } 188 | 189 | do_start 190 | -------------------------------------------------------------------------------- /scripts/start.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | set -e 3 | 4 | # Deploy k3s script 5 | # 6 | 7 | clear 8 | 9 | GET_IP_URL=${GET_IP_URL:-"ip.llll.host"} 10 | 11 | ip="" 12 | mirror=false 13 | node_name="" 14 | user="root" 15 | password="" 16 | server_ip="" 17 | ssh_key="" 18 | k3s_version="v1.23.9+k3s1" 19 | verbose=false 20 | force=false 21 | kernel="ml" 22 | kilo_location="" 23 | use_docker=true 24 | cri_dockerd=false 25 | as_server=false 26 | dry_run=false 27 | 28 | command_name=$1 29 | while [ $# -gt 1 ]; do 30 | case "$2" in 31 | --mirror) mirror=true ;; 32 | --verbose) verbose=true ;; 33 | --dry-run) dry_run=true ;; 34 | --kernel) kernel="$3" shift ;; 35 | --ip) ip="$3" shift ;; 36 | --server-ip) server_ip="$3" shift ;; 37 | --user) user="$3" shift ;; 38 | --password) password="$3" shift ;; 39 | --ssh-key) ssh_key="$3" ;; 40 | --k3s-version) k3s_version="$3" shift ;; 41 | --node-name) node_name="$3" shift ;; 42 | --kilo-location) kilo_location="$3" shift ;; 43 | --cri-dockerd) cri_dockerd=true ;; 44 | --disable-docker) use_docker=false ;; 45 | --server) as_server=true ;; 46 | -y) force=true ;; 47 | --*) echo "Illegal option $2" ;; 48 | esac 49 | shift $(($# > 1 ? 1 : 0)) 50 | done 51 | 52 | if $mirror; then 53 | HUB_URL=${HUB_URL:-"https://hub.llll.host"} 54 | RAW_URL=${RAW_URL:-"https://raw.llll.host"} 55 | else 56 | HUB_URL="https://github.com" 57 | RAW_URL="https://raw.githubusercontent.com" 58 | fi 59 | 60 | log() { 61 | echo -e "\033[36m[INFO] $(date "+%Y-%m-%d %H:%M:%S")\033[0m $@" 62 | } 63 | 64 | echo_title() { 65 | echo -e "\033[36m[INFO] $(date "+%Y-%m-%d %H:%M:%S")\033[0m \033[92m===== $@ =====\033[0m" 66 | } 67 | 68 | command_exists() { 69 | command -v "$@" >/dev/null 2>&1 70 | } 71 | 72 | set_var() { 73 | user="$(id -un 2>/dev/null || true)" 74 | sh_c="sh -c" 75 | if [ "$user" != "root" ]; then 76 | if command_exists sudo; then 77 | sh_c="sudo -E sh -c" 78 | elif command_exists su; then 79 | sh_c="su -c" 80 | else 81 | cat >&2 <<-EOF 82 | Error: this installer needs the ability to run commands as root. 83 | We are unable to find either "sudo" or "su" available to make this happen. 84 | EOF 85 | exit 1 86 | fi 87 | fi 88 | 89 | suf="" 90 | if ! $verbose; then 91 | suf=">/dev/null 2>&1" 92 | else 93 | set -x 94 | fi 95 | } 96 | 97 | waitNodeReady() { 98 | starting=true; 99 | while $starting; do 100 | [[ $(k3s kubectl get nodes "$1" | awk '$2 == "Ready" {print $2}') == "Ready" ]] && starting=false; 101 | sleep 1; 102 | done 103 | } 104 | 105 | do_install() { 106 | set_var 107 | if [ $kernel != "ml" ] && [ $kernel != "lt" ]; then kernel="ml"; fi 108 | requirement_param="--kernel $kernel" 109 | k3s_param="" 110 | if $mirror; then 111 | requirement_param="$requirement_param --mirror" 112 | k3s_param="$k3s_param --mirror" 113 | fi 114 | if $verbose; then 115 | requirement_param="$requirement_param --verbose" 116 | k3s_param="$k3s_param --verbose" 117 | fi 118 | curl -fsSL "$RAW_URL/aliuq/k3sup/master/scripts/requirement.sh" | sh -s - $requirement_param 119 | if [ $? != 0 ]; then 120 | log "\033[31mFailed to install requirements\033[0m" 121 | exit 1 122 | fi 123 | if ! $use_docker; then k3s_param="$k3s_param --disable-docker"; fi 124 | if $cri_dockerd; then k3s_param="$k3s_param --cri-dockerd"; fi 125 | if $dry_run; then k3s_param="$k3s_param --dry-run"; fi 126 | if [ $kilo_location ]; then k3s_param="$k3s_param --kilo-location $kilo_location"; fi 127 | if [ $k3s_version ]; then k3s_param="$k3s_param --k3s-version $k3s_version"; fi 128 | if [ $node_name ]; then k3s_param="$k3s_param --node-name $node_name"; fi 129 | if [ $ip ]; then k3s_param="$k3s_param --ip $ip"; fi 130 | curl -fsSL "$RAW_URL/aliuq/k3sup/master/scripts/k3s_server.sh" | sh -s - $k3s_param 131 | if [ $? != 0 ]; then 132 | log "\033[31mFailed to start k3s service\033[0m" 133 | exit 1 134 | fi 135 | log "\033[92mDone\033[0m" 136 | } 137 | 138 | do_join() { 139 | if [ ! $ip ]; then 140 | log "\033[31mIP address is required\033[0m" 141 | exit 1 142 | fi 143 | if [ ! $node_name ]; then 144 | log "\033[31mNode name is required\033[0m" 145 | exit 1 146 | fi 147 | if [ ! $password ]; then 148 | log "\033[31mPassword is required\033[0m" 149 | exit 1 150 | fi 151 | 152 | set_var 153 | if [ $kernel != "ml" ] && [ $kernel != "lt" ]; then kernel="ml"; fi 154 | 155 | echo_title "Check sshpass" 156 | if command_exists sshpass; then 157 | sshpass_version=$(sshpass -V | grep -oP 'sshpass\s+\K[\d.]+') 158 | log "sshpass already installed with version v$sshpass_version" 159 | else 160 | log "Start installing sshpass" 161 | $sh_c "yum install sshpass -y $suf" 162 | log "Successfully installed sshpass" 163 | fi 164 | 165 | if [ ! $server_ip ]; then 166 | server_ip=$(curl -fsSL $GET_IP_URL) 167 | if [ $? != 0 ]; then 168 | echo "Failed to get server ip from $GET_IP_URL, please input server ip manually!" 169 | exit 1 170 | fi 171 | fi 172 | 173 | echo_title "Connectcion to $ip" 174 | if [ ! $ssh_key ]; then 175 | name=$(echo "$server_ip" | sed s/\\./_/g) 176 | secrect="$HOME/.ssh/$name" 177 | if [ -a "$secrect" ]; then 178 | log "\033[33mThe ssh key $name already exists in $secrect\033[0m" 179 | else 180 | log "\033[33mThe ssh key not found and will be generated automatically\033[0m" 181 | ssh-keygen -t ed25519 -f $secrect -N "" -q 182 | log "Successfully generated ssh key $name in $secrect" 183 | fi 184 | else 185 | secrect="$ssh_key" 186 | if [ ! -a "$secrect" ]; then 187 | log "\033[31mThe ssh key $secrect not found\033[0m" 188 | exit 1 189 | fi 190 | fi 191 | 192 | log "Start copying public key $secrect.pub to $ip" 193 | option="-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" 194 | $sh_c "sshpass -p "\'$password\'" ssh-copy-id -i $secrect.pub $option $user@$ip $suf" 195 | sed_str="sed -i 's/^#\?PubkeyAuthentication \(yes\|no\)$/PubkeyAuthentication yes/g' /etc/ssh/sshd_config" 196 | $sh_c "sshpass -p "\'$password\'" ssh $option $user@$ip \"$sed_str && systemctl restart sshd\" $suf" 197 | sshr="ssh -i $secrect -o ConnectTimeout=60 $option $user@$ip export TERM=xterm-256color;" 198 | 199 | k3s_url="https://$server_ip:6443" 200 | k3s_token=$(cat /var/lib/rancher/k3s/server/node-token) 201 | if [ $? != 0 ]; then 202 | log "\033[31mFailed to get k3s token.\033[0m" 203 | exit 1 204 | fi 205 | 206 | requirement_param="--kernel $kernel" 207 | k3s_param="--k3s-url $k3s_url --k3s-token $k3s_token" 208 | if $mirror; then 209 | requirement_param="$requirement_param --mirror" 210 | k3s_param="$k3s_param --mirror" 211 | fi 212 | if $verbose; then 213 | requirement_param="$requirement_param --verbose" 214 | k3s_param="$k3s_param --verbose" 215 | fi 216 | 217 | $sshr "curl -fsSL $RAW_URL/aliuq/k3sup/master/scripts/requirement.sh | sh -s - $requirement_param" 218 | if [ $? != 0 ]; then 219 | log "\033[31mFailed to install requirements\033[0m" 220 | exit 1 221 | fi 222 | if ! $use_docker; then k3s_param="$k3s_param --disable-docker"; fi 223 | if $cri_dockerd; then k3s_param="$k3s_param --cri-dockerd"; fi 224 | if $dry_run; then k3s_param="$k3s_param --dry-run"; fi 225 | if $as_server; then k3s_param="$k3s_param --server"; fi 226 | if [ $k3s_version ]; then k3s_param="$k3s_param --k3s-version $k3s_version"; fi 227 | if [ $node_name ]; then k3s_param="$k3s_param --node-name $node_name"; fi 228 | if [ $ip ]; then k3s_param="$k3s_param --ip $ip"; fi 229 | $sshr "curl -fsSL $RAW_URL/aliuq/k3sup/master/scripts/k3s_agent.sh | sh -s - $k3s_param" 230 | if [ $? != 0 ]; then 231 | log "\033[31mConnection to $ip closed\033[0m" 232 | exit 1 233 | fi 234 | 235 | if $use_docker && ! $cri_dockerd && ! $as_server; then 236 | sleep 10 237 | else 238 | waitNodeReady $node_name 239 | fi 240 | k_loc=$node_name 241 | if [ $kilo_location ]; then k_loc=$kilo_location; fi 242 | if $as_server; then 243 | log "\033[33mIf an error occurs, execute the following command\033[0m" 244 | log "\$ k3s kubectl annotate node $node_name kilo.squat.ai/location=$k_loc" 245 | log "\$ k3s kubectl annotate node $node_name kilo.squat.ai/force-endpoint=$ip:51820" 246 | log "\$ k3s kubectl annotate node $node_name kilo.squat.ai/persistent-keepalive=20" 247 | fi 248 | 249 | $sh_c "k3s kubectl annotate node $node_name kilo.squat.ai/location=$k_loc $suf" 250 | $sh_c "k3s kubectl annotate node $node_name kilo.squat.ai/force-endpoint=$ip:51820 $suf" 251 | $sh_c "k3s kubectl annotate node $node_name kilo.squat.ai/persistent-keepalive=20 $suf" 252 | log "Successfully added kilo annotates" 253 | if $use_docker && ! $cri_dockerd; then 254 | waitNodeReady $node_name 255 | fi 256 | log "\033[92mDone\033[0m" 257 | } 258 | 259 | # Need user confirmation to continue 260 | do_confirm() { 261 | if ! $force; then 262 | read -p "Do you want to continue? [y/N]" answer 263 | case "$answer" in 264 | y|Y) ;; 265 | *) echo "Aborting."; exit 1 ;; 266 | esac 267 | fi 268 | } 269 | 270 | # Start install steps 271 | # do_install 272 | case $command_name in 273 | install) do_confirm; do_install ;; 274 | join) do_confirm; do_join ;; 275 | *) echo "Illegal command \033[31m$command_name\033[0m"; exit 1 ;; 276 | esac 277 | -------------------------------------------------------------------------------- /scripts/setup.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | clear 4 | # Colors 5 | bold="\033[1m" 6 | red="\033[0;31m" 7 | green="\033[0;32m" 8 | yellow="\033[0;33m" 9 | cyan="\033[0;36m" 10 | plain="\033[0m" 11 | 12 | KERNEL_LIMIT_VERSION="5.4.205" 13 | DRY_RUN=${DRY_RUN:-} 14 | ip="" 15 | agent=false 16 | verbose=false 17 | force=false 18 | kernel="ml" 19 | input_hostname="" 20 | help=false 21 | k3s_url="" 22 | k3s_token="" 23 | 24 | while [ $# -gt 0 ]; do 25 | case "$1" in 26 | --kernel) 27 | kernel="$2" 28 | shift 29 | ;; 30 | --ip) 31 | ip="$2" 32 | shift 33 | ;; 34 | --hostname) 35 | input_hostname="$2" 36 | shift 37 | ;; 38 | --k3s_url) 39 | k3s_url="$2" 40 | shift 41 | ;; 42 | --k3s_token) 43 | k3s_token="$2" 44 | shift 45 | ;; 46 | --agent) 47 | agent=true 48 | ;; 49 | --verbose) 50 | verbose=true 51 | ;; 52 | -y) 53 | force=true 54 | ;; 55 | --dry-run) 56 | DRY_RUN=1 57 | ;; 58 | --help) 59 | help=true 60 | ;; 61 | --*) 62 | echo "Illegal option $1" 63 | ;; 64 | esac 65 | shift $(($# > 0 ? 1 : 0)) 66 | done 67 | 68 | info() { 69 | if $verbose; then 70 | printf "$1\n" 71 | fi 72 | } 73 | yellow() { 74 | if $verbose; then 75 | printf "${yellow}$1${plain}\n" 76 | fi 77 | } 78 | green() { 79 | if $verbose; then 80 | printf "${green}$1${plain}\n" 81 | fi 82 | } 83 | red() { 84 | if $verbose; then 85 | printf "${red}$1${plain}\n" 86 | fi 87 | } 88 | cyan() { 89 | if $verbose; then 90 | printf "${cyan}$1${plain}\n" 91 | fi 92 | } 93 | 94 | echo_title() { 95 | if $verbose; then 96 | green "\n======================= 🧡 $1 =======================\n" 97 | fi 98 | } 99 | 100 | command_exists() { 101 | command -v "$@" >/dev/null 2>&1 102 | } 103 | 104 | # version_lt checks if the version is less than the argument 105 | # 106 | # examples: 107 | # 108 | # version_lt 5.0.4 5.0.5 // true (success) 109 | # version_lt 5.0.4 5.1.5 // true (success) 110 | # version_lt 5.0.5 5.0.5 // false (fail) 111 | # version_lt 5.1.4 5.0.5 // false (fail) 112 | version_lt() { 113 | test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" != "$1"; 114 | } 115 | 116 | is_dry_run() { 117 | if [ -z "$DRY_RUN" ]; then 118 | return 1 119 | else 120 | return 0 121 | fi 122 | } 123 | 124 | run() { 125 | if ! is_dry_run; then 126 | echo "+ $sh_c '$1'" 127 | fi 128 | $sh_c "$1" 129 | } 130 | 131 | # Centos 7.x kernel default version is 3.x, so we need to update it to 5.x 132 | # if the kernel version is greater than $KERNEL_LIMIT_VERSION, will skip this step 133 | update_kernel() { 134 | echo_title "Update Kernel" 135 | kernel_ver=$(uname -r | grep -oP "^[\d.]+") 136 | 137 | if version_lt $kernel_ver $KERNEL_LIMIT_VERSION; then 138 | info "The current version $(yellow v$kernel_ver) less than $(yellow v$KERNEL_LIMIT_VERSION), need to upgrade kernel version" 139 | info "wait for 5s, will be auto started upgrade!\n" 140 | cyan "Load the public key of the ELRepo" 141 | run "rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org" 142 | cyan "Preparing udpate ELRepo" 143 | run "rpm -Uvh https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm" 144 | cyan "Load elrepo-kernel metadata" 145 | run "yum --disablerepo=\* --enablerepo=elrepo-kernel repolist" 146 | cyan "List avaliable" 147 | run "yum --disablerepo=\"*\" --enablerepo=\"elrepo-kernel\" list available" 148 | cyan "Install $(green kernel-$kernel)" 149 | run "yum --disablerepo=\* --enablerepo=elrepo-kernel install kernel-$kernel -y" 150 | cyan "Setup default" 151 | run "sed -i \"s/GRUB_DEFAULT=saved/GRUB_DEFAULT=0/g\" /etc/default/grub" 152 | cyan "Generate grub file" 153 | run "grub2-mkconfig -o /boot/grub2/grub.cfg" 154 | cyan "Remove old kernel tools" 155 | run "yum remove -y kernel-tools-libs.x86_64 kernel-tools.x86_64" 156 | cyan "Install newest kernel tools" 157 | run "yum --disablerepo=\* --enablerepo=elrepo-kernel install -y kernel-$kernel-tools.x86_64" 158 | cyan "Wait for 5s to reboot" 159 | run "sleep 5" 160 | run "reboot" 161 | else 162 | info "The current version($(yellow $kernel_ver)) greater than $(yellow $KERNEL_LIMIT_VERSION), no need to upgrade kernel version!\n" 163 | fi 164 | } 165 | 166 | # Install docker 167 | # 168 | # see more: https://get.docker.com 169 | # 170 | install_doker() { 171 | echo_title "Install Docker" 172 | if command_exists docker; then 173 | run "docker --version" 174 | if is_dry_run; then 175 | return 176 | fi 177 | printf "\n${yellow}To reinstall docker, please run the below command firstly:${plain}\n" 178 | echo 179 | echo "> yum -y remove docker-*" 180 | echo 181 | else 182 | cyan "Install docker (Need a little time)" 183 | run "curl -fsSL https://get.docker.com | sh -s - --mirror Aliyun" 184 | cyan "Setup startup" 185 | run "systemctl enable --now docker" 186 | fi 187 | } 188 | 189 | # Install kubectl 190 | install_kubectl() { 191 | echo_title "Install Kubectl" 192 | kubectl_latest=$(curl -fsSL https://dl.k8s.io/release/stable.txt) 193 | if command_exists kubectl; then 194 | if is_dry_run; then 195 | return 196 | fi 197 | kubectl_version=$(kubectl version --client --output=yaml) 198 | kubectl_ver=$(echo $kubectl_version | grep -oP "gitVersion: v[\d.]+\+?" | grep -oP "[\d.]+") 199 | if version_lt $kubectl_ver $kubectl_latest; then 200 | echo "kubectl version($(yellow v$kubectl_ver)) is less than offical latest($(yellow $kubectl_latest))" 201 | echo "run the below commands to upgrade kubectl:" 202 | echo 203 | echo "> curl -LO https://dl.k8s.io/release/$kubectl_latest/bin/linux/amd64/kubectl" 204 | echo "> sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl" 205 | echo "> kubectl version --client --output=yaml" 206 | echo 207 | else 208 | echo "kubectl version($(yellow v$kubectl_ver)) is greater than offical latest($(yellow $kubectl_latest)), no need to update!" 209 | fi 210 | else 211 | cyan "Install kubectl binary" 212 | run "curl -fsSLO https://dl.k8s.io/release/$kubectl_latest/bin/linux/amd64/kubectl" 213 | cyan "Validate the binary" 214 | run "curl -fsSLO https://dl.k8s.io/$kubectl_latest/bin/linux/amd64/kubectl.sha256" 215 | run "echo \"\$(cat kubectl.sha256) kubectl\" | sha256sum --check" 216 | cyan "Install kubectl" 217 | run "sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl" 218 | run "kubectl version --output=yaml" 219 | fi 220 | } 221 | 222 | # Install wireguard 223 | install_wireguard() { 224 | echo_title "Install Wireguard" 225 | run "yum update -y" 226 | run "yum install epel-release https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm -y" 227 | run "yum install yum-plugin-elrepo -y" 228 | run "yum install kmod-wireguard wireguard-tools -y" 229 | } 230 | 231 | # Get public ip address 232 | get_public_ip() { 233 | if [ -z "$ip" ]; then 234 | if is_dry_run; then 235 | return 236 | fi 237 | ip=$(curl -fsSL https://api.ipify.org) 238 | cyan "Your public ip is: $(green $ip)" 239 | fi 240 | } 241 | 242 | # Install K3S 243 | install_k3s() { 244 | echo_title "Install K3S" 245 | get_public_ip 246 | if $agent; then 247 | cyan "Install k3s binary" 248 | run "curl -fsSL https://rancher-mirror.oss-cn-beijing.aliyuncs.com/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn K3S_URL=$k3s_url K3S_TOKEN=$k3s_token sh -s - --docker" 249 | cyan "Write /etc/systemd/system/k3s-agent.service" 250 | run "cat >/etc/systemd/system/k3s-agent.service <<-EOF 251 | [Unit] 252 | Description=Lightweight Kubernetes 253 | Documentation=https://k3s.io 254 | Wants=network-online.target 255 | 256 | [Install] 257 | WantedBy=multi-user.target 258 | 259 | [Service] 260 | Type=exec 261 | EnvironmentFile=/etc/systemd/system/k3s-agent.service.env 262 | KillMode=process 263 | Delegate=yes 264 | LimitNOFILE=infinity 265 | LimitNPROC=infinity 266 | LimitCORE=infinity 267 | TasksMax=infinity 268 | TimeoutStartSec=0 269 | Restart=always 270 | RestartSec=5s 271 | ExecStartPre=-/sbin/modprobe br_netfilter 272 | ExecStartPre=-/sbin/modprobe overlay 273 | ExecStart=/usr/local/bin/k3s agent \\ 274 | --docker \\ 275 | --node-external-ip $ip \\ 276 | --node-ip $ip \\ 277 | --kube-proxy-arg \"proxy-mode=ipvs\" \"masquerade-all=true\" \\ 278 | --kube-proxy-arg \"metrics-bind-address=0.0.0.0\" 279 | EOF" 280 | cyan "Setup enable" 281 | run "systemctl enable k3s-agent --now" 282 | else 283 | cyan "Install k3s binary" 284 | # curl -sfL https://get.k3s.io | sh -s - --docker 285 | run "curl -fsSL https://rancher-mirror.oss-cn-beijing.aliyuncs.com/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn sh -s - --docker" 286 | cyan "Link config file" 287 | run "mkdir ~/.kube -p" 288 | run "cat /etc/rancher/k3s/k3s.yaml >> ~/.kube/config" 289 | run "chmod 600 ~/.kube/config" 290 | cyan "Write /etc/systemd/system/k3s.service" 291 | run "cat > /etc/systemd/system/k3s.service <<-EOF 292 | [Unit] 293 | Description=Lightweight Kubernetes 294 | Documentation=https://k3s.io 295 | Wants=network-online.target 296 | 297 | [Install] 298 | WantedBy=multi-user.target 299 | 300 | [Service] 301 | Type=notify 302 | EnvironmentFile=/etc/systemd/system/k3s.service.env 303 | KillMode=process 304 | Delegate=yes 305 | # Having non-zero Limit*s causes performance problems due to accounting overhead 306 | # in the kernel. We recommend using cgroups to do container-local accounting. 307 | LimitNOFILE=1048576 308 | LimitNPROC=infinity 309 | LimitCORE=infinity 310 | TasksMax=infinity 311 | TimeoutStartSec=0 312 | Restart=always 313 | RestartSec=5s 314 | ExecStartPre=-/sbin/modprobe br_netfilter 315 | ExecStartPre=-/sbin/modprobe overlay 316 | ExecStart=/usr/local/bin/k3s server \\ 317 | --docker \\ 318 | --tls-san $ip \\ 319 | --node-ip $ip \\ 320 | --node-external-ip $ip \\ 321 | --no-deploy servicelb \\ 322 | --flannel-backend wireguard \\ 323 | --kube-proxy-arg "proxy-mode=ipvs" "masquerade-all=true" \\ 324 | --kube-proxy-arg "metrics-bind-address=0.0.0.0" 325 | EOF" 326 | cyan "Setup enable" 327 | run "systemctl enable k3s --now" 328 | cyan "Check k3s health" 329 | run "kubectl get cs" 330 | fi 331 | run "sleep 5" 332 | cyan "Overwrite public ip" 333 | run "kubectl annotate nodes $(hostname) flannel.alpha.coreos.com/public-ip-overwrite=$ip" 334 | cyan "View [wireguard] connection status" 335 | run "wg show flannel.1" 336 | } 337 | 338 | # Prinit help info 339 | echo_info() { 340 | if is_dry_run; then 341 | return 342 | fi 343 | echo 344 | echo "===================== THEN =====================" 345 | echo 346 | 347 | if ! $agent; then 348 | master_url="https://$ip:6443" 349 | master_token=$(cat /var/lib/rancher/k3s/server/node-token) 350 | 351 | echo -e "K3S_URL: ${green}$master_url${plain}" 352 | echo -e "K3S_TOKEN: ${green}$master_token${plain}" 353 | echo 354 | echo "Run below command to join a node to the cluster:" 355 | echo 356 | echo -e "> sh <(curl -fsSL https://raw.githubusercontent.com/aliuq/k3sup/master/scripts/setup.sh) --verbose --agent --k3s_url $master_url --k3s_token $master_token --hostname ${red}${plain}" 357 | echo 358 | echo "change to your node name" 359 | echo 360 | else 361 | echo "Run below command in your control server node:" 362 | echo 363 | echo -e "> kubectl annotate nodes $input_hostname flannel.alpha.coreos.com/public-ip-overwrite=$ip" 364 | echo 365 | fi 366 | 367 | echo -e "\n${yellow}After reboot, run ${green}wg show flannel.1${plain} ${yellow}to check the connection status${plain}\n" 368 | echo 369 | echo 370 | } 371 | 372 | # Echo help message 373 | echo_help() { 374 | echo 375 | echo "Description:" 376 | echo 377 | echo " The script is about how to easily deploy k3s in cross public cloud on Centos 7.x" 378 | echo " it contains upgrade kernel, install docker、wireguard、kubectl、k3s" 379 | echo " when run this script in cluster master node, it will print k3s_url and k3s_token" 380 | echo " which must be required to join the cluster" 381 | echo 382 | printf " ${yellow}It will be restart few times.${plain}\n" 383 | echo 384 | echo "Usage:" 385 | echo " Server:" 386 | printf " ${bold}sh <(curl -fsSL https://raw.githubusercontent.com/aliuq/k3sup/master/scripts/setup.sh) --hostname master --verbose${plain}\n" 387 | echo " Agent:" 388 | printf " ${bold}sh <(curl -fsSL https://raw.githubusercontent.com/aliuq/k3sup/master/scripts/setup.sh) --verbose --agent --k3s_url --k3s_token --hostname ${plain}\n" 389 | echo 390 | echo "Options:" 391 | echo 392 | printf " --kernel Kernel type, options are: ${bold}ml${plain}, ${bold}lt${plain}; default is ${bold}ml${plain}\n" 393 | printf " lt is stands for long term, ml is based on mainline branch\n" 394 | printf " --agent Install k3s agent, default is ${bold}false${plain}\n" 395 | printf " if the value is ${bold}true${plain}, the script will install k3s agent, k3s_url and k3s_token are required\n" 396 | printf " if the value is ${bold}false${plain}, the script will install k3s server\n" 397 | printf " --ip Public ipv4 address, default is ${bold}$ip${plain}, it is from ${bold}curl -fsSL https://api.ipify.org${plain}\n" 398 | printf " if provided ip address, the script will overwrite the ipv4 address\n" 399 | printf " --hostname Hostname, default is ${bold}$hostname${plain}, it will be used as cluster node name\n" 400 | printf " no duplicate names with nodes in the cluster\n" 401 | printf " --k3s_url The k3s master api server url, general format is: ${bold}https://:6443${plain}\n" 402 | printf " where is the public IP of the cluster control node. only used in k3s agent\n" 403 | printf " --k3s_token The token required to join the cluster, only used in k3s agent\n" 404 | printf " run ${bold}cat /var/lib/rancher/k3s/server/node-token${plain} in your control node\n" 405 | printf " --dry-run Print command only, will not install anything, default is ${bold}false${plain}\n" 406 | printf " --verbose Output more information, default is ${bold}false${plain}\n" 407 | printf " -y Skip script prompt, default is ${bold}false${plain}\n" 408 | printf " --help Show this help message and exit\n" 409 | echo 410 | } 411 | 412 | do_preinstall() { 413 | if is_dry_run; then 414 | return 415 | fi 416 | if [ $kernel != "ml" ] && [ $kernel != "lt" ]; then 417 | cyan "Set kernel to ml" 418 | kernel="ml" 419 | fi 420 | 421 | if [ $input_hostname ]; then 422 | run "hostnamectl set-hostname $input_hostname" 423 | else 424 | input_hostname=$(hostname) 425 | fi 426 | 427 | if $agent; then 428 | if [ -z $k3s_url ] || [ -z $k3s_token ]; then 429 | printf "${red}--k3s_url and --k3s_token is required when --agent is specified${plain}\n" 430 | echo_help 431 | exit 1 432 | fi 433 | fi 434 | } 435 | 436 | do_install() { 437 | if $help; then 438 | echo_help 439 | exit 0 440 | fi 441 | if ! $force && ! is_dry_run; then 442 | echo_help 443 | echo 444 | read -p "Do you want to continue? [y/N]" answer 445 | if [ $answer != "y" ] && [ $answer != "Y" ]; then 446 | echo 447 | echo "Aborted." 448 | echo 449 | exit 1 450 | fi 451 | fi 452 | 453 | user="$(id -un 2>/dev/null || true)" 454 | sh_c="sh -c" 455 | if [ "$user" != "root" ]; then 456 | if command_exists sudo; then 457 | sh_c="sudo -E sh -c" 458 | elif command_exists su; then 459 | sh_c="su -c" 460 | else 461 | cat >&2 <<-EOF 462 | Error: this installer needs the ability to run commands as root. 463 | We are unable to find either "sudo" or "su" available to make this happen. 464 | EOF 465 | exit 1 466 | fi 467 | fi 468 | 469 | if is_dry_run; then 470 | sh_c="echo" 471 | fi 472 | 473 | do_preinstall 474 | update_kernel 475 | install_doker 476 | install_wireguard 477 | install_kubectl 478 | install_k3s 479 | run "sleep 5" 480 | echo_info 481 | reboot 482 | } 483 | # Start install steps 484 | do_install 485 | -------------------------------------------------------------------------------- /ingress-nginx/controller-v1.3.0.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | labels: 5 | app.kubernetes.io/instance: ingress-nginx 6 | app.kubernetes.io/name: ingress-nginx 7 | name: ingress-nginx 8 | --- 9 | apiVersion: v1 10 | automountServiceAccountToken: true 11 | kind: ServiceAccount 12 | metadata: 13 | labels: 14 | app.kubernetes.io/component: controller 15 | app.kubernetes.io/instance: ingress-nginx 16 | app.kubernetes.io/name: ingress-nginx 17 | app.kubernetes.io/part-of: ingress-nginx 18 | app.kubernetes.io/version: 1.3.0 19 | name: ingress-nginx 20 | namespace: ingress-nginx 21 | --- 22 | apiVersion: v1 23 | kind: ServiceAccount 24 | metadata: 25 | labels: 26 | app.kubernetes.io/component: admission-webhook 27 | app.kubernetes.io/instance: ingress-nginx 28 | app.kubernetes.io/name: ingress-nginx 29 | app.kubernetes.io/part-of: ingress-nginx 30 | app.kubernetes.io/version: 1.3.0 31 | name: ingress-nginx-admission 32 | namespace: ingress-nginx 33 | --- 34 | apiVersion: rbac.authorization.k8s.io/v1 35 | kind: Role 36 | metadata: 37 | labels: 38 | app.kubernetes.io/component: controller 39 | app.kubernetes.io/instance: ingress-nginx 40 | app.kubernetes.io/name: ingress-nginx 41 | app.kubernetes.io/part-of: ingress-nginx 42 | app.kubernetes.io/version: 1.3.0 43 | name: ingress-nginx 44 | namespace: ingress-nginx 45 | rules: 46 | - apiGroups: 47 | - "" 48 | resources: 49 | - namespaces 50 | verbs: 51 | - get 52 | - apiGroups: 53 | - "" 54 | resources: 55 | - configmaps 56 | - pods 57 | - secrets 58 | - endpoints 59 | verbs: 60 | - get 61 | - list 62 | - watch 63 | - apiGroups: 64 | - "" 65 | resources: 66 | - services 67 | verbs: 68 | - get 69 | - list 70 | - watch 71 | - apiGroups: 72 | - networking.k8s.io 73 | resources: 74 | - ingresses 75 | verbs: 76 | - get 77 | - list 78 | - watch 79 | - apiGroups: 80 | - networking.k8s.io 81 | resources: 82 | - ingresses/status 83 | verbs: 84 | - update 85 | - apiGroups: 86 | - networking.k8s.io 87 | resources: 88 | - ingressclasses 89 | verbs: 90 | - get 91 | - list 92 | - watch 93 | - apiGroups: 94 | - "" 95 | resourceNames: 96 | - ingress-controller-leader 97 | resources: 98 | - configmaps 99 | verbs: 100 | - get 101 | - update 102 | - apiGroups: 103 | - "" 104 | resources: 105 | - configmaps 106 | verbs: 107 | - create 108 | - apiGroups: 109 | - coordination.k8s.io 110 | resourceNames: 111 | - ingress-controller-leader 112 | resources: 113 | - leases 114 | verbs: 115 | - get 116 | - update 117 | - apiGroups: 118 | - coordination.k8s.io 119 | resources: 120 | - leases 121 | verbs: 122 | - create 123 | - apiGroups: 124 | - "" 125 | resources: 126 | - events 127 | verbs: 128 | - create 129 | - patch 130 | --- 131 | apiVersion: rbac.authorization.k8s.io/v1 132 | kind: Role 133 | metadata: 134 | labels: 135 | app.kubernetes.io/component: admission-webhook 136 | app.kubernetes.io/instance: ingress-nginx 137 | app.kubernetes.io/name: ingress-nginx 138 | app.kubernetes.io/part-of: ingress-nginx 139 | app.kubernetes.io/version: 1.3.0 140 | name: ingress-nginx-admission 141 | namespace: ingress-nginx 142 | rules: 143 | - apiGroups: 144 | - "" 145 | resources: 146 | - secrets 147 | verbs: 148 | - get 149 | - create 150 | --- 151 | apiVersion: rbac.authorization.k8s.io/v1 152 | kind: ClusterRole 153 | metadata: 154 | labels: 155 | app.kubernetes.io/instance: ingress-nginx 156 | app.kubernetes.io/name: ingress-nginx 157 | app.kubernetes.io/part-of: ingress-nginx 158 | app.kubernetes.io/version: 1.3.0 159 | name: ingress-nginx 160 | rules: 161 | - apiGroups: 162 | - "" 163 | resources: 164 | - configmaps 165 | - endpoints 166 | - nodes 167 | - pods 168 | - secrets 169 | - namespaces 170 | verbs: 171 | - list 172 | - watch 173 | - apiGroups: 174 | - coordination.k8s.io 175 | resources: 176 | - leases 177 | verbs: 178 | - list 179 | - watch 180 | - apiGroups: 181 | - "" 182 | resources: 183 | - nodes 184 | verbs: 185 | - get 186 | - apiGroups: 187 | - "" 188 | resources: 189 | - services 190 | verbs: 191 | - get 192 | - list 193 | - watch 194 | - apiGroups: 195 | - networking.k8s.io 196 | resources: 197 | - ingresses 198 | verbs: 199 | - get 200 | - list 201 | - watch 202 | - apiGroups: 203 | - "" 204 | resources: 205 | - events 206 | verbs: 207 | - create 208 | - patch 209 | - apiGroups: 210 | - networking.k8s.io 211 | resources: 212 | - ingresses/status 213 | verbs: 214 | - update 215 | - apiGroups: 216 | - networking.k8s.io 217 | resources: 218 | - ingressclasses 219 | verbs: 220 | - get 221 | - list 222 | - watch 223 | --- 224 | apiVersion: rbac.authorization.k8s.io/v1 225 | kind: ClusterRole 226 | metadata: 227 | labels: 228 | app.kubernetes.io/component: admission-webhook 229 | app.kubernetes.io/instance: ingress-nginx 230 | app.kubernetes.io/name: ingress-nginx 231 | app.kubernetes.io/part-of: ingress-nginx 232 | app.kubernetes.io/version: 1.3.0 233 | name: ingress-nginx-admission 234 | rules: 235 | - apiGroups: 236 | - admissionregistration.k8s.io 237 | resources: 238 | - validatingwebhookconfigurations 239 | verbs: 240 | - get 241 | - update 242 | --- 243 | apiVersion: rbac.authorization.k8s.io/v1 244 | kind: RoleBinding 245 | metadata: 246 | labels: 247 | app.kubernetes.io/component: controller 248 | app.kubernetes.io/instance: ingress-nginx 249 | app.kubernetes.io/name: ingress-nginx 250 | app.kubernetes.io/part-of: ingress-nginx 251 | app.kubernetes.io/version: 1.3.0 252 | name: ingress-nginx 253 | namespace: ingress-nginx 254 | roleRef: 255 | apiGroup: rbac.authorization.k8s.io 256 | kind: Role 257 | name: ingress-nginx 258 | subjects: 259 | - kind: ServiceAccount 260 | name: ingress-nginx 261 | namespace: ingress-nginx 262 | --- 263 | apiVersion: rbac.authorization.k8s.io/v1 264 | kind: RoleBinding 265 | metadata: 266 | labels: 267 | app.kubernetes.io/component: admission-webhook 268 | app.kubernetes.io/instance: ingress-nginx 269 | app.kubernetes.io/name: ingress-nginx 270 | app.kubernetes.io/part-of: ingress-nginx 271 | app.kubernetes.io/version: 1.3.0 272 | name: ingress-nginx-admission 273 | namespace: ingress-nginx 274 | roleRef: 275 | apiGroup: rbac.authorization.k8s.io 276 | kind: Role 277 | name: ingress-nginx-admission 278 | subjects: 279 | - kind: ServiceAccount 280 | name: ingress-nginx-admission 281 | namespace: ingress-nginx 282 | --- 283 | apiVersion: rbac.authorization.k8s.io/v1 284 | kind: ClusterRoleBinding 285 | metadata: 286 | labels: 287 | app.kubernetes.io/instance: ingress-nginx 288 | app.kubernetes.io/name: ingress-nginx 289 | app.kubernetes.io/part-of: ingress-nginx 290 | app.kubernetes.io/version: 1.3.0 291 | name: ingress-nginx 292 | roleRef: 293 | apiGroup: rbac.authorization.k8s.io 294 | kind: ClusterRole 295 | name: ingress-nginx 296 | subjects: 297 | - kind: ServiceAccount 298 | name: ingress-nginx 299 | namespace: ingress-nginx 300 | --- 301 | apiVersion: rbac.authorization.k8s.io/v1 302 | kind: ClusterRoleBinding 303 | metadata: 304 | labels: 305 | app.kubernetes.io/component: admission-webhook 306 | app.kubernetes.io/instance: ingress-nginx 307 | app.kubernetes.io/name: ingress-nginx 308 | app.kubernetes.io/part-of: ingress-nginx 309 | app.kubernetes.io/version: 1.3.0 310 | name: ingress-nginx-admission 311 | roleRef: 312 | apiGroup: rbac.authorization.k8s.io 313 | kind: ClusterRole 314 | name: ingress-nginx-admission 315 | subjects: 316 | - kind: ServiceAccount 317 | name: ingress-nginx-admission 318 | namespace: ingress-nginx 319 | --- 320 | apiVersion: v1 321 | data: 322 | allow-snippet-annotations: "true" 323 | kind: ConfigMap 324 | metadata: 325 | labels: 326 | app.kubernetes.io/component: controller 327 | app.kubernetes.io/instance: ingress-nginx 328 | app.kubernetes.io/name: ingress-nginx 329 | app.kubernetes.io/part-of: ingress-nginx 330 | app.kubernetes.io/version: 1.3.0 331 | name: ingress-nginx-controller 332 | namespace: ingress-nginx 333 | --- 334 | apiVersion: v1 335 | kind: Service 336 | metadata: 337 | labels: 338 | app.kubernetes.io/component: controller 339 | app.kubernetes.io/instance: ingress-nginx 340 | app.kubernetes.io/name: ingress-nginx 341 | app.kubernetes.io/part-of: ingress-nginx 342 | app.kubernetes.io/version: 1.3.0 343 | name: ingress-nginx-controller 344 | namespace: ingress-nginx 345 | spec: 346 | externalTrafficPolicy: Local 347 | ports: 348 | - appProtocol: http 349 | name: http 350 | port: 80 351 | protocol: TCP 352 | targetPort: http 353 | - appProtocol: https 354 | name: https 355 | port: 443 356 | protocol: TCP 357 | targetPort: https 358 | selector: 359 | app.kubernetes.io/component: controller 360 | app.kubernetes.io/instance: ingress-nginx 361 | app.kubernetes.io/name: ingress-nginx 362 | type: LoadBalancer 363 | --- 364 | apiVersion: v1 365 | kind: Service 366 | metadata: 367 | labels: 368 | app.kubernetes.io/component: controller 369 | app.kubernetes.io/instance: ingress-nginx 370 | app.kubernetes.io/name: ingress-nginx 371 | app.kubernetes.io/part-of: ingress-nginx 372 | app.kubernetes.io/version: 1.3.0 373 | name: ingress-nginx-controller-admission 374 | namespace: ingress-nginx 375 | spec: 376 | ports: 377 | - appProtocol: https 378 | name: https-webhook 379 | port: 443 380 | targetPort: webhook 381 | selector: 382 | app.kubernetes.io/component: controller 383 | app.kubernetes.io/instance: ingress-nginx 384 | app.kubernetes.io/name: ingress-nginx 385 | type: ClusterIP 386 | --- 387 | apiVersion: apps/v1 388 | kind: Deployment 389 | metadata: 390 | labels: 391 | app.kubernetes.io/component: controller 392 | app.kubernetes.io/instance: ingress-nginx 393 | app.kubernetes.io/name: ingress-nginx 394 | app.kubernetes.io/part-of: ingress-nginx 395 | app.kubernetes.io/version: 1.3.0 396 | name: ingress-nginx-controller 397 | namespace: ingress-nginx 398 | spec: 399 | minReadySeconds: 0 400 | revisionHistoryLimit: 10 401 | selector: 402 | matchLabels: 403 | app.kubernetes.io/component: controller 404 | app.kubernetes.io/instance: ingress-nginx 405 | app.kubernetes.io/name: ingress-nginx 406 | template: 407 | metadata: 408 | labels: 409 | app.kubernetes.io/component: controller 410 | app.kubernetes.io/instance: ingress-nginx 411 | app.kubernetes.io/name: ingress-nginx 412 | spec: 413 | containers: 414 | - args: 415 | - /nginx-ingress-controller 416 | - --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller 417 | - --election-id=ingress-controller-leader 418 | - --controller-class=k8s.io/ingress-nginx 419 | - --ingress-class=nginx 420 | - --configmap=$(POD_NAMESPACE)/ingress-nginx-controller 421 | - --validating-webhook=:8443 422 | - --validating-webhook-certificate=/usr/local/certificates/cert 423 | - --validating-webhook-key=/usr/local/certificates/key 424 | env: 425 | - name: POD_NAME 426 | valueFrom: 427 | fieldRef: 428 | fieldPath: metadata.name 429 | - name: POD_NAMESPACE 430 | valueFrom: 431 | fieldRef: 432 | fieldPath: metadata.namespace 433 | - name: LD_PRELOAD 434 | value: /usr/local/lib/libmimalloc.so 435 | # image: registry.k8s.io/ingress-nginx/controller:v1.3.0@sha256:d1707ca76d3b044ab8a28277a2466a02100ee9f58a86af1535a3edf9323ea1b5 436 | image: registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:v1.3.0@sha256:c886d79d3be96bd4b62b2e033045142abef119ae70761a92491ea9acca8f1cc6 437 | imagePullPolicy: IfNotPresent 438 | lifecycle: 439 | preStop: 440 | exec: 441 | command: 442 | - /wait-shutdown 443 | livenessProbe: 444 | failureThreshold: 5 445 | httpGet: 446 | path: /healthz 447 | port: 10254 448 | scheme: HTTP 449 | initialDelaySeconds: 10 450 | periodSeconds: 10 451 | successThreshold: 1 452 | timeoutSeconds: 1 453 | name: controller 454 | ports: 455 | - containerPort: 80 456 | name: http 457 | protocol: TCP 458 | - containerPort: 443 459 | name: https 460 | protocol: TCP 461 | - containerPort: 8443 462 | name: webhook 463 | protocol: TCP 464 | readinessProbe: 465 | failureThreshold: 3 466 | httpGet: 467 | path: /healthz 468 | port: 10254 469 | scheme: HTTP 470 | initialDelaySeconds: 10 471 | periodSeconds: 10 472 | successThreshold: 1 473 | timeoutSeconds: 1 474 | resources: 475 | requests: 476 | cpu: 100m 477 | memory: 90Mi 478 | securityContext: 479 | allowPrivilegeEscalation: true 480 | capabilities: 481 | add: 482 | - NET_BIND_SERVICE 483 | drop: 484 | - ALL 485 | runAsUser: 101 486 | volumeMounts: 487 | - mountPath: /usr/local/certificates/ 488 | name: webhook-cert 489 | readOnly: true 490 | dnsPolicy: ClusterFirst 491 | nodeSelector: 492 | kubernetes.io/os: linux 493 | serviceAccountName: ingress-nginx 494 | terminationGracePeriodSeconds: 300 495 | volumes: 496 | - name: webhook-cert 497 | secret: 498 | secretName: ingress-nginx-admission 499 | --- 500 | apiVersion: batch/v1 501 | kind: Job 502 | metadata: 503 | labels: 504 | app.kubernetes.io/component: admission-webhook 505 | app.kubernetes.io/instance: ingress-nginx 506 | app.kubernetes.io/name: ingress-nginx 507 | app.kubernetes.io/part-of: ingress-nginx 508 | app.kubernetes.io/version: 1.3.0 509 | name: ingress-nginx-admission-create 510 | namespace: ingress-nginx 511 | spec: 512 | template: 513 | metadata: 514 | labels: 515 | app.kubernetes.io/component: admission-webhook 516 | app.kubernetes.io/instance: ingress-nginx 517 | app.kubernetes.io/name: ingress-nginx 518 | app.kubernetes.io/part-of: ingress-nginx 519 | app.kubernetes.io/version: 1.3.0 520 | name: ingress-nginx-admission-create 521 | spec: 522 | containers: 523 | - args: 524 | - create 525 | - --host=ingress-nginx-controller-admission,ingress-nginx-controller-admission.$(POD_NAMESPACE).svc 526 | - --namespace=$(POD_NAMESPACE) 527 | - --secret-name=ingress-nginx-admission 528 | env: 529 | - name: POD_NAMESPACE 530 | valueFrom: 531 | fieldRef: 532 | fieldPath: metadata.namespace 533 | # image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.1.1@sha256:64d8c73dca984af206adf9d6d7e46aa550362b1d7a01f3a0a91b20cc67868660 534 | image: registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v1.1.1@sha256:23a03c9c381fba54043d0f6148efeaf4c1ca2ed176e43455178b5c5ebf15ad70 535 | imagePullPolicy: IfNotPresent 536 | name: create 537 | securityContext: 538 | allowPrivilegeEscalation: false 539 | nodeSelector: 540 | kubernetes.io/os: linux 541 | restartPolicy: OnFailure 542 | securityContext: 543 | fsGroup: 2000 544 | runAsNonRoot: true 545 | runAsUser: 2000 546 | serviceAccountName: ingress-nginx-admission 547 | --- 548 | apiVersion: batch/v1 549 | kind: Job 550 | metadata: 551 | labels: 552 | app.kubernetes.io/component: admission-webhook 553 | app.kubernetes.io/instance: ingress-nginx 554 | app.kubernetes.io/name: ingress-nginx 555 | app.kubernetes.io/part-of: ingress-nginx 556 | app.kubernetes.io/version: 1.3.0 557 | name: ingress-nginx-admission-patch 558 | namespace: ingress-nginx 559 | spec: 560 | template: 561 | metadata: 562 | labels: 563 | app.kubernetes.io/component: admission-webhook 564 | app.kubernetes.io/instance: ingress-nginx 565 | app.kubernetes.io/name: ingress-nginx 566 | app.kubernetes.io/part-of: ingress-nginx 567 | app.kubernetes.io/version: 1.3.0 568 | name: ingress-nginx-admission-patch 569 | spec: 570 | containers: 571 | - args: 572 | - patch 573 | - --webhook-name=ingress-nginx-admission 574 | - --namespace=$(POD_NAMESPACE) 575 | - --patch-mutating=false 576 | - --secret-name=ingress-nginx-admission 577 | - --patch-failure-policy=Fail 578 | env: 579 | - name: POD_NAMESPACE 580 | valueFrom: 581 | fieldRef: 582 | fieldPath: metadata.namespace 583 | # image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.1.1@sha256:64d8c73dca984af206adf9d6d7e46aa550362b1d7a01f3a0a91b20cc67868660 584 | image: registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v1.1.1@sha256:23a03c9c381fba54043d0f6148efeaf4c1ca2ed176e43455178b5c5ebf15ad70 585 | imagePullPolicy: IfNotPresent 586 | name: patch 587 | securityContext: 588 | allowPrivilegeEscalation: false 589 | nodeSelector: 590 | kubernetes.io/os: linux 591 | restartPolicy: OnFailure 592 | securityContext: 593 | fsGroup: 2000 594 | runAsNonRoot: true 595 | runAsUser: 2000 596 | serviceAccountName: ingress-nginx-admission 597 | --- 598 | apiVersion: networking.k8s.io/v1 599 | kind: IngressClass 600 | metadata: 601 | labels: 602 | app.kubernetes.io/component: controller 603 | app.kubernetes.io/instance: ingress-nginx 604 | app.kubernetes.io/name: ingress-nginx 605 | app.kubernetes.io/part-of: ingress-nginx 606 | app.kubernetes.io/version: 1.3.0 607 | name: nginx 608 | spec: 609 | controller: k8s.io/ingress-nginx 610 | --- 611 | apiVersion: admissionregistration.k8s.io/v1 612 | kind: ValidatingWebhookConfiguration 613 | metadata: 614 | labels: 615 | app.kubernetes.io/component: admission-webhook 616 | app.kubernetes.io/instance: ingress-nginx 617 | app.kubernetes.io/name: ingress-nginx 618 | app.kubernetes.io/part-of: ingress-nginx 619 | app.kubernetes.io/version: 1.3.0 620 | name: ingress-nginx-admission 621 | webhooks: 622 | - admissionReviewVersions: 623 | - v1 624 | clientConfig: 625 | service: 626 | name: ingress-nginx-controller-admission 627 | namespace: ingress-nginx 628 | path: /networking/v1/ingresses 629 | failurePolicy: Fail 630 | matchPolicy: Equivalent 631 | name: validate.nginx.ingress.kubernetes.io 632 | rules: 633 | - apiGroups: 634 | - networking.k8s.io 635 | apiVersions: 636 | - v1 637 | operations: 638 | - CREATE 639 | - UPDATE 640 | resources: 641 | - ingresses 642 | sideEffects: None 643 | --------------------------------------------------------------------------------