容器技术(六):K8S容器编排基础

您所在的位置:网站首页 怎么加入相关微信群 容器技术(六):K8S容器编排基础

容器技术(六):K8S容器编排基础

2024-07-18 04:15:59| 来源: 网络整理| 查看: 265

K8S是如何实现容器编排的?本文介绍了K8S的基本架构,常见的资源对象,让读者能够理解K8S容器编排的基本原理。

K8S基本架构

目前主流的集群资源管理与使用框架大多都是主从(Master/Worker)模式,即一个Master管理一堆Worker去执行任务,对使用者屏蔽集群中结点之前相互通信的复杂细节,可以使用户像操作单机一样去操控整个集群。

K8S也不例外,在K8S中由master负责集群中应用的调度、更新、扩缩容等操作。 K8S中的执行角色为Node,一个Node一般是一个虚拟机或物理机,它上面事先运行着 docker 服务和 kubelet 服务( Kubernetes 的一个组件), 当接收到 master 下发的"任务"后,Node 就要去完成任务(用 docker 运行一个指定的应用)。

Master 上的主要组件有:

apiserver:提供了集群资源操作的统一接口,它通过与每个节点上的kubelet组件通信来控制节点的运行。kubectl客户端也是通过与apiserver交互来操作集群资源的。此外它还提供了认证、授权、访问控制、API注册和发现等机制。scheduler:负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上,比如运维通过kubectl客户端命令根据推荐算法的Deployment配置文件与镜像启动100个Pod,master接受到请求后,scheduler就会根据每个节点的负载信息,决定将这100个Pod分配到哪些节点。controller manager:master上运行着很多控制器,如节点控制器、副本控制器、端点控制器等,用于故障检测、自动扩展、滚动更新等以保证集群的稳定运行,controller manager为这些控制器提供了一个统一的运行组件

跟master密切相关的还有两个组件

etcd:它是一个高性能的分布式数据库,master用它来存储所有node上报的状态信息,实际也可以用其它DB代替。kubectl:它是一个客户端工具,运维通过它可以使用命shell命令来操作K8S集群资源。

每个Node主要包含下列一些组件

kubelet负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理,它会周期性的向apiserver上报节点信息,使得master可以得知每个节点状态,合理的操作每一个节点。kube-proxy负责为Service提供cluster内部的服务发现和负载均衡,使得可以通过Service的name来访问服务。针对不在同一个节点的pod之间的通信,需要在本地配置路由转发信息,将pod之间的通信转为节点之间的通信,这些配置信息也是由kube-proxy来维护。

Kubernetes有一个基于web的用户界面,它可以图表化显示当前集群状态。

K8S网络模型三种IP

在K8S的网络中主要会涉及三种IP:

Node IP:容器宿主机也就是节点的ip,由路由器分配。Pod IP:K8s在每个Node里虚拟出的局域网,为Node上每个Pod分配一个IP,且同一宿主机下Pod位于相同网段,该地址是实际存在于某个网卡(可以是虚拟设备)上的。Service Cluster IP:由k8s分配给每个service的全局唯一的虚拟ip(VIP),service一般包含若干Pod,可以理解为这些Pod的反向代理。其原理是由kube-proxy通过Iptables规则重新定向到其本地端口,再均衡到后端Pod的。但VIP没有挂接到网络设备,外部不能直接访问。设计原则

每个Pod都拥有一个独立的IP地址(IPper Pod),而且假定所有的pod都在一个可以直接连通的、扁平的网络空间中,无论这些Pod是否位于同一个宿主机。并且所有容器之间都是以非NAT(网络地址转换)的方式通信的,即容器的真实地址与看到的地址一致。

Linux网络名词基础网络的命名空间(namespace):Linux在网络栈中引入网络命名空间,将独立的网络协议栈隔离到不同的命令空间中,彼此间无法通信;docker利用这一特性,实现不容器间的网络隔离。Veth设备对:Veth设备对的引入是为了实现在不同网络命名空间的通信。Iptables/Netfilter:Netfilter负责在内核中执行各种挂接的规则(过滤、修改、丢弃等),运行在内核模式中;Iptables模式是在用户模式下运行的进程,负责协助维护内核中Netfilter的各种规则表;通过二者的配合来实现整个Linux网络协议栈中灵活的数据包处理机制。网桥:网桥是一个二层网络设备,通过网桥可以将linux支持的不同的端口连接起来,并实现类似交换机那样的多对多的通信。路由:Linux系统包含一个完整的路由功能,当IP层在处理数据发送或转发的时候,会使用路由表来决定发往哪里。同一Pod内容器间通信

同一Pod内的容器共享同一个网络命名空间,它们之间的访问可以用localhost地址 + 容器端口就可以访问。

