kubernetes容器管理技术

一、概念

1、k8s的特点

轻量级 :使用go语言编译型语言,语言级别支持进程管理,不需要人为控制,所以以go开发的资源消耗占用资源小

开源:免费可编辑

自我修复:对异常状态的容器进行重启或重建(先创建、再删除),目的是保证业务线不中断

弹性伸缩:使用命令、UI或者基于CPU使用情况自动快速扩容和缩容应用程序实例,保证应用业务高峰并发时的高可用性;且在业务低峰时回收资源,以最小成本运行服务

自动部署和回滚:K8S采用滚动更新策略更新应用(默认),一次更新一个Pod,而不是同时删除所有Pod,如果更新过程中出现问题,将回滚更改,确保升级不会影响业务

服务发现和负载均衡:(userapaces——iptables——ipvs)K8S为多个pod(容器)提供一个统一访问入口(内部IP地址和一个DNS名称),并且负载均衡关联的所有容器,使得用户无需考虑容器IP问题

机密和配置管理:管理机密数据和应用程序配置,而不需要把敏感数据暴露在镜像里,提高敏感数据安全性。并可以将一些常用的配置存储在K8S中,方便应用程序使用

存储编排(静态、动态):挂载外部存储系统,无论是来自本地存储,公有云(如AWS),还是网络存储(如NFS、GlusterFS、Ceph)都作为集群资源的一部分使用,极大提高存储使用灵活性

批处理:提供一次性任务(job),定时任务(crontab);满足批量数据处理和分析的场景

2、k8s的基本组件(Pod)

一个pod 会封装多个容器组成一个子节点的运行环境

最小部署单元一组容器的集合(基础容器+ 主应用容器+挂斗/副容器)

一个Pod中的容器共享网络命名空间(基础容器提供的pause)

Pod是短暂的 (叙述的是其生命周期)

pod内最少跑3个容器,分布是基础容器pause+运行容器+主应用

3、pod分类

自主式Pod:这种Pod本身是不能自我修复的。当Pod被创建后(不论是由你直接创建还是被其它controller),都会被K8s调度到集群的Node上。直到pod的进程终止、被删掉。因为缺少资源而被驱逐、或者Node故障之前这个Pod都会一直保持在八个Node上。如果Pod运行的Node故障,或者是调度器本身故障,这个Pod就会被删除。同样的,如果Pod所在Node缺少资源或者Pod处于维护状态,Pod也会被驱逐

控制器管理的Pod:K8s使用更高级的称为Controller的抽象层,来管理Pod实例。Controller可以创建和管理多个Pod,提供副本管理、滚动升级和集群级别的自愈能力。例如。如果一个Node故障,Controller就能自动将该节点上的Pod调度到其他健康的Node上,虽然可以直接使用Pod,但是在K8s中通常是使用Controller来管理Pod的

4、资源清单

K8S中资源的概念: 在kubernetes中,所有控制器,组件等都称为资源

资源清单格式(资源清单/配置文件):在k8s中,一般使用yaml格式的文件来创建符合我们预期期望的pod

创建资源的方法
apiserver 仅接受JSON格式的资源定义
yaml格式提供配置清单,apiserver 可自动将其转为JSON格式,而后再提交

Pod 生命周期:收到kubectl指令–>初始化容器(init container),生成文件(init可以有多个,但是不可以同时运行)–>创建容器成功–>start容器–>readnessProbe(就绪性特征):就绪检测–> liveness Probe (存活性探针):生存检测–>stop容器
InitC:是一个pod中先于应用容器启动的容器
init总是运行到成功完成为止,init结束后pod不会退出,多个init不能同时运行
mainC主容器启动后需要一些必要的文件和目录的访问权限,而最好不包含产生这些容器的工具(冗余和安全性),所以,initC包含了这些工具和访问权限,直接给mainC提供这些文件
保证容器都启动完成,不会让容器间的关联性,启动顺序导致pod一直重启
若pod重启,所有的init都要重新执行

