准备机器

我的机器详情如下,配置至少为 4C4G

hostname IP 作用
public 10.0.0.3 ingress 和 apiserver 的负载均衡,nfs 存储
master1 10.0.0.11 k8s master 节点
master2 10.0.0.12 k8s master 节点
master3 10.0.0.13 k8s master 节点
worker1 10.0.0.21 k8s worker 节点
worker2 10.0.0.22 k8s worker 节点

替换软件源

在2022年1月31日,CentOS团队终于从官方镜像中移除CentOS 8的所有包。
CentOS 8已于2021年12月31日寿终正非,但软件包仍在官方镜像上保留了一段时间。现在他们被转移到https://vault.centos.org

使用vault.centos.org代替mirror.centos.org

sudo sed -i -e "s|mirrorlist=|#mirrorlist=|g" /etc/yum.repos.d/CentOS-*
sudo sed -i -e "s|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g" /etc/yum.repos.d/CentOS-*

每台机器都做域名解析,或者绑定 hosts (可选但建议)

vim /etc/hosts

10.0.0.3  public kube-apiserver
10.0.0.11 master1
10.0.0.12 master2
10.0.0.13 master3

每台机器都关闭防火墙和 SELinux

负载均衡机器必须要关闭,因为 6443 不是 nginx 的标准端口,会被 selinux 拦截,防火墙也需要放行 6443 端口,可以考虑直接关闭

sudo systemctl disable --now firewalld
setenforce 0
sed -i "s/^SELINUX=.*/SELINUX=disabled/g" /etc/selinux/config

基础环境配置

基础环境是不管 master 还是 worker 都需要的环境

  1. 禁用 swap
  2. 确保每个节点上 MAC 地址和 product_uuid 的唯一性 sudo cat /sys/class/dmi/id/product_uuid
  3. 修改 hostname
  4. 允许 iptables 检查桥接流量
swapoff -a  
sed -ri 's/.*swap.*/#&/' /etc/fstab

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF

cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sudo sysctl --system

安装 runtime

  • Containerd

先决条件

BASH
cat <<EOF | sudo tee /etc/modules-load.d/containerd.conf
overlay
br_netfilter
EOF

sudo modprobe overlay
sudo modprobe br_netfilter

# 设置必需的 sysctl 参数,这些参数在重新启动后仍然存在。
cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf
net.bridge.bridge-nf-call-iptables  = 1
net.ipv4.ip_forward                 = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF

# 应用 sysctl 参数而无需重新启动
sudo sysctl --system

安装

BASH
# 卸载旧版本Docker
sudo yum remove docker \
        docker-client \
        docker-client-latest \
        docker-common \
        docker-latest \
        docker-latest-logrotate \
        docker-logrotate \
        docker-engine

# 安装docker仓库
sudo yum install -y yum-utils
sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo

# 安装containerd
sudo yum install containerd.io -y

配置

生成默认配置

sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml

结合 runc 使用 systemd cgroup 驱动,在 /etc/containerd/config.toml 中设置

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
...
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
   SystemdCgroup = true
  
# 修改/etc/containerd/config.toml 文件
sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.6"
  
# containerd开机自启
systemctl enable --now containerd


# 重启containerd
sudo systemctl restart containerd

crictl 配置

之前使用 docker 的时候,docker 给我们做了很多好用的工具,现在用了 containerd,管理容器我们用 cri 管理工具 crictl,创建配置文件

vim /etc/crictl.yaml

runtime-endpoint: unix:///run/containerd/containerd.sock
debug: false

Docker

安装 Docker

curl -fsSL get.docker.com | bash

配置 Doker

sudo mkdir /etc/docker
cat <<EOF | sudo tee /etc/docker/daemon.json
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2"
}
EOF

sudo systemctl restart docker

安装 kubeadm、kubelet 和 kubectl

  • 使用阿里云镜像仓库
# 创建仓库文件
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

setenforce 0

