Kubernetes4

生命周期与资源管理

#### 一、Pod生命周期

##### 生命周期

​    表示Pod对象从创建直至终止的时间范围,这段范围用于运行复杂的逻辑如启动顺序、依赖关系、生成配置、数据预加载、检测、安装等

初始化容器:initContainer

容器探针:
    生命探测:livenessProbe
    就绪探测:readinessProbe
    启动探测:startupProbe

事件处理函数:
    启动后回调:PostStart
    结束前回调:PreStop

![image-20250331095334619](image-20250331095334619.png)

```yaml
# 测试初始化容器
---
kind: Pod
apiVersion: v1
metadata:
  name: apache
spec:
  restartPolicy: OnFailure        # Always选项对初始化容器无效
  initContainers:                # never失败不重启,会导致主容器永远不启动
  - name: inithttp1                # 初始化任务失败,主容器不会启动
    image: myos:8.5
    command: [sh]
    args:
    - -c
    - |
      ID=${RANDOM}
      echo "${RANDOM}"
      sleep 3
      exit $((ID%2))
  - name: inithttp2                # 可以定义多个初始化容器
    image: myos:latest            # 初始化容器可以使用不容镜像
    command: [sh]
    args:
    - -c
    - |
      ID=${RANDOM}
      echo "${RANDOM}"
      sleep 3
      exit $((ID%2))            # 状态非零表示失败,会重新执行初始化
  containers:
  - name: http
    image: myos:httpd
```

```shell
# 验证初始化容器执行
kubectl replace --force -f web1.yaml
# 查看细节
kubectl get pods -w
kubectl logs apache -c inithttp1
kubectl logs apache -c inithttp2

# 验证主容器重启,初始化容器不执行
kubectl exec -it http -- bash
```

##### 容器探针

###### 启动探针

启动探针在主容器中运行,不同于初始化必须在一个独立的容器中运行。若容器启动失败探针通知Pod重启容器。用于保护启动慢的容器,比如java需要先编译后运行

```yaml
---
kind: Pod
apiVersion: v1
metadata:
  name: apache
spec:
  containers:
  - name: http
    image: myos:httpd
    startupProbe:                 # 启动探针
      initialDelaySeconds: 30     # 首次检查延时
      failureThreshold: 3         # 可失败的次数
      periodSeconds: 10           # 检查间隔
      tcpSocket:                  # 使用 tcp 协议检测
        port: 80                  # 端口号
```

```shell
# 查看测试容器状态
kubectl apply -f web2.yaml 
kubectl get pods -w
# 查看帮助,获取字段说明
kubectl get pods apache -o jsonpath='{.spec.containers[*].startupProbe}' | python3 -m json.tool
```

###### 生命探针

默认探测器只会检测pid为1的进程,而生命探针会探测容器中某个核心资源是否可用,“核心资源”通常指容器内**维持应用正常运行的关键依赖**,具体包括进程状态、文件存在、服务连通、内部依赖等等。

```yaml
---
kind: Pod
apiVersion: v1
metadata:
  name: apache
spec:
  containers:
  - name: http
    image: myos:httpd
    startupProbe:
      initialDelaySeconds: 30
      failureThreshold: 3
      periodSeconds: 10
      tcpSocket:
        port: 80
    livenessProbe:                # 定义存活探针
      timeoutSeconds: 3           # 服务影响超时
      httpGet:                    # 使用 HTTP 协议检测
        path: /info.php           # 请求的 URL 路径
        port: 80                  # 服务端口号
```

```shell
# 测试
kubectl apply -f web2.yaml
kubectl exec -it apache -- bash
在容器中包含index.html和info.php
# 测试删除静态资源index.html,容器不会重启
# 测试删除动态资源info.php,容器重启
```

###### 就绪探针

就绪探针用于确定容器是否已准备好**接收外部流量**,如果就绪探针失败,Kubernetes 会将该 Pod 从 Service 的 Endpoints 列表中移除,**停止向其发送流量**,但不同于生命探针的是就绪探针不会重建容器

