如何用Go创建一个 deployment 到容器拉起来的全流程

article/2025/8/29 19:17:41

整体流程概述:

  1. 认证与配置: 连接到Kubernetes集群。
  2. 创建Deployment对象: 构建一个appsv1.Deployment结构体,定义Pod的模板、副本数量、选择器等。
  3. 发送创建请求: 使用Kubernetes Go客户端库将Deployment对象发送到API服务器。
  4. 监控Deployment状态: 持续检查Deployment的状态,直到它达到预期的副本数量并且所有Pod都已准备就绪。

详细步骤与Go语言代码示例:

首先,您需要导入必要的Kubernetes Go客户端库:

package mainimport ("context""fmt""time"appsv1 "k8s.io/api/apps/v1"apiv1 "k8s.io/api/core/v1"metav1 "k8s.io/apimachinery/pkg/apis/meta/v1""k8s.io/client-go/kubernetes""k8s.io/client-go/tools/clientcmd"
)

1. 认证与配置

Go客户端库可以通过多种方式连接到Kubernetes集群:

  • 集群内(In-cluster): 如果您的Go应用程序运行在Kubernetes集群内部的Pod中,它会自动使用Service Account凭证。
  • 集群外(Out-of-cluster): 如果您的Go应用程序运行在集群外部(例如本地开发环境),它通常会使用kubeconfig文件。

以下示例展示了如何使用kubeconfig文件进行配置:

func getKubeConfig() (*kubernetes.Clientset, error) {// 尝试从默认路径或KUBECONFIG环境变量加载kubeconfig// 您也可以指定一个具体的kubeconfig文件路径kubeconfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(clientcmd.NewDefaultClientConfigLoadingRules(),&clientcmd.ConfigOverrides{},)config, err := kubeconfig.ClientConfig()if err != nil {return nil, fmt.Errorf("加载kubeconfig失败: %w", err)}clientset, err := kubernetes.NewForConfig(config)if err != nil {return nil, fmt.Errorf("创建Kubernetes客户端失败: %w", err)}return clientset, nil
}

2. 创建Deployment对象

这是一个Go语言结构体,定义了Deployment的各种属性,包括Pod的模板、副本数量等。

func createDeploymentObject(namespace, deploymentName, imageName string, replicas int32) *appsv1.Deployment {labels := map[string]string{"app": "my-app",}return &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name:      deploymentName,Namespace: namespace,},Spec: appsv1.DeploymentSpec{Replicas: &replicas, // 副本数量Selector: &metav1.LabelSelector{MatchLabels: labels,},Template: apiv1.PodTemplateSpec{ObjectMeta: metav1.ObjectMeta{Labels: labels,},Spec: apiv1.PodSpec{Containers: []apiv1.Container{{Name:  "my-container",Image: imageName,Ports: []apiv1.ContainerPort{{ContainerPort: 80,},},},},},},},}
}

3. 发送创建请求

使用clientset.AppsV1().Deployments(namespace).Create()方法向Kubernetes API服务器发送创建Deployment的请求。

func createDeployment(clientset *kubernetes.Clientset, deployment *appsv1.Deployment) (*appsv1.Deployment, error) {fmt.Printf("尝试创建Deployment: %s\n", deployment.Name)ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) // 设置超时defer cancel()result, err := clientset.AppsV1().Deployments(deployment.Namespace).Create(ctx, deployment, metav1.CreateOptions{})if err != nil {return nil, fmt.Errorf("创建Deployment失败: %w", err)}fmt.Printf("Deployment %s 创建成功\n", result.Name)return result, nil
}

4. 监控Deployment状态

创建Deployment后,Kubernetes Controller Manager会负责创建Pod并确保它们运行起来。我们需要监控Deployment的状态,直到所有预期的Pod都已启动并准备就绪。

func waitForDeploymentReady(clientset *kubernetes.Clientset, namespace, deploymentName string, desiredReplicas int32, timeout time.Duration) error {fmt.Printf("等待Deployment %s 准备就绪...\n", deploymentName)ctx, cancel := context.WithTimeout(context.Background(), timeout)defer cancel()ticker := time.NewTicker(5 * time.Second) // 每5秒检查一次defer ticker.Stop()for {select {case <-ctx.Done():return fmt.Errorf("等待Deployment %s 超时", deploymentName)case <-ticker.C:deployment, err := clientset.AppsV1().Deployments(namespace).Get(ctx, deploymentName, metav1.GetOptions{})if err != nil {return fmt.Errorf("获取Deployment %s 状态失败: %w", deploymentName, err)}// 检查ReadyReplicas是否达到预期if deployment.Status.ReadyReplicas == desiredReplicas &&deployment.Status.AvailableReplicas == desiredReplicas &&deployment.Status.UpdatedReplicas == desiredReplicas {fmt.Printf("Deployment %s 准备就绪!(副本数: %d)\n", deploymentName, desiredReplicas)return nil}fmt.Printf("Deployment %s 状态: ReadyReplicas=%d, AvailableReplicas=%d, UpdatedReplicas=%d (预期: %d)\n",deploymentName,deployment.Status.ReadyReplicas,deployment.Status.AvailableReplicas,deployment.Status.UpdatedReplicas,desiredReplicas,)}}
}

