四、K8S资源清单

1、资源的分类

名称空间级别

  • 工作负责型资源:Pod、ReplicaSet、Deployment、StatefulSet、DaemonSet、Job、CronJob
  • 服务发现及负责均衡资源:Service、Ingress
  • 配置与存储型资源:Volume(存储卷)、CSI(容器存储接口)
  • 特殊类型存储卷:ConfigMap(当配置中心用的资源类型)、Secret(保存敏感数据)、DownwardAPI(把外部环境中的信息输出给容器)。

集群级资源:Namespace、Node、Role、ClusterRole、RoleBinding、ClusterRoleBinding

元数据型资源:HPA、PodTemplate、LimitRange

2、理解Kubernetes中的对象

在 Kubernetes 系统中,Kubernetes 对象 是持久化的条目。Kubernetes 使用这些条目去表示整个集群的状态。特别地,它们描述了如下信息

  • 什么容器化应用在运行(以及在哪个 Node 上)
  • 可以被应用使用的资源
  • 关于应用如何表现的策略,比如重启策略、升级策略,以及容错策略

Kubernetes 对象是 “目标性记录” —— 一旦创建对象,Kubernetes 系统将持续工作以确保对象存在。通过创建对象,可以有效地告知 Kubernetes 系统,所需要的集群工作负载看起来是什么样子的,这就是 Kubernetes 集群的 期望状态。

与 Kubernetes 对象工作 —— 是否创建、修改,或者删除 —— 需要使用 Kubernetes API。当使用 kubectl 命令行接口时,比如,CLI 会使用必要的 Kubernetes API 调用,也可以在程序中直接使用 Kubernetes API。

3、对象的Spec和状态

每个 Kubernetes 对象包含两个嵌套的对象字段,它们负责管理对象的配置:对象 spec 和 对象 statusspec 必须提供,它描述了对象的 期望状态—— 希望对象所具有的特征。status 描述了对象的 实际状态,它是由 Kubernetes 系统提供和更新。在任何时刻,Kubernetes 控制平面一直处于活跃状态,管理着对象的实际状态以与我们所期望的状态相匹配。

例如,Kubernetes Deployment 对象能够表示运行在集群中的应用。当创建 Deployment 时,可能需要设置 Deployment 的 spec,以指定该应用需要有 3 个副本在运行。Kubernetes 系统读取 Deployment spec,启动我们所期望的该应用的 3 个实例 —— 更新状态以与 spec 相匹配。如果那些实例中有失败的(一种状态变更),Kubernetes 系统通过修正来响应 spec 和状态之间的不一致 —— 这种情况,启动一个新的实例来替换。

4、Pod的资源清单格式

当创建 Kubernetes 对象时,必须提供对象的 spec,用来描述该对象的期望状态,以及关于对象的一些基本信息(例如,名称)。当使用 Kubernetes API 创建对象时(或者直接创建,或者基于kubectl),API 请求必须在请求体中包含 JSON 格式的信息。更常用的是,需要在 .yaml 文件中为 kubectl 提供这些信息。 kubectl 在执行 API 请求时,将这些信息转换成 JSON 格式。查看已经部署好的pod的资源定义格式:

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
[root@k8s-master ~]# kubectl get pod myapp-848b5b879b-5f69p -o yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: 2018-08-24T07:40:57Z
generateName: myapp-848b5b879b-
labels:
pod-template-hash: "4046164356"
run: myapp
name: myapp-848b5b879b-5f69p
namespace: default
ownerReferences:
- apiVersion: apps/v1
blockOwnerDeletion: true
controller: true
kind: ReplicaSet
name: myapp-848b5b879b
uid: caf2ec54-a76f-11e8-84d2-000c2972dc1f
resourceVersion: "90507"
selfLink: /api/v1/namespaces/default/pods/myapp-848b5b879b-5f69p
uid: 09bc0ba1-a771-11e8-84d2-000c2972dc1f
spec:
containers:
- image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
name: myapp
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: default-token-j5pf5
readOnly: true
dnsPolicy: ClusterFirst
nodeName: k8s-node01
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-j5pf5
secret:
defaultMode: 420
secretName: default-token-j5pf5
status:
conditions:
- lastProbeTime: null
lastTransitionTime: 2018-08-24T07:40:57Z
status: "True"
type: Initialized
- lastProbeTime: null
lastTransitionTime: 2018-08-24T07:40:59Z
status: "True"
type: Ready
- lastProbeTime: null
lastTransitionTime: null
status: "True"
type: ContainersReady
- lastProbeTime: null
lastTransitionTime: 2018-08-24T07:40:57Z
status: "True"
type: PodScheduled
containerStatuses:
- containerID: docker://a5e7004f45b1ec4a4297e50db6d0b5b11573e36ed8de814ea8b6cdacd13b8f9a
image: ikubernetes/myapp:v1
imageID: docker-pullable://ikubernetes/myapp@sha256:9c3dc30b5219788b2b8a4b065f548b922a34479577befb54b03330999d30d513
lastState: {}
name: myapp
ready: true
restartCount: 0
state:
running:
startedAt: 2018-08-24T07:40:58Z
hostIP: 192.168.56.12
phase: Running
podIP: 10.244.1.11
qosClass: BestEffort
startTime: 2018-08-24T07:40:57Z

