Kubernetes 源码 (16) 计算资源管理 2

Submitted by Lizhe on Fri, 07/17/2020 - 02:18

上一节中我们出现了 OOM kill ,pod 的状态会变成 

CrashLoopBackOff 

CrashLoopBackOff 状态表示 Kubelet 还没有放弃,它意味着在崩溃之后Kubelet会增加下次重启的间隔时间

间隔时间会按照 10秒,20秒,40秒,80秒,160秒,最终收敛于 300 秒

一旦间隔时间到达 300 秒,Kubelet 将会以固定的 300 秒 为间隔时间对容器进行无限重启

 


 

在容器中看到的始终是节点的整体内存,而不是容器被限制使用的内存

在容器中看到的始终是节点的整体cpu内核,而不是容器被限制使用的内核,而且容器的进程会随机在node的内核上调用


 

下面的内容也很重要

Pod QoS 等级

Qos 等级直接影响当资源耗尽时,哪些容器会被优先杀死的问题

需要特别注意的是,QoS 等级是作用于 Pod 的, 但是决定 QoS等级的是 运行在 Pod 上的所有 容器,并且被杀死的是容器,而不是 pod,运行在同一个pod上的容器,拥有相同的QoS

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 ,