主函数示例:

func main() {clientset, err := getKubeConfig()if err != nil {fmt.Printf("获取Kubernetes客户端失败: %v\n", err)return}namespace := "default" // 或者您想部署到的命名空间deploymentName := "go-app-deployment"imageName := "nginx:latest" // 您要部署的镜像replicas := int32(3)        // 期望的副本数量// 1. 定义Deploymentdeployment := createDeploymentObject(namespace, deploymentName, imageName, replicas)// 2. 创建Deployment_, err = createDeployment(clientset, deployment)if err != nil {fmt.Printf("创建Deployment失败: %v\n", err)return}// 3. 等待Deployment就绪err = waitForDeploymentReady(clientset, namespace, deploymentName, replicas, 5*time.Minute) // 最多等待5分钟if err != nil {fmt.Printf("等待Deployment就绪失败: %v\n", err)return}fmt.Println("Deployment 和容器已成功启动并准备就绪。")// 可选:获取Pod信息pods, err := clientset.CoreV1().Pods(namespace).List(context.TODO(), metav1.ListOptions{LabelSelector: "app=my-app", // 使用Deployment的标签选择器来过滤Pod})if err != nil {fmt.Printf("获取Pod列表失败: %v\n", err)} else {fmt.Println("相关Pod列表:")for _, pod := range pods.Items {fmt.Printf("  - Pod Name: %s, Status: %s\n", pod.Name, pod.Status.Phase)}}// 可选:清理资源 (如果不需要,可以注释掉)// fmt.Printf("尝试删除Deployment %s...\n", deploymentName)// deletePolicy := metav1.DeletePropagationForeground// if err := clientset.AppsV1().Deployments(namespace).Delete(context.TODO(), deploymentName, metav1.DeleteOptions{// 	PropagationPolicy: &deletePolicy,// }); err != nil {// 	fmt.Printf("删除Deployment失败: %v\n", err)// } else {// 	fmt.Printf("Deployment %s 已成功删除。\n", deploymentName)// }
}

运行此代码的步骤:

  1. 安装Go语言: 确保您的系统上安装了Go。
  2. 安装Kubernetes客户端库:
    go get k8s.io/client-go@latest
    
  3. 配置kubeconfig: 确保您的~/.kube/config文件配置正确,并且有权访问您的Kubernetes集群。
  4. 保存代码: 将上述Go代码保存为 .go 文件(例如 deploy_app.go)。
  5. 运行:
    go run deploy_app.go
    

运行结果
在这里插入图片描述

解释流程中涉及的Kubernetes概念:

  • Deployment (部署): Kubernetes中最常用的控制器,用于声明式地管理Pod的副本。它确保指定数量的Pod始终运行,并支持滚动更新和回滚。
  • Pod (容器组): Kubernetes中最小的可部署单元,包含一个或多个紧密耦合的容器。
  • ReplicaSet (副本集): Deployment在底层会创建和管理ReplicaSet。ReplicaSet确保特定数量的Pod副本始终运行。
  • Container (容器): 在Pod中运行的应用程序进程。
  • Image (镜像): 容器运行所需的文件系统和应用程序代码的打包。
  • Namespace (命名空间): 用于将集群资源划分为逻辑组,避免命名冲突并提供资源隔离。
  • Labels (标签): 键值对,用于标识Kubernetes对象。它们对于选择器(如Deployment的选择器)至关重要。
  • Selector (选择器): 用于查找和管理具有特定标签的Kubernetes对象。Deployment使用选择器来识别它应该管理的Pod。
  • Kubernetes API Server: Kubernetes集群的控制平面,所有操作都通过它进行。
  • Controller Manager: 运行各种控制器(包括Deployment控制器)的组件,这些控制器会持续观察集群的期望状态和实际状态,并采取行动使它们一致。

容器拉取过程(在K8s集群内部发生):

