目标是方便快捷地部署一个比较稳定的 k8s 集群
前言
前面用到过的 minikube 只是一个单节点的 k8s 集群,这对于学习而言是不够的。我们需要有一个多节点集群,才能用到各种调度/监控功能。而且单节点只能是一个加引号的“集群”。
kubernetes 安装方式面面观
kubernetes 是一个组件化的系统,安装过程有很大的灵活性,很多组件都有多种实现,这些实现各有特点,让初学者眼花缭乱。
而且要把这些组件一个个安装配置好并且能协同工作,也是很不容易的。
因此社区出现了各种各样的安装方案。安装方案如此之多,以致于我不晓得该用哪个好。。于是特地调查了一番。将几个流行的安装方案罗列如下:
- kops: 只支持 aws/gce,另外 openstack/vsphere 的支持正处于 beta 状态。不支持裸机部署。
- kubeadm: k8s 官方推出的一个 k8s 快速安装工具,但是仍然有一定的工作量。
- kubespray: k8s 社区项目,使用 ansible 部署可用于生产环境的 k8s。(k8s-sigs,即 k8s special interest group)
- KubeOperator: 提供 UI 界面的部署工具及集群运维系统(底层用的是 ansible)。对 vshpere 的支持比较好,通过 vCenter 可以动态地伸缩 worker 节点。
- kubeasz: 和 kubespray 一样,都是使用 ansible 进行部署。不过是纯中文的,而且是分步部署。还添加了几个方便的运维功能。
- sealos: 一行命令部署 k8s 集群,支持离线安装。
- 国人开发的项目,使用方式非常简单。只是它的离线安装包是收费的,各版本价格从 0.01-50 元不等。。(代码开源,因此离线包应该可以自己制作。)
- rke/rancher: 完全使用容器运行 k8s 自身,配置文件简单,一行命令部署集群(国内会自动从阿里云拉镜像)。另外中文文档非常详细。
- rke 评价:现在在开发环境用了半年 rke 了,体验上讲,安装是相当方便。但是它也存在几个比较明显的问题:
rke up
经常会健康检查失败,需要跑两三次才能成功。- 对修改集群有点语焉不详,找了半天文档才知道修改集群就是改 cluster.yaml 然后重新跑
rke up
。 - 将 cni 插件从 canal 切换到 calico/flannel 后重新
rke up
,集群网络直接就炸了。rke remove
再rke up
都没用(清理不干净)。也没看到哪里有讲网络插件不能更换。 - 我们有一部分机器晚上会关机,有时候第二天开机后,nginx_proxy 就挂了,导致节点无法访问 apiserver 而下线。。
- Rancher 评价:用了一段时间了,文档我觉得是非常详细,很受用。但是 rancher 本身感觉不怎么稳定,经常莫名其妙地报错、卡顿。。也不知道是不是我配置不对。。
- rke 评价:现在在开发环境用了半年 rke 了,体验上讲,安装是相当方便。但是它也存在几个比较明显的问题:
此外社区还有 n 种方案可供选择,五花八门。而且关注度(stars)都不低。贪多嚼不烂,我就不一一介绍了。
分一下类的话,按规模分有两类:
- 单节点集群:主要用于开发测试.
- minikube/microk8s
- 多节点集群:可用于生产。
- kubespray/kops/rke 等等。
按安装速度分类的话,首先支持离线安装的单节点集群肯定是最快的,有
- kubeadm: 自己编写脚本,先 load 所有镜像或从内网仓库拉取镜像,然后通过 kubeadm 进行离线安装。
其次是支持离线安装的多节点集群,有
- rke: 需要提前使用批量推送脚本将镜像推送到内网镜像仓库中。
一番搜索,我最终确定了用 rancher 来部署我的第一个 kubernetes 多节点集群(后来发现其实 rke 方便),怎么简单怎么来哈哈~
除了多节点集群,我们每个开发人员还需要一台个人测试用的机器。目前公司的这些测试用的是单节点集群,为了快速部署,这些单节点集群都是通过离线安装包(或内网镜像仓库)、以容器方式部署的。
一、准备虚拟机
要部署多节点嘛,自然得先有多台主机。我自己的机器内存够用,就直接开了一台 Ubuntu 虚拟机,然后克隆了四份。(这个克隆操作导致我后面掉进了坑。。)
主机的操作系统可以用自己熟悉的 Ubuntu/Debian/CentOS 等。这里主要强调一个坑:
- **各主机的 hostname 不能相同!!!**否则后续的节点永远部署不上!第一次手动安装节点很容易被这个问题卡住。(血泪教训。。)
- 因为我节点的虚拟机都是克隆 rancher-server 节点的,它们的 hostname 全都一样,搞了好久才找到问题原因。
- Ubuntu Server 18.04 无法修改 hostname
如果是使用 rke/kubespray 进行批量安装,可以直接在配置文件里指定节点 hostname,这俩工具会帮你自动修改。
具体的主机配置过程官方文档写得非常详细,请移步 Rancher-基础环境配置
二、使用 rancher 部署 k8s 集群
1. 部署 rancher server
首先在用做 rancher server 的虚拟机上跑官方给出的 docker 命令启动 rancher server:
sudo docker run -d -v <主机路径>:/var/lib/rancher/ --restart=unless-stopped -p 80:80 -p 443:443 rancher/rancher:stable
不过说实话我觉得用 docker-compose 的方式会更好一点。
部署好后访问 https://<server-ip>
配置好账号/密码/url,这没啥好说的。
注意事项
- 以 docker 方式部署 rancher,显然是存在单点故障的。生产环境建议查看官方文档的 HA 部署。
- 使用 rancher 部署好的集群,如果你使用 rancher 生成的 kubeconfig 的话,rancher 挂了你就无法使用 kubectl 了。
- 所以rancher 一定要做好备份,或者在部署时启用「授权集群访问地址」,否则 rancher 出了问题就jj了。
2. 部署 kubernetes 集群
现在进入了 rancher 首页,点击右上角的「添加集群」,选择「自定义」来添加本地集群。
当然如果你用的是云服务,那直接使用 rancher 提供的对应的功能显然更方便。(在导航栏「工具」-「驱动管理」中可以添加「阿里云」「腾讯云」「华为云」等国内云服务支持)
然后输入「集群名称」,「云提供商」选择「无」。
然后就是最后一步——在各个节点上部署 rancher agent——了。
只要你勾选了 worker
选项(其实就是添加了 --worker
参数),rancher agent 在运行时,就会自动在节点上部署 k8s
节点所需要的所有容器。
在多个节点上运行带 --worker
的 rancher agnet 命令,就能得到多个 k8s worker。而 etcd 和 controller 开发环境各部署一个就好了。
然后就可以愉快地玩耍了hhh~
3. 离线部署 k8s 集群
要使用 rancher 离线部署,首先需要一个 docker 私有镜像仓库,推荐使用 harbor.
虽然也可以使用官方的 rancher_save_images.sh 把所有镜像打包成 tar.gz 进行离线安装,但是这并没有使用私有仓库的方式灵活简便。(前提是你本来就已经有一个内网私有仓库。。)
然后参照上一步 2. 部署 kubernetes 集群
就行。
三、使用 kubespray 部署本地 k8s 集群
今天尝试了一下使用 kubespray 部署一个本地 k8s 集群,总的来说,坑,还是 rancher 最方便。。
使用 kubespary 部署,难点有二:
- 国内网络问题,gcr.io 和 quay.io 的镜像都无法拉取,github 的 release 下载也特别慢。
- 镜像可以使用 azure 的镜像源:
- 把
gcr.io
全都替换成gcr.azk8s.cn
- 把
quay.io
全都替换成quay.azk8s.cn
- 而 dockerhub 官方镜像,可以换成
dockerhub.azk8s.cn
- 把
- 但是 github 就没办法了
- 镜像可以使用 azure 的镜像源:
- ansible 的配置问题。我节点用的 ubuntu server 1804,第一次用 ansible,遇到好多问题:
- 用 kubespray 的 requirements.txt 安装 ansible,运行 ansible 命令时提示找不到
/usr/bin/python
,升级到最新版本才能识别到/usr/bin/python3
- 然后又提示需要将节点的指纹加入 know_hosts,我一直输入 yes 都没用。。全部手动用 ssh 登录了一次才好。(回退 ansible 的版本也没用。)
- 启用了 download_run_once 之后,ansible 把下载下来的数据用 rsync 传到别的节点时老是报错,要我将指纹加入 know_hosts(输入 yes)。只好关掉。(回退 ansible 的版本也没用。)
- 现在终于正常了,但是有几个工具的下载链接是 github release 的,慢到吐血。我只好手动下载下来,再手动分发到所有节点上。。
- 用 kubespray 的 requirements.txt 安装 ansible,运行 ansible 命令时提示找不到
趟完了上面说的坑之后,终于把 kubernetes 安装上了。安装体验上来说比 rancher 差多了。不过这也可能和我想尝鲜 k8s 1.16,所以使用了 master 分支有关。。
优势: 1. 节点只要有 python 就行,好像连 docker 都可以交给 kubespray 安装(只要你能忍受它的速度。。) 1. 会自动配置节点的 hostname,不需要手动一台台地改了。
然后装完后我才晓得,原来 kubeconfig 是需要手动生成的。。之前用 rancher 时它直接就给生成好了,我以为这是自动的来着。。
四、使用 rke(rancher kubernetes engine)离线部署 k8s 集群
前面使用 rancher 部署了一个 k8s 集群,但是那种方式不适合内网环境,因为它所有的镜像都还是会从外网拉取,遇到出口带宽被限速,或者与公网物理隔离的情况下,就无能为力了。(rancher 的 UI 界面也可以设置私有仓库)
因此我改用 rke 进行部署,这种方式自定义程度更高,而且支持配置私有 docker 仓库,通过 ssh 批量部署。其实用法和 kubespray 有点像,但是比 kubespray 简单多了。(kuberspray 的配置文件实在太多了。。)
经过使用我发现,rke 才是最简单方便的 kubernetes 部署方式。流程如下:
- OS 还是使用 ubuntu1804,ssh 账号使用 root(测试环境,方便)
- 注:CentOS/RedHat 不能使用 root 账号进行操作。
- 其他系统配置参见 rke - 系统需求
- 使用
ssh-keygen
创建密钥对,通过ssh-copy-id
将公钥传到各节点上。 - 下载 rke,和 kubectl 一样是个单一可执行文件。
- 下载好后将它重命名为
rke
,放到 PATH 路径下(比如/usr/local/bin
)。
- 下载好后将它重命名为
- 创建配置文件:cluster.yml
- 修改 cluster.yml,配置好所有的节点与对应的角色。
- 节点可以指定一个
hostname_override
,覆盖掉原有的 hostname,这非常方便。
- 节点可以指定一个
- cluster.yml 还有非常多的其他参数,作为新手大部分我们都不要去改,但是有几个重点需要注意
- private_registries: 配置私有仓库。提前将 rancher 的镜像离线到本地仓库(如 harbor),可以大大加快部署速度。
- kubernetes_version: k8s 版本号,可通过
rke config --list-version --all
查看所有支持的版本号。 - service.kube_api: apiserver 相关的配置,其中 service_node_port_range 限定了 node_port 的端口范围。
- service.kube_controller/kubelet/kube_proxy: 调整 k8s 的其他各项参数。。
- authorization.mode: 测试环境可以改成 none,方便后面使用 dashboard
- network.plugin: 设置网络插件,各插件的差别待了解
- ingress.provider: rke 部署的这个 ingress 我弄了半天都没弄好,最后把这个改成 none,然后手动用
kubectl
部署官方的 ingress-controller 才正常。。 - dns: 域名解析嘛,默认的 coredns 就行,上游 dns 可以设 114.114.114.114
- addons_include: 导入其他插件,最常见的有(详细的部署方式下面会写):
- dashboard
- nginx-ingress-controller
- 使用
rke up
命令部署 k8s
在 k8s 集群上部署 dashboard 和 nginx-ingress-controller
1. 部署 dashboard
部署 dashboard 存在两个问题
- 官方提供的镜像地址
k8s.gcr.io/kubernetes-dashboard-amd64:v1.10.1
被墙。 - dashboard 默认创建的 serviceaccount
kubernetes-dashboard
权限相当小,啥都看不了。
解决办法,首先下载官方的 yaml 文件,做如下修改:
- Deployment 使用 azure 镜像源:
gcr.azk8s.cn/google_containers/kubernetes-dashboard-amd64:v1.10.1
- 修改
RoleBinding
那一部分的 yaml 配置,将服务账号kubernetes-dashboard
绑定到管理员角色cluster-admin
上。详见官方文档:https://github.com/kubernetes/dashboard/blob/master/docs/user/access-control/creating-sample-user.md#create-clusterrolebinding
然后再 kubectl create
访问 dashboard
dashboard 不怎么好用,只适合粗略查看。更建议使用 k9s
- 在本机使用
kubectl proxy
提供一个访问集群内部 service 的入口 - 通过
http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/
进入 dashboard 的 ui 界面 - 如果在前面的集群创建时,你将
authorization.mode
设为了 none,那应该会有个skip
的按钮,点击就能进入 dashboard 了。 - 否则你大概需要参照 使用 token 登录。
2. 本地部署 nginx-ingress-controller
建议用 traefik 替换掉它
参照 NGINX Ingress Controller - 安装指南
Prerequisite Generic Deployment Command
:kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml
- 使用 nodePort 导出 ingress 端口:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/baremetal/service-nodeport.yaml
- 这个官方提供的 yaml 没有指定
nodePort
,会导致最后导出的 nodePort 是随机分配的。。 - 可以手动指定成 80 和 443,或者如果端口被占用,也可以改成 8080 和 8443
- 这个官方提供的 yaml 没有指定
然后就可以使用 ingress 啦。