LOADING

Follow me

【转载】K8S 弹药库 |一键部署 Kubernetes1.6 高可用集群
四月 28, 2017|DockerPaaS

【转载】K8S 弹药库 |一键部署 Kubernetes1.6 高可用集群

【转载】K8S 弹药库 |一键部署 Kubernetes1.6 高可用集群

K8S 弹药库 |一键部署 Kubernetes1.6 高可用集群

本文适合于有一定 K8S 基础的人,通过本文你将学到:

  • K8S 各组件的交互原理

  • K8S 的集群规划

  • K8S 系统配置,各组件主要启动参数含义

  • K8S 部署过程可能出现的问题及解决方案

  • Ansible 基本知识

本文大概

3500

读完共需

10

分钟

背 景

Kubernetes 是 Google 开源的容器编排框架,也是最流行的容器编排框架之一,以下简称 K8S。部署一个 K8S 集群,特别是一个高可用的 K8S 集群,往往需要费非常多的时间和精力。

当前关于 K8S 部署的文章绝大部分是单 Master 的部署,满足不了高可用的需求,本文将为您介绍平安云使用多 Master 的部署方案来保证 K8S控制节点高可靠的实操案例。

考虑到当前文章大多介绍的比较简单,只是罗列了安装步骤,对集群规划、组件交互原理、遇到的问题及优化的手段等介绍的较少。本文会通过介绍使用二进制部署 K8S 集群的步骤、各组件的启动参数、含义、可能遇到的问题以及简单介绍系统各组件的交互原理,来帮助大家理解和解决实际问题。

后面会有一系列的文章来介绍 K8S 概念原理和生产实践。那些日子开过的路段,踩过的坑,都会毫无保留的分享。

这是 Kubernetes 实践系列的第一篇:一键部署 kubernetes 1.6 高可用集群

集 群 详 情

实际生产实践中,按照系统设计的流程,我们一般会先确定系统的逻辑架构图,系统组件的调用关系图,根据架构图确定需要多少机器资源,需要开通什么样的防火墙策略。另外在部署之前需要考虑集群的规划,比如需要什么样的网段,每台主机需要管理多少容器,支撑多少应用。

架构图


放一张官方的高可用逻辑部署图。我们会按照这个部署图来构建整个 K8S 集群。

K8S 弹药库 |一键部署 Kubernetes1.6 高可用集群

另外放一张 K8S 各组件之间交互调用的原理图,有助于大家理解每个组件的启动参数和防火墙策略的设定。

K8S 弹药库 |一键部署 Kubernetes1.6 高可用集群


软件版本

组件或系统

版本

Kubernetes

1.6.0

1.6版本支持单集群5000节点, 15万容器(官方数据)

Docker

1.12.3

需要系统内核版本3.10以上支持

Etcd

3.1.5

Etcd3的性能优于etcd2,k8s1.6版本使用etcd3做为状态存储组件。

Flanneld

0.7

backend为vxlan网络,需要系统内核版本3.7以上支持

CentOS

7.2

建议系统内核3.10及以上

机器配置

下面的配置是 POC 环境的机器配置情况。实际生产部署可以选择更好的机器,目前没有最优建议,可以根据成本预算和使用应用承载量而定。

组件

机器配置

ETCD

建议4核CPU, 4G内存及以上配置, 3台

可以和k8s master组件共用机器混合部署,如果机器资源充足,建议分开部署

K8S Master

建议4核CPU, 4G内存及以上配置, 3台

同上建议

LoadBalance

建议4核CPU, 4G内存及以上配置, 2台

主备,注意这个不要和master,node组件混合部署,影响稳定性和可用性

Node

4核CPU, 4G内存, 1台以上

配置需求与运行的容器数量和应用类型相关

如果 K8S 不是在一个扁平的大二层网络里,如果跨了多个网段,且网段之间有防火墙隔离,那么还需要考虑防火墙问题(以下不考虑加密传输的情况下,且使用默认启用的端口, 如果你修改了默认的端口,那么相应的修改防火墙即可)


