在CSDN学Golang云原生(Kubernetes Pod)

一,pod的定义与基本用法

在 Kubernetes 中,Pod 是最小的可部署单元,它包含一个或多个容器。使用 Golang 来定义和操作 Pod 时,需要使用 kubernetes/client-go 包提供的 API。

以下是 Golang 定义和基本用法 Pod 的示例:

  1. 安装 kubernetes/client-go 包

在 Golang 环境中安装 kubernetes/client-go 包,该包提供了访问 Kubernetes API Server 的客户端库。

go get k8s.io/client-go/...
  1. 编写代码定义 Pod

下面是一个简单的示例代码片段,可以用来创建一个包含两个容器的 Pod:

package mainimport ("context""fmt"corev1 "k8s.io/api/core/v1"metav1 "k8s.io/apimachinery/pkg/apis/meta/v1""k8s.io/apimachinery/pkg/util/intstr""k8s.io/client-go/kubernetes""k8s.io/client-go/tools/clientcmd"
)func main() {config, err := clientcmd.BuildConfigFromFlags("", "/path/to/kubeconfig")if err != nil {panic(err.Error())}clientset, err := kubernetes.NewForConfig(config)if err != nil {panic(err.Error())}pod := &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name:      "example-pod",Namespace: "default",Labels: map[string]string{"app": "example-app",},},Spec: corev1.PodSpec{RestartPolicy: corev1.RestartPolicyOnFailure,Volumes: []corev1.Volume{{Name: "example-volume",VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{},},},},Containers: []corev1.Container{{Name:  "container-1",Image: "nginx",Ports: []corev1.ContainerPort{{Name:          "http",ContainerPort: 80,Protocol:      corev1.ProtocolTCP,},},},{Name:  "container-2",Image: "busybox",Command: []string{"sleep", "3600"},VolumeMounts: []corev1.VolumeMount{{Name:      "example-volume",MountPath: "/data",},},},},NodeSelector: map[string]string{"node-role.kubernetes.io/worker": "",},Tolerations: []corev1.Toleration{corev1.Toleration{Key: "key", Operator:"Equal", Value:"value"},},},}_, err = clientset.CoreV1().Pods("default").Create(context.Background(), pod, metav1.CreateOptions{})if err != nil {panic(err.Error())}fmt.Println("Pod created successfully")
}
  1. 运行代码创建 Pod

使用 Golang 运行上面的示例代码,它会在 Kubernetes 集群中创建一个名为 example-pod 的 Pod,其中包含两个容器:nginx 和 busybox。Nginx 容器将公开 TCP 端口 80,并且 busybox 容器将在 /data 目录中挂载一个名为 example-volume 的空目录。

运行示例代码的命令如下:

go run main.go

以上是 Golang 定义和基本用法 Pod 的示例,可以根据实际需求修改代码。

二,pod生命周期与重启策略

在 Kubernetes 中,Pod 是最小的可部署单元。它包含一个或多个容器,并且有自己的生命周期和重启策略。

Golang 可以通过 Kubernetes 提供的 API 来定义和操作 Pod 的生命周期和重启策略。以下是一些常见的 Pod 生命周期和重启策略:

  1. Pod 生命周期

Pod 的生命周期分为三个阶段:

  • Pending:Pod 已经被创建,但是尚未调度到任何节点上。
  • Running:Pod 已经被调度到某个节点上并且至少有一个容器正在运行。
  • Terminated:Pod 所有容器都已停止运行。
  1. 重启策略

Pod 的重启策略指定了当某个容器失败时 Kubernetes 应该采取哪种行动:

  • Always:无论什么原因导致容器停止运行,Kubernetes 都会自动重新启动该容器。这是默认的重启策略。
  • OnFailure:只有当容器以非正常退出状态(如错误码不为 0)终止时,Kubernetes 才会自动重新启动该容器。
  • Never:当某个容器停止运行时,Kubernetes 不会自动重新启动该容器。

