Kubernetes 学习笔记(二):本地部署一个 kubernetes 集群

Stella981
• 阅读 608

目标是方便快捷地部署一个比较稳定的 k8s 集群

前言

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

kubernetes 安装方式面面观

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

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

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

  1. kops: 只支持 aws/gce,另外 openstack/vsphere 的支持正处于 beta 状态。不支持裸机部署。
  2. kubeadm: k8s 官方推出的一个 k8s 快速安装工具,但是仍然有一定的工作量。
  3. kubespray: k8s 社区项目,使用 ansible 部署可用于生产环境的 k8s。(k8s-sigs,即 k8s special interest group)
  4. KubeOperator: 提供 UI 界面的部署工具及集群运维系统(底层用的是 ansible)。对 vshpere 的支持比较好,通过 vCenter 可以动态地伸缩 worker 节点。
  5. kubeasz: 和 kubespray 一样,都是使用 ansible 进行部署。不过是纯中文的,而且是分步部署。还添加了几个方便的运维功能。
  6. sealos: 一行命令部署 k8s 集群,支持离线安装。
    • 国人开发的项目,使用方式非常简单。只是它的离线安装包是收费的,各版本价格从 0.01-50 元不等。。(代码开源,因此离线包应该可以自己制作。)
  7. rke/rancher: 完全使用容器运行 k8s 自身,配置文件简单,一行命令部署集群(国内会自动从阿里云拉镜像)。另外中文文档非常详细。
    • rke 评价:现在在开发环境用了半年 rke 了,体验上讲,安装是相当方便。但是它也存在几个比较明显的问题:
      • rke up 经常会健康检查失败,需要跑两三次才能成功。
      • 对修改集群有点语焉不详,找了半天文档才知道修改集群就是改 cluster.yaml 然后重新跑 rke up
      • 将 cni 插件从 canal 切换到 calico/flannel 后重新 rke up,集群网络直接就炸了。rke removerke up 都没用(清理不干净)。也没看到哪里有讲网络插件不能更换。
      • 我们有一部分机器晚上会关机,有时候第二天开机后,nginx_proxy 就挂了,导致节点无法访问 apiserver 而下线。。
    • Rancher 评价:用了一段时间了,文档我觉得是非常详细,很受用。但是 rancher 本身感觉不怎么稳定,经常莫名其妙地报错、卡顿。。也不知道是不是我配置不对。。

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

分一下类的话,按规模分有两类:

  1. 单节点集群:主要用于开发测试.
    • minikube/microk8s
  2. 多节点集群:可用于生产。
    • kubespray/kops/rke 等等。

按安装速度分类的话,首先支持离线安装的单节点集群肯定是最快的,有

  1. kubeadm: 自己编写脚本,先 load 所有镜像或从内网仓库拉取镜像,然后通过 kubeadm 进行离线安装。

其次是支持离线安装的多节点集群,有

  1. rke: 需要提前使用批量推送脚本将镜像推送到内网镜像仓库中。

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

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

一、准备虚拟机

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

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

  1. **各主机的 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,这没啥好说的。

注意事项

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

2. 部署 kubernetes 集群

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

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

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

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

只要你勾选了 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
  7. 使用 rke up 命令部署 k8s

在 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

dashboard 不怎么好用,只适合粗略查看。更建议使用 k9s

  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 登录

2. 本地部署 nginx-ingress-controller

建议用 traefik 替换掉它

参照 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 啦。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
2年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
Java日期时间API系列36
  十二时辰,古代劳动人民把一昼夜划分成十二个时段,每一个时段叫一个时辰。二十四小时和十二时辰对照表:时辰时间24时制子时深夜11:00凌晨01:0023:0001:00丑时上午01:00上午03:0001:0003:00寅时上午03:00上午0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这