KUBEADM部署简单K8S集群-V1.26
前言:
关键字:Kubernetes 1.26.0、dockershim、cri-dockerd、kubeadm;
本博文为原创博文,欢迎转载,但请请注明出处;
距离上一篇博文,已经是五个月之前的事了!其实不太写博客的主要原因是,现在这个博客的文本编辑器实在太难用了,每次写完博客,都需要花一大段时间调整样式,这个很烦~
为什么有这篇博客?主要的之前把自己的K8S的测试环境给搞没了,于是就需要再搭建一次~好吧,其实我一直都不太喜欢K8S,太复杂了,而且,真的只有大公司才能玩得转这个东西,是很大很大的公司才玩得转!这次只是搭建一个只有三个节点的K8S集群,但还是出问题了,原因就是由那个网上很多人喜欢挂嘴边的那句话"DOCKER已死"所引起的;主要原因是,自K8S的"1.24版本(含)"开始,K8S从"kubelet"组件中移除了"dockershim"的代码,如果不明白这在说什么,下面应该还会再说这个话题;"dockershim"的移除意味着什么?意味着,我们过去常用的那种搭建K8S集群的方法("kubelet"组件直接支持使用"docker"进行K8S集群的容器管理),已经不适用了,是的,包括这个博客上那篇访问率很高的"K8S二进制部署高可用集群"的搭建教程,它已经不适用于"1.24(含)"之后的版本了;这就是K8S麻烦的原因,因为这个问题,让我又查了几天的官网......说实话,每次搭建K8S集群,我都得上官网转一圈,因为老是忘记一些东西......
其实嘛,你说之前的那篇"K8S二进制部署高可用集群"还有没有用?其实还是有用的,虽然"kubelet"组件移除了"dockershim"的代码使其不再适用于高于"1.24(含)"的版本,但其实大部分二进制部署的相关配置与方法还是一样的(部署"1.24(含)"之后的版本只需要一点额外的修改[这"一点"估计需要改的配置项也不少]);看完这篇教程你能得到什么?我也不知道呢,但至少能你搭建起"1.26"版本的一个简单的K8S集群,是没有问题的。至于其它嘛,看读者自己对K8S的了解有多深了......
照惯例,开篇的废话说完了……
特别提示:如果你在实验过程中,直接复制本博客任意博文中的配置/代码,"空格"字符的前面将可能产生不可见的字符"M-BM-",从而造成文件不可用,这是字符编码的问题~若必需使用复制粘贴方式,请务必手动替换掉配置项中的所有空格!!!或尝试使用以下命令过滤掉所有"M-BM-"字符~
1 2 3 4 |
sed -i 's/\xc2\xa0/ /g' [文件名称] # LINUX下可使用以下命令查看不可见字符的情况 cat -A [文件名称] |
*、关于DOCKER已死
关于产生这样的言论的原因主要是:K8S自"1.24(含)"版本开始不再直接支持DOCKER去管理K8S集群中的容器["kubelet"组件移除了"dockershim"的代码],而K8S与DOCKER本质都只是"容器的管理工具",而对于"管理工具",通常都是只需要一个即可[例如"top"与"htop"命令,你通常只会使用其中一个],于是便"产生了DOCKER已死"这样的言论;
网络上,类似的言论并不少,"DOCKER已死"、"K8S都放弃DOCKER了"、"还DOCKER?现在都K8S了"、"K8S才是未来",说实话,我很讨厌这样的言论/评论,因为误导性太强了,兴幸的是,博主在学K8S时,K8S还直接支持DOCKER,而博主是先学DOCKER再学K8S的[当然,那时博主并没有想过去学K8S],否则,博主那将是被误导的其中一个;这么说,从博主个人的感受来说,DOCKER并没有死,反而,它活得比K8S还要好;为什么这么说?去看看GITHUB上的开源项目就知道了,如果一个开源项目支持容器化快速部署,那么,快速部署的方式一般是使用DOCKER(从没见过提供K8S的YAML文件的[这里不知道我说什么就算了]);
所以,不要再说"DOCKER已死"这样的话了,DOCKER依然是主流,K8S只有真正的大企业才有资格玩(看看K8S的工作都是些什么企业在招吧);
*、关于"dockershim"与"cri-dockerd"
关于"dockershim",其实上文已经提过了,它是"kubelet"组件中用于支持DOCKER管理容器的功能代码,在"1.24(含)"版本中被移除了,于是就产生了一个问题"1.24版本[含]之后,如何还能像以前一样,使用DOCKER管理K8S集群中的容器?",于是便产生了"cri-dockerd",本质上,你可以将"dockershim"等同于"cri-dockerd";
K8S为什么要移除"dockershim"?无论K8S还是DOCKER,都只是一个容器管理工具,而至今天,容器技术并不只有DOCKER,K8S的野心是支持所有的容器技术,只需要该容器技术遵从K8S的CRI规范即可(什么是CRI规范?就是K8S定义的一个标准而已),而由于DOCKER早于K8S开发,使得DOCKER不支持K8S所定义的CRI规范,所以需要"dockershim"作为一个中间层作"解释";早期容器技术只有DOCKER,而且是绝对的主导权,而K8S想推广自己,所以就做了"dockershim"这么个东西;但现在不同了,K8S现在做大了,也有主导权了,也有就有资格说不需要"dockershim"了;这本质就是"你去支持我,还是我去支持你的问题",以上只是博主的个人猜测;怎么说呢,颇有一种"以前叫人小甜甜,现在叫人牛夫人"的感觉。再更明白点说,Kubenetes就像一个厂家,它生产的螺丝刀(K8S),而它希望这把螺丝刀(K8S)可以匹配所有厂家生产的螺丝(各种容器技术[它们都遵从CRI规范]),而最早生产螺丝的企业A(DOCKER),那时并没有关于螺丝的生产规范(CRI规范),所以DOCKER生产的螺丝不满足现在定义的规范,而早其的K8S厂家为了推广它的螺丝刀(K8S),于时,其做一个"中间件"(dockershim),使这把螺丝刀(K8S)可以对企业A螺丝使用(DOCKER);
关于"cri-dockerd",本质就是另一个"dockershim",只不过是名字与维护者不一样了,现在"cri-dockerd"的其中一个维护者就是DOCKER;从DOCKER的角度来说,这真的就是"从你去支持我变成了我去支持你了",DOCKER真的失去了它原有的主导权;这么来说,"DOCKER已死"也很合理?还是错的,上一节已解释过;另外,你要明白,这个所谓的主导权的前提是什么,它的前提是"企业应用与利润来源"。大型企业由于服务器很多,要想做到资源利用的最大化,所以他们需要使用K8S,同时,开发容器技术/容器工具,它的利润来源也必定是来自企业,DOCKER与K8S都在追逐利润,现在多服务器上应该容器技术是K8S在主导,所以"DOCKER失去主导权"是建立在利润追逐的基础上的(其实DOCKER也开发了类似K8S的东西,只不过败了);
其实,就算我上面这么解释了,对于那些不了解K8S软件架构的,也是极可能听不懂的,下面博主贴一张图,希望能帮助你了解容器技术的各种术语之前的关系:
"dockershim"在"1.24(含)"被移除了,那么在"1.24"之前,传统的使用DOCKER去管理K8S集群的容器的方式是什么?而"1.24(含)"之后,要使用DOCKER去管理K8S集群的容器的方式又是什么(使用了"cri-dockerd")?看下面这张图的解释:
在"1.24"之前,使用K8S与DOCKER的方式一般是"kubelet[CRI > dockershim] > DOCKER > contained > RUNC";而"1.24(含)"之后,就变成了"kubelet[CRI] > cri-docker > DOCKER > contained > RUNC";
有没有发现,有一条更短的路径到达"RUNC"?就是这条"kubelet[CRI] > contained > RUNC"!是的,K8S完全可以不通过DOCKER去管理K8S集群自身的容器;又来了"看来DOCKER真的已死"!K8S都只需要有"contained"就可以了,还要DOCKER做什么……什么是"contained"?"contained"本来是人家DOCKER的东西,只不过后来开源赠送给了CNCF组织(估计是不情愿的,只是没办法),本质上你还是在用人家DOCKER的东西,却说"DOCKER已死",这太不合理了吧?
又写了很多,真要说的话真的没完没了的啊,就这样吧~因为真的说不完,这个话题至此完了~
一、环境与其它
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
*、测试日期[2023.01.01] *、注:本次教程没有二次复测有效性,如果有发现问题可留言 *、 应该没问题吧 *、[ 环境 ] [MASTER] K8S-MASTER 192.168.100.53 [NODE] K8S-NODE01 192.168.100.54 K8S-NODE02 192.168.100.55 *、[ 方案 ] 1、K8S集群方案 :KUBEADM + CRI-DOCKERD 2、集 群 期 望:*、启用IPVS (关联"KUBE-PROXY"、"CALICO") *、使用CALICO (关联"CNI"、"BGP模式"、"IPVS模式") *、systemd (关联"Cgroup驱动") *、cri-dockerd (关联"Docker") *、[ 版本 ] OS --> Debian11 # 操作系统 (Kernel -- 5.10.84) DOCKER --> 20.10.12 # DOCKER版本 (在线安装) KUBERNETES --> 1.26.0 # KUBERNETES版本(在线安装) CRI-DOCKERD --> 0.3.0 # CRI-DOCKERD (二进制安装) |
二、系统优化[DEBIAN 11]
关于这部分内容,博主觉得,你都玩K8S了,这里的内容应该对你不构成任何问题了,而且,实际上也没有什么特别好说的~硬要说有什么的话,也只有"内核模块"与"内核参数"的启用上了,但这些东西在官方文档上也是写得明明白白的。当然,关于"内核参数"这个话题上,还是能说一说的,网上的一堆教程,都会给你一大堆的所谓的"内核优化参数",这显得很专业,但基本毫无意义,因为你会发现,它们很统一,都给你参数配置,但从不解释,很简单,都是抄的或套用的;你应该这么想,"内核参数"并没有什么统一的标准,都是实际按照服务器的配置、性能与用途来决定如何定义"内核参数"的,尤其是那值非"0、1、2"的"内核参数",网上的那些关于K8S内核优化的话题,其实你可以忽略了,估计也就第一个定义这些"优化参数"的人知道为什么这么定义;当然,如此配置大概有这么一个理念:如果希望不作限制的话,那么我只需要配置一个足够大的值即可......;关于"内核参数"的启用,官方文档很清楚的表明,K8S必须的只有"三条"(博主定义了"六条")~
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# 以下操作在[192.168.100.53 - 55]上执行(*、注:第"7"步按实际情况使用) 1、时区修改及时间同步 timedatectl set-timezone Asia/Shanghai timedatectl set-local-rtc 0 timedatectl set-ntp true timedatectl 2、关闭SWAP: vim /etc/fstab # 不清楚如何关闭SWAP百度一下 mount -a # 修改"fstab"后检查"fstab"文件是否会引起LINUX启动异常 3、检查IPTABLES功能是否存在、安装"ipvsadm"(用于检测IPVS是否生效) iptables -L apt-get -y install ipvsadm 4、启用基本内核 + 启用IPVS所必须的内核模块[为"kube-proxy"组件使用作准备] # 基本内核:"overlay、br_netfilter"模块在启用状态 # IPVS内核:"ip_vs、ip_vs_rr、ip_vs_wrr、ip_vs_sh、nf_conntrack"模块在启用状态 # 启用内核模块(需要重启生效) cat > /etc/modules-load.d/k8s-ipvs.conf </etc/sysctl.d/k8s_better.conf << EOF net.bridge.bridge-nf-call-iptables=1 # 官方文档表示的必须的"内核参数"配置 net.bridge.bridge-nf-call-ip6tables=1 # 同时也是IPVS所必需的配置 net.ipv4.ip_forward=1 # 启用IPV4转发 vm.swappiness=0 # 禁止使用 swap 空间,只有当系统 OOM 时才允许使用它 vm.overcommit_memory=1 # 不检查物理内存是否够用 vm.panic_on_oom=0 # 开启 OOM EOF # 加载指定配置[执行一下,看一下是否有报错,内核参数可能有变动] sysctl -p /etc/sysctl.d/k8s_better.conf 7、更改计算机名: # 配置名字"大写/小写"没有区别(大写看起来起漂亮),重要的是"/etc/hosts"中的DNS解释; # 因为当使用"ping"命令如"ping K8S-MASTER"时,实际是没有大小写区分的 MASTER:--> # hostnamectl set-hostname K8S-MASTER NODE :--> # hostnamectl set-hostname K8S-NODE01 --> # hostnamectl set-hostname K8S-NODE02 8、HOSTS文件解释: cat >> /etc/hosts << "EOF" 192.168.100.53 k8s-master 192.168.100.54 k8s-node01 192.168.100.55 k8s-node02 EOF 9、重启(使增加的"内核模块"能重新加载) reboot *、MASTER 与 NODE 检查: ip addr show # 确保MAC的唯一性 cat /sys/class/dmi/id/product_uuid # 确保PRODUCT_UUID的唯一性 |
三、DOCKER部署(在线安装)
DOCKER的部署经过这么多年的发展,其实已经很成熟了(主要是国内下载问题的解决),没什么好写的,这当中唯一最重要的,也就只有"daemon.json"的配置了!以下操作适用于[192.168.100.53 - 55];
DOCKER在线安装(使用阿里源):
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# DOCKER安装 # └-> 这种方式已默认配置好:"docker.service"、"docker.socket"、"containerd.service" # 更新与安装必要依赖 apt-get -y update apt-get -y install apt-transport-https ca-certificates curl software-properties-common gnupg2 # 安装基于阿里云的DOCKER仓库的密钥、并定义DOCKER仓库 curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/debian/gpg | apt-key add - add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/debian $(lsb_release -cs) stable" # 安装"DOCKER-CE"(会安装依赖"containerd") apt-get -y update apt-get -y install docker-ce |
创建相关目录:
1 |
mkdir -p /etc/docker |
创建"daemon.json"配置文件[JSON格式请删除的注释说明];
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
cat > /etc/docker/daemon.json << "EOF" { "exec-opts": [ "native.cgroupdriver=systemd" # CPU\MEN的资源管理方式(其实只有这项是为K8S服务的) ], "log-driver": "json-file", # 日志的格式; "log-level": "warn", # 日志等级; "log-opts": { "max-size": "1000m", # 日志的最大限制; "max-file": "3" # 日志轮转的数量; }, "registry-mirrors": [ # 额外的镜像源设定; "https://docker.mirrors.ustc.edu.cn" # 使用你习惯的国内镜像源 ], "insecure-registries": [], # 信任的HTTP镜像仓库 "selinux-enabled": false # 禁用SELINUX(没什么意义,DEBIAN系默认没有SELINUX) } EOF |
检查DOCKER服务是否正常安装(其默认的SYSTEMD已经定义好开机启动);
1 |
systemctl status docker |
四、KUBEADM工具安装(在线安装)
这实际上是从网络安装三样东西,分别是:1、"kubeadm"工具,用于快速部署K8S集群;2、"kubectl"工具,用于管理K8S集群;3、"kubelet"组件,一个完整的K8S集群有很多的"组件","kubelet"组件只是其中的一个(唯一一个不能使用容器方法的组件),其它的"组件",在使用KUBLADM部署集群的方式下,以容器的方式运行;以下操作适用于[192.168.100.53 - 55];
在线安装(使用阿里源):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
2、K8S安装(安装相关工具) └-> 这种方式已默认配置好:"kubelet.service" # 安装基于阿里云的K8S仓库的密钥 curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add - # 定义K8S仓库 cat > /etc/apt/sources.list.d/kubernetes.list << EOF deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main EOF # 安装前先检查有没有希望安装的版本 apt-get -y update apt-cache madison kubelet kubeadm kubectl | grep "1.26" # K8S安装(安装相关工具"kubelet"、"kubeadm"、"kubectl") # 注:K8S工作节点并不需要"kubectl" #> 安装最新的版本直接使用以下命令 #> 在需要指定版本时 #> apt-get -y update #> apt-get install -y kubelet=1.26.0-00 \ #> kubeadm=1.26.0-00 kubectl==1.26.0-00 apt-get -y update apt-get install -y kubelet kubeadm kubectl |
五、CRI-DOCKERD组件部署(二进制安装)
CRI-DOCKERD组件,自K8S的"1.24(含)”版本开始,代替了"kubelet"组件中被移除的"dockershim"的功能,K8S集群如仍然希望使用"docker"工具管理K8S集群中的容器,则必须部署本组件;CRI-DOCKERD组件的部署方式为二进制部署;以下操作适用于[192.168.100.53 - 55];
1 2 3 4 5 6 7 8 9 10 11 12 |
# CRI-DOCKERD安装 # └-> 这种方式需要自定义:"cri-docker.service"、"cri-docker.socket" # 下载"cri-dockerd"组件 # GITHUB:https://github.com/Mirantis/cri-dockerd # 如:下载了"cri-dockerd-0.3.0.amd64.tgz" >> 解压会得到"cri-dockerd"文件 tar -zxvf cri-dockerd-0.3.0.amd64.tgz # 安装"cri-dockerd" # 注:"install"命令等同 --> "cp" + "chown" + "chmod" cd cri-dockerd install -o root -g root -m 0755 cri-dockerd /usr/local/bin/cri-dockerd cri-dockerd --version |
创建"cri-docker.service"文件;这里额外说一下,关于"pasue"镜像,"pause"镜像文件,是"kube-proxy"组件所使用到的镜像,在使用KUBEADM部署K8S集群的过程中,是无法通过"kubeadm"控制"pause"镜像版本的使用的,见附带说明:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# 配置"cri-docker.service" # GITHUB:https://github.com/Mirantis/cri-dockerd/tree/master/packaging/systemd # # 关于"--pod-infra-container-image registry.aliyuncs.com/google_containers/pause:3.9" # *、由于"kubeadm"无法控制"pause"镜像从那里下载,所以需要额外加入本配置项 # *、"pause"使用具体的镜像版本由"cri-dockerd"组件控制(解释见"$ cri-dockerd --help") cat > /etc/systemd/system/cri-docker.service << "EOF" [Unit] Description=CRI Interface for Docker Application Container Engine Documentation=https://docs.mirantis.com After=network-online.target docker.service firewalld.service Wants=network-online.target Requires=cri-docker.socket [Service] Type=notify ExecStart=/usr/local/bin/cri-dockerd --container-runtime-endpoint fd:// \ --pod-infra-container-image registry.aliyuncs.com/google_containers/pause:3.9 ExecReload=/bin/kill -s HUP $MAINPID TimeoutSec=0 RestartSec=2 Restart=always StartLimitBurst=3 StartLimitInterval=60s LimitNOFILE=infinity LimitNPROC=infinity LimitCORE=infinity TasksMax=infinity Delegate=yes KillMode=process [Install] WantedBy=multi-user.target EOF |
创建"cir-docker.socket"文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# 配置"cri-docker.socket" # GITHUB:https://github.com/Mirantis/cri-dockerd/tree/master/packaging/systemd cat > /etc/systemd/system/cri-docker.socket << "EOF" [Unit] Description=CRI Docker Socket for the API PartOf=cri-docker.service [Socket] ListenStream=%t/cri-dockerd.sock SocketMode=0660 SocketUser=root SocketGroup=docker [Install] WantedBy=sockets.target EOF |
启动并检查CRI-DOCKERD服务是否正常部署;
1 2 3 4 |
# 启用"CRI-DOCKERD"组件 systemctl daemon-reload systemctl enable cri-docker.service systemctl enable --now cri-docker.socket |
六、K8S集群部署(MASTER节点)
网络上,很多使用KUBEADM部署K8S简单集群的教程,很多都是使用"命令行参数"的方式去部署K8S集群(包括很多培训机构的教程)!这其实是不好的,主要的问题在于,你在使用了K8S集群一段时间后,你很可能就无法溯源这个K8S集群初始部署时的状态了!K8S的官方文档中,也明确表明,它更希望大家使用"配置文件"的方式去部署K8S,主要是可选择配置的东西更多,也更灵活,另一方面,"配置文件"也保存了K8S集群的初次部署时的状态;本教程使用的是官方推荐的方式:使用"配置文件"去部署K8S集群;
在这一节,我本来是想把所有相关的"K8S配置资源(K8S中所有东西都是一个"资源",估计这里又有人要看不懂在说什么了)"解释一遍的,但是这样的话,我本想一篇写完的教程,可能就需要按内容拆分为四篇了,想想,还是算了,于是嘛,关于配置内容的部分,我直接贴了博主所定义过后的;以下操作仅适用于[192.168.100.53];
1、生成一个TOKEN(这个TOKEN是用于工作节点加入K8S集群所使用的[又看不懂]),这个TOKEN用于替换"配置文件"中默认的TOKEN,你应该记下自已生成的并替换它:
1 2 3 |
# 生成TOKEN(后续的准备工作) # TOKEN(本规例生成值为:2gvlmx.yu1c7qtm4d1t3qyf)(你应该记下自已的) kubeadm token generate |
*、关于"镜像查询"、"pause镜像"、"COREDNS";本步不是必需的,只是用于帮助你了解,当前的KUBEADM在部署K8S集群时,KUBEADM希望使用的"镜像"的版本;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# 查询镜像要求与"pause:3.9" # ====================================================================================================== # 镜像查询不是必须的,但可以提供该版本"kubeadm"所要求使用的"镜像版本"; # 其中最重要的是其所使用的"镜像仓库"来源 # *、"镜像仓库"的选择可通过"kind: ClusterConfiguration"的"imageRepository:"配置项定义 # *、阿里云"镜像仓库":registry.aliyuncs.com/google_containers (不可浏览器访问) # # 另外是"coredns"的来源 # *、使用"kubeadm"部署集群时,已定义好使用的"coredns"的镜像了 # *、在"kubeadm"对"coredns"的镜像定义中,包含了一个子目录"coredns/",这可能使"在使用自定义镜像仓库"时, # "coredns"的镜像无法下载; # *、对于"coredns"镜像,可能需要以下的特殊操作(使用"cri-dockerd"组件时)(测试这步不需要) # $ docker pull registry.aliyuncs.com/google_containers/coredns:v1.9.3 # $ docker tag registry.aliyuncs.com/google_containers/coredns:1.9.3 \ # registry.aliyuncs.com/google_containers/coredns/coredns:1.9.3 # # "kubeadm"无法控制"pause"镜像从那一个镜像仓库进行下载("pause"镜像由那下载由"cri-dockerd"组件决定) # *、这需要定义"cri-docker.service"文件(解释见"$ cri-dockerd --help") # *、也可以使用以下方式强制使用"pause:3.9"(不在"cri-docker.service"文件中进行定义)[不推荐] # $ docker pull registry.aliyuncs.com/google_containers/pause:3.9 # $ docker tag registry.aliyuncs.com/google_containers/pause:3.9 \ # registry.k8s.io/pause:3.6 # *、本示例已在"cri-docker.service"文件中进行定义[推荐] $ kubeadm config images list | sort registry.k8s.io/coredns/coredns:v1.9.3 registry.k8s.io/etcd:3.5.6-0 registry.k8s.io/kube-apiserver:v1.26.0 registry.k8s.io/kube-controller-manager:v1.26.0 registry.k8s.io/kube-proxy:v1.26.0 registry.k8s.io/kube-scheduler:v1.26.0 registry.k8s.io/pause:3.9 ======================================================================================================== |
*、生成K8S集群的初始化配置文件"kubeadm-init.yaml",并将其保存在专用目录中以备日后查询;实际上这步并不需要,这里只是创建了一个保存用的目录;这个只有在需要自成定义配置时,用于快速生成一份基础模版,但这里博主将在下文中提供对应定义好的内容了;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# 生成K8S集群初始化的配置文件"kubeadm-init.yaml"(这步其实不需要,下一步的调整才是最重要的) # "kubeadm config"可定义的配置有五种 # ├── kind: InitConfiguration ["kubeadm init"] - 定义K8S运行时的配置 # ├── kind: ClusterConfiguration ["kubeadm init"] - 定义K8S"集群范围"的配置(如"networking"、"etcd") # ├── kind: KubeletConfiguration ["kubeadm init"] - 定义"kubelet"组件配置 # ├── kind: KubeProxyConfiguration ["kubeadm init"] - 定义"kube-proxy"组件配置 # └── kind: JoinConfiguration ["kubeadm join"] # # 打印完整的INIT相关配置 # $ kubeadm config print init-defaults --component-configs KubeProxyConfiguration,KubeletConfiguration mkdir -p /opt/K8S_DeployData # 需要自定义时快速生成一份模板文件 # kubeadm config print init-defaults \ # --component-configs KubeProxyConfiguration,KubeletConfiguration > /opt/K8S_DeployData/kubeadm-init.yaml |
2、生成/配置"kubeadm-init.yaml"配置文件;可配置的内容非常多(见官方文档),那些未在"配置文件"中明确定义的配置项,会使用当前KUBEADM版本所定义的默认值;另外,虽然YAML文件支持注释,但博主建议你删除这些注释;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# 按需要修改"kubeadm-init.yaml"(基本上你只需要替换TOKEN + 修改你的MASTER地址即可) # 关联K8S的这四种"资源" # ├─ InitConfiguration # ├─ ClusterConfiguration # ├─ KubeProxyConfiguration # └─ KubeletConfiguration cd /opt/K8S_DeployData cat > /opt/K8S_DeployData/kubeadm-init.yaml << "EOF" kind: InitConfiguration apiVersion: kubeadm.k8s.io/v1beta3 bootstrapTokens: - groups: - system:bootstrappers:kubeadm:default-node-token token: 2gvlmx.yu1c7qtm4d1t3qyf # 替换此TOKEN ttl: "0" # 配置TOKEN永久有效 usages: - signing - authentication localAPIEndpoint: advertiseAddress: 192.168.100.53 # K8S的MASTER的地址 bindPort: 6443 # 对应端口 nodeRegistration: criSocket: unix:///var/run/cri-dockerd.sock # 定义K8S通过什么方式管理容器 imagePullPolicy: IfNotPresent # "镜像"下载策略 taints: null # 污点定义 --- kind: ClusterConfiguration apiVersion: kubeadm.k8s.io/v1beta3 apiServer: timeoutForControlPlane: 2m0s certificatesDir: /etc/kubernetes/pki clusterName: kubernetes controllerManager: {} dns: {} etcd: local: dataDir: /var/lib/etcd imageRepository: registry.aliyuncs.com/google_containers # 下载镜像时所选用的"镜像仓库"[国内] kubernetesVersion: 1.26.0 # K8S集群的版本[从测试上看,这个值类似一个正则匹配表达式] networking: dnsDomain: cluster.local serviceSubnet: 10.96.0.0/16 # K8S"service"资源的CIDR范围 podSubnet: 10.97.0.0/16 # K8S"pod"资源的CIDR范围 scheduler: {} --- kind: KubeProxyConfiguration apiVersion: kubeproxy.config.k8s.io/v1alpha1 bindAddress: 0.0.0.0 clusterCIDR: "10.97.0.0/16" # 定义K8S集群中"POD"资源CIDR范围[官方]、也是"CNI网络插件"的CIDR范围 portRange: "30000-65535" # 限制POD可以工作节点上使用的端口 ipvs: scheduler: "rr" # IPVS使用轮询模式 mode: "ipvs" # CNI启用IPVS模式 --- kind: KubeletConfiguration apiVersion: kubelet.config.k8s.io/v1beta1 authentication: anonymous: enabled: false x509: clientCAFile: /etc/kubernetes/pki/ca.crt readOnlyPort: 0 # 进行显式定义(以表示禁用"非安全方式访问") enableServer: true # 进行显式定义(以表示必须使用"安全方式访问") cgroupDriver: systemd # Cgroup驱动定义 clusterDNS: - 10.96.0.10 # 基于对"POD/SERVICES"资源的CIDR定义,此DNS服务只 clusterDomain: cluster.local # 支持对"SERVICES"资源进行"域名解释服务区" rotateCertificates: true EOF |
3、初始化MASTER节点;定义好"kubeadm-init.yaml"配置文件后(这步是最难的),之后的操作就很简单了;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# 初始化MASTER节点(使用"kubeadm-init.yaml") # 注意:如果"coredns"镜像在调整"镜像仓库"后下载失败,则参见"*、查询镜像要求"中的解决办法 # 初始化成功后,会输出"节点添加的方法" cd /opt/K8S_DeployData kubeadm init --config kubeadm-init.yaml # "kubectl"命令的配置("root"权限)(这个在成功部署MASTER节点后就会有相关提示) # 定义"kubectl"命令使用的配置文件 + 命令补全 mkdir -p $HOME/.kube cp -i /etc/kubernetes/admin.conf $HOME/.kube/config chown $(id -u):$(id -g) $HOME/.kube/config kubectl completion bash > /usr/share/bash-completion/completions/kubectl kubectl get node |
七、K8S集群部署(NODE节点)
在成功初始化MASTER节点,就需要向K8S集群中添加节点了,这一步更简单;但一点需要注意,就是这里的"kubeadm join"并没有使用"配置文件"的方式,原因嘛,因为官方提示的也是使用命令行啊~另外一个重点是,我们现在使的是"非原生支持DOCKER的K8S版本"(使用了CRI-DOCKERD组件),所以官方所提供的"节点加入方法",还需要调整一下(关于"--cri-socket"配置项);以下操作适用于[192.168.100.54 - 55];
1 2 3 4 5 6 7 8 9 10 11 |
# "kubectl"配置("root"权限) # 关于"--cri-socket unix:///var/run/cri-dockerd.sock" # *、由于没有定义"kind: JoinConfiguration",所以"kubeadm join"并不清楚"--cri-socket"的定义; # 所以本处需要额外指定"--cri-socket"(表示使用了"cri-dockerd"组件) # 关于"--discovery-token-ca-cert-hash"请查看实际值; kubeadm join 192.168.100.53:6443 --token 2gvlmx.yu1c7qtm4d1t3qyf \ --discovery-token-ca-cert-hash sha256:12b60ef80b3eddc52921fb7eade1dec1290e7b4fb2a81f384e197ca3f218e4cc \ --cri-socket unix:///var/run/cri-dockerd.sock # 本步在MASTER上操作看是否成功"添加节点" kubectl get node |
八、CALICO部署(CNI网络运行时)
啊~~~CALICO是什么?……不想写,在博客的"K8S二进制部署高可用集群"或"百度"一下吧……
就是K8S还需要第三方的CNI网络运行时来保证K8S的正常使用(CNI也有很多,K8S不提供),CALICO的优点主要是他支持"BGP"模式(一种网络技术)(其实现在好像其它的也支持,但大家比较认可它);以下操作适用于[192.168.100.53]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# 创建一个目录专用保存第三方插件 $ mkdir -p /opt/K8S_DeployData/plugins # 从网络下载部署模板文件 $ cd /opt/K8S_DeployData/plugins $ curl https://docs.projectcalico.org/manifests/calico.yaml -O # 对模板文件进行修改(请找到以下配置项[内容太多])(同时按需要修改) $ vim calico.yaml - name: CALICO_IPV4POOL_CIDR # PodIP的CIDR范围 value: "10.97.0.0/16" - name: CALICO_IPV4POOL_IPIP # CALICO IPIP 模式的启用/禁用 value: "Never" # [修改]"Never"表示使用BGP;"Always"表示使用IPIP - name: IP_AUTODETECTION_METHOD # [按需使用]特殊配置,未在默认的配置文件中存在,需要手动增加,与"CALICO_IPV4POOL_CIDR"同级 value: "interface=eth0" # CALICO的部署默认会自动选择合适的网卡,但在一些环境中此方法可能会存在问题,本配置项的作用为 # 用于定义部署过程中的网卡选择;"eth0"这实际是一个正则表达式,"eth0"表示严格匹配所使用的网卡 # 提示:如果你的网络环境能正常部署成功,不需要特别增加此项而提高维护的复杂度 # 应用配置 # 关于"kubectl apply -f calico.yaml"为什么能正常执行 # *、"kubeadm"默认会为MASTER节点"添加污点"("kind: InitConfiguration"中的"nodeRegistration.taints: null"定义), # "kubectl apply -f calico.yaml"能正常执行,是由于"calico.yaml"中已经定义好:匹配"kubeadm"对MASTER所定义的"相应的污点容忍策略" $ kubectl apply -f calico.yaml $ kubectl get pod -A |
这步完成后,一个简单的K8S集群便已经正常部署完成了……
九、集群测试
至此,整个K8S集群的搭建算是完成了。现在,我们写一份YAML文件进行K8S集群的测试;在MASTER上操作[192.168.100.53];
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# 进入对应目录 cd /root # 生成"k8stest.yaml" cat > k8stest.yaml << "EOF" --- apiVersion: v1 kind: ReplicationController metadata: name: nginx-controller spec: replicas: 2 selector: name: nginx template: metadata: labels: name: nginx spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: nginx-service-nodeport spec: ports: - port: 80 targetPort: 80 nodePort: 30001 protocol: TCP type: NodePort selector: name: nginx EOF |
在K8S集群中应用"k8stest.yaml":
1 2 |
$ cd /root $ kubectl apply -f k8stest.yaml |
使用浏览器访问"http://192.168.100.4X:30001"[成功];
1 2 3 |
# 删除测试POD cd /root kubectl delete -f k8stest.yaml |
题外话(关于"containerd")
看上面的第二幅图,可以看到,K8S与DOCKER都使用到"containerd";这东西就是容器技术中的其中一种了,你安装DOCKER的同时,"containerd"以依赖的方式被安装了,所以你就应该知道为什么安装DOCKER,会存在一个"containerd.service"的SYSTMED服务了;实际上有K8S使用了DOCKER与没有使用DOCKER有什么区别,一个显注的区别是,在K8S使用的DOCKER的情况下,你所使用的,用K8S部署的应用,你可以使用"docker ps"查看到具体的使用了什么容器,当然,你还可以使用"docker exec"这样类似的命令~~~
实际上,无论K8S用不DOCKER,其最终都需要经过"containerd"组件,所以DOCKER对K8S来说,并不是必须的;从另一方面来说,K8S直接使用"containerd",能有更高效率,无论怎么说,中间都少了"dockershim/cri-dockerd > DOCKER"两个过程;不过,效率提高了多少就不好说了,反正,以前不是大部分的情况下,都是经过了DOCKER在使用的嘛~其实,"containerd"也有类似"docker"这样的命令,这个命令叫"ctr"(如果你安装了DOCKER,这个命令一定在你系统中),使用上和"docker"命令差不多;你说为什么明明K8S都可以绕过DOCKER了,但还有"cri-dockerd"这个东西的出现,很简单,大家都更熟悉DOCKER嘛,另外,何必又去学一个重复的新东西,很多时候,很多人连DOCKER都玩不好呢~
结、
这应该是博主写过最差的一篇博文了,因为博主只想快点写完~其实也没有办法,因为使用了官方推荐的方式去使用"kubeadm init"与"kubeadm join",问题是这种使用"配置文件"的方式,那么多的配置项,需要对K8S有中够的了解才能明白那些配置项的意思,那实际上就是意味着你已经会使用K8S,并且已经了解K8S的软件架构(玩过二进制部署就会了解了),就这样吧,博主也不知道想说什么~
KUBEADM部署简单K8S集群-V1.26:等您坐沙发呢!