Kubernetes 的 Pod 资源

Kubernetes 命令

选项 作用
-n 指定名称空间
-f 指定资源清单
-c 指定连接 POD 中的容器
-o 查看 pod 指定格式信息
-w 动态查看
1)查看资源
kubectl get 资源名
kubectl get ns(namespace)
kubectl get node
kubectl get pod

2)创建资源
kubectl create 资源名 名称空间名字 --image(可指定镜像)
kubectl create ns 名称空间名字

3)给资源打标签
kubectl label 资源名 key=value
kubectl label pod key=value
kubectl label node key=value

4)删除资源
kubectl delete 资源名 名称空间
kubectl delete ns 名称空间

5)查看资源相关信息(排错)
kubectl describe 资源名

6)查看日志
kubectl logs pod pod名

7)启动pod
kubectl run pod

8)连接pod
kubectl exec -it pod名字 -- /bin/bash

9)连接pod中的指定容器
kubectl exec -it pod名字 -c 容器名 -- /bin/bash

Pod 沉浸式体验

# 创建一个控制器资源
[root@master-1 ~]# kubectl create deployment  nginx --image=nginx:alpine

# 指定副本数量
--replicas=10
# 创建10个nginx
[root@master-1 ~]# kubectl create deployment  nginx10 --image=nginx:alpine --replicas=10
[root@master-1 ~]# kubectl get pod
NAME                       READY   STATUS    RESTARTS   AGE
nginx-565785f75c-clz9l     1/1     Running   0          17s
nginx10-6cc8ffd95b-222z8   1/1     Running   0          6s
nginx10-6cc8ffd95b-2plb9   1/1     Running   0          6s
nginx10-6cc8ffd95b-5q5q8   1/1     Running   0          6s
nginx10-6cc8ffd95b-hfwwr   1/1     Running   0          6s
nginx10-6cc8ffd95b-mh2cj   1/1     Running   0          6s
nginx10-6cc8ffd95b-pbzvw   1/1     Running   0          6s
nginx10-6cc8ffd95b-qf64d   1/1     Running   0          6s
nginx10-6cc8ffd95b-r9gns   1/1     Running   0          6s
nginx10-6cc8ffd95b-rccn7   1/1     Running   0          6s
nginx10-6cc8ffd95b-rvp97   1/1     Running   0          6s

# 查看pod指定格式信息(常用)
[root@master-1 ~]# kubectl get pod -o name
[root@master-1 ~]# kubectl get pod -o wide
[root@master-1 ~]# kubectl get pod -o json
[root@master-1 ~]# kubectl get pod -o yaml

# 将yaml语法导出
[root@master-1 ~]# kubectl get pod nginx-565785f75c-clz9l -o yaml > /root/nginx.yml
# 使用资源清单启动pod
[root@master-1 ~]# vim nginx-test.yml
apiVersion: v1
kind: Pod
metadata:
  labels:
    app: nginx
  name: nginx
  namespace: default
spec:
  containers:
  - image: nginx:alpine
    imagePullPolicy: IfNotPresent
    name: nginx
## 启动容器(如果配置有变化,可以自动更新)
[root@master-1 ~]# kubectl apply -f nginx-test.yaml 
## 启动容器(只能运行一次)
[root@master-1 ~]# kubectl create -f nginx-test.yaml 
## 查看
[root@master-1 ~]# kubectl get pod nginx
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          77s

# 删除控制器中的pod
[root@master-1 ~]# kubectl delete deployments nginx10

# 自己编写资源清单实践
[root@master-1 ~]# cat suibian.yml 
apiVersion: "v1"
kind: "Namespace"
metadata:
  name: hg
---
apiVersion: "v1"
kind: "Pod"
metadata:
  name: nginx-nb666
  namespace: hg 
  labels:
    app: nginx
spec: 
  containers:
  - image: nginx:alpine
    imagePullPolicy: IfNotPresent
    name: nginx
# 查看pod
[root@master-1 ~]# kubectl get pod -n hg
NAME           READY   STATUS    RESTARTS   AGE
nginx-nb666    1/1     Running   0          14s

