kubeadm构建k8s源码阅读环境

目标

前面看了minikube的源码了解到其本质是调用了kubeadm来启动k8s集群,并没有达到最初看代码的目的。 所以继续看看kubeadm的代码,看看能否用来方便地构建源码调试环境。

k8s源码编译

kubeadm源码在k8s源码库中,所以要先克隆k8s源码。之前用minikube创建的k8s集群是v1.32.0
在这里插入图片描述

所以克隆v1.32.0版本的代码

git clone  --branch v1.32.0 --single-branch https://github.com/kubernetes/kubernetes.git

考虑到后续可能要改改源码并保存下来,所以我forkmaster分支去编译。

Makefile中可以看到如何编译
在这里插入图片描述

在编译前先修改.go-version文件中go的版本, 默认里面指定的是1.23.4k8s源码中要求go版本是1.23.0以上就可以了,我的是1.23.3不想重新下载go压缩包了,所以改了。

修改shell脚本让其输出编译的命令,看不到命令我不是很放心
在这里插入图片描述

通过环境变量指定版本号,修改完版本后执行编译命令编译kubeadm

export KUBE_GIT_VERSION=v1.32.0 
export KUBE_GIT_COMMIT=$(git rev-parse --short HEAD) 
export KUBE_GIT_TREE_STATE=clean
make all DBG=1 WHAT=cmd/kubelet

可以看到编译的命令已经带上了禁用优化的参数了
在这里插入图片描述

kubeadm在一开始检查的过程中会调用kubelet获取版本号,所以我把全部二进制文件都编译了

export KUBE_GIT_VERSION=v1.32.0 
export KUBE_GIT_COMMIT=$(git rev-parse --short HEAD) 
export KUBE_GIT_TREE_STATE=clean
make all DBG=1

调试命令如下

dlv --headless --listen=:8005 --api-version=2 --accept-multiclient --log exec /root/kubernetes/_output/bin/kubeadm -- init --cri-socket unix:///run/containerd/containerd.sock

vscode配置如下

{// 使用 IntelliSense 了解相关属性。 // 悬停以查看现有属性的描述。// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387"version": "0.2.0","configurations": [{"name": "kubeadm","type": "go","request": "attach","mode": "remote","remotePath": "/root/kubernetes","port": 8005,"host": "4c","showLog": true,"trace": "verbose","substitutePath": [{"from": "${workspaceFolder}","to": "/root/kubernetes"},{"from": "/Users/wy/wy/workspace_go/pkg/mod", // 本地路径"to": "/root/go_path/pkg/mod" // 远程路径},]}]
}

调试源码前准备工作

PATH环境变量

将前面编译源码生成二进制文件的目录添加到PATH环境变量中,因为kubeadm需要调用kubelet

containerd启用cri插件

kubeadm中,contianerd是默认的容器运行时,containerd需要启动cri插件,随docker启动的contianerd默认是禁用了cri插件的。

containerd配置cri插件官方文档地址:
https://github.com/containerd/containerd/blob/main/docs/cri/config.md

docker version命令查看docker版本是27.5.0, containerd对应的版本是1.7.25
containerd配置文件默认位置是/etc/containerd/config.toml

在配置文档中有完整的配置文件样例且有大量的注释,有需要的时候再来看,但这不是我们目前要关注的
在这里插入图片描述

使用命令生成默认配置

# 备份旧配置
cp /etc/containerd/config.toml /etc/containerd/config.toml.bak
# 生成默认配置
containerd config default > /etc/containerd/config.toml

修改的值如下,v1.32.0版本k8s要求是3.10版本,没有的话会触发下载镜像的操作

SystemdCgroup = true
sandbox_image = "registry.k8s.io/pause:3.10"

需要重启containerd。由于我docker服务是apt安装的,估计是自动装的containerd,是由systemd托管的。所以重启命令如下

sudo systemctl restart containerd

下载k8s相关镜像

由于网络问题,你得先下载k8s的镜像

# 查看需要下载的镜像
kubeadm config images list

镜像清单如下

registry.k8s.io/kube-apiserver:v1.32.1
registry.k8s.io/kube-controller-manager:v1.32.1
registry.k8s.io/kube-scheduler:v1.32.1
registry.k8s.io/kube-proxy:v1.32.1
registry.k8s.io/coredns/coredns:v1.12.0
registry.k8s.io/pause:3.10
registry.k8s.io/etcd:3.5.17-0

然后用github action大法下载镜像,下载完成后,检查镜像

ctr --namespace k8s.io images list | awk '{print $1}'

镜像已经拉取成功了
在这里插入图片描述

配置kubelet

