一、机器准备

本次搭建k8s集群采用三台云服务器,master节点最好采用2核2G以上的机器,node节点不作要求

二、开始搭建

1、机器

| 角色     | IP           |
| --------- | ------------ |
| master | you master ip |
| node1  | you node1  ip |
| node2  | you node2 ip  |

2、机器环境初始化

以下操作均在所有机器执行!!!!!!

有些机器选的镜像不同,可能没有下载 wget,这里先下载一下

yum install wget

 关闭防火墙

systemctl stop firewalld
systemctl disable firewalld

原因:官网给的解释如下,(nftables后端兼容性问题,产生重复的防火墙规则)

The iptables tooling can act as a compatibility layer, behaving like iptables but actually configuring nftables. This nftables backend is not compatible with the current kubeadm packages: it causes duplicated firewall rules and breakskube-proxy.

关闭selinux

sed -i 's/enforcing/disabled/' /etc/selinux/config  # 永久
setenforce 0  # 临时

原因:官网给的解释如下,(关闭selinux以允许容器访问宿主机的文件系统)

Setting SELinux in permissive mode by runningsetenforce 0andsed ...effectively disables it. This is required to allow containers to access the host filesystem, which is needed by pod networks for example. You have to do this until SELinux support is improved in the kubelet.

 关闭swap

swapoff -a  # 临时
sed -ri 's/.*swap.*/#&/' /etc/fstab    # 永久

原因:如下

        在计算集群(请注意计算集群这四个字的含义,这种集群主要运行一些生存周期短暂的计算应用,申请大量内存-动用大量CPU-完成计算-输出结果-退出,而不是运行诸如mysql之类的服务型程序)中,我们通常希望OOM的时候直接杀掉进程,向运维或者作业提交者报错提示,并且执行故障转移,把进程在其他节点上重启起来。而不是用swap续命,导致节点hang住,集群性能大幅下降,并且运维还得不到报错提示。更可怕的是有一些集群的swap位于机械硬盘阵列上,大量动用swap基本可以等同于死机,你甚至连root都登录不上,不用提杀掉问题进程了。往往结局就是硬重启。

        节点hang住是非常恶劣的情况,往往发现问题的时候,已经造成了大量损失。而程序出错可以自动重试,重试还OOM说明出现了预料之外的情况(比如程序bug或是预料之外的输入、输入文件大小远超预期等问题),这种时候就应该放弃这个作业等待人员处理,而不是不停地尝试着执行它们,从而导致后面的其他作业全部完蛋。

        所以计算集群通常都是关闭swap的,除非你十分明确swap可以给你的应用带来收益。

计算集群和诸如执行mysql的集群有一个根本不同就是计算集群不在意单个进程、单个作业的失败(由于面向的用户很宽泛,这些作业所执行的程序很可能未经严格的测试,它们客观上出问题的几率远高于mysql等成熟的程序),但是绝对不接受hang住引起整个集群无法处理任何作业,这是非常严重的事故。

        关闭swap的含义其实就是OOM了就赶紧滚蛋,让正常的程序进来继续执行,OOM的程序让用户去处理。

 将桥接的IPv4流量传递到iptables的链

cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system  # 生效

时间同步

yum install ntpdate -y
ntpdate time.windows.com

 添加阿里云YUM软件源

