#!/bin/bash # 空白机器安装 Kubernetes 1.37.1 单节点。 # 运行时是 cri-dockerd 0.4.8,网络是本机网桥。不要再装 Flannel。 # 不要在已经跑着业务的 prod102 上执行。 set -eu export DEBIAN_FRONTEND=noninteractive export KUBECONFIG=/root/.kube/config if [ "$(hostname)" = "prod102" ] && [ -f /etc/kubernetes/admin.conf ]; then echo "prod102 上控制面已经在。这份脚本是给空机器的,停在这里。" exit 1 fi KVER=1.37.1-1.1 IMG_REPO=registry.aliyuncs.com/google_containers WORKDIR=/usr/cluster/k8s mkdir -p "$WORKDIR" /etc/cni/net.d /opt/cni/bin echo "=== cri-dockerd 0.4.8 ===" if ! /usr/local/bin/cri-dockerd --version 2>/dev/null | grep -q '0.4.8'; then curl -fL --retry 3 -o "$WORKDIR/cri-dockerd-0.4.8.amd64.tgz" \ https://github.com/Mirantis/cri-dockerd/releases/download/v0.4.8/cri-dockerd-0.4.8.amd64.tgz tar -xzf "$WORKDIR/cri-dockerd-0.4.8.amd64.tgz" -C "$WORKDIR" install -m 0755 "$WORKDIR/cri-dockerd/cri-dockerd" /usr/local/bin/cri-dockerd fi if [ ! -f /lib/systemd/system/cri-docker.service ] && [ ! -f /etc/systemd/system/cri-docker.service ]; then cat > /etc/systemd/system/cri-docker.socket << 'EOF' [Unit] Description=CRI Docker Socket for the API PartOf=cri-docker.service [Socket] ListenStream=%t/cri-dockerd.sock SocketMode=0660 SocketUser=root SocketGroup=root [Install] WantedBy=sockets.target EOF cat > /etc/systemd/system/cri-docker.service << 'EOF' [Unit] Description=CRI Interface for Docker Application Container Engine After=network-online.target docker.service Wants=network-online.target Requires=cri-docker.socket [Service] Type=notify ExecStart=/usr/local/bin/cri-dockerd --container-runtime-endpoint fd:// ExecReload=/bin/kill -s HUP $MAINPID TimeoutSec=0 RestartSec=2 Restart=always Delegate=yes KillMode=process [Install] WantedBy=multi-user.target EOF fi systemctl mask cri-dockerd.service >/dev/null 2>&1 || true systemctl daemon-reload systemctl enable cri-docker.socket cri-docker.service echo "=== pause 镜像,写在 kubeadm init 之前 ===" docker pull "$IMG_REPO/pause:3.10.2" docker tag "$IMG_REPO/pause:3.10.2" registry.k8s.io/pause:3.10 mkdir -p /etc/systemd/system/cri-docker.service.d cat > /etc/systemd/system/cri-docker.service.d/pause.conf << 'EOF' [Service] ExecStart= ExecStart=/usr/local/bin/cri-dockerd --container-runtime-endpoint fd:// --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.10.2 EOF systemctl daemon-reload systemctl restart cri-docker.socket systemctl restart cri-docker.service echo "=== kubeadm 1.37.1 ===" install -d -m 0755 /etc/apt/keyrings curl -fsSL https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.37/deb/Release.key \ | gpg --dearmor --yes -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg cat > /etc/apt/sources.list.d/kubernetes.list << 'EOF' deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.37/deb/ / EOF apt-get update systemctl stop kubelet || true systemctl disable kubelet || true apt-get install -y -o Dpkg::Options::=--force-confnew \ kubelet="$KVER" kubeadm="$KVER" kubectl="$KVER" conntrack socat apt-mark hold kubelet kubeadm kubectl systemctl unmask kubelet || true cat > "$WORKDIR/kubeadm-config.yaml" << 'EOF' apiVersion: kubeadm.k8s.io/v1beta4 kind: InitConfiguration localAPIEndpoint: advertiseAddress: 10.0.1.47 bindPort: 6443 nodeRegistration: criSocket: unix:///run/cri-dockerd.sock imagePullPolicy: IfNotPresent name: prod102 kubeletExtraArgs: - name: node-ip value: 10.0.1.47 --- apiVersion: kubeadm.k8s.io/v1beta4 kind: ClusterConfiguration kubernetesVersion: v1.37.1 imageRepository: registry.aliyuncs.com/google_containers controlPlaneEndpoint: 10.0.1.47:6443 networking: podSubnet: 10.244.0.0/16 serviceSubnet: 10.96.0.0/12 apiServer: certSANs: - 10.0.1.47 - prod102 extraArgs: - name: bind-address value: 10.0.1.47 EOF echo "=== 网桥,写在 init 之前,节点才能 Ready ===" cat > /etc/cni/net.d/10-bridge.conflist << 'EOF' { "cniVersion": "1.0.0", "name": "k8s-pod-network", "plugins": [ { "type": "bridge", "bridge": "cni0", "isGateway": true, "ipMasq": true, "promiscMode": true, "ipam": { "type": "host-local", "ranges": [[{"subnet": "10.244.0.0/24"}]], "routes": [{"dst": "0.0.0.0/0"}] } }, { "type": "portmap", "capabilities": {"portMappings": true} } ] } EOF kubeadm config images pull --config "$WORKDIR/kubeadm-config.yaml" kubeadm init --config "$WORKDIR/kubeadm-config.yaml" --ignore-preflight-errors=FileExisting-tc mkdir -p /root/.kube cp /etc/kubernetes/admin.conf /root/.kube/config chmod 600 /root/.kube/config systemctl restart kubelet kubectl taint nodes prod102 node-role.kubernetes.io/control-plane:NoSchedule- || true kubectl wait --for=condition=Ready node/prod102 --timeout=180s kubectl get nodes -o wide echo INSTALL_OK