Kubernetes 源码 (15) 计算资源管理

Submitted by Lizhe on Thu, 07/16/2020 - 03:11

先来说一下这个话题的重要性,如果创建pod时不对 容器 的资源进行限制,很可能会发生以下情况

某个 container 在 某个时刻 消耗光了所有的 cpu 时间或者 node 的内存,造成 kubelet 进程本身无响应或者是 node 心跳停止

此时,master 会认为这个 node 节点已经下线,然后会导致这个node上所有的pod开始向其他node节点迁移

 

在创建一个pod时,可以指定 容器对cpu和内存的资源请求量 和 限制量
这里所有的配置都是对于 容器 生效的,并不是对 pod。pod 使用的资源是 它所运行的所有容器的资源总和

 

对于 cpu 资源

Request 表现出来的是 Cgroups 中的进程在 CFS 调度器上的 cpu.shares,而 Limit 则是 CFS 上的带宽限制

简而言之,request 和 docker 本身的 cpu 资源分配原理一样,是按照使用百分比分配的,例如

容器A 和 容器B 按照 1:4 分配,那么当两个容器满载时,容器A最高可以使用20%的cpu资源,容器B最高可以使用80%的cpu资源

Kubernetes 源码 (14) Api Server 认证机制 4

Submitted by Lizhe on Wed, 07/15/2020 - 10:50

RBAC 授权插件将用户角色作为决定用户是否能执行操作的关键因素。

主体 ( 人、sa 或者 group ) 和 一个或者多个 role 关联,每个 role 被允许在特定的资源上执行特定的 动作

如果一个用户有多个角色,他们可以做任何角色允许的动作。

 

RBAC 通过创建 四种 特定的 Kubernetes 资源来完成

Role 和 ClusterRole

它们指定了在资源上可以执行哪些动作

RoleBinding 和 ClusterRoleBinding 

它们将上述角色绑定到特定的 用户、组 或者 sa 上

之前我们使用过

kubectl create clusterrolebinding permissive-binding --clusterrole=cluster-admin --group=system:serviceaccounts:lizhe

Kubernetes 源码 (12) Api Server 认证机制 2

Submitted by Lizhe on Wed, 07/15/2020 - 06:26

Kubernetes 将连接到 api server 的客户端分为两种

真实的人
pod 中的应用 ( service account )

正常用户 和 service account 都可以属于一个或者多个组

常用组:

system:unauthenticated 用于所有认证插件都不会认证认证客户端身份的请求

system:authenticated 组会自动分配给一个成功通过认证的用户

system:serviceaccounts 包含所有在系统中的 ServiceAccount

system:serviceaccounts:<namespace> 组包含了所有在特定命名空间中的 ServiceAccount

下面来做实验

 

首先是失败实验

我们在 lizhe namespace 下面创建一个 ubuntu 实例,

Kubernetes 源码 (11) Api Server 认证机制

Submitted by Lizhe on Tue, 07/14/2020 - 07:10

上一节中虽然我安装 coredns的尝试失败了,但是我们仍然可以看到 dns 组件是如何安装的

安装过程中有一个错误

failed with No API token found for service account "coredns" 

我们选择禁用 ServiceAccount 简单粗暴的规避了这个错误

将:KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota"

改为:KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ResourceQuota"

 

所以这一节我打算研究一下 ServiceAccount

Kubernetes 源码 (10) CoreDNS

Submitted by Lizhe on Tue, 07/14/2020 - 02:18

曾几何时,我第一次使用kubeadm安装 kubernetes 1.10 时,kubernetes自带的还是 kube-dns,

在一些教材中也一直把kube-dns作为dns服务在k8s上的默认实现。

趁此机会这里我要好好捋一捋,在kubernetes1.11开始,CoreDNS就开始作为 kubeadm的默认实现了

传统的kubeDNS由3个部分组成

  1. kubedns: 依赖 client-go 中的 informer 机制监视 k8s 中的 Service 和 Endpoint 的变化,并将这些结构维护进内存来服务内部 DNS 解析请求。
  2. dnsmasq: 区分 Domain 是集群内部还是外部,给外部域名提供上游解析,内部域名发往 10053 端口,并将解析结果缓存,提高解析效率。
  3. sidecar: 对 kubedns 和 dnsmasq 进行健康检查和收集监控指标。

 

