K8s中的一些重要概念和常用指令

一米阳光zw 2022-08-06 08:11:20 阅读数:19

k8s概念指令常用重要

重要组件


k8s前身,谷歌borglet架构图

image-20220718171715435

K8S架构图

BorgMaster/api server的数量尽量保证为大于等于3的奇数,目的是避免选取主节点时票数相同

image-20220718172034965

etcd与结构图

etcd是键值对数据库,存储k8s集群所有重要数据(持久化)。官方将它定位成一个可信赖的分布式键值存储服务,它能够为整个分布式集群存储一些关键数据,协助分布式集群的正常运转,内部使用增量备份和完整备份保证数据完整性

image-20220718172726393

Kubernetes设计理念和功能其实就是一个类似Linux的分层架构

img

  • 核心层:Kubernetes最核心的功能,对外提供API构建高层的应用,对内提供插件式应用执行环境
  • 应用层:部署(无状态应用、有状态应用、批处理任务、集群应用等)和路由(服务发现、DNS解析等)
  • 管理层:系统度量(如基础设施、容器和网络的度量),自动化(如自动扩展、动态Provision等)以及策略管理(RBAC、Quota、PSP、NetworkPolicy等)
  • 接口层:kubectl命令行工具、客户端SDK以及集群联邦
  • 生态系统:在接口层之上的庞大容器集群管理调度的生态系统,可以划分为两个范畴
    • Kubernetes外部:日志、监控、配置管理、CI、CD、Workflow、FaaS、OTS应用、ChatOps等
    • Kubernetes内部:CRI、CNI、CVI、镜像仓库、Cloud Provider、集群自身的配置和管理等

网络解决方案Flannel

image-20220726115414290

image-20220721201032603

ETCD之Flannel提供说明

  • 存储管理Flannel可分配的IP地址段资源,防止IP冲突
  • 监控ETCD中每个pod的实际地址,并在内存中简历维护pod节点路由表

Replication Controller 名词解释 Replication Controller

Replication Controller 保证了在所有时间内,都有特定数量的Pod副本正在运行,如果太多了,Replication Controller就杀死几个,如果太少了,Replication Controller会新建几个,和直接创建的pod不同的是,Replication Controller会替换掉那些删除的或者被终止的pod,不管删除的原因是什么(维护阿,更新啊,Replication Controller都不关心)。基于这个理由,我们建议即使是只创建一个pod,我们也要使用Replication Controller。Replication Controller 就像一个进程管理器,监管着不同node上的多个pod,而不是单单监控一个node上的pod,Replication Controller 会委派本地容器来启动一些节点上服务(Kubelet ,Docker)。

Node 名词解释:Node

Node是Pod真正运行的主机,可以物理机,也可以是虚拟机。为了管理Pod,每个Node节点上至少要运行container runtime(比如docker或者rkt)、kubelet和kube-proxy服务。

image-20220803164948889

api server Kube-API Server

web UI、kubectl、scheduler都需要与它交互,不过他有replication controller为它缓存数据,不需要每个请求都经过api service,提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;Kubernetes API服务器为API对象验证和配置数据,这些对象包含Pod,Service,ReplicationController等等。API Server提供REST操作以及前端到集群的共享状态,所有其它组件可以通过这些共享状态交互

ReplicaSet(副本集) 名词解释:ReplicaSets

它跟 ReplicationController区别不大,但是rs支持集合式的selector,所以rc被新版本中被舍弃,一般使用Deployment来自动管理ReplicaSet,这样就不用担心跟其他机制不兼容的问题,比如RS不支持rolling-update但Deployment支持

pod 名词解释Pods

  • 一个pod(就像一群鲸鱼,或者一个豌豆夹)相当于一个共享context的配置组,在同一个context下,应用可能还会有独立的cgroup隔离机制,一个Pod是一个容器环境下的“逻辑主机”,它可能包含一个或者多个紧密相连的应用,这些应用可能是在同一个物理主机或虚拟机上。Pod 的context可以理解成多个linux命名空间的联合

    • PID 命名空间(同一个Pod中应用可以看到其它进程)
    • 网络 命名空间(同一个Pod的中的应用对相同的IP地址和端口有权限)
    • IPC 命名空间(同一个Pod中的应用可以通过VPC或者POSIX进行通信)
    • UTS 命名空间(同一个Pod中的应用共享一个主机名称)
  • 同一个pod内部通讯:同一个pod共享同一个网络命名空间,共享同一个Linux协议栈。Pod是Kubernetes的最小工作单元。每个Pod包含一个或多个容器。Pod中的容器会作为一个整体被Master调度到一个Node上运行。这意味着,即使是只有一个容器,Master也是要把它作为一个Pod调度运行的。

  • 两个pod之间的通讯:两个pod不在同一台主机:Pod的地址是与docker0在同一个网段的,但docker0网桥与宿主机网卡是两个完全不同的IP网段,并且不同Node之间的通信只能通过宿主机的物理网卡进行。将pod的ip和所在的Node的ip关联起来,通过这个关联让Pod可以互相访问

  • 两个pod在同一台主机:由docker0网桥直接转发请求至Pod2,不需要经过Flannel

  • Pod至Service的网络:目前基于性能考虑,全部为LVS维护和转发