以下是一个 Golang 示例代码片段,用于定义 Pod 的生命周期和重启策略:

package mainimport ("context""fmt"corev1 "k8s.io/api/core/v1"metav1 "k8s.io/apimachinery/pkg/apis/meta/v1""k8s.io/client-go/kubernetes""k8s.io/client-go/tools/clientcmd"
)func main() {config, err := clientcmd.BuildConfigFromFlags("", "/path/to/kubeconfig")if err != nil {panic(err.Error())}clientset, err := kubernetes.NewForConfig(config)if err != nil {panic(err.Error())}pod := &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name:      "example-pod",Namespace: "default",Labels: map[string]string{"app": "example-app",},},Spec: corev1.PodSpec{RestartPolicy: corev1.RestartPolicyOnFailure,Volumes: []corev1.Volume{corev1.Volume{Name: "example-volume",VolumeSource: corev1.VolumeSource{ConfigMap: &corev1.ConfigMapVolumeSource{LocalObjectReference: corev1.LocalObjectReference{Name:"configmap-name"},},},},},InitContainers: []corev1.Container{ // 定义 init container{Name:"init-container-01",Image:"busybox",Command:["sleep", "10"],},},Containers: []corev1.Container{ // 定义主容器corev1.Container{Name:  "container-01",Image: "nginx",Command:["nginx"],Args:["-g", "daemon off;"], corev1.Container{Name:  "container-02",Image: "busybox",Command:["sh", "-c"],Args:[`while true; do echo "$(date) Hello, World!"; sleep 10 ; done`],VolumeMounts: []corev1.VolumeMount{corev1.VolumeMount{Name:      "example-volume",MountPath: "/data",},},},},NodeSelector: map[string]string{"node-role.kubernetes.io/worker": "",},Tolerations: []corev1.Toleration{ // 添加容忍corev1.Toleration{Key:"key", Operator:"Equal", Value:"value"},},},}_, err = clientset.CoreV1().Pods("default").Create(context.Background(), pod, metav1.CreateOptions{})if err != nil {panic(err.Error())}fmt.Println("Pod created successfully")
}

在上面的示例中,我们使用了 RestartPolicy 字段来定义 Pod 的重启策略。我们还使用了 InitContainers 字段来定义 Pod 中的初始化容器。

通过这些示例代码片段,你可以更好地理解 Pod 生命周期和重启策略。

三,容器镜像拉取策略

在 Golang 中,我们可以使用 Kubernetes 提供的 API 来定义容器镜像拉取策略。以下是一些常见的容器镜像拉取策略:

  1. Always

无论本地是否存在该镜像,都会尝试拉取最新版本。如果本地已经有该镜像,则会被更新为最新版本。

container := corev1.Container{Name: "example-container",Image: "nginx",ImagePullPolicy: corev1.PullAlways,
}
  1. IfNotPresent

如果本地已经有该镜像,则直接使用本地版本;否则尝试从远程仓库拉取最新版本。

container := corev1.Container{Name: "example-container",Image: "nginx",ImagePullPolicy: corev1.PullIfNotPresent,
}
  1. Never

只使用本地已经存在的该镜像,不尝试从远程仓库拉取任何版本。

container := corev1.Container{Name: "example-container",Image: "nginx",ImagePullPolicy: corev1.PullNever,
}

需要注意的是,这些策略可能会影响到你的 Pod 的行为和性能。例如,如果你选择了 Always 策略,则每次启动 Pod 时都会去检查并下载最新的镜像,这可能会增加启动时间和网络带宽消耗。因此,在选择镜像拉取策略时,请根据实际情况进行权衡和选择。

另外,还可以在 Pod 或者 Deployment 等资源定义时指定默认的镜像拉取策略。例如:

pod := &corev1.Pod{// ...Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "example-container",Image: "nginx",// 可以覆盖全局配置中定义的策略ImagePullPolicy: corev1.PullIfNotPresent,},},// 指定默认的镜像拉取策略ImagePullSecrets: []corev1.LocalObjectReference{{Name:"myregistrykey"}},},
}

上面的代码片段中,我们通过 ImagePullSecrets 字段来指定使用哪个 Secret 对象来拉取镜像。这里我们使用了名为 myregistrykey 的本地 Secret 对象。

四,init Container

在 Kubernetes 中,一个 Pod 可以包含多个容器。其中,除了主要的业务容器之外,还可以定义一个或多个 Init Container(初始化容器),用于在业务容器启动之前完成一些必要的预处理工作。

使用 Init Container 有以下几个好处:

  1. 解耦应用逻辑和初始化逻辑,使应用更加清晰可维护。
  2. 避免竞态条件和资源争夺等问题,提高系统可靠性和稳定性。
  3. 灵活控制启动顺序和执行流程,满足不同场景下的需求。

对于 Golang 应用程序来说,在 Kubernetes 中使用 Init Container 的方法与其他语言类似。以下是一个简单的示例代码:

apiVersion: v1
kind: Pod
metadata:name: myapp-pod
spec:initContainers:- name: init-myserviceimage: busyboxcommand: ['sh', '-c', 'wget -O /work-dir/myservice https://myservice.com && chmod +x /work-dir/myservice']volumeMounts:- name: workdir-volumemountPath: /work-dircontainers:- name: myapp-containerimage: myapp:v1.0.0command: ['/myapp']volumeMounts:- name: workdir-volumemountPath: /work-dirvolumes:- name: workdir-volumeemptyDir: {}

上面的 YAML 文件定义了一个 Pod,其中包含一个 Init Container 和一个业务容器。Init Container 的作用是下载并安装 myservice 程序到共享目录 /work-dir 中,而业务容器则通过挂载该目录来使用 myservice 程序。

需要注意的是,Init Container 的执行顺序是按照它们在 YAML 文件中的顺序依次执行的。只有当所有 Init Container 成功完成后,才会启动业务容器。如果任何一个 Init Container 失败,则整个 Pod 也将被标记为失败,并重新启动。

另外,还可以在创建 Deployment 或 StatefulSet 时指定 Init Container。例如:

apiVersion: apps/v1
kind: Deployment
metadata:name: myapp-deployment
spec:replicas: 3template:metadata:labels:app: myappspec:initContainers:- name: init-myserviceimage: busyboxcommand: ['sh', '-c', 'wget -O /work-dir/myservice https://myservice.com && chmod +x /work-dir/myservice']volumeMounts:- name: workdir-volumemountPath: /work-dircontainers:- name: myapp-containerimage: myapp:v1.0.0command: ['/myapp']volumeMounts:- name: workdir-volumemountPath: /work-dirvolumes:- name: workdir-volumeemptyDir: {}

上面的代码片段中,我们在 template 字段中定义了 Init Container 和业务容器,然后通过 Deployment 控制器来创建和管理多个 Pod。

五,容器资源配额

在 Kubernetes 中,可以为 Pod 和容器定义资源配额(Resource Quota),以限制它们所能使用的 CPU、内存等资源数量。这对于避免应用程序过度占用资源、提高系统可靠性和稳定性非常有用。

在 Golang 应用程序中,可以通过设置环境变量或代码方式来定义容器资源配额。以下是示例代码:

apiVersion: v1
kind: Pod
metadata:name: myapp-pod
spec:containers:- name: myapp-containerimage: myapp:v1.0.0command: ['/myapp']env:- name: CPU_LIMITvalue: "500m"- name: MEMORY_LIMITvalue: "256Mi"

上面的 YAML 文件定义了一个 Pod,其中包含一个名为 myapp-container 的容器,并且设置了它的 CPU 和内存限制分别为 500m 和 256Mi。

在 Golang 应用程序中,可以通过读取环境变量获取这些值并进行相应处理。例如:

import ("os"
)func main() {cpuLimit := os.Getenv("CPU_LIMIT")memoryLimit := os.Getenv("MEMORY_LIMIT")// 使用 cpuLimit 和 memoryLimit 进行相应处理...
}

需要注意的是,Kubernetes 支持更多的资源配额类型和更细粒度的控制方式。例如,可以针对不同的命名空间、标签或用户组设置不同的配额规则。此外,还可以使用 Kubernetes 的自动扩缩容功能来根据资源使用情况动态调整 Pod 和容器的数量,以确保系统始终处于最佳状态。

六,容器声明周期处理函数

在 Golang 应用程序中,可以使用以下生命周期处理函数来处理容器的声明周期事件:

  • func init():在容器启动时执行。通常用于初始化应用程序的环境变量、配置等。
  • func main():在容器启动后立即执行。通常用于启动应用程序的服务或者监听端口。
  • func shutdown():在容器关闭之前执行。通常用于清理资源和状态,并停止正在运行的任务。

这些函数是可选的,您可以根据需要选择使用其中一个或多个。例如,如果您的应用程序不需要进行特殊初始化或清理操作,则无需编写 init 或 shutdown 函数。

以下是示例代码,展示如何使用生命周期处理函数:

package mainimport ("context""fmt""net/http""os""os/signal"
)func init() {fmt.Println("Initializing...")
}func main() {http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {w.Write([]byte("Hello World!"))})srv := &http.Server{Addr: ":8080"}go func() {if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {fmt.Printf("listen: %s\n", err)os.Exit(1)}}()fmt.Println("Started server at :8080")c := make(chan os.Signal, 1)signal.Notify(c, os.Interrupt)sig := <-cfmt.Println("Got signal:", sig)ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)defer cancel()srv.Shutdown(ctx)fmt.Println("Server stopped gracefully")
}func shutdown() {fmt.Println("Shutting down...")// 清理资源和状态
}

