rancher 1.6 实践指南-1

rancher 1.6 实践指南-1

rancher 1.6 实践指南-1

前言:
话说认识rancher应该是14年,当时我还在某人寿公司,为了在vmware上自动化部署应用环境而大搞ansible。后来我跳槽到新东方搞容器云,这才正儿八经的研究rancher的落地方案。rancher是个轻量级方案,可探索的东西很多,很多组件需要自己实施补全。除了在项目中自己反复实践和摸索外,也受到rancher社区成员实践讨论或者技术分享的启发,因此我也总结一片日志,把一期项目彻底总结沉淀一下。一是来源于社区再回馈社区,看看是否对大家有启发,二是准备卸下之前的工作成果,整理着装继续上路。 转载请注明出处:jiangjiang.space

目录:

目录注:
由于篇幅问题,这篇日志比较长,我会陆续更新上来。
本文是第一篇,主要是闲扯和架构,以及部署架构和宿主机配置

1. 架构

1.1 Rancher是何物?

以下摘自rancher.com:

Rancher是一个开源的企业级容器管理平台。通过Rancher,企业再也不必自己使用一系列的开源软件去从头搭建容器服务平台。Rancher提供了在生产环境中使用的管理Docker和Kubernetes的全栈化容器部署与管理平台。

rancher提供如下功能:

  • 基础设施编排
  • 容器编排与调度
  • 应用商店
  • 企业级权限管理

官方的架构说明图

从图中看rancher是一个中介,下层他为你管理跑容器用的主机(Iaas层对接),比如在阿里云或者vmware上创建的主机, 中间帮你对接各种编排引擎,比如cattle或k8s, 上层帮你打包应用,比如用rancher catalog或者helm,左手帮你做用户接入和权限控制,右手帮你整合现有的运维工具,比如cicd,镜像仓库和监控等。

我胡乱解读一下rancher的定位。Rancher的定位给大家的印象比较模糊。之前经历了多个版本的迭代,改变也比较大。 听说早期rancher的版本就是给k8s做安装部署和UI的。具体历史我也不是太了解,随着docker的快速成长,当时业界的方向还没有现在这么清晰,在那个独特的环境下,rancher 同时支持k8s 、swarm和mesos,加上自己发展的cattle。确实给外界一个模糊的印象。在我看来其实这模糊的印象恰恰给出了rancher的准确定位—— rancher就是管理容器平台的平台。你可以简单理解rancher就是一个带ui,带虚机管理和权限控制等诸多功能的kubadmin 。不知道这么说是不是有助于理解? (是不是更糊涂了? 笑~)
下面说的rancher都是指的是rancher的cattle引擎。

下面所有Rancher的表述代表着Rancher 1.6 ,编排引擎为cattle ,请避免不必要的误会。

1.2 为什么选rancher?

我之前在公司内部和外部都谈过这个话题,从纯技术角度考虑,确实有更多的高大上方案要优于rancher,技术选型上技术最优只是选择方案的因素之一,一个项目是否能成功落地还需要考虑:项目资源、项目的时间、团队人员情况和团队文化等等。 rancher的架构小巧,实现简单,生态直接建立在docker和docker compose之上,学习成本非常低。 实施快,容易定制。 特别适合有以下情况的团队:

  • 时间紧任务急,想要快速构建一套容器云平台
  • 人员不多,人员复用情况高,无专职运维,开发人员自己搞
  • 团队build能力强,需求二次开发框架。

总结一下大概就是这样:

  1. rancher项目100%开源,可选的商业支持。
  2. 提供丰富的api,组件插件化,可供用户自行定制选择。
  3. 学习成本低,直接沿用了docker生态,非常好上手。
  4. 内置容器网络方案,NFS共享存储,CI/CD工具,应用商店框架(rancher catalog),公有/私有云对接,LDAP对接方案。能节省你很多的方案选择和摸索时间。

也说说劣势,或者说什么情况下不适用rancher

  1. 生产级别的有状态应用,rancher有很多办法来支持有状态应用,不过难度有点高。因此还是跑无状态应用轻松一些。
  2. 对共享存储有较高写要求的用户,目前共享存储支持最好的是NFS,比较适合作为读存储。目前我还没发现非常满意的写存储方案。
  3. 动手能力弱,对开源业态和方案不甚了解的用户。前面提到过,rancher落地到你的组织中需要很多磨合,需要自己琢磨方案(购买其官方支持的除外)。

