查看原文
其他

生产用例 | 百台边缘设备上的Kubernetes实践

RancherLabs 2019-12-18

以下文章来源于边缘计算k3s社区 ,作者曾永杰

本文由11月7日晚,上海全应科技运维经理曾永杰的技术分享整理而成。

曾永杰,上海全应科技有限公司运维经理,曾在华为西安研究所云计算部门承担软件测试工程师、项目交付、线上运维等工作职责,当前工作主要为CI/CD流程的建设与维护、应用的容器化改革和容器云平台的运维管理。

欢迎添加k3s中文社区助手微信(微信ID:k3s2019),加入k3s官方中文社区,和大家一起交流k3s使用经验。


项目简介


背景


随着国家政策的导向,互联网基础设施的普及,工业、能源行业的智能化改造已经进行的如火如荼,传统行业的特点是信息化、智能化水平严重落后于其他行业,在进行信息化、智能化改造的过程中,首先第一步,就是要获取底层系统的全方位的数据。


为此,需要部署大量的边缘设备来采集数据、分析数据,通过这些数据进行建模,大量的边缘设备一般离散的分布在不同机房、厂区、甚至是不同的地理区域,这对运维人员来讲是令人恐惧的事情,维护这些设备,管理其上运行的应用变得极其困难。


我们公司是国内第一批投身于工业互联网改革浪潮中一员,因此上面提到的问题,也是我们面临的问题。


公司从一开始就采用了微服务化的开发模式,除了平台框架核心应用之外,所有应用都是可插拔的微服务。


与业务平台不同的是,边缘设备具有下面的特点:


  • 数量大,动辄有数十台、数百台设备;

  • 单点故障影响小,一个设备只负责一小块区域的数据采集、分析与计算,因此单台设备的故障导致的局部数据的缺失,数据分析层面也进行了数据清洗,因此,单点故障对全局业务影响不大。


需求


对于运维角色来讲:


  • 管理这些边缘设备,保持边缘设备上运行的服务的高可用性;

  • 快速的上线、升级

  • 配置的快速更改与应用


逻辑拓扑图


下面的图形简单描述了项目基础设施层的拓扑:



其中,每一个边缘侧设备上运行的业务会和中枢业务系统通讯,边缘侧所有设备在单独的一个网络平面中。


运维方案选型


在决定运维方式时,考虑过下面的几种方式:


Ansible


我们在边缘侧设备上运行的应用大部分都是纯Java应用,再加上一部分Python应用,因此部署和启动非常简单,外加上supervisord应用实现了应用的基本高可用方案。在公司还没有进行容器化转型之前,我们采用传统的部署形式部署微服务,就是配置好宿主机的系统环境,直接将应用部署在宿主机系统上,在这种情况下,我们只需要解决的问题是大批量设备部署和维护的问题,因为不管是部署还是更新升级、配置,所有边缘侧使用Ansible可以较好的满足这一条件。


但是这种方法也有缺点,需要维护一套甚至多套ansible playbook,边缘侧设备所在的网络条件比较差,异常状况也比较差,经常掉电重启或者断网,使用ansible 容易造成各个节点的配置不同步。


kubeedge


kubeedge是由华为基于kubernetes开发并开源,专门用于边缘容器编排的运维方案,其基本架构如下:



从上面的架构图中可以看到,kubeedge实现了一个边缘侧完整的框架,对我们公司来讲,我们自行实现了例如“DeviceTwin”、“EventBus”、“ServiceBus”以及基于MQTT收发消息。因此:


  1. 一部分组件与kubeedge重叠了;

  2. 部署不方便,kubeedge要求在各个节点上以kubeadmin部署kubernetes集群(0.6版本,现在已经更新至1.1版本,不知道现在是否有更简便快捷的形式),对网络环境不好的边缘侧设备有较大难度;

  3. kubeedge组件与kubernetes组件基本一致,对于边缘设备寸土寸金的资源来说,不太友好。


通过实践,第2点和第3点原因直接打消了我采用kubeedge的念头。


k3s简介


什么是k3s?


k3s is 5 less then k8s,直接翻译过来就是k3s比k8s少了5个字符,引申一下就是k3s就是k8s的简化版。可以看做k8s的一个衍生版,特点就是轻量。


k3s的特点有哪些?


  • apiserver、controller manager、scheduler、kubelet、flannel等组件这到一个进程中(通过指定是server或者agent选项来控制节点上需要启动哪些组件,server相当于k8s的master节点,agent相当于worker节点),占用的内存更少了,整个k3s server进程需要的内存在500MB以下。


