k8s基本概念

Namespace

Namespace 可以将一个物理的 cluster 逻辑上划分为多个虚拟 cluster 。每个cluster 就是一个Namespace 。不同的 Namespace 里的资源是完全隔离的。( 不能实现pod 间网络通讯隔离,仅用来限制资源对象名称的作用域)

default : 创建资源时,默认放入 这个 Namespace

kube-system : Kubernetes 自己创建的系统资源放入这个 Namespace

NameSpace

K8S 组件

Master组件

API Service : 提供 HTTP/HTTPS RESTful API, 即Kubernetes API, 是 Kubernetes Cluster 的前端接口,各种客户端 以及 Kubernetes其他组件可以通过它 管理 Cluster 的各种资源

Scheduler : 负责决定将 Pod 放在哪个 Node 上运行,在调度时会充分考虑 Cluster 的拓步结构,当前各个节点的负载,以及应用对高可用、性能、数据清和性的需求

Controller Manager : 负责管理 Cluster 各种资源,保证资源处于预期的状态。为满足不同业务,开发了多种 Controller

etcd : 负责保存 Kubernetes Cluster 的配置信息和各种资源的状态信息。当数据发生变化时,etcd 会快速地通知 Kubernetes相关组件。(只与 API Service 交互)

K8S架构

Pod网络: 实现 Pod 间的相互通信 eg: flannel

Node 节点
kubelet: 运行在 Cluster 所有节点上,负责启动 Pod 和容器。kubeletNodeagent ,当 Scheduler 确定在 某个 Node 上运行 Pod 后,会将 Pod 的具体配置信息(image,volume 等)发送给 该节点的 kubelet ,kubelet 根据这些信息创建和运行容器,并向 Master 报告运行状态。 kubelet 进程会定时向 APIService 汇报 “心跳”。一段时间内 心跳包没更新,那么 kubectl controller manager 就会将其 标记为 NodeLost

kube-proxy : 集群中每个节点上运行的网络代理, 实现 Kubernetes 服务(Service) 概念的一部分。每台机器上都运行一个 kube-proxy 服务,它监API serverserviceendpoint 的 变化情况,并通过 iptables 等来为服务配置负载均衡(仅支持 TCPUDP)

curl 127.0.0.1:10249/proxyMode : 查看 Kube-proxy 工作模式

Container Runtime : 容器运行环境是负责运行容器的软件,支持多个容器运行环境: Docker (1.20开始移除,预计 1.23 正式移除)、 containerdCRI-O 以及任何实现 Kubernetes CRI (容器运行环境接口)。

当通过 Service 的域名访问, 会通过 CoreDNS 解析出 Service 对应的 Cluster IP(虚拟 IP)。 请求到达宿主机网络后, 就会被 kube-proxy 所配置的 iptables 规则拦截,之后请求回被转发到每一个实际的后端 Pod 上面去

kubeadm,kubectl

kubeadm : 用于初始化 Cluster

客户端组件 kubectl
kubectl : Kubernetes 命令行工具,可以通过 kubectl 部署和管理应用,查看各种资源的,创建、删除和更新各种组件。( kubelet 会在API Server 上注册当前工作节点,定期向 Master 汇报节点资源使用情况,并通过 cAdvisor 监控容器和节点的资源占用状况)

1
2
3
4
kubectl get nodes  # 查看节点的状态
kubectl get pod --all-namespaces # 查看所有命名空间的pod
kubectl get pod --all-namespaces -o wide # 查看所有命名空间的pod,并显示详细信息
kubectl describe pod -n kube-system etcd-k8s01 # 查看namespace 为 kube-system pod 为 etcd-k8s01 的具体情况

service : Service是建立在一组Pod对象之上的资源抽象,它通过标签选择器
选定一组Pod对象, 定义了 外界访问一组特定 Pod 的方式 (eg : 这组Pod对象定义一个统一的固定访问入口), service有自己的 IP和端口,为 Pod 提供了负载均衡。
(Service对象创建完成后即可作为服务被各客户端访问,但要真正响应这些请求,还是要依赖于各后端的资源对象。)

