Kubernetes 核心对象概览详解

之前说了k8s对象共性的部分,包括typemeta定义了这个对象是什么,metadata定义了对象是谁,以及spec是用户的期望,往往都是用户输入的,status是对象的状态,一般是由控制器去更新。

typemeta和metadata是所有对象共性共有的,spec每个对象长的不一样。

Node


Node是Pod真正运行的主机,可以物理机,也可以是虚拟机。

为了管理Pod,每个Node节点上至少要运行container runtime ·

(比如 Docker 或者 Rkt)、Kubelet和 Kube-proxy服务。

node就是计算节点,k8s第一个层面的能力就是集群管理能力,将一堆的计算节点放到集群里面,那么每一个计算节点就代表一个node对象。

这部分是typemeta,这里v1前面其实是有group的信息的,但是node是core group,所以这里可以省略。

有些项目比如calico,是集群的cni插件,它想写一些属性到这个节点上面,但是又没有地方写,所以它将信息写到了annotation里面,所以annotation就是这个对象的扩展属性。

[root@master ~]# kubectl get node master -o yaml
apiVersion: v1
kind: Node
metadata:
  annotations:
    kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock
    node.alpha.kubernetes.io/ttl: "0"
    projectcalico.org/IPv4Address: 192.168.111.6/24
    projectcalico.org/IPv4IPIPTunnelAddr: 10.244.219.64
    volumes.kubernetes.io/controller-managed-attach-detach: "true"
  creationTimestamp: "2022-04-18T09:00:46Z"
  labels:
    beta.kubernetes.io/arch: amd64
    beta.kubernetes.io/os: linux
    kubernetes.io/arch: amd64
    kubernetes.io/hostname: master
    kubernetes.io/os: linux
    node-role.kubernetes.io/master: ""

spec对于节点来说信息非常少,也就是节点需要配置的属性非常少,也就是配置这个节点pod的cidr,其实也就是配置了这个节点的sybnet,也就是这个节点的pod能够使用哪个子网去分配ip。

spec:
  podCIDR: 10.244.0.0/24
  podCIDRs:
  - 10.244.0.0/24
  taints:
  - effect: NoSchedule
    key: node-role.kubernetes.io/master

最后就是status,当我们要去关心节点的,要去关心它的健康状况,它的近十年来等等这些信息,其实都是它的状态上报。

address:ip和主机名是什么

 allocatable:节点能够分配的资源是多少,包括cpu memory,资源并不是可以全部使用资源的,能够使用多少,这里面定义了

  capacity:这个节点最大的能力是多少,也就是有多少硬件资源

status:
  addresses:
  - address: 192.168.111.6
    type: InternalIP
  - address: master
    type: Hostname
  allocatable:
    cpu: "1"
    ephemeral-storage: "16871797528"
    hugepages-1Gi: "0"
    hugepages-2Mi: "0"
    memory: 1538360Ki
    pods: "110"
  capacity:
    cpu: "1"
    ephemeral-storage: 17878Mi
    hugepages-1Gi: "0"
    hugepages-2Mi: "0"
    memory: 1640760Ki
    pods: "110"

conditions包含了节点的健康状态,比如kernel有没有deadlock,比如你的cni插件是不是ready的,比如是否有足够的内存。硬盘是不是承压,比如pid是不是足够。

所有这些conditation最后决定了这个节点的健康状况。

如果不健康了,k8s就会去做一些事情来确保这个节点不会压垮。

  conditions:
  - lastHeartbeatTime: "2022-06-21T23:40:17Z"
    lastTransitionTime: "2022-06-21T23:40:17Z"
    message: Calico is running on this node
    reason: CalicoIsUp
    status: "False"
    type: NetworkUnavailable
  - lastHeartbeatTime: "2022-06-25T01:12:44Z"
    lastTransitionTime: "2022-06-23T20:05:46Z"
    message: kubelet has sufficient memory available
    reason: KubeletHasSufficientMemory
    status: "False"
    type: MemoryPressure
  - lastHeartbeatTime: "2022-06-25T01:12:44Z"
    lastTransitionTime: "2022-06-23T20:05:46Z"
    message: kubelet has no disk pressure
    reason: KubeletHasNoDiskPressure
    status: "False"
    type: DiskPressure
  - lastHeartbeatTime: "2022-06-25T01:12:44Z"
    lastTransitionTime: "2022-06-23T20:05:46Z"
    message: kubelet has sufficient PID available
    reason: KubeletHasSufficientPID
    status: "False"
    type: PIDPressure
  - lastHeartbeatTime: "2022-06-25T01:12:44Z"
    lastTransitionTime: "2022-06-23T20:05:46Z"
    message: kubelet is posting ready status
    reason: KubeletReady
    status: "True"
    type: Ready
  daemonEndpoints:
    kubeletEndpoint:
      Port: 10250