$ systemctl status k3s-server● k3s-server.service - Lightweight Kubernetes Loaded: loaded (/usr/lib/systemd/system/k3s-server.service; enabled; vendor preset: disabled) Active: active (running) since 一 2019-10-28 11:35:25 CST; 1 weeks 3 days ago Docs: https://k3s.io Main PID: 1534 (k3s-server) Tasks: 0 Memory: 210.2M CGroup: /system.slice/k3s-server.service ‣ 1534 /usr/bin/k3s server --docker --bind-address=10.0.0.201 --cluster-cidr=10.128.0.0/16 ...
11月 07 14:21:35 test01-201 k3s[1534]: I1107 14:21:35.426083 1534 trace.go:81] Trace[193609352...ms):11月 07 14:21:35 test01-201 k3s[1534]: Trace[1936093523]: [575.582721ms] [575.489216ms] Listing f...done11月 07 14:22:14 test01-201 k3s[1534]: W1107 14:22:14.958361 1534 reflector.go:289] object-"te...978)11月 07 14:23:32 test01-201 k3s[1534]: W1107 14:23:32.403901 1534 reflector.go:289] object-"te...043)11月 07 14:23:52 test01-201 k3s[1534]: W1107 14:23:52.762578 1534 reflector.go:289] object-"te...061)11月 07 14:24:08 test01-201 k3s[1534]: W1107 14:24:08.159614 1534 reflector.go:289] object-"ku...074)11月 07 14:24:20 test01-201 k3s[1534]: W1107 14:24:20.815875 1534 reflector.go:289] object-"te...086)11月 07 14:24:21 test01-201 k3s[1534]: W1107 14:24:21.038295 1534 reflector.go:289] object-"te...086)11月 07 14:26:17 test01-201 k3s[1534]: W1107 14:26:17.367497 1534 reflector.go:289] object-"te...183)11月 07 14:26:27 test01-201 k3s[1534]: W1107 14:26:27.321999 1534 reflector.go:289] object-"te...192)Hint: Some lines were ellipsized, use -l to show in full.[asadmin@test01-201 ~]$


从上面看出k3s server进程当前占用的内存是210MB。


去除了k8s中的一些实验特性、非必须的组件,例如云厂商的驱动、存储插件,k3s在默认状态下只会启动除自身进程之外的两个应用:


  • coredns:提供集群内部的DNS解析服务。

  • traefik:ingress controller的角色。


通讯效率高:k3s server默认使用本地(已集成)的sqllite作为后端数据存储,通讯效率更高一些。


占用资源少:k3s默认使用containerd(server节点,不可更改)作为容器运行时,不在需要中间层的docker engine,占用资源更少。


部署简单:对环境依赖少,可离线也可在线部署(不过国内的网络环境不推荐在线部署。),离线部署时,只需要下载一个大约40MB的二进制文件和一个200MB不到的离线镜像包,启动k3s节点几乎是秒级的。


上手无代价:


  • 使用k3s与kubernetes习惯完全一致,对于使用kubernetes的人来讲使用k3s没有任何代价;

  • 支持部署helm tiller服务端(尽管tiller端会在helm 3.x版本中被干掉),直接使用原有charts部署应用无障碍;


扩缩容方便:增删节点极其方便,几乎是分钟以内就可以完成;


兼容arm架构设备:对于部分有此种类型的设备的集群友好。


下面是k3s的架构图:



k3s集群的所有数据存储在server(master)节点本地的SQLite数据库中,当然也支持存储在诸如MySQL、etcd中,都是支持按照需求在部署节点时选择配置的。server节点与agent节点之间采用tunnel隧道通信,增强了安全性,同时也提升了效率。agent与server节点即使断开网络连接,也不影响相互各自的业务。


因此通过上面的对比和实践验证,我们决定采用k3s来管理边缘设备集群。


运维架构简介


下面是一张完整的运维架构图:



部署k3s集群


由于集群节点一般存在多个,一台台手工安装部署会占用大量的时间,吃力不讨好,因此,我写成了ansible playbook来完成k3s集群的多节点快速自动化部署,如有需要,可以联系yj.zeng@aliyun.com。


各个组件版本信息:


  • k3s: v0.9.1

  • docker: 18.09.9

  • helm: v2.14.3

  • OS:CentOS Linux release 7.6.1810 (Core)

  • Ansible: 2.8.3(在多节点下,用来快速批量部署集群节点)


本次实践在Centos 7上完成,由于部署k3s节点需要root用户权限,因此本实践中所有操作均直接使用root用户登录后进行。


获取k3s以及离线镜像包


k3s GitHub主页:

https://github.com/rancher/k3s/releases


由于国内访问GitHub的速度很慢,在线安装耗时很长,因此推荐采用离线部署方式部署。


以v0.8.1版本为例,下载下面的两个文件:


  • k3s

  • k3s-airgap-images-amd64.tar


准备工作


假定下载到的文件已经上传到服务器节点的~/packages目录下面。


将k3s二进制文件放置到/usr/local/bin目录下,并赋予可执行权限:


# cp ~/packages/k3s /usr/local/bin/ # chmod +x /usr/local/bin/k3s


将离线镜像包放置到指定的位置:


# mkdir -p /var/lib/rancher/k3s/agent/images/# cp ~/packages/k3s-airgap-images-amd64.tar /var/lib/rancher/k3s/agent/images/


