以下是一个完整的自动化脚本方案,用于在Linux系统上安装Kubernetes集群。这个脚本支持主节点和工作节点的安装配置。
#!/bin/bash
# Kubernetes自动化安装脚本
# 支持Ubuntu/CentOS系统
# 使用方式: sudo ./install_k8s.sh [master|worker] [options]
set -e
# 参数定义
ROLE=""
K8S_VERSION="1.28.0"
POD_NETWORK_CIDR="10.244.0.0/16"
SERVICE_CIDR="10.96.0.0/12"
MASTER_IP=""
TOKEN=""
TOKEN_HASH=""
INSTALL_DASHBOARD=false
INSTALL_METRICS=false
INSTALL_ISTIO=false
CONTAINER_RUNTIME="containerd"
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color
# 显示帮助信息
usage() {
echo "Usage: $0 [master|worker] [options]"
echo "Options:"
echo " --k8s-version <version> Kubernetes版本 (默认: $K8S_VERSION)"
echo " --pod-network-cidr <cidr> Pod网络CIDR (默认: $POD_NETWORK_CIDR)"
echo " --service-cidr <cidr> 服务CIDR (默认: $SERVICE_CIDR)"
echo " --master-ip <ip> 主节点IP (工作节点需要)"
echo " --token <token> 加入集群的token (工作节点需要)"
echo " --token-hash <hash> 加入集群的token hash (工作节点需要)"
echo " --container-runtime <runtime> 容器运行时 (containerd/docker, 默认: $CONTAINER_RUNTIME)"
echo " --install-dashboard 安装Kubernetes Dashboard"
echo " --install-metrics 安装Metrics Server"
echo " --install-istio 安装Istio服务网格"
exit 1
}
# 检查命令是否存在
command_exists() {
command -v "$@" >/dev/null 2>&1
}
# 检查是否为root用户
check_root() {
if [ "$(id -u)" -ne 0 ]; then
echo -e "${RED}错误: 必须使用root用户运行此脚本${NC}" >&2
exit 1
fi
}
# 检测操作系统
detect_os() {
if [ -f /etc/os-release ]; then
. /etc/os-release
OS=$ID
VERSION=$VERSION_ID
elif command_exists lsb_release; then
OS=$(lsb_release -si | tr '[:upper:]' '[:lower:]')
VERSION=$(lsb_release -sr)
else
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
VERSION=$(uname -r)
fi
}
# 安装必要工具
install_tools() {
echo -e "${GREEN}[INFO] 安装必要工具...${NC}"
if [ "$OS" = "ubuntu" ] || [ "$OS" = "debian" ]; then
apt-get update
apt-get install -y apt-transport-https ca-certificates curl gnupg lsb-release software-properties-common
elif [ "$OS" = "centos" ] || [ "$OS" = "rhel" ] || [ "$OS" = "amzn" ]; then
yum install -y yum-utils device-mapper-persistent-data lvm2
else
echo -e "${RED}错误: 不支持的操作系统${NC}"
exit 1
fi
}
# 禁用交换空间
disable_swap() {
echo -e "${GREEN}[INFO] 禁用交换空间...${NC}"
swapoff -a
sed -i '/swap/s/^\(.*\)$/#\1/g' /etc/fstab
}
# 配置内核参数
configure_kernel() {
echo -e "${GREEN}[INFO] 配置内核参数...${NC}"
cat <<EOF | tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
modprobe overlay
modprobe br_netfilter
cat <<EOF | tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sysctl --system
}
# 安装容器运行时
install_container_runtime() {
echo -e "${GREEN}[INFO] 安装容器运行时: $CONTAINER_RUNTIME...${NC}"
if [ "$CONTAINER_RUNTIME" = "containerd" ]; then
install_containerd
elif [ "$CONTAINER_RUNTIME" = "docker" ]; then
install_docker
else
echo -e "${RED}错误: 不支持的容器运行时: $CONTAINER_RUNTIME${NC}"
exit 1
fi
}
# 安装containerd
install_containerd() {
if command_exists containerd; then
echo -e "${YELLOW}[INFO] containerd 已安装,跳过安装${NC}"
return
fi
if [ "$OS" = "ubuntu" ] || [ "$OS" = "debian" ]; then
curl -fsSL https://download.docker.com/linux/$OS/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/$OS $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list >/dev/null
apt-get update
apt-get install -y containerd.io
elif [ "$OS" = "centos" ] || [ "$OS" = "rhel" ] || [ "$OS" = "amzn" ]; then
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install -y containerd.io
fi
mkdir -p /etc/containerd
containerd config default | tee /etc/containerd/config.toml >/dev/null
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml
systemctl restart containerd
systemctl enable containerd
}
# 安装docker
install_docker() {
if command_exists docker; then
echo -e "${YELLOW}[INFO] Docker 已安装,跳过安装${NC}"
return
fi
if [ "$OS" = "ubuntu" ] || [ "$OS" = "debian" ]; then
curl -fsSL https://download.docker.com/linux/$OS/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/$OS $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list >/dev/null
apt-get update
apt-get install -y docker-ce docker-ce-cli containerd.io
elif [ "$OS" = "centos" ] || [ "$OS" = "rhel" ] || [ "$OS" = "amzn" ]; then
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install -y docker-ce docker-ce-cli containerd.io
fi
mkdir -p /etc/docker
cat <<EOF | tee /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
EOF
systemctl restart docker
systemctl enable docker
}
# 安装kubeadm, kubelet和kubectl
install_kube_packages() {
echo -e "${GREEN}[INFO] 安装kubeadm, kubelet和kubectl...${NC}"
if [ "$OS" = "ubuntu" ] || [ "$OS" = "debian" ]; then
curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | gpg --dearmor -o /etc/apt/keyrings/kubernetes-archive-keyring.gpg
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | tee /etc/apt/sources.list.d/kubernetes.list
apt-get update
apt-get install -y kubelet=$K8S_VERSION-00 kubeadm=$K8S_VERSION-00 kubectl=$K8S_VERSION-00
apt-mark hold kubelet kubeadm kubectl
elif [ "$OS" = "centos" ] || [ "$OS" = "rhel" ] || [ "$OS" = "amzn" ]; then
cat <<EOF | tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF
yum install -y kubelet-$K8S_VERSION kubeadm-$K8S_VERSION kubectl-$K8S_VERSION
yum versionlock add kubelet kubeadm kubectl
fi
systemctl enable kubelet
}
# 初始化主节点
init_master() {
echo -e "${GREEN}[INFO] 初始化Kubernetes主节点...${NC}"
kubeadm init \
--apiserver-advertise-address=$(hostname -I | awk '{print $1}') \
--pod-network-cidr=$POD_NETWORK_CIDR \
--service-cidr=$SERVICE_CIDR \
--kubernetes-version=$K8S_VERSION
# 配置kubectl
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
# 获取加入集群的token和hash
TOKEN=$(kubeadm token create)
TOKEN_HASH=$(openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //')
echo -e "${GREEN}[INFO] 主节点初始化完成!${NC}"
echo -e "${YELLOW}工作节点加入集群命令:${NC}"
echo "kubeadm join $(hostname -I | awk '{print $1}'):6443 --token $TOKEN --discovery-token-ca-cert-hash sha256:$TOKEN_HASH"
}
# 安装网络插件 (Flannel)
install_network_plugin() {
echo -e "${GREEN}[INFO] 安装Flannel网络插件...${NC}"
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
}
# 安装Dashboard
install_dashboard() {
echo -e "${GREEN}[INFO] 安装Kubernetes Dashboard...${NC}"
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml
# 创建管理员用户
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kubernetes-dashboard
EOF
# 获取访问令牌
DASHBOARD_TOKEN=$(kubectl -n kubernetes-dashboard create token admin-user)
echo -e "${GREEN}[INFO] Dashboard安装完成!${NC}"
echo -e "${YELLOW}访问令牌:${NC}"
echo "$DASHBOARD_TOKEN"
echo -e "${YELLOW}访问命令:${NC}"
echo "kubectl proxy"
echo -e "然后访问: http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/"
}
# 安装Metrics Server
install_metrics_server() {
echo -e "${GREEN}[INFO] 安装Metrics Server...${NC}"
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
# 修改参数以兼容某些环境
kubectl patch deployment metrics-server -n kube-system --type=json \
-p='[{"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value": "--kubelet-insecure-tls"}]'
echo -e "${GREEN}[INFO] Metrics Server安装完成!${NC}"
}
# 安装Istio
install_istio() {
echo -e "${GREEN}[INFO] 安装Istio...${NC}"
curl -L https://istio.io/downloadIstio | sh -
cd istio-*
export PATH=$PWD/bin:$PATH
istioctl install --set profile=demo -y
# 启用自动sidecar注入
kubectl label namespace default istio-injection=enabled
echo -e "${GREEN}[INFO] Istio安装完成!${NC}"
}
# 加入工作节点
join_worker() {
if [ -z "$MASTER_IP" ] || [ -z "$TOKEN" ] || [ -z "$TOKEN_HASH" ]; then
echo -e "${RED}错误: 工作节点需要--master-ip, --token和--token-hash参数${NC}"
exit 1
fi
echo -e "${GREEN}[INFO] 加入Kubernetes集群...${NC}"
kubeadm join $MASTER_IP:6443 --token $TOKEN --discovery-token-ca-cert-hash sha256:$TOKEN_HASH
}
# 主函数
main() {
check_root
detect_os
# 解析参数
while [ $# -gt 0 ]; do
case "$1" in
master|worker)
ROLE=$1
;;
--k8s-version)
K8S_VERSION=$2
shift
;;
--pod-network-cidr)
POD_NETWORK_CIDR=$2
shift
;;
--service-cidr)
SERVICE_CIDR=$2
shift
;;
--master-ip)
MASTER_IP=$2
shift
;;
--token)
TOKEN=$2
shift
;;
--token-hash)
TOKEN_HASH=$2
shift
;;
--container-runtime)
CONTAINER_RUNTIME=$2
shift
;;
--install-dashboard)
INSTALL_DASHBOARD=true
;;
--install-metrics)
INSTALL_METRICS=true
;;
--install-istio)
INSTALL_ISTIO=true
;;
-h|--help)
usage
;;
*)
echo -e "${RED}未知参数: $1${NC}"
usage
;;
esac
shift
done
if [ -z "$ROLE" ]; then
echo -e "${RED}错误: 必须指定角色(master或worker)${NC}"
usage
fi
# 执行安装步骤
install_tools
disable_swap
configure_kernel
install_container_runtime
install_kube_packages
if [ "$ROLE" = "master" ]; then
init_master
install_network_plugin
if [ "$INSTALL_DASHBOARD" = true ]; then
install_dashboard
fi
if [ "$INSTALL_METRICS" = true ]; then
install_metrics_server
fi
if [ "$INSTALL_ISTIO" = true ]; then
install_istio
fi
elif [ "$ROLE" = "worker" ]; then
join_worker
fi
echo -e "${GREEN}[SUCCESS] Kubernetes $ROLE节点安装完成!${NC}"
}
main "$@"
```bash
sudo ./install_k8s.sh master
sudo ./install_k8s.sh master \ --k8s-version 1.28.0 \ --pod-network-cidr 10.244.0.0/16 \ --service-cidr 10.96.0.0/12 \ --container-runtime contain