在CSDN学Golang云原生(Kubernetes Pod无状态部署)

一,静态pod

Kubernetes中的Pod是可以动态创建、销毁的,如果希望Pod只使用静态的IP地址而不是自动生成一个IP地址,那么就需要使用静态Pod。

静态Pod是在kubelet启动时通过指定文件夹路径来加载的。当kubelet检测到这些配置文件变化后,它会创建或删除相应的Pod,这样就可以轻松地部署静态配置的Pod。

以下是一个示例静态pod配置文件:

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
    - name: nginx
      image: nginx:latest
      ports:
        - containerPort: 80

将上述内容保存为 nginx.yaml 文件并放置在指定目录下(如 /etc/kubernetes/manifests),然后重启kubelet服务即可部署该静态pod。

二,Deployment部署

在Kubernetes中,Deployment是用于部署应用程序的一种资源对象,它定义了一个可伸缩、自修复的应用程序副本集,并通过控制器对这些副本进行管理和协调。

以下是一个示例Deployment配置文件:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3   # 副本数为3个
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx-container
          image: nginx:latest   # 使用最新版nginx镜像
          ports:
            - containerPort: 80   # 对外暴露80端口

上述配置文件指定了名称为 nginx-deployment 的Deployment,要求有3个Pod副本。每个Pod都使用最新版本的 nginx 镜像,并将容器内部端口80映射到外部网络中。

创建Deployment可以使用kubectl命令行工具,如下所示:

kubectl apply -f deployment.yaml   # 根据deployment.yaml文件创建或更新Deployment对象

除了上述静态方式外,还可以通过Helm等工具来快速生成和管理复杂的Kubernetes资源对象。

三,Deployment 升级和回滚

在Kubernetes中,Deployment可以实现应用程序的无宕机升级和回滚操作。下面分别介绍如何进行升级和回滚操作:

  1. 升级Deployment

在更新镜像或修改配置等需求时,我们可以通过执行以下命令来更新Deployment:

kubectl set image deployment/nginx-deployment nginx-container=nginx:1.19   # 将容器镜像更新为1.19版本

该命令会自动触发Deployment的rolling update机制,逐步替换旧Pod副本为新副本。此时可以使用 kubectl rollout status 命令来查看升级进度。

  1. 回滚Deployment

如果出现了意外情况,需要将应用程序回滚到以前的版本,则可以执行以下命令:

kubectl rollout undo deployment/nginx-deployment   # 回滚到上一个版本

也可以指定特定的历史版本进行回滚:

kubectl rollout undo deployment/nginx-deployment --to-revision=3   # 回滚到第3个历史版本

此时,Kubernetes会自动将新Pod副本替换为旧版本,并且保证整个过程中不会有宕机时间(零停机)。

四,Deployment暂停与恢复

在Kubernetes中,Deployment提供了一种暂停和恢复Rollout的机制。当需要对应用程序进行升级或回滚操作时,可以使用该机制来控制Rollout过程的暂停和恢复。

  1. 暂停Rollout

执行以下命令可以暂停当前正在进行的Rollout:

kubectl rollout pause deployment/nginx-deployment   # 暂停nginx-deployment的rolling update

此时,新旧Pod副本都不会继续替换。如果想查看Deployment的状态,可以使用 kubectl rollout status 命令。

  1. 恢复Rollout

执行以下命令可以恢复之前被暂停的Rollout:

kubectl rollout resume deployment/nginx-deployment   # 恢复nginx-deployment的rolling update

此时,Kubernetes会自动将新Pod副本逐步替换为旧版本,并保证整个过程中不会有宕机时间(零停机)。

除了上述方法外,还可以通过修改Deployment的 .spec.paused 字段来实现暂停/恢复Rollout。例如:

  • 将Deployment暂停:
    kubectl patch deployment nginx-deployment -p '{"spec":{"paused":true}}'
  • 将Deployment恢复:
    kubectl patch deployment nginx-deployment -p '{"spec":{"paused":false}}'