Services 名词解释 Services

Kubernete Service 是一个定义了一组Pod的策略的抽象,我们也有时候叫做宏观服务。这些被服务标记的Pod都是(一般)通过label Selector决定的(下面我们会讲到我们为什么需要一个没有label selector的服务)

Volumes 名词解释 Volumes

容器中的磁盘的生命周期是短暂的,这就带来了一系列的问题,第一,当一个容器损坏之后,kubelet 会重启这个容器,但是文件会丢失-这个容器会是一个全新的状态,第二,当很多容器在同一Pod中运行的时候,很多时候需要数据文件的共享。Kubernete Volume解决了这个问题。容器中的一个进程看到文件系统由Docker镜像和磁盘构成,Docker镜像是文件系统的最底层,所有的磁盘都是挂在在这个镜像的特殊路径上。磁盘不能被挂在到被的磁盘或者创建硬链接。每个Pod中的容器必须是独立指定的取挂在这些磁盘。Kubernete 支持如下类型的volume

emptyDir
hostPath
gcePersistentDisk
awsElasticBlockStore
nfs
iscsi
glusterfs
rbd
gitRepo
secret
persistentVolumeClaim

kubelet kubectl

直接跟容器引擎交互实现容器的生命周期管理。可以存放容器,不仅仅是docker容器,实现pod和pod之间的访问和负载均衡,默认操作对象是firewall实现访问。它能够保证容器都在pod中,kubelet不会管理不是由Kubernetes创建的容器。kubelet接收一组通过各类机制提供给它的PodSpecs,确保这些PodSpecs中描述的容器处于运行状态且健康,当scheduler确定在某个node上运行pod后,会将pod的具体配置信息发送给该节点的kubelet,kubelet根据这些信息创建和运行容器,并向master报告运行状态。

scheduler

负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上

coredns

可以为集群中svc创建一个域名IP的对应关系解析

INGRESS CONTROLLER

官方只能实现四层代理,ingress可以实现7层代理

FEDETATION

提供一个可以跨集群中心多k8s统一管理功能

dashborad

给K8S集群提供一个B/S结构访问体系

DaemonSet(守护进程集) 名词解释:DaemonSet

有时候,应用程序每个节点需要的实例不超过一个。比如 FileBeat[1]这类日志收集器就是个很好的例子。为了从各个节点收集日志,其代理需要运行在所有节点上,但每个节点只需要一个实例。Kubernetes 的 DaemonSet 即可用于创建这样的工作负载。

ELK

提供K8S集群日志统一分析介入平台

PROMETHEUS

提供K8S集群的监控能力

HPA

容器水平扩展,支持cpu利用率、最大扩容数量、最小数量等参数。例如CPU利用率设置为80%时,自动扩展增加pod数量,低于80%时减少pod数量

StatefulSet(有状态集) 名词解释:StatefulSet

为了解决有状态服务的问题,对应的Deployments和ReplicaSets是为无服务而设计,应用场景包括:

  • 稳定的持久化存储,即pod重新调度后还能访问到相同的持久化数据,基于PVC来实现
  • 稳定的网络标志,即pod重新调度后其PodName和HostName不变,基于Headless Service来实现。
  • 有序部署,有序扩展,即下一个pod运行之前所有的必须都是running和ready状态,基于init containers
  • 有序收缩,有序删除,从N-1到0

Deployment(部署) 名称解释:Deployment

​ Deployment为Pod和ReplicaSet提供了一个声明式定义(declarative)方法,用来替代以前的ReplicationController来方便的管理应用,通过yaml文件定义应用。典型的应用场景包括:

  • 定义Deployment来创建Pod和ReplicaSet
  • 滚动升级和回滚应用
  • 扩容和缩容
  • 暂停和继续Deployment

kube-proxy(网络代理)

