kubernetes组件再认知

本文涉及的产品
应用型负载均衡 ALB,每月750个小时 15LCU
网络型负载均衡 NLB,每月750个小时 15LCU
简介: 之前学习k8s的各组件还是感觉不深入, 只停留在名字解释上面。总是不能深入理解,例如应用部署后kuber-proxy会在master 和node上添加什么样的iptables规则、部署一个应用的完整流程( 手画各组件功能并介绍10分钟以上 )、schedule具体是怎么调度的、limit request 是如何限制资源的…

背景


之前学习k8s的各组件还是感觉不深入, 只停留在名字解释上面。总是不能深入理解,例如应用部署后kuber-proxy会在master 和node上添加什么样的iptables规则、部署一个应用的完整流程( 手画各组件功能并介绍10分钟以上 )、schedule具体是怎么调度的、limit request 是如何限制资源的…


[ 在这里先抛砖引玉,极客时间孟老师的云原生训练营讲的比较深,推荐观看。后续把学习笔记再更新上来。]

k8s主要组件及功能(感性认知)


一个kubernetes集群主要是由控制节点(master)、**工作节点(node)**构成,每个节点上都会安装不同的组件。


master:集群的控制平面,负责集群的决策 ( 管理 )


ApiServer : 资源操作的唯一入口,接收用户输入的命令,提供认证、授权、API注册和发现等机制


Scheduler : 负责集群资源调度,按照预定的调度策略将Pod调度到相应的node节点上


ControllerManager : 负责维护集群的状态,比如程序部署安排、故障检测、自动扩展、滚动更新等


Etcd :负责存储集群中各种资源对象的信息


node:集群的数据平面,负责为容器提供运行环境 ( 干活 )


Kubelet : 负责维护容器的生命周期,即通过控制docker,来创建、更新、销毁容器


KubeProxy : 负责提供集群内部的服务发现和负载均衡


Docker : 负责节点上容器的各种操作

4bd8e77581ec41a397818b5d80495d86.png

各组件再认识


Kubernetes的节点包含两种角色:Master节点和Node节点。

Master节点上面部署


  • apiserver
  • scheduler
  • controller manager(replication controller、node controller等)


Node节点上面部署kubelet和proxy。当然也可以将它们部署到一起,只是生产环境通常不建议这样做。

【1】Apiserver


Apiserver是Kubernetes最核心的组件,它是整个集群API的入口,每个组件都需要和它交互


Kubernetes所有资源数据都是通过Apiserver保存到后端Etcd的,当然它本身还提供了对资源的缓存。它本身是无状态的,所以在集群的高可用部署中,可以部署成多活。

Kubernetes API接口的分层


Kubernetes API接口主要分为组、版本和资源三层,接口层次如图所示。

对于“/apis/batch/v1/jobs”接口,batch是组,v1是版本,jobs是资源。Kubernetes的核心资源都放在“/api”接口下,扩展的接口放在“/apis”下。

04c5d87a9e364cf986bcfafae7018eba.png

api版本规划


Kubernetes资源会同时存在多个版本。当新的资源接口刚加入还不成熟时,通常会使用alpha版本,伴随着充分测试逐渐成熟后会变更为beta版本,最终稳定版本将会使用vx版本。譬如statefuleset这个资源之前在“/apis/batch/v2alpha1”和“/apis/batch/v1beta1”中都存在,但伴随着该功能的完善,现在已经将会迁移到v1版本下。

请求到达apiserver后的流程


Apiserver启动后会将每个版本的接口都注册到一个核心的路由分发器(Mux)中。当客户端请求到达Apiserver后,首先经过Authentication认证和Authorization授权。认证支持Basic、Token及证书认证等。授权目前默认使用的是RBAC。经过路由分发到指定的接口,为了兼容多个资源版本,请求的不同版本的资源类型会统一转化为一个内部资源类型,然后进入Admission准入控制和Validation资源校验,在准入控制采用插件机制,用户可以定义自己的注入控制器验证,并更改资源配置。资源校验主要是验证参数是否合法,必传参数是否齐备等。最后再转化到用户最初的资源版本,并保存到Etcd中

9cd61db5664a490ebcbc07b44424e739.png

详细的架构图如下:

6d7a805655da44219c951a6d776046dc.png

为了将外部传入不同版本的资源类型统一转化为对应的内部类型,需要这个内部资源类型能够兼容不同版本的外部资源。


