Kubernetes Q&A

Kubernetes Q&A

kubernetes 集群规模,使用的版本以及部署方式,master节点跑了什么组件,每个组件的作用?

规模:规模不要超过1000个节点,节点过多的话建议使用多集群的管理方式。

版本:关于版本问题个人有一个建议,那就是按照基数版本或者偶数版本持续升级,例如 1.12-->1.14-->1.16;或者1.13-->1.15-->1.17这样进行升级。尤其是生成环境,不建议频繁的更改和升级。

部署:个人比较推荐使用kubeadm进行部署,结合ansbile进行自动化部署和升级。当然如果本身有一定的go语言开发能力,而且对k8s需要进行源码编译和定制的化,使用二进制部署更佳。

Master:一般master回跑etcd集群、ApiServer、ControllerManager、Scheduler,master节点本身也属于集群中,当然也会跑Kubelet以及Kube-Proxy。

Scheduler工作的原理

根据调度算法将pod调度至最合适的工作节点

  • Predicates(预选)--- 输入的是所有节点,输出是满足预选条件的节点。kube-scheduler根据预选策略过滤掉不满足策略的Nodes。如果某节点的资源不足或者不满足预选策略的条件;例如Node的label必须与Pod的selector一致时,则无法通过预选。
  • Pirorities(优选)--- 输入是预选阶段筛选出的节点,优选会根据优先策略为通过预选的Nodes进行打分排名,选择得分最高的Node。例如,资源越富裕、负载越小的Node可能具有越高的排名。

Scheduler: 是一个策略丰富、拓扑感知、工作负载特定的功能,调度器显著影响可用性、性能和容量。调度器需要考虑个人和集体资源的资源要求、服务质量要求、硬件/软件/政策约束、亲和力和反亲和力规范、数据局部性、负载间干扰、完成期限等。

kube-scheduler给一个pod做调度选择包含两个步骤:

  • 过滤:过滤阶段会将所有满足pod调度需求的node选出来。例如,PodFitsResources过滤函数会检查候选Node的可用资源能否满足Pod的资源请求。在过滤后,得出一个node列表,里面包含了所有可调度节点,通常情况下,这个node列表包含不止一个node。如果这个列表是空的,代表这个pod不可被调度。
  • 打分: 打分阶段,调度器会为pod从所有可调度节点中选取一个最合适的node。根据当前启用的打分规则,调度器会给每一个可调度节点进行打分。最后kube-scheduler会将pod调度到得分最高的node上。如果存在多个得分最高的node,kube-scheduler会从中随机选取一个。

apiserver工作原理,多少节点对外提供服务,负责均衡高可以用如何实现?

一般情况下,3台apiserver已经够用,如果集群规模较大,apiserver和etcd节点都需要进行扩容。

关于负载:

apiserver服务是一个无状态服务,可以使用Nginx+Keepalived、HAProxy+Keepalived以及云厂商的LB。

受限于云厂商不支持vrrp协议,也可以选择Nginx Local Proxy 这种方式,此种方式不再受限于你的SDN网络环境。也可以避免单节点故障。

关于此种部署方式可参考青木的博客https://qingmu.io/2019/05/17/Deploy-a-highly-available-cluster-with-kubeadm/

contorller-manager和etcd通信吗?

不通信,controller-manager和 scheduler他们都是和kube-apiserver通信,然后kube-apiserver再和etcd通信。将数据存储在etcd集群中。

headless service(无头服务)使用场景

  • 不使用ClusterIP,他直接解析到关联的POD
  • 当部署有状态应用(statefulset)的副本集时,必须使用headless service
  • headless service 的对应的每一个Endopoints,即每一个Pod,都会有对应的DNS域名解析,这样Pod之间就可以互相访问。

k8s集群使用的网络方案,pod如何与node进行网络通信?

k8s网络通信

  1. 容器间通信: 同一个pod内的多个容器间通信,通过lo
  2. pod间通信: pod IP <---> pod IP
  3. Pod与service通信。通过ipvs和iptables进行地址转换
  4. Service与集群外部客户端的通信 使用Ingress或NodePort

CNI: containers network interface 容器网络接口插件

解决方案:虚拟网桥 多路复用(MACVlan) 硬件交换(SR-IOV)

flannel支持多种后端:

(1): vxlan 包括vxlan 和 Diretrouting

(2)Host-gw: host gateway