kube-proxy是8s集群中的每个节点上运行的代理,通过维护主机的网络规则并执行转发,实现了Kubernetes服务抽象。service在逻辑上代表了后端的多个pod,外界通过service访问pod。service接收到的请求就是通过kube-proxy转发到pod上的,kube-proxy服务负责将访问的service的tcp数据流转发到后端的容器。如果有多个副本,kube-proxy会实现负载均衡。

Secret 名词解释:Secret

Secret解决了密码、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者Pod Spec中。Secret可以以Volume或者环境变量的方式使用。

Secret有三种类型:

  • Service Account:用来访问Kubernetes API,由Kubernetes自动创建,并且会自动挂载到Pod的/run/secrets/kubernetes.io/serviceaccount目录中;
  • Opaque:base64编码格式的Secret,用来存储密码、密钥等;
  • kubernetes.io/dockerconfigjson:用来存储私有docker registry的认证信息。

kube-proxy中的IPVS模式 介绍

由于自己在构建项目时网络出现故障时稍微看了一下ipvs,有些点写的特别好记录一下

IPVS(IP virtual Server)构建在Netfilter之上,并将四层负载(OSI七层模型的传输层)作为Linux内核的一部分实现。IPVS 被合并到 LVS(Linux 虚拟服务器)中,它在主机上运行并充当真实服务器集群前面的负载平衡器。IPVS 可以将基于 TCP 和 UDP 的服务的请求定向到真实服务器,并使真实服务器的服务在单个 IP 地址上表现为虚拟服务。因此,IPVS 自然支持 Kubernetes Service。

img

上图只能解释OSI七层的工作模式,甚至连其中的网络层做什么都没有展现出来,再来看一下下图

img

OSI模型是一个高阶模型,它在其具体实现——TCP/IP模型上,TCP/IP四层模型与之相对应,可以看到,工作在第四层的协议是TCP/UDP协议,也就是说四层负载均衡,是主要作用于TCP协议报文之上,基于IP+端口来判断需要重定向的报文,并修改报文中目标IP地址以进行重定向的负载均衡方式。

典型问题:为什么要为 Kubernetes 使用 IPVS?

随着 Kubernetes 使用量的增长,其资源的可扩展性变得越来越重要。Kube-proxy,服务路由的构建块,依靠久经考验的 iptables 来实现核心支持的服务类型,例如 ClusterIP 和 NodePort。然而,iptables 难以扩展到数以万计的服务,因为它纯粹是为了防火墙目的而设计的,并且基于内核规则列表。尽管 Kubernetes 在 v1.6 版本中已经支持 5000 个节点,但带有 iptables 的 kube-proxy 实际上是将集群扩展到 5000 个节点的瓶颈。一个例子是在一个 5000 个节点的集群中使用 NodePort 服务,如果我们有 2000 个服务并且每个服务有 10 个 pod,这将导致每个工作节点上至少有 20000 条 iptable 记录,这会使内核非常忙碌。另一方面,在这种情况下,使用基于 IPVS 的集群内服务负载平衡可以提供很大帮助。IPVS 专为负载平衡而设计,并使用更高效的数据结构(哈希表),允许在后台实现几乎无限的规模。

Labels 名词解释 Labels

标签其实就一对 key/value ,被关联到对象上,比如Pod,标签的使用我们倾向于能够标示对象的特殊特点,并且对用户而言是有意义的(就是一眼就看出了这个Pod是尼玛数据库),但是标签对内核系统是没有直接意义的。标签可以用来划分特定组的对象(比如,所有女的),标签可以在创建一个对象的时候直接给与,也可以在后期随时修改,每一个对象可以拥有多个标签,但是,key值必须是唯一的

PV/PVC/StorageClass 名词解释:PV/PVC/StorageClass

  • PersistentVolume(PV)是集群中已由管理员配置的一段网络存储。 集群中的资源就像一个节点是一个集群资源。 PV是诸如卷之类的卷插件,但是具有独立于使用PV的任何单个pod的生命周期。 该API对象捕获存储的实现细节,即NFS,iSCSI或云提供商特定的存储系统。

  • PersistentVolumeClaim(PVC)是用户存储的请求。 它类似于pod。Pod消耗节点资源,PVC消耗存储资源。 pod可以请求特定级别的资源(CPU和内存)。 权限要求可以请求特定的大小和访问模式。

  • 虽然PersistentVolumeClaims允许用户使用抽象存储资源,但是常见的是,用户需要具有不同属性(如性能)的PersistentVolumes,用于不同的问题。 群集管理员需要能够提供多种不同于PersistentVolumes的PersistentVolumes,而不仅仅是大小和访问模式,而不会使用户了解这些卷的实现细节。 对于这些需求,存在StorageClass资源。StorageClass为管理员提供了一种描述他们提供的存储的“类”的方法。 不同的类可能映射到服务质量级别,或备份策略,或者由群集管理员确定的任意策略。 Kubernetes本身对于什么类别代表是不言而喻的。 这个概念有时在其他存储系统中称为“配置文件”