需要在k3s集群所有节点上都放置上面的离线文件。


在部署k3s集群之前,需要对所有节点做如下的基础配置。


如果没有专门的域名服务器提供主机名解析服务,那么在每一台节点的/etc/hosts文件中。写入本节点的IP与主机名映射。


给所有节点安装并配置相同的NTP服务器,保证服务器时间的正确性。


# yum -y install ntp && systemctl start ntpd && systemctl enable ntpd


为了方便我们直接关闭防火墙服务:


# systemctl stop firewalld && systemctl disable firewalld


至此,准备工作完成。


部署k3s server节点


提醒:


  • 截止目前,k3s server节点并不支持HA。

  • k3s server节点安装时,可以选在同时在本地安装一个k3s agent节点用以承载工作负载,如果选择不在server节点上安装agent节点,则除了k3s集成的kuberntes组件(如kubelet、api server)之外,其余的插件、应用均不会被调度到server节点上。

  • k3s支持使用多种容器运行时环境,server默认以containerd作为运行时,不支持更改。agent节点可以使用contained也可以使用docker,推荐使用docker,因为docker人机更友好,可以方便的管理镜像和容器以及查错。所以如果选择agent节点以docker作为容器运行时,那么必须要提前安装并配置好docker服务。


现在,我们可以启动k3s server节点:


# k3s server \ --docker \ --bind-address=10.0.0.201 \ --cluster-cidr=10.128.0.0/16 \ --service-cidr=10.129.0.0/16 \ --kube-apiserver-arg service-node-port-range=1000-65000 \ --write-kubeconfig=/root/.kube/config \ --write-kubeconfig-mode=644 \ --node-label asrole=worker


参数说明:


  • --docker: k3s server组件以containerd作为容器运行时。可以顺便在k3s server节点上启动一个agent节点,agent节点可以使用docker作为容器运行时,这样k3s server节点也可以当做工作节点用。当然也可以不在server节点上启动agent节点(添加参数--disable-agent即可)。

  • --bind-address:k3s监听的IP地址,非必选,默认是localhost。

  • --cluster-cidr:与kubernetes一样,也就是pod所在网络平面,非必选,默认是10.42.0.0/16.

  • --service-cidr:与kubernetes一样,服务所在的网络平面,非必选,默认是10.43.0.0/16.

  • --kube-apiserver-arg:额外的api server配置参数,具体可以参考kuberntes官方网站了解支持的配置选项,非必选。

  • --write-kubeconfig:安装时顺便写一个kubeconfig文件,方便使用kubectl工具直接访问。如果不加此参数,则默认的配置文件路径为/etc/rancher/k3s/k3s.yaml,默认只有root用户能读。

  • --write-kubeconfig-mode:与--write-kubeconfig一起使用,指定kubeconfig文件的权限。

  • --node-label:顺便给节点打上一个asrole=worker的label,非必选。


k3s支持众多的安装参数和选型,详细请参考官方文档。


完成之后,检查集群状态:


# k3s kubectl get nodesNAME STATUS ROLES AGE VERSIONtest01-201 Ready master 11m v1.15.4-k3s.1


可见节点已经呈就绪状态。


检查pod的状态:


# k3s kubectl get po --all-namespacesNAMESPACE NAME READY STATUS RESTARTS AGEkube-system helm-install-traefik-fhr87 0/1 Completed 0 3m4skube-system svclb-traefik-zlgwx 3/3 Running 0 54skube-system coredns-66f496764-x9svh 1/1 Running 0 3m4skube-system traefik-d869575c8-kvwbc 0/1 Running 0 54s


可以看到,系统命名空间下所有的应用都已经启动了,server节点已经就绪,接下来可以部署k3s agent工作节点了。


在上面的命令中,我们均是以k3s kubectl开头的命令,是否可以直接使用kubectl客户端呢?当然可以,只需要下载一个对应版本的kubectl二进制文件放到系统的path中,赋予可执行权限即可,使用起来与使用kubernetes集群一模一样!


由于上面的命令是在前台执行的,一旦断开SSH链接或者终止shell进程,k3s server就停止运行了,因此我们给他配置一个systemd服务,用以像管理系统服务一样管理k3s server节点。


创建文件/usr/lib/systemd/system/k3s-server.service,内容为:


[Unit]Description=Lightweight KubernetesDocumentation=https://k3s.ioAfter=network-online.target
[Service]Type=notifyEnvironmentFile=/etc/systemd/system/k3s.service.envExecStart=/usr/local/bin/k3s server --docker --bind-address=10.0.0.201 --cluster-cidr=10.128.0.0/16 --service-cidr=10.129.0.0/16 --kube-apiserver-arg service-node-port-range=1000-65000KillMode=processDelegate=yesLimitNOFILE=infinityLimitNPROC=infinityLimitCORE=infinityTasksMax=infinityTimeoutStartSec=0Restart=alwaysRestartSec=5s
[Install]WantedBy=multi-user.target


然后设置服务开机自启:


