当前位置 : 首页 » 文章分类 :  开发  »  Kubernetes

Kubernetes

Kubernetes/K8S 笔记

Kubernetes Handbook——Kubernetes中文指南/云原生应用架构实践手册
https://jimmysong.io/kubernetes-handbook/

Kubernetes 是 Google 开源容器集群管理系统,提供应用部署、维护、 扩展机制等功能,利用 Kubernetes 能方便地管理跨机器运行容器化的应用,其主要功能如下:
使用 Docker 对应用程序包装 (package)、实例化 (instantiate)、运行 (run)。
以集群的方式运行、管理跨机器的容器。
解决 Docker 跨机器容器之间的通讯问题。
Kubernetes 的自我修复机制使得容器集群总是运行在用户期望的状态。包括容器的自动启动、自动重调度以及自动备份。


概述

Kubernetes是为生产环境而设计的容器调度管理系统,对于负载均衡、服务发现、高可用、滚动升级、自动伸缩等容器云平台的功能要求有原生支持 。

一个K8S集群是由分布式存储(etcd)、 Node节点和Master节点构成的。所有的 集群状态都保存在etcd中,Master节点上则运行集群的管理控制模块。

Node节点是真正运行应用容器的主机节点,在每个Node节点上都会运行一个Kubelet代理,控制该节点上的容 器、镜像和存储卷等。

基础组件功能

etcd保存了整个集群的状态;
apiserver提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;
controller manager负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
scheduler负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上;
kubelet负责维护容器的生命周期,同时也负责Volume(CSI)和网络(CNI)的管理;
container runtime负责镜像管理以及Pod和容器的真正运行(CRI);
kube-proxy负责为Service提供cluster内部的服务发现和负载均衡;

K8S中一些基本概念

Pod:Pod是kubernetes中你可以创建和部署的最小也是最简的单位。Pod代表着部署的一个单位:kubernetes中应用的一个实例,可能由一个或者多个容器组合在一起共享资源。
Label:是一个 key=value的键值对,由用户指定,可以附加到 K8S资源之上。给某个资源定义一个标签,随后可以通过label进行查询和筛选 ,deployment与service之间通过label来关联。
Namespace:通过将系统内部的对象分配到不同的Namespace中,这些namespace之间可以完全隔离,也可以通过某种方式,让一个namespace中的service可以访问到其他的namespace中的服务。
Deployment:Deployment为Pod提供声明式更新。只需要在 Deployment 中描述您想要的目标状态是什么,Deployment controller 就会帮您将 Pod 和ReplicaSet 的实际状态改变到您的目标状态。可以滚动升级和回滚应用,扩容和缩容。
Service:在K8s集群中,客户端需要访问的服务就是Service对象。每个Service会对应一个集群内部有效的虚拟IP,该虚拟IP通过IPVS规则,自动轮询访问后端Pod。在K8s集群中微服务的负载均衡是由Kube-proxy实现的。
Volume:Volume是Pod中能够被多个容器访问的共享目录。
DaemonSet: 确保全部(或者一些)Node 上运行一个 Pod 的副本。当有 Node 加入集群时,也会为他们新增一个 Pod 。当有 Node 从集群移除时,这些 Pod 也会被回收。删除DaemonSet 将会删除它创建的所有 Pod。
ConfigMap:ConfigMap API给我们提供了向容器中注入配置信息的机制,ConfigMap可以被用来保存单个属性,也可以用来保存整个配置文件或者JSON二进制大对象。ConfigMap 可以更方便地处理不包含敏感信息的字符串。
HPA:Horizontal Pod Autoscaling,顾名思义,使Pod水平自动缩放。

K8S三种IP及端口:

Node IP: 节点设备的IP,如物理机,虚拟机等容器宿主的实际IP。
Node Port:服务对外(gateway)暴露的端口。
Pod IP: Pod 的IP地址,是根据网络组件的IP段进行分配的。
Pod Port:应用程序启动时监听的端口,即Tomcat或undertow容器监听端口,例如8080。
Service IP: Service的IP,是一个虚拟IP,仅作用于service对象,由k8s 管理和分配,需要结合service port才能使用,单独的IP没有通信功能,集群外访问需要一些修改。
Service Port:服务内部(K8S内部)使用的端口。
在K8S集群内部,node ip 、pod ip、 service ip的通信机制是由k8s制定的路由规则,不是IP路由,即K8S的Pod ip、 Service ip与外界网络不通。

使用K8S的好处

降低成本:利用docker的隔离机制,一个node上可以部署多个pod
方便接入:新项目接入不用单独申请ec2资源,由SE根据集群资源使用情况扩缩容;使用docker镜像,不用安装依赖
自动化运维:k8s自动检测pod的heath状态,检测不通后自动从service上摘除节点;pod崩溃后自动重启;node宕机后pod自动漂移;pod部署为滚动部署,理论上无宕机时间