```yaml
---
kind: Pod
apiVersion: v1
metadata:
  name: apache
spec:
  containers:
  - name: http
    image: myos:httpd
    startupProbe:
      initialDelaySeconds: 30
      failureThreshold: 3
      periodSeconds: 10
      tcpSocket:
        port: 80
    livenessProbe:
      timeoutSeconds: 3
      httpGet:
        path: /info.php
        port: 80
    readinessProbe:               # 定义就绪探针
      failureThreshold: 3         # 失败确认次数
      periodSeconds: 5            # 检测间隔
      exec:                       # 执行命令进行检测
        command:                  # 检测命令
        - sh
        - -c
        - |
          read ver < /var/www/html/version.txt
          if (( ${ver:-0} > 2 ));then
            res=0
          fi
          exit ${res:-1}          # 版本大于 2 成功,否则失败
```

```shell
# 测试
kubectl apply -f web2.yaml
kubectl exec -it apache -- bash
# 容器内测试成功结果
echo 3 > /var/www/html/version.txt
# 容器外测试状态
kubectl get pods -w
# 测试失败结果
echo 1 > /var/www/html/version.txt
# 容器外查看状态
kubectl get pods -w
```

##### 事件处理函数

###### 启动回调与结束回调

```yaml
---
kind: Pod
apiVersion: v1
metadata:
  name: apache
spec:
  containers:
  - name: web
    image: myos:httpd
    lifecycle:                    # 定义启动后事件处理函数
      postStart:
        exec:
          command:
          - sh
          - -c
          - |
            echo "start server" | tee -a /tmp/web.log
            sleep 10
      preStop:                    # 定义关闭前事件处理函数
        exec:
          command:
          - sh
          - -c
          - |
            echo "stop server" | tee -a /tmp/web.log
            sleep 10
```

```shell
# 测试返回结果
kubectl apply -f web3.yaml
# 进入容器查看日志结果
kubectl exec -it apache -- bash
cat /tmp/web.log
# 容器外结束容器
kubectl delete pods web3
# 在容器退出的宽限期内查看结果
cat /tmp/web.log
```

#### 二、资源的配额与限额

##### 资源配额

保护pod

```yaml
# 配额测试
---
kind: Pod
apiVersion: v1
metadata:
  name: apache
spec:
  containers:
  - name: web3
    image: myos:httpd
    resources:                  # 配置资源策略
      requests:                 # 配额策略
        cpu: 1500m              # 计算资源配额
        memory: 800Mi           # 内存资源配额
```

###### 验证资源配额

```shell
## 验证创建4个pods
for i in {1..4}
 do
  sed "s,apache,apache$i," application.yml | kubectl apply -f -
 done
# 查看pod状态,虽然4个pod都能创建成功但pod3与pods4处于pending状态
kubectl get pods
-------------------------------------------------------
# 占用CPU资源
curl http://10.244.1.10/info.php?id=5000000
# 占用内存资源
memtest.py 500
```

##### 资源限额

限制pod

```yaml
# 调整资源限额
---
kind: Pod
apiVersion: v1
metadata:
  name: apache
spec:
  containers:
  - name: web3
    image: myos:httpd
    resources:                  # 配置资源策略
      limits:                   # 限额策略
        cpu: 500m               # 计算资源限额
        memory: 800Mi           # 内存资源限额
```

###### 验证资源限额

```shell
## 验证限额,当前pod:cpu限额500m,内存限额800Mi
# 将文件传给容器并添加执行权限用于测试
kubectl cp memtest.py apache:/usr/bin/
chmod +x /usr/bin/memtest.py
# 验证多端同时申请占用内存资源测试限额度
memtest.py 500
# 两个端口总计需要占用1024Mi内存,超出总共提供800Mi,系统会随机杀死一个端口申请的进程

# 验证大量连续访问容器服务,占用cpu资源测试限额度
curl http://10.244.21.160/info.php?id=5000000 &
curl http://10.244.21.160/info.php?id=5000000 &
curl http://10.244.21.160/info.php?id=5000000 &
# 容器查看信息
kubectl top pods apache
-------------------------------------------------------
# 占用CPU资源
curl http://10.244.1.10/info.php?id=5000000
# 占用内存资源
memtest.py 500
```

#### 三、Pod 服务质量与Quota 资源管理的配额

##### 服务质量

为了防止资源饥饿,kubelet可以回收一个或多个pods的资源。在节点压力驱逐期间,kubelet会将Pod状态设置为Failed并终止其运行

三种QoS类别:
        Guaranteed类型:这类Pod有稳定的资源配额/限额,被当作驱逐目标的概率很小
                当资源配额**等于**资源限额时,Pod属于Cuaranteed类型
        Burstable类型:该类Pod使用资源在有限制的范围内波动,节点资源不足时会被驱逐
                当资源配额**小于**资源限额,则Pod属于Burstable类型
        BestEffort类型:没有明确的资源使用量,是首选被驱逐的对象
                当一个Pod没有设置资源配额和资源限额,属于BestEffort类型