kubeadm init命令会使用systemctl命令重启kubelet,所以需要编写 /etc/systemd/system/kubelet.service

但是具体怎么写,需要通过官方提供的apt命令安装kubeadm后,使用kubeadm命令安装一次k8s,然后查看kubelet.service可以看到具体的脚本是怎么写的
在这里插入图片描述

可以看到需要编写两个文件,分别是kubelet.service以及 10-kubeadm.conf

编写/etc/systemd/system/kubelet.service

[Unit]
Description=kubelet: The Kubernetes Node Agent
Documentation=https://kubernetes.io/docs/home/
Wants=network-online.target
After=network-online.target[Service]
ExecStart=/root/kubernetes/_output/bin/kubelet
Restart=always
StartLimitInterval=0
RestartSec=10
KillMode=process
Delegate=yes[Install]
WantedBy=multi-user.target

编写/etc/systemd/system/kubelet.service.d/10-kubeadm.conf,可以看到这里指定了config.yaml文件

# Note: This dropin only works with kubeadm and kubelet v1.11+
[Service]
Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf"
Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml"
# This is a file that "kubeadm init" and "kubeadm join" generates at runtime, populating the KUBELET_KUBEADM_ARGS variable dynamically
EnvironmentFile=-/var/lib/kubelet/kubeadm-flags.env
# This is a file that the user can use for overrides of the kubelet args as a last resort. Preferably, the user should use
# the .NodeRegistration.KubeletExtraArgs object in the configuration files instead. KUBELET_EXTRA_ARGS should be sourced from this file.
EnvironmentFile=-/etc/default/kubelet
ExecStart=
ExecStart=/root/kubernetes/_output/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS

然后启用该service

systemctl enable kubelet.service

调试源码

主要是想搞清kubeadm是怎么部署k8s集群的,看看能不能用来调试代码。
代码入口是/cmd/kubeadm/kubeadm.go

kubeadm源码调试

kebeadm中将部署集群的每个步骤抽象成phase组成一个数组,然后遍历这个数组,运行每个phase对应的函数,当phase数组遍历完了,kubeadm init命令就完成了
在这里插入图片描述

cmd命令初始化的时候,可以看到有哪些phase
在这里插入图片描述

其实在磊哥的《深入剖析Kubernetes》中有写了kubeadm的部署原理,只是有些东西还是得自己看看才知道
在这里插入图片描述

很明显,kubelet的启动对应是NewKubeletStartPhase,随后的NewWaitControlPlanePhase中等待apiserver启动完成。

... 省略
initRunner.AppendPhase(phases.NewKubeletStartPhase())
initRunner.AppendPhase(phases.NewWaitControlPlanePhase())
... 省略

Kubelet 运行时,它会持续监视参数staticPodPath指定的目录,如果有新的 Pod 配置文件加入,Kubelet 会自动创建 Pod。这种启动Pod的方式叫静态启动,该过程不需要 apiserver 参与调度。

kubeadm生成的kubelet的配置文件中有个staticPodPath选项,值如下

staticPodPath: /etc/kubernetes/manifests

该目录下的yaml都是kubeadm生成的,共四个yaml文件,分别是

  • etcd.yaml
  • kube-apiserver.yaml
  • kube-controller-manager.yaml
  • kube-scheduler.yaml

kubelet源码调试

正常情况下,kubelet是不会有问题的,如果在kubeadm init命令执行过程提示 kubelet失败,得看kubelet到底报啥错了。查看kubelet日志

journalctl -u kubelet

如果从日志上没看出是啥问题,可以调试下源码看看。当代码运行到启动kubelet时,启动所需要的配置文件都已经生成了,所以调试kubelet的时候,可以先退出kubeadm的调试。

调试kubelet需要先把kubeadm init的代码运行到下图中的位置,然后kill掉调试kubeadm initdlv进程,然后调试kubelet进程
在这里插入图片描述

调试前需要先停止kubelet,并禁用自动重启

systemctl disable kubelet.service
systemctl stop kubelet

用下面的命令调试kubelet源码

KUBELET_CONFIG_ARGS="--config=/var/lib/kubelet/config.yaml"
KUBELET_KUBECONFIG_ARGS="--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf"
KUBELET_KUBEADM_ARGS="--container-runtime-endpoint=unix:///run/containerd/containerd.sock --pod-infra-container-image=registry.k8s.io/pause:3.10"
dlv --headless --listen=:8005 --api-version=2 --accept-multiclient --log exec /root/kubernetes/_output/bin/kubelet -- $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS

变量$KUBELET_EXTRA_ARGS是由文件/etc/default/kubelet中定义的,默认是空值,所以我没有赋值。