source

destination

port

kubelet/kube-proxy

api server

8080

controller-manager/scheduler

api server

8080

api server

etcd

2379

dockerd

docker  registry

5000

flanneld

etcd

2379

flanneld

flanneld

8285

集群规划

网络和端口规划,以下针对的是单个 K8S 集群的情况

注解

配置

FLANNEL_NET

flannel的网段

192.168.0.0/16

注意不要和现有的网段规划冲突,另外此处掩码为26,意味着支持2^(26-16),约1024个node节点

FLANNEL_SUBNETLEN

flannel的子网掩码

26

掩码26,意味着单个主机可以最多分配2^(32-26) -2 ,约62个容器

SERVICE_CLUSTER_IP_RANGE

service 的 ip 网段

10.10.1.0/22

假设每个应用占用1个service ip,则可以支持约2^(32-22) -2 ,约1022个应用部署

NODE_PORT_RANGE

node port的端口范围

30000 ~ 32767

service的node port 可以使用主机上2767个端口

部 署 详 情

整个部署中,所有 K8S 的组件都用了编译好的二进制包进行安装,启动参数都写在单独的配置文件里。 进程使用 Systemd 管理, 且加入开机自启动, 同时增加一个 Crontab 任务,定时启动进程,确保进程在挂掉时能够及时拉起。Ansible 用来做任务编排。接下来会对 Ansible 做一个简单的介绍,每个组件具体用到的启动参数和注意事项也会简要说明。

Ansible 介绍

整个 K8S 集群的部署是用 Ansible 进行任务编排的。这里简单介绍下 Ansible,更加详细的 Ansible 介绍可以参考 Ansible 文档。


架构图

K8S 弹药库 |一键部署 Kubernetes1.6 高可用集群


基本概念

  • ansible core:ansible自身核心模块

  • host inventory:主机库,定义可管控的主机列表

  • connection plugins:连接插件,一般默认基于ssh协议连接

  • modules:core modules(自带模块)、custom modules(自定义模块)

  • playbooks:剧本,按照所设定编排的顺序执行完成安排任务

  • files/:此角色中用到的所有文件均放置于此目录中

  • templates/:Jinja2模板文件存放位置

  • tasks/:任务列表文件;可以有多个,但至少有一个叫做main.yml的文件

  • handlers/:处理器列表文件;可以有多个,但至少有一个叫做main.yml的文件

  • vars/:变量字典文件;可以有多个,但至少有一个叫做main.yml的文件

  • meta/:此角色的特殊设定及依赖关系;


常用命令

  • ansible-playbook -i hosts site.yml –list-hosts   列出要被执行任务的远程主机,不执行任务

  • ansible-playbook -i hosts site.yml–list-tasks   列出要执行的任务,不执行任务

  • ansible-playbook -i hosts site.yml–syntax-check   进行语法检查,不执行任务

  • ansible-playbook -i hosts site.yml    执行任务


任务优化

  • 增加失败重试

  • 增加失败检查,比如etcd部署失败,则任务退出,不再进行接下去的部署

  • 执行操作前会先对旧的配置进行备份,方便出错时回滚配置。

部署流程

1.  etcd 集群搭建

2.   loadbalance主备搭建

3.   k8s master cluster 搭建

4.   k8s node 部署

5.   给node机器打label

6.   dns 插件部署

7.   dashboard插件部署

8.   部署ingress controller插件

9.   部署efk插件

ps:因为公司有一套完整的 es 集群, docker registry 私有仓库和监控系统,所以在部署中没有再额外构建这些环境。不过以后会根据需要在部署过程中加入这些组件的构建。

ETCD 集群

默认搭建一个有3个节点的 ETCD 集群

启动参数

参数说明

ETCD_NAME

节点名称

ETCD_DATA_DIRS