```yaml
---
kind: Pod
apiVersion: v1
metadata:
  name: apache
spec:
  containers:
  - name: web3
    image: myos:httpd
# ↑BestEffort型--------------------------------------------------------
    resources:
      requests:
        cpu: 500m
        memory: 800Mi
# ↑Burstable型--------------------------------------------------------
      limits:
        cpu: 500m
        memory: 800Mi
# ↑Guaranteed型--------------------------------------------------------
```

###### 验证QoS

```shell
# 验证BestEffort型
vim application.yml
kubectl apply -f application.yml
kubectl describe pods apache | grep QoS
# 验证Burstable型
vim application.yml
kubectl replace --force -f application.yml
kubectl describe pods apache | grep QoS
# 验证Guaranteed型
vim application.yml
kubectl replace --force -f application.yml
kubectl describe pods apache | grep QoS
```

##### 设置全局资源配额

**全局资源配额(Resource Quota)**需要创建ResourceQuota对象,并绑定到特定的命名空间(Namespace)

资源单位格式:
    CPU:1 = 1核,500m = 0.5核
    内存:1G = 1000M,1Gi = 1024Mi

```shell
# 快速生成quota的1号测试模板
kubectl create quota my-quota-1 --namespace=testns --hard=pods=3 --scopes=BestEffort --dry-run=client -o yaml > quota.yml

# 参数说明
--hard: 指定资源限制(如 cpu=10,memory=20Gi,pods=100)
--dry-run=client: 仅生成模板,不实际创建
-o yaml: 输出YAML格式

# 创建名称空间以及更新配额策略quota
kubectl create namespace testns
kubectl apply -f quota.yml
# 查看当前quota状态
kubectl describe namespaces testns
# 使用BestEffort型,测试创建多个pods后查看配额信息
for i in {1..4}
 do
  sed 's,apache,apache$i,' application.yml | kubectl -n testns apply -f -            # 第4个创建失败,因为scopes只有3个限制
 done
kubectl describe namespaces testns
```

生成测试模板

```yaml
---
apiVersion: v1
kind: ResourceQuota                # 全局资源限额对象
metadata:
  creationTimestamp: null        # 记录资源的创建时间
  name: my-quota-1                # 规则名称
  namespace: testns                # 规则作用的名称空间
spec:                            # 定义ResourceQuota.spes
  hard:                            # 创建强制规则
    pods: "3"                    # 限制创建资源对象总量
  scopes:                        # 配置服务质量类型
  - BestEffort                    # Pod QoS类型
status: {}
```

##### 设置服务质量配额

通过资源与数量双重配额,限制手段更灵活

```shell
# 生成2号测试模板
kubectl create quota my-quota-2 \
--namespace=testns \
--hard=cpu=2300m,memory=1500M,pods=10 \
--scopes=NotBestEffort \
--dry-run=client -o yaml >> quota.yml

# 名称空间已存在不用创建,但要清空名称空间的测试pods以及重新更新配额策略quota
kubectl -n testns delete pods --all
kubectl replace --force -f quota.yml
# 查看当前quota状态
kubectl describe namespaces testns
# 使用Guaranteed型并且cpu和内存的开支只设置200,测试创建多个pods后查看配额信息
for i in {1..10}
 do
  sed 's,apache,apache'$i',' application.yml | kubectl -n testns apply -f -            # 第8个开始创建失败,因为内存只设置了1500M,7×200+200>1500
 done
kubectl describe namespaces testns
# 若把quota内存限制修改至2G将会从第11个开始创建失败,三重限制cpu、内存、数量都达到上限
```

生成测试模板

```yaml
---
apiVersion: v1
kind: ResourceQuota
metadata:
  creationTimestamp: null        # 记录资源的创建时间
  name: my-quota-2                # 创建名称不能使用下划线"_",无法创建会报错
  namespace: testns
spec:
  hard:
    cpu: 2300m                    # 计算资源配额
    memory: 1500M                # 内存资源配额
    pods: "10"                    # 限制创建资源对象总量
  scopes:
  - NotBestEffort
status: {}
```

---------------------------

```shell
# 清理实验配置环境
kubectl -n testns delete pods --all
kubectl delete namespace testns
```

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值