前言

前面用到过的 minikube 只是一个单节点的 k8s 集群,这对于学习而言是不够的。我们需要有一个多节点集群,才能用到各种调度/监控功能。而且单节点只能是一个加引号的“集群”。

kubernetes 安装方式面面观

kubernetes 是一个组件化的系统,安装过程有很大的灵活性,很多组件都有多种实现,这些实现各有特点,让初学者眼花缭乱。

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

而且要把这些组件一个个安装配置好并且能协同工作,也是很不容易的。

因此社区出现了各种各样的安装方案。安装方案如此之多,以致于我不晓得该用哪个好。。于是特地调查了一番。将几个流行的安装方案罗列如下:

  1. minikube/microk8s: 单节点集群,只适合学习/开发使用
  2. kubeadm: k8s 官方推出的一个 k8s 快速安装工具,但是仍然有一定的工作量。
  3. kubespray: k8s 社区项目,使用 ansible 部署可用于生产环境的 k8s。(k8s-sigs,即 k8s special interest group)
  4. kubeasz: 和 kubespray 一样,都是使用 ansible 进行部署。不过是纯中文的,而且是分步部署。还添加了几个方便的运维功能。
  5. rancher: k8s 之上的企业级管理系统,安装相当方便(国内会自动从阿里云拉镜像),中文文档相当详细,而且还提供了更高层次的管理功能。

此外社区还有 n 种方案可供选择,五花八门。而且关注度(stars)都不低。贪多嚼不烂,我就不一一介绍了。

一番搜索,我最终确定了用 rancher 来部署我的第一个 kubernetes 多节点集群(后来发现其实 rke 更适合我的使用场景),怎么简单怎么来哈哈~

除了多节点集群,我们每个开发人员还需要一台个人测试用的机器。目前公司的这些测试用的是单节点集群,为了快速部署,这些单节点集群都是通过离线安装包(或内网镜像仓库)、以容器方式部署的。

一、准备虚拟机

要部署多节点嘛,自然得先有多台主机。我自己的机器内存够用,就直接开了一台 Ubuntu 虚拟机,然后克隆了四份。(这个克隆操作导致我后面掉进了坑。。)

主机的操作系统可以用自己熟悉的 Ubuntu/Debian/CentOS 等。这里主要强调一个坑:

  1. 各主机的 hostname 不能相同!!!否则后续的节点永远部署不上!第一次手动安装节点很容易被这个问题卡住。(血泪教训。。)

如果是使用 rke/kubespray 进行批量安装,可以直接在配置文件里指定节点 hostname,这俩工具会帮你自动修改。

具体的主机配置过程官方文档写得非常详细,请移步 Rancher-基础环境配置

二、部署 rancher

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,这没啥好说的。

注意事项

  1. 以 docker 方式部署 rancher,显然是存在单点故障的。生产环境建议查看官方文档的 HA 部署。
  2. 使用 rancher 部署好的集群,如果你使用 rancher 生成的 kubeconfig 的话,rancher 挂了你就无法使用 kubectl 了。
    • 所以rancher 一定要做好备份,或者在部署时启用「授权集群访问地址」,否则 rancher 出了问题就jj了。

2. 部署 kubernetes 集群

现在进入了 rancher 首页,点击右上角的「添加集群」,选择「自定义」来添加本地集群。

当然如果你用的是云服务,那直接使用 rancher 提供的对应的功能显然更方便。(在导航栏「工具」-「驱动管理」中可以添加「阿里云」「腾讯云」「华为云」等国内云服务支持)

然后输入「集群名称」,「云提供商」选择「无」。

然后就是最后一步——在各个节点上部署 rancher agent——了。
 Kubernetes 学习笔记(二):本地部署一个 kubernetes 集群 Cloud

只要你勾选了 worker 选项(其实就是添加了 --worker 参数),rancher agent 在运行时,就会自动在节点上部署 k8s 节点所需要的所有容器。

在多个节点上运行带 --worker 的 rancher agnet 命令,就能得到多个 k8s worker。而 etcd 和 controller 开发环境各部署一个就好了。

然后就可以愉快地玩耍了hhh~

3. 离线部署 k8s 集群

要使用 rancher 离线部署,首先需要一个 docker 私有镜像仓库,推荐使用 harbor.

虽然也可以使用官方的 rancher_save_images.sh 把所有镜像打包成 tar.gz 进行离线安装,但是这并没有使用私有仓库的方式灵活简便。(前提是你本来就已经有一个内网私有仓库。。)

  1. 参照 准备离线镜像 的脚本,使用 image-list.txt 拉取镜像到本地,然后批量上传到私有仓库
  2. 参照 修改镜像仓库地址,让 rancher 从内网仓库拉取系统镜像。

然后参照上一步 2. 部署 kubernetes 集群 就行。