最后可以看到节点上有哪些镜像,镜像有哪些版本,大小是多少

  images:
  - names:
    - calico/node@sha256:b386769a293d180cb6ee208c8594030128a0810b286a93ae897a231ef247afa8
    - calico/node:v3.15.1
    sizeBytes: 262367223
  - names:
    - registry.aliyuncs.com/google_containers/etcd@sha256:735f090b15d5efc576da1602d8c678bf39a7605c0718ed915daec8f2297db2ff
    - registry.aliyuncs.com/google_containers/etcd:3.4.9-1
    sizeBytes: 253331281
  - names:
    - calico/cni@sha256:b86711626e68a5298542efc52e2bd3c64e212a635359b3a017ee0a8cd47b0c1e
    - calico/cni:v3.15.1
    sizeBytes: 217115249

nodeInfo:展示k8s版本和kernel的版本是什么,操作系统的版本是什么,如果要看k8s升级成功没,那么从这里面就可以看到 

 nodeInfo:
    architecture: amd64
    bootID: fb5e2f05-00af-4556-9305-a4cb32193d9b
    containerRuntimeVersion: docker://20.10.14
    kernelVersion: 3.10.0-1160.62.1.el7.x86_64
    kubeProxyVersion: v1.19.0
    kubeletVersion: v1.19.0
    machineID: 13872de9684d45898ae6f3614b134670
    operatingSystem: linux
    osImage: CentOS Linux 7 (Core)
    systemUUID: 45F34D56-0606-8E7E-69C8-41C8CB0E1ABF

Namespace


Namespace 是对一组资源和对象的抽象集合,比如可以用来将系统内部的对象划分为不同的项目组或用户组。

常见的pods,services,replication controllers和 deployments等都是属于某一个Namespace 的(默认是 default),而 Node,persistentVolumes 等则不属于任何 Namespace。

有了namespace就能够很好的将对象组织起来,通过权限控制和namespace隔离,就可以使得多个用户在同一集群里面,但是互不干扰。

当一个对象没有namespace属性,那么意味着它是none-namespace的对象,它是一个全局范围的,这个对象是属于整个集群的。

[root@master ~]# kubectl get ns default -o yaml
spec:
  finalizers:
  - kubernetes

这个finalizers意义是什么呢?当namespace对象被删除的时候,这个对象不会立刻消失,它依然是一个逻辑删除的状态,正是有个这个finalizers的属性,当去删除namespace对象的时候,首先它有一个namespace controller,它会去扫描当前这个namspace里面所有的归属对象,如果发现还有任何的子对象没有删除,它会先去删除这些子对象,当所有的子对象被删除,清理赶紧之后,它才会将namspace删除掉。

所以finalizers依然是锁对象的。

什么是pod


[root@master ~]# kubectl run --image=nginx nginx
pod/nginx created

 如何通过pod对象定义支撑应用运行


12要素:代码和配置是要分离的,当我们构建容器镜像的时候,我们只是将源码构建为二进制的可执行文件,然后再去打包为容器镜像,但是应用的配置我们希望通过外部注入的方式,通过voume mount方式或者环境变量的方式传进去,让这个应用来读取。

这样的好处是,当生产系统要去做配置变更的时候,我就不需要重新去打镜像,重新打镜像意味着要发布版本,整个ci/cd流水线要走一遍,所以这个整个过程是非常重的。有些参数动态调整,没必要走流水线,这些可以通过外部的环境变量,或者以卷的方式mount到这个pod里面。