内部的版本定义在types.go文件中。如果是其他版本和内部版本之间转化可以通过自动生成的zz_generated.conversion.go或者自定义的conversion.go完成。


由于v2beta2版本的autoscaling可以直接转化为内部autoscaling,而v1版本的autoscaling并不支持多指标(只能根据CPU扩容),所以需要在conversion.go中将CPU指标当作多指标中的一个指标进行处理。

api-server限流的算法


api-server限流是对自己的一种保护,其实任何系统的限流都是这样的。这些限流方式都是比较经典的,放之四海而皆准。

计数器固定算法

16e42f9281084a19bd2eaa6ba65a413b.png计数器滑动窗口算法


如果某一个窗口大量并发请求也无法挡住.

4b68dad554d34abfa7a65227ef7c39bb.png

思考: 为什么滑动窗口比滚动窗口指标更能体现产品品质?

漏斗算法

6aa34c51c154412e992969c38f4b2408.png令牌桶算法

b998558fdd674b30a7ba0b9612a56bec.png

API-Server限流的两个参数


api-server能处理的并发请求。


max-requests-inflight

限制请求总数例如list/watch

max-mutating-requests-inflight

限制读写请求总数例如delete/update


节点数越多请求越多,对应参数调大一点。

6fd18fa072334d69b8422cd4dc5742fc.png

目前限流的缺陷


传统限流方法的局限性

•粒度粗

无法为不同用户,不同场景设置不通的限流


•单队列

共享限流窗口/桶,一个坏用户可能会将整个系统堵塞,其他正常用户的请求无法被及时处理


•不公平

正常用户的请求会被排到队尾,无法及时处理而饿死


•无优先级

重要的系统指令一并被限流,系统故障难以恢复

API Priority and Fairness


3b23e6d8d2c346d785f343165be54633.png70a68747205043179d25f3f3f6351501.png

什么是flowschema?

769d632aa8f948eeb30a567b0de9ae13.png
⚡ root@master1  ~  k get flowschema
NAME                           PRIORITYLEVEL     MATCHINGPRECEDENCE   DISTINGUISHERMETHOD   AGE    MISSINGPL
exempt                         exempt            1                    <none>                148d   False
probes                         exempt            2                    <none>                148d   False
system-leader-election         leader-election   100                  ByUser                148d   False
workload-leader-election       leader-election   200                  ByUser                148d   False
system-node-high               node-high         400                  ByUser                148d   False
system-nodes                   system            500                  ByUser                148d   False
kube-controller-manager        workload-high     800                  ByNamespace           148d   False
kube-scheduler                 workload-high     800                  ByNamespace           148d   False
kube-system-service-accounts   workload-high     900                  ByNamespace           148d   False
service-accounts               workload-low      9000                 ByUser                148d   False
global-default                 global-default    9900                 ByUser                148d   False
catch-all                      catch-all         10000                ByUser                148d   False
 ⚡ root@master1  ~ 
 ⚡ root@master1  ~ 

什么是PriorityLevelConfiguration?666a35c654974ab0b46a86d0128166d5.png

Apf的日志

api-server日志中会告诉你apf_fs 和 apf_pl

I1122 10:40:18.969066   32615 httplog.go:129] "HTTP" verb="WATCH" URI="/apis/crd.projectcalico.org/v1/networksets?resourceVersion=16290621&watch=true" latency="47m37.783288379s" userAgent="Go-http-client/2.0" audit-ID="7844f68d-24ac-4e95-bc25-2180d34aefc3" srcIP="10.50.10.36:42486" apf_pl="workload-high" apf_fs="kube-system-service-accounts" apf_init_latency="717.913µs" resp=200
⚡ root@master1  ~  k get PriorityLevelConfiguration
NAME              TYPE      ASSUREDCONCURRENCYSHARES   QUEUES   HANDSIZE   QUEUELENGTHLIMIT   AGE
catch-all         Limited   5                          <none>   <none>     <none>             148d
exempt            Exempt    <none>                     <none>   <none>     <none>             148d
global-default    Limited   20                         128      6          50                 148d
leader-election   Limited   10                         16       4          50                 148d
node-high         Limited   40                         64       6          50                 148d
system            Limited   30                         64       6          50                 148d
workload-high     Limited   40                         128      6          50                 148d
workload-low      Limited   100                        128      6          50                 148d
如何监控 / 调试限流?

类似于tcp 监控队列.