当您创建Deployment后,Kubernetes Controller Manager会执行以下步骤以拉起容器:

  1. Deployment控制器创建ReplicaSet: Deployment控制器会根据Deployment的spec.replicasspec.selector创建一个或多个ReplicaSet。
  2. ReplicaSet控制器创建Pod: ReplicaSet控制器根据Deployment的spec.template创建Pod。这些Pod会被标记为由该ReplicaSet管理。
  3. 调度器(Scheduler)选择节点: Kubernetes调度器会监听到新的Pod被创建,并根据资源需求(CPU、内存)、节点亲和性/反亲和性、Taints/Tolerations等策略,选择一个最合适的节点来运行这个Pod。
  4. Kubelet在节点上创建Pod: 被调度到节点的Kubelet会接收到Pod的创建请求。
  5. 容器运行时(Container Runtime)拉取镜像: Kubelet会指示节点上的容器运行时(例如Docker、containerd)从配置的镜像仓库(如Docker Hub、私有仓库)拉取指定的容器镜像。
  6. 容器运行时启动容器: 镜像拉取完成后,容器运行时会根据Pod的定义启动容器。
  7. 容器启动和健康检查:
    • 容器内的进程开始运行。
    • 如果Pod定义了livenessProbereadinessProbe,Kubelet会定期执行这些健康检查。
    • livenessProbe失败会导致容器重启。
    • readinessProbe失败会导致Pod的Service流量不再路由到该Pod,直到其准备就绪。
  8. Pod状态更新: Kubelet会向API Server报告Pod的当前状态(例如Pending -> Running -> Ready)。
  9. Deployment状态更新: Deployment控制器会持续监控其管理的ReplicaSet和Pod的状态。当足够数量的Pod达到"Ready"状态时,Deployment会被认为是"准备就绪"。

整个过程是异步的,Go程序通过轮询Deployment的状态来判断容器是否成功拉起并运行。


http://www.hkcw.cn/article/jxbbITMohR.shtml

相关文章

echarts主题切换实现

文章目录 一、实现方式1.实现思路2.指定主题3.设置图表背景透明 二、具体实现1.监听与销毁2修改主题色细节 参考链接 一、实现方式 场景: 首先是我的项目有不同主题色&#xff0c;切换主题时候想要将echarts的图表主题色也一并更改&#xff0c;暂时只设置’light’和’dark’…

如何在 Ubuntu 24.04 服务器上安装 Apache Solr

Apache Solr 是一个免费、开源的搜索平台&#xff0c;广泛应用于实时索引。其强大的可扩展性和容错能力使其在高流量互联网场景下表现优异。 Solr 基于 Java 开发&#xff0c;提供了分布式索引、复制、负载均衡及自动故障转移和恢复等功能。 本教程将指导您如何在 Ubuntu 24.…

从零开始的云计算生活——第十四天,困难重重,安全管理。

一故事背景 在前面的基本无操作内容后&#xff0c;来到了大头内容&#xff0c;安全管理&#xff01;其中的防火墙相关的内容更是重中之重&#xff0c;要好好掌握&#xff0c;熟练运用。 二SELinux安全上下文 1SELinux 简介 a. SELinux&#xff08;Security-Enhanced Linux&…

UDP编程

udp是无连接的&#xff0c;没有listen 与 accept。 bind 服务端一定需要bind&#xff0c;告知别人自己的ip和port。 客户端可以不bind&#xff0c;在发送数据时候可以随机分配&#xff0c;客户端推荐bind&#xff08;与tcp不同&#xff0c;udp本身无连接&#xff09;。 注意&am…

【计网】分片

MF DF MAC帧 MTU 首部数据载荷 片偏移是整数

记录一个梦,借助大语言模型图片生成

梦见家门口有一条大河&#xff0c;但大河和其它景物都是灰暗没有鲜艳色彩很普通的梦中场景。大河似乎是长江的支流&#xff0c;但也可能有一个响亮的名字似乎是金沙江。 突然看到一条金红色的龙在快速游动&#xff0c;不敢相信自己的眼睛&#xff0c;因为一直不相信有这种生物…

PostgreSQL查询一个表的数据

要从一个表中检索数据就是按要求查询表的信息&#xff0c;。SQL的SELECT语句可分为&#xff1a; 1.选择列表&#xff08;选择查询返回的列&#xff09; 2.表列表操作&#xff08;从中查询出的数据&#xff0c;进一步进行加减乘除-*/、筛选等操作&#xff09; 3.可选的条件 whe…

聊聊后端面试中的MySQL高频考题

如大家所了解的&#xff0c;SQL&#xff08; Structured Query Language &#xff09;是一门在开发者中使用覆盖率超50%的数据库结构化查询语言。 不可否认&#xff0c;无论是常年与数据打交道的数据分析师和数据科学家&#xff0c;经常需要管理和维护数据库的数据库管理员&am…

R3GAN利用配置好的Pytorch训练自己的数据集

