创建kubernetes集群
1. 前言
本文主要讲述配置一个最简单的 k8s 集群, 本集群由 1 个 master(master01) 和 2 个 node 节点(node01, node02)组成. 当前(2021/02/15) kubernetes 的最新稳定版本为 v1.20.2. 但是我依然采用的是较老的版本 v1.13.2, 因为众多参考文档使用的是这个版本,目前不清楚各组件之间的版本兼容性问题,所以依然采用这个版本,后续经过多次重复安装,验证各版本的兼容性后再回头来更新版本信息。另外网上有很多的 k8s 实验平台, 只需轻松几个点击, 就可以搭建 k8s 集群, 如果只是学习目的, 可以跳过这唬人的安装过程, 直接进入概念学习阶段, 等对 k8s 玩得很溜了再回头来搭建环境. 欲练此功, 不安装 k8s 也可以. 这里推荐play-with-k8s.com, 创建过程可参考这篇文章只要有 github 账号即可以登录使用.
2. 部署工具介绍
部署工具和部署环境有很多种选项
常用的部署环境:
IaaS 公有云环境:AWS, GCE, Azure,阿里云等;
Iaas 私有云环境: OpenStack 和 vSphere 等;
Baremetal 环境(裸金属环境):物理服务器或独立的虚拟机等;常用部署工具:
kubeadm
kops
kubespray
Kontena Pharos其它更完善的二次封装的常用发行版
Rancher (Labs)
Tectonic (CoreOS)
Openshift (Redhat)
本文主要讲述选择使用 kubeadm 采用 docker 镜像安装,目的是为了更好的掌握 kubernetes 深层次的概念和运行机制。
主机规划:
主机名 | 虚拟机类型 | 系统 | 配置 | 网络 |
---|---|---|---|---|
master01 | VirtualBox | Centos7.9 | 2U2GB SATA:100GB | IP:192.168.1.71 |
node01 | VirtualBox | Centos7.9 | 2U2GB SATA:50GB | IP:192.168.1.61 |
node01 | VirtualBox | Centos7.9 | 2U2GB SATA:50GB | IP: 192.168.162 |
2.1. 环境要求
各主机(master01, node01, node02)所需的环境如下:
(1) 借助于 NTP 服务设定各节点时间精确同步;
(2) 借助 DNS 完成各节点的主机名称解析,测试环境主机较少时可以使用 hosts 文件进行名称解析;
(3)关闭主机的 iptables 或 firewall 服务,并确保它们被禁止随系统引导过程启动;
(4)各主机禁用 SELinux;
(5) 各节点禁用所有 Swap 设备
(6)若要使用 ipvs 模型的 proxy, 各节点还需要载入 ipvs 相关的各模块
2.1.1. 设置各主机 ip
首先将虚拟机设置为桥接模式
在 x86 架构上安装 CentOs7 最小安装时,默认 ip 地址设置为 ipv6,如果需要设置为 ipv4,需要进行如下设置。
首先确定以 enp 打头的网卡
/etc/sysconfig/network-scripts/ifcfg-enp8s0
1 | 修改为 IPV6INIT=no |
修改 /etc/resolv.conf
1 | # 添加域名解析服务 |
1 | # 修改后立即重启网络服务,使其生效 |
2.1.2. 设置时钟同步
范围:master01, node01, node02
若各节点可直接访问互联网,直接启动 chronyd 系统服务,并设定为开机启动
1 | systemctl enable --now chronyd.service |
时钟同步后和主机不一致的解决办法
第一检查
1 | ls -ltr /etc/localtime |
如下
1 | 1、vi /etc/sysconfig/clock #编辑文件 |
1 | ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime #linux的时区设置为上海 |
不过,建议用户配置使用本地的时间服务器,在节点数量众多时尤其如此。 存在可用的时间服务器时,修改节点的/etc/chrony.conf 配置文件,并将时间服务器指向相应的主机即可, 配置格式如下:
1 |
|
2.1.3. 主机名称解析
范围:master01, node01, node02
出于简化配置步骤的目的,本教程使用 hosts 文件进行各节点名称解析,文件内容如下所示:
hostnamectl set-hostname <主机名>
1 | vi /etc/hosts |
2.1.4. 关闭 iptables 或 firewalld 服务
范围:master01, node01, node02
在 centos7 上, iptables 或 firewalld 服务通常只会安装并启动一种,在不确定具体启动状态的前提下,这里通过同时关闭并禁用二者即可简单达到设定目标。
1 |
|
2.1.5. 关闭并禁用 SELinux
范围:master01, node01, node02
修改 /etc/sysconfig/selinux 文件,将 SELINUX 配置设置为 disabled
1 | #修改配置文件,永久禁用selinux, 防止重启导致selinux开启 |
1 | # 禁用SELinux 立即生效 |
2.1.6. 禁用 Swap 设备
范围:master01, node01, node02
部署集群时,kubeadm 默认会预先检查当前主机是否禁用了 swap 设备,并在未禁用时强制终止部署过程。因此,在主机内存资源充裕的条件下,需要禁用所有的 Swap 设备,否则,就需要在后文的 kubeadm init 及 kubeadm join 命令执行时额外使用相关的选项忽略检查错误。
关闭 Swap 设备,需要分两步。首先关闭当前已启用的所有 Swap 设备:
1 |
|
然后编辑/etc/fstab 配置文件,注释掉 swap 设备的挂载项(永久关闭 swap 分区)
2.1.7. 启用 ipvs 内核模块
范围:master01, node01, node02
创建内核模块载入相关的脚本文件/etc/sysconfig/modules/ipvs.modules, 设定自动载入的内核模块。文件内容如下:
1 |
|
修改文件权限,并手动为当前系统加载内核模块
1 |
|
3. 安装程序包(在各主机上完成如下设定)
3.1. 安装 docker (master01, node01 & node02)
安装 docker 之前要确定 docker 版本是否在 kubernetes 相应版本支持列表里面,以避免遇到版本兼容性问题的坑,这里 列出了部分 kubernetes 版本与 docker 版本的兼容信息,希望对你的集群环境搭建有帮助。
3.1.1. 配置 docker-ce yum 源
范围:master01, node01, node02
1 | # 使用阿里云yum源 |
3.1.2. 配置 docker
3.1.2.1. 配置镜像加速
由于 dockerhub 镜像仓库在国外,访问速度较慢,下载镜像的过程中,多数情况下会因为超时而失败,所以强烈建议配置镜像加速。
另外在整个安装过程中主要需要与 internet 上三个镜像仓库打交道
- DockerHub,
- gcr.io 这个几乎不能访问,后面会介绍到如何获得其上相应的镜像
- quay.io , 主要是一些网络组件相关的镜像
1 | $sudo vi /etc/docker/daemon.json |
镜像加速列表
提供者 | 镜像地址 |
---|---|
科大镜像 | https://docker.mirrors.ustc.edu.cn/ |
网易 | https://hub-mirror.c.163.com/ |
阿里云 | <https://<你的ID>.mirror.aliyuncs.com> |
七牛云加速器 | https://reg-mirror.qiniu.com |
daocloud 加速器 | <http://<你的ID>.m.daocloud.io/> |
其他还有华为云镜像加速,显然是为华为云用户准备的,请参考这篇文章进行配置镜像加速
3.1.2.2. docker iptables FORWARD 策略
docker 自 1.13 版起会自动设置 iptables 的 FORWARD 默认策略为 DROP,这可能会影响 kubernetes 集群依赖的报文转发功能,因此,需要在 docker 服务启动后,重新将 FORWARD 链的默认策略设置为 ACCEPT,方式是修改/usr/lib/systemd/system/docker.service 文件,在 “ExecStart=/usr/bin/dockerd” 一行之后新增加一行内容如下:
1 | ExecStartPost=/usr/sbin/iptables -P FORWARD ACCEPT |
重载完成后即可启动 docker 服务:
1 | # 重新加载docker服务设置 |
设置为开机自启动
1 | systemctl enable docker |
确保默认使用桥接模式
1 | $ sudo sysctl -a | grep bridge |
如果不是桥接模式(等号后面为 0), 手动修改这两个参数
方法 1:
修改/etc/sysctl.conf 添加以上两个参数
方法 2:
在 /etc/sysctl.d 中添加一个以 conf 为后缀的文件例如 k8s.conf,将以上两项配置添加进去
手动执行 sysctl -p /etc/sysctl.conf 或者 sysctl -p /etc/sysctl.d/k8s.conf 使其立即生效
1 | net.bridge.bridge-nf-call-ip6tables = 1 |
3.2. 安装 kubelet (master01)
范围:master01, node01, node02
3.2.1. 配置 kubernetes yum 源
创建 /etc/yum.repos.d/kubernetes.repo
内容如下:
1 |
|
1 | # 更新yum源缓存 |
3.2.2. 安装 kubelet
master 和 node 节点要安装以下软件
1 | sudo yum install -y kubeadm-1.18.2-0.x86_64 kubelet-1.18.2-0.x86_64 kubectl-1.18.2-0.x86_64 kubernetes-cni-0.8.7-0.x86_64 |
并且要设置为开机启动
1 | systemctl enable kubelet && systemctl start kubelet |
说明:
- kubelet 为 Kubernetes 的核心守护进程之一,负责将配置清单运行为容器(Pod)
- Kubeadm 相当于部署集群本身的一个工具,用于简化集群的安装工作,负责根据配置文件部署集群,升级集群等等工作。
- kubectl 相当于集群的客户端,负责和集群的 API 组件交互,比如查询 node 的状态,容器的运行情况,以及提交任务等等。
3.2.3. 配置 kubelet
如果未禁用 swap 设备,则需要编辑 kubelet 的配置文件/etc/sysconfig/kubelet, 设置忽略 Swap 启用的状态错误, 内容如下:
1 | KUBELET_EXTRA_ARGS="--fail-swap-on=false" |
4. 配置 Master 和 Nodes
components 规划
主机名 | 组件 | 备注 |
---|---|---|
master01 | kubelet (yum 安装) kubadm (yum 安装) kubectl(yum 安装) docker (yum 安装) kube-apiserver (Pod)kube-scheduler (Pod) kub-controller-manager (Pod) cni (flannel Pod) etcd (Pod) kube-proxy (Pod) | |
node01 | kubelet (yum 安装) docker (yum 安装) cni (flannel Pod) kube-proxy (Pod) | |
node02 | kubelet (yum 安装) docker (yum 安装) cni (flannel Pod) kube-proxy (Pod) |
4.1. 插件安装
Metrics-Server(Pod)
Dashboard (Pod)
CoreDNS (Pod)
EFK (Pod)
Prometheus (Pod)
Ingress-Controller (Pod)
4.2. 配置 master 节点
4.2.1. 拉取必要的镜像
说明:k8s.gcr.io 上的镜像由于无法描述的原因,在国内无法直接拉取。但是阿里云 registry 中共享了相应版本的 kubernetes 镜像,这里再次感谢阿里的无私贡献,敬佩阿里的企业文化(利他),不仅免费,还有消耗阿里云的大量带宽。由于 docker 镜像命名规范的原因,拉取下来后要重新打 tag 才能使用,以下脚本包含了拉取镜像,更名,清理的功能。本人把安装文档写得足够详细,向阿里致敬!
kubeadm init –kubernetes-version=1.18.1 --apiserver-advertise-address=192.168.1.71 --image-repository registry.aliyuncs.com/google_containers --service-cidr=10.1.0.0/16 --pod-network-cidr=10.244.0.0/16
注意修改 apiserver-advertise-address 为 master 节点 ip
参数解释:
–kubernetes-version: 用于指定 k8s 版本;
–apiserver-advertise-address:用于指定 kube-apiserver 监听的 ip 地址,就是 master 本机 IP 地址。
–pod-network-cidr:用于指定 Pod 的网络范围; 10.244.0.0/16
–service-cidr:用于指定 SVC 的网络范围;
–image-repository: 指定阿里云镜像仓库地址
这一步很关键,由于 kubeadm 默认从官网 k8s.grc.io 下载所需镜像,国内无法访问,因此需要通过–image-repository 指定阿里云镜像仓库地址
4.2.2. 初始化 master
kubeadm init 命令支持两种初始化方式, 一是通过命令行选项传递关键部署设定,另一种是基于 yaml 格式的 kubeadm 专用配置文件,后一种运行用户自定义各种部署参数。下面分别给出了两种实现方式的配置步骤,建议读者采用第二种方式进行。
4.2.2.1. 初始化方式一
1 | systemctl enable kubelet.service |
命令中的各选项说明:
(1)–kubernetes-version 选项的版本号用于指定要部署的 kubernetes 程序版本,它需要与预拉取的 kubernetes 镜像版本一致参考脚本变量(K8S_VERSION)
(2)–pod-network-cidr 选项用于指定 pod 网络的网段,它通常应该与要部署使用的网络插件(例如 flannel, calico 等)的默认设定保持一致, 10.244.0.0/16 是 flannel 默认使用的网络;
(3)–service-cidr 用于指定为 Service 分配使用的网络地址,它由 kubernetes 管理, 默认即为 10.96.0.0/12
(4)最后一个选项 –ignore-preflight-errors=Swap 防止未禁用 swap 设备而导致初始化失败,生产环境建议关闭 swap 设备,已获得更好的性能,请参考前述禁用 swap 分区进行设定。
(5)这里需要读者对 kubernetes 的三层网(node 网络,pod 网络,service 网络)知识有所了解,再来做相关参数的调整。
4.2.2.2. 初始化方式二
kubeadm 也可以通过配置文件加载配置, 以定制更丰富的部署选项。以下是符合前述命令设定方式的使用示例,不过,它明确定义了 kubeProxy 的模式为 ipvs, 并支持通过修改 imageRepository 的值修改获取系统镜像时使用的镜像仓库。
1 | apiVersion: kubeadm.k8s.io/v1alpha2 |
将上面的内容保存于配置文件中, 例如 kuberadm-config.yaml, 而后执行相应的命令:
1 | # kubeadm init --config kubeadm-config.yaml --ignore-prelight-errors=Swap |
注意:对于 kubernetes 系统的新用户来说,无论使用上述哪种方式,命令运行结束后,请记录最后的 kubeadm join 命令输出的最后提示的操作步骤。 下面的内容是需要用户记录的一个命令输出示例,它提示了后续需要操作的步骤:
1 | To start using your cluster, you need to run the following as a regular user: |
接下来要部署一个 podnetwork addon
以 flannel 为例:
1 | kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml |
vi kube-flannel.yml
1 | --- |
注意:kubernetes 本身没有 pod 网络创建和管理功能,其本身只提供了一组依赖网络组件的接口,网络功能一般有第三方插件完成,比如 flannel, calico 等等。但是 Kubernetes 本身集成了 service 网络的管理功能,其底层实际是创建一系列 iptables 或 ipvs 规则来完成的。
部署完之后查看 kubernetes 相关的容器
coredns
etcd
kube-apiserver
kuber-controller
kube-flannel-ds-amd64-bbnz2
kube-proxy
kube-scheduler
4.3. 配置第一个 node 节点, 并添加到集群
修改 ip 地址
修改主机名部分,改为 k8s-node01
1 | hostnamectl set-hostname k8s-node01 |
安装软件
1 | sudo yum install -y kubeadm-1.18.2-0.x86_64 kubelet-1.18.2-0.x86_64 kubectl-1.18.2-0.x86_64 kubernetes-cni-0.8.7-0.x86_64 |
并且要设置为开机启动
1 | systemctl enable kubelet && systemctl start kubelet |
下载 flannel 镜像
1 | docker pull registry.cn-hangzhou.aliyuncs.com/daoh/flannel:v0.12.0-amd64 |
为镜像打 tag,保持和 yaml 文件一样。
1 | docker tag registry.cn-hangzhou.aliyuncs.com/daoh/flannel:v0.12.0-amd64 quay.io/coreos/flannel:v0.12.0-amd64 |
准备配置文件
1 | mkdir -p /etc/cni/net.d/ |
1 |
|
1 | mkdir ~/k8s |
在 master 上查询 join string
1 | kubeadm token create --print-join-command |
在 node 上执行查询结果, 加入集群
1 | kubeadm join 192.168.1.71:6443 --token ud6ny7.9wzcg5du5zvrbbfv \ |
设置开机启动
1 |
查看 node 状态
1 | [root@node01 k8s]# kubectl get nodes |
4.4. 配置第二个 node 节点, 并添加到集群
修改 ip 地址
vi /etc/sysconfig/network-scripts/ifcfg-enp0s3
修改 ip 地址
修改主机名部分,改为 k8s-node02
1 | hostnamectl set-hostname k8s-node02 |
重新启动
重新登录 node2
重新初始化节点配置, 执行命令
1 | kubeadm reset |
重新加入集群
1 | kubeadm join 192.168.1.71:6443 --token ud6ny7.9wzcg5du5zvrbbfv \ |
1 | [root@k8s-node02 ~]# kubectl get nodes |
5. 问题排查 troubleshooting
在 k8s 中,大部分的问题,都能通过 logs 和 describe 两个命令进行分析和定位
6. 后记
本技术博客原创文章位于鹏叔的技术博客 - 创建 kubernetes 集群, 要获取最近更新请访问原文.
更多技术博客请访问: 鹏叔的技术博客
7. 参考文档
Kubernetes 1.20 版本开始不推荐使用 Docker,你知道吗
Kubernetes 各版本对应支持的 docker 版本列表
k8s 不再支持 docker_k8s 不支持 Docker 了? 别慌!官方最新解释来了…
[Which kubernetes version is supported in docker version 18.09]
单机版 kubernetes 1.18.2 安装
https://www.cnblogs.com/zhizihuakai/p/12629514.html
https://blog.csdn.net/llinyunxia/article/details/106160654?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-0&spm=1001.2101.3001.4242
创建kubernetes集群