很多视频、博客,都是基于虚拟机的,但是真实环境不能照搬。
收手吧阿祖,看我这就打住吧,外面全是坑 😅
其实搭建的各种配置,版本不对齐问题,导致自搭建集群困难重重,我这里有极简版本,包教包会,我已经搭建几十次了,不到五分钟即可搭建。但是很多步骤、概念我们还是一步步来。
搭建K8s集群
目前主流搭建k8s集群有以下四种方式:
minikube
minikube 是一个工具, 能让你在本地运行 Kubernetes。 minikube 在你的个人计算机(包括 Windows、macOS 和 Linux PC)上运行一个一体化(all-in-one)或多节点的本地 Kubernetes 集群,以便你来尝试 Kubernetes 或者开展每天的开发工作。适合初学者学习。
kubeadm
你可以使用 kubeadm 工具来创建和管理 Kubernetes 集群。 该工具能够执行必要的动作并用一种用户友好的方式启动一个可用的、安全的集群。
二进制安装
利用 k8s 官方 github 仓库下载二进制包安装,安装过程较复杂,但相对较为稳定,推荐生产环境使用
命令行工具
我们使用kubeadm来搭建。
强烈建议使用真实的云服务器来搭建,买个按流量计费的,要不了多少钱。很多视频、博客都是按照虚拟机,你照着他们,根本在云平台上就搭建不起来。
先放行
开启相关端口,必须在云服务后台操作,因为还包装了一层。
master 节点
协议 端口范围 作用 使用者 TCP 6443 Kubernetes API 服务器 所有组件 TCP 2379-2380 etcd 服务器客户端 API kube-apiserver、etcd TCP 10250 Kubelet API kubelet 自身、控制平面组件 TCP 10251 kube-scheduler kube-scheduler 自身 TCP 10252 kube-controller-manager kube-controller-manager 自身 TCP 10252 kube-controller-manager kube-controller-manager 自身 worker节点
协议 端口范围 作用 使用者 TCP 10250 Kubelet API kubelet 自身、控制平面组件 TCP 30000-32767 NodePort 服务 所有组件 所有节点
协议 端口范围 作用 使用者 UDP 8472 vxlan Overlay 网络通信 Overlay 网络 TCP 179 calico networking BGP UDP 4789 calico networking BGP TCP 5473 calico networking BGP
初始操作
先不要跟着敲,后面有彩蛋。先不要跟着敲,后面有彩蛋。先不要跟着敲,后面有彩蛋。
前置环境准备如下:
两台服务器,分别为:43.138.214.237 master,43.136.97.177 node1 最低配置:2核2G,20G硬盘,网络通畅 CentOS7的操作系统 Docker:18.09.9 k8s:v1.16.4
注意的点是k8s和docker是有版本依赖的,切记切记
初始化操作
每台节点上面都需要操作的
# 关闭防火墙 systemctl stop firewalld systemctl disable firewalld # 关闭selinux sed -i 's/enforcing/disabled/' /etc/selinux/config # 永久 setenforce 0 # 临时 # 关闭swap swapoff -a # 临时 sed -ri 's/.*swap.*/#&/' /etc/fstab # 永久 # 根据规划设置主机名 hostnamectl set-hostname <hostname> # 配置ip_forward转发 echo "1" > /proc/sys/net/ipv4/ip_forward # 添加hosts cat >> /etc/hosts << EOF 43.136.97.177 k8s-node1 43.138.214.237 k8s-master EOF
安装基础软件
安装Docker
卸载旧版本 yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine rm -rf /etc/yum.repos.d/* # 下载centos7软件源和ocker源 wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo wget -P /etc/yum.repos.d/ http://mirrors.aliyun.com/repo/epel-7.repo wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # 刷新yum缓存 yum clean all && yum makecache fast #配置镜像 #推荐使用阿里云 yum-config-manager \ --add-repo \ http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 安装docker相关内容,ce社区版本,ee企业版本 yum install docker-ce-18.09.9 docker-ce-cli-18.09.9 containerd.io -y docker version #行k8s需要docker配置参数--cgroup-driver=systemd sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://pue18cfq.mirror.aliyuncs.com"], "exec-opts": ["native.cgroupdriver=systemd"] } EOF # 启动docker systemctl enable docker.service sudo systemctl daemon-reload sudo systemctl restart docker
添加阿里云源
cat <<EOF > /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64 enabled=1 gpgcheck=0 EOF
安装kubeadm、kubelet、kubectl
yum install -y kubelet-1.16.4 kubeadm-1.16.4 kubectl-1.16.4 # 设置开机启动 systemctl enable kubelet && systemctl start kubelet # 添加kubectl上下文到环境中,并在~目录中,使配置生效 echo "source <(kubectl completion bash)" >> ~/.bash_profile cd ~ source .bash_profile # 将桥接的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 -p /etc/sysctl.d/k8s.conf
好了,到这里,是不是看懵逼了。
彩蛋来了。哥们我整理了一个脚本,直接运行就好了。哪那么多幺蛾子。
享用方式,拷贝下来后,修改如下几个点:
- 搜索addr add,把你的公网ip换上,这是把公网ip加到eth0里面,不然master init会出错的。很多人希望绕过去,正路不好么。
- 搜索set-hostname,换上你的节点名称,master或者是node。
- 搜索/etc/hosts,把你所有节点的hosts配置上去。
- 如果需要更好docker和k8s的版本,搜索docker-ce,换上docker的版本,搜索kubelet-,换上kubelet、kubeadm、kubectl的版本。请记得,docker和k8s的版本是配套使用的,否则出现奇奇怪怪的问题。
- 改完之后,给一个chmod +x setup_k8s.sh后,./setup_k8s.sh执行吧
- 看到 congratulations success 恭喜你,初步完成了。
经过测验一下版本对是可以的:
- docker-ce-20.10.20
- kubelet-1.23.6
- calico 3.24 https://docs.tigera.io/archive/v3.24/manifests/calico.yaml
部署Kubernetes master
只是在master上面做操作就可以了。 这里有个坑,就是kubeadm init 指定了"--apiserver-advertise-address"为公网ip,但是阿里云的机器是vpc网络,使用ifconfig时候,可以看到网卡上显示的是内网ip,并没有公网ip,这就会导致etcd无法启动
,解决的办法可以参考:公网访问解决方案
不过我有个骚操作,就是在执行init的时候,等待检测到createing /etc/kubernetes/manifests的时候,立即在另外一个窗口上执行把etcd的公网ip替换为内网ip即可。vim /etc/kubernetes/manifests/etcd.yaml
把下面三行替换掉:
- --listen-client-urls=https://127.0.0.1:2379
- --listen-metrics-urls=http://127.0.0.1:2381
- --listen-peer-urls=https://127.0.0.1:2380
但是,我是说但是,如果你使用我的shell脚本,就没有问题,不用骚操作,因为我把公网地址配置到网卡里面去了。
我们直接来正常流程吧。
kubeadm init \
--apiserver-advertise-address=43.138.214.237 \
--image-repository registry.aliyuncs.com/google_containers \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16
看到没,就是这么简单,你只需要把apiserver-advertise-address 换成你的公网ip后即可。
慢慢等,不需要做任何操作,如果你看到:
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 43.138.214.237:6443 --token 426zly.paefezw4aeqf7yul \
--discovery-token-ca-cert-hash sha256:ac599b1060922ea80522de42cdcc825aeeb6da50735ee350fa3aea658dfb3f63
那么恭喜你,master安装完成了,你只是需要执行下面三步即可。
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
[root@VM-12-9-centos ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master NotReady master 1m48s v1.16.4
部署work节点
这个就简单了,直接加入集群即可:
#加入集群,就是复制刚刚的kubeadm join
kubeadm join 43.136.97.177:6443 --token ognh7w.hyhfgt6hi1mchuzv \
--discovery-token-ca-cert-hash sha256:ee0e8a7ae2f547f1a7d6cbdd4a8fdfc26914dcedef098944c4077858dc3629b9
但是,此时在master上面查看状态:
[root@VM-12-9-centos ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master NotReady master 35m v1.16.4
k8s-node1 NotReady <none> 30m v1.16.4
这是由于还没有网络,没法连起来就绪。
如果你忘记之前join的连接了,可以重新生成,并不是影响已经 加入过节点的信息。
kubeadm token create --print-join-command
部署 CNI 网络插件
存档点
正常来说,你已经度过第一阶段了,使用我的shell脚本,你应该还好吧,比其他博客要简单吧。
接下来,需要进行网络配置了。
“安装网络插件”对环境是破坏性的。如果安装失败了,它很难简单使用kubeadm reset重置。它会给你的机器引入永久性的改变……
我想说的是,如果网络插件安装失败、或者想改变使用的网络插件,你可能会陷入一种“无论如何配置都不行”的境地。
你仍然可以反复尝试,但我需要提醒的是:如果你多次尝试都失败,很可能是机器环境已经被网络插件改变过了,你可能需要回滚这些设置。
所以:
1:如果你有条件,可以考虑在此时创建一个系统镜像,以方便回滚。
2:如果不行,你可以查找如何彻底卸载网络插件的方法, 这个东西因插件、版本而异。
3:但较简单的做法,可能是重装系统,然后重新执行一次上述步骤。我重装了N次。。。
嗯,我也是使用简单的。
在master节点中执行以下命令进行配置:
- 下载:wget -O local_calico.yaml https://docs.projectcalico.org/v3.10/manifests/calico.yaml
- 修改calico.yaml 搜索CALICO_IPV4POOL_CIDR,把value换成 10.244.0.0/16 即可
- 执行
kubectl apply -f calico.yaml
如果你的机器下来不下来,你就手动下来下来修改后再执行吧。
一般来说,等个两分钟,状态就就绪了。
[root@k8s-master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master Ready master 36m v1.16.4
k8s-node1 Ready <none> 35m v1.16.4
[root@VM-12-9-centos ~]# kubectl get po -n kube-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-7994b948dd-knhzm 1/1 Running 0 119s
calico-node-cthzk 1/1 Running 0 119s
calico-node-kg6h4 1/1 Running 0 119s
coredns-58cc8c89f4-7l7fv 1/1 Running 0 4m51s
coredns-58cc8c89f4-v8gc9 1/1 Running 0 4m51s
etcd-k8s-master 1/1 Running 0 4m9s
kube-apiserver-k8s-master 1/1 Running 0 4m11s
kube-controller-manager-k8s-master 1/1 Running 0 4m4s
kube-proxy-dwlrp 1/1 Running 0 3m43s
kube-proxy-lkx89 1/1 Running 0 4m51s
kube-scheduler-k8s-master 1/1 Running 0 3m51s
测试
[root@VM-12-9-centos ~]# kubectl create deployment nginx --image=nginx
deployment.apps/nginx created
[root@VM-12-9-centos ~]# kubectl expose deployment nginx --port=80 --target-port=80 --type=NodePort
service/nginx exposed
[root@VM-12-9-centos ~]# kubectl get pod,svc
NAME READY STATUS RESTARTS AGE
pod/nginx-86c57db685-km82j 1/1 Running 0 48s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7m3s
service/nginx NodePort 10.100.215.30 <none> 80:32571/TCP 17s
[root@VM-12-9-centos ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-86c57db685-km82j 1/1 Running 0 114s
节点配置kubectl
我们在其他节点,执行命令发现:
[root@VM-12-4-centos ~]# kubectl get nodes
The connection to the server localhost:8080 was refused - did you specify the right host or port?
我们需要配置:
- 将 master 节点中 /etc/kubernetes/admin.conf 拷贝到需要运行的服务器的 /etc/kubernetes 目录中
- 在对应的服务器上配置环境变量:
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
- 执行让其生效:
source ~/.bash_profile
[root@VM-12-4-centos kubernetes]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-86c57db685-km82j 1/1 Running 0 10m
总结
以下几步:
- 运行shell脚本,如果你使用我的docker和k8s版本的话,你就只是需要修改脚本的几个ip地址和hostname。
- init master节点
- node加入集群
- 部署CNI网络插件
打完收工
遇到的坑
错误:calico/node is not ready: Error querying BIRD: BIRD is not ready: BGP not established
calico-kube-controllers-7994b948dd-jxrjm 1/1 Running 0 6m30s calico-node-gnvf4 0/1 Running 0 6m26s calico-node-xfjl6 0/1 Running 0 6m41s
你去网上搜,大部分都是说网卡不对导致的,但是你配置了对应的网卡,比如eth*,ens*等等,还是运行不起来,pod还是不通。因为是云平台,所以两个节点之间没有建立BGP链接的原因,就是你没开端口,云平台要一个个端口开,你关闭防火墙也米用。
- master init会出错,原因就是etcd是内网的,访问不到,此时需要配置你的网卡,你也可以绕过去,但是总归不是正道。
资料
【云原生 • Kubernetes】搭建 k8s 集群(Kubeadm 方式)
【Kubernetes】centos7搭建k8s集群(一) - 环境搭建与安装