(3)UDP

flannel的配置参数:
Network: flannel使用CIDR格式的网络地址,用于为pod配置网络功能 10.244.0.0/16
Subnetlen: 把network切分子网供各个节点使用时,使用多长的掩码进行切分,默认为24位。
Subnetmin: 指定子网从哪一个子网开始 10.244.10.0/24
SubnetMax: 指定子网在哪一个结束 10.244.100.0、24
Backend: vxlan, host-gw, udp

Flannel: 一般情况下使用vxlan技术为各节点创建一个可以互通的Pod网络,使用的端口为UDP8472(需要开放该端口,如公有云AWS等)。flanneld第一次启动时,从etcd获取配置的Pod的网段信息,为本节点分配一个未使用的地址段,然后创建flanneld.1的网络接口,flannel将分配给自己的Pod网段信息写入/run/flannel/subnet.env文件,docker后续会使用这个文件中的环境变量设置docker0网桥 ,从而从这个地址段为本节点的所有pod容器分配IP。

Calico:在宿主机部署calico作为虚拟路由器,基于BGP协议,生成路由表;容器通过veth pair到达宿主机的网络名称空间上。支持网络策略,且性能较好,复杂度较高。

k8s集群节点需要关机维护,应该怎么操作?

# 驱逐node节点上的pod,并忽略daemonset
$ kubectl drain k8s-node01 --force --ignore-daemonsets
# 关机
$ init 0

Pod的控制器类型,crd需要定义什么?

  • Pod控制器: deployment, ReplicationController, StatefulSet, DaemonSet, CronJob, Job
  • CRD(CustomResourceDefinition):自定义资源定义,在k8s中一切都可视为资源,kubernetes1.7之后增加了对CRD自定义资源二次开发能力来扩展 kubernetes api,通过CRD我们可以向API中增加新资源类型,而不需要修改kubernetes源码来创建自定义的API server,该功能大大提高了kubernetes的扩展能力。当你创建一个新的CRD时,kubernetes api服务器将为你指定每个版本创建一个新的RESTful资源路径,我们可以根据该api路径来创建一些我们自定义的类型资源。CRD可以是命名空间的,也可以是集群范围的,由CRD的作用域中所指定的,与现有的内置对象一样,删除名称空间将删除该名称空间中的所有自定义对象。CRD本身是没有名称空间的,所有名称空间都可以使用。

存活性监测好就绪性监测的实现方式

readiness probe, liveness probe:HTTP请求 TCP链接 命令行等

Pod如何平滑升级

minReadySeconds: 5
strategy:
  type: RollingUpdate
  rollingUpdate:
    maxSurge: 30%
    maxUnavailable: 30%

k8s内核及文件系统需要哪些设置

  • 开启网桥模式
  • 禁止使用swap空间
  • 开启OOM
  • 不检查物理内存是否够用
  • 关闭ipv6防止出发docker bug
  • 设置系统时区
  • 设置HostNmae
  • tcp_tw_recycle关闭与k8s的NAT冲突
  • 升级内核到4.4+

存储卷的使用方式

  • 动态存储使用 storageclass
  • 静态存储使用 persistentvolume

对外服务的pod暴露方式有哪些

  • hostNetwork: 在pod中使用该配置,在这种pod中运行的应用程序可以直接看到pod启动的主机的网络接口
  • hostPort: 直接将容器的端口与所调度的节点上的端口路由,这样用户就可以通过主机的IP来访问Pod
  • NodePort:是k8s里一个广泛应用的服务暴露方式。k8s中的service默认情况都是使用ClusterIP这种类型,会产生一个只能在内部访问的ClusterIP,如果想能够直接访问service,需要将service type修改为nodePort。同时给service指定一个nodeport值(30000-32767),用--service-node-port-range定义。
  • loadBalancer: 只能在service上定义,是公有云提供的负载均衡器。
  • Ingress: ingress controller是由k8s管理的负载均衡容器,它一般包含一个nginx 或 Haproxy负载均衡器和一个控制器守护进程。

Traefik实现原理

Traefik 作为一种边缘路由器,能够动态感知后端服务实例变化,进行动态调整并转发配置,会与apiserver进行交互,发现k8s集群内部容器状态变化。

APIServer详解

apiserver对外提供增删改查etcd中资源配置数据,worker节点kubelet同master节点的apiserver进行交互,master节点的scheduler和controller manager组件也需要同api server进行交互以获取和修改对应资源的状态。

