简介

Kubernetes,k8s,go语言开发,Google开源容器集群管理系统,构建于docker技术之上,用于管理容器部署,维护和扩张,提供资源调度、部署运行、服务发现、扩容缩容等整一套功能。当前k8s支持GCE、vShpere、CoreOS、OpenShift、Azure等平台,也可以直接运行在物理机上。

功能

  • 使用Docker对应用程序包装(package)、实例化(instantiate)、运行(run)。
  • 以集群的方式运行、管理跨机器的容器。
  • 解决Docker跨机器容器之间的通讯问题。
  • Kubernetes的自我修复机制使得容器集群总是运行在用户期望的状态。
  • 应用的高可用和靠扩展
  • 支持应用的在线升级(Rolling Update)
  • 支持跨云平台(IaaS)的部署

功能

服务部署

服务部署是最基本的容器管理功能,依靠容易编写的yaml或者json。多个组件可用一个文件,灵活性很高。

版本管理

借助rs的概念,k8s可以在不停止业务的情况下对应用进行滚动升级和回滚。

资源管理

kubelet可以采集宿主机的资源并汇报给k8s,使得k8s可以拿到集群中的资源情况,同时借助于Docker的资源限制,k8s实现从用户层到部署层到应用层多个层级的资源限制,非常方便。
在进行服务部署时,k8s也能根据各个节点自身的资源情况完成分配。

负载可扩展性

应用程序打包成微服务部署在k8s上 。这些微服务是由多个容器分组成pods。每个容器的设计只执行一个任务。pod可以由无状态容器或状态容器组成。无状态的pod可以轻易按比例要求扩展或通过动态自动扩展。k8s 1.4支持平行pod自动扩展,即可以基于CPU自动扩展RC中pods数量。未来的版本将通过定义自动扩展原则,支持用户量度和阈值。
谷歌云托管Kubernetes运行支持集群自动扩展。当在所有可用的节点pods扩展,Kubernetes协同底层基础设施向集群添加节点。
一个应用程序架构是微服务架构,以容器封装部署为pods,可以利用Kubernetes的极端的扩展功能。虽然这主要是适用于无状态的pods, Kubernetes通过pet sets增加支持持久化工作负载,如:NoSQL数据库与关系数据库管理系统(RDBMS);同时将能扩展无状态的应用,如:Cassandra集群和MongoDB副本集。这种能力将使弹性的、无状态的Web层和持久的、有状态的数据库共同运行在相同的基础设施上。

可兼容性

k8s集群可以安装在各种主流Linux系统上,包括本地开发机,云平台如AWS,Azure和谷歌云;基于KVM的虚拟环境,vSphere和libvirt;及裸机。用户可以启动Docker或rkt,未来新的容器运行时的容器。
通过fedreation,可以混合匹配集群,使之运行在跨多云提供商和私有部署 。这将给容器化的工作负载带来混合云能力。客户可以无缝移动工作负载从一个部署目标转移到另一个部署目标。

安全

k8s的安全性可以通过多层次的配置。API接口通过传输层安全TLS,确保用户使用最安全的机制认证。k8s集群有两类用户-服务账户直接由k8s管理的,普通用户认为是由一个独立的服务管理。服务帐户由API服务器自动创建的k8s API管理的。管理集群内运行的进程的每一个操作必须由已验证的用户启动;该机制确保集群的安全性。
部署k8s集群内应用,可以利用secret的概念来安全地访问数据。secret包含少量的敏感数据,如密码、令牌或密钥,从而减少意外的数据暴露的风险。敏感信息以base64编码存储一个k8s集群内。在运行时pods通过安装的卷或环境变量可以访问secret。secret对同一集群命名空间的所有用户都可用。
通过部署网络策略限制pods的网络流量。k8s的网络策略是规范pods选择如何相互通信以及与其他网络的通信。这对于在多层部署中不暴露于其他应用程序的pods是非常有用的。

网络连通

使用Flannel来解决网络问题只是一种方式,并不是唯一的方式。Flannel最大的特点是对业务的简洁,在使用Flannel之后,不同主机的不同镜像之间可以通过IP直接通信。
同时,为了对这些IP进行管理,k8s的DNS模块还对Pod名字,Service名字做IP映射,业务上使用起来非常方便。
问题是性能会不太好,毕竟在宿主机上cURL一个远端的IP,需要经过Route规则、iptables、Flannel虚拟网卡、封包、传包、宿主机网卡、Flannel虚拟网卡、解包、Route规则,Docker虚拟网卡才能进到目的地,不过究竟有多差还没有测试。

服务高可用