(并不配置于任何主机或容器的网络接口之上,而是通过 Node 之上的 kube-proxy 配置为 iptablesipvs 规则,从而将发往此地址的所有流量调度至其后端的各 Pod 对象之上。Service 网络在 Kubernetes 集群创建时予以指定,而各 Service 的地址则在用户创建Service时予以动态配置。)


示例: ipvs 后端 3pod

  1. 生成一个 service 时, kube-proxy 会 先在宿主机创建 一个虚拟网卡 eg: kube-ipvs0, 并以 Service IP 作为 IP 地址。
  2. kube-proxy 通过 linuxIPVS 模块 为 这个 IP 地址 设置 3 个 虚拟主机 (负载均衡策略为 轮询). 虚拟主机的 ip 和 端口 正是 对应被代理的三个 pod

不需要为每个 pod 设置 iptalbes 规则,而是将这些 规则 放到内核态,降低了维护规则的代价。 但 包过滤,SNAT等 还需要 iptables 实现

Service架构

Service 主要有三种常用类型

  1. 仅用于集群内部通信的 ClusterIP 类型
  2. 接入集群外部请求的 NodePort 类型,它工作于每个节点的主机 IP 之上;
  3. LoadBalancer 类型,它可以把外部请求负载均衡至多个 Node 的主机 IPNodePort 之上。

此三种类型中,每一种都以其前一种为基础才能实现,而且第三种类型中的 LoadBalancer 需协同集群外部的组件才能实现,并且此外部组件并不接受 Kubernetes 的管理。

kube-proxy : 外界通过 service 访问 Pod, kube-proxyserviceTCP/UDP 数据流转发到后端的容器。如有多个副本, kube-proxy 会实现负载均衡。
(每个工作节点都需要运行一个 kube-proxy 守护进程,它能够按需为 Service资源对象生成 iptablesipvs 规则,从而捕获访问当前 ServiceClusterIP 的流量并将其转发至正确的后端Pod 对象)

Pod 网络 : 实现 Pod 间的相互通信 eg: flannel, calico

kube-dns(已默认为 coreDNS) : 为 Cluster 提供 DNS 服务,在执行 kubeadm init 时作为附加组件安装。是 pod 内的 NDS服务器

网络

Port

Port : :port 提供给集群内部访问 service 的入口
NodePort : :NodePort 提供给集群外部访问 service 的入口
targetPort : 从 PortNodePort 上来的数据最终经过 kube-proxy 流入到后端PodtargetPort 进入容器.
containerPort : 容器内部的 port,映射到 targetPort

eg:docker run -p 16379:6379 --name k8s-redis redis redis-server

16379(targetPort) 实际访问的 6379(containerPort)

当通过 Service 的域名访问, 会通过 CoreDNS 解析出 Service 对应的 Cluster IP(虚拟 IP)。 请求到达宿主机网络后, 就会被 kube-proxy 所配置的 iptables(或 ipvs) 规则拦截,之后请求回被转发到每一个实际的后端 Pod 上面去。

例子
1
kubectl run httpd-app --image=httpd --replicas=2
  1. kubectl 发送 部署请求到 API Server
  2. API Server 通知 Controller Manager 创建一个 deployment资源
  3. Scheduler 执行调度任务, 将两个副本 Pod 分发到 k8s02k8s03
  4. k8s02k8s03 上的 kubelet 再各自的节点上创建并运行 Pod

    执行 kubectl get podAPI Service 会从 etcd 中读取这些数据。

    Deployment示例

集群运行模式

  1. “独立组件”模式,系统各组件直接以守护进程的方式运行于节点之上,各组件之间相互协作构成集群
    独立组件
  2. “静态Pod模式”,除 kubeletDocker 之外的其他组件(如 etcdkube-apiserverkube-controller-managerkubescheduler 等)都是以静态 Pod 对象运行于 Master主机之上的
    静态Pod模式
  3. Kubernetes 的“自托管”(self-hosted )模式,它类似于第二种方式,将除了 kubeletDocker 之外的其他组件运行为集群之上的 Pod 对象,但不同的是,这些 Pod 对象托管运行在集群自身之上受控于 DaemonSet 类型的控制器,而非静态的 Pod 对象