kube-proxy

kube-proxy作为Kubernetes集群中的网络代理和负载均衡器,其作用是将发送到Service的请求转发到具体的后端。
Kubernetes从1.8开始为kube-proxy组件引入了IPVS模式,并在Kubernetes 1.11进入GA,在Kubernetes 1.12成为kube-proxy的默认代理模式。

当前Kubernetes kube-proxy的负载均衡支持以下三种代理模式:

userspace

userspace:这种模式下kube-proxy进程在用户空间监听一个本地端口,iptables规则将流量转发到这个本地端口,然后kube-proxy在其内部应用层建立到具体后端的连接,即在其内部进行转发,这是在用户空间的转发,虽然比较稳定,但效率不高。userspace模式是kube-proxy早期(Kubernetes 1.0)的模式,早就不推荐使用,也不会被我们使用。

iptables

iptables:这种模式是从Kubernetes 1.2开始并在Kubernetes 1.12之前的默认方式。
在这种模式下kube-proxy监控Kubernetes对Service、Endpoint对象的增删改操作。监控到Service对象的增删改,将配置iptables规则,截获到Service的ClusterIp和端口的流量并将其重定向到服务的某个后端;监控到Endpoint对象的增删改,将更新具体到某个后端的iptables规则。iptables模式基于netfilter,但因为流量的转发都是在Kernel Space,所以性能更高且更加可靠。 这种模式的缺点是,对于超大规模集群,当集群中服务数量达到一定量级时,iptables规则的添加将会出现很大延迟,因为规则的更新出现kernel local,所以此时将会出现性能问题

ipvs

ipvs:这种模式从Kubernetes 1.11进入GA,并在Kubernetes 1.12成为kube-proxy的默认代理模式。
ipvs模式也是基于netfilter,对比iptables模式在大规模Kubernetes集群有更好的扩展性和性能,支持更加复杂的负载均衡算法(如:最小负载、最少连接、加权等),支持Server的健康检查和连接重试等功能。ipvs依赖于iptables,使用iptables进行包过滤、SNAT、masquared。ipvs将使用ipset需要被DROP或MASQUARED的源地址或目标地址,这样就能保证iptables规则数量的固定,我们不需要关心集群中有多少个Service了。

IPVS(IP Virtual Server)是lvs项目的一部分,作为Linux内核的一部分,提供4层负载均衡器的功能,即传输层负载均衡。ipvs运行在主机内核中,作为真是服务器集群前的负载均衡器,将到对服务的请求转发到真实的服务器上,并将多个ip的真实服务器集群的服务显示为单个ip的虚拟机服务。

Kubernetes 从1.10到1.11升级记录(续):Kubernetes kube-proxy开启IPVS模式
https://blog.frognew.com/2018/10/kubernetes-kube-proxy-enable-ipvs.html

k8s ipvs 长连接 Connection reset by peer问题

查看 tcp keepalive 的内核参数

$ sysctl net.ipv4.tcp_keepalive_time net.ipv4.tcp_keepalive_probes net.ipv4.tcp_keepalive_intvl
net.ipv4.tcp_keepalive_time = 7200
net.ipv4.tcp_keepalive_probes = 9
net.ipv4.tcp_keepalive_intvl = 75

net.ipv4.tcp_keepalive_time 是连接时长,当超过这个时间后,每隔 net.ipv4.tcp_keepalive_intvl 的时间间隔会发送keepalive数据包,net.ipv4.tcp_keepalive_probe 是发送keepalived数据包的频率。

使用 ipvsadm 命令查看k8s节点上ipvs的超时时间:

ipvsadm -l --timeout
Timeout (tcp tcpfin udp): 900 120 300

经过上面的分析可以看出,各个k8s节点上tcp keepalive超时是7200秒(即2小时),ipvs超时是900秒(15分钟),这就出现如果客户端或服务端在15分钟内没有应答时,ipvs会主动将tcp连接终止,而客户端服务还傻傻以为是2个小时呢。 很明显net.ipv4.tcp_keepalive_time不能超过ipvs的超时时间。

Kubernetes IPVS模式下服务间长连接通讯的优化,解决Connection reset by peer问题
https://blog.frognew.com/2018/12/kubernetes-ipvs-long-connection-optimize.html


问题

upstream connect error or disconnect/reset before headers. reset reason connection failure

k8s 的 Istio 网关报的这个错

Istio DestinationRule gives upstream connect error or disconnect/reset before headers
https://stackoverflow.com/questions/53103984/istio-destinationrule-gives-upstream-connect-error-or-disconnect-reset-before-he


上一篇 Pinpoint

下一篇 Prometheus监控

阅读
评论
2,359
阅读预计9分钟
创建日期 2019-10-05
修改日期 2019-12-20
类别

页面信息

location:
protocol:
host:
hostname:
origin:
pathname:
href:
document:
referrer:

评论