Allen Blog Allen Blog

SELF SPACE

目录
k8s-manifest learn
/    

k8s-manifest learn

K8S资源清单内容

Pod

关键字简介:

apiVersion:
指的是Api的版本。
kind:
资源的类型。
metadata:
资源的元数据。比如资源的名称,标签,名称空间,注解等信息。
spec:
用户期望资源的运行状态。
staus:
资源实际的运行状态,由K8S集群内部维护。

案例1:

编写yaml文件:

# 指定API的版本号
apiVersion: v1
# 指定资源的类型
kind: Pod
# 指定元数据
metadata:
  # 指定名称
  name: web
# 用户期望的资源状态
spec:
  # 定义容器资源
  containers:
    # 指定的名称
  - name: nginx
    # 指定容器的镜像
    image: harbor.allen.com/k8s/nginx:1.23.4-alpine

创建Pod:

kubectl create -f 01-nginx.yaml

如果Pod存在,更新资源;如果不存在,创建资源

kubectl apply -f 01-nginx.yaml

查看资源:

kubectl get pods -o wide

相关字段说明:

NAME
代表的是资源的名称。
READY
代表资源是否就绪。比如 0/1 ,表示一个Pod内有一个容器,而且这个容器还未运行成功。
STATUS
代表容器的运行状态。
RESTARTS
代表Pod重启次数,即容器被创建的次数。
AGE
代表Pod资源运行的时间。
IP
代表Pod的IP地址。
NODE
代表Pod被调度到哪个节点。
其他:
"NOMINATED NODE和"READINESS GATES"暂时先忽略哈

删除资源:

kubectl delete -f 01-nginx.yaml

案例2:一个清单运行多个容器

apiVersion: v1
kind: Pod
metadata:
  name: allen-nginx-tomcat
spec:
  containers:
  - name: nginx
    image: nginx:1.23.4-alpine
  - name: tomcat
    image: tomcat:jre8-alpine

故障排查案例:

alpine:轻量级的 Linux 发行版 ⚠ 使用此镜像启动的容器,会失败,因为容器中没有持久运行的进程

涉及到知识点:

hostNetwork: true 使用宿主机网络,相当于"docker run --network host"

stdin: true

args: ["tail","-f","/etc/hosts"]

command: ["sleep","15"]

command:

/- "tail"
/- args:

/- "-f"

/- "/etc/hosts"

apiVersion: v1
kind: Pod
metadata:
  name: allen-nginx-alpine
spec:
  # 使用宿主机网络,相当于"docker run --network host"
  hostNetwork: true
  containers:
  - name: nginx
    image: nginx:1.23.4-alpine
  - name: linux
    image: alpine
    # 给容器分配一个标准输入,默认值为false
    # stdin: true
    # 给容器分配一个启动命令,修改Dockerfile的CMD指令
    # args: ["tail","-f","/etc/hosts"]
    # 也可以修改command字段,相当于修改Dockerfile的ENTRYPOINT指令
    # command: ["sleep","15"]
    # args也可以和command命令搭配使用,和Dockfile的ENTRYPOINT和CMD效果类似
    command:
    - "tail"
    args:
    - "-f"
    - "/etc/hosts"

案例3:

apiVersion: v1
kind: Pod
metadata:
  name: games
spec:
  hostNetwork: true
  # 将Pod调度到指定节点,注意,该node名称必须和etcd的数据保持一致
  nodeName: k8s-node01
  containers:
  - name: game
    image: harbor.allen.com/games/games:v0.1

案例4:一个清单运行多个Pod

apiVersion: v1
kind: Pod
metadata:
  name: allen-web-restartpolicy-always
spec:
  nodeName: k8s-node01
  # 当容器退出时,始终重启容器。
  restartPolicy: Always
  containers:
  - name: nginx
    image: harbor.allen.com/k8s/web:v0.1
    imagePullPolicy: Always
    command:
    - "sleep"
    - "10"

---
apiVersion: v1
kind: Pod
metadata:
  name: allen-web-restartpolicy-onfailure
spec:
  nodeName: k8s-node01
  # 当容器正常退出时不会重启容器,异常退出时,会重启容器。
  restartPolicy: OnFailure
  containers:
  - name: nginx
    image: harbor.allen.com/k8s/web:v0.1
    imagePullPolicy: Always
    command:
    - "sleep"
    - "10"

---
apiVersion: v1
kind: Pod
metadata:
  name: allen-web-restartpolicy-never
spec:
  nodeName: k8s-node01
  # 当容器退出时,始终不重启。
  restartPolicy: Never
  containers:
  - name: nginx
    image: harbor.allen.com/k8s/web:v0.1
    imagePullPolicy: Always
    command:
    - "sleep"
    - "10"

