Rancher2.1.4使用记录

1、前言

    说实话,Rancher的官方文档真的很全,围绕着UI的方方面面都面面俱到。但看多了却发现,不少东西都浅尝辄止,尤为某个东西实在不懂的时候,看文档只能让本身更没头绪。因此此文的目的是方便本身可以在须要的时候回忆出点点滴滴。html

    Rancher1.6的傻瓜式操做给了我很大的帮助,也帮我赢得了大部分运维的支持,最终得以施展。但Rancher2.0不管是开发版仍是beta版,都并非那么友好,老是莫名其妙的出现各类各样的问题。后来由于工做的调动,没有继续研究新版。不过如今终于有时间了,当前最新版本2.1.4,因此此文的基础也就是2.1.4。前端

    另外,本文不会花篇幅去介绍如何安装或者解决安装中的问题,但涉及到的,我都会附上连接。本文主要的做用一个是备忘,还一个是手册。若是之后回头看这篇文章,发现忘了的看一遍就回忆起来了,照着作一遍的环境就搭好了那就完美了。node

2、先决

    有必要在这里提早声明一下先决条件(并非说实际上就是这个数据,而是个人环境是这个数据)。从Rancher1.6开始到如今的2.1.4,每个版本都用过。不一样的版本对先决条件敏感,如1.6是敏感度最迟钝的,只要保证OS内核3.1.10以上(含)便可。至于Docker版本,在查阅Rancher文档的时候,不少地方明确指出最高支持版本17.02,但实际使用过程当中,只要是最新版本的均可以。如下是具体的环境说明:mysql

    物理机OS:Ubuntu 18.04linux

    Docker:18.09nginx

    harbor:1.7.1git

    Gitlab:10.4.4sql

3、准备

    从零开始,现有三台物理机,两台服务器,一台笔记本,服务器上只跑一个虚拟机实例,笔记本跑两个虚拟机实例。但须要注意的是:若是须要拷贝虚拟机,必须是同物理机上的拷贝,而不能夸物理机拷贝,哪怕用了什么ovf虚拟机格式,也都不行,由于在实际使用的时候会出现一些莫名的错误,也可能不出,全靠运气。如下是主要步骤(可直接点击穿越到教程,教程来源于网络):docker

    一、更新源(apt-get update && apt-get upgrade)数据库

    二、修改vi命令(默认vi命令不友好)

    三、设置root用户以及启用root远程登陆

    四、设置limit

    五、安装docker

    六、配置加速器(加速器可用daoclould也可用阿里的,这里贴出的是daoclould的)

    七、设置机器域名host指向(若是是直接使用IP访问的话,跳过这个)

    8.一、安装rancher

sudo docker run -d --restart=unless-stopped -p 80:80 -p 443:443 rancher/rancher

    8.二、安装harbor

    九、登陆Rancher建立集群导入机器

    十、全部机器harbor登陆受权(若是不须要本身手动pull私服上的镜像,此步跳过)

    额外须要注意的是:

        一、最新版本的docker默认采用https方式拉取镜像(确切的说是自1.3.2版本开始),若是使用http,那就须要在机器上添加过滤,详情点击

        二、自受权的https证书,须要在机器上信任,信任方式点此

        三、Rancher内部是k8s,k8s集群中,不会读取宿主机的证书。故在宿主机配置了证书信任,不会渗透到k8s集群。也就是说在宿主机信任证书,对于k8s来讲,没有任何影响。这个产生一个很大问题,就是在Rancher里配置了镜像库后,Rancher没法登录到镜像库,缘由就是CA证书不被信任。这直接致使私有镜像私服被废了,除非公司花钱买证书,或者使用如阿里云镜像私服这样第三方服务。阿里云地址点此

4、概念说明

    这一部分是说明1.6和2.0两部分,Rancher的概念,目的是着重理解Rancher。

    前段时间看了本书叫《码农翻身:用故事给技术加点料》,这个思路很清奇,久久不能忘。遂本章也用说故事的方式来阐明概念。

