裸机搭建k8s集群 电脑版发表于:2022/5/30 15:20 tn2>这里自己用虚拟机搭建的,可以整一个主节点,几个子节点。要保证虚拟机能访问外网,能获取自己的ip地址以及能相互ping通。怎么装虚拟机可以参考这篇文章,网络这些的设置里边也有提到。 https://www.tnblog.net/aojiancc2/article/details/6357 装虚拟机的时候保证每个节点包括主节点有两个cpu,和2g内存。不然装环境会有问题的。 ## 每个节点设置好主机名 ``` hostnamectl set-hostname master hostnamectl set-hostname node1 hostnamectl set-hostname node2 ``` 主节点设置成master,子节点设置成node1,node2...。设置好后可以输入hostname查询一下是否设置成功了。 ![](https://img.tnblog.net/arcimg/aojiancc2/4a462ca01ce443e8bcf062588418c80b.png) ## 所有节点都修改 hosts tn2> 设置hosts是为了让主机名和ip地址做一个映射,能够使用主机名进行通讯。这里ip地址换成自己的电脑ip地址。我这里用vi编辑文件的,vim暂时没有装。 ``` vi /etc/hosts 192.168.1.102 master 192.168.2.108 node2 192.168.2.109 node1 ``` ![](https://img.tnblog.net/arcimg/aojiancc2/6954af53213c4604b339c1bd1632e13c.png) 修改之后根据主机名拼一下,试试能不能拼通 ![](https://img.tnblog.net/arcimg/aojiancc2/aa974a1b27e94dcbaae09dcfb9a9c0f1.png) ## 所有节点关闭 SELinux ``` # 所有节点关闭 SELinux setenforce 0 sed -i --follow-symlinks 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux ``` ## 关闭所有节点的防火墙 ``` systemctl stop firewalld systemctl disable firewalld ``` 可以使用如下命令查看防火墙是否关闭 ``` systemctl status firewalld ``` ## 所有节点设置iptables ``` iptables -P FORWARD ACCEPT ``` ## 所有节点关闭 swap ``` swapoff -a ``` 防止开机自动挂载 swap 分区(将 /etc/fstab 中的内容注释掉) ``` sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab ``` ## 所有节点关闭 selinux 和 firewalld 将 selinux 由 enforcing 改为 disabled 。注意下面命令中 disabled 前面是数字 1,不是小写的英文字母 l ``` sed -ri 's#(SELINUX=).*#\1disabled#' /etc/selinux/config ``` 临时关闭 enforce ``` setenforce 0 ``` 验证 enforce 是否已关闭:如关闭,应返回结果:Permissive ``` getenforce ``` ## 时间同步可能会执行一下 我这里是默认就同步了的,所以不执行也可以的。 tn2>如果要设置的话,所有主机均需要操作。最小化安装系统需要安装ntpdate软件。同步的是阿里云的时间。 ``` # crontab -l 0 */1 * * * /usr/sbin/ntpdate time1.aliyun.com ``` ## 所有节点修改内核参数(配置网桥过滤及内核转发) 第一种方法(推荐!写到独立内核文件中): ``` cat > /etc/sysctl.d/k8s.conf <<EOF net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 net.ipv4.ip_forward = 1 vm.max_map_count = 262144 vm.swappiness=0 EOF ``` 第二种方法(写到默认内核文件中:/etc/sysctl.conf) ``` cat >> /etc/sysctl.conf <<eof net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 net.ipv4.ip_forward = 1 vm.max_map_count = 262144 vm.swappiness=0 eof ``` 第三种方法(写到默认内核文件中:/etc/sysctl.conf): ``` sudo sysctl -w net.bridge.bridge-nf-call-ip6tables=0 sudo sysctl -w net.bridge.bridge-nf-call-iptables = 1 sudo sysctl -w net.ipv4.ip_forward = 1 sudo sysctl -w vm.max_map_count = 262144 sudo sysctl -w vm.swappiness=0 ``` **参数说明:** - net.bridge.bridge-nf-call-ip6tables 和 net.bridge.bridge-nf-call-iptables,netfilter实际上既可以在L2层过滤,也可以在L3层过滤的。当值为 0 ,即要求iptables不对bridge的数据进行处理。当值为 1,也就意味着二层的网桥在转发包时也会被iptables的FORWARD规则所过滤,这样就会出现L3层的iptables rules去过滤L2的帧的问题。 - max_map_count,文件包含限制一个进程可以拥有的VMA(虚拟内存区域)的数量。如不设置可能会报错:“max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]” - net.ipv4.ip_forward,出于安全考虑,Linux系统默认是禁止数据包转发的。所谓转发即当主机拥有多于一块的网卡时,其中一块收到数据包,根据数据包的目的ip地址将数据包发往本机另一块网卡,该网卡根据路由表继续发送数据包。这通常是路由器所要实现的功能。要让Linux系统具有路由转发功能,需要配置 Linux 的内核参数 - net.ipv4.ip_forward = 1。如果你不设置这个,你部署的web服务可能会在外部访问不到。 - swappiness,等于 0 的时候表示最大限度使用物理内存,然后才是 swap空间,swappiness=100的时候表示积极的使用swap分区,并且把内存上的数据及时的搬运到swap空间里面。 **然后所有节点执行如下命令加载内核使修改生效** ``` modprobe br_netfilter sysctl -p /etc/sysctl.d/k8s.conf ``` ## 所有节点添加安装源 ``` # 添加 k8s 安装源 cat <<EOF > kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64 enabled=1 gpgcheck=1 repo_gpgcheck=1 gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg EOF mv kubernetes.repo /etc/yum.repos.d/ # 添加 Docker 安装源 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo ``` tn>如果执行yum-config-manager报错:yum-config-manager: 未找到命令。 这个是因为系统默认没有安装这个命令,这个命令在yum-utils 包里,可以通过命令yum -y install yum-utils 安装就可以了。 #### 然而你执行yum -y install yum-utils,可能还会遇到错 repomd.xml signature could not be verified for kubernetes **是因为repo 的 gpg 验证不通过导致的,可以修改repo_gpgcheck=0跳过验证。** 在linux下,repo文件都是存放在/etc/yum.repos.d文件夹之中的 进入/etc/yum.repos.d,找到kubernetes.repo,文件打开修改即可 ![](https://img.tnblog.net/arcimg/aojiancc2/f71e464b543b4c2c8a36a9978c1f4488.png) 修改repo_gpgcheck=0跳过验证。 ![](https://img.tnblog.net/arcimg/aojiancc2/4dc5b84d6cc34e6991c7c2f596ce7b60.png) 修改之后在执行yum -y install yum-utils就可以成功了 ![](https://img.tnblog.net/arcimg/aojiancc2/2a4e054c49144de495d93578464d4eba.png) ## 所有节点安装所需组件 tn2>版本更新太频繁了,刚开始用最新版本的时候坑要多点,所以可以固定一个版本,可以少点不同版本的坑。 比如我这里装的kubelet的1.16.2,和docker的18.06.3。要注意k8s和docker的版本对应。不然也可能会遇到问题的 ``` yum install -y kubelet-1.16.2 kubeadm-1.16.2 kubectl-1.16.2 docker-ce-18.06.3.ce-3.el7 ``` 1.18.0版本 <font color=red>(相比1.16.x推荐使用1.18版本)</font> ``` yum install -y kubelet-1.18.0 kubeadm-1.18.0 kubectl-1.18.0 --disableexcludes=kubernetes docker-ce-18.06.1.ce-3.el7 ``` 如果你想装最新版本,那么不接版本号就可以了 ``` yum install -y kubelet kubeadm kubectl docker-ce ``` 安装成功之后可以使用docker --version,和kubelet --version查看版本号 ![](https://img.tnblog.net/arcimg/aojiancc2/96c6deb7e99d4378996eff5071d4073d.png) ## 所有节点启动 kubelet、docker,并设置开机启动 ``` systemctl enable kubelet systemctl start kubelet systemctl enable docker systemctl start docker ``` ## 所有节点修改 docker 配置 主要是修改docker的cgroupdrive为systemd。不然和k8s的cgroupdrive不一致,会出现问题的。 ``` # kubernetes 官方推荐 docker 等使用 systemd 作为 cgroupdriver,否则 kubelet 启动不了 cat <<EOF > daemon.json { "exec-opts": ["native.cgroupdriver=systemd"], "registry-mirrors": ["https://ud6340vz.mirror.aliyuncs.com"] } EOF mv daemon.json /etc/docker/ ``` 修改之后,重启生效 ``` # 重启生效 systemctl daemon-reload systemctl restart docker ``` ## 用 kubeadm 初始化集群(仅在主节点跑) ``` # 初始化集群控制台 Control plane # 失败了可以用 kubeadm reset 重置 kubeadm init --image-repository=registry.aliyuncs.com/google_containers ``` tn6>初始化的时候最好设置一下,pod,service网段这些,还有监听使用的ip地址这些。 不然如果有多网卡,不设置监听的ip,识别到错误的网卡,就会出现错误的ip,你集群都加入不进来的。还有不设置pod,service网段这些你可能后面部署应用后通信会有问题,比如使用了NodePort类型的service,只有工作节点能访问,master节点访问不到(-。-坑了我很久的一个问题)。所以建议使用下面这种。当然也可以在配置文件中设置,就不用再kubeadm init中给参数了 ``` kubeadm init \ --apiserver-advertise-address=192.168.12.244 \ --image-repository registry.cn-hangzhou.aliyuncs.com/google_containers \ --kubernetes-version v1.18.0 \ --service-cidr=10.1.0.0/16 \ --pod-network-cidr=10.244.0.0/16 ``` 执行成功如下: ![](https://img.tnblog.net/arcimg/aojiancc2/6a4c846f129a4455b911ce33a57561f5.png) 把最下面的kubeadm命令复制一下,后边集群中的子节点要通过这个加入 #### 复制授权文件,以便 kubectl 可以有权限访问集群 ``` # 如果你其他节点需要访问集群,需要从主节点复制这个文件过去其他节点 mkdir -p $HOME/.kube cp -i /etc/kubernetes/admin.conf $HOME/.kube/config chown $(id -u):$(id -g) $HOME/.kube/config # 在其他机器上创建 ~/.kube/config 文件也能通过 kubectl 访问到集群 ``` ## 把工作节点(slave)加入到集群中(在所有 slave 执行) 就执行刚刚复制的命令,类似:kubeadm join 192.168.2.102:6443 --token xxx --discovery-token-ca-cert-hash xxx ###注意格式: 复制出来是这种带换行的格式 ![](https://img.tnblog.net/arcimg/aojiancc2/e34309fc78524327abe91250a22ac231.png) 需要处理成一行的格式在执行: ![](https://img.tnblog.net/arcimg/aojiancc2/db203712b72742798b9304b781922f40.png) **运行成功效果如下:** ![](https://img.tnblog.net/arcimg/aojiancc2/a8c47e3d60424ce5bfc57544923d15c5.png) ## 在主节点查看集群 **使用kubectl get nodes查看集群情况:** ![](https://img.tnblog.net/arcimg/aojiancc2/d2f3136e906f404c8e7a923b54d0bb28.png) 其他节点有安装 kubectl 也可以查看 目前节点都是NotReady状态,因为这个 Master 节点的网络尚未就绪。 ![](https://img.tnblog.net/arcimg/aojiancc2/4003abeb92654f2089836712f9e06425.png) ## 安装网络插件flannel,否则 node 是 NotReady 状态,主节点跑就行(网络插件推荐使用calico了,可以跳过flannel的安装方法看下面的教程) ``` kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml ``` tn6>注意由于这是外国的网址很有可能会访问不到遇到错误:kube-flannel.yml The connection to the server raw.githubusercontent.com was refused。 是因为域名解析不了,所以访问不了。 ![](https://img.tnblog.net/arcimg/aojiancc2/22e52517d0dc4021a4d31356c87a9c9d.png) ### 解决方法: 不用域名登录,直接用ip登录,或者去/etc/hosts里设置下域名解析 **1、通过第三方网站查询到raw.githubusercontent.com所对应的ip是多少** http://ip.tool.chinaz.com/raw.githubusercontent.com ![](https://img.tnblog.net/arcimg/aojiancc2/1b59a5ca3efe4284a7fc25e84f3eebf2.png) **2、修改/etc/hosts做好域名解析,ip最好用网站上查询到的最新的** 使用vi命令打开hosts文件: ``` vi /etc/hosts ``` 添加:185.199.109.133 raw.githubusercontent.com ![](https://img.tnblog.net/arcimg/aojiancc2/1bc8014217a14087959330a37a795466.png) **3、再次执行上面贴的命令就可以成功了** ![](https://img.tnblog.net/arcimg/aojiancc2/7d529af2bbb743d78cfe259cb8e95821.png) ### 再次查看节点状态就已经正常了! ![](https://img.tnblog.net/arcimg/aojiancc2/8647e68785b746208d12d1346724b5aa.png) ### 解决方法2 把地址换一下,换成可以访问的地址。 ``` kubectl apply -f https://www.tnblog.net/k8s/kube-flannel.yml ``` **如果访问不到了,可以自己把`kube-flannel.yml`下载下来,然后在执行:** 链接: https://pan.baidu.com/s/1lotIWPVZYjmav89-wjbe_A?pwd=pqeb 提取码: pqeb 复制这段内容后打开百度网盘手机App,操作更方便哦 ## 安装网络插件calico calico和flannel类似,感觉更强大一点,所以推荐使用它 ####下载calico 注意版本,如果直接下载最新版本会报错,和你的k8s不匹配,比如我这里k8s使用的1.18.0,calico使用v3.14版本是可以的 ``` wget https://docs.projectcalico.org/v3.14/manifests/calico.yaml --no-check-certificate ``` tn2>如果因为网络问题下载不到可以使用下面的地址下载后然后放到传递k8s的电脑上即可。 链接: https://pan.baidu.com/s/1VNUPE4HmIAW_F2_Mo-wfgg?pwd=c75e 提取码: c75e 复制这段内容后打开百度网盘手机App,操作更方便哦 #### 下载之后修改配置,修改calico.yaml里的pod网段 tn2>把calico.yaml里pod所在网段改成kubeadm init时选项--pod-network-cidr所指定的网段。 默认是192.168.0.0/16。把这个地址修改成kubeadm init时选项--pod-network-cidr所指定的网段,所以我这里应该修改成10.244.0.0/16。 1:使用vi calico.yaml打开文件 2:在命令模式下输入/192就可以快速定位到需要修改的地址了,不然慢慢找太麻烦了,文件很长 3:然后把注释取消掉,把value的默认值修改成我们的ip地址即可 ![](https://img.tnblog.net/arcimg/aojiancc2/bbbd1e811e0946309692314796f3f923.png) 4:执行一下即可kubectl apply -f calico.yaml 可能在多网卡下你还需要配置一下calico使用的网卡问题 tn4> 视频教程地址:录一套视频准备地址放到tnblog