创建资源的方法:

  • apiserver在定义资源时,仅接收JSON格式的资源定义
  • yaml格式提供配置清单,apiservere可自动将其转为json格式,而后再提交创建对应资源

大部分资源的配置清单格式都由5个一级字段组成:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: group/version  # 指明api资源属于哪个群组和版本,同一个组可以有多个版本
$ kubectl api-versions # 查看所有api版本

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这个资源的定义:

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
[root@k8s-master ~]# 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/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/api-conventions.md#types-kinds

metadata <Object>
Standard object's metadata. More info:
https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata

spec <Object>
Specification of the desired behavior of the pod. More info:
https://git.k8s.io/community/contributors/devel/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/api-conventions.md#spec-and-status

从上面可以看到apiVersion,kind等定义的键值都是,而metadata和spec看到是一个,当看到存在的提示,说明该字段可以存在多个二级字段,那么可以使用如下命令继续查看二级字段的定义方式:

1
2
3
4
5
6
7
8
9
[root@k8s-master ~]# kubectl explain pods.metadata
[root@k8s-master ~]# kubectl explain pods.spec

# 二级字段下,每一种字段都有对应的键值类型,常用类型大致如下:
<[]string>:表示是一个字串列表,也就是字串类型的数组
<Object>:表示是可以嵌套的字段
<map[string]string>:表示是一个由键值组成映射
<[]Object>:表示是一个对象列表
<[]Object> -required-:required表示该字段是一个必选的字段

资源清单常用字段

必须存在的字段

主要的对象

额外的参数选项

5、使用资源清单创建自主式Pod

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
[root@k8s-master ~]# mkdir mainfests
[root@k8s-master ~]# cd mainfrests
[root@k8s-master mainfrests]# vim pod-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-demo
namespace: default
labels:
app: myapp
tier: frontend
spec:
containers:
- name:myapp
image: putianhui/myapp:v1
- name: busybox
image: busybox:latest
command:
- "/bin/sh"
- "-c"
- "sleep 3600"
[root@k8s-master mainfrests]$ kubectl create -f pod-demo.yaml # 从资源清单创建Pod
[root@k8s-master mainfrests]$ kubectl get pods # 查看所有Pod
[root@k8s-master mainfrests]$ kubectl describe pods pod-demo  # 获取pod详细信息
[root@k8s-master mainfrests]$ kubectl logs pod-demo myapp # 查看Pod日志
[root@k8s-master mainfrests]$ kubectl exec -it pod-demo -c myapp -- /bin/sh

6、spec的containers必需字段详解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@k8s-master ~]# kubectl explain pods.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运行。

7、标签及标签选择器

①.标签

key=value

  • key:只能使用 字母 数字 _ - . (只能以字母数字开头,不能超过63给字符)
  • value: 可以为空 只能使用 字母 数字开头
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
root@k8s-master mainfests]$ kubectl get pods --show-labels  #查看pod标签
NAME READY STATUS RESTARTS AGE LABELS
pod-demo 2/2 Running 0 25s app=myapp,tier=frontend

[root@k8s-master mainfests]$ kubectl get pods -l app  #过滤包含app的标签
NAME READY STATUS RESTARTS AGE
pod-demo 2/2 Running 0 1m
[root@k8s-master mainfests]$ kubectl get pods -L app
NAME READY STATUS RESTARTS AGE APP
pod-demo 2/2 Running 0 1m myapp