读取pod文件的代码位置如下,config.NewSourceFile中会启动goroutinue监听/etc/kubernetes/manifests的文件,如果文件有改动,会往一个 channel发送数据
在这里插入图片描述

最后在kubelet的主循环中处理channel中的数据,创建、更新或者删除pod
在这里插入图片描述

启动的代码东西太多了,等需要的时候再回来看,此处只是记录下代码的位置

kube-scheduler源码调试

回到主题上,k8s相关的组件都是通过静态pod的方式启动的,要了解一个pod,就得看它的yaml文件,以kube-scheduler组件为例

在这里插入图片描述

可以看到是使用宿主机的网络命名空间,那么就可以直接使用执行源码编译的二进制文件启动kube-schedualer代替静态pod的方式来实现断点调试了。

先用kubeadm init命令把k8s部署成功,默认情况下,出于安全原因,不会在控制平面节点上调度 Pod。想要在控制平面节点上调度需要执行下面的命令

kubectl taint nodes --all node-role.kubernetes.io/control-plane-

然后删除对应的kube-scheduler.yaml,由于kubelet是持续监视着/etc/kubernetes/manifests的,如果文件有变动,则执行对应的操作,例如我删除了yaml文件,kubelet会删除掉对应的pod

删除yaml文件后已经看不到kube-scheduler了,coredns是要等到CNI插件安装成功后才会启动,这里先不管
在这里插入图片描述

参考yaml中的启动命令,使用下面的命令调试

dlv --headless --listen=:8005 --api-version=2 --accept-multiclient --log exec /root/kubernetes/_output/bin/kube-scheduler -- --authentication-kubeconfig=/etc/kubernetes/scheduler.conf --authorization-kubeconfig=/etc/kubernetes/scheduler.conf --bind-address=127.0.0.1 --kubeconfig=/etc/kubernetes/scheduler.conf --leader-elect=false

参数说明

  • --authentication-kubeconfig 负责身份认证,确保 kube-scheduler 可以连接 API Server。
  • --authorization-kubeconfig 负责权限授权,确保 kube-scheduler 有权限调度 Pod。
  • --leader-elect=false因为没有多个节点,所以把leader选举关掉

可以看到已经能够成功断点调试了,SchedulerOne函数就是对Pod进行调度的入口函数。
在这里插入图片描述

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

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

相关文章

LLM学习笔记1——本地部署Meta-Llama-3.2-1B大模型

系列文章目录 参考博客 参考博客 文章目录 系列文章目录前言与调用一、部署要求二、实现步骤0.深度学习环境错误1,验证pytorch版本时提示以下问题:错误2,验证pytorch版本时提示以下问题:错误3,有时候还会提示你有一些…

搜维尔科技:提供人形机器人传感器的应用案例分析

视觉传感器 • 家庭服务场景:在家庭清洁机器人中,视觉传感器可以识别家具、障碍物的位置和形状,规划清洁路径,避开桌椅、宠物玩具等。如小米扫地机器人,通过视觉传感器与算法结合,能构建房间地图&#xff…

windows蓝牙驱动开发-蓝牙 LE 邻近感应配置文件

邻近感应检测是蓝牙低功耗 (LE) 的常见用途。 本部分提供了创建可用于开发 UWP 设备应用的邻近感应配置文件的设备实现的指南。 在开发此应用之前,应熟悉蓝牙 LE 函数和蓝牙 LE 邻近感应配置文件规范。 示例服务声明 蓝牙低功耗引入了一个新的物理层,…

逻辑回归:Sigmoid函数在分类问题中的应用

欢迎来到我的主页:【Echo-Nie】 本篇文章收录于专栏【机器学习】 1 什么是Sigmoid函数? Sigmoid函数(Logistic函数)是机器学习中最经典的激活函数之一,是一个在生物学中常见的S型函数,也称为S型生长曲线。…

如何在Windows中配置MySQL?

MySQL是一个广泛使用的开源关系型数据库管理系统,它支持多种操作系统平台,其中包括Windows。无论是开发者进行本地开发,还是管理员为应用程序配置数据库,MySQL都是一个非常流行的选择。本篇文章将详细介绍如何在Windows操作系统中…

MySQL的操作

一.数据库的操作 1.创建数据库 create database (if not exists) 数据库名称 (character set/charset 字符集名称); SQL中有特定含义的单词(create database)也就是关键字 在创建数据库名 表名 列名的时候都可以和关键字重复 。 if not exists&#xff1…

MariaDB *MaxScale*实现mysql8读写分离