#/debug/api_priority_and_fairness/dump_priority_levels
#1、所有优先级及其当前状态的列表
kubectl get --raw /debug/api_priority_and_fairness/dump_priority_levels
#/debug/api_priority_and_fairness/dump_queues
#2、所有队列及其当前状态的列表
kubectl get --raw /debug/api_priority_and_fairness/dump_queues
# /debug/api_priority_and_fairness/dump_requests
# 3、当前正在队列中等待的所有请求的列表
kubectl get --raw /debug/api_priority_and_fairness/dump_requests

822ae4fad15748f4aaf31a03a5b907fd.png

api 高可用


apiserver是无状态的Rest Server 无状态所以方便Scale Up/down 负载均衡

•在多个apiserver实例之上,配置负载均衡

•证书可能需要加上Loadbalancer VIP重新生成


随着集群中节点数量不断增多,APIServer对CPU和内存的开销也不断增大。过少的CPU资源会降低其处理效率,过少的内存资源会导致Pod被OOMKilled,直接导致服务不可用。在规划APIServer资源时,不能仅看当下需求,也要为未来预留充分。

kube-apiserver配置

如果需要开启特殊插件,修改api-server配置即可。

KUBE_APISERVER_OPTS="--enable-admission-plugins=NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \
  --anonymous-auth=false \
  --bind-address=10.50.10.31 \
  --secure-port=6443 \
  --advertise-address=10.50.10.31 \
  --insecure-port=0 \
  --authorization-mode=Node,RBAC \
  --runtime-config=api/all=true \
  --enable-bootstrap-token-auth \
  --service-cluster-ip-range=10.96.0.0/16 \
  --token-auth-file=/etc/kubernetes/token.csv \
  --service-node-port-range=30000-32767 \
  --tls-cert-file=/etc/kubernetes/ssl/kube-apiserver.pem  \
  --tls-private-key-file=/etc/kubernetes/ssl/kube-apiserver-key.pem \
  --client-ca-file=/etc/kubernetes/ssl/ca.pem \
  --kubelet-client-certificate=/etc/kubernetes/ssl/kube-apiserver.pem \
  --kubelet-client-key=/etc/kubernetes/ssl/kube-apiserver-key.pem \
  --service-account-key-file=/etc/kubernetes/ssl/ca-key.pem \
  --service-account-signing-key-file=/etc/kubernetes/ssl/ca-key.pem  \
  --service-account-issuer=api \
  --etcd-cafile=/etc/etcd/ssl/ca.pem \
  --etcd-certfile=/etc/etcd/ssl/etcd.pem \
  --etcd-keyfile=/etc/etcd/ssl/etcd-key.pem \
  --etcd-servers=https://10.50.10.31:2379,https://10.50.10.32:2379,https://10.50.10.33:2379 \
  --enable-swagger-ui=true \
  --allow-privileged=true \
  --apiserver-count=3 \
  --audit-log-maxage=30 \
  --audit-log-maxbackup=3 \
  --audit-log-maxsize=100 \
  --audit-log-path=/var/log/kube-apiserver-audit.log \
  --event-ttl=1h \
  --alsologtostderr=true \
  --logtostderr=false \
  --log-dir=/var/log/kubernetes \
  --v=4"
设置何时缓存

APIServer与etcd之间基于gRPC协议进行通信,gRPC协议保证了二者在大规模集群中的数据高速传输。gRPC基于连接复用的HTTP/2协议,即针对相同分组的对象,APIServer和etcd之间共享相同的TCP连接,不同请求由不同的stream传输。

一个HTTP/2连接有其stream配额 ,配额的大小限制了能支持的并发请求。APIServer提供了集群对象的缓存机制,当客户端发起查询请求时,APIServer默认会将其缓存直接返回给客户端。


  • gRPC通信协议
  • 复用连接
  • 不同请求不同stream传输

缓存区大小可以通过参数“–watch-cache-sizes”设置。


针对访问请求比较多的对象,适当设置缓存的大小,极大降低对etcd的访问频率,节省了网络调用,降低了对etcd集群的读写压力,从而提高对象访问的性能。

resourceVersion 决定 APIServer是否直接访问ETCD

APIServer是允许客户端忽略缓存的,例如客户端请求中ListOption中没有设置resourceVersion,这时APIServer直接从etcd拉取最新数据返回给客户端。

