• 本文介绍基于 kubeadm + 内地网络 进行 k8s 集群部署。
  • 本文介绍搭建单 master 节点 k8s 集群,适用于开发及测试,一般不适用生产环境。

环境准备

主机配置要求

  • k8s 集群要求机器最低配置为 2CPU 2GRAM

关闭防火墙、交换分区、selinux

# 防火墙   
systemctl status firewalld
# 如果没有firewalld.service,执行如下命令
sudo ufw status
sudo ufw disable

# 关闭swap
swapoff -a
cat /etc/fstab | grep swap
# 删除或注释掉带有swap关键字的行
vi /etc/fstab

# selinux
# 检查 结果为Disabled即为关闭状态
apt update -y
apt install -y selinux-utils
getenforce
# 如果selinux是启用状态,则需要永久关闭,关闭后重启机器方可生效
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
reboot

应用安装

安装容器运行时(CR)

  • 自 1.24 版起,Dockershim 已从 Kubernetes 项目中移除,本文只介绍 containerd 的安装。

允许 iptables 检查桥接流量

# 确保overlay br_netfilter内核模块加载
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

sudo modprobe overlay
sudo modprobe br_netfilter

# 为了Linux 节点上的 iptables 能够正确地查看桥接流量,需要确保在sysctl 配置中将 net.bridge.bridge-nf-call-iptables 设置为 1
# 设置所需的 sysctl 参数,参数在重新启动后保持不变
cat <<EOF | sudo 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 参数而不重新启动
sudo sysctl --system

containerd安装

  • 安装 apt repository
# 删除旧版本(如果存在的话)
sudo apt-get remove docker docker-engine docker.io containerd runc

sudo apt-get update -y
sudo apt-get install -y apt-transport-https ca-certificates curl gnupg lsb-release software-properties-common

sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
  • 安装 containerd
sudo apt-get update -y
sudo apt-get install containerd.io=1.6.20-1
  • 配置 containerd
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml

# 设置SystemdCgroup
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml

# 修改pause镜像地址
sudo sed -i 's/registry.k8s.io/registry.aliyuncs.com\/google_containers/g' /etc/containerd/config.toml

sudo systemctl restart containerd
  • 配置镜像加速
mkdir -p /etc/containerd/certs.d/docker.io
sed -i 's/\(config_path *= *\)"[^"]*"/\1"\/etc\/containerd\/certs.d"/' /etc/containerd/config.toml

cat > /etc/containerd/certs.d/docker.io/hosts.toml << EOF
server = "https://docker.io"
[host."https://9ptmljtk.mirror.aliyuncs.com"]
  capabilities = ["pull", "resolve"]
EOF

sudo systemctl restart containerd
  • 安装 crictl
VERSION="v1.25.0"
wget https://github.com/kubernetes-sigs/cri-tools/releases/download/$VERSION/crictl-$VERSION-linux-amd64.tar.gz
sudo tar zxvf crictl-$VERSION-linux-amd64.tar.gz -C /usr/local/bin
rm -f crictl-$VERSION-linux-amd64.tar.gz
  • 设置运行时,crictl 默认连接到 unix:///var/run/dockershim.sock,我们需要将其改为 containerd 的 socket
# 配置
sudo crictl config runtime-endpoint unix:///run/containerd/containerd.sock
sudo crictl config image-endpoint unix:///run/containerd/containerd.sock
# 检查结果
cat /etc/crictl.yaml

安装kubeadm、kubelet 和 kubectl

  • 在使用的机器上面都需要安装以下软件包
    • kubeadm:用来初始化集群的指令。
    • kubelet:在集群中的每个节点上用来启动 Pod 和容器等。
    • kubectl:用来与集群通信的命令行工具。
  • 更新包索引、安装必要软件
sudo apt-get update -y
sudo apt-get install -y apt-transport-https ca-certificates curl
  • 从阿里镜像仓库下载密钥(无网络限制的话可以从 google 地址下载)
sudo curl -s https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add -
  • 添加 k8s apt 仓库(无网络限制的话可以添加为 google 地址)
sudo tee /etc/apt/sources.list.d/kubernetes.list <<-'EOF'
deb https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial main
EOF
  • 更新包索引,安装 kubelet、kubeadm 和 kubectl,并锁定其版本
# 旧版本清理
sudo apt remove -y kubeadm kubelet kubectl
sudo apt autoremove -y
# 安装
sudo apt-get update -y
sudo apt-get install -y kubelet=1.26.4-00 kubeadm=1.26.4-00 kubectl=1.26.4-00
sudo apt-mark hold kubelet kubeadm kubectl

集群初始化

kubeadm init

  • kubeadm config: 初始化配置文件,指定 apiServer endpoint 等地址
