1. 简介

虽然说我们在工作过程中,很少单独去创建pod,我们都会使用控制器来管理pod,但是控制器里是包括pod模板的,如果我们不理解pod的话,那么如果想修改控制器的话,也是比较难的。

2. 创建pod方式

创建pod的话,通过:
1.命令行的方式
2.yaml文件 —更推荐—yaml可以有更多的选项

创建pod通用语法
kubectl run podname --image nginx --image-pull-policy IfNotPresent --dry-run=client -o yaml

3. 获取yaml

通过命令行获取模板,然后修改即可

1
kubectl run pod1 --image nginx --image-pull-policy IfNotPresent --dry-run=client -o yaml > pod1.yaml

4. yaml文件

k8s里有很多中资源,比如:
ns
node
pod
configmap
secret
cluster

每种资源的类型使用kind标记

每种资源都会有对应的挨批version,资源和apiversion之间的关系是固定的

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
[root@node001 chap3-pod]# cat pod1.yaml 
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod1
name: pod1
spec:
#hostNetwork: true
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: pod1
resources: {}
env:
- name: MYSQL_ROOT_PASSWORD
value: haha001
- name: MYSQL_DATABASE
value: db1
- name: myip
valueFrom:
fieldRef:
fieldPath: status.podIP
#ports:
#- name: http
# containerPort: 80
# hostPort: 8888
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}

4.1 yaml格式

要遵照驼峰写法

  1. 冒号左边
     多个单词的话,第一个单词首字母小写,其余单词首字母大写。
  2. 冒号右边
     多个单词的话,每个单词的首字母都大写
  3. 在yaml文件不能出现等于号,所有的等于号都要替换为冒号空格
  4. 在yaml中有严格的缩进要求,每次缩进2个空格

4.2 查看yaml帮助

1
[root@node001 chap3-pod]# kubectl explain pod.spec

5. pod的基本操作

5.1 执行命令

1
[root@node001 chap3-pod]# kubectl exec  pod2 -- env

5.2 复制文件

1
2
3
[root@node001 chap3-pod]# kubectl cp /etc/issue pod1:/tmp
[root@node001 chap3-pod]# kubectl exec pod1 -- ls /tmp
issue

5.3 进入容器

1
[root@node001 chap3-pod]# kubectl exec -it pod2 -c c1 -- bash

5.4 查看容器log

1
[root@node001 chap3-pod]# kubectl logs pod2 -c c1 -f

6. pod的生命周期

pod重启----所谓pod重启,就是删除pod里的容器,然后重建容器

重启策略
Always 总是重启
OnFailure 非正常退出才重启
Never 从不重启

pod hook(pod钩子进程)

  1. postStart
    在主进程运行的同时,可以再启用一个钩子进程,钩子进程没有结束的话,pod状态一直为createing
  2. preStop
    在关闭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
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod4
name: pod4
spec:
terminationGracePeriodSeconds: 30
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: pod4
resources: {}
command:
- sh
- -c
- sleep 1d
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c","date > /tmp/bb.txt ;sleep 15"]
preStop:
exec:
command: ["/bin/sh","-c","date > /tmp/cc.txt; sleep 15"]
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}

pod的状态
Pending pod 因为其他的原因导致pod准备开始创建 还没有创建(卡住了)
Running pod已经被调度到节点上,且容器工作正常
Completed pod里所有容器正常退出
error
CrashLoopBackOff 创建的时候就出错,属于内部原因
imagePullBackoff 创建pod的时候,镜像下载失败

7. 初始化容器

比如一个容器A依赖其他容器,可以为A设置多个依赖容器A1,A2,A3
A1,A2,A3要按照顺序启动,A1没有启动起来的话,A2,A3是不会启动的,直到所有的静态容器全部启动完毕,主容器A才会启动。
一般用于A容器运行之前,先做一些准备工作。

7.1 创建初始化容器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod5
name: pod5
spec:
initContainers:
- image: alpine
imagePullPolicy: IfNotPresent
name: initc1
command: ["sh","-c","/sbin/sysctl -w swappiness=0; sleep 10"]
securityContext:
privileged: true
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: pod5
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}

8. 静态pod