以上两种方法等价于调用 kubectl rollout pause/resume 命令。

五,Deployment 手动与自动伸缩

在Kubernetes中,Deployment提供了自动伸缩和手动伸缩两种方式。

  1. 自动伸缩

Deployment可以通过 spec.replicas 字段控制Pod副本的数量,同时还可以使用Horizontal Pod Autoscaler (HPA)实现自动伸缩。HPA会根据CPU利用率等指标调整Pod副本的数量,以保证应用程序的可用性和稳定性。

例如,创建一个基于CPU利用率来自动扩展/收缩nginx-deployment的HPA:

kubectl autoscale deployment nginx-deployment --cpu-percent=80 --min=1 --max=10

该命令会创建一个名为 nginx-deployment 的Horizontal Pod Autoscaler对象,并设置CPU利用率达到80%时自动扩展Pod副本数量至最大值10个(如果当前Pod副本数小于1,则会自动创建一个新的Pod)。

  1. 手动伸缩

除了使用HPA进行自动伸缩外,还可以通过手动修改Deployment的 .spec.replicas 字段来进行手动伸缩。例如:

  • 将Pod副本数量增加到3:
    kubectl scale deployment nginx-deployment --replicas=3
  • 将Pod副本数量减少到1:
    kubectl scale deployment nginx-deployment --replicas=1

以上两种方法等价于直接修改Deployment YAML文件中的 .spec.replicas 字段。

需要注意的是,在使用手动伸缩时,应该保证Pod副本数量不会低于 .spec.minReadySeconds 字段所设置的最小可用时间(默认为0),以确保所有新创建的Pod都已经就绪并且能够接受流量。

六,DaemonSet 部署

DaemonSet 是 Kubernetes 中的一种资源类型,用于在每个节点上运行一个 Pod 副本。这里简单介绍下使用 kubectl 部署 golang DaemonSet 的步骤:

  1. 编写 DaemonSet 的 YAML 文件

    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
    name: example-golang-daemonset
    spec:
    selector:
    matchLabels:
    app: example-golang
    template:
    metadata:
    labels:
    app: example-golang
    spec:
    containers:
    - name: example-golang-container
    image: your_golang_image_name

  2. 使用 kubectl apply 命令部署 DaemonSet

    kubectl apply -f your_daemonset_yaml_file.yaml

  3. 查看 DaemonSet 是否部署成功

    kubectl get ds example-golang-daemonset

以上就是一个简单的 golang DaemonSet 部署的步骤,可以根据实际需求修改 YAML 文件中的配置信息。

七,Job 批处理

在Kubernetes中,Job是一种用于批处理作业的控制器。一个Job对象会创建一个或多个Pod副本实例来运行指定的容器镜像,并保证这些Pod副本实例能够成功完成任务。

以下是一个简单的golang Job批处理示例:

  1. 编写golang程序

编写一个简单的golang程序 main.go,例如:

package main

import (
	"fmt"
)

func main() {
	fmt.Println("Hello from Golang Job!")
}
  1. 创建Docker镜像并推送到仓库

使用Dockerfile将golang程序打包为Docker镜像,并将其推送到镜像仓库中,例如:

FROM golang:1.15-alpine AS build-env

RUN apk --no-cache add ca-certificates git && \
    mkdir /app

ADD . /app/
WORKDIR /app
RUN go build -o app .

FROM alpine:3.12
COPY --from=build-env /app/app /usr/local/bin/app
CMD ["app"]

执行以下命令构建并推送Docker镜像:

$ docker build -t your-repo/golang-job:v1 .
$ docker push your-repo/golang-job:v1
  1. 创建Job YAML文件

创建一个名为 golang-job.yaml 的YAML文件,用于定义Job对象:

apiVersion: batch/v1
kind: Job
metadata:
  name: golang-job
spec:
  template:
    spec:
      containers:
      - name: app-container
        image: your-repo/golang-job:v1
      restartPolicy: Never
  backoffLimit: 3