4.1白手起家的农场主(1.x)

    小明的志向是当一个农场主。虽然他历来没干过,可是他如今准备干了。

    因而他买了一块地,首先他用栅栏围了起来,防止牛羊越狱,同时也防止可恶的豺狼豹子偷猎牛羊。而后小明对圈内的地进行的划分,A区域B区域……,这样能够方便管理。每一个区域他又建了不少棚舍,不过棚舍之间是互通的,这样牛羊就不会寂寞,能够串串门。

    万事俱备只差牛羊,小明考虑直接去牛羊中心,路途遥远,倒不如去最近的代理商,代理商就像超市,把牛羊从厂家运送过来,这样省时又省力。为了保险起见,小明只买了几百只牛羊,而后赶到本身规划好的农场。

    其实小明的工做很简单,定时检查一下牛羊的状态,是否是饿了渴了或者生病了又或者死亡了,不过若是牛羊死亡了,小明就必须再买一头回来。有时候小明还会给牛羊作个造型美化一下,小明说这叫升级,固然若是美化失败了,小明还会恢复原样,小明又叫这个回滚。

    小明很满意本身的农场,但以为一我的有点无聊,因而他又创建了一个站台,站在站台上能够看到某个区域的每一个棚舍,就像动物园同样。而后开放给你们,不只能赚点外快,还不会以为无聊。

    今后,小明过上了幸福的农场主生活,实现了人生理想。

    故事到此结束,如今解释一下文中的概念:

        一、小明:rancher的master节点 

        二、栅栏:rancher集群

        三、区域:集群

        四、棚舍:项目

        五、牛羊:容器

        六、牛羊中心:docker hub镜像中心

        七、代理商:国内镜像如阿里云

        八、升级:镜像升级

        九、回滚:镜像回滚

        十、站台:负载均衡(HA)

        十一、小明的工做:cattle编排引擎

4.2高速发展的农场(2.x)

    小明的幸福没过多久,就出现问题了。第一,小明天天不只要进行繁琐的工做,还要接待到访的游客,忙得团团转。第2、牧场过小了,访客太多了,每次都有人抱怨等待的时间过久了。小明痛定思痛决定要改善这两个问题,好在经营了一段时间,手里攒了很多积蓄。

    首先,他扩大了牧场,区域划分保持不变,之前一个大棚舍,如今建好几个大棚舍,但棚舍里作好规划,不一样棚舍养不一样的牛羊,同时棚舍之间是独立的,防止牛羊乱窜,但同样的同一个棚舍仍是不由止的。另外,大棚舍里的小棚舍,也得改造,每次游客来都反应脏乱差。因此,给每一头牛羊创建单独的房间,再装饰的很是精美,除此以外,每一个房间还会配备专人管理,最后起个洋气的名字,叫pod。

    而后,雇佣一大批的人,把小明之前的工做都细化分工下去,好比待在pod里,负责牛羊的管理,好比升级和回滚。而后每一个大棚舍自治,牛羊的采购、参观等等独立化,这样管理起来更方便,同时若是一个大棚舍出现问题,也不会影响到别的大棚舍。

    接着站台也要优化一下,之前是固定的几个站台,你们都按序排队。如今不用那么麻烦了,由于大棚舍自治了,每一个大棚舍单独售票,因此只须要安排几个迎宾,游客来了,问一下去哪一个大棚舍,而后直接带过去就好了,大大减小了访客的等待时间。

    最后,因为规模相比以前不可同日而语,各个流程小明没法手动管理,因而小明又规划了一个叫流程的东西,想要干什么东西话,只须要按照流程走就对了。

    至此,全部问题都解决了,而且小明也解放了,天天只须要巡视工做就成了,小日子过得不要不要得。
    故事到此结束,如今解释一下文中的概念:

        一、小明:rancher的master节点 

        二、栅栏:rancher集群

        三、区域:集群

        四、大棚舍:命名空间

        五、小棚舍:项目

        六、pod:pod,k8s对容器的包装,负责容器的生命周期

        七、牛羊中心:docker hub镜像中心

        八、代理商:国内镜像如阿里云

        九、升级:镜像升级

        十、回滚:镜像回滚

        十一、站台:负载均衡(nginx),之前会在固定的IP上,如今只要在集群的任何一台机器上便可,由于会有专门的“迎宾”处理

        十二、为小明工做的人:k8s编排引擎

        1三、流程:流水线(CI/CD)

5、场景实例

    有一个以JAVA编写的微服务,如今要部署上线。

5.1规划

    首先,环境分为本地环境(dev)、测试环境(test)、预发布环境(uat)、线上环境(live)。

    而后,根据业务划分命名空间,好比后台统一为service,手机客户端统一为app

    而后,根据业务划分项目,如用户管理的后台服务项目,则命名为user-manager

    而后,根据代码项目划分服务,好比认证服务是user-auth,登陆是user-login

    而后,根据实际代码,配置负责均衡暴露服务,为外界提供接口

    同时,配备日志采集,能够统一查看各个项目的日志