Dockershim Dockershim:历史背景

img

自 Kubernetes v1.24 起,Dockershim 已被删除,但由于本人搭建的版本较低所以也有一些接触,放到底部有兴趣的可以了解一下

在 Kubernetes 的早期,我们只支持一个容器运行时,那个运行时就是 Docker Engine。 那时,并没有太多其他选择,而 Docker 是使用容器的主要工具。 我们开始添加更多的容器运行时,比如 rkt 和 hypernetes,很明显 Kubernetes 用户希望选择最适合他们的运行时。因此,Kubernetes 需要一种方法来允许集群操作员灵活地使用他们选择的任何运行时。容器运行时接口 (CRI) 已发布以支持这种灵活性。 CRI 的引入对项目和用户来说都很棒,但它确实引入了一个问题:Docker Engine 作为容器运行时的使用早于 CRI,并且 Docker Engine 不兼容 CRI。 为了解决这个问题,在 kubelet 组件中引入了一个小型软件 shim (dockershim),专门用于填补 Docker Engine 和 CRI 之间的空白, 允许集群操作员继续使用 Docker Engine 作为他们的容器运行时基本上不间断。然而,这个小软件 shim 从来没有打算成为一个永久的解决方案。 多年来,它的存在给 kubelet 本身带来了许多不必要的复杂性。由于这个 shim,Docker 的一些集成实现不一致,导致维护人员的负担增加,并且维护特定于供应商的代码不符合我们的开源理念。 为了减少这种维护负担并朝着支持开放标准的更具协作性的社区迈进, 引入了 KEP-2221, 建议移除 dockershim。随着 Kubernetes v1.20 的发布,正式弃用。

k8s常用指令


# 查看系统中的pods服务,不加默认default
kubectl get pods -n kube-system
# 列出当前命名空间下的全部 Pods,并显示更详细的信息
kubectl get pods -o wide
# 设置多个副本
kubectl scale --replicas=3 deployment/nginx-deployment
# 查看副本数量并根据名称删除一个
kubectl get pod -o wide
kubectl delete pod POD-NAME
# 在容器内部执行命令
示例:kubectl exec POD [-c CONTAINER] -- COMMAND [args...]
kubectl exec 123456-7890 date # 默认在pod 123456-7890的第一个容器中运行“date”并获取输出
# 在pod 123456-7890的容器ruby-container中运行“date”并获取输出
kubectl exec 123456-7890 -c ruby-container date
# 切换到终端模式,将控制台输入发送到pod 123456-7890的ruby-container的“bash”命令,并将其输出到控制台错误控制台的信息发送回客户端
kubectl exec 123456-7890 -c ruby-container -i -t -- bash -il
# 扩容
kubectl scale deployment nginx-deployment --replicas 10
# 更新镜像也比较简单
kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
# 回滚
kubectl rollout undo deployment/nginx-deployment
# 列出当前命名空间下的所有 services
kubectl get services / kubectl get svc
# 列举所有 PV 持久卷,按容量排序
kubectl get pv --sort-by=.spec.capacity.storage
# 查看系统中所有deployment
kubectl get deployment
# 将 /tmp/foo_dir 本地目录复制到远程当前命名空间中 Pod 中的 /tmp/bar_dir
kubectl cp /tmp/foo_dir my-pod:/tmp/bar_dir
# 将 /tmp/foo 从远程 Pod 复制到本地 /tmp/bar
kubectl cp my-namespace/my-pod:/tmp/foo /tmp/bar
# 获取一个 Deployment 的 Pod 的日志(单容器例子)
kubectl logs podName
# 设置多个副本
kubectl scale --replicas=3 deployment/nginx-deployment
# 删除一个指定的pod
kubectl delete podpodName
# 将容器内部的80端口映射到svc的30000端口
```java
kubectl expose deployment nginx-deployment --port=30000 --target-port=80
# 查看当前配置的虚拟服务和各个RS的权重
ipvsadm -Ln
版权声明:本文为[一米阳光zw]所创,转载请带上原文链接,感谢。 https://blog.csdn.net/qq_42910468/article/details/126185352