客户端应尽量避免此操作,应在ListOption中设置resourceVersion为0,APIServer则将从缓存里面读取数据,而不会直接访问etcd。

客户端尽量使用长连接

当查询请求的返回数据较大且此类请求并发量较大时,容易引发TCP链路的阻塞,导致其他查询 操作超时。


因此基于Kubernetes开发组件时,例如某些DaemonSet和Controller,如果要查询某类对象,应尽量通过长连接ListWatch监听对象变更,避免全量从APIServer获取资源。如果在同一应用程序中,如果有多个Informer监听APIServer资源变化,可以将这些Informer合并,减少和APIServer的长连接数,从而降低对APIServer的压力。

APIServer限流参数配置(自我保护)

APIServer的参数“–max-requests-inflight”和“–max-mutating-requests-inflight”支持在给定时间内限制并行处理读请求(包括Get、List和Watch操作)和写请求(包括Create、Delete、Update和Patch操作)的最大数量。

当APIServer接收到的请求超过这两个参数设定的值时,再接收到的请求将会被直接拒绝。通过速率限制机制,可以有效地控制APIServer内存的使用。如果该值配置过低,会经常出现请求超过限制的错误,如果配置过高,则APIServer可能会因为占用过多内存而被强制终止,因此需要根据实际的运行环境,结合实时用户请求数量和APIServer的资源配置进行调优。


客户端在接收到拒绝请求的返回值后,应等待一段时间再发起重试,无间隔的重试会加重APIServer的压力,导致性能进一步降低。


针对并行处理请求数的过滤颗粒度太大,在请求数量比较多的场景,重要的消息可能会被拒绝掉,**自1.18版本开始,社区引入了优先级和公平保证

(Priority and Fairness)功能,以提供更细粒度地客户端请求控制。**该功能支持将不同用户或不同类型的请求进行优先级归类,保证高优先级的请求总是能够更快得到处理,从而不受低优先 级请求的影响。

如何访问api-server?


对外部客户(user/client/admin),永远只通过LoadBalancer访问 只有当负载均衡出现故障时,管理员才切换到apiserver IP进行管理内部客户端,优先访问cluster IP?(是否一定如此?)

bd2356e2709441119762e314bdaa87c9.png

搭建多租户的Kubernetes集群


授信

•认证:

禁止匿名访问,只允许可信用户做操作。

•授权:

基于授信的操作,防止多用户之间互相影响,比如普通用户删除Kubernetes核心服务,或者A用户删除或修改B用户的应用。

隔离

•可见行隔离:

用户只关心自己的应用,无需看到其他用户的服务和部署。

•资源隔离:

有些关键项目对资源需求较高,需要专有设备,不与其他人共享。

•应用访问隔离:

用户创建的服务,按既定规则允许其他用户访问。

资源管理

•Quota管理

谁能用多少资源?

认证


与企业现有认证系统集成

•很多企业基于Microsoft Active Directory 提供认证服务选择认证插件

选择webhook作为认证插件(*以此为例展开)

也可以选择Keystone作为认证插件,以Microsoft Ad作为backend搭建keystone服务

一旦认证完成,Kubernetes即可获取当前用户信息(主要是用户名),并针对该用户做授权。授权和准入控制完成后,该用户的请求完成。

规划系统角色


a596a8b348c342a89355704d87678c3d.pngUser

•管理员

所有资源的所有权限??

•普通用户

是否有该用户创建的namespace下的所有object的操作权限?

对其他用户的namespace资源是否可读,是否可写?


SystemAccount

•SystemAccount是开发者(kubernetes developer或者domain developer)创建应用后,应用于apiserver通讯需要的身份

•用户可以创建自定的ServiceAccount,kubernetes也为每个namespace创建default ServiceAccount

•Default ServiceAccount通常需要给定权限以后才能对apiserver做写操作

权限最佳实践


ClusterRole是非namespace绑定的,针对整个集群生效

通常需要创建一个管理员角色,并且绑定给开发运营团队成员

ThirdPartyResource和CustomResourceDefinition是全局资源,普通用户创建ThirdPartyResource以后需要管理员授予相应权限后才能真正操作该对象

针对所有的角色管理,建议创建spec,用源代码驱动


•虽然可以通过edit操作来修改权限,但后期会导致权限管理混乱,可能会有很多临时创建出来的 角色和角色绑定对象,重复绑定某一个资源权限