在 kubedns 包含两个部分, kubedns 和 skydns。

Kubernetes 源码 (9) 阶段总结一

Submitted by Lizhe on Tue, 07/14/2020 - 02:01

目前为止,我们已经使用源码编译过了kubernetes的代码,并且使用编译的代码手动启动了一套简单的kubernetes实现

我们使用最基本的三个组件运行了基础 pod

  1. kubelet:在集群中每个节点上运行的代理,负责容器真正运行的核心组件
  2. 为 api-server 安装了 etcd
  3. kube-apiserver:Kubernetes 控制平面的组件,提供资源操作的唯一入口
  4. 容器运行时(Docker)

 

然后使用

5. kube-scheduler 自动分配pod 到 node 节点
6. 并且配合 kube-controller-manager 自动创建了 pod instance
7. 使用kube-proxy 基于 nodepot 对外暴露了 nginx 服务

 

这样一个最基本的kubernetes集群就启动起来了,下面我会尝试一些非必要组件 

Kubernetes 源码 (8) kube-proxy

Submitted by Lizhe on Mon, 07/13/2020 - 06:52

kube-proxy是Kubernetes的核心组件,部署在每个Node节点上,它是实现Kubernetes Service的通信与负载均衡机制的重要组件; kube-proxy负责为Pod创建代理服务,从apiserver获取所有server信息,并根据server信息创建代理服务,实现server到Pod的请求路由和转发,从而实现K8s层级的虚拟转发网络。

我们知道kube-proxy支持 iptables 和 ipvs 两种模式, 在kubernetes v1.8 中引入了 ipvs 模式,在 v1.9 中处于 beta 阶段,在 v1.11 中已经正式可用了。iptables 模式在 v1.1 中就添加支持了,从 v1.2 版本开始 iptables 就是 kube-proxy 默认的操作模式,ipvs 和 iptables 都是基于netfilter的,那么 ipvs 模式和 iptables 模式之间有哪些差异呢?

Kubernetes 源码 (7) kube-controller-manager

Submitted by Lizhe on Sun, 07/12/2020 - 09:45

先来一个备注,如果按照下面内容启动之后 你的pod仍然 pending

要注意 请按照下面顺序启动以下这三个组件

 

sudo ./kubelet --pod-manifest-path=pods --fail-swap-on=false --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.2 --kubeconfig=kubeconfig.yaml

./kube-scheduler --kubeconfig=kubeconfig.yaml

./kube-controller-manager --kubeconfig=kubeconfig.yaml

书接上回,上一篇文章里我们启动了 scheduler 之后,pod 确实被自动分配了,但是状态却仍然是pending

这里的根本原因是我们还没有启动 kube-controller-manager , 

Kubernetes 源码 (6) kube-scheduler

Submitted by Lizhe on Wed, 07/08/2020 - 03:08

 

Scheduler 是以一种 多人负责同一工作,然后基于投票激活一个主工作节点 的方式运作的。

领导者选举机制可以保证高可用性,但是正常工作的Scheduler节点只有一个,其他节点作为候选节点处于阻塞状态。

在领导者节点因某些原因而退出后,其他候选节点则通过选举机制竞选,成为新领导的节点将接替原来节点的工作。

 

选举机制是通过分布式锁来实现的,

  1. 分布式锁依赖于 Etcd 上的一个 key,key 的操作都是原子操作,将 key 作为分布式锁,它有两种状态——存在和不存在。

  2. key(分布式锁)不存在时:多节点中的一个节点成功创建该 key(获得锁)并写入自身节点的信息,获得锁的节点被称为领导者节点。领导者节点会定时更新(续约)该 key 的信息。

  3. key(分布式锁)存在时:其他节点处于阻塞状态并定时获取锁,这些节点被称为候选节点。候选节点定时获取锁的过程如下:定时获取 key 的数据,验证数据中领导者租约是否到期,如果未到期则不能抢占它,如果已到期则更新 key 并写入自身节点的信息,更新成功则成为领导者节点。