Kubernetes 核心对象概览详解
之前说了k8s对象共性的部分,包括typemeta定义了这个对象是什么,metadata定义了对象是谁,以及spec是用户的期望,往往都是用户输入的,status是对象的状态,一般是由控制器去更新。typemeta和metadata是所有对象共性共有的,spec每个对象长的不一样。Node是Pod真正运行的主机,可以物理机,也可以是虚拟机。为了管理Pod,每个Node节点上至少要运行contain
之前说了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中读也读取不到真实的数据。
这样能够确保敏感的信息是安全的。
更多推荐
所有评论(0)