5.2流水线(CI/CD)

    简单说下原理,Rancher按如下步骤运行:

        一、Rancher启动一个jenkins镜像,此镜像能够经过配置一个负载均衡来暴露出去访问后台界面,用户名是admin,密码是容器里的环境变量ADMIN_PASSWORD,默认是cgfh9ljx7dtx7s2vmqf7r9xcf6zj45s5lxcwg95zmtqz9n58mg84pc,若是启动流水线报错,登陆jenkins,进去系统设置->全局安全设置,找到“防止跨站点请求伪造”,肯定勾选,而后点击保存(若是已勾选,那么勾选掉,保存,再编辑,勾选,保存),再从新启动流水线便可。

        二、将流水线任务生成groovy脚本,而后在jenkins上建立任务并执行。

        三、流水线的每个阶段对应一个镜像,Rancher会启动对应的容器,执行流水线配置的流程。

    一个典型的jenkins流水线脚本,相似以下:

import org.jenkinsci.plugins.pipeline.modeldefinition.Utils
def label = "buildpod.${env.JOB_NAME}.${env.BUILD_NUMBER}".replace('-', '_').replace('/', '_')
podTemplate(label: label, namespace: 'p-8j2pf-pipeline', instanceCap: 1, serviceAccount: 'jenkins',volumes: [emptyDirVolume(mountPath: '/var/lib/docker', memory: false), secretVolume(mountPath: '/etc/docker/certs.d/docker-registry.p-8j2pf-pipeline', secretName: 'registry-crt')], containers: [
containerTemplate(name: 'step-0-0', image: 'rancher/pipeline-tools:v0.1.0', ttyEnabled: true, command: 'cat' , envVars: [
    envVar(key: 'CICD_GIT_REF', value: 'refs/heads/master'),envVar(key: 'CICD_GIT_BRANCH', value: 'master'),envVar(key: 'CICD_PIPELINE_ID', value: 'p-dd58c'),envVar(key: 'CICD_CLUSTER_ID', value: 'c-gb2hf'),envVar(key: 'CICD_LOCAL_REGISTRY', value: '127.0.0.1:34350'),envVar(key: 'CICD_GIT_COMMIT', value: '6795394'),envVar(key: 'CICD_GIT_URL', value: 'http://git.lumiai.top/york/hyperloop-baseapi.git'),envVar(key: 'CICD_TRIGGER_TYPE', value: 'user'),envVar(key: 'CICD_EVENT', value: ''),envVar(key: 'CICD_EXECUTION_ID', value: 'p-dd58c-27'),envVar(key: 'CICD_EXECUTION_SEQUENCE', value: '27'),envVar(key: 'CICD_PROJECT_ID', value: 'p-8j2pf'),envVar(key: 'CICD_GIT_REPO_NAME', value: 'hyperloop-baseapi'),
]),containerTemplate(name: 'step-1-0', image: 'maven:3.6.0-jdk-8-alpine', ttyEnabled: true, command: 'cat' , envVars: [
    envVar(key: 'CICD_GIT_COMMIT', value: '6795394'),envVar(key: 'CICD_GIT_REPO_NAME', value: 'hyperloop-baseapi'),envVar(key: 'CICD_GIT_REF', value: 'refs/heads/master'),envVar(key: 'CICD_GIT_URL', value: 'http://git.lumiai.top/york/hyperloop-baseapi.git'),envVar(key: 'CICD_PIPELINE_ID', value: 'p-dd58c'),envVar(key: 'CICD_EVENT', value: ''),envVar(key: 'CICD_CLUSTER_ID', value: 'c-gb2hf'),envVar(key: 'CICD_GIT_BRANCH', value: 'master'),envVar(key: 'CICD_TRIGGER_TYPE', value: 'user'),envVar(key: 'CICD_EXECUTION_ID', value: 'p-dd58c-27'),envVar(key: 'CICD_EXECUTION_SEQUENCE', value: '27'),envVar(key: 'CICD_PROJECT_ID', value: 'p-8j2pf'),envVar(key: 'CICD_LOCAL_REGISTRY', value: '127.0.0.1:34350'),
]),containerTemplate(name: 'step-2-0', image: 'rancher/jenkins-plugins-docker:17.12', ttyEnabled: true, command: 'cat' , privileged: true, envVars: [
    envVar(key: 'CICD_GIT_REF', value: 'refs/heads/master'),envVar(key: 'CICD_PIPELINE_ID', value: 'p-dd58c'),envVar(key: 'CICD_EXECUTION_ID', value: 'p-dd58c-27'),envVar(key: 'CICD_EXECUTION_SEQUENCE', value: '27'),envVar(key: 'CICD_PROJECT_ID', value: 'p-8j2pf'),envVar(key: 'CICD_CLUSTER_ID', value: 'c-gb2hf'),envVar(key: 'CICD_LOCAL_REGISTRY', value: '127.0.0.1:34350'),envVar(key: 'CICD_GIT_COMMIT', value: '6795394'),envVar(key: 'CICD_GIT_REPO_NAME', value: 'hyperloop-baseapi'),envVar(key: 'CICD_GIT_BRANCH', value: 'master'),envVar(key: 'CICD_GIT_URL', value: 'http://git.lumiai.top/york/hyperloop-baseapi.git'),envVar(key: 'CICD_TRIGGER_TYPE', value: 'user'),envVar(key: 'CICD_EVENT', value: ''),envVar(key: 'PLUGIN_DOCKERFILE', value: './Dockerfile'),envVar(key: 'PLUGIN_CONTEXT', value: '.'),envVar(key: 'DOCKER_REGISTRY', value: '127.0.0.1:34350'),envVar(key: 'PLUGIN_REPO', value: '127.0.0.1:34350/scc/hyperloop/baseapi'),envVar(key: 'PLUGIN_TAG', value: 'dev'),secretEnvVar(key: 'DOCKER_USERNAME', secretName: 'p-8j2pf-12700134350', secretKey: 'username'),secretEnvVar(key: 'DOCKER_PASSWORD', secretName: 'p-8j2pf-12700134350', secretKey: 'password'),
]),
containerTemplate(name: 'jnlp', image: 'rancher/jenkins-jnlp-slave:3.10-1-alpine', envVars: [
envVar(key: 'JENKINS_URL', value: 'http://jenkins:8080')], args: '${computer.jnlpmac} ${computer.name}', ttyEnabled: false)], yaml: """
apiVersion: v1
kind: Pod
metadata:
  labels:
    app: jenkins
    execution: p-dd58c-27
spec:
  affinity:
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: app
              operator: In
              values:
              - jenkins
          topologyKey: kubernetes.io/hostname
"""
) {
node(label) {
timestamps {
timeout(60) {
stage('Clone'){

parallel 'step-0-0': {
  stage('step-0-0'){
    container(name: 'step-0-0') {
      checkout([$class: 'GitSCM', branches: [[name: 'local/temp']], userRemoteConfigs: [[url: 'http://git.lumiai.top/york/hyperloop-baseapi.git', refspec: '+refs/heads/master:refs/remotes/local/temp', credentialsId: 'p-dd58c-27']]])
    }
  }
}
}

stage('打包'){

parallel 'step-1-0': {
  stage('step-1-0'){
    container(name: 'step-1-0') {
      sh ''' 
echo "haha">baseapi.jar '''
    }
  }
}
}

stage('发布ƒ'){

parallel 'step-2-0': {
  stage('step-2-0'){
    container(name: 'step-2-0') {
      sh '''/usr/local/bin/dockerd-entrypoint.sh /bin/drone-docker'''
    }
  }
}
}


}
}
}
}

    好了,说完原理,下面实操。

    进入到Rancher管理平台,依次进入dev(集群)->service(命名空间),而后点击流水线。   