更新

三、使用 kubespray 部署本地 k8s 集群

今天尝试了一下使用 kubespray 部署一个本地 k8s 集群,总的来说,坑,还是 rancher 最方便。。

使用 kubespary 部署,难点有二:

  1. 国内网络问题,gcr.io 和 quay.io 的镜像都无法拉取,github 的 release 下载也特别慢。
    • 镜像可以使用 azure 的镜像源:
      • gcr.io 全都替换成 gcr.azk8s.cn
      • quay.io 全都替换成 quay.azk8s.cn
      • 而 dockerhub 官方镜像,可以换成 dockerhub.azk8s.cn
    • 但是 github 就没办法了
  2. ansible 的配置问题。我节点用的 ubuntu server 1804,第一次用 ansible,遇到好多问题:
    1. 用 kubespray 的 requirements.txt 安装 ansible,运行 ansible 命令时提示找不到 /usr/bin/python,升级到最新版本才能识别到 /usr/bin/python3
    2. 然后又提示需要将节点的指纹加入 know_hosts,我一直输入 yes 都没用。。全部手动用 ssh 登录了一次才好。(回退 ansible 的版本也没用。)
    3. 启用了 download_run_once 之后,ansible 把下载下来的数据用 rsync 传到别的节点时老是报错,要我将指纹加入 know_hosts(输入 yes)。只好关掉。(回退 ansible 的版本也没用。)
    4. 现在终于正常了,但是有几个工具的下载链接是 github release 的,慢到吐血。我只好手动下载下来,再手动分发到所有节点上。。

趟完了上面说的坑之后,终于把 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 部署方式。流程如下:

  1. OS 还是使用 ubuntu1804,ssh 账号使用 root(测试环境,方便)
    • 注:CentOS/RedHat 不能使用 root 账号进行操作。
    • 其他系统配置参见 rke - 系统需求
  2. 使用 ssh-keygen 创建密钥对,通过 ssh-copy-id 将公钥传到各节点上。
  3. 下载 rke,和 kubectl 一样是个单一可执行文件。
    • 下载好后将它重命名为 rke,放到 PATH 路径下(比如 /usr/local/bin)。
  4. 创建配置文件:cluster.yml
  5. 修改 cluster.yml,配置好所有的节点与对应的角色。
    • 节点可以指定一个 hostname_override,覆盖掉原有的 hostname,这非常方便。
  6. cluster.yml 还有非常多的其他参数,作为新手大部分我们都不要去改,但是有几个重点需要注意
    1. private_registries: 配置私有仓库。提前将 rancher 的镜像离线到本地仓库(如 harbor),可以大大加快部署速度。
    2. kubernetes_version: k8s 版本号,可通过 rke config --list-version --all 查看所有支持的版本号。
    3. service.kube_api: apiserver 相关的配置,其中 service_node_port_range 限定了 node_port 的端口范围。
    4. service.kube_controller/kubelet/kube_proxy: 调整 k8s 的其他各项参数。。
    5. authorization.mode: 测试环境可以改成 none,方便后面使用 dashboard
    6. network.plugin: 设置网络插件,各插件的差别待了解
    7. ingress.provider: rke 部署的这个 ingress 我弄了半天都没弄好,最后把这个改成 none,然后手动用 kubectl 部署官方的 ingress-controller 才正常。。
    8. dns: 域名解析嘛,默认的 coredns 就行,上游 dns 可以设 114.114.114.114
    9. addons_include: 导入其他插件,最常见的有(详细的部署方式下面会写):
      • dashboard
      • nginx-ingress-controller

在 k8s 集群上部署 dashboard 和 nginx-ingress-controller

1. 部署 dashboard

部署 dashboard 存在两个问题

  1. 官方提供的镜像地址 k8s.gcr.io/kubernetes-dashboard-amd64:v1.10.1 被墙。
  2. dashboard 默认创建的 serviceaccount kubernetes-dashboard 权限相当小,啥都看不了。

解决办法,首先下载官方的 yaml 文件,做如下修改:

  1. Deployment 使用 azure 镜像源:gcr.azk8s.cn/google_containers/kubernetes-dashboard-amd64:v1.10.1
  2. 修改 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

  1. 在本机使用 kubectl proxy 提供一个访问集群内部 service 的入口
  2. 通过 http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/ 进入 dashboard 的 ui 界面
  3. 如果在前面的集群创建时,你将 authorization.mode 设为了 none,那应该会有个 skip 的按钮,点击就能进入 dashboard 了。
  4. 否则你大概需要参照 使用 token 登录,使用 token 登录。

2. 本地部署 nginx-ingress-controller

参照 NGINX Ingress Controller - 安装指南

  1. Prerequisite Generic Deployment Command: kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml
  2. 使用 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

然后就可以使用 ingress 啦。

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