故障常用命令

(1)将Pod容器的文件拷贝到宿主机

kubectl cp games:/start.sh /tmp/start.sh

(2)连接到Pod的容器(必须在容器是run的状态)

kubectl exec -it games -- sh

(3)查看某个Pod的日志。

kubectl logs -f games

持久化

emptyDir(同一Pod)

apiVersion: v1
kind: Pod
metadata:
  name: allen-volume-emptydir
spec:
  # 定义存储卷
  volumes:
  # 指定存储卷名称
  - name: data01
  # 指定存储卷类型为emptyDir
  # 当pod删除时,存储卷也会被删除
    emptyDir: {}
  containers:
  - name: web
    image: harbor.allen.com/k8s/nginx:1.23.4-alpine
    # 指定挂载点
    volumeMounts:
    # 指定存储卷的名称
    - name: data01
    # 指定挂载目录
      mountPath: /usr/share/nginx/html
  - name: linux
    image: harbor.allen.com/k8s/alpine:v1
    stdin: true
    #一个Pod里面的容器都共享这个存储卷
    volumeMounts:
    - name: data01
      mountPath: /allen
#本地存储卷所在的位置
[root@k8s-node01 ~]# ll /var/lib/kubelet/pods/a14858f1-be81-4f8b-a526-e683e629da57/volumes/kubernetes.io~empty-dir/data01/
total 4
-rw-r--r-- 1 root root 26 Jul 27 02:45 index.html

#共享存储卷data01
[root@k8s-master01 /server/yaml]# kubectl exec allen-volume-emptydir -c linux -- ls -l /allen/
total 4
-rw-r--r--    1 root     root            42 Jul 26 19:03 index.html

Pod被删除,卷也被删除,因为会将/var/lib/kubelet/pods/a14858f1-be81-4f8b-a526-e683e629da57/ 这个目录删除 ------>(emptyDir类型的存储卷)

hostPath(同一node)
apiVersion: v1
kind: Pod
metadata:
  name: allen-volume-hostpath01
spec:
  nodeName: k8s-node01
  # 定义存储卷
  volumes:
  # 指定存储卷名称
  - name: web-data
  # 指定存储卷类型为hostpath
    hostPath:
  # 指定宿主机存储卷的路径 (将数据存在主机这个目录下)
      path: /hostpath-data
  containers:
  - name: web
    image: harbor.allen.com/k8s/nginx:1.23.4-alpine
    # 指定挂载点
    volumeMounts:
    # 指定存储卷的名称
    - name: web-data
    # 指定挂载目录
      mountPath: /usr/share/nginx/html

---
apiVersion: v1
kind: Pod
metadata:
  name: allen-volume-hostpath02
spec:
  nodeName: k8s-node01
  volumes:
  - name: linux-data
    hostPath:
      path: /hostpath-data
  containers:
  - name: linux
    image: harbor.allen.com/k8s/alpine:v1
    stdin: true
    volumeMounts:
    - name: linux-data
      mountPath: /allen
#master节点
kubectl apply -f 07-volume-hostpath.yaml
kubectl exec allen-volume-hostpath01 -it -c web -- sh
kubectl gte pods -o wide
curl 10.100.2.12
<h1>我是hostPath v1.0</h1>
kubectl exec allen-volume-hostpath02 -c linux -- ls -l /allen
total 4
-rw-r--r--    1 root     root            29 Jul 26 19:30 index.html

#node节点
[root@k8s-node01 ~]# cd /hostpath-data/
[root@k8s-node01 /hostpath-data]# ls
index.html
[root@k8s-node01 /hostpath-data]# cat "<h1>我是通过外部存储卷修改的 v2.0</h1>" > index.html
cat: <h1>我是通过外部存储卷修改的 v2.0</h1>: No such file or directory
[root@k8s-node01 /hostpath-data]# echo "<h1>我是通过外部存储卷修改的 v2.0</h1>" > index.html

#master节点
[root@k8s-master01 /server/yaml]# curl 10.100.2.12
<h1>我是通过外部存储卷修改的 v2.0</h1>

删除Pod时,不会删除存储卷,注意:共享hostPath存储卷的Pod必须存在同一个节点

Nfs
apiVersion: v1
kind: Pod
metadata:
  name: allen-volume-nfs01
spec:
  nodeName: k8s-node01
  # 定义存储卷
  volumes:
  # 指定存储卷名称
  - name: web-data
  # 指定存储卷类型为nfs
    nfs:
  # 指定nfs服务器地址
      server: harbor.allen.com
  # 指定nfs存储卷的路径
      path: /allen/data/k8s
  containers:
  - name: web
    image: harbor.allen.com/k8s/nginx:1.23.4-alpine
    # 指定挂载点
    volumeMounts:
    # 指定存储卷的名称
    - name: web-data
    # 指定挂载目录
      mountPath: /usr/share/nginx/html

