手把手从零部署与运营生产级的 Kubernetes 集群与 KubeSphere
本文来自 KubeSphere 社区用户 Liu_wt 投稿,欢迎所有社区用户参与投稿或分享经验案例。
本文将从零开始,在干净的机器上安装 Docker、Kubernetes (使用 kubeadm)、Calico、Helm 与 KubeSphere,通过手把手的教程演示如何搭建一个高可用生产级的 Kubernetes,并在 Kubernetes 集群之上安装 KubeSphere 容器平台可视化运营集群环境。
一、准备环境
开始部署之前,请先确定当前满足如下条件,本次集群搭建,所有机器处于同一内网网段,并且可以互相通信。
⚠️⚠️⚠️:请详细阅读第一部分,后面的所有操作都是基于这个环境的,为了避免后面部署集群出现各种各样的问题,强烈建议你完全满足第一部分的环境要求
- 两台以上主机
- 每台主机的主机名、Mac 地址、UUID 不相同
- CentOS 7(本文用 7.6/7.7)
- 每台机器最好有 2G 内存或以上
- Control-plane/Master至少 2U 或以上
- 各个主机之间网络相通
- 禁用交换分区
- 禁用 SELINUX
- 关闭防火墙(我自己的选择,你也可以设置相关防火墙规则)
- Control-plane/Master和Worker节点分别开放如下端口
Master节点
协议 | 方向 | 端口范围 | 作用 | 使用者 |
---|---|---|---|---|
TCP | 入站 | 6443* | Kubernetes API 服务器 | 所有组件 |
TCP | 入站 | 2379-2380 | etcd server client API | kube-apiserver, etcd |
TCP | 入站 | 10250 | Kubelet API | kubelet 自身、控制平面组件 |
TCP | 入站 | 10251 | kube-scheduler | kube-scheduler 自身 |
TCP | 入站 | 10252 | kube-controller-manager | kube-controller-manager 自身 |
Worker节点
协议 | 方向 | 端口范围 | 作用 | 使用者 |
---|---|---|---|---|
TCP | 入站 | 10250 | Kubelet API | kubelet 自身、控制平面组件 |
TCP | 入站 | 30000-32767 | NodePort 服务** | 所有组件 |
其他相关操作如下:
友情提示😊,如果集群过多,可以了解下 ansible,批量管理你的多台机器,方便实用的工具。
先进行防火墙、交换分区设置
# 为了方便本操作关闭了防火墙,也建议你这样操作
systemctl stop firewalld
systemctl disable firewalld
1. 关闭 SeLinux
setenforce 0
sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
1. 关闭 swap
swapoff -a
yes | cp /etc/fstab /etc/fstab_bak
cat /etc/fstab_bak |grep -v swap > /etc/fstab
更换CentOS YUM源为阿里云yum源
# 安装wget
yum install wget -y
1. 备份
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
1. 获取阿里云yum源
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
1. 获取阿里云epel源
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
1. 清理缓存并创建新的缓存
yum clean all && yum makecache
1. 系统更新
yum update -y
进行时间同步,并确认时间同步成功
timedatectl
timedatectl set-ntp true
⚠️⚠️⚠️以下操作请严格按照声明的版本进行部署,否则将碰到乱七八糟的问题
二、安装 Docker
2.1、安装 Docker
您需要在每台机器上安装 Docker,我这里安装的是 docker-ce-19.03.4
# 安装 Docker CE
1. 设置仓库
1. 安装所需包
yum install -y yum-utils
device-mapper-persistent-data
lvm2
1. 新增 Docker 仓库,速度慢的可以换阿里云的源。
yum-config-manager
--add-repo
https://download.docker.com/linux/centos/docker-ce.repo
1. 阿里云源地址
1. http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
1. 安装 Docker CE.
yum install -y containerd.io-1.2.10
docker-ce-19.03.4
docker-ce-cli-19.03.4
1. 启动 Docker 并添加开机启动
systemctl start docker
systemctl enable docker
2.2、修改 Cgroup Driver
需要将Docker 的 Cgroup Driver 修改为 systemd,不然在为Kubernetes 集群添加节点时会报如下错误:
# 执行 kubeadm join 的 WARNING 信息
[WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". Please follow the guide at https://kubernetes.io/docs/setup/cri/
目前 Docker 的 Cgroup Driver 看起来应该是这样的:
$ docker info|grep "Cgroup Driver"
Cgroup Driver: cgroupfs
需要将这个值修改为 systemd ,同时我将registry替换成国内的一些仓库地址,以免直接在官方仓库拉取镜像会很慢,操作如下。
⚠️⚠️⚠️:注意缩进,直接复制的缩进可能有问题,请确保缩进为正确的 Json 格式;如果 Docker 重启后查看状态不正常,大概率是此文件缩进有问题,Json格式的缩进自己了解一下。
# Setup daemon.
cat > /etc/docker/daemon.json > /etc/hosts
export MASTER_IP=192.168.115.49
export APISERVER_NAME=kuber4s.api
echo "${MASTER_IP} ${APISERVER_NAME}" >> /etc/hosts
友情提示🙂🙂🙂:
截止2020年01月29日,官方文档声明了使用 kubeadm 初始化 master 时,--config 这个参数是实验性质的,所以就不用了;我们用其他参数一样可以完成 master 的初始化。
--config string kubeadm 配置文件。 警告:配置文件的使用是试验性的。
下面有不带注释的初始化命令,建议先查看带注释的每个参数对应的意义,确保与你的当前配置的环境是一致的,然后再执行初始化操作,避免踩雷。
# 初始化 Control-plane/Master 节点
kubeadm init
--apiserver-advertise-address 0.0.0.0
1. API 服务器所公布的其正在监听的 IP 地址,指定“0.0.0.0”以使用默认网络接口的地址
1. 切记只可以是内网IP,不能是外网IP,如果有多网卡,可以使用此选项指定某个网卡
--apiserver-bind-port 6443
1. API 服务器绑定的端口,默认 6443
--cert-dir /etc/kubernetes/pki
1. 保存和存储证书的路径,默认值:"/etc/kubernetes/pki"
--control-plane-endpoint kuber4s.api
1. 为控制平面指定一个稳定的 IP 地址或 DNS 名称,
1. 这里指定的 kuber4s.api 已经在 /etc/hosts 配置解析为本机IP
--image-repository registry.cn-hangzhou.aliyuncs.com/google_containers
1. 选择用于拉取Control-plane的镜像的容器仓库,默认值:"k8s.gcr.io"
1. 因 Google被墙,这里选择国内仓库
--kubernetes-version 1.17.3
1. 为Control-plane选择一个特定的 Kubernetes 版本, 默认值:"stable-1"
--node-name master01
1. 指定节点的名称,不指定的话为主机hostname,默认可以不指定
--pod-network-cidr 10.10.0.0/16
1. 指定pod的IP地址范围
--service-cidr 10.20.0.0/16
1. 指定Service的VIP地址范围
--service-dns-domain cluster.local
1. 为Service另外指定域名,默认"cluster.local"
--upload-certs
1. 将 Control-plane 证书上传到 kubeadm-certs Secret
不带注释的内容如下,如果初始化超时,可以修改DNS为8.8.8.8后重启网络服务再次尝试。
kubeadm init
--apiserver-advertise-address 0.0.0.0
--apiserver-bind-port 6443
--cert-dir /etc/kubernetes/pki
--control-plane-endpoint kuber4s.api
--image-repository registry.cn-hangzhou.aliyuncs.com/google_containers
--kubernetes-version 1.17.3
--pod-network-cidr 10.10.0.0/16
--service-cidr 10.20.0.0/16
--service-dns-domain cluster.local
--upload-certs
接下来这个过程有点漫长(初始化会下载镜像、创建配置文件、启动容器等操作),泡杯茶,耐心等待,你也可以执行 tailf /var/log/messages
来实时查看系统日志,观察 Master 的初始化进展,期间碰到一些报错不要紧张,可能只是暂时的错误,等待最终反馈的结果即可。
如果初始化最终成功执行,你将看到如下信息:
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/
You can now join any number of the control-plane node running the following command on each as root:
kubeadm join kuber4s.api:6443 --token 0j287q.jw9zfjxud8w85tis
--discovery-token-ca-cert-hash sha256:5e8bcad5ec97c1025e8044f4b8fd0a4514ecda4bac2b3944f7f39ccae9e4921f
--control-plane --certificate-key 528b0b9f2861f8f02dfd4a59fc54ad21e42a7dea4dc5552ac24d9c650c5d4d80
Please note that the certificate-key gives access to cluster sensitive data, keep it secret!
As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use
"kubeadm init phase upload-certs --upload-certs" to reload certs afterward.
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join kuber4s.api:6443 --token 0j287q.jw9zfjxud8w85tis
--discovery-token-ca-cert-hash sha256:5e8bcad5ec97c1025e8044f4b8fd0a4514ecda4bac2b3944f7f39ccae9e4921f
为普通用户添加 kubectl
运行权限,命令内容在初始化成功后的输出内容中可以看到。
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
建议root用户也进行以上操作,作者使用的是root用户执行的初始化操作,然后在操作完成后查看集群状态的时候,出现如下错误:
The connection to the server localhost:8080 was refused - did you specify the right host or port?
这时候请备份好 kubeadm init
输出中的 kubeadm join
命令,因为将会需要这个命令来给集群添加节点。
⚠️⚠️⚠️提示:令牌是主节点和新添加的节点之间进行相互身份验证的,因此请确保其安全。任何人只要知道了这些令牌,就可以随便给您的集群添加节点。 你可以使用
kubeadm token
命令来查看、创建和删除这类令牌。
4.2、安装 Pod 网络附加组件
关于 Kubernetes 网络,建议读完这篇 文章,以及文末的其他链接,如这个。
集群必须安装Pod网络插件,以使Pod可以相互通信,只需要在Master节点操作,其他新加入的节点会自动创建相关pod。
必须在任何应用程序之前部署网络组件。另外,在安装网络之前,CoreDNS将不会启动(你可以通过命令 kubectl get pods --all-namespaces|grep coredns
查看 CoreDNS 的状态)。
# 查看 CoreDNS 的状态,并不是 Running 状态
$ kubectl get pods --all-namespaces|grep coredns
kube-system coredns-7f9c544f75-bzksd 0/1 Pending 0 14m
kube-system coredns-7f9c544f75-mtrwq 0/1 Pending 0 14m
kubeadm 支持多种网络插件,我们选择 Calico 网络插件(kubeadm 仅支持基于容器网络接口(CNI)的网络(不支持kubenet)。),默认情况下,它给出的pod的IP段地址是 192.168.0.0/16
,如果你的机器已经使用了此IP段,就需要修改这个配置项,将其值改为在初始化 Master 节点时使用 kubeadm init --pod-network-cidr=x.x.x.x/x
的IP地址段,即我们上面配置的 10.10.0.0/16
,大概在625行左右,操作如下:
# 获取配置文件
mkdir calico && cd calico
wget https://docs.projectcalico.org/v3.8/manifests/calico.yaml
1. 修改配置文件
1. 找到 625 行左右的 192.168.0.0/16 ,并修改为我们初始化时配置的 10.10.0.0/16
vim calico.yaml
1. 部署 Pod 网络组件
kubectl apply -f calico.yaml
稍等片刻查询 pod 详情,你也可以使用 watch
命令来实时查看 pod 的状态,等待 Pod 网络组件部署成功后,就可以看到一些信息了,包括 Pod 的 IP 地址信息,这个过程时间可能会有点长。
watch -n 2 kubectl get pods --all-namespaces -o wide
4.3、将 Worker 节点添加到 Kubernetes
请首先确认 Worker 节点满足第一部分的环境说明,并且已经安装了 Docker 和 kubeadm、kubelet 、kubectl,并且已经启动 kubelet。
# 添加 Hosts 解析
echo "127.0.0.1 $(hostname)" >> /etc/hosts
export MASTER_IP=192.168.115.49
export APISERVER_NAME=kuber4s.api
echo "${MASTER_IP} ${APISERVER_NAME}" >> /etc/hosts
将 Worker 节点添加到集群,这里注意,执行后可能会报错,有幸的话你会跳进这个坑,这是因为 Worker 节点加入集群的命令实际上在初始化 master 时已经有提示出来了,不过两小时后会删除上传的证书,所以如果你此时加入集群的时候提示证书相关的错误,请执行 kubeadm init phase upload-certs --upload-certs
重新加载证书。
kubeadm join kuber4s.api:6443 --token 0y1dj2.ih27ainxwyib0911
--discovery-token-ca-cert-hash sha256:5204b3e358a0d568e147908cba8036bdb63e604d4f4c1c3730398f33144fac61
执行加入操作,你可能会发现卡着不动,大概率是因为令牌ID对此集群无效或已过 2 小时的有效期(通过执行 kubeadm join --v=5
来获取详细的加入过程,看到了内容为 ”token id "0y1dj2" is invalid for this cluster or it has expired“ 的提示),接下来需要在 Master 上通过 kubeadm token create
来创建新的令牌。
$ kubeadm token create --print-join-command
W0129 19:10:04.842735 15533 validation.go:28] Cannot validate kube-proxy config - no validator is available
W0129 19:10:04.842808 15533 validation.go:28] Cannot validate kubelet config - no validator is available
1. 输出结果如下
kubeadm join kuber4s.api:6443 --token 1hk9bc.oz7f3lmtbzf15x9b --discovery-token-ca-cert-hash sha256:5e8bcad5ec97c1025e8044f4b8fd0a4514ecda4bac2b3944f7f39ccae9e4921f
在 Worker 节点上重新执行加入集群命令
kubeadm join kuber4s.api:6443
--token 1hk9bc.oz7f3lmtbzf15x9b
--discovery-token-ca-cert-hash sha256:5e8bcad5ec97c1025e8044f4b8fd0a4514ecda4bac2b3944f7f39ccae9e4921f
接下来在Master上查看 Worker 节点加入的状况,直到 Worker 节点的状态变为 Ready 便证明加入成功,这个过程可能会有点漫长,30 分钟以内都算正常的,主要看你网络的情况或者说拉取镜像的速度;另外不要一看到 /var/log/messages
里面报错就慌了,那也得看具体报什么错,看不懂就稍微等一下,一般在 Master 上能看到已经加入(虽然没有Ready)就没什么问题。
watch kubectl get nodes -o wide
4.4、添加 Master 节点
需要至少2个CPU核心,否则会报错
kubeadm join kuber4s.api:6443
--token 1hk9bc.oz7f3lmtbzf15x9b
--discovery-token-ca-cert-hash sha256:5e8bcad5ec97c1025e8044f4b8fd0a4514ecda4bac2b3944f7f39ccae9e4921f
--control-plane --certificate-key 5253fc7e9a4e6204d0683ed2d60db336b3ff64ddad30ba59b4c0bf40d8ccadcd
4.5、补充内容
- kubeadm init 初始化 Kubernetes 主节点
- kubeadm token 管理
kubeadm join
的令牌 - kubeadm reset 将
kubeadm init
或kubeadm join
对主机的更改恢复到之前状态,一般与-f
参数使用
移除 worker 节点
正常情况下,你无需移除 worker 节点,如果要移除,在准备移除的 worker 节点上执行
kubeadm reset -f
或者在 Control-plane 上执行
kubectl delete node nodename
- 将 nodename 替换为要移除的 worker 节点的名字
- worker 节点的名字可以通过在 Control-plane 上执行 kubectl get nodes 命令获得
五、Kubernetes 高可用集群
5.1、环境说明
如果你使用的是以上方法部署你的 Kubernetes 集群,想在当前基础上进行高可用集群的创建,则可以按照下面的步骤继续进行。
值得注意的是,这里没有将ETCD放在Master外的机器上,而是使用默认的架构,即官方的 Stacked etcd topology 方式的集群
你需要至少 3 台 Master 节点和 3 台 Worker 节点,或者更多的机器,但要保证是 Master 和 Worker 节点数都是奇数的,以防止 leader 选举时出现脑裂状况。
机器名称 | 机器IP | 工作内容 |
---|---|---|
master01 | 192.168.115.49 | master、etcd |
master02 | 192.168.115.41 | master、etcd |
master03 | 192.168.115.42 | master、etcd |
node01 | 192.168.115.46 | worker |
node02 | 192.168.115.47 | worker |
node03 | 192.168.115.48 | worker |
nfs | 192.168.115.50 | 存储 |
5.2、高可用扩展
Kubernetes 的高可用扩展其实挺简单,你只需要将不同的 Master 和 Worker 节点加入到集群中就行了。加入的指令在你初始化集群时已经给出了。
- 添加 Master 节点:
需要至少 2 个 CPU 核心,否则会报错
kubeadm join kuber4s.api:6443
--token 1hk9bc.oz7f3lmtbzf15x9b
--discovery-token-ca-cert-hash sha256:5e8bcad5ec97c1025e8044f4b8fd0a4514ecda4bac2b3944f7f39ccae9e4921f
--control-plane --certificate-key 5253fc7e9a4e6204d0683ed2d60db336b3ff64ddad30ba59b4c0bf40d8ccadcd
- 添加 Worker 节点
在 Worker 节点上重新执行加入集群命令
kubeadm join kuber4s.api:6443
--token 1hk9bc.oz7f3lmtbzf15x9b
--discovery-token-ca-cert-hash sha256:5e8bcad5ec97c1025e8044f4b8fd0a4514ecda4bac2b3944f7f39ccae9e4921f