k8s内置rs(复制集)的概念,在rs中的实例数量指定后,k8s会尽力保证实例的数量,如果出现节点挂掉或者容器挂掉的情况,rs会使用重启或者选择的节点启动新服务的方式,保证正常实例的数量。
因为etcd本身可以做成集群,k8s的master节点也做加锁操作,自身的高可用可以通过配置多个主节点加一个LB比较方便地实现。
一个配置良好的k8s集群从管理服务到应用服务都避免单点的存在,实现服务的高可用。

当代工作负载要求在基础设施和应用水平上。在扩展集群中,一切都容易失败,这使得生产负载的高可用性严格必要。更多的容器编排引擎和PaaS提供实现应用程序的可用性, Kubernetes是设计用来解决基础设施和应用程序的可用性。
在应用方面,Kubernetes通过replica sets,replication controllers和pet sets确保应用程序的高可用。运维能定义在某个指定时间点的最小pods数。如果容器和pod因为错误崩溃,预设策略能回到预定的配置部署。有状态负载通过pet sets能被配置成高可用的。
对于基础设施的可用性,Kubernetes已经支持大范围的分布式文件系统的存储:如NFS和GlusterFS,块存储设备如Amazon EBS和谷歌计算引擎persistent disk,专业容器存储插件如:Flocker。通过增加一个可靠的可用的存储层,Kubernetes保证有状态的工作负载的高可用性。
Kubernetes集群的每个组件-etcd, API服务器,节点–可配置成高可用。通过负载均衡器和健康检查确保应用程序的高可用。

架构

kubernetes基础入门总结_高可用


Kubernets属于主从的分布式集群架构,包含Master和Node:

Master作为控制节点,暴露API,调度部署和管理整个集群。Master定义k8s集群Master/API Server的主要声明,包括Pod Registry、Controller Registry、Service Registry、Endpoint Registry、Minion Registry、Binding Registry、RESTStorage以及Client,是client(Kubecfg)调用k8s API,管理k8s主要构件Pods、Services、Minions、容器的入口。Master由API Server、Scheduler以及Registry等组成。Master的工作流主要分以下步骤:

  1. Kubecfg将特定的请求,比如创建Pod,发送给Kubernetes Client。
  2. k8s Client将请求发送给API server。
  3. API Server根据请求的类型,比如创建Pod时storage类型是pods,然后依此选择何种REST Storage API对请求作出处理。
  4. REST Storage API对的请求作相应的处理。
  5. 将处理的结果存入高可用键值存储系统Etcd中。
  6. 在API Server响应Kubecfg的请求后,Scheduler会根据Kubernetes Client获取集群中运行Pod及Minion信息。
  7. 依据从k8s Client获取的信息,Scheduler将未分发的Pod分发到可用的Minion节点上。

包含以下组件:

  • API Server作为k8s系统的入口,封装核心对象的增删改查操作,以RESTFul接口方式提供给外部客户和内部组件调用。它维护的REST对象将持久化到etcd(一个分布式强一致性的key/value存储)。
  • Scheduler:负责集群的资源调度,为新建的pod分配机器。这部分工作分出来变成一个组件,意味着可以很方便地替换成其他的调度器。Scheduler收集和分析当前k8s集群中所有Minion节点的资源(内存、CPU)负载情况,然后依次分发新建的Pod到k8s集群中可用的节点。由于一旦Minion节点的资源被分配给Pod,那这些资源就不能再分配给其他Pod, 除非这些Pod被删除或者退出, 因此,k8s需要分析集群中所有Minion的资源使用情况,保证分发的工作负载不会超出当前该Minion节点的可用资源范围。具体来说,Scheduler做以下工作:
  1. 实时监测k8s集群中未分发的Pod。
  2. 实时监测k8s集群中所有运行的Pod,Scheduler需要根据这些Pod的资源状况安全地将未分发的Pod分发到指定的Minion节点上。
  3. Scheduler也监测Minion节点信息,由于会频繁查找Minion节点,Scheduler会缓存一份最新的信息在本地。
  4. Scheduler在分发Pod到指定的Minion节点后,会把Pod相关的信息Binding写回API Server。
  • Controller Manager:负责执行各种控制器,目前有两类:Endpoint Controller:定期关联service和pod(关联信息由endpoint对象维护),保证service到pod的映射总是最新的。
  • Replication Controller:定期关联replicationController和pod,保证replicationController定义的复制数量与实际运行pod的数量总是一致的。