所谓静态pod就是,不是master上创建的,而是需要在node的/etc/kubelet.d/里创建一个yaml文件,然后根据这个yaml文件,创建一个pod,这样创建出来的node,是不会接受master管理的。
当然,要是想创建静态pod的话,需要对node的kubelet配置文件进行一些设置才可以,在指定目录下面创建一个yaml文件,然后改kubelet的systemd配置,reload+重启。

8.1 创建静态pod

进入静态pod目录

1
[root@node003 ~]# cd /etc/kubernetes/manifests

添加yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@node003 manifests]# cat pod6.yaml 
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod6
name: pod6
spec:
containers:
- args:
- clinet
image: nginx
imagePullPolicy: IfNotPresent
name: pod6
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}

查看pod

1
2
3
[root@node001 chap3-pod]# kubectl -n default get pod
NAME READY STATUS RESTARTS AGE
pod6-node003 0/1 CrashLoopBackOff 1 (9s ago) 10s

9. 标签

9.1 添加标签

1
2
3
4
5
[root@node001 chap3-pod]# kubectl label nodes node002 tag=node002
node/node002 labeled
[root@node001 chap3-pod]# kubectl get nodes -l tag=node002
NAME STATUS ROLES AGE VERSION
node002 Ready <none> 2d2h v1.24.4

9.2 强制覆盖

1
2
[root@node001 chap3-pod]# kubectl label nodes node002 tag=node002-new --overwrite
node/node002 labeled

9.3 删除标签

1
2
3
4
[root@node001 chap3-pod]# kubectl label nodes node002 tag-
node/node002 unlabeled
[root@node001 chap3-pod]# kubectl get nodes -l tag=node002
No resources found

9.4 调度pod

通过nodeName标签调度pod
如果pod是通过nodeName来指定是在哪个节点上运行的话,此pod是可以在有污点的节点上运行的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod6
name: pod6
spec:
nodeName: node001
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: pod6
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}

9.5 通过标签选择器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod6
name: pod6
spec:
#nodeName: node001
nodeSelector:
tag: node002
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: pod6
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}

9.6 通过亲和性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: nginx
resources: {}
affinity:
nodeAffinity:
# requiredDuringSchedulingIgnoredDuringExecution: # 硬策略
# nodeSelectorTerms:
# - matchExpressions:
# - key: kubernetes.io/hostname
# operator: In
# values:
# - vms63.rhce.cc
# - vms62.rhce.cc
preferredDuringSchedulingIgnoredDuringExecution: # 软策略
- weight: 2
preference:
matchExpressions:
- key: bb
operator: Gt
values:
- "3"

10. 节点cordon

如果一个node被标记为cordon,新创建的pod不会被调度到此node上,已经调度上去的不会被移走,需要被删除让其重新生成。

1
2
3
4
5
6
7
[root@node001 chap3-pod]# kubectl cordon node002 
node/node002 already cordoned
[root@node001 chap3-pod]# kubectl get node
NAME STATUS ROLES AGE VERSION
node001 Ready control-plane 2d3h v1.24.4
node002 Ready,SchedulingDisabled <none> 2d3h v1.24.4
node003 Ready <none> 2d2h v1.24.4

取消

1
2
[root@node001 chap3-pod]# kubectl uncordon node002 
node/node002 uncordoned

11. 排空节点drain

如果一个节点被设置为drain,则此节点不再被调度pod,且此节点上已经运行的pod会被驱逐(evicted)到其他节点(所谓驱逐就是删除这个节点上的pod)
drain包含:
 cordon
 evicted

1
[root@node001 chap3-pod]# kubectl drain node002 --ignore-daemonsets

12. 节点taint及tolerations

定义污点格式
kubectl taint node xxx 键=值:effect(NoSchedule)

取消污点
kubectl untaint node xxx 键-

查看节点污点

1
2
3
4
[root@node001 chap3-pod]# kubectl describe nodes node001 |grep -A2 Tain
Taints: node-role.kubernetes.io/control-plane:NoSchedule
node-role.kubernetes.io/master:NoSchedule
Unschedulable: false

容忍污点
创建容忍,以运行pod在master节点

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
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod6
name: pod6
spec:
#nodeName: node001
nodeSelector:
tag: node001
tolerations:
- effect: NoSchedule
key: node-role.kubernetes.io/control-plane
operator: Exists
- effect: NoSchedule
key: node-role.kubernetes.io/master
value: ""
operator: Equal
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: pod6
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}