权限是可以传递的,用户A可以将其对某对象的某操作,抽取成一个权限,并赋给用户B

防止海量的角色和角色绑定对象,因为大量的对象会导致鉴权效率低,同时给apiserver增加负担


ServiceAccount也需要授权的,否则你的component可能无法操作某对象

Tips:SSH到master节点通过insecure port访问apiserver可绕过鉴权,当需要做管理操作又没有权限时可以使用(不推荐)

什么是GKV?


  • G : group
  • nod和pod复用一个长连接,list pod如果卡主,list node会也会hang住.
  • K: kind
  • 是node还是pod
  • V: version
  • internal verion 和external version

如何界定版本?

α: 可以demo

β: 功能完成,api会变更

v1: 功能稳定,基本不会再变

k8s版本向后兼容问题


向前兼容3个版本.

【2】Controller manager


Controller manager是真正负责资源管理的组件,它主要负责容器的副本数管理、节点状态维护、节点网段分配等。


它是Kubernetes负责实现生命式API和控制器模式的核心

ReplicaSet controller 是如何被管理的?


以ReplicaSet为例,它会周期地检测理想的“目标容器数”和真实的“当前容器数”是否相同。如果不相等,则会将实际的容器数调整到目标容器数。


当设置一个ReplicaSet的副本数为10的时候,如果实际的容器数小于10,则会执行调用Apiserver创建Pod。如果当前容器数大于10,则会执行删除Pod操作。ReplicaSet检测过程如图673ea99ca4e2449f8fed9e0d49b511c1.png

【3】Scheduler


Scheduler负责容器调度组件。每个Pod最终需要在一台node节点上启动,通过Scheduler调度组件的筛选、打分,可以选择出Pod启动的最佳节点。当Pod创建后,Pod的NodeName属性为空,Scheduler会查询所有NodeName为空的Pod,并执行调度策略。选择最优的放置节点后,调用Apiserver绑定Pod对应的主机(设置Pod NodeName属性)。当绑定过后,对应节点的Kubelet便可以启动容器。

Scheduler的调度过程的两个步骤


第一步是筛选(Predicate)

筛选满足需要的节点。筛选的条件主要包括

1)Pod所需的资源(CPU、内存、GPU等);

2)端口是否冲突(主要是针对Pod HostPort端口和主机上面已有端口);

3)nodeSelector及亲和性(Pod亲和性和Node亲和性)

4)如果使用本地存储,那么Pod在调度时,将只会调度存储绑定的节点;

5)节点的驱赶策略,节点可以通过taint(污点)设置驱赶Pod策略,对应的Pod也可以设置Toleration(容忍)。1278cf864bf743f08f80086c1429001c.png

09d90c41508240d9988104e6ae9deb8b.png

第二步是根据资源分配算法排序打分(Priorities)