cat > /etc/kubernetes/config.yaml << EOF
apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
nodeRegistration:
  criSocket: "unix:///run/containerd/containerd.sock"
  taints: [ ]
  imagePullPolicy: "IfNotPresent"
localAPIEndpoint:
  # 公布 apiServer 正在监听的 IP 地址,需要替换为自己主机的 ip 地址
  advertiseAddress: "10.10.98.36"
  bindPort: 6443
skipPhases:
  # 如果安装的网络插件为cilium, 可跳过 kube-proxy 的安装, 因为 cilium 内置 Host-Reachable Services 功能可以替换 kube-proxy
  - addon/kube-proxy
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
kubernetesVersion: 1.26.4
# 公布 apiServer 正在监听的 IP 地址,需要替换为自己主机的 ip 地址
controlPlaneEndpoint: "10.10.98.36:6443"
certificatesDir: "/etc/kubernetes/pki"
imageRepository: "registry.aliyuncs.com/google_containers"
EOF
  • kubeadm init
kubeadm init --config /etc/kubernetes/config.yaml
  • 如果此步骤出错可运行kubeadm reset --force重置kubeadm状态,然后进行检查。
  • 使非 root 用户可以运行 kubectl
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
  • root用户
export KUBECONFIG=/etc/kubernetes/admin.conf
  • 默认情况下,出于安全原因,你的集群不会在控制平面节点上调度 Pod。 如果你希望能够在控制平面节点上调度 Pod, 例如用于开发的单机 Kubernetes 集群,请运行:
kubectl taint nodes --all node-role.kubernetes.io/control-plane-

安装 helm

  • 安装 k8s 包管理工具 helm,后续可以使用 helm 来进行应用安装。
curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null
sudo apt-get install apt-transport-https --yes
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
sudo apt-get update
sudo apt-get install helm

安装网络插件

  • 你必须部署一个基于 Pod 网络插件的容器网络接口 (CNI),以便你的 Pod 可以相互通信。 在安装网络之前,集群 DNS (CoreDNS) 将不会启动。

  • 每个集群只能安装一中 Pod 网络插件。

  • 常见的pod网络插件有 Calico、Flannel、Cilium 等,本文以 Cilium 插件安装做示例,其余两种插件安装可参考对应的官网。

    • Cilium

      # add helm repo
      helm repo add cilium https://helm.cilium.io/
      # helm install
      API_SERVER_IP=10.10.98.36
      API_SERVER_PORT=6443
      helm upgrade --install cilium cilium/cilium \
          --namespace kube-system \
          --version 1.13.1 \
          --set kubeProxyReplacement=strict \
          --set k8sServiceHost=${API_SERVER_IP} \
          --set k8sServicePort=${API_SERVER_PORT} \
          --set operator.replicas=1
      ### 参数说明
      kubeProxyReplacement: cilium agent是否在底层 Linux 内核支持缺失的情况下退出, 没有安装 kube-proxy 的情况下配置 strict, 表示内核不支持的话就退出.
      k8sServiceHost: apiserver ip
      k8sServicePort: apiserver port
      
  • 由于每个人使用的机器网络状况不一样,所以安装网络插件后要等待一定的时间,等待相关 pod 就绪后再检查集群状态是否正常。

健康检查

  • 检查网络
# 在以下命令输出中检查 CoreDNS Pod 是否 Running 来确认其是否正常运行。
kubectl get pods --all-namespaces
  • apiserver健康端点
curl -k https://localhost:6443/livez?verbose

# 以上命令输出结果如下时证明 kube-apiserver 状态正常
[+]ping ok
[+]log ok
[+]etcd ok
[+]poststarthook/start-kube-apiserver-admission-initializer ok
[+]poststarthook/generic-apiserver-start-informers ok
[+]poststarthook/start-apiextensions-informers ok
[+]poststarthook/start-apiextensions-controllers ok
[+]poststarthook/crd-informer-synced ok
[+]poststarthook/bootstrap-controller ok
[+]poststarthook/rbac/bootstrap-roles ok
[+]poststarthook/scheduling/bootstrap-system-priority-classes ok
[+]poststarthook/start-cluster-authentication-info-controller ok
[+]poststarthook/start-kube-aggregator-informers ok
[+]poststarthook/apiservice-registration-controller ok
[+]poststarthook/apiservice-status-available-controller ok
[+]poststarthook/kube-apiserver-autoregistration ok
[+]autoregister-completion ok
[+]poststarthook/apiservice-openapi-controller ok
healthz check passed
  • 同样的,可以使用 k8s 部署一个例如 nginx 的应用 pod ,然后使用 service 将资源公开,使用 curl 进行访问,测试集群是否正常,此处不做赘述。

参考资料