# systemctl enable k3s-server


CTRL+C结束在前台执行的命令,我们看到服务文件中引用了一个环境变量文件/etc/systemd/system/k3s.service.env,这个文件并不存在需要先创建一个然后才能启动服务:


# touch /etc/systemd/system/k3s.service.env# systemctl start k3s-server


查看服务状态:


# systemctl status k3s-server● k3s-server.service - Lightweight Kubernetes Loaded: loaded (/usr/lib/systemd/system/k3s-server.service; disabled; vendor preset: disabled) Active: active (running) since 五 2019-10-11 09:37:09 CST; 15min ago Docs: https://k3s.io Main PID: 10841 (k3s-server) Tasks: 0 Memory: 223.3M CGroup: /system.slice/k3s-server.service ‣ 10841 /usr/local/bin/k3s server --docker --bind-address=10.0.0.201 --cluster-cidr=10.128.0.0/16 --service-cidr=10.129.0.0/16 --...
10月 11 09:37:22 test01-201 k3s[10841]: I1011 09:37:22.920359 10841 event.go:258] Event(v1.ObjectReference{Kind:"Node", Namespace:"", Nam...10月 11 09:37:22 test01-201 k3s[10841]: I1011 09:37:22.927021 10841 controller_utils.go:1036] Caches are synced for persistent vo...ntroller10月 11 09:37:22 test01-201 k3s[10841]: I1011 09:37:22.934842 10841 controller_utils.go:1036] Caches are synced for attach detach controller10月 11 09:37:22 test01-201 k3s[10841]: I1011 09:37:22.940745 10841 controller_utils.go:1036] Caches are synced for garbage colle...ntroller10月 11 09:37:22 test01-201 k3s[10841]: I1011 09:37:22.956261 10841 controller_utils.go:1036] Caches are synced for garbage colle...ntroller10月 11 09:37:22 test01-201 k3s[10841]: I1011 09:37:22.956292 10841 garbagecollector.go:137] Garbage collector: all resource moni... garbage10月 11 09:37:22 test01-201 k3s[10841]: I1011 09:37:22.959183 10841 controller_utils.go:1036] Caches are synced for cidrallocator controller10月 11 09:37:23 test01-201 k3s[10841]: I1011 09:37:23.292627 10841 controller.go:606] quota admission added evaluator for: jobs.batch10月 11 09:38:02 test01-201 k3s[10841]: I1011 09:38:02.930061 10841 event.go:258] Event(v1.ObjectReference{Kind:"Node", Namespace...NotReady10月 11 09:38:02 test01-201 k3s[10841]: E1011 09:38:02.970568 10841 daemon_controller.go:302] kube-system/svclb-traefik failed wi...Link:"/aHint: Some lines were ellipsized, use -l to show in full.


提醒:如果出现错误,可以通过journalctl -u k3s-server查看日志。


部署k3s agent节点


在server节点部署完成之后,在server节点的/var/lib/rancher/k3s/server/目录下面生成一个node-token文件,该文件存储了k3s agent节点加入集群时所需的token。


在server节点上,获取token:


# cat /var/lib/rancher/k3s/server/node-token K10e3dc328c9e2cbb07c195542da31ab435dbe0182b1c99c613f460097b5173dbc7::node:0595ee334f5d2847542b5b1c9300f363


在作为k3s agent节点的系统中,以root用户执行下面的命令启动k3s agent节点,但是,因为我们采用了docker作为agent节点的容器运行时,所以我们先将离线镜像导入到docker中:


# docker load -i ~/packages/k3s-airgap-images-amd64.tar fb61a074724d: Loading layer [==================================================>] 479.7kB/479.7kBed9e1db7c0e6: Loading layer [==================================================>] 40.16MB/40.16MBLoaded image: coredns/coredns:1.3.0faf7c252da57: Loading layer [==================================================>] 236kB/236kBd27d00a62b62: Loading layer [==================================================>] 71.48MB/71.48MBLoaded image: traefik:1.7.12d9ff549177a9: Loading layer [==================================================>] 4.671MB/4.671MBd635f458a6f8: Loading layer [==================================================>] 7.586MB/7.586MB9ce3955d3fa8: Loading layer [==================================================>] 73.36MB/73.36MB6c5cc370be91: Loading layer [==================================================>] 4.608kB/4.608kBLoaded image: rancher/klipper-helm:v0.1.5767f936afb51: Loading layer [==================================================>] 4.672MB/4.672MBd9f07b03cc3c: Loading layer [==================================================>] 1.786MB/1.786MB4d018801281b: Loading layer [==================================================>] 3.072kB/3.072kBLoaded image: rancher/klipper-lb:v0.1.1e17133b79956: Loading layer [==================================================>] 744.4kB/744.4kBLoaded image: k8s.gcr.io/pause:3.1


然后执行下面的命令安装k3s-agent节点


# k3s agent \ --docker \ --server https://10.0.0.201:6443 \ --token K10e3dc328c9e2cbb07c195542da31ab435dbe0182b1c99c613f460097b5173dbc7::node:0595ee334f5d2847542b5b1c9300f363 \ --node-ip=10.0.0.202 \ --node-label asrole=worker


参数说明:


  • --docker:k3s agent以docker作为容器运行时。

  • --server:k3s server节点监听的url,必选参数。

  • --token:k3s server安装时生成的token,必选参数。

  • --node-ip:k3s agent节点的IP地址,非必选参数。

  • --node-label:同样给k3s agent节点打上一个asrole=worker的标签,非必选参数。


稍等一会儿,在server节点上查看agent节点是否已经加入到了集群中:


# k3s kubectl get nodesNAME STATUS ROLES AGE VERSIONtest01-201 Ready master 12h v1.15.4-k3s.1test02-202 Ready worker 11h v1.15.4-k3s.1


可以看到节点已经成功加入到了集群中。


同样给agent节点配置成systemd可以管理的系统服务,创建/usr/lib/systemd/system/k3s-agent.service,内容如下:


[Unit]Description=Lightweight KubernetesDocumentation=https://k3s.ioAfter=network-online.target
[Service]Type=notifyEnvironmentFile=/etc/systemd/system/k3s.service.envExecStart=/usr/local/bin/k3s agent --docker --server https://10.0.0.201:6443 --token K10e3dc328c9e2cbb07c195542da31ab435dbe0182b1c99c613f460097b5173dbc7::node:0595ee334f5d2847542b5b1c9300f363 --node-ip=10.0.0.202 --node-label asrole=workerKillMode=processDelegate=yesLimitNOFILE=infinityLimitNPROC=infinityLimitCORE=infinityTasksMax=infinityTimeoutStartSec=0Restart=alwaysRestartSec=5s
[Install]WantedBy=multi-user.target


我们终止前台执行的命令,执行下面的命令通过systemd重新启动服务:


# touch /etc/systemd/system/k3s.service.env# systemctl daemon-reload && systemctl enable k3s-agent# systemctl enable k3s-agentCreated symlink from /etc/systemd/system/multi-user.target.wants/k3s-agent.service to /usr/lib/systemd/system/k3s-agent.service.# systemctl start k3s-agent# systemctl status k3s-agent● k3s-agent.service - Lightweight Kubernetes Loaded: loaded (/usr/lib/systemd/system/k3s-agent.service; enabled; vendor preset: disabled) Active: active (running) since 五 2019-10-11 10:05:12 CST; 1min 30s ago Docs: https://k3s.io Main PID: 13631 (k3s-agent) Tasks: 0 Memory: 149.0M CGroup: /system.slice/k3s-agent.service ‣ 13631 /usr/local/bin/k3s agent --docker --server https://10.0.0.201:6443 --token K10e3dc328c9e2cbb07c195542da31ab435dbe0182b1c9...
10月 11 10:05:13 test02-202 k3s[13631]: I1011 10:05:13.074705 13631 cpu_manager.go:156] [cpumanager] reconciling every 10s10月 11 10:05:13 test02-202 k3s[13631]: I1011 10:05:13.074731 13631 policy_none.go:42] [cpumanager] none policy: Start10月 11 10:05:13 test02-202 k3s[13631]: I1011 10:05:13.079218 13631 plugin_manager.go:116] Starting Kubelet Plugin Manager10月 11 10:05:13 test02-202 k3s[13631]: I1011 10:05:13.350068 13631 kube.go:134] Node controller sync successful10月 11 10:05:13 test02-202 k3s[13631]: I1011 10:05:13.350282 13631 vxlan.go:120] VXLAN config: VNI=1 Port=0 GBP=false DirectRouting=false10月 11 10:05:13 test02-202 k3s[13631]: I1011 10:05:13.353705 13631 flannel.go:75] Wrote subnet file to /run/flannel/subnet.env10月 11 10:05:13 test02-202 k3s[13631]: I1011 10:05:13.353740 13631 flannel.go:79] Running backend.10月 11 10:05:13 test02-202 k3s[13631]: I1011 10:05:13.353767 13631 vxlan_network.go:60] watching for new subnet leases10月 11 10:05:13 test02-202 k3s[13631]: I1011 10:05:13.412763 13631 reconciler.go:203] operationExecutor.VerifyControllerAttachedVolume s...10月 11 10:05:14 test02-202 k3s[13631]: I1011 10:05:14.215209 13631 reconciler.go:150] Reconciler: start to sync stateHint: Some lines were ellipsized, use -l to show in full.