在上面的示例中,init 函数用于输出一个初始化消息。main 函数启动了一个 HTTP 服务器,并使用 signal.Notify() 监听 os.Interrupt 信号(即 Ctrl+C),以便在接收到该信号时优雅地关闭服务器。最后,当服务器关闭时,shutdown 函数被调用以清理资源。

需要注意的是,在 Kubernetes 中管理容器生命周期的方式有所不同。Kubernetes 使用一种称为控制器(Controller)的机制来管理容器和 Pod 的运行状态,并提供了相应的生命周期钩子函数来处理容器事件。

七,容器健康检查与服务可用性

在 Golang 应用程序中,可以使用以下方法来实现容器健康检查和服务可用性:

  1. HTTP 接口健康检查

HTTP 接口是最常见的容器健康检查方式之一。您可以在应用程序中添加一个简单的 /healthz 接口来提供健康状态信息。

示例代码如下:

package mainimport ("fmt""net/http"
)func main() {http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {w.WriteHeader(http.StatusOK)w.Write([]byte("OK"))})http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {w.Write([]byte("Hello World!"))})if err := http.ListenAndServe(":8080", nil); err != nil {fmt.Println(err)}
}

在上面的示例中,我们添加了一个 /healthz 接口来返回 200 OK 状态码和 "OK" 字符串表示应用程序正常运行。当 Kubernetes 发现该容器的该接口返回非 200 的 HTTP 状态码时,将会认为该容器不健康并重启该容器或者 Pod。

  1. TCP Socket 健康检查