5.2.1源码管理

    源码管理使用本地Gitlab,代码语言是Java,使用maven构建,提供REST风格的API接口。

    目前Rancher只支持接入单个代码库,不支持多代码库同时接入。打开Gitlab,点击我的设置->应用,而后配置应用信息,拿到应用ID和应用密钥,最后回到Rancher输入gitlab地址、应用ID和应用密钥便可接入。

5.2.3源码打包

    启用任意代码项目后,流水线首页就会出现对应的数据,点击编辑。

    编辑页面,可操做的东西很少,但很简明易懂。

    第一步克隆代码,这一步是默认的也是必须和没法编辑的。

    点击添加阶段,输入阶段名,如“打包”,点击完成

    点击添加步骤,步骤类型分三类,一类是运行脚本,一类是构建并发布镜像,最后一类是部署YAML,每个阶段能够添加不少步骤。这里点击运行脚本,而后在下面镜像那里输入maven:3.6.0-jdk-8-alpine,输入完成后会出现提示框maven:3.6.0-jdk-8-alpine (Custom),鼠标点击便可,最后在脚本那里输入mvn clean package。

5.2.4镜像发布

    打包完成后,再建立一个阶段,叫“镜像发布”,再点击添加步骤。

    步骤类型是“构建并发布镜像”,下面Dockerfile路径指的是代码中基于项目根路径的Dockerfile路径,镜像名称注意不用写镜像私服地址,但要带有仓库中对应项目名,好比harbor中我有一个项目叫shy,那么这里应该输入shy/xxx:[xxx],再勾选下面的“推送镜像到远端镜像仓库”,选择对应的镜像库便可。

     特别须要注意的是,这一步会启动一个叫rancher/jenkins-plugins-docker:17.12的镜像,这个镜像会使用默认的https推送镜像,若是使用了Harbor,可是自签证书,那么这一步永远过不去,必须是合法的CA证书。或者使用阿里云的镜像私服,那个CA证书确定得合法的。