[root@k8s-master mainfests]$ kubectl label pods pod-demo release=canary  #给pod-demo打上标签
pod/pod-demo labeled
[root@k8s-master mainfests]$ kubectl get pods -l app --show-labels
NAME READY STATUS RESTARTS AGE LABELS
pod-demo 2/2 Running 0 1m app=myapp,release=canary,tier=frontend

[root@k8s-master mainfests]$ kubectl label pods pod-demo release=stable --overwrite  #修改标签
pod/pod-demo labeled
[root@k8s-master mainfests]$ kubectl get pods -l release
NAME READY STATUS RESTARTS AGE
pod-demo 2/2 Running 0 2m
[root@k8s-master mainfests]$ kubectl get pods -l release,app
NAME READY STATUS RESTARTS AGE
pod-demo 2/2 Running 0 2m

②标签选择器

  • 等值关系标签选择器:=, == , != (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字段的值必须是空列表

③节点标签选择器

1
2
3
4
5
6
7
8
9
10
11
[root@k8s-master mainfests]$ 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创建在哪个节点上,举个例子,给节点k8s-node01打上标签disktype=ssd,让pod-demo运行k8s-node01节点上

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
48
# (1)给k8s-node01节点打标签
[root@k8s-master mainfests]# kubectl label nodes k8s-node01 disktype=ssd
node/k8s-node01 labeled

[root@k8s-master mainfests]# kubectl get nodes --show-labels
NAME STATUS ROLES AGE VERSION LABELS
k8s-master Ready master 10d v1.11.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/hostname=k8s-master,node-role.kubernetes.io/master=
k8s-node01 Ready <none> 10d v1.11.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disktype=ssd,kubernetes.io/hostname=k8s-node01
k8s-node02 Ready <none> 9d v1.11.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/hostname=k8s-node02

#(2)修改yaml文件,增加标签选择器
[root@k8s-master mainfests]# cat pod-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-demo
namespace: default
labels:
app: myapp
tier: frontend
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
- name: busybox
image: busybox:latest
command:
- "/bin/sh"
- "-c"
- "sleep 3600"
nodeSeletor:
disktype: ssd

#(3)重新创建pod-demo,可以看到固定调度在k8s-node01节点上
[root@k8s-master mainfests]# kubectl delete -f pod-demo.yaml
pod "pod-demo" deleted

[root@k8s-master mainfests]# kubectl create -f pod-demo.yaml
pod/pod-demo created
[root@k8s-master mainfests]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
pod-demo 2/2 Running 0 20s 10.244.1.13 k8s-node01
[root@k8s-master mainfests]# kubectl describe pod pod-demo
......
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 42s default-scheduler Successfully assigned default/pod-demo to k8s-node01

annotations:

  与label不同的地方在于,annotations不能用于挑选资源对象,仅用于为对象提供”元数据”,没有键值长度限制。

8、Init-C初始化容器

示例:定义两个初始化容器进行分别对域名进行反向dns解析,当存在对应域名解析就跳出循环返回状态为0

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# --- 定义一个Pod两个初始化容器
apiVersion: v1
kind: Pod
metadata:
name: my-nginx
namespace: default
labels:
app: my-nginx
run1: my-nginx
spec:
restartPolicy: Always
containers:
- name: nginx-01
image: hub.nnv5.cn/test/myapp:v1
imagePullPolicy: IfNotPresent
workingDir: /opt
ports:
- hostIP: 192.168.1.49
hostPort: 8880
containerPort: 80
protocol: TCP
initContainers:
- name: init-myservice1
image: busybox:latest
imagePullPolicy: IfNotPresent
workingDir: /opt
command: ['sh','-c','until nslookup myservice; do echo is not myservice; sleep 2; done;']
- name: init-mynginx
image: busybox:latest
imagePullPolicy: IfNotPresent
workingDir: /opt
command: ['sh','-c','until nslookup mynginx;do echo myservice is not mynginx; sleep 3; done;']



## --- 定义两个service
apiVersion: v1
kind: Service
metadata:
name: myservice
labels:
app: run-init
run: initCN
spec:
ports:
- port: 8080
protocol: TCP
targetPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: mynginx
labels:
app: run-init
run: initCN
spec:
ports:
- port: 8080
protocol: TCP
targetPort: 80

9、readness与liveness探针

探针常用选项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
kubernetes探针有许多配置项,您可以使用它们来更精确地控制如何进行就绪和生存检查:

initialDelaySeconds:容器启动多少秒后开始探测
periodSeconds:检查的频率(以秒为单位)。默认为10秒。最小值为1。
timeoutSeconds:检查超时的秒数。默认为1秒。最小值为1。
successThreshold:失败后检查成功的最小连续成功次数。默认为1.活跃度必须为1。最小值为1。
failureThreshold:探测失败多少次认为失败。默认为3.最小值为1。

## httpGet探针配置项
host:主机名,默认为pod的IP。
scheme:用于连接主机的方案(HTTP或HTTPS)。默认为HTTP。
path:探针的路径。(如:/index.html)
httpHeaders:在HTTP请求中设置的自定义标头。 HTTP允许重复的请求头。
port:端口的名称或编号。数字必须在1到65535的范围内

## tcpSocket探针配置项
host:主机名,默认为pod的IP。
port:端口的名称或编号。数字必须在1到65535的范围内

Readness探针示例

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
## --- readiness http方式探针
apiVersion: v1
kind: Pod
metadata:
name: my-nginx01
labels:
app: nginx
deployment: dev
spec:
containers:
- name: readness-nginx
image: hub.nnv5.cn/test/myapp:v1
imagePullPolicy: IfNotPresent
readinessProbe:
httpGet:
path: /test.html
port: 80
successThreshold: 1
failureThreshold: 3
initialDelaySeconds: 10
timeoutSeconds: 10
periodSeconds: 5
restartPolicy: Always


## --- readiness TCP方式探针
apiVersion: v1
kind: Pod
metadata:
name: mynginx-readines-tcp01
labels:
run: readiness-tcp
app: mynginx
spec:
containers:
- name: nginx-01
image: hub.nnv5.cn/test/myapp:v1
imagePullPolicy: IfNotPresent
readinessProbe:
tcpSocket:
port: 80
successThreshold: 1
failureThreshold: 3
initialDelaySeconds: 10
timeoutSeconds: 10
periodSeconds: 5
restartPolicy: Always


## --- readiness exec方式探针
apiVersion: v1
kind: Pod
metadata:
name: mynginx-exec01
labels:
run: nginx
app: nginx
spec:
restartPolicy: Always
containers:
- name: ngxin01
image: hub.nnv5.cn/test/myapp:v1
imagePullPolicy: IfNotPresent
readinessProbe:
exec:
command: ['test','-e','/tmp/live']
successThreshold: 1
failureThreshold: 3
initialDelaySeconds: 10
timeoutSeconds: 10
periodSeconds: 5
restartPolicy: Always

Liveness探针示例

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
48
## --- liveness http方式探针---创建pod后当删除pod内index.html文件pod会自动重启
apiVersion: v1
kind: Pod
metadata:
name: my-nginx01
labels:
app: nginx
deployment: dev
spec:
containers:
- name: liveness-nginx
image: hub.nnv5.cn/test/myapp:v1
imagePullPolicy: IfNotPresent
livenessProbe:
httpGet:
path: /index.html
port: 80
successThreshold: 1
failureThreshold: 3
initialDelaySeconds: 10
timeoutSeconds: 10
periodSeconds: 5
restartPolicy: Always


## --- Liveness exec方式探针---创建pod后会自动在tmp目录下创建live文件,之后liveness探测/tmp/live文件是否存在,当30秒过后删除live文件,liveness探测三次未找到live文件将自动重启pod
apiVersion: v1
kind: Pod
metadata:
name: my-nginx01
labels:
app: nginx
deployment: dev
spec:
containers:
- name: liveness-nginx
image: hub.nnv5.cn/test/myapp:v1
imagePullPolicy: IfNotPresent
command: ['/bin/sh','-c','touch /tmp/live;sleep 20;rm -f /tmp/live;sleep 3000']
livenessProbe:
exec:
command: ['test','-e','/tmp/live']
successThreshold: 1
failureThreshold: 3
initialDelaySeconds: 10
timeoutSeconds: 10
periodSeconds: 5
restartPolicy: Always
文章作者: Mr.Pu
文章链接: http://www.putianhui.cn/posts/98a89830ab6b/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Mr.Pu 个站博客

评论