apiserver三层认证

kubernetes提供了多种认证方式,比如客户端证书、静态tokern、静态密码文件、ServiceAccountTokens等等。你可以同时使用一种或多种认证方式。只要通过任何一个都被认作认证通过。

  • 客户端证书认证:也叫做TLS双向认证,也就是服务器客户端互相验证证书的正确性,在都正确的情况下协调通信加密方案。为了使用这个方案,api-server需要用-client-ca-file选项来开启.
  • 静态token: 当我们有非常多的node节点时,手动为每个node节点配置TLS认证比较麻烦,这时就可以用到引导token的认证方式,前提是需要在api-server 开启experimental-bootstrap-token-auth特性,客户端的doken信息与预先定义的token匹配认证通过后,自动为node颁发证书。当然引导token是一种机制,可以用到各种场景中。
  • Service Account Tokens 认证: 有些情况下,我们希望pod内部访问api-server,获取集群的信息,甚至对集群进行改动。针对这种情况,kubernetes提供了一种特殊的认证方式,Service Account。Service Account主要包含了三个内容: namespace token和CA。namespace指定了pod所在的namespace ,CA用于验证apiserver的证书,token用作身份验证。他们都通过mount的方式保存在pod的文件系统中。

Kubernetes授权

在kubernetes1.6以及之后的版本中,新增了角色访问控制机制(Role-Based Acess, RBAC)让集群管理员可以针对特定使用者或服务账号角色,进行更精准的资源访问控制。在RBAC中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。在一个组织中,角色是为了完成各种工作而创造,用户则依据它的责任和资格来被指派相应的角色,用户可以很容易地从一个角色被指派到另一个角色。

Kubernetes 准入控制

(AdmissionControl)准入控制本质上为一段准入代码,在对kubernetes api的请求过程中,顺序为:先经过认证&授权,然后执行准入操作,最后对目标对象进行操作。这个准入代码在api-server中,而且必须被编译到二进制文件中才能被执行。

在对集群进行请求时,每个准入控制代码都按照一定顺序执行。如果有一个准入控制拒绝了此次请求,那么整个请求的结果将会立即返回,并提示用户相应的EROOR信息。常用的控制代码如下:

  • AlwaysAdmit: 允许所有请求
  • AlwaysDeny: 禁止所有请求,多用于测试环境
  • ServiceAccount: 它将serviceAccounts实现了自动化,它会辅助ServiceAccount做一些事情,比如pod没有ServiceAccount属性,它会自动添加一个default,并确保POD的ServiceAccount始终存在。
  • LimitRanger: 它会观察所有的请求,确保没有违反已经定义好的约束条件,这系统条件定义在namespace中的LimitRanger对象中。如果在kubernetes中使用LimitRanger对象,则必须使用这个插件。
  • NamespaceExists: 它会观察所有的请求,如果请求尝试创建一个不存在的namespace,则这个请求被拒绝。

Controller Manager

Controller Manager: 以守护进程的形式运行着kubernetes几个核心的控制循环(也就是控制器),包括deploymentreplicasetnamespaceserviceaccountnode等等,通过调用Api Server的 list watch接口来监控自己负责的资源的配置变化。

ETCD 分布式的K-V存储系统

  • HTTP Server(Grpc Server):主要处理client(客户端)的操作请求以及节点间的数据同步和心跳保持。
  • raft状态机:通过对raft一致性协议的实现来保证etcd集群的高可用性。
  • store:负责Etcd中事务操作的逻辑,是api server的命令的具体实现。
  • wal存储:负责具体的数据持久存储操作。它分为两部分,entry负责实际的日志数据存储(在etcd里数据的存储都是带版本号的,对于同一个键值可能会有多个版本的记录存在,所以数据实际的存储方式即通过事务日志进行存储,而在内存里则存有键和版本号的映射关系以方便查询)。Snapshot则是对日志数据的状态存储以防止过多的数据存在。

etcd集群的备份

$ ETCDCTL_API=3 etcdctl --cacert="${CACERT}" --cert="${CERT}" --key="${KEY}" 
  --endpoints=${ENDPOINTS} 
  snapshot save /data/etcd_backup_dir/etcd-snapshot-`date +%Y%m%d`.db
原文地址:https://www.cnblogs.com/skymyyang/p/12864998.html