1.MaxScale 是干什么的? MaxScale是maridb开发的一个mysql数据中间件,其配置简单,能够实现读写分离,并且可以根据主从状态实现写库的自动切换,对多个从服务器能实现负载均衡。 2.MaxScale 实验环境 中间件192.168.12…

响应式编程_05 Project Reactor 框架

文章目录 概述响应式流的主流实现框架RxJavaReactor Project Reactor 框架Reactor 异步数据序列Flux 和 Mono 组件FluxMono 操作符背压处理 小结 概述 响应式编程_02基本概念:背压机制 Backpressure介绍了响应式流规范以及 Spring 框架中的响应式编程技术&#xff…

免费windows pdf编辑工具Epdf

Epdf(完全免费) 作者:不染心 时间:2025/2/6 Github: https://github.com/dog-tired/Epdf Epdf Epdf 是一款使用 Rust 编写的 PDF 编辑器,目前仍在开发中。它提供了一系列实用的命令行选项,方便用户对 PDF …

计算机组成原理(3)

计算机组成原理(3) 存储器层次结构存储器概述存储器分类存储器性能指标 半导体随机存储SRAM和DRAM 存储器层次结构 主存-辅存:实现了虚拟存储系统,解决了主存容量不足的问题; Cache-主存:解决了主存于CPU速…

html 列动态布局

样式说明: /* 列动态布局,列之间以空格填充 */ li {display: flex;/* flex-direction: column; */justify-content: space-between; }

25/2/8 <机器人基础> 阻抗控制

1. 什么是阻抗控制? 阻抗控制旨在通过调节机器人与环境的相互作用,控制其动态行为。阻抗可以理解为一个力和位移之间的关系,涉及力、速度和位置的协同控制。 2. 阻抗控制的基本概念 力控制:根据感测的外力调节机械手的动作。位置…

Redis03 - 高可用

Redis高可用 文章目录 Redis高可用一:主从复制 & 读写分离1:主从复制的作用2:主从复制原理2.1:全量复制2.2:增量复制(环形缓冲区) 3:主从复制实际演示3.1:基本流程准…

蓝桥杯C语言组:图论问题

蓝桥杯C语言组图论问题研究 摘要 图论是计算机科学中的一个重要分支,在蓝桥杯C语言组竞赛中,图论问题频繁出现,对参赛选手的算法设计和编程能力提出了较高要求。本文系统地介绍了图论的基本概念、常见算法及其在蓝桥杯C语言组中的应用&#…

在阿里云ECS上一键部署DeepSeek-R1

DeepSeek-R1 是一款开源模型,也提供了 API(接口)调用方式。据 DeepSeek介绍,DeepSeek-R1 后训练阶段大规模使用了强化学习技术,在只有极少标注数据的情况下提升了模型推理能力,该模型性能对标 OpenAl o1 正式版。DeepSeek-R1 推出…

Ollama + AnythingLLM + Deepseek r1 实现本地知识库

1、Ollama:‌是一个开源的大型语言模型 (LLM)服务工具,旨在简化在本地运行大语言模型的过程,降低使用大语言模型的门槛‌。 2、AnythingLLM:是由Mintplex Labs Inc. 开发的一款全栈应用程序,旨在构建一个高效、可定制、…

(Arxiv-2023)HiPA: 通过高频增强自适应实现一步文本到图像扩散模型

HiPA: 通过高频增强自适应实现一步文本到图像扩散模型 paper是NUS发布在Arxiv 2023的工作 paper title:HiPA: Enabling One-Step Text-to-Image Diffusion Models via High-Frequency-Promoting Adaptation Code:等待开源 Abstract 扩散模型已彻底改变了文本到图像…

Java版本与JDK版本

两者关联 Java版本指的Java语言和平台的版本,例如Java8、Java11、Java17等,每个版本会引入新特性、改进和修复。 JDK(Java Development Kit)版本则是开发工具包,包含编译器、调试器等工具,通常与Java版本对应,例如JDK…

【C语言标准库函数】三角函数

目录 一、头文件 二、函数简介 2.1. 正弦函数:sin(double angle) 2.2. 余弦函数:cos(double angle) 2.3. 正切函数:tan(double angle) 2.4. 反正弦函数:asin(double value) 2.5. 反余弦函数:acos(double value)…

活动预告 |【Part 2】Microsoft 安全在线技术公开课:通过扩展检测和响应抵御威胁

课程介绍 通过 Microsoft Learn 免费参加 Microsoft 安全在线技术公开课,掌握创造新机遇所需的技能,加快对 Microsoft Cloud 技术的了解。参加我们举办的“通过扩展检测和响应抵御威胁”技术公开课活动,了解如何更好地在 Microsoft 365 Defen…