指定节点的数据存储目录,这些数据包括节点ID,集群ID,集群初始化配置,Snapshot文件等

ETCD_LISTEN_PEER_URLS

监听URL,用于与其他节点通讯

ETCD_INITIAL_ADVERTISE_PEER_URLS

告知集群其他节点url

ETCD_INITIAL_CLUSTER

集群中所有节点

ETCD_INITIAL_CLUSTER_STATE

初始化集群状态

ETCD_INITIAL_CLUSTER_TOKEN

集群的ID

ETCD_ADVERTISE_CLIENT_URLS

告知客户端url, 也就是服务的url

Tips建议和提示

ETCD_NAME=master01ETCD_INITIAL_CLUSTER=”master01=http://1.1.1.1:2380,master02=http://2.2.2.2:2380,master03=http://3.3.3.3:2380″这里ETCD_NAME和ETCD_INITIAL_CLUSTER对应的name要一致,否则可能会启动失败。


Master 节点

部署考虑了 Master组件的高可用, 由三个节点构成一个集群。Apiserver是无状态的,前端提供负载均衡,暴露 Vipcontroller Manager 和 Mcheduler 是有状态的,需要进行Leader elect,同一时间只能有一个实例对集群信息进行读写。

组件名

参数

参数

api server

–etcd-servers

以逗号分隔的etcd服务url列表, etcd服以http://ip:port格式表示

api server

–insecure-bind-address 

绑定不安全的ip地址,默认且localhost,设置为0.0.0.0就可以侦听所有网络接口

api server

–insecure-port

提供非安全认证的监控端口,默认为8080

api server

–kubelet-port 

kubelet侦听的端口

api server

–service-node-port-range 

Service的node port 能使用的主机端口范,默认为30000 ~ 32767,包括30000和32767

api server

–allow-privileged

允许pod允许具有系统特权的容器,默认值为false

api server

–service-cluster-ip-range  

service的cluster ip (虚拟ip)池,这个不能和集群所在物理网络重合

controller manager / scheduler

–master

api server的url地址

controller manager / scheduler

–leader-elect 

设置为true时,表示进行leader选举,一般用于master的高可用部署,默认值是false

controller manager / scheduler

–leader-elect-lease-duration

leader选举过程中非leader等待选举的时间间隔,默认为15秒

controller manager / scheduler

–leader-elect-renew-deadline

leader选举过程中在定制leading角色之前再次renew的时间间隔,应小于等于eader-elect-lease-duration,默认为10秒

controller manager / scheduler

–leader-elect-retry-period 

leader选举过程中,获取leader角色和renew之间的等待时间,默认为2秒


Tips建议和提示

Controller manager 和 Scheduler 的启动参数一致,将 –leader-elect 设置为true,其它 elect 参数保持默认即可。

Node节点

组件名

参数

参数

kubelet

–addresss   

绑定主机的地址,默认为0.0.0.0,表示使用主机上的所有网络接口

kubelet

–port   

进程侦听的端口

kubelet

–api-servers

api server地址列表,以ip:port 格式表示,以逗号分隔

kubelet

–allow-privileged 

是否允许以特权模式启动容器,默认是false

kubelet

–cluster_dns 

集群内dns服务的ip地址

kubelet

–cluster_domain

集群内dns服务所用域名

kubelet

–pod_infra_container_image

用于pod内网络命名空间共享的基础的pause镜像, 默认值为gcr.io/google_containers/pause-amd64:3.0

kube-proxy

–master

api server的url地址

flannel

-etcd-endpoints

以逗号分隔的etcd服务url列表, etcd服务以http://ip:port格式表示

flannel

-etcd-prefix 

etcd的前缀,默认是/coreos.com/network

docker

–insecure-registry 

设置私有仓库url地址

docker

 –bip  

绑定的bridge网卡地址

docker

–ip-masq 

启用ip伪装技术,一般用于NAT ,默认为false

docker

–mtu 

网络包的大小,默认为 1450

Tips建议和提示