简介 简介:这篇论文挑战了"GANs难以训练"的广泛观点,通过提出一个更稳定的损失函数和现代化的网络架构,构建了一个简洁而高效的GAN基线模型R3GAN。作者证明了通过合适的理论基础和架构设计,GANs可以稳定训练并达到优异性能。 论文题目:The GAN is dead; long l…

【python深度学习】Day 39 图像数据与显存

知识点 图像数据的格式&#xff1a;灰度和彩色数据模型的定义显存占用的4种地方 模型参数梯度参数优化器参数数据批量所占显存神经元输出中间状态 batchisize和训练的关系 作业&#xff1a;今日代码较少&#xff0c;理解内容即可 一、图像数据的介绍 结构化数据&#xff08;如表…

mongodb源码分析session接受客户端find命令过程

mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程&#xff0c;并且验证connection是否超过限制。 现在继续研究ASIOSession和connection是怎么接受客户端命令的&#xff1f; mongo/transport/service_state_machine.cpp核心方法有&#xf…

酒店管理破局:AI 引领智能化转型

一、酒店行业现状&#xff1a;规模扩张加速与效率瓶颈并存 根据中国五矿证券《中国酒店行业格局分析》报告&#xff0c;国内酒店行业呈现头部集中化趋势。截至2024年第三季度&#xff0c;锦江酒店以13,186家门店、125.8万间客房的规模稳居行业第一[1]。华住集团则以178.68亿元…

大模型深度学习之双塔模型

前言 双塔模型&#xff08;Two-Tower Model&#xff09;是一种在推荐系统、信息检索和自然语言处理等领域广泛应用的深度学习架构。其核心思想是通过两个独立的神经网络&#xff08;用户塔和物品塔&#xff09;分别处理用户和物品的特征&#xff0c;并在共享的语义空间中通过相…

【Java Web】速通CSS

参考笔记:JavaWeb 速通CSS_java css-CSDN博客 目录 一、CSS入门 1. 基本介绍 2. 作用 二、CSS的3种引入方式 1. 行内式 1.1 示例代码 1.2 存在问题 2. 写在head标签的style子标签中 2.1 示例代码 2.2 存在问题 3.以外部文件的形式引入(开发中推荐使用)⭐⭐⭐ 3.1 说明 3…

PostgreSQL安装

我们使用开源的对象关系型数据库--PostgreSQL&#xff0c;它具有高性能、可扩展和支持复杂查询的特性&#xff0c;非常适合现在学习使用。 一.安装PostgreSQL 我用的windows&#xff0c;就在windows上安装。 1.首先访问 PostgreSQL 官方网站https://www.postgresql.org/dow…

C++:栈帧、命名空间、引用

一、前置知识 1.1、栈区&#xff08;Stack&#xff09; 1.1.1、内存分配与回收机制 分配方式​​&#xff1a;由编译器自动管理&#xff0c;通过调整栈指针&#xff08;ESP/RSP&#xff09;实现。 函数调用时&#xff0c;栈指针下移&#xff08;栈从高地址向低地址增长&…

【HarmonyOS 5】鸿蒙应用px,vp,fp概念详解

【HarmonyOS 5】鸿蒙应用px&#xff0c;vp&#xff0c;fp概念详解 一、前言 目前的鸿蒙开发者&#xff0c;大多数是从前端或者传统移动端开发方向&#xff0c;转到鸿蒙应用开发方向。 前端开发同学对于开发范式很熟悉&#xff0c;但是对于工作流程和开发方式是会有不适感&am…

[Rust_1] 环境配置 | vs golang | 程序运行 | 包管理

目录 Rust 环境安装 GoLang和Rust 关于Go 关于Rust Rust vs. Go&#xff0c;优缺点 GoLang的优点 GoLang的缺点 Rust的优点 Rust的缺点 数据告诉我们什么&#xff1f; Rust和Go的主要区别 (1) 性能 (2) 并发性 (3) 内存安全性 (4) 开发速度 (5) 开发者体验 Ru…

Codeforces Round 1024 (Div. 2)

Problem - A - Codeforces 思维题&#xff1a; 如果n不能整除p&#xff0c;就会多出一部分&#xff0c;这个部分可以作为调和者&#xff0c;使整个数组符合要求。 如果n能整除p&#xff0c;没有调和空间&#xff0c;只有看n/p*qm 来看代码&#xff1a; #include <bits/s…

【东枫科技】KrakenSDR 天线阵列设置

标准测向需要五根相同的全向天线。您可以折衷使用更少的天线&#xff0c;但为了获得最佳性能&#xff0c;我们建议使用全部五根天线。这些天线通常是磁铁安装的鞭状天线&#xff0c;或偶极子天线。我们建议始终使用均匀圆形阵列 (UCA) 天线&#xff0c;因为它可以确定来自各个方…