---
apiVersion: v1
kind: Pod
metadata:
  name: allen-volume-nfs02
spec:
  nodeName: k8s-node02
  volumes:
  - name: linux-data
    nfs:
      server: harbor.allen.com
  # 指定nfs存储卷的路径
      path: /allen/data/k8s
  containers:
  - name: linux
    image: harbor.allen.com/k8s/alpine:v1
    stdin: true
    volumeMounts:
    - name: linux-data
      mountPath: /allen
#server
[root@k8s-master01 /server/yaml]# kubectl apply -f 08-volume-nfs.yaml
pod/allen-volume-nfs01 created
pod/allen-volume-nfs02 created
[root@k8s-master01 /server/yaml]# kubectl get pods
NAME                 READY   STATUS    RESTARTS   AGE
allen-volume-nfs01   1/1     Running   0          7s
allen-volume-nfs02   1/1     Running   0          7s
[root@k8s-master01 /server/yaml]# kubectl get pods -o wide
NAME                 READY   STATUS    RESTARTS   AGE   IP            NODE         NOMINATED NODE   READINESS GATES
allen-volume-nfs01   1/1     Running   0          11s   10.100.2.16   k8s-node01   <none>           <none>
allen-volume-nfs02   1/1     Running   0          11s   10.100.1.10   k8s-node02   <none>           <none>

#nfs
[root@harbor01 /allen/data/k8s]# echo "<h1>我是nfs添加的内容</h1>" > index.html
[root@harbor01 /allen/data/k8s]# ls
index.html

#server
[root@k8s-master01 /server/yaml]# curl 10.100.2.16
<h1>我是nfs添加的内容</h1>
[root@k8s-master01 /server/yaml]# kubectl exec allen-volume-nfs02 -- ls -l /allen
total 4
-rw-r--r--    1 root     root            34 Jul 26 20:00 index.html

Nfs存储卷解决了两个node的Pod之间数据共享问题

资源限制

apiVersion: v1
kind: Pod
metadata:
  name: allen-stress-01
spec:
  containers:
  - name: stress
    image: harbor.allen.com/tools/linux-tools:v0.1
    args:
    - "tail"
    - "-f"
    - "/etc/hosts"
    # 对容器进行资源限制
    resources:
    # 期望目标节点有的资源大小,不满足以下条件不会进行调度,Pod处于pending状态
      requests:
      # 要求目标内存
        memory: 256M
      # 要求目标CPU核数,固定单位:1core = 1000m
        cpu: 500m
    # 配置容器使用资源的上限
      limits:
        memory: 256M
      # 不带单位就为 1核
        cpu: 1

知识点:

resources: 资源关键字

requests: 期望目标资源大小 不满足条件不会进行调度,Pod处于pending状态

limits: 配置容器使用资源的上限

#master
[root@k8s-master01 /server/yaml]# kubectl apply -f 09-stress.yaml
[root@k8s-master01 /server/yaml]# kubectl exec allen-stress-01 -it -- sh

/usr/local/stress # stress -c 4 --verbose --timeout 1m
/usr/local/stress # stress -m 5 --vm-bytes 200000000 --vm-keep --verbose

#node
[root@k8s-node02 ~]# docker stats 2e9d43e29947

面试题

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

kubectl exec -it allen-nginx-tomcat -- sh # 默认连接到第一个容器

kubectl exec -it allen-nginx-tomcat -c nginx -- sh # 连接nginx容器

kubectl exec -it allen-nginx-tomcat -c tomcat -- sh # 连接tomcat容器

查看容器名称

cat 02-nginx-tomcat.yaml

kubectl describe pod allen-nginx-tomcat

kubectl get pods allen-nginx-tomcat -o yaml

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

kubectl logs -c nginx -f --timestamps --since=20m allen-nginx-tomcat

-c:
指定要查看的容器名称。

-f:
实时查看日志。

--timestamps :
显示时间戳相关信息。

--since=20m
查看最近20分钟内的日志。

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

kubectl logs -c tomcat -f --timestamps -p allen-nginx-tomcat

-p:

​ 查看上一个挂掉的容器

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

使用"kubectl logs"查看的是容器的标准输出或错误输出日志,如果想要使用该方式查看,需要将日志重定向到/dev/stdout或者/dev/stderr。

如何实现Pod的容器的文件和宿主机之间相互拷贝?
#将Pod的的文件拷贝到宿主机:
kubectl cp allen-game-014:/start.sh /tmp/1.sh  # 拷贝文件
kubectl cp allen-game-014:/etc /tmp/2222  # 拷贝目录
ll /tmp/
total 16
-rw-r--r--  1 root root 3369 Apr 13 17:01 1.sh
drwxr-xr-x 20 root root 4096 Apr 13 17:02 2222

