k8s概述
Kubernetes 是一个可移植、可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化。 Kubernetes 拥有一个庞大且快速增长的生态,其服务、支持和工具的使用范围相当广泛。
Kubernetes 这个名字源于希腊语,意为"舵手"或"飞行员"。k8s 这个缩写是因为 k 和 s 之间有八个字符的关系。 Google 在 2014 年开源了 Kubernetes 项目。 Kubernetes 建立在 Google 大规模运行生产工作负载十几年经验的基础上, 结合了社区中最优秀的想法和实践。
Kubernetes 架构
K8s安装步骤
1、环境要求及准备
- 一台或多台运行兼容 deb/rpm 的 Linux 操作系统的计算机;例如:Ubuntu 或 CentOS。
- 每台机器 2 GB 以上的内存,内存不足时应用会受限制。
- 用作控制平面节点的计算机上至少有 2 个 CPU。
- 集群中所有计算机之间具有完全的网络连接。你可以使用公共网络或专用网络。
准备三台虚拟机
|----------------|------------|
| 节点IP | 节点角色 |
| 192.168.42.138 | k8s-master |
| 192.168.42.139 | k8s-node01 |
| 192.168.42.140 | k8s-node02 |
关闭防火墙firewalld
systemctl stop firewalld
systemctl disable firewalld
关闭selinux
setenforce 0 #临时关闭
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config #永久关闭
时间进行同步
yum install ntpdate -y
ntpdate cn.pool.ntp.org (如果服务器时间不一致才做)
关闭swap
swapoff -a # 临时
sed -i 's/.swap./#&/' /etc/fstab #永久注释swap开机挂载行
三台节点配置主机名解析
bash
cat >> /etc/hosts << EOF
192.168.42.138 k8s-master
192.168.42.139 k8s-node01
192.168.42.140 k8s-node02
EOF
设置主机名
主机名根据自己的主机去使用这条命令,注意要跟上面的主机名解析保持一致
hostnamectl set-hostname xxxx
转发 IPv4 并让 iptables 看到桥接流量
执行下述指令:
bash
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
# 设置所需的 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
通过运行以下指令确认 br_netfilter
和 overlay
模块被加载:
bash
lsmod | grep br_netfilter
lsmod | grep overlay
通过运行以下指令确认 net.bridge.bridge-nf-call-iptables
、net.bridge.bridge-nf-call-ip6tables
和 net.ipv4.ip_forward
系统变量在你的 sysctl
配置中被设置为 1:
bash
sysctl net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv4.ip_forward
2、选择容器运行时
容器运行时是负责运行容器的软件。
在集群内每个节点上都需要安装一个 容器运行时 以使 Pod 可以运行在上面。
常见的容器运行时有:
说明:
v1.24 之前的 Kubernetes 版本直接集成了 Docker Engine 的一个组件,名为 dockershim 。 这种特殊的直接整合不再是 Kubernetes 的一部分 (这次删除被作为 v1.20 发行版本的一部分宣布)。
v1.20版本之后,docker已经从k8s中剥离出来了,但是官方依然支持,只是不再是必须安装的组件。
下面的表格包括被支持的操作系统的已知端点。
运行时 | Unix 域套接字 |
---|---|
containerd | unix:///var/run/containerd/containerd.sock |
CRI-O | unix:///var/run/crio/crio.sock |
Docker Engine(使用 cri-dockerd) | unix:///var/run/cri-dockerd.sock |
这里我们依旧选择当下最流行的Docker引擎做容器运行时:
Docker Engine安装
这里使用rpm包管理工具安装docker最新版,也是官方文档提供的安装方案
注意:三台节点都需要容器运行时,也就是都要安装docker
Install Docker Engine on CentOS | Docker Docs
2.1 设置镜像仓库
bash
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
这两个命令执行完后,会在系统上自动下载对应的docker-ce.repo文件。
2.2 安装docker引擎
bash
sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
2.3 启动服务
bash
sudo systemctl start docker
镜像加速器
Daocloud公司建议使用,提高镜像下载速度,使用k8s官方默认的cgroup的
bash
#vi /etc/docker/daemon.json
{
"registry-mirrors": ["http://f1361db2.m.daocloud.io"],
"exec-opts":["native.cgroupdriver=systemd"]
}
重启docker
#systemctl restart docker
3、安装 kubeadm、kubelet 和 kubectl
-
kubeadm
:用来初始化集群的指令。 -
kubelet
:在集群中的每个节点上用来启动 Pod 和容器等。 -
kubectl
:用来与集群通信的命令行工具。
注意:三台节点都安装
3.1 添加 Kubernetes 的 yum
仓库
bash
# 此操作会覆盖 /etc/yum.repos.d/kubernetes.repo 中现存的所有配置
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.29/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.29/rpm/repodata/repomd.xml.key
exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni
EOF
3.2 安装 kubelet、kubeadm 和 kubectl,并启用 kubelet 以确保它在启动时自动启动
bash
sudo yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
sudo systemctl enable --now kubelet
4、使用 kubeadm 创建集群
4.1 初始化控制平面节点
控制平面节点是运行控制平面组件的机器, 包括 etcd(集群数据库) 和 API 服务器 (命令行工具 kubectl 与之通信)。
要初始化控制平面节点,请运行:
kubeadm init <args>
实际命令:
注意:这个初始化命令只在k8s-master节点执行
kubeadm init --apiserver-advertise-address=192.168.42.138 --control-plane-endpoint=k8s-master --image-repository registry.cn-hangzhou.aliyuncs.com/google_containers --kubernetes-version v1.29.2 --service-cidr=10.96.0.0/16 --pod-network-cidr=10.244.0.0/16
参数解释:
--apiserver-advertise-address
可用于为控制平面节点的 API 服务器设置广播地址
--control-plane-endpoint
可用于为所有控制平面节点设置共享端点,允许 IP 地址和可以映射到 IP 地址的 DNS 名称。
--image-repository 声明使用阿里云官方镜像
--kubernetes-version 指定k8s安装的版本,这里我安装最新的
--service-cidr 集群内部虚拟网络,Pod统一访问入口
--pod-network-cidr Pod网络,与下面部署的CNI网络组件yaml中保持一致
初始化过程
kubeadm init
首先运行一系列预检查以确保机器为运行 Kubernetes 准备就绪。 这些预检查会显示警告并在错误时退出。然后 kubeadm init
下载并安装集群控制平面组件。这可能会需要几分钟。
完成之后你应该看到:
要使非 root 用户可以运行 kubectl,请运行以下命令, 它们也是 kubeadm init
输出的一部分:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
或者,如果你是 root
用户,则可以运行:
bash
export KUBECONFIG=/etc/kubernetes/admin.conf
记录 kubeadm init
输出的 kubeadm join
命令。 你需要此命令将节点加入集群。
4.2 将节点加入集群
在其他从节点上执行如下命令,这个命令的token以你的虚拟机kubeadm init为准
139执行:
140执行:
4.3 验证安装结果
提示使用kubectl get nodes在控制节点查看从节点的加入情况,当然其他节点也可以执行
在139执行命令报错如下:
出现这个问题的原因是kubectl命令需要使用kubernetes-admin来运行
解决办法:
1.将主节点(master节点)中的【/etc/kubernetes/admin.conf】文件拷贝到从节点相同目录下:
2.从节点配置环境变量
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
3.立即生效
source ~/.bash_profile
两个node执行后则再指令kubectl get nodes命令则都可以返回
注意:以前老版本的Roles字段显示master,新版本已经被control-plane替代
5、安装 Pod 网络附加组件
bash
[root@k8s-master ~]# kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
5、验证安装结果
出现上述结果,说明我们已经安装成功!
也可通过查看kube-system名字空间下的pod资源判断
当所有组件状态都是running时才能确保k8s正常使用。
过程中报错
1、CNI网络插件未初始化
"Container runtime network not ready" networkReady="NetworkReady=false reason:NetworkPluginNotReady message:Network plugin returns error: cni plugin not initialized"
解决方案:
三台节点都重启kubelet进程后再查看node状态
2、无法从API端点获取集群ConfigMap信息
Unable to fetch the kubeadm-config ConfigMap from cluster: failed to get config map: Get "https://master:6443/api/v1/namespaces/kube-system/configmaps/kubeadm-config?timeout=10s": dial tcp: lookup master on 223.5.5.5:53: no such host
这个报错是由于我之前把kubeadm init命令那里的--control-plane-endpoint=master,我实际上是k8s-master,导致主机名解析失败,找不到https://master:6443/api/v1/namespaces/kube-system/configmaps/kubeadm-config?timeout=10s这个api端点,那必然会报错,修改正确后,使用kubeadm reset重置,然后重新Init就好了
3、拉取 registry.k8s.io/pause:3.6 镜像失败 导致sandbox 创建不了而报错
*报错:*detected that the sandbox image "registry.k8s.io/pause:3.6" of the container runtime is inconsistent with that used by kubeadm. It is recommended that using "registry.aliyuncs.com/google_containers/pause:3.9" as the CRI sandbox image.
解决方案:
bash
### 三台节点执行如下命令 生成 containerd 的默认配置文件
containerd config default > /etc/containerd/config.toml
### 查看 sandbox 的默认镜像仓库在文件中的第几行
cat /etc/containerd/config.toml | grep -n "sandbox_image"
### 使用 vim 编辑器 定位到 sandbox_image,将 仓库地址修改成 registry.aliyuncs.com/google_containers/pause:3.9/pause:3.6
vim /etc/containerd/config.toml
sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.9/pause:3.6"
### 重启 containerd 服务
systemctl daemon-reload
systemctl restart containerd.service
修改完成后记得重启containerd服务
4、k8s初始化int时出现Initial timeout of 40s passed
可以先使用以下命令查看k8s的启动日志:
systemctl status kubelet
或使用以下命令查看最近的k8s日志:
journalctl -xeu kubelet
具体参考:k8s初始化int时出现Initial timeout of 40s passed | 思维网络|站长博客|陈配锋