这个来源是一个filed,是metadata.name,也就是这个环境变量希望获取这个pod的name,并且把它作为环境变量传进去。

configmap里面定义了键值对,希望从configmap的键值对里面去获取某个环境变量。

同理secret也一样的。

通过上面可以将来自不同来源的剪纸通过环境变量的方式传入到pod里面。

进入pod之后可以使用env这条命令就能够拿到所有的环境变量。

存储卷


pod网络


 资源限制


资源限制最后影响的就是调度器,它会去找一个满足你需求的节点去做调度。

健康检查


 一个pod启动了之后,它有可能还在做初始化,这就意味着在初始化的应用进程还不能接受网络流量,所以要去控制一下pod的状态,也就是我还没有就绪,我还不能够接受流量。

有些应用跑着跑着没有响应,出现大量的503,应用实例以及不能够正常工作了,是否需要帮你重启。

tcp stocket  查看某个端口,比如某个应用跑在80端口上面,你只需要去看80端口是否是活着的,你就能够知道它是否就绪了。

但是有时候80端口启动了并不代表我业务正常了,可能应用已经死掉了,那么可以通过HTTP,任何的微服务里面都要开放healthz的健康检查的uri,我们就可以针对uri去做健康检查。

如果这个文件存在,那么会返回code为0,这样就认为健康检查是通过的,如果这个文件不存在,那么这个return code为非0,也就是这次健康检查会失败。

ConfigMap


ConfigMap 用来将非机密性的数据保存到键值对中。

使用时,Pods 可以将其用作环境变量、命令行参数或者存储卷中的配置文件。

ConfigMap 将环境配置信息和 容器镜像解耦,便于应用配置的修改。

需要遵循代码和配置分离的原则,代码进容器镜像,配置通过外挂存储,或者通过环境变量的方式注入给pod。

有时候挂载一个存储并不是说要一块很大的空间,并不是说我要写很多的数据,更多的时候是希望将配置文件放进去,这种通常可以使用configmap挂载进去。

可以通过命令,create config file读取上面文件,将上面文件转化为configmap。

将整个文件读取出来了,key为文件名字,value就是文件里面所有的内容,这是最常用的一种方式,不管我配置文件长的是什么样的,它里面是不是key value,我们会将配置放在文件里面,比如yaml json xml,把它放到一个文件里面去,在正真去创建configmap的时候就会--from-file去读取这个文件,在config里面就会以文件名为key,文件内容为value。

当我们加上env-fiile的时候,行为和上面就不一样了,它会抛弃文件名字,解析了文件里面的所有key value,也就是解析了所有有效的键值对,并且放到这个configmap里面。

 除了configmap可以从文件当中读取,还可以给他一个输入,输入为key-value

上面是创建configmap,那么怎么使用呢?通过volume形式挂载

 当你应用程序启动的时候可以去对应的路径读取这个文件,完成应用配置和启动。

密钥对象(Secret)


  • Secret 是用来保存和传递密码、密钥、认证凭证这些敏感信息的对象。
  • 使用 Secret 的好处是可以避免把敏感信息明文写在配置文件里。
  • Kubernetes 集群中配置和使用服务不可避免的要用到各种敏感信息实现登录、认证等功能,例如访问 AWS存储的用户名密码。
  • 为了避免将类似的敏感信息明文写在所有需要使用的配置文件中,可以将这些信息存入一个Secret 对象,而在配置文件中通过 Secret 对象引用这些敏感信息。
  • 这种方式的好处包括∶意图明确,避免重复,减少暴漏机会。

你可能会说base64是对称加密,不安全,做个decode就可以看见。

在sercert里面它会将values以base64去做一次加密,这样你无法直观的看出它的值是什么,其次你可以通过权限控制,即使管理员要不然你看用户的secret,这样可以控制secret只被有权限的人去读,第三在存储的时候可以为secret配置加密,在存到etcd落盘的时候,secret可以以加密的形式存储,即使去etcd中读也读取不到真实的数据。

这样能够确保敏感的信息是安全的。

猜你喜欢

转载自blog.csdn.net/qq_34556414/article/details/125527995