其中, backoffLimit 字段表示在任务失败时尝试重新运行的次数。

  1. 部署Job

执行以下命令创建并部署Job:

$ kubectl apply -f golang-job.yaml

该命令会在Kubernetes集群中创建一个名为 golang-job 的Job对象,并自动运行一个Pod副本实例。可以使用以下命令查看Job的状态:

$ kubectl get jobs.batch golang-job

NAME         COMPLETIONS   DURATION   AGE
golang-job   1/1           5s        18s

其中, COMPLETIONS 字段表示已经成功完成的任务数, DURATION 字段表示任务完成所用的时间。

  1. 查看日志

可以使用以下命令查看Pod的日志输出:

$ kubectl logs -l job-name=golang-job

Hello from Golang Job!

如果任务失败,则可以使用以下命令查看Pod的详细信息和错误日志:

$ kubectl describe pod -l job-name=golang-job

...
Events:
  Type     Reason            Age                From               Message
  ----     ------            ----               ----               -------
  Normal   Scheduled         <unknown>          default-scheduler  Successfully assigned default/golang-job-6pwlj to node-1.example.com
  Normal   SuccessfulCreate  <unknown>          kubelet, node-1    Created container app-container
  Normal   Started           <unknown>          kubelet, node-1    Started container app-container
  Warning  BackoffLimitExceeded  <unknown>       kubelet, node-1    Job has reached the specified backoff limit
...

如果 backoffLimit 字段设置得太小,可能会导致Job在失败后无法重新运行。因此,在实际使用中应该根据任务的复杂程度和容器镜像的稳定性等因素来调整该字段的值。

八,Crontab 定时任务

在Go语言中,我们可以使用第三方库 github.com/robfig/cron 来实现Crontab定时任务。

以下是一个简单的示例:

  1. 安装依赖

首先,需要安装 github.com/robfig/cron 库。可以执行以下命令安装:

$ go get github.com/robfig/cron
  1. 编写代码

创建一个名为 main.go 的文件,并编写以下代码:

package main

import (
	"fmt"
	"time"

	"github.com/robfig/cron"
)

func main() {
	c := cron.New()
	c.AddFunc("0 */5 * * * *", func() {
		fmt.Println("Run task at", time.Now().Format("2006-01-02 15:04:05"))
	})
	c.Start()

	select {}
}

该程序将每隔5分钟执行一次任务,输出当前时间。

  1. 运行程序

执行以下命令运行程序:

$ go run main.go
  1. 测试结果

等待5分钟后,可以看到程序输出如下内容:

Run task at 2022-08-16 10:00:00
Run task at 2022-08-16 10:05:00
Run task at 2022-08-16 10:10:00
...

这表明任务已经按照设定的时间间隔成功执行了。

注意:在生产环境中,应该将定时任务和其他业务逻辑分开部署,并加入健康检查等机制,以确保系统的稳定性和可靠性。

相关推荐
Ttang235 分钟前
Leetcode:118. 杨辉三角——Java数学法求解
算法·leetcode
喜欢打篮球的普通人5 分钟前
rust模式和匹配
java·算法·rust
java小吕布19 分钟前
Java中的排序算法:探索与比较
java·后端·算法·排序算法
杜若南星1 小时前
保研考研机试攻略(满分篇):第二章——满分之路上(1)
数据结构·c++·经验分享·笔记·考研·算法·贪心算法
路遇晚风1 小时前
力扣=Mysql-3322- 英超积分榜排名 III(中等)
mysql·算法·leetcode·职场和发展
Neophyte06081 小时前
C++算法练习-day40——617.合并二叉树
开发语言·c++·算法
木向1 小时前
leetcode104:二叉树的最大深度
算法·leetcode
一个不喜欢and不会代码的码农1 小时前
力扣113:路径总和II
算法·leetcode
向阳12181 小时前
LeetCode40:组合总和II
java·算法·leetcode