#将宿主机的文件拷贝到Pod的容器中:
kubectl cp 01-nginx.yaml allen-game-014:/
kubectl cp /tmp/2222/ allen-game-014:/
kubectl exec allen-game-014 -- ls -l /
total 24
-rw-r--r--    1 root     root           301 Apr 13 09:03 01-nginx.yaml
drwxr-xr-x   20 root     root          4096 Apr 13 09:04 2222
镜像下载策略有哪些?请分别说明?

Always 默认值,表示始终拉取最新的镜像。

IfNotPresent 如果本地有镜像,则不去远程仓库拉取镜像,若本地没有,才会去远程仓库拉取镜像。

Never 如果本地有镜像则尝试启动,若本地没有镜像,也不会去远程仓库拉取镜像。

apiVersion: v1
kind: Pod
metadata:
  name: allen-web-imagepullpolicy-001
spec:
  nodeName: k8s-node01
  containers:
  - name: nginx
    image: harbor.allen.com/k8s/web:v0.1
    # 指定镜像的下载策略,有效值为: Always, Never, IfNotPresent
    #    Always:
    #       默认值,表示始终拉取最新的镜像。
    #    IfNotPresent:
    #       如果本地有镜像,则不去远程仓库拉取镜像,若本地没有,才会去远程仓库拉取镜像。
    #    Never:
    #       如果本地有镜像则尝试启动,若本地没有镜像,也不会去远程仓库拉取镜像。
    #imagePullPolicy: Always
    # imagePullPolicy: IfNotPresent
    imagePullPolicy: Never
容器的重启策略有哪些?请分别说?(注意, K8S所谓的重启指的是重新创建容器。)

restartPolicy: Always # 当容器退出时,始终重启容器。

restartPolicy: OnFailure # 当容器正常退出时不会重启容器,异常退出时,会重启容器。

restartPolicy: Never # 当容器退出时,始终不重启。

apiVersion: v1
kind: Pod
metadata:
 name: allen-web-restartpolicy-always
spec:
 nodeName: k8s-node01
 # 当容器退出时,始终重启容器。
 restartPolicy: Always
 containers:
 - name: nginx
   image: harbor.allen.com/k8s/web:v0.1
   imagePullPolicy: Always
   command:
   - "sleep"
   - "10"

---
apiVersion: v1
kind: Pod
metadata:
 name: allen-web-restartpolicy-onfailure
spec:
 nodeName: k8s-node01
 # 当容器正常退出时不会重启容器,异常退出时,会重启容器。
 restartPolicy: OnFailure
 containers:
 - name: nginx
   image: harbor.allen.com/k8s/web:v0.1
   imagePullPolicy: Always
   command:
   - "sleep"
   - "10"

---
apiVersion: v1
kind: Pod
metadata:
 name: allen-web-restartpolicy-never
spec:
 nodeName: k8s-node01
 # 当容器退出时,始终不重启。
 restartPolicy: Never
 containers:
 - name: nginx
   image: harbor.allen.com/k8s/web:v0.1
   imagePullPolicy: Always
   command:
   - "sleep"
   - "10"
向容器传递环境变量的两种方式

知识点:

env: 后面跟键值对 - key

​ value

valueFrom: 引用已有的关键字变量

​ fieldRef: 引用某个字段

​ fieldPath: 指定字段的路径

metadata.name

spec.nodeName

status.hostIP

status.podIP

apiVersion: v1
kind: Pod
metadata:
 name: allen-game-env
spec:
 nodeName: k8s-node01
 containers:
 - name: game
   image: harbor.allen.com/games/games:v0.1
   # 想容器传递环境变量
   env:
     # 指定的变量名称
   - name: SCHOOL
     # 指定变量的值
     value: HBNU
   - name: CLASS
     value: 2110
   - name: ALLEN_POD_NAME
     # 不适用自定义的变量值,而是引用别处的值
     valueFrom:
       # 值引用自某个字段
       fieldRef:
         # 指定字段的路径 
         fieldPath: "metadata.name"
   - name: ALLEN_NODENAME
     valueFrom:
       fieldRef:
         fieldPath: "spec.nodeName"
   - name: ALLEN_HOSTIP
     valueFrom:
       fieldRef:
         fieldPath: "status.hostIP"
   - name: ALLEN_PODIP
     valueFrom:
       fieldRef:
         fieldPath: "status.podIP"

kubectl exec linux85-game-env -- env


标题:k8s-manifest learn
作者:jiu5
地址:http://solo.jiufog.space/articles/2025/03/04/1741065113564.html