同一Node中Pod之间的通信

同一Node中Pod的默认路由都是docker0的地址,由于它们关联在同一个docker0网桥上,地址网段相同,所有它们之间应当是能直接通信的。

不同Node中Pod间通信

不同Node中Pod间通信要满足2个条件: Pod的IP不能冲突; 将Pod的IP和所在的Node的IP关联起来。通过Node IP网络的转发,从而可以让Pod之间可以互相访问。这种转发时通过iptables实现的。

Service服务的暴露方式

在K8S中,服务一般时以Service的形式对外服务的,它是一组Pod的服务抽象,相当于一组Pod的代理或负载均衡器(Load Balancer),负责将请求分发给某个具体的Pod去处理;Service可以通过IP或域名的方式被其他应用访问,具体暴露方式有四种。

Cluster IP:默认采用的是这种方式,仅限于集群内部访问,外部访问。IP可以自己手动指定,不指定的话服务启动时系统会动态分配。spec: clusterIP: 10.0.0.1 ports: - name: httpNodePort:建立在Cluster IP类型之上,将服务暴露到所有节点的指定端口,访问任意一个node ip加端口号都可以访问到(前提没有指定node调度策略)服务,可以通过apiserver的配置文件查看端口暴露范围,类似于Docker Swarm中的Routing Mesh。这种模式K8S依然会为service分配集群IP地址,并将此作为NodePort的路由目标。配置示例如下,targetPort即为对外暴露的端口。apiVersion: v1 kind: Service metadata: name: test-nodportsvc spec: type: NodePort selector: app: test-deploy ports: - protocol: TCP port: 80 targetPort: 80LoadBalancer:建立在NodePort类型之上,其通过cloud provider提供的负载均衡器将服务暴露到集群外部。与NodePort类型的service的使用方法基本类似,需要指定外部的负载均衡器,示例如下。kind: Service apiVersion: v1 metadata: name: my-service spec: selector: app: MyApp ports: - protocol: TCP port: 80 targetPort: 9376 clusterIP: 10.0.171.239 loadBalancerIP: 78.11.24.19 type: LoadBalancer status: loadBalancer: ingress: - ip: 146.148.47.155ExternalIPs:用于将集群外部的服务以自定义名称的形式发布到集群中以供Pod中的应用程序访问,不需要使用标签选择器关联任何的pod对象,但必须要用spec.externalName属性定义一个CNAME记录用于返回外部真正提供服务的主机的别名,而后通过CHAME记录获取到相关主机的IP地址。配置示例如下,当查询主机 my-service.prod.svc.CLUSTER时,集群的DNS服务将返回一个值为http://my.database.example.com 的 CNAME记录。kind: Service apiVersion: v1 metadata: name: my-service namespace: prod spec: type: ExternalName externalName: my.database.example.comKube-proxy原理

那么Service是如何实现的呢?这就用到了Kube-proxy。它是一个简单的网络代理和负载均衡器,具体来说,是实现了内部从Pod到Service和外部的从NodePort向Service的访问。它有两种实现方式:

用户空间代理:直接通过kuber-proxy实现LB的代理服务,这个是kube-proxy的最初的版本,较为稳定,但是效率也自然不太高。通过采用iptables来实现LB,这是目前kube-proxy默认的方式。其原理如下:对于每个服务都建立起iptables规则,从而可以将服务的clusterIP(虚拟)和端口的流量重定向到服务的后端集合之一。对于每个Endpoints对象,安装选择后端Pod的iptables规则。kube-proxy监视Kubernetes主服务器添加和删除服务和端点的操作,根据这些操作实时更新所有节点上的iptables规则。默认情况下,后端的选择是随机的。可以通过将service.spec.sessionAffinity设置为“ClientIP”(默认为“无”)来选择基于客户端IP的会话关联。与用户空间代理一样,最终结果是绑定到服务的IP:端口的任何流量被代理到适当的后端,而客户端不知道关于Kubernetes或服务或Pod的任何信息。这应该比用户空间代理更快,更可靠。然而,与用户空间代理不同,如果最初选择的Pod不响应,则iptables代理不能自动重试另一个Pod,因此需要有工作准备就绪探测。Kube-dns介绍

Kube-proxy是实现了流量从ClusterIp到pod的转发,然而在实际编码的时候,我们更希望能通过固定的域名来访问服务。Kube-dns就是用来为kubernetes service分配子域名的,在集群中可以直接通过名称访问service;通常kube-dns会为service赋予一个名为“service名称.namespace.svc.cluster.local”的A记录,用来解析service的clusterip。

Kube-dns主要(1.4版本之后)由“Kubedns、dnsmasq、exechealthz”三个组件组成,它们的功能如下。

