过程记录


安装虚拟机

# ISO安装系统时配置镜像地址
deb http://mirrors.aliyun.com/ubuntu

# 选择安装、或手动安装 openssh
apt-get update
apt intall -y openssh-server openssh-client

虚拟机基本设置

# 设置ROOT账户密码
sudo passwd root
su

# 设置允许远程登陆root账户
vim /etc/ssh/sshd_config
PermitRootLogin yes

# 重启服务
service ssh restart

# 临时关闭交换空间、永久关闭
sudo swapoff -a
vim /etc/fstab  # 注释掉swap
free -h

# 关闭防火墙
ufw disable

# 禁用安全组策略
setenforce 0
/etc/selinux/config # 将SELINUX=enforcing改为SELINUX=disabled

# 时间同步

网络:修改IP、hostname、域名解析

# 修改成静态 IP
vim /etc/netplan/00-installer-config.yaml
network:
    ethernets:
        enp1s0:
           dhcp4: false
           addresses: [192.168.122.10/24]
           gateway4: 192.168.122.1
           nameservers:
              addresses: [233.5.5.5, 8.8.8.8]
    version: 2

netplan apply
ping baidu.com

# 修改主机名
hostnamectl set-hostname k8s-master
hostnamectl 

cat >>/etc/hosts<< EOF
192.168.122.10 k8s-master
192.168.122.11 k8s-node1
192.168.122.12 k8s-node2
EOF

# 开启转发 IPv4 并让 iptables 看到桥接流量
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 参数而不重新启动
sysctl --system

安装 Docker.io

# 安装 docker.io

apt-get install -y docker.io
docker version
# The following NEW packages will be installed:
#   bridge-utils containerd dns-root-data dnsmasq-base docker.io libidn11 pigz runc ubuntu-fan
# 配置docker镜像源加速
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://XXXXweaag4mq.mirror.aliyuncs.com"]  # 阿里云专属地址在:https://cr.console.aliyun.com 查看
}
EOF

systemctl daemon-reload
systemctl restart docker

# 校验
docker pull helloword
docker info
# 这里不安装docker-ce是因为社区版往往没有经过k8s项目的认证
# —————— 以下存档用,不用执行 ————————
# 安装GPG证书
curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -

# 增加一条软件源信息
add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"

# 更新软件源并升级
apt-get -y update
apt-get upgrade

# 安装依赖
apt-get -y install apt-transport-https ca-certificates curl software-properties-common
apt-get -y install docker.ce

安装 kubeadm、kubectl和kubelet

  • kubeadm:用来初始化集群
  • kubelet:在集群中的每个节点上用来启动 Pod 和容器等
  • kubectl:用来与集群通信的命令行工具
# 安装 GPG 证书
curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -

# 写入软件源
cat << EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF

# 安装 kubeadm,kubectl,kubelet
apt-get install -y kubeadm
# The following NEW packages will be installed:
  conntrack cri-tools ebtables kubeadm kubectl kubelet kubernetes-cni socat

# 开机启动、校验版本
systemctl enable kubelet && systemctl start kubelet
kubeadm version
kubelet version

# 从.deb包安装 containerd,默认不支持 cni,需要注释掉
vim /etc/containerd/config.toml 
# diabled_plugins = ["cri"]
systemctl restart containerd

# 如果上面文件不存在,这样生成
mkdir /etc/containerd
containerd config default > /etc/containerd/config.toml

# 保存镜像,用来快速复制虚拟机
# 增加快照,用来还原环境

容器运行时:

  • containerd:调用链更短,组件更少,更稳定,支持OCI标准,占用节点资源更少。 建议选择 containerd。
  • CRI-O
  • Docker Engine(使用 cri-dockerd)


配置 Master

#打印初始化配置到yaml文件
kubeadm config print init-defaults --kubeconfig ClusterConfiguration > kubeadm.yml

#修改advertiseAddress:为
localAPIEndpoint:
  advertiseAddress: 192.168.122.10 # master的地址
  bindPort: 6443
nodeRegistration:
  criSocket: unix:///var/run/containerd/containerd.sock
  imagePullPolicy: IfNotPresent
  name: k8s-master01 # master节点名称
imageRepository: registry.aliyuncs.com/google_containers # 设置国内镜像地址,加速镜像拉取
networking:
  podSubnet: 10.244.0.0/16 # 设置pod的网络地址,flannel默认是这个地址

#查看所需镜像列表
kubeadm config images list --config kubeadm.yml

#拉取镜像
kubeadm config images pull --config kubeadm.yml

#初始化主节点。追加的 tee kubeadm-init.log 用以输出日志
kubeadm init --config=kubeadm.yml | tee kubeadm-init.log

# 配置kubectl
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config