除了 HTTP 接口外,还可以通过监听一个 TCP 端口来进行健康检查。这种方式要求 Kubernetes 配置 livenessProbe 和 readinessProbe 分别使用 TCP socket 进行探测。

示例代码如下:

package mainimport ("fmt""net"
)func main() {l, err := net.Listen("tcp", ":8080")if err != nil {fmt.Println(err)}defer l.Close()for {conn, err := l.Accept()if err != nil {fmt.Println(err)continue}go func(c net.Conn) {c.Write([]byte("OK\n"))c.Close()}(conn)}
}

在上面的示例中,我们监听 8080 端口并返回 "OK" 字符串表示容器健康。当 Kubernetes 发现该容器的 TCP Socket 不可用时,将会认为该容器不健康并重启该容器或者 Pod。

需要注意的是,在使用 TCP Socket 进行健康检查时,需要确保应用程序在启动后尽快开始监听端口,并且能够正确响应连接请求。否则 Kubernetes 将无法正常进行健康检查。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/13025.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Java】Spring框架是如何解决Bean创建过程中的循环依赖问题的

文章目录 【Java】Spring框架是如何解决Bean创建过程中的循环依赖问题的引言三级缓存数据结构简介源码阅读如何启动调试&#xff1f;场景1&#xff1a;通过xml配置文件来构造循环引用场景2&#xff1a;通过注解自动装配属性来构造循环引用&#xff1a;以Controller为例 脉络场景…