使用 kubeadm 部署的 Kubernetes 集群可运行为第 2 种或第 3 种模式,默认为静态 Pod 对象模式,需要使用自托管模式时,kubeadm init 命令使用--features-gates=selfHosting 选项即可。第 1 种模式集群的构建需要将各组件运行于系统之上的独立守护进程中,其间需要用到的证书及 Token 等认证信息也都需要手动生成,过程烦琐且极易出错,一般不推荐使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
[root@centos01 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s01 Ready master 18m v1.18.6
k8s02 Ready <none> 15m v1.18.6
k8s03 Ready <none> 15m v1.18.6

[root@k8s01 ~]# kubectl label nodes k8s02 node-role.kubernetes.io/node=
node/k8s02 labeled
[root@k8s01 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s01 Ready master 18m v1.18.6
k8s02 Ready node 15m v1.18.6
k8s03 Ready <none> 15m v1.18.6

[root@centos01 ~]# kubectl get pod --all-namespaces # kubectl get pod -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system calico-kube-controllers-76d4774d89-xqw6g 1/1 Running 0 14m
kube-system calico-node-5xqsz 1/1 Running 0 14m
kube-system calico-node-cwv6n 1/1 Running 0 14m
kube-system calico-node-pfpr4 1/1 Running 0 14m
kube-system coredns-7ff77c879f-7frh7 1/1 Running 0 18m
kube-system coredns-7ff77c879f-hlzpn 1/1 Running 0 18m
kube-system etcd-k8s01 1/1 Running 0 18m
kube-system kube-apiserver-k8s01 1/1 Running 0 18m
kube-system kube-controller-manager-k8s01 1/1 Running 0 18m
kube-system kube-proxy-hmlxx 1/1 Running 0 15m
kube-system kube-proxy-nh96k 1/1 Running 0 15m
kube-system kube-proxy-x57zq 1/1 Running 0 18m
kube-system kube-scheduler-k8s01 1/1 Running 0 18m


[root@k8s01 ~]# kubectl get pod -A -o wide
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kube-system calico-kube-controllers-76d4774d89-xqw6g 1/1 Running 0 44m 172.18.235.129 k8s03 <none> <none>
kube-system calico-node-5xqsz 1/1 Running 0 44m 192.168.43.103 k8s03 <none> <none>
kube-system calico-node-cwv6n 1/1 Running 0 44m 192.168.43.101 k8s01 <none> <none>
kube-system calico-node-pfpr4 1/1 Running 0 44m 192.168.43.102 k8s02 <none> <none>
kube-system coredns-7ff77c879f-7frh7 1/1 Running 0 48m 172.18.73.66 k8s01 <none> <none>
kube-system coredns-7ff77c879f-hlzpn 1/1 Running 0 48m 172.18.73.65 k8s01 <none> <none>
kube-system etcd-k8s01 1/1 Running 0 48m 192.168.43.101 k8s01 <none> <none>
kube-system kube-apiserver-k8s01 1/1 Running 0 48m 192.168.43.101 k8s01 <none> <none>
kube-system kube-controller-manager-k8s01 1/1 Running 0 48m 192.168.43.101 k8s01 <none> <none>
kube-system kube-proxy-hmlxx 1/1 Running 0 45m 192.168.43.103 k8s03 <none> <none>
kube-system kube-proxy-nh96k 1/1 Running 0 45m 192.168.43.102 k8s02 <none> <none>
kube-system kube-proxy-x57zq 1/1 Running 0 48m 192.168.43.101 k8s01 <none> <none>
kube-system kube-scheduler-k8s01 1/1 Running 0 48m 192.168.43.101 k8s01 <none> <none>
[root@k8s01 ~]#