Node是运行节点,运行业务容器,包含以下组件:

  • Kubelet:Kubelet的主要工作是管理Pod和容器的生命周期,其包括Docker Client、Root Directory、Pod Workers、Etcd Client、Cadvisor Client以及Health Checker组件。负责管控docker容器,如启动/停止、监控运行状态等。它会定期从etcd获取分配到本机的pod,并根据pod信息启动或停止相应的容器。同时接收apiServer的HTTP请求,汇报pod的运行状态。Kubelet是k8s集群中每个Minion和Master API Server的连接点,Kubelet运行在每个Minion上,接收Master API Server分配给它的commands和work,与持久性键值存储etcd、file、server和http进行交互,读取配置信息。具体工作如下:
  1. 通过Worker给Pod异步运行特定的Action。
  2. 设置容器的环境变量。
  3. 给容器绑定Volume。
  4. 给容器绑定Port。
  5. 根据指定的Pod运行一个单一容器。
  6. 杀死容器。
  7. 给指定的Pod创建network 容器。
  8. 删除Pod的所有容器。
  9. 同步Pod的状态。
  10. 从Cadvisor获取container info、 pod info、root info、machine info。
  11. 检测Pod的容器健康状态信息。
  12. 在容器中运行命令。
  • Kube Proxy:负责为pod提供代理。它会定期从etcd获取所有的service,并根据service信息创建代理。当某个客户pod要访问其他pod时,访问请求会经过本机proxy做转发。

Kubernets使用Etcd作为存储和通信中间件,实现Master和Node的一致性,这是目前比较常见的做法,典型的SOA架构,解耦Master和Node。

基本概念

Pod

Pod是Kubernetes的基本操作单元,把相关的一个或多个容器构成一个Pod,通常Pod里的容器运行相同的应用。Pod包含的容器运行在同一个Node(Host)上,看作一个统一管理单元,共享相同的volumes和network namespace/IP和Port空间。

Replica sets

通过始终维护一组预定义的pods,提供所需的规模和可用性。单个pod或replica set能通过services暴露给内部或外部消费者。services通过特定的标准将一组Pods关联来实现对pods的发现。通过键值对的标签和选择器来关联pods,任何与标签匹配的新pod将自动被服务发现。

Replication Controller

RC确保任何时候k8s集群中有指定数量的pod副本(replicas)在运行, 如果少于指定数量的pod副本(replicas),RC会启动新的Container,反之会杀死多余的以保证数量不变。RC使用预先定义的pod模板创建pods,一旦创建成功,pod 模板和创建的pods没有任何关联,可以修改pod模板而不会对已创建pods有任何影响,也可以直接更新通过RC创建的pods。对于利用pod 模板创建的pods,RC根据label selector来关联,通过修改pods的label可以删除对应的pods。RC主要有如下用法:

  1. Rescheduling
    RC会确保k8s集群中指定的pod副本在运行, 即使在节点出错时;
  2. Scaling
    通过修改RC的副本数量来水平扩展或者缩小运行的pods;
  3. Rolling updates
    RC的设计原则使得可以一个一个地替换pods来rolling updates服务;
  4. Multiple release tracks
    如果需要在系统中运行multiple release的服务,RC使用labels来区分multiple release tracks。

Service

也是k8s的基本操作单元,是真实应用服务的抽象,每一个服务后面都有很多对应的容器来支持,通过Proxy的port和服务selector决定服务请求传递给后端提供服务的容器,对外表现为一个单一访问接口,外部不需要了解后端如何运行,这给扩展或维护后端带来很大的好处。

Label

Label是用于区分Pod、Service、RC的key/value键值对,Pod、Service、 RC可以有多个label,但是每个label的key只能对应一个value。Labels是Service和RC运行的基础,为了将访问Service的请求转发给后端提供服务的多个容器,正是通过标识容器的labels来选择正确的容器。同样RC也使用labels来管理通过pod 模板创建的一组容器,这样RC可以更加容易,方便地管理多个容器,无论有多少容器。

secret

ConfigMap

Job

PetSet

StatefulSet

ingress

常用命令

kubectl get all --all-namespaces
kubectl get all --all-namespaces --show-all -o wide
kubectl get ns
kubectl get pods/pod/ing/rc/rs/svc/ns -n core
kubectl get pods -n=<namespace>
kubectl exec -it <pod_id> -n=<namespace> /bin/bash
kubectl exec -it <pod_id> -n=<namespace> bash
kubectl create -f *.yaml
kubectl delete -f *.json
kubectl logs idm-2958378241-nsqq3 -n core -c idm

dashboard

Kube dashboard是 kube 1.2版本中新增的,具备与 kubelet commandline 类似的功能,允许用户通过一种新方式与kubernetes集群交互。
可以进行增删改查:

  • 增:新建(上传json或yaml的),等同于 ​​kubectl create -f​
  • 删:删除副本(replicationControllers)
  • 改:修改副本数
  • 查:查询相关信息,同 ​​kubectl get​​ 命令