jdk8使用okhttp发送http2请求

本文主要用于工作记录&#xff0c;在项目中遇到了就记录一下 在早期&#xff0c;原生的JDK8是不支持HTTP/2协议的&#xff0c;所以&#xff0c;要想使用这个特性&#xff0c;需要有web服务器和应用环境的支持&#xff0c; 例如&#xff1a;在VM中增加-Xbootclasspath/p:/Users…

Android Studio 启用设备远程调试配置完整步聚

启用手机设置->开发者选项-无线调试,然后选择允许 已启用后无线调试变成绿色 ,点击无线调试进入详情页面 点击Android Studio的Device Manager 下的WIFI图标 会弹出下图窗口 打开手机的开发者选项中的WIFI调试(无线调试)下的使用二维码配对设备进行扫描. 设备配对成功后手机…

Unity Shader - if 和 keyword 的指令比较

文章目录 环境TestingIf4Sampleunity shaderlab 中的 TestingIf4Sample.shadergraphics analyzer 中的 TestingIf4Sample.glsl TestingKW4Sampleunity shaderlab 中的 TestingKW4Sample.shadergraphics analyzer 中的 TestingKW4Sample.glsl 比较 环境 Unity : 2020.3.37f1 Pi…

在Linux中用strsignal函数输出对各种信号的描述

2023年7月29日&#xff0c;周六上午 目录 函数原型Linux有多少种信号使用示例 函数原型 #include <string.h>char* strsignal(int signum);strsignal函数接受一个整数参数signum&#xff0c;表示信号的编号。 用于把信号编号转换成一个简短的对这个信号编号的描述。 L…

JAVA SE -- 第十一天

&#xff08;全部来自“韩顺平教育”&#xff09; 异常-Exception 一、异常介绍 1、基本介绍 Java语言中&#xff0c;将程序执行中发生的不正常情况为“异常”&#xff08;开发过程中的语法错误和逻辑错误不是异常&#xff09; 2、执行过程中发生的异常事件可分为两大类 …

FPGA2-采集OV5640乒乓缓存后经USB3.0发送到上位机显示

1.场景 基于特权A7系列开发板&#xff0c;采用OV5640摄像头实时采集图像数据&#xff0c;并将其经过USB3.0传输到上位机显示。这是验证数据流能力的很好的项目。其中&#xff0c;用到的软件版本&#xff0c;如下表所示&#xff0c;基本的硬件情况如下。该项目对应FPGA工程源码…

图注意力网络论文详解和PyTorch实现

图神经网络(gnn)是一类功能强大的神经网络&#xff0c;它对图结构数据进行操作。它们通过从节点的局部邻域聚合信息来学习节点表示(嵌入)。这个概念在图表示学习文献中被称为“消息传递”。 消息(嵌入)通过多个GNN层在图中的节点之间传递。每个节点聚合来自其邻居的消息以更新其…

MyBatis(二)