pause 镜像默认是从 gcr.io上 拉取的,但是由于 gfw 的缘故,国内无法正常下载。

可以通过–pod_infra_container_image 指定私有仓库或者可以访问的仓库镜像地址,让 K8S 到这些仓库去下载,而不是从 gcr.io 如果集群中有的 Node 节点位于非 dmz 区域,有的 Node 节点位于 dmz 网络区域, 那么 dmz 区的 Docker 启动的时候一定要设置–ip-masq 为 true,同时 Flanneld 启动的时候要指定 -public-ip 为nat转换后的 ip,否则无法和非 dmz 区的 Docker 容器正常通信,具体原理涉及 Flannel 和 Vxlan 网络原理,限于篇幅,不在这里赘述。

相关插件

使用的相关插件有nginx ingress controller, Kubernetes dashboard, kubedns, fluentd ,都是使用 K8S 的方式进行编排,启动并加载


插件名称

kubedns

启动1个replication  controller,副本数为1, pod里包含了三个container,分别为kube-dns, kube-dnsmasq,  exechalhz,此外还会启动一个service,注意在kube-dns容器的启动参数中指定–kube-master-url

nginx ingress controller

动2个replication  controller ,分别为default-http-backend  和 nginx ingress controller,启动一个service。注意在ginx ingress  controller容器的启动过程设置环境变量  KUBERNETES_MASTER, 指定api server的url 及端口

kubernetes dashboard

启动一个 replication  controller, 一个service, 一个ingress,注意在kubernetes-dashboard容器的启动参数中指定–apiserver-host

fluentd

启动一个daemonset,一个configmap,通过挂载configmap的方式可以修改fluent.conf


Tips建议和提示

根据插件互相之间的依赖关系,可以确定插件的加载顺序是 kubedns -> nginx ingress controller-> kubernetes dashboard / fluentd/…外部下载镜像会遇到墙的问题。可以通过灵雀云 http://www.alauda.cn/ 的镜像中心来构建或者拉取被墙的镜像,限于篇幅,具体实现方法在这里不赘述。

优 化 和 改 进

由于时间匆忙,本人水平又有限,也有一些需要改进和完善地方。如:

  • 增加prometheus+grafana插件

  • 增加私有的docker registry或harbor插件

  • 增加安全相关配置, 如 TLS 认证通信(所有组件,如 etcd、Kubernetes Mmaster 和 Node) ,RBAC 授权等

  •  Docker 的后端存储修改为 overlayfs 或者 devicemapper 的 direct-lvm 模式,以提高性能

  • Ansible playbook 增加回滚步骤,可以进行一键回滚

  •  针对负载均衡 vip 和 vrid 是否占用的自动检测,防止网络冲突,导致 loadbalance 无法正常启用

  • etcd 前面暴露 vip、 flannel、 api-server 连接时使用vip进行连接

  •  Ansible 每个task都进行检查,以校验是否成功

  • 调整 kubelet 的日志级别,防止日志量过大,撑爆磁盘

  • 除Docker, kubelet 之外,其它组件全部用  K8S static pod的方式实现

  •  提供 Web 界面,提供部署,动态修改参数等功能

总 结

Kubernetes 集群的整个部署过程是比较复杂的,涉及的知识栈也比较多,特别是在出现问题的时候,需要查阅大量的资料,包括源码。

另外值得一提的是, Ansible 是一个非常棒的自动化工具。我们使用 Ansible 来编排自动化部署的任务,提高部署效率。原来3天甚至1个星期的部署工作,现在用半个小时的时间就可以部署一套功能相对完备的,高可靠的 K8S 集群。

限于篇幅有限,有些细节可能叙述得不是很清楚。如有谬误的地方,也恳请指出。附上我的个人公众号,欢迎关注和交流。

本文转载自公众号“云时代的运维开发”。K8S 弹药库 |一键部署 Kubernetes1.6 高可用集群

no comments
Share

发表评论