温馨提示请仔细阅读:❤️❤️❤️❤️❤️❤️❤️❤️
1. 由于新版的k8s不支持docker了,因此开始前建议新开一台全新的虚拟机
2. 全程安装过程最大的问题是网络问题,经常需要拉取到外网的东西,如果条件允许请准备好魔法上网
3. 请在每一步进行之前妥善利用快照功能,避免一切前功尽弃,有时候网络问题重来一次方便过去解决网络问题产生的麻烦
4. 建议安装完docker后才克隆新的虚拟机能减轻工作,注意文章标题,并不是所有虚拟机都需要进行相同操作
此教程为k8s当前官方最新版1.27.1集群搭建教程(一切基于k8s官方文档进行搭建,若遇到教程以外问题请仔细参考官方文档,全网资料少,此教程亲测可用!
官方文档链接:====> 《Kubernetes 文档 | Kubernetes》
Kubernetes 是一个可移植、可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化。 Kubernetes 拥有一个庞大且快速增长的生态,其服务、支持和工具的使用范围相当广泛。
Kubernetes 这个名字源于希腊语,意为“舵手”或“飞行员”。k8s 这个缩写是因为 k 和 s 之间有八个字符的关系。 Google 在 2014 年开源了 Kubernetes 项目。 Kubernetes 建立在 Google 大规模运行生产工作负载十几年经验的基础上, 结合了社区中最优秀的想法和实践。
容器是打包和运行应用程序的好方式。在生产环境中, 你需要管理运行着应用程序的容器,并确保服务不会下线。 例如,如果一个容器发生故障,则你需要启动另一个容器。 如果此行为交由给系统处理,是不是会更容易一些?
这就是 Kubernetes 要来做的事情! Kubernetes 为你提供了一个可弹性运行分布式系统的框架。 Kubernetes 会满足你的扩展要求、故障转移你的应用、提供部署模式等。 例如,Kubernetes 可以轻松管理系统的 Canary (金丝雀) 部署。
Kubernetes 为你提供:
服务发现和负载均衡
Kubernetes 可以使用 DNS 名称或自己的 IP 地址来暴露容器。 如果进入容器的流量很大, Kubernetes 可以负载均衡并分配网络流量,从而使部署稳定。
存储编排
Kubernetes 允许你自动挂载你选择的存储系统,例如本地存储、公共云提供商等。
自动部署和回滚
你可以使用 Kubernetes 描述已部署容器的所需状态, 它可以以受控的速率将实际状态更改为期望状态。 例如,你可以自动化 Kubernetes 来为你的部署创建新容器, 删除现有容器并将它们的所有资源用于新容器。
自动完成装箱计算
你为 Kubernetes 提供许多节点组成的集群,在这个集群上运行容器化的任务。 你告诉 Kubernetes 每个容器需要多少 CPU 和内存 (RAM)。 Kubernetes 可以将这些容器按实际情况调度到你的节点上,以最佳方式利用你的资源。
自我修复
Kubernetes 将重新启动失败的容器、替换容器、杀死不响应用户定义的运行状况检查的容器, 并且在准备好服务之前不将其通告给客户端。
密钥与配置管理
Kubernetes 允许你存储和管理敏感信息,例如密码、OAuth 令牌和 ssh 密钥。 你可以在不重建容器镜像的情况下部署和更新密钥和应用程序配置,也无需在堆栈配置中暴露密钥。
Kubernetes 不是传统的、包罗万象的 PaaS(平台即服务)系统。 由于 Kubernetes 是在容器级别运行,而非在硬件级别,它提供了 PaaS 产品共有的一些普遍适用的功能, 例如部署、扩展、负载均衡,允许用户集成他们的日志记录、监控和警报方案。 但是,Kubernetes 不是单体式(monolithic)系统,那些默认解决方案都是可选、可插拔的。 Kubernetes 为构建开发人员平台提供了基础,但是在重要的地方保留了用户选择权,能有更高的灵活性。
Kubernetes:
不限制支持的应用程序类型。 Kubernetes 旨在支持极其多种多样的工作负载,包括无状态、有状态和数据处理工作负载。 如果应用程序可以在容器中运行,那么它应该可以在 Kubernetes 上很好地运行。
不部署源代码,也不构建你的应用程序。 持续集成(CI)、交付和部署(CI/CD)工作流取决于组织的文化和偏好以及技术要求。
不提供应用程序级别的服务作为内置服务,例如中间件(例如消息中间件)、 数据处理框架(例如 Spark)、数据库(例如 MySQL)、缓存、集群存储系统 (例如 Ceph)。这样的组件可以在 Kubernetes 上运行,并且/或者可以由运行在 Kubernetes 上的应用程序通过可移植机制(例如开放服务代理)来访问。
不是日志记录、监视或警报的解决方案。 它集成了一些功能作为概念证明,并提供了收集和导出指标的机制。
不提供也不要求配置用的语言、系统(例如 jsonnet),它提供了声明性 API, 该声明性 API 可以由任意形式的声明性规范所构成。
不提供也不采用任何全面的机器配置、维护、管理或自我修复系统。
此外,Kubernetes 不仅仅是一个编排系统,实际上它消除了编排的需要。 编排的技术定义是执行已定义的工作流程:首先执行 A,然后执行 B,再执行 C。 而 Kubernetes 包含了一组独立可组合的控制过程,可以持续地将当前状态驱动到所提供的预期状态。 你不需要在乎如何从 A 移动到 C,也不需要集中控制,这使得系统更易于使用且功能更强大、 系统更健壮,更为弹性和可扩展。
一键安装最新版docker
curl -fsSL https://test.docker.com -o test-docker.sh
将docker加入用户组
sudo sh test-docker.sh
sudo gpasswd -a $USER docker
newgrp docker
安装完docker以后,克隆两台新的虚拟机用作k8s节点(克隆完成后)
# 获取网络接口的 MAC 地址(对比一下三台虚拟机)
ip link
# 对 product_uuid 校验
sudo cat /sys/class/dmi/id/product_uuid
一般来讲,硬件设备会拥有唯一的地址,但是有些虚拟机的地址可能会重复。 Kubernetes 使用这些值来唯一确定集群中的节点。 如果这些值在每个节点上不唯一,可能会导致安装失败。
如果你有一个以上的网络适配器,同时你的 Kubernetes 组件通过默认路由不可达,我们建议你预先添加 IP 路由规则, 这样 Kubernetes 集群就可以通过对应的适配器完成连接。
启用这些必要的端口后才能使 Kubernetes 的各组件相互通信。 可以使用 netcat 之类的工具来检查端口是否启用,例如:
nc 127.0.0.1 6443
进入/etc/hosts,配置域名解析(三台虚拟机都需要进行操作)
master节点ip k8smaster.example.net k8smaster
node01节点ip k8sworker1.example.net k8sworker1
node02节点ip k8sworker2.example.net k8sworker2
exec bash
Kubernetes 命令行工具 kubectl, 让你可以对 Kubernetes 集群运行命令。 你可以使用 kubectl 来部署应用、监测和管理集群资源以及查看日志。
kubectl 版本和集群版本之间的差异必须在一个小版本号内。 例如:v1.27 版本的客户端能与 v1.26、 v1.27 和 v1.28 版本的控制面通信。 用最新兼容版的 kubectl 有助于避免不可预见的问题。
参考文档:在 Linux 系统中安装并设置 kubectl | Kubernetes
存在多种安装方式:以下仅介绍使用curl在Linux系统中安装的安装方式,记着进root
# x86-64架构
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
# ARM64
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/arm64/kubectl"
下载 kubectl 校验和文件:
# x86-64架构
curl -LO "https://dl.k8s.io/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl.sha256"
# ARM64
curl -LO "https://dl.k8s.io/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/arm64/kubectl.sha256"
基于校验和文件,验证 kubectl 的可执行文件:
echo "$(cat kubectl.sha256) kubectl" | sha256sum --check
验证通过时,输出为:
kubectl: OK
验证失败时,sha256
将以非零值退出,并打印如下输出:
kubectl: FAILED
sha256sum: WARNING: 1 computed checksum did NOT match
说明: 下载的 kubectl 与校验和文件版本必须相同。
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
kubectl version --client
说明:
上面的命令会产生一个警告:
WARNING: This version information is deprecated and will be replaced with the output from kubectl version --short.
你可以忽略这个警告。你只检查你所安装的 kubectl
的版本。
或者使用如下命令来查看版本的详细信息:
kubectl version --client --output=yaml
说明: 自 1.24 版起,Dockershim 已从 Kubernetes 项目中移除。
你需要在集群内每个节点上安装一个 容器运行时以使 Pod 可以运行在上面。本文概述了所涉及的内容并描述了与节点设置相关的任务。
Kubernetes 1.27 要求你使用符合容器运行时接口(CRI)的运行时。
以下步骤将通用设置应用于 Linux 上的 Kubernetes 节点。
如果你确定不需要某个特定设置,则可以跳过它。
执行下述指令:
cat <
通过运行以下指令确认 br_netfilter
和 overlay
模块被加载:
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:
sysctl net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv4.ip_forward
省流版:Ubuntu 22 选择的是systemd驱动
(如果可以请抽空看看以下知识点,有助于帮助理解)
在 Linux 上,控制组(CGroup)用于限制分配给进程的资源。
kubelet 和底层容器运行时都需要对接控制组来强制执行 为 Pod 和容器管理资源并为诸如 CPU、内存这类资源设置请求和限制。若要对接控制组,kubelet 和容器运行时需要使用一个 cgroup 驱动。 关键的一点是 kubelet 和容器运行时需使用相同的 cgroup 驱动并且采用相同的配置。
可用的 cgroup 驱动有两个:
cgroupfs 驱动
cgroupfs
驱动是 kubelet 中默认的 cgroup 驱动。当使用 cgroupfs
驱动时, kubelet 和容器运行时将直接对接 cgroup 文件系统来配置 cgroup。
当 systemd是初始化系统时, 不 推荐使用 cgroupfs
驱动,因为 systemd 期望系统上只有一个 cgroup 管理器。 此外,如果你使用 cgroup v2, 则应用 systemd
cgroup 驱动取代 cgroupfs
。
systemd cgroup 驱动
当某个 Linux 系统发行版使用 systemd作为其初始化系统时,初始化进程会生成并使用一个 root 控制组(cgroup
),并充当 cgroup 管理器。
systemd 与 cgroup 集成紧密,并将为每个 systemd 单元分配一个 cgroup。 因此,如果你 systemd
用作初始化系统,同时使用 cgroupfs
驱动,则系统中会存在两个不同的 cgroup 管理器。
同时存在两个 cgroup 管理器将造成系统中针对可用的资源和使用中的资源出现两个视图。某些情况下, 将 kubelet 和容器运行时配置为使用 cgroupfs
、但为剩余的进程使用 systemd
的那些节点将在资源压力增大时变得不稳定。
当 systemd 是选定的初始化系统时,缓解这个不稳定问题的方法是针对 kubelet 和容器运行时将 systemd
用作 cgroup 驱动。
我们将在 Kubernetes 集群中使用containerd 运行时,首先要安装它的依赖项。
sudo apt install -y curl gnupg2 software-properties-common apt-transport-https ca-certificates
启用 docker 存储库
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmour -o /etc/apt/trusted.gpg.d/docker.gpg
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
运行以下 apt 命令安装 containerd
sudo apt update
sudo apt install -y containerd.io
配置 containerd,使它使用 systemd 作为 cgroup**(关键步骤,没改后面一定错!~)**
containerd config default | sudo tee /etc/containerd/config.toml >/dev/null 2>&1
sudo sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/g' /etc/containerd/config.toml
重启并启用 containerd 服务
sudo systemctl restart containerd
sudo systemctl enable containerd
请在开始这一步之前确保你的容器运行时安装成功!!!!!!!
你需要在每台机器上安装以下的软件包:
kubeadm
:用来初始化集群的指令。kubelet
:在集群中的每个节点上用来启动 Pod 和容器等。kubectl
:用来与集群通信的命令行工具。kubeadm 不能帮你安装或者管理 kubelet
或 kubectl
, 所以你需要确保它们与通过 kubeadm 安装的控制平面的版本相匹配。 如果不这样做,则存在发生版本偏差的风险,可能会导致一些预料之外的错误和问题。 然而,控制平面与 kubelet 之间可以存在一个次要版本的偏差,但 kubelet 的版本不可以超过 API 服务器的版本。 例如,1.7.0 版本的 kubelet 可以完全兼容 1.8.0 版本的 API 服务器,反之则不可以。
一台兼容的 Linux 主机。Kubernetes 项目为基于 Debian 和 Red Hat 的 Linux 发行版以及一些不提供包管理器的发行版提供通用的指令。
每台机器 2 GB 或更多的 RAM(如果少于这个数字将会影响你应用的运行内存)。
CPU 2 核心及以上。
集群中的所有机器的网络彼此均能相互连接(公网和内网都可以)。
节点之中不可以有重复的主机名、MAC 地址或 product_uuid。开启机器上的某些端口。
禁用交换分区。为了保证 kubelet 正常工作,你必须禁用交换分区。
sudo swapoff -a
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
在所有节点上加载以下内核模块
sudo tee /etc/modules-load.d/containerd.conf <
为 Kubernetes 设置以下内核参数,运行如下的 tee命令
sudo tee /etc/sysctl.d/kubernetes.conf <
重新加载上述更改,运行
sudo sysctl --system
ip link
或 ifconfig -a
来获取网络接口的 MAC 地址sudo cat /sys/class/dmi/id/product_uuid
命令对 product_uuid 校验一般来讲,硬件设备会拥有唯一的地址,但是有些虚拟机的地址可能会重复。 Kubernetes 使用这些值来唯一确定集群中的节点。 如果这些值在每个节点上不唯一,可能会导致安装失败。
如果你有一个以上的网络适配器,同时你的 Kubernetes 组件通过默认路由不可达,我们建议你预先添加 IP 路由规则, 这样 Kubernetes 集群就可以通过对应的适配器完成连接。
启用这些必要的端口后才能使 Kubernetes 的各组件相互通信。 可以使用 netcat 之类的工具来检查端口是否启用,例如:
nc 127.0.0.1 6443
你使用的 Pod 网络插件 (详见后续章节) 也可能需要开启某些特定端口。 由于各个 Pod 网络插件的功能都有所不同,请参阅他们各自文档中对端口的要求。
这里会存在报错,请仔细跟着教程走!
apt
包索引并安装使用 Kubernetes apt
仓库所需要的包:sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl
sudo curl -fsSLo /etc/apt/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
报错指南:
这里如果你一次过了,那么恭喜你你真的很幸运,如果失败则会出现以下报错
# 大概意思就是你被墙了没办法下载
Could not connect to packages.cloud.google.com:443
在你的电脑下载证书导入虚拟机
这里需要用到科学上网,如果没有科学上网可以去额外查找换源大法,这里我已经把证书上传到我的百度网盘了(证书估计存在时效性,最好还是自己去官网下载防止报错,2023-5-15前证书有效)
官网链接:https://packages.cloud.google.com/apt/doc/apt-key.gpg
链接: https://pan.baidu.com/s/1TEy9IIw6IwqHn29qWhUmWA?pwd=vqfg 提取码: vqfg 复制这段内容后打开百度网盘手机App,操作更方便哦
手动下载https://packages.cloud.google.com/apt/doc/apt-key.gpg,
将下载后的apt-key.gpg
复制到/usr/share/keyrings/kubernetes-archive-keyring.gpg
文件下
sudo cp 你证书文件的路径 /usr/share/keyrings/kubernetes-archive-keyring.gpg
apt
仓库:echo "deb [signed-by=/etc/apt/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
apt
包索引,安装 kubelet、kubeadm 和 kubectl,并锁定其版本:sudo apt-get update
# 这里只要你没梯子一定会错的直接看报错指南
sudo apt-get install -y kubelet kubeadm kubectl
# 记得看报错指南
sudo apt-mark hold kubelet kubeadm kubectl
报错指南:
这里update和全局install kubelet kubeadm kubectl是会出现报错的
sudo apt-get update
# 会出现无法连接到goole报错
sudo apt-get install -y kubelet kubeadm kubectl
# 会出现以下报错,无法寻找到安装包
E: Unable to locate package kubelet
E: Unable to locate package kubeadm
E: Unable to locate package kubectl
解决办法:(换源大法)
打开这个Software & Update(软件与更新)点击该页面的Download from
选择Other,选择阿里云镜像地址,点击确定(这里出现错误也没事的直接退出就行)
执行命令修改国内镜像地址:
echo "deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
再次执行update(一定要再执行一次否则看不到接下来需要的key)
sudo apt-get update
接下来就会出现第二个报错(是不是很烦!我也很烦!@)
报如下错误:
The following signatures couldn’t be verified because the public key is not available:
看你自己电脑报这个错误的这里,看这里!看这里!(每个人都不一样的一定要看自己的key时多少!!)NO_PUBKEY FEEA9169307EA071 NO_PUBKEY B53DC80D13EDEF05
Reading package lists… Done
W: GPG error: https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial InRelease: The following signatures couldn’t be verified because the public key is not available: NO_PUBKEY FEEA9169307EA071 NO_PUBKEY 8B57C5C2836F4BEB
E: The repository ‘https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial InRelease’ is not signed.
这是ubuntu添加源后,更新提示缺少公钥
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys xxxxxx(缺少的公钥,就是刚刚报错中的那一串!再说一次每个人都不一样的!!)
报错终于解决啦!!!
再执行一次安装命令,更新 apt
包索引,安装 kubelet、kubeadm 和 kubectl,并锁定其版本:
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
恭喜你!做到这一步已经离成功不远了!后面虽然很多坑不过我已经帮你们踩完了,所以后面你们畅通无阻的了,看在这个份上,夸夸我吧呜呜呜呜
接下来的初始化之前会存在莫名奇妙的报错,原因也大部分是网络的问题,少部分是kubectl,container,docker可能没有启动成功要自行去检查
为了避免所有的网络报错,先确保本机电脑能被ping通,以及能连通外网
sudo rm /etc/containerd/config.toml
# 生成 containerd 的默认配置文件
containerd config default > /etc/containerd/config.toml
# 统一换源操作
sed -i "s#registry.k8s.io/pause#registry.aliyuncs.com/google_containers/pause#g" /etc/containerd/config.toml
# 重新加载配置文件
systemctl daemon-reload
# 重启所有有关6443端口的服务
systemctl restart containerd.service
systemctl restart docker
systemctl restart kubelet
sudo kubeadm init \
--image-repository registry.aliyuncs.com/google_containers \
--apiserver-advertise-address=你本机ip \
--v=6
参数解释:
这样集群master节点就搭建完成了
注意修改初始化参数 --v= n(数字) 才能看到更加详细的信息,
如果执行初始化指令报错了一次,请执行reset指令重新再来否则会提示k8s所需的配置文件已经存在无法初始化
# 每一次初始化失败了都要执行!
# --cert-dir string 删除证书的参数建议加上
sudo kubeadm reset --cert-dir string
每个人的报错都千奇百怪,要仔细去仔细阅读日志,报错就藏在里面
journalctl -xeu kubelet
初始化的过程倘若没有加 --v 参数,初始化的信息将会不那么详细,出现无法进行继续初始化的时候会提示
# 这并不能精确定位到报错,最多只能告诉你你的初始化进程卡住了。。一定要查看日志!!!
[kubelet-check] Initial timeout of 40s passed
端口被占用,检查一下你的电脑有什么占用了这两个端口,停了他
提示etcd目录非空,可能你的虚拟机提前安装过etcd,因此把这个目录rm就可以了
6443端口一直访问连接拒绝,此处将初始化参数–v = 6 就可以看到
这里链接拒绝的原因可以等5分钟初始化结束,会提示你出现了什么报错,此处的报错的原因是
# 日志中存在这样一句信息
Failed to create sandbox for pod
解决办法:
# 删除container容器运行时的配置文件
sudo rm /etc/containerd/config.toml
# 进入root
sudo su
# 再次重新生成容器运行时的配置文件
containerd config default > /etc/containerd/config.toml
# 换驱动(驱动这里由于是Ubuntu 22 使用的是CgroupV2 因此支持的是SystemdCgroup,请在文章前面内容选择你虚拟机的驱动)
sudo sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/g' /etc/containerd/config.toml
# 换源
sed -i "s#registry.k8s.io/pause#registry.aliyuncs.com/google_containers/pause#g" /etc/containerd/config.toml
倘若你的主节点master节点搭建成功了,在master节点运行这三句话,(注意看运行成功后这段话,里面包含着主节点的操作,加入节点的操作)
mkdir -p $HOME/.kube
sudo cp i /etc/kubernetes/admin.conf SHOME/.kube/config
sudo chown S(id -u):S(id -g) SHOME/.kube/config
将https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml内容拷贝到节点虚拟机新建的kube-flannel.yml
这里新建在home目录下
随后执行这句指令接受该证书
kubectl apply -f kube-flannel.yml
随后在节点运行这句指令,每个人不一样
kubeadm join ******ip:6443 --token ph9nja.szsmyjzm51xd3893 \
--discovery-token-ca-cert-hash sha256:97282d1f0C54bb9c755c3ea06507fe714457199c4f84df6d234Cd6a4ac416b01
最终查看结果
# 检查节点是否加入成功
kubectl get node
❤️❤️❤️既然都看到这里了,就给我点个赞吧
片转存中…(img-NQDkk1Ie-1684203019732)]
mkdir -p $HOME/.kube
sudo cp i /etc/kubernetes/admin.conf SHOME/.kube/config
sudo chown S(id -u):S(id -g) SHOME/.kube/config
将https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml内容拷贝到节点虚拟机新建的kube-flannel.yml
这里新建在home目录下
随后执行这句指令接受该证书
kubectl apply -f kube-flannel.yml
随后在节点运行这句指令,每个人不一样
kubeadm join ******ip:6443 --token ph9nja.szsmyjzm51xd3893 \
--discovery-token-ca-cert-hash sha256:97282d1f0C54bb9c755c3ea06507fe714457199c4f84df6d234Cd6a4ac416b01
最终查看结果
# 检查节点是否加入成功
kubectl get node