$ cat > /etc/yum.repos.d/kubernetes.repo << EOF
[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

根据规划设置主机名,(如:master,node1,node2)

hostnamectl set-hostname <hostname>

3、master机器配置

配置hosts,只在master执行即可

cat >> /etc/hosts << EOF
you master ip mast
you node1 ip node1
you node2 ip node2
EOF

4、安装docker

master和node均要

这里安装docker需安装不低于19.03的版本,(后面安装Kuboard 需要) 

wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
yum -y install docker-ce-20.10.12.ce-3.el7
systemctl enable docker && systemctl start docker
docker --version
Docker version 20.10.12-ce, build e68fc7a

5、安装kubeadm,kubelet和kubectl

master和node均要

这里特别注意版本的对应关系,我这里安装的都是1.18.0,一开始我安装的是1.23.1,在kubeadm init的时候出现的

[kubelet-check] Initial timeout of 40s passed.

报错没能够解决,不同版本有不同的解决方案,本文按1.18.0版本的来解决。 

注意版本不能低于1.13.0,(后面安装Kuboard 需要) 

yum install -y kubelet-1.18.0 kubeadm-1.18.0 kubectl-1.18.0
systemctl enable kubelet

6、部署Kubernetes Master,node节点加入集群

在master节点执行

kubeadm init \
  --apiserver-advertise-address=you master ip \
  --image-repository registry.aliyuncs.com/google_containers \
  --kubernetes-version v1.18.0 \
  --service-cidr=10.96.0.0/12 \
  --pod-network-cidr=10.244.0.0/16

命令解析:

第二行需填写你的master的ip地址

第三行为指定阿里云镜像仓库地址,目的,应该都知道

第四行为刚刚你下载的Kubernetes 版本号

第五行和第六行为内网ip地址,不要使用常见的ip地址即可

该命令如果是按照本文的版本号进行操作,会出现以下错误,(其它版本可参考)

在输入上述命令后,kubeadm即开始了master节点的初始化,但是由于etcd配置文件不正确,所以etcd无法启动,要对etcd.yaml文件进行修改。

这里需要注意 etcd.yaml文件是在kubeadm init命令执行才会出现的,所以需要你在打开两个master的ssh窗口,一个窗口在执行kubeadm init,立马切到另外一个窗口,找到etcd.yaml文件,命令:

vim /etc/kubernetes/manifests/etcd.yaml

如果还没有该文件,再稍等一下,还没有生成。
 

此处"43.143.65.53"为master公网ip,要关注的是"–listen-client-urls"和"–listen-peer-urls"。需要把–listen-client-urls后面的公网IP删除,把–listen-peer-urls改成127.0.0.1:2380

image-20221013195407150

 原因:因为云服务器只要选择VPC网络均是采用NAT方式将公网IP映射到私人网卡的,有兴趣的同学可以了解下NAT。这也就是为什么很多同事无法在腾讯云或阿里云上安装k8s集群的原因。 

执行成功的截图如下:

 执行成功需要关注两个地方

第一个是使用kubectl工具的命令:(这里使用你生成的)

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

 第二个是kubeadm join 命令,字面意思就是,在子节点执行,让子节点加入到master的k8s集群。

在所有子节点执行:(这里使用你生成的)

kubeadm join 192.168.1.11:6443 --token esce21.q6hetwm8si29qxwn \
    --discovery-token-ca-cert-hash sha256:00603a05805807501d7181c3d60b478788408cfe6cedefedb1f97569708be9c5

这个后面的一串字符是一个token,过期时间默认为24小时,如需从新生成,执行命令:

kubeadm token create --print-join-command

 子节点加入后可以通过命令:查看集群节点信息

kubectl get nodes

 7、部署CNI网络插件

到这一步集群已经搭建完成,可以看到节点处于一个NoReady的一个状态,我们需要变为Ready状态,执行命令:(下载地址是国外的地址,可能会失败,多试几次)

curl https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml >>kube-flannel.yml
chmod 777 kube-flannel.yml 
kubectl apply -f kube-flannel.yml

 下载完成大概等一两分钟,执行命令:查看集群节点信息

kubectl get nodes

成功的情况下可以看到,状态为Ready

该命令可以查看集群节点详细信息

kubectl get nodes -o wide

 8、测试kubernetes集群

在Kubernetes集群中创建一个pod,验证是否正常运行:

kubectl create deployment k8s-nginx --image=nginx
kubectl expose deployment k8s-nginx--port=80 --type=NodePort
kubectl get pod,svc

访问地址:http://NodeIP:80,

成功的访问:

命令的-r 1是启动了一个副本,如果你有多个节点,会随机选取一个。

-r 3 即创建3个pod

9、 安装 Kuboard v3

在master机器执行:

sudo docker run -d \
  --restart=unless-stopped \
  --name=kuboard \
  -p 80:80/tcp \
  -p 10081:10081/tcp \
  -e KUBOARD_ENDPOINT="http://10.96.201.0:80" \
  -e KUBOARD_AGENT_SERVER_TCP_PORT="10081" \
  -v /root/kuboard-data:/data \
  eipwork/kuboard:v3

WARNING

  • KUBOARD_ENDPOINT 参数的作用是,让部署到 Kubernetes 中的 kuboard-agent 知道如何访问 Kuboard Server;
  • KUBOARD_ENDPOINT 中也可以使用外网 IP;
  • Kuboard 不需要和 K8S 在同一个网段,Kuboard Agent 甚至可以通过代理访问 Kuboard Server;
  • 建议在 KUBOARD_ENDPOINT 中使用域名;
  • 如果使用域名,必须能够通过 DNS 正确解析到该域名,如果直接在宿主机配置 /etc/hosts 文件,将不能正常运行;

参数解释

  • 建议将此命令保存为一个 shell 脚本,例如 start-kuboard.sh,后续升级 Kuboard 或恢复 Kuboard 时,需要通过此命令了解到最初安装 Kuboard 时所使用的参数;
  • 第 4 行,将 Kuboard Web 端口 80 映射到宿主机的 80 端口(您可以根据自己的情况选择宿主机的其他端口);
  • 第 5 行,将 Kuboard Agent Server 的端口 10081/tcp 映射到宿主机的 10081 端口(您可以根据自己的情况选择宿主机的其他端口);
  • 第 6 行,指定 KUBOARD_ENDPOINT 为 http://内网IP,如果后续修改此参数,需要将已导入的 Kubernetes 集群从 Kuboard 中删除,再重新导入;
  • 第 7 行,指定 KUBOARD_AGENT_SERVER 的端口为 10081,此参数与第 5 行中的宿主机端口应保持一致,修改此参数不会改变容器内监听的端口 10081,例如,如果第 5 行为 -p 30081:10081/tcp 则第 7 行应该修改为 -e KUBOARD_AGENT_SERVER_TCP_PORT="30081"
  • 第 8 行,将持久化数据 /data 目录映射到宿主机的 /root/kuboard-data 路径,请根据您自己的情况调整宿主机路径;

其他参数

  • 在启动命令行中增加环境变量 KUBOARD_ADMIN_DERAULT_PASSWORD,可以设置 admin 用户的初始默认密码。

在浏览器输入 http://your master ip:80 即可访问 Kuboard v3.x 的界面,登录方式:

  • 用户名: admin
  • 密 码: Kuboard123

下一期出一个 Kuboard 使用的教程。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