23、Kubernetes 背景任务处理与环境管理实践

Kubernetes 背景任务处理与环境管理实践

1. 动态队列任务调度

在 Kubernetes 中,我们可以通过 kubectl 命令来管理任务和 Pod。例如,查看任务和 Pod 的状态:

$ kubectl get job,pod 
NAME                COMPLETIONS   DURATION   AGE 
job.batch/addwork   1/1           22s        36s 
NAME                READY   STATUS      RESTARTS   AGE 
pod/addwork-l9fgg   0/1     Completed   0          37s 
pod/redis-0         1/1     Running     0          19h 
pod/redis-1         1/1     Running     0          19h 
pod/redis-2         1/1     Running     0          19h 

addwork 任务显示为 “Completed” 时,我们可以继续调度 Job 队列:

$ kubectl create -f 10.2.4_JobWorker 
job.batch/jobworker created 

再次查看任务和 Pod 的状态:

$ kubectl get job,pod 
NAME                  COMPLETIONS   DURATION   AGE 
job.batch/addwork     1/1           22s        3m45s 
job.batch/jobworker   0/1 of 2      2m16s      2m16s 
NAME                  READY   STATUS      RESTARTS   AGE 
pod/addwork-l9fgg     0/1     Completed   0          3m45s 
pod/jobworker-swb6k   1/1     Running     0          2m16s 
pod/jobworker-tn6cd   1/1     Running     0          2m16s 
pod/redis-0           1/1     Running     0          19h 
pod/redis-1           1/1     Running     0          19h 
pod/redis-2           1/1     Running     0          19h 

当队列清空后,工作节点会再处理一个任务然后退出。我们可以通过以下命令监控 Redis 队列的深度:

$ kubectl exec -it pod/redis-0 -- redis-cli llen queue:task 
(integer) 0 

当队列长度为 0 时,Pod 会在完成当前任务后进入 “Completed” 状态。

2. 静态队列任务处理

除了使用 Redis 这样的动态队列,Kubernetes 还支持使用静态队列来运行任务。静态队列的长度在任务开始前就已知,并且作为 Job 配置的一部分。以下是几种实现静态队列的方法:
- 使用索引的静态队列 :适用于提前知道任务数量且任务列表易于索引的场景,例如渲染电影帧。Kubernetes 会按照指定的完成次数运行 Job,并为每个任务创建一个 Pod,同时通过环境变量 $JOB_COMPLETION_INDEX 提供索引。示例配置如下:

apiVersion: batch/v1 
kind: Job 
metadata: 
  name: echo 
spec: 
  completions: 5 #A 
  parallelism: 3 #B 
  completionMode: Indexed #C 
  template: 
    spec: 
      restartPolicy: Never 
      containers: 
      - name: 'worker' 
        image: 'docker.io/library/busybox' 
        command: ["echo", "render frame: $JOB_COMPLETION_INDEX"] 
#A the number of times to run the job (upper bound of the index) 
#B number of worker pods to run in parallel 
#C Run in indexed mode, passing in JOB_COMPLETION_INDEX 
3. 背景任务的存活探针

对于执行任务的容器,无论是在 Deployment 还是 Job 中,都应该配置存活探针。存活探针可以帮助我们检测由于外部依赖失败导致的进程挂起问题。与 HTTP 服务不同,批处理工作负载通常没有可用于存活检测的端点或端口,因此可以使用命令来进行存活检测。

以下是一个 Ruby 示例,用于将当前 Unix 时间戳写入文件:

def self.log_process_date 
  fileName = "process.date" 
  aFile = File.new(::Rails.root.to_s + "/log/" + fileName, "w") 
  contents = Time.now.to_i.to_s 
  aFile.write(contents) 
  aFile.close 
end 

在正常运行时, log_process_date 方法会被频繁调用。我们可以使用以下 Bash 脚本来检查时间戳文件的时效性:

#!/bin/bash 
# Liveness probe for batch process 
# The process writes a logfile every time it runs with the current Unix timestamp. 
# Usage: process_liveness.sh <path_to_file> 
# The file must contain only the latest date as a Unix timestamp and no newlines 
if ! rundate=$(<$1); then #A 
  echo >&2 failed #A 
  echo "no logfile" #A 
  exit 1 #A  
fi #A 
curdate=$(date +'%s') #B 
diff=$((curdate-rundate)) #C 
if [ $diff -gt 300 ] #D 
then #D 
  echo "too old" #D 
  exit 100 #D 
fi #D 
exit 0 #E 
#A Read the timestamp file from the input (parameter $1), and exit with an error if it doesn't exist 
#B Get the current timestamp from the system 
#C Compare the two timestamp 
#D Return an error status code if the process timestamp is older than 300 seconds 
#E Return a success status code 

最后,我们可以在部署文件中配置存活探针来调用这个脚本:

livenessProbe: 
  initialDelaySeconds: 600 #A 
  periodSeconds: 30 
  exec: #B 
    command: ["./script/process_liveness.sh", "log/process.date"] #B 
  successThreshold: 1 
  timeoutSeconds: 1 
#A The initial delay is long, as we need time for the app to boot and write the first timestamp 
#B The command to run 
4. 生产和预发布环境管理

在将应用部署到生产环境之前,通常需要创建一个预发布环境来测试更改。Kubernetes 的命名空间功能可以帮助我们轻松实现这一点。

以下是创建和管理命名空间的步骤:
1. 创建命名空间

kubectl create namespace staging 
  1. 切换到命名空间
kubectl config set-context --current --namespace=staging 

也可以使用 kubectx kubens 工具来简化操作:

# List namespaces 
kubens  
# Switch to the staging namespace 
kubens staging 
  1. 部署应用到命名空间
kubectl apply -f . 

当在集群中进行了一些命令式的更改后,我们可以使用以下命令导出配置:

# View the deployment as YAML 
kubectl get deploy your-deployment -o yaml 
# Pipe the deployment YAML config to a file 
kubectl get deploy your-deployment -o yaml > your-deployment.yaml 
5. 总结

Kubernetes 提供了多种处理背景队列和批处理作业的方法:
- Deployments :可用于构建持续运行的作业队列,使用 Redis 等队列数据结构进行协调。
- Jobs :适用于一次性任务,如手动维护任务。
- CronJobs :可用于定时调度作业,如每日清理任务。
- 静态队列 :可以避免使用队列数据结构,通过配置直接调度任务。
- 存活检查 :对于处理背景任务的 Pod 仍然很重要,可以使用 exec 存活检查来检测挂起的进程。

通过使用命名空间和配置文件,我们可以轻松复制多个环境,并且将 Kubernetes 部署配置视为源代码进行管理,从而提高开发和运维的效率。以下是一个简单的流程图,展示了任务处理的基本流程:

graph LR
    A[开始] --> B[调度任务]
    B --> C{任务是否完成}
    C -- 是 --> D[监控队列深度]
    D -- 队列空 --> E[处理最后一个任务]
    E --> F[任务完成]
    C -- 否 --> B

表格展示不同队列处理方式的优缺点:
| 队列处理方式 | 优点 | 缺点 |
| — | — | — |
| 动态队列(如 Redis) | 灵活,可实时调整任务 | 需要额外的队列管理 |
| 索引静态队列 | 适用于可索引任务,配置简单 | 处于 Beta 阶段,可能有变动 |
| 消息队列服务静态队列 | 容器无需感知队列 | 需要额外的消息队列服务 |
| 脚本静态队列 | 实现简单 | 管理繁琐 |

Kubernetes 背景任务处理与环境管理实践

6. GitOps 理念与配置管理

在 Kubernetes 中,我们大量使用 YAML 配置文件来与对象进行交互。将配置视为代码有诸多好处,不仅能方便地创建多个相同配置的环境,还能在应用部署到生产环境时,像管理代码一样管理配置。

6.1 利用命名空间复制环境

Kubernetes 的命名空间功能可帮助我们轻松创建生产和预发布环境。命名空间提供了名称唯一性,避免了在不同环境中对配置进行大量修改。

创建和使用命名空间的步骤如下:
1. 创建命名空间

kubectl create namespace staging
  1. 切换到命名空间
kubectl config set-context --current --namespace=staging

也可以使用 kubectx kubens 工具简化操作:

# 列出命名空间
kubens
# 切换到预发布命名空间
kubens staging
  1. 部署应用到命名空间
kubectl apply -f .

通过上述步骤,我们可以轻松在不同命名空间中部署相同的应用,并且可以通过修改配置文件来调整不同环境的参数,如副本数量、外部服务凭证等。

6.2 以代码方式管理配置的好处

将 Kubernetes 部署配置视为源代码,我们可以利用 Git 的版本控制功能来管理配置的变更。通过 Git 的拉取请求(Merge Request),可以实现对配置变更的审查和自动化部署。

例如,开发人员在分支上修改配置文件,提交拉取请求后,经过团队成员的审查,确认无误后合并到主分支,然后触发自动化部署流程。这样可以确保配置的变更经过严格的审查,减少错误的发生。

7. 处理敏感信息

在配置文件中,我们可能会包含一些敏感信息,如数据库密码、API 密钥等。为了避免将这些信息以明文形式存储在版本控制中,我们可以采用以下方法:
- 使用 Kubernetes Secret :Kubernetes 提供了 Secret 对象,用于存储敏感信息。我们可以将敏感信息加密存储在 Secret 中,然后在配置文件中引用这些 Secret。

# 创建 Secret
kubectl create secret generic my-secret --from-literal=password=my-password
# 在配置文件中引用 Secret
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-container
    image: my-image
    env:
    - name: PASSWORD
      valueFrom:
        secretKeyRef:
          name: my-secret
          key: password
  • 使用外部密钥管理系统 :如 HashiCorp Vault、AWS Secrets Manager 等,这些系统可以安全地存储和管理敏感信息,并提供 API 供 Kubernetes 访问。
8. 总结与展望

Kubernetes 在处理背景队列和批处理作业方面提供了丰富的功能,通过 Deployments、Jobs、CronJobs 等对象,以及动态和静态队列的处理方式,满足了不同场景的需求。同时,命名空间和配置文件的使用,使得环境的复制和管理变得更加简单。

在未来的开发和运维中,我们可以进一步结合 GitOps 理念,将配置管理与 CI/CD 流程集成,实现自动化的部署和更新。同时,合理使用存活探针和敏感信息管理方法,提高应用的稳定性和安全性。以下是一个流程图,展示了 GitOps 流程:

graph LR
    A[开发人员修改配置] --> B[提交拉取请求]
    B --> C{审查通过?}
    C -- 是 --> D[合并到主分支]
    D --> E[触发自动化部署]
    E --> F[部署到目标环境]
    C -- 否 --> A

表格展示不同配置管理方式的特点:
| 配置管理方式 | 特点 |
| — | — |
| 命令式操作 | 简单直接,适合临时操作 |
| 声明式配置 | 可重复使用,便于版本控制 |
| GitOps | 自动化部署,严格审查变更 |

通过合理运用这些技术和方法,我们可以更好地管理 Kubernetes 集群,提高开发和运维效率,确保应用的稳定运行。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值