# 单pod启动多容器
[root@master-1 ~]# vim suibian.yml
apiVersion: "v1"
kind: "Namespace"
metadata:
  name: hg
---
apiVersion: "v1"
kind: "Pod"
metadata:
  name: nginx-nb666
  namespace: hg
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx:alpine
    imagePullPolicy: IfNotPresent

  - name: busybox
    imagePullPolicy: IfNotPresent
    image: busybox
    command: ["/bin/tail","-f","/etc/hosts"]
# 查看pod    
[root@master-1 ~]# kubectl get pod -n hg
NAME           READY   STATUS    RESTARTS   AGE
nginx-nb666    2/2     Running   0          18s

资源清单详解

# API的版本号(接口)
apiVersion: v1
#部署的资源类型
kind: Pod
# 元数据信息
metadata:
  # 资源的名称(pod名字)
  name: nginx-nb666
  # 指定的名称空间(给pod启动在哪个名称空间)
  namespace: default
  # 打标签
  labels:
    标签名 key: value
    app: nginx
# 自定义Pod资源的配置
spec:
  #定义容器相关信息
  containers:
    # 定义容器的名称
  - name: nginx1
    # 定义容器基于哪个镜像,启动
    image: nginx:1.18
    # 镜像拉取规则     
    imagePullPolicy: Always(#总是拉取镜像)
                     Never(#永远不拉取镜像)
                     IfNotPresent(#如果不存在就拉取镜像,存在就不拉取镜像)

Kubernetes 标签使用

## 查看标签
--show-labels
[root@master-1 ~]# kubectl get pod -n hg --show-labels
NAME           READY   STATUS    RESTARTS   AGE     LABELS
nginx-nb666    2/2     Running   0          63s     app=nginx

## 打标签(node)
[root@master-1 ~]# kubectl label nodes node-1 CPU=1c

## 打标签(pod)
[root@master-1 ~]# kubectl label pod -n hg nginx-nb666 app=nginx

## 使用资源清单打标签
metadata:
  labels:
    app: nginx

## 删除标签
[root@master-1 ~]# kubectl label nodes node-1 CPU-

## 根据标签找pod
[root@master-1 ~]# kubectl get pod --selector=app=nginx -n hg
NAME           READY   STATUS    RESTARTS   AGE
nginx-nb666    2/2     Running   0          2m42s

## 根据标签删除
kubectl delete pod -l nginx=nn

重新认识 Pod

共享网络

image-20230920213926033

POD 内的容器使用 Container 模式共享根容器的网络
容器看到的网络设备信息和根容器完全相同
POD 内的多个容器可以使用 localhost 进行网络通讯
POD 内的多个容器不能绑定相同的端口
POD 的生命周期和根容器一样,如果根容器退出了,POD 就退出了

# 测试一个pod中运行两个容器
[root@master-1 ~]# vim suibian.yml
apiVersion: "v1"
kind: "Namespace"
metadata:
  name: hg
---
apiVersion: "v1"
kind: "Pod"
metadata:
  name: nginx-nb666
  namespace: hg
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx:alpine
    imagePullPolicy: IfNotPresent

  - name: busybox
    imagePullPolicy: IfNotPresent
    image: busybox
    command: ["/bin/tail","-f","/etc/hosts"]

# 指定pod启动在某个节点上
spec:
  # 指定node名为node-1的机器上,启动pod
  nodeName: node-1
  # 指定node标签为app: nginx的机器上,启动pod
  nodeSelector:
    app: nginx
  containers:
  - name: nginx
    image: nginx:alpine
    imagePullPolicy: IfNotPresent

  - name: busybox
    imagePullPolicy: IfNotPresent
    image: busybox
    command: ["/bin/tail","-f","/etc/hosts"]

共享存储(挂载)

image-20230920214034084

默认情况下一个POD内的容器文件系统是互相隔离的
如果想让一个POD容器共享文件那么只需要定义一个Volume,然后两个容器分别挂载到这个Volume中
hostPath:将容器中的目录挂载到宿主机上指定的目录,为容器之间共享存储,具有数据持久化
emptyDir:在宿主机找个临时目录挂载,只为容器之间共享存储,无法数据持久化

# hostPath
[root@master-1 ~]# cat suibian.yml
apiVersion: "v1"
kind: "Namespace"
metadata:
  name: hg
---
apiVersion: "v1"
kind: "Pod"
metadata:
  name: nginx-nb666
  namespace: hg 
  labels:
    app: nginx
spec:
  volumes:
  - name: Guazaidian1
    hostPath:
      path: /data/test1

  volumes:
  - name: Guazaidian2
    hostPath:
      path: /data/test2

  containers:
  - name: nginx
    image: nginx:alpine
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - name: Guazaidian1
      mountPath: /var/log/nginx/

  - name: busybox
    imagePullPolicy: IfNotPresent
    image: busybox
    command: ["/bin/tail","-f","/etc/hosts"]
    volumeMounts:
    - name: Guazaidian1
      mountPath: /opt/test

# emptyDir
[root@master-1 ~]# cat suibian.yml
apiVersion: "v1"
kind: "Namespace"
metadata:
  name: hg
---
apiVersion: "v1"
kind: "Pod"
metadata:
  name: nginx-nb666
  namespace: hg 
  labels:
    app: nginx
spec:
  volumes:
  - name: Guazaidian1
    hostPath:
      path: /data/test01

  volumes:
  - name: Guazaidian2
    emptyDir: {}

  containers:
  - name: nginx
    image: nginx:alpine
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - name: Guazaidian2
      mountPath: /var/log/nginx/

  - name: busybox
    imagePullPolicy: IfNotPresent
    image: busybox
    command: ["/bin/tail","-f","/etc/hosts"]
    volumeMounts:
    - name: Guazaidian2
      mountPath: /opt/test

POD的生命周期

image-20230921153907320

image-20230921153921585

### POD的生命周期
1.主容器开始之前启动初始化容器
2.初始化容器,执行完指定的操作时,结束
3.启动主容器
  启动主容器之后,调用启动后的钩子(hook:postStart)
4.存活态探针
  就绪态探针
5.停止容器,先执行停止前的钩子(hook:preStop)

## init container
初始化容器是指,在主容器启动之前,我们可以让他做一些准备工作。
比如:
1.两个容器做了共享存储,那么我们可以让它先启动一个容器,来对目录进行更改用户和授权
2.初始化容器启动后做完指定的操作 在主容器启动之前就会结束
3.容器需要连接数据,那么可以让初始化容器检测数据库是否可以正常连接,如果可以再启动主容器

## hook
PostStart:在容器启动创建后,立即执行,但时间不能太长,否则容器不会是running状态
PreStop:在容器停止前,执行一些命令,主要用于优雅关闭程序

## liveness probe
存活态探针,用于定义容器内,应用是否满足探针指定状态
比如:
pod跑的是nginx服务 设置了存活态探针 nginx进程不存活或者网站访问到的状态码不正常 那k8s就会杀死这个pod 重新启动这个pod

## readiness probe
就绪态探针,指定何时允许容器进入流量
比如:
pod跑的是nginx服务连接了mysql 设置了就绪态探针 那么当mysql没启动(准备就绪)之前 不会允许外网访问到nginx

Pod对容器的封装和应用

那么我们在工作中,一个pod究竟要放几个容器?

在实际工作中我们除了完成任务以外还需要考虑以后扩容的问题,就拿wordpress举例,有以下两种方案:

第一种:全部放一个pod里

image-20230921154204805

第二种:Wordpress和MySQL分开

image-20230921154229798

那么如何扩容呢?如果第一种方案大家会发现没有办法很好的扩容,因为数据库和wordpress已经绑定成一个整体了,扩容wordpress就得扩容mysql。而第二种方案就要灵活的多。(横向扩展肯定是添加新的pod 而不是在pod里去加服务 )

image-20230921154312674

初始化容器

## 可以先initContainers启动一个初始化容器,来对代码进行提前部署,initContainers里的内容写法和正常主容器相同
## 用emptyDir让同一个pod里的两个容器做共享存储 会在宿主机上起一个随机目录放置挂载的内容 但不做持久化 pod结束就会清除目录

# 示例语法:
spec:
  initContainers:
  - name: 容器名
    image: 镜像仓库:标签
    imagePullPolicy: IfNotPresent
    args: ["命令", "选项","参数"]

[root@master-1 ~]# vim nginx-init.yaml
apiVersion: "v1"
kind: "Pod"
metadata:
  name: nginx-init
spec:
  volumes:
  - name: nginx-data
    emptyDir: {}
  initContainers:
  - name: nginx-init-container
    image: busybox
    imagePullPolicy: IfNotPresent
    args: ['/bin/sh', '-c','echo k8s nginx init > /usr/share/nginx/html/index.html']
    volumeMounts:
    - name: nginx-data
      mountPath: /usr/share/nginx/html/
  containers:
  - name: nginx-container
    image: nginx:alpine
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - name: nginx-data
      mountPath: /usr/share/nginx/html/

## 启动
[root@master-1 ~]# kubectl apply -f nginx-init.yml 
pod/nginx-init created

## 查看ip
[root@master-1 ~]# kubectl get pod -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP          NODE     NOMINATED NODE   READINESS GATES
nginx-565785f75c-6q92k   1/1     Running   0          13m   10.2.1.15   node-1   <none>           <none>
nginx-init               1/1     Running   0          21s   10.2.1.20   node-1   <none>           <none>
[root@master-1 ~]# curl 10.2.1.20
k8s nginx init

### 到启动pod的node节点上看随机创建的挂载目录
## 查看随机目录位置的方法 到对应的node节点上 看这个容器的配置
# 找到对应的容器
docker ps
# 查看该容器的配置
docker inspect 容器ID
# 找到
"Mounts": [
    {
        "type": "bind"
        "Source": "随机目录"
        ......
    }
]

[root@node-1 ~]# cat /var/lib/kubelet/pods/6a83310a-0444-4b0b-992b-f1aa07e08bce/volumes/kubernetes.io~empty-dir/nginx-data/index.html 
k8s nginx init

hook

PostStart:在容器启动创建后,立即执行,但时间不能太长,否则容器不会是running状态
exec:执行命令
httpGet:检测http
tcpSocket:检测端口
## 在lifecycle指定要添加的钩子 command指定这个钩子要进行的操作

# 示例语法:
spec:
  containers:
  - name: 容器名
    image: 镜像仓库:标签
    imagePullPolicy: IfNotPresent
    lifecycle:
      postStart:
        exec:
          command: ["命令", "选项","参数"]

## 编写yml文件
[root@master-1 ~]# vim nginx-hook.yml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-prestop
  labels:
    name: nginx-prestop
spec:
  containers:
  - name: nginx-prestop
    image: nginx:alpine
    imagePullPolicy: IfNotPresent
    lifecycle:
      postStart:
        exec:
          command:
          - "/bin/sh"
          - "-c"
          - "echo k8s postStart > /usr/share/nginx/html/index.html"

## 启动
[root@master-1 ~]# kubectl apply -f nginx-hook.yml  

## 查看
[root@master-1 ~]# kubectl get pod -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP          NODE     NOMINATED NODE   READINESS GATES
nginx-prestop            1/1     Running   0          42s   10.2.1.21   node-1   <none>           <none>
[root@master-1 ~]# curl 10.2.1.21
k8s postStart

PreStop:在容器停止前,执行一些命令,主要用于优雅关闭程序
exec:执行命令
httpGet:检测http
tcpSocket:检测端口

## 编写yml文件
[root@master-1 ~]# vim nginx-prestop.yml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-prestop
  labels:
    name: nginx-prestop
spec:
  volumes:
    - name: test
      hostPath:
        path: /data/nginx
  containers:
    - name: nginx-prestop
      image: nginx:alpine
      imagePullPolicy: IfNotPresent
      volumeMounts:
        - name: test
          mountPath: /usr/share/nginx/html/
      lifecycle:
        preStop:
          exec:
            command:
              - "/bin/sh"
              - "-c"
              - "echo bye > /usr/share/nginx/html/1.txt"
        postStart:
          exec:
            command:
              - "/bin/sh"
              - "-c"
              - "echo k8s prestop > /usr/share/nginx/html/index.html"

## 启动
[root@master-1 ~]# kubectl apply -f nginx-prestop.yml 

## 到pod对应节点查看
[root@master-1 ~]# kubectl get pod -o wide 
NAME                     READY   STATUS    RESTARTS   AGE   IP          NODE     NOMINATED NODE   READINESS GATES
nginx-prestop            1/1     Running   0          48s   10.2.1.22   node-1   <none>           <none>
[root@node-1 ~]# cat /data/nginx/index.html 
k8s prestop

## 停止
[root@master-1 ~]# kubectl delete -f nginx-prestop.yml 

## 对应节点查看
[root@node-1 ~]# ll /data/nginx/
total 8
-rw-r--r-- 1 root root  4 Sep 21 17:17 1.txt
-rw-r--r-- 1 root root 12 Sep 21 17:10 index.html
[root@node-1 ~]# cat /data/nginx/1.txt 
bye

健康检查探针

# 存活态探针(存活性探针):检测pod中容器的应用是否存活
exec:执行命令检测
httpGet:检测http
tcpSocket:检测端口

## exec
[root@master-1 ~]# vim exec.yml
apiVersion: v1
kind: Pod
metadata:
  name: liveness
  labels:
    name: liveness
spec:
  volumes:
    - name: test
      hostPath:
        path: /data/test
  containers:
    - name: liveness
      image: nginx:alpine
      imagePullPolicy: IfNotPresent
      volumeMounts:
        - name: test
          mountPath: /usr/share/nginx/html/
      lifecycle:
        postStart:
          exec:
            command:
              - "/bin/sh"
              - "-c"
              - "echo test liveness > /usr/share/nginx/html/index.html"
      livenessProbe:
        exec:
          command:
            - "/bin/sh"
            - "-c"
            - "cat /usr/share/nginx/html/index.html"
        initialDelaySeconds: 3
        periodSeconds: 1

## 启动
[root@master-1 ~]# kubectl apply -f exec.yml 
[root@master-1 ~]# kubectl get pod -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP          NODE     NOMINATED NODE   READINESS GATES
liveness                 1/1     Running   0          40s   10.2.1.24   node-1   <none>           <none>

## 检测

image-20230921174732271

## 使用httpGet的方式检测网站是否可以正常访问 相当于去get一个网站的信息
## httpGet里的path里写要get网站的uri port指定网站的端口
[root@master-1 ~]# vim httpget.yml
apiVersion: v1
kind: Pod
metadata:
  name: liveness
  labels:
    name: liveness
spec:
  volumes:
    - name: test
      hostPath:
        path: /data/test
  containers:
    - name: liveness
      image: nginx:alpine
      imagePullPolicy: IfNotPresent
      volumeMounts:
        - name: test
          mountPath: /usr/share/nginx/html/
      lifecycle:
        postStart:
          exec:
            command:
              - "/bin/sh"
              - "-c"
              - "echo test liveness > /usr/share/nginx/html/index.html"
      livenessProbe:
        httpGet:
          path: /
          port: 80
        initialDelaySeconds: 3
        periodSeconds: 1

## 使用tcpSocket方式的话 一般用于不用对外提供服务的应用 没有域名 直接指定IP 端口检测

# 就绪态探针(就绪性探针):检测pod内容器应用是否都准备就绪,如果没有准备就绪,就不对外提供服务(不开放流量)
exec:执行命令检测
httpGet:检测http
tcpSocket:检测端口
readinessProbe
initialDelaySeconds: 第一次执行探针需要在容器启动后等待的时候时间
periodSeconds: 容器启动后每隔多少秒执行一次存活探针
timeoutSeconds: 探针超时时间,默认1秒,最小1秒
successThreshold: 探针失败后最少连续探测成功多少次才被认定成功,默认1次,如果是
liveness必须为1
failureThreshold: 探针成功后被视为失败的探测的最小连续失败次数。默认3次。最小值为1