可以看到k3s agent节点已经成功启动了。


如果还需要加入新的agent节点到集群中,可以按照上述方式配置启动新节点,完成后,新节点自动加入到集群中。


部署应用


通过helm部署应用


一般情况下,我们会通过helm chart安装应用和升级应用,在k3s集群中,同样可以采用helm来安装部署应用。


下载helm的客户端二进制文件后,放置到/usr/local/bin目录下并赋予可执行权限。执行下面的命令初始化helm客户端:


# k3s kubectl -n kube-system create serviceaccount tillerserviceaccount/tiller created# k3s kubectl create clusterrolebinding tiller \> --clusterrole=cluster-admin \> --serviceaccount=kube-system:tillerclusterrolebinding.rbac.authorization.k8s.io/tiller created# helm init --service-account tiller \> --tiller-image registry.cn-hangzhou.aliyuncs.com/google_containers/tiller:v2.14.3 --skip-refreshCreating /root/.helm Creating /root/.helm/repository Creating /root/.helm/repository/cache Creating /root/.helm/repository/local Creating /root/.helm/plugins Creating /root/.helm/starters Creating /root/.helm/cache/archive Creating /root/.helm/repository/repositories.yaml Adding stable repo with URL: https://kubernetes-charts.storage.googleapis.com Adding local repo with URL: http://127.0.0.1:8879/charts $HELM_HOME has been configured at /root/.helm.
Tiller (the Helm server-side component) has been installed into your Kubernetes Cluster.
Please note: by default, Tiller is deployed with an insecure 'allow unauthenticated users' policy.To prevent this, run `helm init` with the --tiller-tls-verify flag.For more information on securing your installation see: https://docs.helm.sh/using_helm/#securing-your-helm-installation


