前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Gitlab CI/CD 实践三:Docker 安装 Gitlab Runner

Gitlab CI/CD 实践三:Docker 安装 Gitlab Runner

作者头像
Yuyy
发布2024-09-22 13:42:56
700
发布2024-09-22 13:42:56
举报
文章被收录于专栏:yuyy.info技术专栏

问题背景

在学习开源项目时,很多时候光看代码是搞不清楚实际运行时会走哪个逻辑分支,或者无法推测方法参数值。最简单的办法是 debug,熟悉某个功能的执行流程。

我们通常用 delve 去 debug golang 程序,但是很多云原生项目运行在 k8s 环境里,在本地我们可以用 minikube 来模拟 k8s。两者结合产生新问题:如何 debug minikube 里的 golang 容器?

剖析 minikube

在 mac 上运行 docker,无论是官方的 Docker Desktop,还是ColimaOrbStack。都是创建了一个 Linux 虚拟机,然后在虚拟机里运行 docker daemon。

minikube 是一个容器,里面运行着另一个 docker daemon,minikube 里 k8s 的 apiServer、controller、scheduler、etcd,就是通过这个 docker daemon 来创建的容器。如果用 minikube 创建了多个 node,那么每个 node 也是一个容器。

验证

  1. 本地启动 docker
  2. 启动 minikube:minikube start --registry-mirror=https://dockerproxy.net
  3. 登录到 minikube 容器:minikube ssh
  4. 查看minikube 里的 docker daemon 进程

5. 查看 k8s control plane 容器

运行在 minikube 里的 pod,就是用 minikube 容器里的 docker daemon 创建的容器。

这和 docker 官方的 docker in docker 容器类似,都是在容器内部运行独立的 docker daemon 进程。还有一种简单方式实现容器内部使用 docker,就是将宿主机的 docker daemon socke 挂载到容器里,然后容器里的 docker cli 调用该 socket 进行创建容器、构建镜像等,常用于 CI/CD 流水线。

在 mac 上只能看到 minikube 的容器,看不到minikube 内部的容器,近一步证实这是不同的 docker daemon 进程。

我们知道容器就是通过 namespace 技术实现资源隔离,通过 cgroup 实现资源限制,归根结底就是宿主机上的一个进程。所以上面的 minikube 容器,minikube 里运行的 pod,以及我们自己用 docker run 的容器,都是虚拟机里的进程。而父namespace 是可以看到子 namespace 的进程,那么在虚拟机里,我们是可以看到上诉所有容器对应的进程。

我这里启动了一个容器,并指定 pid namespace 是宿主机(虚拟机)的。可以看到 pod 容器进程,k8s apiServer 进程,以及两个 docker daemon 进程(一个是虚拟机里的,一个是 minikube 容器里的)。

解决方案

从上诉可知,运行在 minikube 里,pod 内部的进程,在虚拟机里是能看到的。那我们最开始的问题“如何 debug minikube 里的 golang 容器?”,就变成了“如何 debug 虚拟机里的 golang 进程?”。

如何在虚拟机里运行 golang 的 debug 程序 delve 呢?很简单,启动一个包含 delve 程序,同时设置 host pid namespace 的 docker 容器即可。

这里以调试 open kruise 为例

准备可调试的 kruise 镜像

一般 golang 程序二进制都是进行编译优化的,例如内联优化,这会导致实际运行的代码行数和本地代码对不上。

重新构建二进制

代码语言:javascript
复制
go build -gcflags="all=-N -l" -o bin/manager main.go 

准备 Dockerfile

代码语言:javascript
复制
FROM openkruise/kruise-manager:test
COPY bin/manager .

构建镜像

代码语言:javascript
复制
docker build -t openkruise/kruise-manager:test -f Dockerfile .

替换 minikube 里的镜像

代码语言:javascript
复制
minikube loadimage openkruise/kruise-manager:test

执行前需要将这个镜像的容器删掉。

运行 kruise

delve attach 待调试的 golang 进程

首先找到 kruise manager 的 pid。

然后使用 delve 容器进行 attach。

goland 连接

最后使用 goland 的 remote debug 连接 delve 即可。

以上方法同样适用于调试 k8s 控制面,调试 containerd 等 golang 程序。

Post Views: 8

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-9-21 1,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题背景
  • 剖析 minikube
    • 验证
    • 解决方案
      • 这里以调试 open kruise 为例
        • 准备可调试的 kruise 镜像
        • 运行 kruise
        • delve attach 待调试的 golang 进程
        • goland 连接
    相关产品与服务
    容器服务
    腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档