K8s2️⃣集群搭建(详)
Hint:若物理机内存不足,避免多台虚拟机同时操作造成死锁,建议不要同时操作(特别是下载、重启等)。
1、说明
1.1、部署方式
K8s 常用部署方式
- 单节点:minikube
- 集群:
- kubeadm:快速部署 K8s 集群。
- 二进制包:下载并依次安装组件的二进制包,有利于理解 K8s 集群的组件。
1.2、集群类型
一主多从 | 多主多从 | |
---|---|---|
含义 | 1 个 Master,多个 Node | 多个 Master,多个 Node |
特点 | 搭建简单,存在单机故障风险 | 搭建复杂,安全性高 |
使用场景 | 测试环境 | 生产环境 |
图例 |
1.3、kubeadm(❗)
kubeadm:快速部署 K8s 集群的工具
kubeadm init
:在 Master 节点执行,初始化控制平面节点。kubeadm join
:在 Node 节点执行,部署工作节点并加入集群。
1.3.1、前置条件
安装 kubeadm,部署 K8s 集群 的前提
- 操作系统
- 至少 2 台 Linux 机器,推荐 Ubuntu 或
CentOS
发行版 - 每个节点
CPU
2+,RAM
2GB+,硬盘
30GB+
- 至少 2 台 Linux 机器,推荐 Ubuntu 或
- 集群要求
- 节点之间网络互通(部署网络插件,内网或公网)
- 节点具有唯一的主机名、MAC 地址、product_uuid
- 节点启用必要端口,禁止 swap 分区
1.3.2、搭建步骤
-
主机:
- 主机(节点):搭建、初始化
- 基本组件安装:Docker 和 kubeadm
-
K8s 组件:
- Master:初始化控制平面,部署网络插件。
- Node:将工作节点加入集群
-
可视化界面:部署 Dashboard Web
2、集群搭建:主机(❗)
示例:搭建一主二从的 K8s 集群,节点基本信息如下
Hint:网络号与电脑相关,主机号任意(不冲突即可)。
操作系统 | IP 地址 | |
---|---|---|
master | CentOS 7.9,基础设施服务器 | 网络号.100 |
node1 | 同上 | 网络号.101 |
node2 | 同上 | 网络号.102 |
如何确定网络号(网段)?
- 虚拟机:VMware 编辑 → 虚拟网络编辑器 → Vmnet8 → NAT 设置👉子网地址。
- 服务器:控制台信息
2.1、主机搭建
搭建 3 台虚拟机,重点如下:
-
操作系统
版本 CentOS 7.5+ CPU 2+(如 1 处理器 * 2 内核) RAM 2GB+ 硬盘 30GB+ 软件选择 基础设施服务器(Infrastructure Server) 磁盘分区 自动分区即可
(若手动分区不给swap
分配内存) -
网络配置:注意节点的 IP 地址和主机名唯一
- 主机名唯一:如
k8s.master
,k8s.node1
,k8s.node2
- 禁用 DHCP,手动设置 IP 地址:位于虚拟机网段下,三台主机号分别为 100、101、102
- 主机名唯一:如
2.2、主机初始化
所有节点都需操作,可借助 Xshell 的多会话操作功能。
- 若安装过程无误,但集群不可用,可能是同时操作多会话导致的冲突(如镜像下载,配置)。
- 可尝试依次执行操作,而不是同时执行。
2.2.1、系统设置
① 系统防火墙 & iptables
禁用
-
系统防火墙:K8s 集群节点必须开放必要端口。
(此处测试环境,直接关闭防火墙)
# 状态 systemctl status firewalld # 临时关闭 systemctl stop firewalld # 永久关闭 systemctl disable firewalld
-
iptables:K8s 和 Docker 启动时会产生大量 iptables,易与系统规则混淆。
(若显示找不到服务,跳过此项)
# 状态 systemctl status iptables # 临时关闭 systemctl stop iptables # 永久关闭 systemctl disable iptables
② 主机名解析
便于集群中节点的相互调用(以主机名形式)
-
查看主机名
-
hostnamectl # 或 hostname
-
-
设置主机名:if you need it
hostnamectl set-hostname 主机名 # 或 hostname 主机名
-
主机名解析:每个节点都要配置,格式
IP地址 主机名
(企业建议搭建 DNS)
# vim /etc/hosts,追加以下内容 192.168.88.100 k8s.master 192.168.88.101 k8s.node1 192.168.88.102 k8s.node2
-
自测:保存配置后,尝试
ping 主机名
。
③ 时间同步
集群中的所有节点,要求时间精确统一
-
查看系统时间
date
-
时间同步服务器:
chronyd
# 查看状态 systemctl status chronyd # 启动 systemctl start chronyd # 设置开机自启 systemctl enable chronyd
④ SELinux
Linux 的安全服务,可能会影响集群安装
-
状态:
Enforcing
,Permissive
,Disable
getenforce
-
关闭
-
临时关闭:系统重启后失效
setenfoce 0
-
永久关闭:SELINUX 改为
disabled
,系统重启后生效。vim /etc/selinux/config # 改动:SELINUX=disabled
-
⑤ 禁用 swap 分区
swap 分区:内存不足时,将磁盘空间虚拟成内存,会降低集群性能。
若机器必须启用 swap 分区,需在安装集群时进行相应配置(👉百度)
-
临时关闭:系统重启后失效。
swapoff -a
-
永久关闭:将相应配置注释掉(系统重启才生效)
vim /etc/fstab # 注释 /dev/mapper/centos-swap 一行
2.2.2、网络配置(❗)
① 内核参数
配置地址转发和网桥过滤
-
创建 K8s 配置文件
vim /etc/sysctl.d/kubernetes.conf
-
配置内容
net.bridge.bridge-nf-call-iptables=1 net.bridge.bridge-nf-call-ip6tables=1 net.ipv4.ip_forward=1 net.ipv4.tcp_tw_recycle=0 vm.swappiness=0 # 禁用swap,系统OOM才允许使用 vm.overcommit_memory=1 # 不检查物理内存是否够用 vm.panic_on_oom=0 # OOM的处理方案,OOM killer
-
重新加载配置
sysctl -p
-
-
网桥过滤模块:用于支持 iptables 检查桥接流量。
-
加载模块
modprobe br_netfilter
-
确认加载成功
-
lsmod | grep br_netfilter
-
-
② ipvs
kube-proxy 有 2 种代理模型,iptables 和 ipvs
ipvs 性能更高,因此选用 ipvs。
-
下载:网速慢,需等待
yum -y install ipset ipvsadm
-
配置文件
# vim /etc/sysconfig/modules/ipvs.modules,内容如下 #!/bin/bash modprobe -- ip_vs modprobe -- ip_vs_rr modprobe -- ip_vs_wrr modprobe -- ip_vs_sh modprobe -- nf_conntrack_ipv4
-
加载 ipvs 模块
-
添加可执行权限(👉Linux 文件权限)
# 查看权限 ll /etc/sysconfig/modules/ipvs.modules # 修改权限 chmod 755 /etc/sysconfig/modules/ipvs.modules
-
执行脚本
/bin/bash /etc/sysconfig/modules/ipvs.modules
-
确认加载成功
-
lsmod | grep -e ip_vs -e nf_conntrack_ipv4
-
-
重启机器,使所有配置生效。
reboot
Hint:
- 避免多台虚拟机同时重启造成死锁,建议不要同时重启。
- 回溯本节内容,确认配置生效。
2.2.3、免密登录(*)
Hint:配置公钥,实现集群节点的免密登录访问(若不需要可跳过)。
在每台主机进行以下操作。
示例:master 和 node1 需要免密访问,在这 2 台机器上操作。
-
创建用户 admin,用于集群访问
(也可直接用 root 用户,看个人需求)
useradd admin passwd admin
-
生成密钥文件:包括公钥和私钥
-
# 输入以下指令,按3次回车 ssh-keygen -t rsa
-
-
拷贝公钥:给需要免密访问的远程主机,包括当前机器
-
格式:若已配置主机名解析,则远程 IP 地址改成主机名。
# 若指令正确但无法执行,手动输入即可(不要复制粘贴) ssh-copy-id –i ~/.ssh/id_rsa.pub 远程用户@远程IP地址
-
需要输入:yes,目标主机密码
-
-
测试:若无需输入密码,说明成功
-
ssh 主机号
-
2.3、基本组件安装
注意兼容性
- 容器运行时:Docker
- K8s 组件:kubeadm、kubelet、kubectl
2.3.1、容器运行时
容器运行时(Container Runtime):用于运行容器的软件
👉 CentOS7 安装 Docker,注意点:
- 建议多个虚拟机不要同时安装,避免同时争夺网络和 RAM 导致安装速度慢。
- 兼容性:此处选择
docker-ce-18.06.3.ce-3.el7
- cgroup 配置
2.3.2、kubeadm(❗)
兼容性
-
kubeadm 必须与其它组件的版本匹配(相同,或高一个版本)
-
示例
版本 kubernetes 和 kubelet 1.17.4 kubeadm
1.17.4 或 1.17.5
① 更新镜像源
创建
kubernetes.repo
文件,输入以下配置
# vim /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
② 安装指定版本
--setopt=obsoletes=0
:避免 yum 自动安装更高版本
注意版本号,此处安装 1.17.4 版本
yum install -y --setopt=obsoletes=0 kubelet-1.17.4-0 kubeadm-1.17.4-0 kubectl-1.17.4-0
③ 配置
-
配置 cgroup,设置 service 代理方式为 ipvs
# vim /etc/sysconfig/kubelet,清除原来的内容,新内容如下 KUBELET_CGROUP_ARGS="--cgroup-driver=systemd" KUBE_PROXY_MODE="ipvs"
-
设置 kubelet 开机自启
systemctl enable kubelet
3、集群搭建:K8s 组件(❗)
- master:初始化控制面板
- node:加入集群
3.1、初始化控制面板(m)
Hint:仅在 master 操作
-
查看所需组件
kubeadm config images list
-
初始化:执行初始化命令时,kubeadm 会从远程仓库拉取镜像。
- 默认仓库 是国外的
k8s.gcr.io
,国内可能无法访问。 - 因此采用预拉取方式,从国内镜像仓库拉取镜像,重命名为 kubeadm 可识别的镜像名称。
- 默认仓库 是国外的
3.1.1、容器镜像
采用预拉取方式准备容器镜像,而非默认的远程仓库。
-
通过
docker images
查看本地镜像。 -
定义镜像:注意版本
images=( kube-apiserver:v1.17.4 kube-controller-manager:v1.17.4 kube-scheduler:v1.17.4 kube-proxy:v1.17.4 pause:3.1 etcd:3.4.3-0 coredns:1.6.5 )
-
拉取镜像:
(循环:拉取,重命名,移除旧镜像)
for imageName in ${images[@]};do docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName k8s.gcr.io/$imageName docker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName done
-
通过
docker images
查看本地镜像,对比拉取前后的区别。
3.1.2、初始化
-
apiserver-advertise-address
:master 节点的 IP 地址(注意修改) -
kubernetes-version
:版本(注意) -
其它选项可用默认值。
kubeadm init \ --apiserver-advertise-address=192.168.88.100 \ --kubernetes-version=v1.17.4 \ --pod-network-cidr=10.244.0.0/16 \ --service-cidr=10.96.0.0/12
kubeadm 初始化完成
显示以下提醒信息:
3.1.3、配置
-
创建配置目录(用于 kubectl)
# 依次执行以下指令 mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config
-
部署网络插件:(👉3.3)
-
token:(👉 3.2)
3.2、添加工作节点(n)
Hint:master 默认会加入集群,因此仅在 node 操作
-
<ip/host:port>
:控制面板(master)信息 -
token、CA 证书:由 master 生成。
kubeadm <ip/host:port> --token <token> \ --discovery-token-ca-cert-hash sha256:<hash>
3.3、控制面板(m)
Hint:在 master 操作
3.3.1、集群信息
-
查看信息
# 集群信息 kubectl cluster-info # 集群健康状况 kubectl get cs # 节点 kubectl get nodes
-
状态为
NotReady
,因尚未部署 pod 网络插件。
3.3.2、部署网络插件(❗)
作用:使集群中节点(Pod)可以相互通信。
选择 网络和网络策略 中任意一个选项,可参考对应 GitHub 仓库。
以 Flannel 为例:
-
下载配置文件:在服务器
wget
下载(或下载后上传到服务器)
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
-
部署网络插件
# 启动flannel kubectl apply -f 文件位置/kube-flannel.yml # 查看部署进度 kubectl get pods -n kube-system
-
查看节点信息:启动一段时间后,状态
Ready
Hint
kube-flannel.yml
默认配置国外的 Rancher/quay.io 镜像仓库若访问速度慢,可配置国内镜像仓库。
3.3.3、token 管理
通过命令的
--help
选项,可查看帮助文档。
格式:6位字符串.16位字符串
① 查看
kubeadm token list
② 删除
-
指定完整的 token 值,或前 6 位。
kubeadm token delete [token] ...
-
示例
kubeadm token delete ucvhw9.80nfuq10ujhy5dqi kubeadm token delete ucvhw9
③ 创建
kubeadm token create [token] [option] ...
-
token:指定正确格式的 token 值(可选),否则随机生成。
# 格式:[a-z0-9]{6}.[a-z0-9]{16} ucvhw9.80nfuq10ujhy5dqi
-
常用属性
含义 备注 --print-join-command 创建时打印加入集群的命令 即 kubeadm join ...
--ttl duration 有效期(默认 24h
)0
表示永不过期
4、部署服务(m)
尝试向集群中部署一个 Nginx 服务
- 👉kubernetes 组件:master 的
API Servier
作为控制面板的前端,接收用户请求。 - 因此,只能在 master 节点部署服务,在 node 节点部署会报错。
4.1、部署
-
部署 Nginx
kubectl create deployment nginx --image=nginx
-
暴露端口:
--port
指定 Nginx 部署在集群中的端口号。kubectl expose deployment nginx --port=80 --type=NodePort
4.2、查看服务
命令
-
查看 pod 情况
kubectl get pod
-
查看 service 情况
kubectl get service kubecrl get svc
端口映射:
PORTS
建立容器与宿主机的端口映射关系。
-
集群外部通过
宿主机:宿主机端口
(32212)访问 Nginx -
内部映射到集群中的
工作节点:容器端口
(80)
4.3、访问服务
-
通过 master 和 node 节点都可以访问
-
调试(F12 → Network):无论通过哪个节点访问,首次访问状态码 200,之后 304。