查看helm信息:


# helm version --shortClient: v2.14.3+g0e7f3b6Server: v2.14.3+g0e7f3b6


可见helm的服务端已经在集群中创建成功了,下面就可以使用helm chart安装应用了。在此我们进行演示:


# helm repo add edge https://xxxx.xxxx.com"edge" has been added to your repositories# helm install edge/iotgatewayNAME: idolized-wombatLAST DEPLOYED: Fri Oct 11 11:26:04 2019NAMESPACE: defaultSTATUS: DEPLOYED...


查看pod的情况:


# k3s kubectl get po -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESiotgateway-6c242 1/1 Running 0 2m42s 10.0.0.201 test01-201 <none> <none>iotgateway-pqsx2 1/1 Running 0 2m38s 10.0.0.202 test02-202 <none> <none>


可见应用已经创建成功。


使用Rancher管理k3s集群


在Rancher上添加一个集群,然后按照步骤将该集群导入到Rancher平台中,可以使用Rancher管理和维护集群:



FAQ


1、在边缘计算中,往往涉及到访问硬件资源,如何从容器内部访问硬件资源?


Linux系统中,所有的硬件资源都体现为/dev/目录下面的一个设备,因此只要能够访问/dev/目录下面的设备文件即可,有的同学会说,那是不是将/dev/目录挂载到容器里面就可以了呢?经过我的实践证明不行,因为挂载到容器里面,即便容器里面是以root用户运行,然是仍旧有可能无法访问一些特殊资源文件,也就是说容器中的“root”用户与宿主机的root用户在访问权限上还是有差别。只需要将容器的运行模式设置为“privileged”即可,如下:

resources: limits: cpu: 300m memory: 512Mi requests: cpu: 50m memory: 256MisecurityContext: privileged: true


2、如何备份集群数据?


k3s集群数据全部存储在/var/lib/rancher下面,在/etc/rancher、/etc/kubernetes下面会存储一些配置文件和证书,因此我们可以周期性备份这几个目录的数据即可。也可以给k3s server节点挂载一个高可靠性的存储设备。


3、节点宕机怎么恢复?


对于agent节点,边缘节点只负责一个小区域的业务,单个节点宕机对整个集群业务影响很有限,只需要重新启动将节点加入集群中即可恢复业务运行。对于server节点,如果有数据备份,可以用数据备份进行恢复(将备份数据放置到对应的目录重新按照原有参数启动server节点服务即可),如果没有备份,那么重新安装一个server节点,更改agent节点的启动参数中的token,重新将agent注册到新的server节点,但是因为集群数据丢失,可能需要重新安装应用,因此尽可能对server节点的数据进行周期性备份并妥善存储保管。


4、k3s是否可以外部存储系统?


当然是可以的,如果涉及到应用必须要访问持久化存储,那么也可以像kubernetes一样给其接入外部存储系统,但是不推荐这么做,因为边缘设备一般比较分散,网络环境也不稳定,外接存储系统会导致性能打折扣,因此建议:

  • 对于必须将数据存储在外部存储上的应用,可以通过nodeSelector限制其到某几个特定的比较可靠稳定的节点上,然后接入外部存储系统;

  • 对于daemonset类型的应用,非关键核心数据可以通过hostPath存储在宿主机系统上


社区QA


Q1:一台阿里云杭州服务器,一台阿里云美国服务器,都有公网IP,如何方便、快捷(并且不购买网络带宽费用)地搭建一个2台服务器的K3S集群?


A:这主要是你自己的路由的问题,pod网络和service网络的一个拉平的问题,涉及到这个路由的跳转是需要你自己去配置的。


