Kubernetes 资源清单定义
Kubernetes 常用资源
- 以下举例的内容都是 kubernetes 中的 Object,这些对象都可以在 yaml 文件中作为一种 API 类型来配置
理解 Kubernetes 中的对象
- 在 Kubernetes 系统中,Kubernetes 对象是持久化的条目。Kubernetes 使用这些条目去表示整个集群的状态。它们描述了如下信息
- 什么容器化应用在运行(以及在哪个 Node 上)
- 可以被应用使用的资源
- 关于应用如何表现的策略,比如重启策略,升级策略,以及容错策略
- Kubernetes 对象是 "目标性记录" -- 一旦创建对象,Kubernetes 系统将持续工作以确保对象存在。通过创建对象,可以有效地告知 Kubernetes 系统,所需要的集群工作负载看起来是什么样子的,这就是 Kubernetes 集群的期望状态。
- 与 Kubernetes 对象工作 -- 是否创建、修改、或者删除 -- 需要使用 Kubernetes API。当使用 kubectl 命令行接口时,比如,CLI 会使用必要的 Kubernetes API 调用,也可以在程序中直接使用 Kubernetes API。
对象的 Spec 和 Status
- 每个 Kubernetes 对象包含两个嵌套的对象字段,它们负责管理对象的配置:对象 spec 和 对象 status。spec 必须提供,它描述了对象的 期望状态—— 希望对象所具有的特征。status 描述了对象的 实际状态,它是由 Kubernetes 系统提供和更新。在任何时刻,Kubernetes 控制平面一直处于活跃状态,管理着对象的实际状态以与我们所期望的状态相匹配。
- 例如,Kubernetes Deployment 对象能够表示运行在集群中的应用。当创建 Deployment 时,可能需要设置 Deployment 的 spec,以指定该应用需要有 3 个副本在运行。Kubernetes 系统读取 Deployment spec,启动我们所期望的该应用的 3 个实例 —— 更新状态以与 spec 相匹配。如果那些实例中有失败的(一种状态变更),Kubernetes 系统通过修正来响应 spec 和状态之间的不一致 —— 这种情况,启动一个新的实例来替换。
Pod 的配置格式
- 当创建 Kubernetes 对象时,必须提供对象的 spec,用来描述该对象的期望状态,以及关于对象的一些基本信息(例如,名称)。当使用 Kubernetes API 创建对象时(或者直接创建,或者基于kubectl),API 请求必须在请求体中包含 JSON 格式的信息。更常用的是,需要在 .yaml 文件中为 kubectl 提供这些信息。 kubectl 在执行 API 请求时,将这些信息转换成 JSON 格式。查看已经部署好的 pod 的资源定义格式:
root@k8s-master1:~# kubectl get pod
NAME READY STATUS RESTARTS AGE
net-test1-5fcc69db59-c2plf 1/1 Running 2 2d22h
net-test1-5fcc69db59-xzvrl 1/1 Running 2 2d22h
net-test2-8456fd74f7-ckpsr 1/1 Running 2 2d22h
net-test2-8456fd74f7-nbzx8 1/1 Running 2 2d22h
nginx-deployment-5f4dc447b5-4l6hs 1/1 Running 1 2d14h
tomcat-deployment-5cd65b4d74-d4x7s 1/1 Running 1 2d13h
root@k8s-master1:~# kubectl get pod net-test1-5fcc69db59-c2plf -o yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: "2020-03-29T09:12:07Z"
generateName: net-test1-5fcc69db59-
labels:
pod-template-hash: 5fcc69db59
run: net-test1
name: net-test1-5fcc69db59-c2plf
namespace: default
ownerReferences:
- apiVersion: apps/v1
blockOwnerDeletion: true
controller: true
kind: ReplicaSet
name: net-test1-5fcc69db59
uid: f4aef9ff-cac4-4484-b6ea-fc349336f13f
resourceVersion: "201236"
selfLink: /api/v1/namespaces/default/pods/net-test1-5fcc69db59-c2plf
uid: 9bee2039-bc52-419c-925a-f9d31b7d6e54
spec:
containers:
- args:
- sleep
- "360000"
image: alpine
imagePullPolicy: Always
name: net-test1
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: default-token-qnr5k
readOnly: true
dnsPolicy: ClusterFirst
enableServiceLinks: true
nodeName: node-3
priority: 0
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: default
serviceAccountName: default
terminationGracePeriodSeconds: 30
tolerations:
- effect: NoExecute
key: node.kubernetes.io/not-ready
operator: Exists
tolerationSeconds: 300
- effect: NoExecute
key: node.kubernetes.io/unreachable
operator: Exists
tolerationSeconds: 300
volumes:
- name: default-token-qnr5k
secret:
defaultMode: 420
secretName: default-token-qnr5k
status:
conditions:
- lastProbeTime: null
lastTransitionTime: "2020-03-29T09:12:07Z"
status: "True"
type: Initialized
- lastProbeTime: null
lastTransitionTime: "2020-04-01T07:44:44Z"
status: "False"
type: Ready
- lastProbeTime: null
lastTransitionTime: "2020-03-31T05:54:42Z"
status: "True"
type: ContainersReady
- lastProbeTime: null
lastTransitionTime: "2020-03-29T09:12:07Z"
status: "True"
type: PodScheduled
containerStatuses:
- containerID: docker://a755f88227553883a0f4ecfa188299ce412f8b8d4e0138df5101782feb242006
image: alpine:latest
imageID: docker-pullable://alpine@sha256:b276d875eeed9c7d3f1cfa7edb06b22ed22b14219a7d67c52c56612330348239
lastState:
terminated:
containerID: docker://264f0e23a04216835e1517f39dada4b2ad9530e8ed59db9bbae04c2013fd29bf
exitCode: 255
finishedAt: "2020-03-31T05:25:21Z"
reason: Error
startedAt: "2020-03-29T13:17:15Z"
name: net-test1
ready: true
restartCount: 2
started: true
state:
running:
startedAt: "2020-03-31T05:54:42Z"
hostIP: 192.168.26.164
phase: Running
podIP: 10.10.5.10
podIPs:
- ip: 10.10.5.10
qosClass: BestEffort
startTime: "2020-03-29T09:12:07Z"
- 创建资源的方法
- apiserver 在定义资源时,仅接收 JSON 格式的资源定义
- yaml 格式提供配置清单,apiserver 可自动将其转为 JSON 格式,然后提交
- 大部分资源的配置请单格式由五个一级字段组成
apiVersion: group/version 指明 api 资源属于哪个群组和版本,同一个组可以有多个版本
$ kubectl api-versions
kind: 资源类别,标记创建的资源类型,k8s主要支持以下资源类别
Pod,ReplicaSet,Deployment,StatefulSet,DaemonSet,Job,Cronjob
metadata: 元数据,主要提供以下字段
name:同一类别下的 name 是唯一的
namespace:对应的对象属于哪个名称空间
labels:标签,每一个资源都可以有标签,标签是一种键值数据
annotations:资源注解
每个的资源引用方式(selflink):
/api/GROUP/VERSION/namespace/NAMESPACE/TYPE/NAME
spec: 定义目标资源的期望状态(disired state),资源对象中最重要的字段
status: 显示资源的当前状态(current state),本字段由 kubernetes 进行维护
- K8s 存在内嵌的格式说明,可以使用 kubectl explain 进行查看,如查看 Pod 这个资源的定义:
root@k8s-master1:~# kubectl explain pods
KIND: Pod
VERSION: v1
DESCRIPTION:
Pod is a collection of containers that can run on a host. This resource is
created by clients and scheduled onto hosts.
FIELDS:
apiVersion <string>
APIVersion defines the versioned schema of this representation of an
object. Servers should convert recognized schemas to the latest internal
value, and may reject unrecognized values. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
kind <string>
Kind is a string value representing the REST resource this object
represents. Servers may infer this from the endpoint the client submits
requests to. Cannot be updated. In CamelCase. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
metadata <Object>
Standard object's metadata. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
spec <Object>
Specification of the desired behavior of the pod. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
status <Object>
Most recently observed status of the pod. This data may not be up to date.
Populated by the system. Read-only. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
- 从上面可以看到 apiVersion,kind等定义的键值都是 \<string>,而 metadata 和 spec 看到是一个 \<Object>,当看到存在 \<Object> 的提示,说明该字段可以存在多个二级字段,那么可以使用如下命令继续查看二级字段的定义方式:
root@k8s-master1:~# kubectl explain pods.metadata
root@k8s-master1:~# kubectl explain pods.spec
- 二级字段下,每一种字段都有对应的键值类型,常用类型大致如下:
帮助信息中常见格式如下:
apiVersion <string> #表示字符串类型
metadata <Object> #表示需要嵌套多层字段
labels <map[string]string> #表示是一个由键值组成映射
finalizers <[]string> #表示是一个字串列表,也就是字串类型的数组
ownerReferences <[]Object> #表示是一个对象列表
hostPID <boolean> #布尔类型
priority <integer> #整型
name <string> -required- #如果类型后面接 -required-,表示为必填字段
使用配置清单创建自主式 Pod 资源
root@k8s-master1:~# mkdir mainfests
root@k8s-master1:~# cd mainfrests
root@k8s-master1:~/mainfests# vim pod-demo.yml
apiVersion: v1
kind: Pod
metadata:
name: pod-demo
namespace: default
labels:
app: myapp
tier: frontend
spec:
containers:
- name:myapp
image: k8s.harbor.com/bokebi/busybox:v1
- name: busybox
image: k8s.harbor.com/bokebi/busybox:v1
command:
- "/bin/sh"
- "-c"
- "sleep 3600"
root@k8s-master1:~/mainfests# kubectl create -f pod-demo.yml
root@k8s-master1:~/mainfests# kubectl get pods
root@k8s-master1:~/mainfests# kubectl describe pods pod-demo #获取pod详细信息
root@k8s-master1:~/mainfests# kubectl logs pod-demo myapp
root@k8s-master1:~/mainfests# kubectl exec -it pod-demo -c myapp sh
Pod 资源下 spec 的 containers 必须字段解析
name <string> -required- #containers 的名字
image <string> #镜像地址
imagePullPolicy <string> #如果标签是 latest 就是 Always (总是下载镜像) IfNotPresent (先看本地是否有此镜像,如果没有就下载) Never (就是使用本地镜像)
ports <[]Object> #是个对象列表,可以暴露多个端口,可以对每个端口的属性定义。例如:(名称(可后期调用)端口号、协议,暴露的地址上) 暴露端口只是提供额外信息的,不能限制系统是否真的暴露
- containerPort #容器端口
hostIP #主机地址(基本不会使用)
hostPort #节点端口
name #名称
protocol #(默认是TCP)
args <[]string> #传递参数给 command 相当于 docker 中的 CMD
command <[]string> #相当于 docker 中的 ENTRYPOINT
-
如果 Pod 不提供 command 或 args 使用 Container,则使用 Docker 镜像中的 cmd 或者 ENTRYPOINT。
-
如果 Pod 提供 command 但不提供 args,则仅使用提供 command 的。将忽略 Docker 镜像中定义 EntryPoint和Cmd。
-
如果 Pod 中仅提供 args,则 args 将作为参数提供给 Docker 镜像中 EntryPoint。
-
如果提供了 command 和 args,则 Docker 镜像中的 ENTRYPOINT 和 CMD 都将不会生效,Pod 中的 args 将作为参数给 command 运行。
标签及标签选择器
标签
- key=value
- key:只能使用字母 数字 _ - . (只能以字母数字开头,不能超过 63 个字符)
- value:可以为空,只能使用字母数字开头
root@k8s-master1:~# kubectl get pods --show-labels #查看 pod 标签
NAME READY STATUS RESTARTS AGE LABELS
net-test1-5fcc69db59-c2plf 1/1 Running 2 2d23h pod-template-hash=5fcc69db59,run=net-test1
net-test1-5fcc69db59-xzvrl 1/1 Running 2 2d23h pod-template-hash=5fcc69db59,run=net-test1
net-test2-8456fd74f7-ckpsr 1/1 Running 2 2d23h pod-template-hash=8456fd74f7,run=net-test2
net-test2-8456fd74f7-nbzx8 1/1 Running 2 2d23h pod-template-hash=8456fd74f7,run=net-test2
nginx-deployment-5f4dc447b5-4l6hs 1/1 Running 1 2d15h app=nginx,pod-template-hash=5f4dc447b5
tomcat-deployment-5cd65b4d74-d4x7s 1/1 Running 1 2d14h app=tomcat,pod-template-hash=5cd65b4d74
root@k8s-master1:~# kubectl get pods -l app #过滤包含 app 的标签
NAME READY STATUS RESTARTS AGE
nginx-deployment-5f4dc447b5-4l6hs 1/1 Running 1 2d15h
tomcat-deployment-5cd65b4d74-d4x7s 1/1 Running 1 2d14h
root@k8s-master1:~# kubectl label pods nginx-deployment-5f4dc447b5-4l6hs releass=canary #给 nginx-deployment-5f4dc447b5-4l6hs 打上标签
pod/nginx-deployment-5f4dc447b5-4l6hs labeled
root@k8s-master1:~# kubectl label pods nginx-deployment-5f4dc447b5-4l6hs release=stable --overwrite #修改标签
pod/nginx-deployment-5f4dc447b5-4l6hs labeled
root@k8s-master1:~# kubectl get pods -l release
NAME READY STATUS RESTARTS AGE
nginx-deployment-5f4dc447b5-4l6hs 1/1 Running 1 2d15h
root@k8s-master1:~# kubectl get pods -l release,app
NAME READY STATUS RESTARTS AGE
nginx-deployment-5f4dc447b5-4l6hs 1/1 Running 1 2d15h
标签选择器
- 等值关系标签选择器:=,==,!= (kubectl get pods -l app=test,app=dev)
- 集合关系标签选择器:KEY in (v1,v2,v3), KEY notin(v1,v2,v3) !KEY (kubectl get pods -l "app in (test,dev)")
- 许多资源支持内嵌字段
- matchLabels: 直接给定键值
- matchExpressions: 基于给定的表达式来定义使用标签选择器,{key:"KEY",operator:"OPERATOR",values:[V1,V2,....]}
- 操作符: in notin:Values 字段的值必须是非空列表 Exists NotExists: Values 字段的值必须是空列表
节点标签选择器
root@k8s-master1:~# kubectl explain pod.spec
nodeName <string>
NodeName is a request to schedule this pod onto a specific node. If it is
non-empty, the scheduler simply schedules this pod onto that node, assuming
that it fits resource requirements.
nodeSelector <map[string]string>
NodeSelector is a selector which must be true for the pod to fit on a node.
Selector which must match a node's labels for the pod to be scheduled on
that node. More info:
https://kubernetes.io/docs/concepts/configuration/assign-pod-node/
-
nodeSelector 可以限定 pod 创建在哪个节点上,举个例子,给节点 node-1 打上标签 disktype=ssd,让 nginx-deployment-5f4dc447b5-4l6hs 指定创建在 node-1 上
-
遇到报错
-
出现这个问题的原因是kubectl命令需要使用 kubernetes-admin 来运行
- 解决报错
- 1.将主节点 (master节点) 中的 [/etc/kubernetes/admin.conf] 文件拷贝到从节点相同目录下
scp -r /etc/kubernetes/admin.conf ${node1}:/etc/kubernetes/admin.conf
- 2.配置环境变量
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
- 3.立即生效
source ~/.bash_profile