1.3 什么场景下适合用rancher?

  • 深度定制的用户自服务平台
  • 无状态业务和动态伸缩
  • 作为平台服务的后台支撑平台
  • 容器管理UI

解释一下:

  • 第一条:rancher最常用的场景,所谓轻量级paas就是灵活好定制。rancher的方案很松散,比如日志方案,比如镜像仓库,其实都是社区现有的方案攒起来的。用户自己对接起来的自由度就大一些,功能好裁剪。用户以rancher作为后台,功能和动作都在后台,前台来做环境的隔离、计费、权限等等。也可以集成rancher api到现有的平台中(比如已有的管理后台)。 这也是rancher最大的价值所在,试想一下如果对接openshift等重型paas平台,那需要多少工作量? 侵入性有多大,是否要为了接入对方而改变目前的流程和习惯?
  • 第二条:rancher的动态伸缩还是很好集成的,可以应用直接调用webhook,一个shell脚本或者zabbix的action都能帮你做动态伸缩。
  • 第三条:我见到群里有同学用rancher管理他们所有的ipfs,rancher对他来说就是ipfs这个对内对外服务平台的后台管理和支撑平台。同样的思路,你可以用rancher做为XXX as a service的基础后台。
  • 第四条:rancher用熟了以后会发现,与其手动管理一个个docker,还不如直接用rancher管起来。能轻松不少。

2. 部署

这里开始进入正题,记录rancher的部署架构和需要注意的细节。

2.1 部署架构总览

简单的rancher部署方案大体是这样的:

你只需要按照文档很快就能搭建一套出来,这里需要注意的是
1.如果是虚机部署,切记不要dhcp
2.如果是拷贝虚机的方式,最好在部署docker后,部署rancher前拷贝。(或做成虚机模板)

大家也可能会发现这个方案存在很多问题,比如server只有一个,数据库只有一个。
节点连接写死 server 的 IP(当然也可以用域名解耦)等等。

下面介绍我的部署架构, 我只是在上面简单方案的基础上增加高可用和负载均衡即可,将所有单点都变成负载均衡的,或者至少是HA方式。

架构图如下:

  1. ranher server 部署多台,开启rancher server ha 模式
  2. rancher 数据库采用maxscale中间件和多台mariadb,减少数据库故障对rancher 的影响,缩短库切换时间
  3. 在server和client中间增加4/7层转发作为负载均衡。我们知道当rancher node不断的增加会对后台server造成很大的压力,在s/c中间增加负载均衡就使得两遍的扩展都变得轻松。

下面就逐个介绍一下各个组件的配置,从宿主机开始,直到应用如何对外发布到公网。

2.2 宿主机配置

2.2.1 操作系统的选择
centos还是ubuntu

毋庸置疑推荐选择ubuntu 1604,4.x内核支持overlayfs2,使用起来会轻松好多。
centos在国内使用广泛,已有一整套的配置、监控、运维体系,出于管理成本考虑,选择centos也没关系。我用的也是centos. 下面所有的设置介绍都是基于centos7.4的。

2.2.2 docker版本和设置优化

首先请先卸载centos自己默认安装的docker,以避免不必要的麻烦。

rancher 支持的docker版本
http://rancher.com/docs/rancher/v1.6/en/hosts/#supported-docker-versions
下图为节选

version指的是docker的版本
Supported 指的是cattle是否支持这个docker版本
kubernetes supprted 指的是kubernetes是否支持这个docker版本
也就是说docker并不是最新的最好,因为无论是cattle还是k8s都不可能一直跟着docker跑,而是选择在某个版本上做适配。

举个例子:
如果你打算使用cattle引擎,那么你现在可以安装的docker版本最高是17.12
如果你打算在rancher上部署kubernetes, 目前rancher支持 kubernetes 1.8, docker的版本最高到17.03

直接拷贝后面的脚本到主机上运行即可。

2.2.2.1容器存储选择DeviceMapper