readiness: pod创建成功,但是容器里的应用没有部署完成,但是对外显示running,实际上并不能访问,就绪检测完成后pod才对外显示running。

liveness:liveness监测到主容器不能正常工作时,启用重启策略

Pod phase容器探针
在Pod中担任linux命名空间共享的基础
启动Pid命名空间,开启init进程
Pod hook(钩子):是由Kubernetes管理的kubelet发起的,当容器中的进程启动前或者容器中的进程终止之前运行,这是包含在容器的生命周期之中。可以同时为Pod中的所有容器都配置 hook
Hook的类型包括两种
exec:执行一段命令
HTTP:发送HTTP请求

5、pod暴露

 有的几个主要部分,k8s的网卡、kube-proxy负载均衡器、service服务发现(label标签)、pod组件(主容器/副容器、pause基础容器、init初始化容器)

首先网络进来后,通过网卡是到我们的kube

首先是我们说的k8s最小组件是pod,pod是一个密闭的空间,里面是我们容器,pause就是个基础的容器、主容器/副容器、init初始化容器,在pod出来后,由于 Pod 内共享网络命名空间,就是通过veth对,

6、Pod控制器(维护Pod状态,期望值)

什么是控制器--》对不同的对象及其特性使用不同的方式控制管理—》控制器说明:ReplicaSet        确保预期的Pod副本数量
Deployment      无状态应用控制器(部署)
StatefulSet       有状态应用部署
DaemonSet     确保所有Node运行同一种PodI
Job                  一次性任务
Cronjob            定时任务
ingress             管理的是L7层的网络模式(HTTP/HTTPS流量>
ingress包含:nginx、Haproxy、traffic、istio、 kong

总结

k8s 特性:

轻量级:重点在于开发的语言(解释性语言go,系统资源消耗较少)

开源

自我修复——》控制器

弹性伸缩——》yml定义的阈值(cgroups控制的limit资源上限)和伸缩方式(水平)

自动部署、回滚—》yml定义的(部署方式list-watch机制,rollback回滚)

服务发现、负载均衡—-》services +kube-proxy

机密和配置管理——》 RBAC + configmap(配置中心)

存储编排—》静态+动态 :wEs gfs等网络存储+本地存储+云存储(以上是静态),pv+pvc 动态

批量处理—》一次性任务和周期性任务
 

服务发现和负载均衡三种模式:

userapaces——iptables——ipvs

一个pod多少个容器? 

正常情有,pause基础容器、init初始化容器、主容器/副容器,副容器有的时候也是没有的

pod中多个容器是怎么通信的?

是通过localhost通信的,同一个pod内共享网络命名空间,容器之间通过访问 127.0.0.1:(端口)即可。 veth对的一端是容器内部,就是容器所属的网络命名空间,另一端就是docker0这端,是由 Docker Daemon 挂载在 docker0 网桥上,所以说在同一个 pod 内的多容器间通信,也就是通过我们localhost直接通信了

同节点node不同的pod是怎么通信的?

是通过docker0通信的,由于 Pod 内共享网络命名空间(由 pause 容器创建),所以本质上也是同节点容器间的通信。同时,同一 Node 中 Pod 的默认路由都是 docker0 的地址,由于它们关联在同一个 docker0 网桥上,地址网段相同,所有它们之间应当是能直接通信的,容器和容器共享网络命名空间,因此对pod 外的请求通过 pod1和 Docker0 网桥的 veth对实现,访问另一个pod内的容器,其请求的地址是PodIP而非容器的ip,实际上也是同一个子网间通信,直接经过veth对转发即可

不同node,pod通信是怎么样的?

CNI:容器网络接口:CNI 是为容器平台提供网络的标准化,不同的容器平台能够通过相同的接口调用不同的网络组件

目前kubernetes支持的CNI组件种类很多,例如:bridge flannel calico cannel calico-ipam dhcp host-local ipvlan loopback macvlan portmap ptp sample tuning vlan。在docker中,主流的跨主机通信方案主要有一下几种:

1)基于隧道的overlay网络:按隧道类型来说,不同的公司或者组织有不同的实现方案。docker原生的overlay网络就是基于vxlan隧道实现的。ovn则需要通过geneve或者stt隧道来实现的。flannel最新版本也开始默认基于vxlan实现overlay网络。

