本文将从零开始,在干净的机器上安装 Docker、Kubernetes (使用 kubeadm)、Calico、Helm、NFS StorageClass,通过手把手的教程演示如何搭建一个高可用生产级的 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 # 关闭 SeLinux setenforce 0 sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config # 关闭 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 # 备份 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup # 获取阿里云yum源 wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo # 获取阿里云epel源 wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo # 清理缓存并创建新的缓存 yum clean all && yum makecache # 系统更新 yum update -y
进行时间同步,并确认时间同步成功
timedatectl timedatectl set-ntp true
⚠️⚠️⚠️以下操作请严格按照声明的版本进行部署,否则将碰到乱七八糟的问题
二、安装 Docker
2.1、安装 Docker
您需要在每台机器上安装 Docker,我这里安装的是 docker-ce-19.03.4
# 安装 Docker CE # 设置仓库 # 安装所需包 yum install -y yum-utils device-mapper-persistent-data lvm2 # 新增 Docker 仓库,速度慢的可以换阿里云的源。 yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo # 阿里云源地址 # http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # 安装 Docker CE. yum install -y containerd.io-1.2.10 docker-ce-19.03.4 docker-ce-cli-19.03.4 # 启动 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
将 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 # 输出结果如下 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
六、安装 KubeSphere
6.1、KubeSphere简介
Kubernetes 官方有提供一套 Dashboard,但是我这里选择功能更强大的 KubeSphere,以下内容引用自 KubeSphere 官网:
KubeSphere 是在 Kubernetes 之上构建的以应用为中心的容器平台,提供简单易用的操作界面以及向导式操作方式,在降低用户使用容器调度平台学习成本的同时,极大减轻开发、测试、运维的日常工作的复杂度,旨在解决 Kubernetes 本身存在的存储、网络、安全和易用性等痛点。除此之外,平台已经整合并优化了多个适用于容器场景的功能模块,以完整的解决方案帮助企业轻松应对敏捷开发与自动化运维、DevOps、微服务治理、灰度发布、多租户管理、工作负载和集群管理、监控告警、日志查询与收集、服务与网络、应用商店、镜像构建与镜像仓库管理和存储管理等多种场景。后续版本将提供和支持多集群管理、大数据、AI 等场景。
6.2、安装要求
KubeSphere 支持直接在 Linux 上部署集群,也支持在 Kubernetes 上部署,我这里选择后者,基本的要求如下:
- Kubernetes 版本:1.15.x ≤ K8s version ≤ 1.17.x;
- Helm 版本:2.10.0 ≤ Helm Version < 3.0.0(不支持 helm 2.16.0#6894),且已安装了 Tiller,参考 如何安装与配置 Helm(预计 3.0 支持 Helm v3);
- 集群已有默认的存储类型(StorageClass),若还没有准备存储请参考安装 OpenEBS 创建 LocalPV 存储类型用作开发测试环境。
- 集群能够访问外网,若无外网请参考 在 Kubernetes 离线安装 KubeSphere。
6.3、安装 Helm
6.3.1、Helm 简介
Helm 基本思想如图所示
以下内容引用自 此篇文章
Helm 基本概念
Helm 可以理解为 Kubernetes 的包管理工具,可以方便地发现、共享和使用为Kubernetes构建的应用,它包含几个基本概念:
- Chart:一个 Helm 包,其中包含了运行一个应用所需要的镜像、依赖和资源定义等,还可能包含 Kubernetes 集群中的服务定义
- Release: 在 Kubernetes 集群上运行的 Chart 的一个实例。在同一个集群上,一个 Chart 可以安装很多次。每次安装都会创建一个新的 release。例如一个 MySQL Chart,如果想在服务器上运行两个数据库,就可以把这个 Chart 安装两次。每次安装都会生成自己的 Release,会有自己的 Release 名称。
- Repository:用于发布和存储 Chart 的仓库。
6.3.2、Helm安装
安装过程如下
# 创建部署目录并下载Helm mkdir tiller cd tiller # 先使用官方的方式安装,如果安装不了,可以看到下载文件的地址,然后手动下载解压 curl -L https://git.io/get_helm.sh | bash # 获取到下载地址后,想办法下载 wget https://get.helm.sh/helm-v2.16.3-linux-amd64.tar.gz tar zxf helm-v2.16.3-linux-amd64.tar.gz mv linux-amd64/helm /usr/local/bin/helm # 验证 helm version
部署 Tiller,即 Helm 的服务端。先创建 SA
# yaml文件如下 $ cat /root/tiller/helm-rbac.yaml apiVersion: v1 kind: ServiceAccount metadata: name: tiller namespace: kube-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: tiller roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: tiller namespace: kube-system
创建 RBAC:
kubectl apply -f helm-rbac.yaml
初始化,这个过程可能不会成功,具体接着往下看
helm init --service-account=tiller --history-max 300
检查初始化的情况,不出意外的话,墙内用户看pod详情可以看到获取不到镜像的错误。
kubectl get deployment tiller-deploy -n kube-system
如果一直获取不到镜像,可以通过更换到Azure中国镜像源来解决,操作步骤如下:
# 编辑 deploy kubectl edit deploy tiller-deploy -n kube-system # 查找到image地址,替换为如下地址,保存退出 gcr.azk8s.cn/kubernetes-helm/tiller:v2.16.3
接下来稍等片刻,再次查看deployment和pod详情,就正常了
kubectl get deployment tiller-deploy -n kube-system
6.4、安装 StorageClass
Kubernetes 支持多种 StorageClass,我这选择 NFS 作为集群的 StorageClass。
参考地址:https://github.com/kubernetes-incubator/external-storage/tree/master/nfs-client
6.4.1、下载所需文件
下载所需文件,并进行内容调整
mkdir nfsvolume && cd nfsvolume for file in class.yaml deployment.yaml rbac.yaml ; do wget https://raw.githubusercontent.com/kubernetes-incubator/external-storage/master/nfs-client/deploy/$file ; done
修改 deployment.yaml 中的两处 NFS 服务器 IP 和目录
... env: - name: PROVISIONER_NAME value: fuseim.pri/ifs - name: NFS_SERVER value: 192.168.115.50 - name: NFS_PATH value: /data/k8s volumes: - name: nfs-client-root nfs: server: 192.168.115.50 path: /data/k8s
6.4.2、部署创建
具体的说明可以去官网查看。
kubectl create -f rbac.yaml kubectl create -f class.yaml kubectl create -f deployment.yaml
如果日志中看到“上有坏超级块”,请在集群内所有机器上安装nfs-utils并启动。
yum -y install nfs-utils systemctl start nfs-utils systemctl enable nfs-utils rpcinfo -p
查看storageclass
$ kubectl get storageclass NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE managed-nfs-storage fuseim.pri/ifs Delete Immediate false 10m
6.4.3、标记一个默认的 StorageClass
操作命令格式如下
kubectl patch storageclass -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
请注意,最多只能有一个 StorageClass 能够被标记为默认。
验证标记是否成功
$ kubectl get storageclass NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE managed-nfs-storage (default) fuseim.pri/ifs Delete Immediate false 12m
6.5、部署 KubeSphere
过程很简单,如果你的机器资源足够,建议你进行完整安装,操作步骤如下。如果你的资源不是很充足,则可以进行最小化安装,参考地址。我当然是选择完整安装了,香!
# 下载 yaml 文件 mkdir kubesphere && cd kubesphere wget https://raw.githubusercontent.com/kubesphere/ks-installer/master/kubesphere-complete-setup.yaml # 部署 KubeSphere kubectl apply -f kubesphere-complete-setup.yaml
这个过程根据你实际网速,实际使用时间长度有所不同。你可以通过如下命令查看实时的日志输出。
kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l app=ks-install -o jsonpath='{.items[0].metadata.name}') -f
当你看到如下日志输出,证明你的 KubeSphere 部署成功
************************************************** task monitoring status is successful task notification status is successful task devops status is successful task alerting status is successful task logging status is successful task openpitrix status is successful task servicemesh status is successful total: 7 completed:7 ************************************************** ##################################################### ### Welcome to KubeSphere! ### ##################################################### Console: http://192.168.115.49:30880 Account: admin Password: P@88w0rd #####################################################
确认 Pod 都正常运行后,可使用IP:30880访问 KubeSphere UI 界面,默认的集群管理员账号为admin/P@88w0rd,Enjoy it,😏!