最终选择得分最高的节点作为最终的调度节点,主要调度策略包括


  • LeastRequestedPriority(最少资源请求算法)

  • BalancedResourceAllocation(均衡资源使用算法

  • ImageLocalityPriority(镜像本地优先算法)

  • NodeAffinityPriority(主机亲和算法)等。

为了归一化每种算法的权重,每种算法取值范围都是0~10,最终累加所有算法的总和,取得分最大的主机作为Pod的运行主机。

e6afe5140df1416fb5a699174c61ae92.png

1f48b53c372045e0aa5cb801be0f482e.png

为了提高调度的效率,Scheduler的Predicate和Priorities采用了并行调度。除此之外,Scheduler组件本地维护了一个调度队列和本地缓存,调度队列暂存了需要被调度的Pod,还可以调整调度的先后顺序。本地缓存主要是缓存Pod和Node信息,这样可以避免每次调度时都要从Apiserver获取主机信息。如图

e6f7f52189c14041b4c36db9174eefc5.png

Scheduler中的乐观锁


Predicate和Priorities都是并行操作的,那么有可能会出现数据的不一致,即Pod调度时主机上面资源是符合要求的。当容器启动时,由于其他容器也调度到该节点导致资源又不满足要求了。所以,在Kubelet启动容器之前首先执行一遍审计(在Kubelet上重新执行一遍Predicate)操作,确认资源充足才会启动容器,否则将更新Pod状态为Failed。

Init Container的资源限制的坑


44f7190337f74937ab0ef49e247d4d88.png

pod资源申请计算实例


下面以Pod资源使用为例,Pod通过request和limit的定义资源使用的下限和上限。Scheduler会累加Pod中每个容器的资源申请量,作为Pod的资源申请量。这里需要注意的是Initcontainer容器的资源用量,由于它只是在运行业务容器之前启动一段时间,并不会累加到Pod总资源申请量中,因此只是影响Pod资源申请的最大值

  containers:
  - name: nginx
    image: nginx:1.17.1
    resources:
      limits:  
        cpu: "2" 
        memory: "1Gi"
  - name: nginx
    image: nginx:1.20.2
    resources: 
      limits:  
        cpu: "1" 
        memory: "1Gi"   
  initContainers:
  - name: test-mysql
    image: busybox:1.30
    resources:
      limits:  
        cpu: "2" 
        memory: "3Gi"
  - name: test-redis
    image: busybox:1.30
    resources:
      limits:  
        cpu: "2" 
        memory: "1Gi"

最终得出这个Pod总的资源申请量为:CPU:3,Memory:3G。其中,CPU为3,两个业务容器CPU申请之和,大于任何一个InitContainers的CPU,而内存的3G来自InitContainers的内存申请。(init container 是串行执行完之后资源就释放了,所以不需要4GB)


nodeSelector

Node Affinity

podAffinity

Taints和Tolerations

【4】Kubelet


Kubelet是具体干活的组件,它接收Apiserver分配的启动容器的任务,然后拉起容器。

当然,如果收到销毁指令,同样会执行删除容器的操作。本地镜像也是由Kubelet负责维护,配合GC机制,删除无用的镜像和容器。除此之外,它还需要定时向Apiserver上报自己的状态,一方面告知Apiserver自身还存活着,另一方面为了将本节点的Pod状态、存储使用等信息上报到Apiserver。Kubelet启动一个主线程,用于保持和Apiserver的通信,主线程不能被阻塞,否则将无法定时完成上报,导致Apiserver将该节点设置为NotReady状态。所以,Kubelet会启动很多协程用于检测节点状态,回收废旧资源,驱赶低优先级Pod,探测Pod健康状态等。


syncLoop是Kubelet的核心,它通过一个死循环不断接收来自Pod的变化信息,并通过各种Manger执行对应的操作。

c206181223f448319112caab9433ec4f.png

【5】Kube-proxy


Kube-proxy是代理服务,它可以为Kubernetes的Service提供负载均衡。本质上是iptables或者ipvs实现的

Kubernetes将服务和Pod通过标签的方式关联到一起,通过服务的标签筛选找到后端的Pod,但服务的后端并非直接关联Pod,而是通过Endpoint(端点)关联。

Endpoint可以理解成“Pod地址:Pod端口”的组合,一个Endpoint可以加入多个服务中。

kube-proxy如何生成iptables规则的?


下面将通过一个服务的案例阐述kube-proxy如何生成iptables规则的。当我们创建一个服务后,默认情况下,Kubernetes会为每个服务生成一个集群虚IP。通过访问该IP便可以采用负载均衡的方式访问后端Pod中的服务。

1ac563e5df0d4b96a43b81a354cbbf03.png

service的yaml文件

apiVersion: v1
kind: Service
metadata:
  name: nginx-service-nodeport
  namespace: dev
spec:
  clusterIP: 10.96.70.31
  ports:
  - nodePort: 30001
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    name: nginx
  sessionAffinity: None
  type: NodePort
pod 分布在不同的节点

k get po -l name=nginx -owide
NAME              READY   STATUS    RESTARTS       AGE    IP               NODE    NOMINATED NODE   READINESS GATES
nginx-web-2ztjg   1/1     Running   6 (144d ago)   144d   10.244.166.133   node1   <none>           <none>
nginx-web-jl78g   1/1     Running   8 (144d ago)   144d   10.244.104.6     node2   <none>           <none>
访问nginx

kubectl exec -it nginx-web-2ztjg -- /bin/bash
root@nginx-web-2ztjg:/#
root@nginx-web-2ztjg:/#
root@nginx-web-2ztjg:/# curl -s 10.96.70.31 | grep -i welcome
<title>Welcome to nginx!</title>
<h1>Welcome to nginx!</h1>
Pod-to-Service 的iptables规则探究

Pod-to-Service 数据包都被PREROUTING链拦截

iptables -t nat -nvL PREROUTING

0e4f8c8cee264359ba645b0becaac560.png

这些数据包被重定向到KUBE-SERVICES链,在那里它们与所有配置的匹配,最终到达这些行:

iptables -t nat -nvL KUBE-SERVICES
Chain KUBE-SERVICES (2 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 KUBE-MARK-MASQ  all  --  *      *      !10.244.0.0/16        0.0.0.0/0            /* Kubernetes service cluster ip + port for masquerade purpose */ match-set KUBE-CLUSTER-IP dst,dst
   38  2192 KUBE-NODE-PORT  all  --  *      *       0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL
    0     0 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set KUBE-CLUSTER-IP dst,dst

为iptable设置alias

e7b8e4afc76f447c9a0ae23dc129e1ea.png

Pod 到svc的通信(紫色数据包)——完全在出口节点内实现,并依赖 CNI 实现 Pod 到 Pod 的可达性。

外部到svc的通信(灰色数据包)——包括任何外部来源的,最值得注意的是,节点到服务的流量。


iptables规则参考

Deployment的启动流程串起来


kubectl run(eg:kubectl run nginx–image=nginx–replicas=5)命令去创建一个Deployment。这个请求先到达Apiserver,Apiserver负责保存到Etcd,Controller manager中的Deployment控制器会监测到有一个Deployment被创建,此时会创建相应的ReplicaSet,ReplicaSet的控制器也会监测到有新的ReplicaSet创建这个事情,会根据相应的副本数调用Apiserver创建Pod。此时的Pod的主机字段是空的,因为还不知道将要在哪台机器上面启动,然后Scheduler开始介入,调度没有分配主机的Pod,通过预先设定的调度规则,包括节点标签匹配、资源使用量等选择出最合适的一台机器,在通过apiserver的bind请求将Pod的主机字段设置完成。那么Kubelet也监测到属于自己的节点有新容器创建的事件,于是便拉起一个容器,并上报给apiserver容器的状态

cloud-controller-manager


Kubernetes 1.6后面添加的,主要负责与IaaS云管理平台进行交互,主要是GCE和AWS。Kubernetes大部分部署目前都是在公有云环境中。Cloud-controller-manager通过调用云API获取计算节点状态,通过与云中负载均衡器交互,创建及销毁负载均衡,并且还可以支持云中存储的创建、挂载及销毁,主要是利用IaaS的能力扩展和增强Kubernetes的功能。

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
3月前
|
Kubernetes API 调度
Kubernetes 架构解析:理解其核心组件
【8月更文第29天】Kubernetes(简称 K8s)是一个开源的容器编排系统,用于自动化部署、扩展和管理容器化应用。它提供了一个可移植、可扩展的环境来运行分布式系统。本文将深入探讨 Kubernetes 的架构设计,包括其核心组件如何协同工作以实现这些功能。
341 0
|
3月前
|
Kubernetes API 调度
在K8S中,各个组件及其作用是什么?
在K8S中,各个组件及其作用是什么?
|
2月前
|
Kubernetes 容器
Kubernetes附加组件Dashboard部署实战篇
关于如何在Kubernetes集群中部署和配置Dashboard组件的详细实战指南,涵盖了从创建证书、部署Dashboard、设置服务访问到登录认证的完整流程。
403 0
Kubernetes附加组件Dashboard部署实战篇
|
3月前
|
存储 Kubernetes API
在K8S中,Kubernetes的组件有哪些?
在K8S中,Kubernetes的组件有哪些?
|
3月前
|
Kubernetes 调度 容器
k8s descheduler 组件安装
k8s descheduler 组件安装
|
3月前
|
存储 Kubernetes API
在K8S中,各组件是如何实现高可用的?
在K8S中,各组件是如何实现高可用的?
|
3月前
|
存储 Kubernetes API
在K8S中,各个组件及其作用是什么呢?
在K8S中,各个组件及其作用是什么呢?
|
3月前
|
Kubernetes 负载均衡 网络协议
在K8S中,DNS组件有什么特性?
在K8S中,DNS组件有什么特性?
|
3月前
|
存储 Kubernetes API
在K8S中,calico有哪些组件?都是做什么的?
在K8S中,calico有哪些组件?都是做什么的?
|
3月前
|
域名解析 Kubernetes 负载均衡
在K8S中,外部访问容器服务,比如说提供了一个域名,链路怎么走?数据经过哪些组件?
在K8S中,外部访问容器服务,比如说提供了一个域名,链路怎么走?数据经过哪些组件?
下一篇
无影云桌面