2)基于包封装的overlay网络:基于UDP封装等数据包包装方式,在docker集群上实现跨主机网络。典型实现方案有weave、flannel的早期版本。

3)基于三层实现SDN网络:基于三层协议和路由,直接在三层上实现跨主机网络,并且通过iptables实现网络的安全隔离。同时对不支持三层路由的环境,Project Calico还提供了基于IPIP封装的跨主机网络实现

集群内跨节点通信涉及到不同的子网间通信,仅靠docker0无法实现,这里需要借助CNI网络插件来实现

flannel实现跨节点通信的方式

简单说来,flannel的用户态进程flanneld会为每个node节点创建一个flannel.1的网桥,根据etcd或apiserver的全局统一的集群信息为每个node分配全局唯一的网段,避免地址冲突。同时会为docker0和flannel.1创建veth对,docker0将报文丢给flannel.1

Flanneld维护了一份全局node的网络表,通过flannel.1接收到请求后,根据node表,将请求二次封装为UDP包,扔给eth0网卡,由eth0出口进入物理网路发送给目的node。

在另一端以相反的流程。Flanneld解包并发往docker0,进而发往目的Pod中的容器。

外部外部访问集群

从集群外访问集群有多种方式,比如loadbalancer,Ingress,nodeport,nodeport和loadbalancer是service的两个基本类型,是将service直接对外暴露的方式,ingress则是提供了七层负载均衡,其基本原理将外部流量转发到内部的service,再转发到后端endpoints,在平时的使用中,我们可以依据具体的业务需求选用不同的方式。这里主要介绍nodeport和ingress方式。

Nodeport通过将 Service 的类型设置为 NodePort,就可以在 Cluster 中的主机上通过一个指定端口暴露服务。注意通过 Cluster 中每台主机上的该指定端口都可以访问到该服务,发送到该主机端口的请求会被 Kubernetes 路由到提供服务的 Pod 上。采用这种服务类型,可以在 Kubernetes cluster 网络外通过主机 IP:端口的方式访问到服务。

Ingress 是推荐在生产环境使用的方式,它起到了七层负载均衡器和 Http 方向代理的作用,可以根据不同的 url 把入口流量分发到不同的后端Service。外部客户端只看到 http://foo.bar.com 这个服务器,屏蔽了内部多个 Service 的实现方式。采用这种方式,简化了客户端的访问,并增加了后端实现和部署的灵活性,可以在不影响客户端的情况下对后端的服务部署进行调整

这里我们定义了一个ingress模板,定义通过 http://test.name.com 来访问服务,在虚拟主机http://test.name.com下面定义了两个Path,其中/test被分发到后端服务s1,/name被分发到后端服务s2

集群中可以定义多个ingress,来完成不同服务的转发,这里需要一个ingress controller来管理集群中的Ingress规则。Ingress Contronler 通过与 Kubernetes API 交互,动态的去感知集群中 Ingress 规则变化,然后读取它,按照自定义的规则,规则就是写明了哪个域名对应哪个service,生成一段 Nginx 配置,再写到 Nginx-ingress-control的 Pod 里,这个 Ingress Contronler 的 pod 里面运行着一个nginx服务,控制器会把生成的nginx配置写入 /etc/nginx.conf 文件中,然后 reload使用配置生效

容器健康监控可以通过容器探针?

liveness probe 存活探针和readness probe就绪探针

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值