Kubernetes

Kubernetes 网络 (4) Linux bridge

Submitted by Lizhe on Thu, 07/30/2020 - 02:00

要连接两个以上的 namespace , 需要使用 Linux bridge。

网桥是二层网络设备,两个端口分别有一条独立的交换信道,不共享背板总线,可以隔离冲突 (比集线器性能好一些,集线器共享同一条背板总线)

不过目前网桥已经被具有更多端口、可隔离冲突域的交换机取代了。

Linux 网桥 和 其他的网络设备区别在于, 普通设备(例如网卡)只有两端,从一端进去从另一端出来。

物理网卡从网络中收到数据,转发给 内核协议栈 , 从内核协议栈过来的数据会转发到外面的物理网络中。

 

Linux 网桥 有多个端口,数据可以从任何端口进来,然后取决于 MAC 地址,选择从哪个口出去,原理和交换机差不多

 

创建一个网桥

 

root@ubuntu:/home/lizhe# ip link add name br0 type bridge
root@ubuntu:/home/lizhe# ip link set br0 up
root@ubuntu:/home/lizhe# 

刚创建的网桥只有一端连接着协议栈

 

Kubernetes 网络 (2) veth pair

Submitted by Lizhe on Tue, 07/28/2020 - 02:55

veth 是虚拟以太网卡 ( Virtual Ethemet )的缩写。

veth 设备总是成对的,因此我们称之为 veth pair。 veth pair 常被用于 跨 network namespace 之间的通信,即分别将 veth pair 的两端放在不同的 namespace 里

20200728010538

仅有veth pair设备,容器是无法访问外部网络的。

从容器发出的数据包,实际上是直接进了 veth pair 设备的协议栈。

如果容器需要访问网络,则需要使用网桥等技术将 veth pair 设备接收的数据包转发出去。

 

Kubernetes 网络 (1) Linux network namespace

Submitted by Lizhe on Mon, 07/20/2020 - 07:15

如果你熟悉docker的namespace隔离机制,你应该知道docker的network也是通过 namespace隔离的

要了解kubernetes的网络原理,不得不提到 linux 的network namespace

Linux的 namespace 的作用是 隔离内核资源,命名空间会给其中的进程造成两个错觉

1. 它是系统内唯一的进程

2. 它独享系统的所有资源

network namespace是从 2.6 开始引入的,作用是隔离 Linux 系统的设备,ip 地址、端口、路由表 和 防火墙规则等网络资源

 

创建一个名为 netns1 的 新命名空间

 

sudo ip netns add netns1

当 ip 命令 创建了一个 新命名空间 之后,系统会在 /var/run/netns 目录下生成一个新的挂载点

挂载点的作用在于一方面是为了方便 命名空间管理,另一个方面是使 命名空间  可以在没有进程运行时也能继续存在

Kubernetes 源码 (19) 自动伸缩

Submitted by Lizhe on Sun, 07/19/2020 - 04:22

Kubernetes三种弹性伸缩:

  • HPA(Horizontal Pod Autoscaler):Pod个数自动扩/缩容
  • CA(Cluster Autoscaler):Node级别自动扩/缩容 cluster-autoscaler组件
  • VPA(Vertical Pod Autoscaler):Pod配置自动扩/缩容,主要是CPU、内存 addon-resizer组件

 

我们先来看一下HPA

这里不会演示如何创建HPA,我关注的是一些具体细节

Kubernetes 的自动伸缩特性在1.6和1.7本本之间重写过一次,有一些特性发生了变化

自动伸缩分为3个步骤

1. 获取被伸缩资源对象所管理的所有pod度量
2. 计算使度量数值达到(或接近)所指定的目标数值所需的pod数量
3. 更新被伸缩资源的 replicas 字段

 

如何获取度量数据

度量数据的流向

Pod -> cAdvisor -> Heapster -> Horizontal Pod AutoScaler

Kubernetes 源码 (18) 计算资源管理 4

Submitted by Lizhe on Fri, 07/17/2020 - 08:47

ResourceQuota 的接纳控制插件会检查将要创建的Pod 是否会引起 总资源量 超出 ResourceQuota。

ResourceQuota 也无法影响已经创建的 pod

 

apiVersion: v1

kind: ResourceQuota

metadata:

namespace: lizhe

name: lizhe-rq

spec:

hard:

pods: 5

requests.cpu: 1

requests.memory: 1Gi

limits.cpu: 1.5

limits.memory: 1Gi

configmaps: 2

persistentvolumeclaims: 5

replicationcontrollers: 5

secrets: 2

services: 2

 

 

Kubernetes 源码 (17) 计算资源管理 3

Submitted by Lizhe on Fri, 07/17/2020 - 06:15

这一节讨论 LimitRange 和 ResourceQuota

API Server 在接收到带有 pod 描述信息的 POST 请求时,LimitRanger 插件对 Pod spec 进行校验。如果校验失败,会直接拒绝。

LimitRange 对象的一个广泛应用场景就是阻止用户创建大于 单个节点资源量的 pod。如果没有LimitRange,API Server 将接受任何请求,然后永远无法调度成功。

LimitRange 资源中的 limits 应用于同一个命名空间中的 每一个 独立 Pod、容器或者其他类型对象。但是它并不会限制这个命名空间中所有pod的可用资源总量

ResourceQuota 才是控制总量的配置。


 

 

实验一

如果你像我一样使用的是 rancher,那么rancher界面上只能配置默认 requests 和 limits,但是并没有影响 min 和 max

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