# 安装指定版本的kubeadm
yum install -y --nogpgcheck kubelet-1.25.0 kubeadm-1.25.0 kubectl-1.25.0

# 启动kubelet
systemctl enable --now kubelet

准备负载均衡

  • 使用 Nginx 做负载均衡

vim nginx.conf 在文件最后添加

PLAINTEXT
stream {
    include stream.conf;
}

然后 vim /etc/nginx/stream.conf

upstream k8s-apiserver {
    server master1:6443;
    server master2:6443;
    server master3:6443;
}
server {
    listen 6443;
    proxy_connect_timeout 1s;
    proxy_pass k8s-apiserver;
}
upstream ingress-http {
    server 10.0.0.21:30080;   # 这里需要更改成ingress的NodePort
    server 10.0.0.22:30080;   # 这里需要更改成ingress的NodePort
}
server {
    listen 80;
    proxy_connect_timeout 1s;
    proxy_pass ingress-http;
}
upstream ingress-https {
    server 10.0.0.21:30443;   # 这里需要更改成ingress的NodePort
    server 10.0.0.22:30443;   # 这里需要更改成ingress的NodePort
}
server {
    listen 443;
    proxy_connect_timeout 1s;
    proxy_pass ingress-https;
}

创建集群

kubeadm init

  • 国内阿里云镜像源

在 init 之前先将镜像拉取到本地(可选步骤)

kubeadm config images pull --kubernetes-version 1.21.10 --image-repository registry.cn-hangzhou.aliyuncs.com/google_containers

在 k8s-master0 上执行

sudo kubeadm init \
--kubernetes-version 1.21.10 \
--control-plane-endpoint "kube-apiserver:6443" \
--image-repository registry.cn-hangzhou.aliyuncs.com/google_containers \
--upload-certs \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16
非高可用初始化
sudo kubeadm init \
--kubernetes-version 1.25.3 \
--apiserver-advertise-address 192.168.200.20 \
--image-repository registry.cn-hangzhou.aliyuncs.com/google_containers \
--upload-certs \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16
使用阿里云镜像初始化失败
# 启动containerd开机自启
systemctl enable --now containerd

# 修改/etc/containerd/config.toml 文件
sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.6"

# 重启一下containerd
systemctl restart containerd.service

也可以用 kubeadm config print init-defaults > init.yaml 生成 kubeadm 的配置,并用
kubeadm init --config=init.yaml 来创建集群。

安装网络插件

  • 安装 flannel 插件
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

获取 join 命令,增加新的节点

node

kubeadm init 后会输出在终端上,有效期 2 小时,超时后可以重新生成

生成添加命令:


kubeadm token create --print-join-command

master

  1. 生成证书,记录 certificate key

    
    kubeadm init phase upload-certs --upload-certs
    
  2. 获取加入命令

    
    kubeadm token create --print-join-command
    
  3. 上面两步可以简化成

    
    echo "$(kubeadm token create --print-join-command) --control-plane --certificate-key $(kubeadm init phase upload-certs --upload-certs | tail -1)"
    
查看节点和运行情况
# 查看所有节点状态
kubectl get nodes

# 查看pod组件运行状态
kubectl get pods -A

移除节点

移除节点


kubectl drain worker2 --ignore-daemonsets
kubectl delete node worker2

如果是 master 节点还需要移除 etcd member


kubectl exec -it -n kube-system etcd-master1 -- /bin/sh

# 查看etcd member list
etcdctl --endpoints 127.0.0.1:2379 --cacert /etc/kubernetes/pki/etcd/ca.crt --cert /etc/kubernetes/pki/etcd/server.crt --key /etc/kubernetes/pki/etcd/server.key member list

# 通过ID来删除etcd member
etcdctl --endpoints 127.0.0.1:2379 --cacert /etc/kubernetes/pki/etcd/ca.crt --cert /etc/kubernetes/pki/etcd/server.crt --key /etc/kubernetes/pki/etcd/server.key member remove 12637f5ec2bd02b8

文章作者: 张理坤