K8s的Pod资源清单
K8s的Pod资源清单的编写、资源的增删改查、镜像的下载策略,及面试题
本质是创建一系列的资源清单文件。
一、环境准备
创建资源清单目录(231节点)
1 mkdir -pv /manifests/pods && cd /manifests/pods
二、单容器资源清单 2.1 查阅文档 第一次不会写资源清单文件,可以查阅
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资源清单
这里使用 vi 是方便粘贴,vim 太智能,总是自动补齐上一行的 #
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 apiVersion: v1 kind: Pod metadata: 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
2.4 查看Pod的相关信息
获取所有的 Pod
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]#
同时显示 Pod 的 IP 地址
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]#
获取某个 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 -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 实验及结论
每个节点都能访问到 Pod
两个容器共享一个主机IP地址
发现多个容器都会加入 Pod 所在的网络
kill 掉 tomcat、nginx 容器,ip地址不变,kill 掉 Pod 的容器,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
四、案例
主要有两个案例,
系统镜像需要阻塞,
网络模式,共享宿主机网络
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 -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 -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 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-nginxcat > 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
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.logln -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 [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 [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 Always、IfnotPresent、Never
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 webcat > 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: 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: 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: 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
十、错误整理
拼写错误,找不到指定的字段
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 : Podmetadata: 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]#
没有阻塞
使用任意方式阻塞即可(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]#
不合法的 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]#