文章目录 一.MyBatis的模式开发1.1 定义数据表和实体类1.2 配置数据源和MyBatis1.3 编写Mapper接口和增加xxxMapper.xml1.4 测试我们功能的是否实现. 二. Mybatis的增删查改操作2.1 单表查询2.2 多表查询三.动态SQL的实现3.1 什么是动态SQL3.2 动态SQL的使用if标签的使用trim标…

M1/M2 通过VM Fusion安装Win11 ARM,解决联网和文件传输

前言 最近新入了Macmini M2&#xff0c;但是以前的老电脑的虚拟机运行不起来了。&#x1f605;&#xff0c;实际上用过K8S的时候&#xff0c;会发现部分镜像也跑不起来&#xff0c;X86的架构和ARM实际上还是有很多隐形兼容问题。所以只能重新安装ARM Win11&#xff0c;幸好微软…

Spring整合junit

1、导入pom坐标 <dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><dependency><groupId>org.springframework</gro…

【LeetCode】169.多数元素

题目 给定一个大小为 n 的数组 nums &#xff0c;返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的&#xff0c;并且给定的数组总是存在多数元素。 示例 1&#xff1a; 输入&#xff1a;nums [3,2,3] 输出&#xff1a;3…

【MySQL】表的操作

今天我们来谈谈MySQL下对表的操作 目录 一、创建表 二、查看表 2.1 查看库中存有的表 2.2 查看表结构 2.3 查看表的创建语句 三、修改表 3.1 重命名表名 3.2 新增列 3.3 修改列的数据类型 3.4 删除列 3.5 重命名列 四、删除表 一、创建表 我们要想在数据库中创建…

SpringMvc+阿贾克斯

0目录 1.SpringMVC 加阿贾克斯 2.分页版 1.实战 创建数据库 创建工程和pom依赖 配置web.xml和applicationContext.xml 实体类 Mapper接口方法 Mapper.xml BookService BookSeriviceImpl 控制层 测试 加入findAll.html 测试 2.分页版 控制层 PostMan测…

华为OD机试真题 Java 实现【AI面板识别】【2023 B卷 100分】,附详细解题思路

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明4、控制台输出 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08…

Redis旁路缓存,大KEY

Redis 旁路缓存 由于高并发原因&#xff0c;先更新数据库和先更新缓存策略都会因为延迟时间而导致数据不一致问题。 两种策略 先删除缓存&#xff0c;再更新数据库&#xff1b;先更新数据库&#xff0c;再删除缓存。 因为缓存的写入通常要远远快于数据库的写入&#xff0c;…

nginx 反向代理浅谈

前言 通常情况下&#xff0c;客户端向Web服务器发送请求&#xff0c;Web服务器响应请求并返回数据。而在反向代理中&#xff0c;客户端的请求不直接发送到Web服务器&#xff0c;而是发送到反向代理服务器。反向代理服务器会将请求转发给真实的Web服务器&#xff0c;Web服务器响…

MySQL - 报错问题解决

1、[HY000][1290] 错误信息"[HY000][1290] MySQL服务器使用了–secure-file-priv选项&#xff0c;因此无法执行此语句"表示MySQL服务器已配置启用了–secure-file-priv选项。此选项限制了LOAD DATA INFILE和SELECT INTO OUTFILE语句可以读取或写入文件系统的位置。默…

【C++】STL中stack,queue容器适配器的模拟实现(使用deque容器)

文章目录 前言一、deque的一些基本知识相比vector&#xff1a;相比list&#xff1a;3为什么选择deque作为stack和queue的底层默认容器 二、stack模拟实现三、queue的模拟实现 前言 STL标准库中stack和queue的底层结构 &#xff1a;虽然stack和queue中也可以存放元素&#xff0c…

java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法

文章目录 一、记录文件相关操作方法二、代码1.读取路径返回List\<File>2.读取路径返回List\<String>3.删除文件夹4.删除文件 一、记录文件相关操作方法 二、代码 1.读取路径返回List<File> import org.slf4j.LoggerFactory; import org.slf4j.Logger;impo…