Kubedns

服务端口是10053,主要作用有:

接入SkyDNS,为dnsmasq提供查询服务。替换etcd容器,使用树形结构在内存中保存DNS记录。通过K8S API监视Service资源变化并更新DNS记录。

Dnsmasq

Dnsmasq是一款小巧的DNS配置工具,其Dockerfile在GitHub上Kubernetes组织的contrib仓库中,位于dnsmasq目录下。它在kube-dns中的作用是:

通过kubedns容器获取DNS规则,在集群中提供DNS查询服务提供DNS缓存,提高查询性能降低kubedns容器的压力、提高稳定性

在kube-dns插件的编排文件中可以看到,dnsmasq通过参数–server=127.0.0.1:10053指定upstream为kubedns。

Exechealthz

源码同样在contrib仓库中,位于exec-healthz目录下,主要作用是提供健康检查功能。

K8S常见资源对象极其使用方式

Pod:Pod是一组容器(当然也可以只有一个),是K8S最小调度单位。容器本身就是一个小盒子了,Pod相当于在容器上又包了一层小盒子。这个盒子里面的容器:

可以直接通过volume共享存储。有相同的网络空间,通俗点说就是有一样的ip地址,有一样的网卡和网络设置。 多个容器之间可以“了解”对方,比如知道其他人的镜像,知道别人定义的端口等。

那么Pod是如何被创建的了?这就需要Deployment配置文件。

Deployment是一个抽象的概念,可以说是应用管理者。

K8S是对容器进行编排的,如果使用它我们要事先准备好docker镜像。有了镜像之后,一般我们会通过Kubernetes的Deployment的配置文件去描述应用,比如应用叫什么名字、使用的镜像名字、要运行几个实例、需要多少内存、cpu资源等。示例如下

apiVersion: apps/v1 kind: Deployment metadata: name: web spec: selector: matchLabels: app: web replicas: 2 template: metadata: labels: app: web spec: containers: - name: web image: registry.cn-hangzhou.aliyuncs.com/liuyi01/tomcat:8.0.51-alpine ports: - containerPort: 8080

有了配置文件就可以通过Kubernetes提供的命令行客户端-kubectl去创建这个应用的pod实例了。比如应用的Deployment配置文件叫app.yaml,我们就可以通过命令

kubectl create -f app.yaml

来启动这个应用的pod实例,之后就由Kubernetes来保证我们的应用处于预期的工作状态,当某个pod实例运行失败了或者运行着应用的Node突然宕机了,Kubernetes会根据节点心跳信息发现这个问题,并在新的可用Node上调度一个新的实例。

Service:这个我们前面已经介绍了,它是一组pod的代理。那么Service是如何知道它负责哪些Pod呢?是如何跟踪这些Pod变化的?

最直接的方法是使用Deployment的名字。一个Service对应一个Deployment。当然这样确实可以实现。也可以使用了Label标签,再Deployment配置文件中给Pod打上标签,然后再Service的配置文件中指定其负责的pod的标签,这样Service不仅可以只负责一个Deployment的Pod也可以负责多个Deployment的Pod。

例如前面的Deployment配置文件中指定了其创建的pod的标签为app=web,现在我们创建一个Service,并指定其负责的pod的标签为app=web。相应的配置文件如下

apiVersion: v1 kind: Service metadata: name: web spec: ports: - port: 80 # 服务端口 protocol: TCP targetPort: 8080 # 容器端口 selector: app: web # 标签选择器,这里选择app=web的pod作为这个Service的代理对象

假设配置文件的名称是app.yaml,通过下列kubectl命令就可以启动服务。

kubectl create -f app.yaml

此外,对于需要升级的服务,K8S可以提供RollingUpdate(滚动升级)的解决方案,即一边增加新版本应用的实例数,一边减少旧版本应用的实例数,直到新版本的实例数达到预期,旧版本的实例数减少为0。在整个升级过程中,服务一直处于可用状态。并且可以在任意时刻回滚到旧版本。

Job:Service主要用于一些长期运行的任务,如web应用,数据库服务等。而Job则相反,它适合于一些非长期运行的任务,比如数据处理之类,运行完成后对应的pod会被停止,释放硬件资源。



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


    图片新闻

    实验室药品柜的特性有哪些
    实验室药品柜是实验室家具的重要组成部分之一,主要
    小学科学实验中有哪些教学
    计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
    实验室各种仪器原理动图讲
    1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
    高中化学常见仪器及实验装
    1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
    微生物操作主要设备和器具
    今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
    浅谈通风柜使用基本常识
     众所周知,通风柜功能中最主要的就是排气功能。在

    专题文章

      CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