Q2:边缘节点的K3S集群可以很方便的被中心节点的K8S集群来管理吗?如何管理?数据如何同步?中心节点需要存放边缘节点的数据吗?边缘节点挂了之后中心节点能拉起或管理吗?现在我们也计划做这方面的工作。我们有多个分公司,想在分公司部署集群,但没有维护人员。还有一个问题就是,现在集群联邦不成熟,也不能很好纳管多个集群做资源调度,这该如何解决?


A:k3s集群和k8s集群是平级的关系,属于多个集群。如果要管理多个集群,我们可以采用像Rancher这样的集群管理平台去管理它,我们公司现在就是这么做的:在阿里云上有一个Rancher的平台,然后管着我们在阿里云平台的业务集群和我们的多个边缘集群。


你的第二个问题是中心节点会存储我整个集群的所有的数据,因此我们应该周期性地对这个中心节点的数据进行备份,而且在未来的版本当中,k3s会支持HA,它是通过实现后端存储,如postgresql、MySQL的一个高可用性保证我们的集群的可靠性的,这个现在已经是实验的特性了,估计在未来很快就会发布了。工作节点挂了的话,可能分两种情况,一种是你这个节点直接不能工作了,还有一种情况点跟我的master节点网络不通了。如果是前一种情况,业务肯定也不能正常工作了;后一种情况的话,其实业务还在正常运行,只不过是不能通过主节点去调度了,但是一旦它恢复通信,所有的都会自动恢复,因为边缘设备的网络不稳定有点难以避免。我们这个集群已经跑了两三个月了,表现一直是很好的。


Q3:k3s可以去哪获取资料?


A:k3s的官网是:https://k3s.io,GitHub的主页是:https://github.com/rancher/k3s,最新开始运营的官方微信公众号是:


Q4:K3s的list-watch请求没有走tunel-proxy吗?


A:k3s的主节点和agent节点之间通信都是走的tunnel通道的。


Q5:除了占用较少资源之外,k3s在使用上和k8s相比还有什么限制和优势?


A:对,因为边缘设备的话都是很小的工,一般都是公用的,工业用的工控机,工控机一般都是一个低压的CPU啊,然后还有一个就是内存比较小。实际上来讲的话我目前没有发现根k8s有太大的区别,基本上在我k8s上部署的应用全部可以部署在我的边缘端。


k3s开发人员补充:

除了占用资源较少外,还支持:

  • 极致简化的安装体验,对比k8s和k3s安装部署就会体会到k3s的安装体验上的优化。

  • 除了etcd外,还是支持sqlite/mysql/pg等数据库,最小可以做两节点的HA。


Q6:k3s的主节点和agent节点之间通信都是走的tunnel通道的。List-watch请求也走tunnel通道的吗,据我看源码,并没有走tunnel,只有logs和exec接口走了tunnel。


A:list-watch就是直接访问kube-apiserver的端口。


Q7:k3s集群直接更改设备IP是否可用,如果不支持更改IP,对于更改IP的需求有什么应对方案?


A:这里分两种情况,在集群部署完成后,如果要更改server节点的IP,那么我们需要重新去将所有的agent节点重新加入到集群中,如果更改agent的节点IP,那么可能导致agent节点对应存储在server节点中的身份凭证失效,也就是需要移除失效的节点,将修改后的节点重新加入,当然这种情况是在同一个子网内的情况,如果跨网段的话,那就会更复杂一些了。


Q8:Rancher管理k3s集群,k3s的master要暴露公网IP吗?


A:server节点不需要暴露公网IP,只需要能从server节点内部访问rancher即可。通过import的形式将k3s集群导入到Rancher中即可管理起来,也可以管理应用和配置。


Q9:k3s server 也支持docker吧?


A:是的,agent节点提供了--docker参数,可以指定它的容器运行时为docker。


Q10:Rancher 可以自己部署、管理自己的 k3s?


A:是的,我们的Rancher是部署在阿里云端,同时管理了我们的中枢业务k8s集群和多个客户的k3s边缘集群。


Q11:运行单个Docker容器来安装Rancher,可以满足管理吗?


A:可以,但是这样可靠性会不好,推荐还是多实例通过负载均衡的形式来部署。


Q12:k3s 支持master高可用吗?


A:暂时还未GA支持,但是已经发布了实验性的版本,通过对k3s集群数据存储的高可用来实现的,我们可以部署高可用的postgresql作为k3s集群的管理节点的数据存储。这个特性应该不久就会GA了。


Q13:边缘资源充足,是否可以直接用k8s?


A:如果边缘设备资源充足的情况下,也可以使用k8s来维护,但是需要考虑的是边缘设备网络的复杂性和不稳定性。


Q14:k3s 启动helm的时候,由于众所周知的原因,经常下载不到镜像,怎么解决呢?


A:官方提供了离线镜像包,大约200MB不到,这个镜像包包含了我们启动server和agent节点所需的所有镜像,能够保证集群自身功能正常。helm 我们可以使用国内的charts源来代替,例如azure的源。