# 验证
$ kubectl get nodes
# 查看日志
$ journalctl -xeu kubelet
# 或者手动启动kubelet看下日志
$ /usr/bin/kubelet

# 重置节点
$ kubeadm reset
# pause 镜像版本不对
$ containerd config default > /etc/containerd/config.toml

# kubelet的cgroup driver是cgroupfs,docker的 cgroup driver是systemd,两者不一致导致kubelet启动失败
vim /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"]
}

$ systemctl daemon-reload
$ systemctl restart docker 
$ docker info | grep Cgroup
# 解决 kubelet 报错:6443 connection refused(实际上是后面这个问题)
$ netstat -napt | grep 6443
$ ufw enable
$ apt intall firewalld
$ systemctl start firewalld
$ firewall-cmd --zone=public --add-port=6443/tcp --permanent
$ firewall-cmd --reload

# 查看监听的端口
$ ss -ntpl
$ systemctl status containerd
# !!遇到 containerd 的 stop pulling image registry.k8s.io/pause:3.9的问题
# !!导致 kubelet 访问tcp 8080/443都是问题
# 它一直请求的是registry.k8s.io/pause:3.8 这个registry.k8s.io仓库的初始容器3.8版本,和我们上面通过文件所得到的版本不一样且仓库地址不是阿里云的,所以kubelet pause拉取镜像不受imageRepository: registry.aliyuncs.com/google_containers的影响
# 重定向一个标签
ctr -n k8s.io i tag registry.aliyuncs.com/google_containers/pause:3.9  registry.k8s.io/pause:3.8

kubeadm init 的执行过程

  • init:指定版本进行初始化操作
  • preflight:初始化前的检查和下载所需要的 Docker 镜像文件
  • kubelet-start:生成 kubelet 的配置文件 var/lib/kubelet/config.yaml,没有这个文件 kubelet 无法启动,所以初始化之前的 kubelet 实际上启动不会成功
  • certificates:生成 Kubernetes 使用的证书,存放在 /etc/kubernetes/pki 目录中
  • kubeconfig:生成 KubeConfig 文件,存放在 /etc/kubernetes 目录中,组件之间通信需要使用对应文件
  • control-plane:使用 /etc/kubernetes/manifest 目录下的 YAML 文件,安装 Master 组件
  • etcd:使用 /etc/kubernetes/manifest/etcd.yaml 安装 Etcd 服务
  • wait-control-plane:等待 control-plan 部署的 Master 组件启动
  • apiclient:检查 Master 组件服务状态。
  • uploadconfig:更新配置
  • kubelet:使用 configMap 配置 kubelet
  • patchnode:更新 CNI 信息到 Node 上,通过注释的方式记录
  • mark-control-plane:为当前节点打标签,打了角色 Master,和不可调度标签,这样默认就不会使用 Master 节点来运行 Pod
  • bootstrap-token:生成 token 记录下来,后边使用 kubeadm join 往集群中添加节点时会用到
  • addons:安装附加组件 CoreDNS 和 kube-proxy

安装 Flannel 网络插件

# 可以直接下载这个yaml,然后进行修改
 wget https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml

$ kubectl apply -f kube-flannel.yml
namespace/kube-flannel created
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
serviceaccount/flannel created
configmap/kube-flannel-cfg created
daemonset.apps/kube-flannel-ds created

[root@k8s-master01 ~]# kubectl get nodes -o wide
NAME           STATUS   ROLES           AGE     VERSION   INTERNAL-IP    EXTERNAL-IP   OS-IMAGE                KERNEL-VERSION           CONTAINER-RUNTIME
k8s-master01   Ready    control-plane   15m   v1.29.4   192.168.31.7   <none>        CentOS

$ kubectl get pod -n kube-flannel
# 允许 master 节点部署 pod
$ kubectl taint nodes --all node-role.kubernetes.io/master-

$ kubectl delete -f kube-flannel.yml

因为kubelet用的镜像源不对,只能手动下载

$ grep image kube-flannel.yml
$ docker pull docker.io/flannel/flannel:v0.25.4
$ docker pull docker.io/flannel/flannel-cni-plugin:v1.4.1-flannel1

安装CNI插件

$ wget https://github.com/containernetworking/plugins/releases/download/v1.3.0/cni-plugins-linux-amd64-v1.3.0.tgz

$ mkdir -p /opt/cni/bin
$ tar Cxzvf /opt/cni/bin cni-plugins-linux-amd64-v1.3.0.tgz



配置Node

kubeadm join 192.168.122.10:6443 --token m4ip34.lx36pvi6941l56aw --discovery-token-ca-cert-hash sha256:7c6df25d621fbf5ccf2aaa4bf41f1051207994e49e49f9c2240449cea7619a54
# 要是过期了,master执行
kubeadm token create --print-join-command