K8s的Pod资源清单

K8s的Pod资源清单的编写、资源的增删改查、镜像的下载策略,及面试题

本质是创建一系列的资源清单文件。

一、环境准备

创建资源清单目录(231节点)

1
mkdir -pv /manifests/pods && cd /manifests/pods

二、单容器资源清单

2.1 查阅文档

第一次不会写资源清单文件,可以查阅

1
2
3
4
kubectl explain pods
# kubectl explain pods.spec
# kubectl explain pods.spec.volumes
# .....
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
[root@k8s231.bravexist.cn /manifests/pods]# 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

[root@k8s231.bravexist.cn /manifests/pods]#

2.2 编写单容器Pod资源清单

1
vi 001-my-nginx.yaml

这里使用 vi 是方便粘贴,vim 太智能,总是自动补齐上一行的 #

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# api版本
apiVersion: v1
# 资源类型
kind: Pod
# 元数据,比如资源的名称,标签,名称空间,注解等信息。
metadata:
# Pod的名字
name: 001-linux-web-nginx
# 用户期望资源的运行状态。
spec:
# 容器列表
containers:
# 容器的属性
- name: nginx
image: nginx:1.27

2.3 启动单容器Pod资源清单

1
kubectl create -f 001-my-nginx.yaml

or

1
kubectl apply -f 001-my-nginx.yaml
  • apply 可重复执行(推荐

2.4 查看Pod的相关信息

  1. 获取所有的 Pod
1
kubectl get pods
1
2
3
4
[root@k8s231.bravexist.cn /manifests/pods]# kubectl get pods
NAME READY STATUS RESTARTS AGE
001-linux-web-nginx 1/1 Running 0 67s
[root@k8s231.bravexist.cn /manifests/pods]#

同时显示 PodIP 地址

1
kubectl get pods -o wide
1
2
3
4
[root@k8s231.bravexist.cn /manifests/pods]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
001-linux-web-nginx 1/1 Running 0 80s 10.100.1.3 k8s232.bravexist.cn <none> <none>
[root@k8s231.bravexist.cn /manifests/pods]#
  1. 获取某个 Pod 的详细信息
1
kubectl describe <Pod的名称>
1
kubectl describe pods 001-linux-web-nginx
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
[root@k8s231.bravexist.cn /manifests/pods]# kubectl describe pods 001-linux-web-nginx
Name: 001-linux-web-nginx
Namespace: default
Priority: 0
Node: k8s232.bravexist.cn/192.168.10.232
Start Time: Wed, 24 Dec 2025 15:51:25 +0800
Labels: <none>
Annotations: <none>
Status: Running
IP: 10.100.1.3
IPs:
IP: 10.100.1.3
Containers:
nginx:
Container ID: docker://899ae05cd9c1128b1dbedcbfdc47298e7f122578eb9deb541d2dbfff0426a820
Image: nginx:1.27
Image ID: docker://sha256:1e5f3c5b981a9f91ca91cf13ce87c2eedfc7a083f4f279552084dd08fc477512
Port: <none>
Host Port: <none>
State: Running
Started: Wed, 24 Dec 2025 15:51:26 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-4hpl5 (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
kube-api-access-4hpl5:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Pulled 95s kubelet Container image "nginx:1.27" already present on machine
Normal Created 95s kubelet Created container nginx
Normal Started 95s kubelet Started container nginx
Normal Scheduled 95s default-scheduler Successfully assigned default/001-linux-web-nginx to k8s232.bravexist.cn
[root@k8s231.bravexist.cn /manifests/pods]#

2.5 删除 Pod 资源

删除清单文件中的 Pod

1
kubectl delete -f 001-my-nginx.yaml

删除单个 Pod

1
kubectl delete pods 001-linux-web-nginx

删除所有的 Pod

1
kubectl delete pods --all

三、多容器资源清单

3.1 编写多容器 Pod 资源清单

1
vi 002-my-nginx-tomcat.yaml
1
2
3
4
5
6
7
8
9
10
apiVersion: v1
kind: Pod
metadata:
name: 002-linux-nginx-tomcat
spec:
containers:
- name: nginx
image: nginx:1.20
- name: tomcat
image: tomcat:8.0

3.2 操作资源

3.2.1 创建资源

1
kubectl create -f 002-my-nginx-tomcat.yaml

or

1
kubectl apply -f 002-my-nginx-tomcat.yaml

3.2.2 查看资源

查看基本信息

1
kubectl get pods

查看更多信息

1
kubectl get pods -o wide

查看详细信息

1
kubectl describe pods <Pod的名称>
1
kubectl describe pods 002-linux-nginx-tomcat

3.2.3 删除资源

删除清单文件中的 Pod

1
kubectl delete -f 002-my-nginx-tomcat.yaml

删除单个 Pod

1
kubectl delete pods 002-linux-nginx-tomcat

删除所有的 Pod

1
kubectl delete pods --all

3.3 实验及结论

  1. 每个节点都能访问到 Pod
  2. 两个容器共享一个主机IP地址
  3. 发现多个容器都会加入 Pod 所在的网络
  4. killtomcatnginx 容器,ip地址不变,killPod 的容器,ip地址会变。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@k8s232.bravexist.cn ~]# curl 10.100.1.5 -I
HTTP/1.1 200 OK
Server: nginx/1.20.2
Date: Wed, 24 Dec 2025 08:09:57 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 16 Nov 2021 14:44:02 GMT
Connection: keep-alive
ETag: "6193c3b2-264"
Accept-Ranges: bytes

[root@k8s232.bravexist.cn ~]# curl 10.100.1.5:8080 -I
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=UTF-8
Transfer-Encoding: chunked
Date: Wed, 24 Dec 2025 08:10:03 GMT

[root@k8s232.bravexist.cn ~]#
1
2
3
4
5
[root@k8s232.bravexist.cn ~]# docker ps -a|grep 002
8c13e3fbf0ba ef6a7c98d192 "catalina.sh run" 5 minutes ago Up 5 minutes k8s_tomcat_002-linux-nginx-to
7d1a7903895f 0584b370e957 "/docker-entrypoint.…" 5 minutes ago Up 5 minutes k8s_nginx_002-linux-nginx-tom
058cd9892ad8 registry.aliyuncs.com/google_containers/pause:3.6 "/pause" 5 minutes ago Up 5 minutes k8s_POD_002-linux-nginx-tomca
[root@k8s232.bravexist.cn ~]#
1
2
3
4
5
6
7
[root@k8s232.bravexist.cn ~]# docker kill 8c13e3fbf0ba 
8c13e3fbf0ba
[root@k8s232.bravexist.cn ~]# docker kill 7d1a7903895f
7d1a7903895f
[root@k8s232.bravexist.cn ~]# docker kill 058cd9892ad8
058cd9892ad8
[root@k8s232.bravexist.cn ~]#
1
2
3
4
5
6
7
[root@k8s231.bravexist.cn /manifests/pods]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
002-linux-nginx-tomcat 2/2 Running 2 (10s ago) 8m49s 10.100.1.5 k8s232.bravexist.cn

[root@k8s231.bravexist.cn /manifests/pods]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
002-linux-nginx-tomcat 2/2 Running 4 (4s ago) 9m3s 10.100.1.6 k8s232.bravexist.cn

四、案例

主要有两个案例,

  1. 系统镜像需要阻塞,
  2. 网络模式,共享宿主机网络

4.1 tomcat 替换为 alpine

系统镜像需要执行一条前台命令阻塞住,否则会一直重启,无法正常启动。

4.1.1 情况一:不阻塞

1
vim 003-my-nginx-alpine.yaml
1
2
3
4
5
6
7
8
9
10
apiVersion: v1
kind: Pod
metadata:
name: 003-my-nginx-alpine-001-no-block
spec:
containers:
- name: nginx
image: nginx:1.20
- name: alpine
image: alpine:3.23.2

报错日志

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
[root@k8s231.bravexist.cn /manifests/pods]# kubectl describe pods 003-my-nginx-alpine-001-no-block
Name: 003-my-nginx-alpine-001-no-block
Namespace: default
Priority: 0
Node: k8s232.bravexist.cn/192.168.10.232
Start Time: Wed, 24 Dec 2025 16:56:39 +0800
Labels: <none>
Annotations: <none>
Status: Running
IP: 10.100.1.8
IPs:
IP: 10.100.1.8
Containers:
nginx:
Container ID: docker://faf6cee419f1639b5101458ca5fe70eb4061edc05486453a7a556642394aa6e7
Image: nginx:1.20
Image ID: docker://sha256:0584b370e957bf9d09e10f424859a02ab0fda255103f75b3f8c7d410a4e96ed5
Port: <none>
Host Port: <none>
State: Running
Started: Wed, 24 Dec 2025 16:56:40 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-pvwqq (ro)
alpine:
Container ID: docker://0a25f83a86c5a8e4c25880927b708949b44eebe782e1538f60d27a795382139f
Image: alpine:3.23.2
Image ID: docker://sha256:11879f4a35ffe215fdb4175a8023aaf5bc096709e52a2d15ccacce55f145001f
Port: <none>
Host Port: <none>
State: Waiting
Reason: CrashLoopBackOff
Last State: Terminated
Reason: Completed
Exit Code: 0
Started: Wed, 24 Dec 2025 16:57:27 +0800
Finished: Wed, 24 Dec 2025 16:57:27 +0800
Ready: False
Restart Count: 3
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-pvwqq (ro)
Conditions:
Type Status
Initialized True
Ready False
ContainersReady False
PodScheduled True
Volumes:
kube-api-access-pvwqq:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Pulled 85s kubelet Container image "nginx:1.20" already present on machine
Normal Created 85s kubelet Created container nginx
Normal Started 85s kubelet Started container nginx
Normal Scheduled 85s default-scheduler Successfully assigned default/003-my-nginx-alpine-001-no-block to k8s232.bravexist.cn
Normal Pulled 38s (x4 over 85s) kubelet Container image "alpine:3.23.2" already present on machine
Normal Created 38s (x4 over 85s) kubelet Created container alpine
Normal Started 38s (x4 over 85s) kubelet Started container alpine
Warning BackOff 14s (x7 over 83s) kubelet Back-off restarting failed container
[root@k8s231.bravexist.cn /manifests/pods]#

关键报错

1
2
3
4
State:          Waiting
Reason: CrashLoopBackOff

Back-off restarting failed container

4.1.2 阻塞的方式

有多种阻塞的方式

数组可以放到中括号中,也可以竖着写。

法一 stdin: true

1
vim 003-my-nginx-alpine.yaml
1
2
3
4
5
6
7
8
9
10
11
apiVersion: v1
kind: Pod
metadata:
name: 003-my-nginx-alpine-002-stdin
spec:
containers:
- name: nginx
image: nginx:1.20
- name: alpine
image: alpine:3.23.2
stdin: true
1
2
CONTAINER ID   IMAGE         COMMAND    CREATED              STATUS              PORTS     NAMES
18cc5a2aa9ec 11879f4a35ff "/bin/sh" About a minute ago Up About a minute k8s_alpine_003-my-nginx-alpine-002-stdin_default_a8f692c4-cbcb-4555-9fd1-8487e0a28724_0

法二 command: ["tail","-f","/etc/hosts"]

1
vim 003-my-nginx-alpine.yaml
1
2
3
4
5
6
7
8
9
10
11
apiVersion: v1
kind: Pod
metadata:
name: 003-my-nginx-alpine-003-command-method
spec:
containers:
- name: nginx
image: nginx:1.20
- name: alpine
image: alpine:3.23.2
command: ["tail","-f","/etc/hosts"]
1
2
CONTAINER ID   IMAGE         COMMAND                CREATED         STATUS         PORTS     NAMES
b44286585dc5 11879f4a35ff "tail -f /etc/hosts" 2 minutes ago Up 2 minutes k8s_alpine_003-my-nginx-alpine-003-command-method_default_83b21176-b82b-476a-8510-ce43e6edef11_0

法三 args

1
vim 003-my-nginx-alpine.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: v1
kind: Pod
metadata:
name: 003-my-nginx-alpine-004-agrs-method
spec:
containers:
- name: nginx
image: nginx:1.20
- name: alpine
image: alpine:3.23.2
args:
- "tail"
- "-f"
- "/etc/hosts"
1
2
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS     NAMES
c33c6739eadb 11879f4a35ff "tail -f /etc/hosts" 53 seconds ago Up 52 seconds k8s_alpine_003-my-nginx-alpine-004-agrs-method_default_7b47c125-9791-40e3-902f-538e3e884958_0

法四(法二+法三)command + args

1
vim 003-my-nginx-alpine.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: v1
kind: Pod
metadata:
name: 003-my-nginx-alpine-005-command-and-agrs-method
spec:
containers:
- name: nginx
image: nginx:1.20
- name: alpine
image: alpine:3.23.2
command: ["tail"]
args:
- "-f"
- "/etc/hosts"
1
2
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS     NAMES
e8ba568a653d 11879f4a35ff "tail -f /etc/hosts" 46 seconds ago Up 46 seconds k8s_alpine_003-my-nginx-alpine-005-command-and-agrs-method_default_809c5174-7c1a-4665-b41e-64c2d84a0c95_0

4.1.3 基本操作

1
kubectl apply -f 003-my-nginx-alpine.yaml
1
kubectl get pods
1
kubectl get pods -o wide
1
2
3
4
5
6
7
8
9
kubectl describe pods 003-my-nginx-alpine-001-no-block

kubectl describe pods 003-my-nginx-alpine-002-stdin

kubectl describe pods 003-my-nginx-alpine-003-command-method

kubectl describe pods 003-my-nginx-alpine-004-agrs-method

kubectl describe pods 003-my-nginx-alpine-005-command-and-agrs-method
1
2
3
4
5
6
7
8
9
kubectl delete pods 003-my-nginx-alpine-001-no-block

kubectl delete pods 003-my-nginx-alpine-002-stdin

kubectl delete pods 003-my-nginx-alpine-003-command-method

kubectl delete pods 003-my-nginx-alpine-004-agrs-method

kubectl delete pods 003-my-nginx-alpine-005-command-and-agrs-method
1
kubectl delete -f 003-my-nginx-alpine.yaml
1
kubectl delete pods --all

4.2 宿主机网络hostNetwork

1
vi 004-my-nginx-host-network.yaml
1
2
3
4
5
6
7
8
9
10
apiVersion: v1
kind: Pod
metadata:
name: 005-nginx-host-network
spec:
# 共享宿主机网络
hostNetwork: true
containers:
- name: nginx
image: nginx:1.20
1
kubectl apply -f 004-my-nginx-host-network.yaml
1
kubectl get pods
1
kubectl get pods -o wide

验证发现,确实是宿主机网络

1
2
3
4
[root@k8s231.bravexist.cn /manifests/pods]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
005-nginx-host-network 1/1 Running 0 15s 192.168.10.232 k8s232.bravexist.cn <none> <none>
[root@k8s231.bravexist.cn /manifests/pods]#s
1
kubectl describe pods 004-nginx-host-network
1
kubectl delete pods 004-nginx-host-network
1
kubectl delete pods --all
1
kubectl delete -f 004-my-nginx-host-network.yaml

五、面试题

5.1 当一个Pod有多个容器时,如果连接到指定的容器?

使用 kubectl exec-c 参数

以多容器 002-my-nginx-tomcat.yaml 为例

1
kubectl create -f 002-my-nginx-tomcat.yaml
1
kubectl get pods -o wide

默认行为:连接第一个容器 nginx

1
kubectl exec -it 002-linux-nginx-tomcat bash
1
2
3
4
[root@k8s231.bravexist.cn /manifests/pods]# kubectl exec -it 002-linux-nginx-tomcat bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
Defaulted container "nginx" out of: nginx, tomcat
root@002-linux-nginx-tomcat:/#

指定连接某个容器

1
kubectl exec -it 002-linux-nginx-tomcat -c tomcat -- bash
1
2
[root@k8s231.bravexist.cn /manifests/pods]# kubectl exec -it 002-linux-nginx-tomcat -c tomcat -- bash
root@002-linux-nginx-tomcat:/usr/local/tomcat#

5.2 如果查看一个Pod最近20分钟的日志?

使用 kubectl logs,配合--since=20m
--timestamps 添加时间戳,用于日志没日期的情况。

以第一个案例 001-my-nginx.yaml 为例

1
kubectl apply -f 001-my-nginx.yaml
1
kubectl get pods -o wide |grep 001
1
curl -I 10.100.1.29
1
kubectl logs 001-linux-web-nginx --since=20m --timestamps
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
[root@k8s231.bravexist.cn /manifests/pods]# kubectl get pods -o wide |grep 001
001-linux-web-nginx 1/1 Running 0 3m51s 10.100.1.29 k8s232.bravexist.cn <none> <none>
[root@k8s231.bravexist.cn /manifests/pods]# curl -I 10.100.1.29
HTTP/1.1 200 OK
Server: nginx/1.27.5
Date: Wed, 24 Dec 2025 13:24:24 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Wed, 16 Apr 2025 12:01:11 GMT
Connection: keep-alive
ETag: "67ff9c07-267"
Accept-Ranges: bytes

[root@k8s231.bravexist.cn /manifests/pods]# kubectl logs 001-linux-web-nginx --since=20m --timestamps
2025-12-24T13:20:02.378609912Z /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
2025-12-24T13:20:02.378629388Z /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
2025-12-24T13:20:02.381083551Z /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
2025-12-24T13:20:02.383476799Z 10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
2025-12-24T13:20:02.388984197Z 10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
2025-12-24T13:20:02.389026498Z /docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
2025-12-24T13:20:02.389190445Z /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
2025-12-24T13:20:02.391742739Z /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
2025-12-24T13:20:02.393092274Z /docker-entrypoint.sh: Configuration complete; ready for start up
2025-12-24T13:20:02.405759492Z 2025/12/24 13:20:02 [notice] 1#1: using the "epoll" event method
2025-12-24T13:20:02.405773521Z 2025/12/24 13:20:02 [notice] 1#1: nginx/1.27.5
2025-12-24T13:20:02.405775606Z 2025/12/24 13:20:02 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14)
2025-12-24T13:20:02.405777120Z 2025/12/24 13:20:02 [notice] 1#1: OS: Linux 3.10.0-1160.el7.x86_64
2025-12-24T13:20:02.405778616Z 2025/12/24 13:20:02 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2025-12-24T13:20:02.405797214Z 2025/12/24 13:20:02 [notice] 1#1: start worker processes
2025-12-24T13:20:02.405799651Z 2025/12/24 13:20:02 [notice] 1#1: start worker process 29
2025-12-24T13:20:02.405801030Z 2025/12/24 13:20:02 [notice] 1#1: start worker process 30
2025-12-24T13:20:48.066455337Z 10.100.0.0 - - [24/Dec/2025:13:20:48 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.29.0" "-"
2025-12-24T13:21:22.304994185Z 10.100.0.0 - - [24/Dec/2025:13:21:22 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
2025-12-24T13:24:24.212284839Z 10.100.0.0 - - [24/Dec/2025:13:24:24 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.29.0" "-"
[root@k8s231.bravexist.cn /manifests/pods]#

5.3 如果查看一个Pod上一个容器的日志,上一个挂掉的容器日志?

使用 kubectl logs,配合 -p

以5.2案例为例,kill掉容器,然后重新看日志,需要-p 才能看到上一个挂掉容器的日志。

1
2
3
[root@k8s233.bravexist.cn ~]# docker kill 48829cdf51c0
48829cdf51c0
[root@k8s233.bravexist.cn ~]#
1
kubectl logs 001-linux-web-nginx -p
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
[root@k8s231.bravexist.cn /manifests/pods]# kubectl logs 001-linux-web-nginx 
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2025/12/24 10:04:42 [notice] 1#1: using the "epoll" event method
2025/12/24 10:04:42 [notice] 1#1: nginx/1.27.5
2025/12/24 10:04:42 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14)
2025/12/24 10:04:42 [notice] 1#1: OS: Linux 3.10.0-1160.el7.x86_64
2025/12/24 10:04:42 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2025/12/24 10:04:42 [notice] 1#1: start worker processes
2025/12/24 10:04:42 [notice] 1#1: start worker process 29
2025/12/24 10:04:42 [notice] 1#1: start worker process 30
[root@k8s231.bravexist.cn /manifests/pods]#
[root@k8s231.bravexist.cn /manifests/pods]#
[root@k8s231.bravexist.cn /manifests/pods]# kubectl logs 001-linux-web-nginx -p
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2025/12/24 10:01:35 [notice] 1#1: using the "epoll" event method
2025/12/24 10:01:35 [notice] 1#1: nginx/1.27.5
2025/12/24 10:01:35 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14)
2025/12/24 10:01:35 [notice] 1#1: OS: Linux 3.10.0-1160.el7.x86_64
2025/12/24 10:01:35 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2025/12/24 10:01:35 [notice] 1#1: start worker processes
2025/12/24 10:01:35 [notice] 1#1: start worker process 29
2025/12/24 10:01:35 [notice] 1#1: start worker process 30
10.100.0.0 - - [24/Dec/2025:10:02:21 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.29.0" "-"
[root@k8s231.bravexist.cn /manifests/pods]#

5.4 使用kubectl logs无法查看日志是什么原因,如何让其能够查看呢?

没有将日志输出到标准输出,错误输出。只需要创建软链接

这里自建构建一个nginx做实验。

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
mkdir /tmp/my-nginx && cd /tmp/my-nginx

cat > nginx.repo <<EOF
[nginx-stable]
name=nginx stable repo
baseurl=https://nginx.org/packages/centos/\$releasever/\$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
EOF

curl -o Centos7-tuna.repo https://mirrors.wlnmp.com/centos/Centos7-tuna-x86_64.repo

cat > Dockerfile <<EOF
FROM centos:7
RUN rm -rf /etc/yum.repos.d/*
COPY Centos7-tuna.repo /etc/yum.repos.d/Base.repo
COPY nginx.repo /etc/yum.repos.d/nginx.repo
# build v0.2
RUN yum install -y nginx
# build v0.3
# RUN yum install -y nginx && \ln -sf /dev/stdout /var/log/nginx/access.log && ln -sf /dev/stderr /var/log/nginx/error.log
CMD ["nginx","-g","daemon off;"]
EOF

cat > build.sh << EOF
#!/bin/bash
VERSION=\$1
docker build -t mynginx:v0.\${VERSION:-2} .
docker tag mynginx:v0.\${VERSION:-2} harbor.bravexist.cn/web/mynginx:v0.\${VERSION:-2}
docker push harbor.bravexist.cn/web/mynginx:v0.\${VERSION:-2}
EOF

chmod +x build.sh
./build.sh 2
# 修改配置后也构建一个 3版本的镜像
# ./build.sh 3
1
vim 006-mynginx-stdout-stderr.yaml
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:
name: 006-mynginx-stdout-stderr-no
spec:
containers:
- name: my-nginx
image: harbor.bravexist.cn/web/mynginx:v0.2
command:
- "nginx"
- "-g"
- "daemon off;"

---

apiVersion: v1
kind: Pod
metadata:
name: 006-mynginx-stdout-stderr
spec:
containers:
- name: my-nginx
image: harbor.bravexist.cn/web/mynginx:v0.3
command:
- "nginx"
- "-g"
- "daemon off;"
1
kubectl apply -f 006-mynginx-stdout-stderr.yaml
1
kubectl get pods -o wide

看不到日志

1
2
kubectl logs -f 006-mynginx-stdout-stderr-no
kubectl logs -f 006-mynginx-stdout-stderr
1
kubectl delete pods --all

差异配置。修改 Dockerfile 文件

1
2
ln -svf /dev/stdout /var/log/nginx/access.log
ln -svf /dev/stderr /var/log/nginx/error.log

5.5 如何实现Pod的容器的文件和宿主机之间相互拷贝?

使用 kubectl cp 即可

以5.1 案例继续(多容器应用)

这里有个疑惑,多容器的pod,复制进去后是哪个容器。

1
2
3
4
cat > index.html <<EOF
kubectl cp Test!!!
This is nginx? or tomcat?
EOF

拷贝进去

会拷贝到默认的第一个容器中,除非 -c 参数指定。

1
kubectl cp index.html 002-linux-nginx-tomcat:/usr/share/nginx/html
1
2
3
[root@k8s231.bravexist.cn /manifests/pods]# kubectl cp index.html 002-linux-nginx-tomcat:/usr/share/nginx/html
Defaulted container "nginx" out of: nginx, tomcat
[root@k8s231.bravexist.cn /manifests/pods]#
1
kubectl get pods -o wide|grep 002
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[root@k8s231.bravexist.cn /manifests/pods]# curl 10.100.1.14 -vv
* About to connect() to 10.100.1.14 port 80 (#0)
* Trying 10.100.1.14...
* Connected to 10.100.1.14 (10.100.1.14) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 10.100.1.14
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.20.2
< Date: Wed, 24 Dec 2025 11:16:31 GMT
< Content-Type: text/html
< Content-Length: 45
< Last-Modified: Wed, 24 Dec 2025 11:15:49 GMT
< Connection: keep-alive
< ETag: "694bcb65-2d"
< Accept-Ranges: bytes
<
kubectl cp Test!!!
This is nginx? or tomcat?
* Connection #0 to host 10.100.1.14 left intact
[root@k8s231.bravexist.cn /manifests/pods]#

拷贝到 tomcat,(需要手动指定容器)

1
kubectl cp index.html 002-linux-nginx-tomcat:/usr/local/tomcat/webapps/ROOT -c tomcat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[root@k8s231.bravexist.cn /manifests/pods]# curl 10.100.1.14:8080 -vv
* About to connect() to 10.100.1.14 port 8080 (#0)
* Trying 10.100.1.14...
* Connected to 10.100.1.14 (10.100.1.14) port 8080 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 10.100.1.14:8080
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Accept-Ranges: bytes
< ETag: W/"45-1766575110000"
< Last-Modified: Wed, 24 Dec 2025 11:18:30 GMT
< Content-Type: text/html
< Content-Length: 45
< Date: Wed, 24 Dec 2025 11:18:50 GMT
<
kubectl cp Test!!!
This is nginx? or tomcat?
* Connection #0 to host 10.100.1.14 left intact
[root@k8s231.bravexist.cn /manifests/pods]#

拷贝出来

替换顺序即可。

1
kubectl cp 002-linux-nginx-tomcat:/usr/local/tomcat/webapps/ROOT/index.jsp index.jsp -c tomcat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@k8s231.bravexist.cn /manifests/pods]# kubectl cp 002-linux-nginx-tomcat:/usr/local/tomcat/webapps/ROOT/index.jsp index.jsp -c tomcat 
tar: Removing leading `/' from member names
[root@k8s231.bravexist.cn /manifests/pods]# head index.jsp
<%--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

[root@k8s231.bravexist.cn /manifests/pods]#

5.6 镜像下载策略有哪些?请分别说明?

三种imagePullpolicy AlwaysIfnotPresentNever

Always: 会比较目前的和仓库的镜像状态,不一致就会重新拉取,镜像仓库没有也会显示拉取失败。

IfnotPresent:本地不存在镜像才会拉取。

Never:本地没有镜像也不会拉取。

构建镜像的脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
mkdir web && cd web

cat > index.html <<EOF
v1
EOF

cat > Dockerfile << EOF
FROM nginx:1.20
COPY index.html /usr/share/nginx/html
CMD ["nginx" "-g" "daemon off;"]
EOF

cat > build.sh << EOF
#!/bin/bash
VERSION=\$1
docker build -t nginx:v\${VERSION:-1} .
docker tag nginx:v\${VERSION:-1} harbor.bravexist.cn/web/nginx:v\${VERSION:-1}
docker push harbor.bravexist.cn/web/nginx:v\${VERSION:-1}
EOF

chmod +x build.sh

为了方便,指定Pod所在的节点。

1
vim 005-my-nginx-play-pullpolicy.yaml
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
apiVersion: v1
kind: Pod
metadata:
name: 005-pullpolicy-always
spec:
# 指定Node节点
nodeName: k8s232.bravexist.cn
containers:
- name: nginx
image: harbor.bravexist.cn/web/nginx:v1
command: ["nginx","-g","daemon off;"]
imagePullPolicy: Always

---

apiVersion: v1
kind: Pod
metadata:
name: 005-pullpolicy-ifnotpresent
spec:
# 指定Node节点
nodeName: k8s232.bravexist.cn
containers:
- name: nginx
image: harbor.bravexist.cn/web/nginx:v1
command: ["nginx","-g","daemon off;"]
imagePullPolicy: IfNotPresent

---

apiVersion: v1
kind: Pod
metadata:
name: 005-pullpolicy-never
spec:
# 指定Node节点
nodeName: k8s232.bravexist.cn
containers:
- name: nginx
image: harbor.bravexist.cn/web/nginx:v1
command: ["nginx","-g","daemon off;"]
imagePullPolicy: Never

多构建几次镜像,查看变化。

1
kubectl apply -f 005-my-nginx-play-pullpolicy.yaml
1
kubectl get pods -o wide
1
kubectl delete pods --all

十、错误整理

  1. 拼写错误,找不到指定的字段
  • kind 拼写成 bind
  • spec 拼写成 desc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@k8s231.bravexist.cn /manifests/pods]# cat 003-my-nginx-alpine.yaml 
apiVersion: v1
bind: Pod
metadata:
name: 003-my-nginx-alpine-001-no-block
desc:
containers:
- name: nginx
image: nginx:1.20
- name: alpine
image: alpine:3.23.2
[root@k8s231.bravexist.cn /manifests/pods]# kubectl apply -f 003-my-nginx-alpine.yaml
error: error validating "003-my-nginx-alpine.yaml": error validating data: kind not set; if you choose to ignore these errors, turn validation off with --validate=false
[root@k8s231.bravexist.cn /manifests/pods]#
1
2
3
[root@k8s231.bravexist.cn /manifests/pods]# kubectl apply -f 003-my-nginx-alpine.yaml
error: error validating "003-my-nginx-alpine.yaml": error validating data: ValidationError(Pod): unknown field "desc" in io.k8s.api.core.v1.Pod; if you choose to ignore these errors, turn validation off with --validate=false
[root@k8s231.bravexist.cn /manifests/pods]#
  1. 没有阻塞

使用任意方式阻塞即可(stdin、command、args、command + args)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  alpine:
Container ID: docker://0a25f83a86c5a8e4c25880927b708949b44eebe782e1538f60d27a795382139f
Image: alpine:3.23.2
Image ID: docker://sha256:11879f4a35ffe215fdb4175a8023aaf5bc096709e52a2d15ccacce55f145001f
Port: <none>
Host Port: <none>
State: Waiting
Reason: CrashLoopBackOff
Last State: Terminated

....

Normal Created 38s (x4 over 85s) kubelet Created container alpine
Normal Started 38s (x4 over 85s) kubelet Started container alpine
Warning BackOff 14s (x7 over 83s) kubelet Back-off restarting failed container
[root@k8s231.bravexist.cn /manifests/pods]#
  1. 不合法的 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
[root@k8s231.bravexist.cn /manifests/pods]# kubectl apply -f 005-my-nginx-play-pullpolicy.yaml
pod/005-pullpolicy-always created
pod/005-pullpolicy-never created
The Pod "005-pullpolicy-IfNotPresent" is invalid: metadata.name: Invalid value: "005-pullpolicy-IfNotPresent": a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')
[root@k8s231.bravexist.cn /manifests/pods]# cat 005-my-nginx-play-pullpolicy.yaml
apiVersion: v1
kind: Pod
metadata:
name: 005-pullpolicy-always
spec:
containers:
- name: nginx
image: harbor.bravexist.cn/web/nginx:v1
command: ["nginx","-g","daemon off;"]
imagePullPolicy: Always

---

apiVersion: v1
kind: Pod
metadata:
name: 005-pullpolicy-IfNotPresent
spec:
containers:
- name: nginx
image: harbor.bravexist.cn/web/nginx:v1
command: ["nginx","-g","daemon off;"]
imagePullPolicy: IfNotPresent

---

apiVersion: v1
kind: Pod
metadata:
name: 005-pullpolicy-never
spec:
containers:
- name: nginx
image: harbor.bravexist.cn/web/nginx:v1
command: ["nginx","-g","daemon off;"]
imagePullPolicy: Never
[root@k8s231.bravexist.cn /manifests/pods]#