Q15:containerd可以配置morror么?


A:可以配置,但是比较麻烦,docker提供了比较好的人际接口,所以推荐使用docker。


Q16:备份k3s的集群数据,为什么是备份那几个目录而不是备份sqlite的db文件?k3s的server支持类似rke对etcd定期自动备份配置吗?


A:因为还涉及到一些认证文件,譬如agent节点在server端存储有一个身份标记,agent节点的恢复是会判断这些身份的。一旦丢失,重新注册相当于是一个新的节点了。


Q17:不管是基于containerd还是docker,它们都是共享内核的,那么如何做到安全隔离呢?


A:在底层的资源隔离上,还是依赖于系统的各种命名空间,这块建议可以详细研究一下pod的安全策略。


Q18:离线镜像文件是否只要放在images目录即可,文件名并不重要,都可以被识别出来?


A:是的,使用containerd作为runtime时,不需要手动导入,启动时会自动从这里获取镜像,如果使用docker作为运行时,需要手动load镜像,因为国内直接访问不了gcr.io下面的镜像。


Q19:单机版K3S,容器内访问本机的一个服务端口,无法访问,这个问题官方测试过吗?


A:这个可能有很多种情形了,看是否是主机安全策略限制。例如selinux或者iptables规则限制了。


k3s开发人员补充:

简单验证了从容器内访问主机的ssh端口并没有问题。应该是自身的应用有其特殊性,你可以尝试在k8s中确实可以work后,在k3s中部署。 


Q20:centos在边缘设备小内存设备上能装吗?也是有内存限制的吧,最小支持多少?


A:k3s server官方给的需求是512MB就能满足,在我们公司的实际观察中,一般情况下用到200多MB,剩下的就看你部署的应用的资源需求了。另外我们需要保证应用不能把系统资源全部抢占了。


Q21:k8s与k3s在api上使用上有啥具体差别?比如是否支持crd?另外k8s的网络组网方案有flannel和calico,k3是怎么组网的?


A:K3s默认使用的是flannel网络,也支持手动指定其他的CNI,都是比较灵活的配置。


Q22:IoT client设备没有固定公网ip下如何进行部署?需要自行组网吗?


A:这里是一个大家都会遇到的问题,一般来说,IOT设备都是客户内网的,不可能给你在防火墙上打洞,我们现在是自己开发了一套系统,只用来偶尔维护边缘设备的后台,类似ssh反向代理就可以实现。


Q23:边缘设备是怎么被监控的,有的什么方案呢?是否也有监控的实时界面?


A:我们可以考虑采取prometheus pushgateway的形式来在边缘内网部署监控代理,然后再介入到统一的监控平台。


Q24:内网环境(可通过代理上网),需要为containerd配制代理吗?还是containerd可以识别主机的代理配制?如果需要配制的话应该如何配制?


A:如果是全局代理的话,应该是支持的。


Q25:k3s跟k8s的迭代关系是什么,每发布新版k8s,k3s都要修剪出相应的版本,还是增量开发?用k3s需不需要定期升级?


A:我们一直在持续关注相关release notes,当有重大新特性和安全问题、功能Bug修复时我们会考虑升级版本。


k3s开发人员补充:

每次k8s发版后都会修建对应的k3s版本。你如果很在意k8s的安全更新,你可以升级k3s,否则如果业务已经稳定适用,可不必太过频繁升级。


Q26:我尝试给containerd配了代理,单独安装的containerd可以拉镜像,但是k3s内嵌的containerd确一直没法拉镜像。这个应该怎么解决?


A:不确定你在k3s的containerd中如何配置的,k3s的containerd中的配置文件会被重置,你需要以模版方式配置

https://rancher.com/docs/k3s/latest/en/configuration/#containerd-and-docker

详细问题可以提issue到k3s来讨论:

https://github.com/rancher/k3s


文档下载


公众号后台(不是小助手)回复“1107技术分享”,即可获取技术分享的PDF文档下载链接~


推荐阅读

Kubernetes行业调研报告:多集群、多云部署成企业首选策略

K8s 还是 k3s?This is a question

kubectl+HPA!提升K8S容器资源利用的关键解决方案

About Rancher Labs


Rancher Labs由CloudStack之父梁胜创建。旗舰产品Rancher是一个开源的企业级Kubernetes管理平台,实现了Kubernetes集群在混合云+本地数据中心的集中部署与管理。Rancher一向因操作体验的直观、极简备受用户青睐,被Forrester评为2018年全球容器管理平台领导厂商,被Gartner评为2017年全球最酷的云基础设施供应商。


目前Rancher在全球拥有超过一亿的下载量,并拥有包括中国人寿、华为、中国平安、兴业银行、民生银行、平安证券、海航科技、厦门航空、上汽集团、海尔、米其林、丰田、本田、中船重工、中联重科、迪斯尼、IBM、Cisco、Nvidia、辉瑞制药、西门子、CCTV、中国联通等全球著名企业在内的共27000家企业客户。

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存