ubuntu1604就不用考虑使用dm了,直接上overlayfs2即可。
如果你是centos7.4 ,也可以直接使用overlayfs2。
但是下面的介绍重点是DeviceMapper,我参考了openshift和docker EE,他们都用的DM,因此我也选择DM作为容器存储。 DM实际就是跳过了文件系统层,直接在磁盘上划薄逻辑卷(lvm thin volume)作为容器的存储。性能还不错,所谓薄卷的意思就是超卖,大概意思就是承诺给10个容器分别配置10G磁盘,但是实际自己拥有的磁盘要远小于100G,可能只有小几十个G。这么做主要是考虑容器自身存储不算大,有个几百兆就算不小了,加上应用也就1g或者2g大,因此如果按照10G或者20G一个容器来分配磁盘还是挺浪费的。另外容器的生命周期短,磁盘全部用满的机会较少。因此超卖是个节省资源的做法。

顺便说一下,rancher有时容器创建不出来也是因为磁盘满,一般多是之前积累下的镜像占用了空间。这里还是多给一些磁盘,同时注意定期清理镜像。

什么很多人不推荐DeviceMapper,因为DM确实有点问题,很多时候会出现容器删除掉但是对应的lvm卷删不掉,导致容器变为dead。 请看我之前的一篇日志来解决这个问题。
解决docker容器删除后处于removal-in-progress-状态不释放
这篇日志的办法还会引发新的问题,mountoption改为private后删除容器变得很顺畅,但是在挂载在host上的glusterfs时又会出现只能看到glusterfs的父目录二看不到子目录的问题。如果你不需要用到glusterfs那就没有问题。

因此我现在也准备放弃devicemapper了,直接从centos迁移到ubuntu或者coreos。
对于自行在centos上升级内核的高手们, 自己玩还行, 为了你老板的健康还是算了吧。

2.2.2.2 direct-LVM 和 loop-LVM

都是DeviceMapper方式,还分为direct-LVM 和 loop-LVM,这里是个坑。红帽系列系统中的docker默认开启的是 loop-lvm,其实是一个文件假装成一个磁盘放在文件系统中,再通过device mapper 做成卷挂载,性能和可扩展性可想而知。因此一定要将loop-lvm改为direct-lvm。

改dircet-lvm有两种方法,手动或者自动,如果是新装系统就自动就行了。
配置方法如下:

/etc/docker/daemon.json 中加入:
{
  "storage-driver": "devicemapper",
  "storage-opts": [
    "dm.directlvm_device=/dev/xdf",
    "dm.thinp_percent=95",
    "dm.thinp_metapercent=1",
    "dm.thinp_autoextend_threshold=80",
    "dm.thinp_autoextend_percent=20",
    "dm.directlvm_device_force=false"
  ]
}
# 转载请注明出处:jiangjiang.space 

参数解释和手动配置方法详细请见:https://docs.docker.com/storage/storagedriver/device-mapper-driver/#configure-direct-lvm-mode-for-production

2.2.2.3 docker 子网规划

docker的默认bridge docker0 的子网是从172.17.0.0/16 开始的. 需要注意的是172.17可能已经存在与物理网络之上,这就造成启动了docker的机器和172.17网段就失联了。原因是外面172.17网段发来的包,被docker路由到docker0上去了, 因此所有的包都有去无回,两遍自然也无法通信。

解决办法:
规划组织内的子网,留一段子网专门给docker使用。

{
   "bip": "172.xxx.0.1/xx",
}

2.2.2.4 registry加速

docker默认从docker hub 拉取镜像。 docker hub距离较远,中途有又众所周知的一些情况干扰。因此需要配置国内镜像源加速。

这里使用docker中国官方源

解决办法:

 "registry-mirrors": [
            "https://registry.docker-cn.com"
   ],

2.2.2.5 其他的一些设置

常见的内核参数优化,最大文件打开数,swappiness 等等
sysclt 配置

/etc/sysctl.conf
net.core.somaxconn = 65535
fs.file-max = 655360
vm.swappiness = 1

ulimit nofile

/etc/security/limits.conf
*  soft    nofile  102536
*  hard    nofile  102536

2.2.2.6 Systemd中的设置

这里要说明一下是MountFlags参数。
前面我也说了一下,我这里设置mount flags 为 private,主要是为了避免容器存储卷因为被其他进程打开而出现关闭上
请参考我之前的一片笔记。这里设置要看情况,比如你如果想完全避免容器删除不掉的情况发生,那么需要设置为private 。
但是如果需要挂载glusterfs,后面我会提到,则需要修改为share。

/usr/lib/systemd/system/docker.service
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
MountFlags=private    # 解决容器删除不掉的问题,可能会影响bind host目录到容器里面
#MountFlags=shared