5.2.5上线部署

    镜像发布后,在建立一个阶段,叫“上线部署”,再点击添加步骤。

    步骤类型是“部署YAML”,下面YAML路径一样指的是代码中基于项目根路径的YAML路径。而后点击添加, 在流水线配置的右下角有个“显示高级选项”,打开他,配置触发规则。也可不配置,每次手动执行。

    最后点击完成,即建立完一个完整的流水线。

5.3日志采集

    一个服务不可能只有1个实例,多实例就致使日志的排查比较困难,由于不知道访问落到了哪一个实例上,因此一个集中式的日志中心是颇有必要的。rancher针对每个命名空间都提供了一个专门的日志采集接口,只须要配置日志输出便可。

    打开全部的应用商店,搜索efk,而后点击安装。

    接着,命名空间视图下,点击资源->日志,选择Elasticsearch,输入刚刚建立的es的地址,肯定索引前缀,保存便可。指的注意的是,这里的日志粒度仍是有点粗的,只到项目这一层级,实际使用的时候,能够多建项目,每一个项目一类服务的方式,规避粒度粗的问题。

5.4负载均衡

    1.x的Rancher,事先是不知道实际的IP地址的,每次都是先配置负载均衡,拿到IP再配置DNS解析。

    2.x的Rancher,不用事先知道具体的IP了,访问集群内的任何一台机器便可,而且不再用担忧80端口不够用的状况。但因为这个版本放弃了HA,采用的nginx,而且不支持自定义配置,致使目前只支持L7层的负载均衡。

5.5机器扩容

    Rancher的扩容很是容易,按照第三章的前7条执行,而后将此时的镜像打包成系统镜像,之后直接拿这个镜像安装系统。安装完成后,直接在Rancher界面上添加主机,便可实现扩容,另外2.x的版本新主机的管理不须要手动进行,k8s会主动进行管理。

6、最佳实践

    这里说的咱们线上集群的状况,并进行了必定得推测。另外,docker最佳搭档就是全部无状态的服务,Rancher同理也最适合无状态的服务,对于有状态的,如mysql,最好不要丢到rancher或者说docker上运行,不稳定是其次,数据丢失可怕了。

6.1机器配置

    物理机很重要,他是载体,决定了容器的状况。

    CPU:最低单U8核,越多越好,看具体状况。

    内存:32G是最低了,再少跑不了多少容器,咱们是64G。

    硬盘:机械盘RAID5跑不了(这玩意读取性能不高为啥用他?由于生产中硬盘坏了很常见啊,呵呵),固然最好的仍是固态,但那玩意成本过高。

    网卡:千兆的应该是标配了吧

6.2节点数量

    1.x受限于cattle的编排能力,节点数最好保持在20台左右,容器总量500如下,多了cattle就处理不过来了。

    2.x对节点数量没限制,可是节点的类型须要注意下:

        worker:是工做节点,不限数量,咱们是除rancher自己外,其它都是worker

        control:集群控制节点,负责每一个pod的控制,咱们是设置了总机器数量的数量

        etcd:k-v存储,数量必须是奇数,咱们是设置了总机器数量的1/3

    也就是说每3台机器,有一台的类型是worker和control以及etcd,其它两台是worker和control。

6.3HA

    Rancher:主节点必须是高可用的,咱们是3个主节点,使用mysql存储数据,中间用mycat代理。

    Mysql:跑在物理机上,1主2从。

6.4安全

    虽然Rancher是一个密闭的集群,但宿主机被黑,跑在这上面的容器也会遭殃。但若是物理机若是开启了防火墙,却又会致使一些莫名的错误,这时该怎么办呢?

    若是有本身的机房和机器,解决方案是:

        一、关闭全部主机的防火墙,同时断开一切与外网的链接,至关于一个密闭的局域网

        二、将F5架设在局域网的前端,外网能够访问F5,内网也能够访问F5,但外网访问不了内网。而后再将F5打形成一个堡垒机,最后全部请求经过F5转发的对应的服务上。

    若是是云服务器,购买机器,不买外网IP,经过云提供商的负载均衡访问所购买的机器,这种和上面是如出一辙的。

    最后说下登陆认证,企业通常使用ldap,或者直接数据库密码存储。但推荐ldap,企业里是很是方便的。

相关文章
相关标签/搜索