博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
跟我学 K8S--代码: 调试 Kubernetes
阅读量:5791 次
发布时间:2019-06-18

本文共 6726 字,大约阅读时间需要 22 分钟。

openstack 搞了2年,对动态语言的 debug 和 pdb念念不忘,总寻思着看 kubernetes代码能不能和 openstack 一样 pdb 一步步看下去。golang 里面有个debug 工具,叫 ,可以比较方便的调试 go 应用。

kubernetes 项目的 hack 目录下有个好用的 shell 脚本local-up-cluster.sh,它是通过_output/local/bin/linux/amd64/hyperkube在容器里启动k8s各服务的。考虑可以在本地进程启动 kubernetes 服务,这样便可以当作一个 go 应用去调试了。本文写作时kubernetes master 分支最新 commit id 为9884215f7976e8cc294fdbb62f8c2a6af9bca728。

linux 环境信息

这里不再赘述,我用的是 centos 7.4 虚拟机,配置是4C/16G/100G

$ cat /etc/redhat-releaseCentOS Linux release 7.5.1804 (Core)

go 环境安装

Kubernetes requires go1.10.2 or greater.Please install go1.10.2 or later.

go版本要求大于1.10.2

# 具体参见 https://golang.org/doc/installwget https://dl.google.com/go/go1.10.3.linux-amd64.tar.gz (具体参见)tar -C /usr/local/ -xzf go1.10.3.linux-amd64.tar.gz# 测试是否安装成功$ go versiongo version go1.10.3 linux/amd64# 配置 go 环境 (建议直接将 export 内容写入到/etc/profile下)mkdir /goexport GOPATH=/goexport PATH=$PATH:/usr/local/go/binexport PATH=$PATH:/go/bin# 安装 dlvgo get -u github.com/derekparker/delve/cmd/dlvexport PATH=$PATH:$GOPATH/bin# 下载 kubernetes 代码放到 $GOPATH/src/k8s.io目录下 (代码较大,如果只要最新一次提交的代码来加速下载,指定--depth=1)git clone https://github.com/kubernetes/kubernetes# 提供一个习惯访问的 shell 脚本,可以不操作(因为后面启动的local-up-cluster 使用的是cluster 目录下的kubectl.sh 来操作k8s 环境)cat<
/usr/local/bin/kubectl#!/bin/bash/go/src/k8s.io/kubernetes/cluster/kubectl.sh \$@EOFchmod +x /usr/local/bin/kubectl

etcd 安装

etcd version 3.2.18 or greater required.

etcd 版本要求大于3.2.18

# 具体参见 https://github.com/coreos/etcd/releaseswget https://github.com/coreos/etcd/releases/download/v3.3.9/etcd-v3.3.9-linux-amd64.tar.gz  tar xzvf etcd-v3.3.9-linux-amd64.tar.gz -C /usr/local/# 拷贝 bin 文件到/usr/local/bin下cp /usr/local/etcd-v3.3.9-linux-amd64/etcd /usr/local/etcd-v3.3.9-linux-amd64/etcdctl /usr/local/bin# 测试是否安装成功etcd —version

docker 安装

# 安装 docker repo(配了中科大源)sudo yum install -y yum-utils device-mapper-persistent-data lvm2sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.reposed -i 's/download.docker.com/mirrors.ustc.edu.cn\/docker-ce/g' /etc/yum.repos.d/docker-ce.repoyum makecache# 安装 docker-cesudo yum install -y docker-ce# 启动 dockersystemctl start dockersystemctl enable docker

docker 镜像

由于安装镜像存在墙,提前准备好 (感谢 提供的同步镜像仓库)

docker pull anjia0532/pause-amd64:3.1docker tag  anjia0532/pause-amd64:3.1 k8s.gcr.io/pause:3.1docker pull anjia0532/k8s-dns-kube-dns-amd64:1.14.10docker tag anjia0532/k8s-dns-kube-dns-amd64:1.14.10 k8s.gcr.io/k8s-dns-kube-dns-amd64:1.14.10docker pull anjia0532/k8s-dns-dnsmasq-nanny-amd64:1.14.10docker tag anjia0532/k8s-dns-dnsmasq-nanny-amd64:1.14.10 k8s.gcr.io/k8s-dns-dnsmasq-nanny-amd64:1.14.10docker pull anjia0532/k8s-dns-sidecar-amd64:1.14.10docker tag anjia0532/k8s-dns-sidecar-amd64:1.14.10 k8s.gcr.io/k8s-dns-sidecar-amd64:1.14.10

修改 kubernetes 代码

由于 local-up-cluster.sh 默认使用的是 hyperkube 镜像在容器中启动 kuebrnetes 服务,但是这样不能使用 dlv 去调试代码,那么需要在 host 进程启动,有两种方案都可以试试,由于local-up-cluster.sh 会在本地编译好代码并放入到 _output/bin 中,那么可以直接通过写 systemd 配置文件的方式在本地启动服务; 还有一种是我选择的,修改local-up-cluster.sh代码,如下:

图片描述

注意: 这个只在commit id: 30b89d830b7fd0827576853d6a0db44b66a90d3d 以后可用。之前的会编译不成功,是因为cmd下没有 kube-schduler 包,该目录在plugins/cmd/kube-sheduler下,需要重写规则。

启动集群

通过执行local-up-cluster.sh脚本启动集群

# 切换到 kubernetes 根目录$ pwd/go/src/k8s.io/kubernetes·$ ./hack/local-up-cluster.shKubelet cgroup driver defaulted to use: cgroupfsAPI SERVER insecure port is free, proceeding...API SERVER secure port is free, proceeding… ... ...Alternatively, you can write to the default kubeconfig:  export KUBERNETES_PROVIDER=local  cluster/kubectl.sh config set-cluster local --server=https://localhost:6443 --certificate-authority=/var/run/kubernetes/server-ca.crt  cluster/kubectl.sh config set-credentials myself --client-key=/var/run/kubernetes/client-admin.key --client-certificate=/var/run/kubernetes/client-admin.crt  cluster/kubectl.sh config set-context local --cluster=local --user=myself  cluster/kubectl.sh config use-context local  cluster/kubectl.sh # 验证集群是否成功 $ kubectl get componentstatus NAME                 STATUS    MESSAGE             ERRORcontroller-manager   Healthy   okscheduler            Healthy   oketcd-0               Healthy   {"health":"true"}

这里有个 tip, 在代码中有个判断 [ "x$GO_OUT" == "x” ], 也就是说如果第一次编译生成 bin 包后,往后只要指定 GO_OUT 再次执行就可以不再编译

我这里是: export GO_OUT=/go/src/k8s.io/kubernetes/_output/bin

调试举例

# 查找 并 kill 相关进程$ ps -ef | grep kubeletroot       538 26665  0 17:14 pts/1    00:00:00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn kubeletroot     31690 30984  0 17:14 pts/0    00:00:00 sudo -E /go/src/k8s.io/kubernetes/_output/bin/kubelet --v=3 --vmodule= --chaos-chance=0.0 --container-runtime=docker --hostname-override=127.0.0.1 --cloud-provider= --cloud-config= --address=127.0.0.1 --kubeconfig /var/run/kubernetes/kubelet.kubeconfig --feature-gates=AllAlpha=false --cpu-cfs-quota=true --enable-controller-attach-detach=true --cgroups-per-qos=true --cgroup-driver=cgroupfs --eviction-hard=memory.available<100Mi,nodefs.available<10%,nodefs.inodesFree<5% --eviction-soft= --eviction-pressure-transition-period=1m --pod-manifest-path=/var/run/kubernetes/static-pods --fail-swap-on=false --cluster-dns=10.0.0.10 --cluster-domain=cluster.local --port=10250root     31693 31690  3 17:14 pts/0    00:00:01 /go/src/k8s.io/kubernetes/_output/bin/kubelet --v=3 --vmodule= --chaos-chance=0.0 --container-runtime=docker --hostname-override=127.0.0.1 --cloud-provider= --cloud-config= --address=127.0.0.1 --kubeconfig /var/run/kubernetes/kubelet.kubeconfig --feature-gates=AllAlpha=false --cpu-cfs-quota=true --enable-controller-attach-detach=true --cgroups-per-qos=true --cgroup-driver=cgroupfs --eviction-hard=memory.available<100Mi,nodefs.available<10%,nodefs.inodesFree<5% --eviction-soft= --eviction-pressure-transition-period=1m --pod-manifest-path=/var/run/kubernetes/static-pods --fail-swap-on=false --cluster-dns=10.0.0.10 --cluster-domain=cluster.local --port=10250$ kill -9 31690$ kill -9 31693# 我移除了部分配置项,否则报错$ dlv --headless -l 127.0.0.1:1234 exec /go/src/k8s.io/kubernetes/_output/bin/kubelet -- --v=3 --vmodule= --chaos-chance=0.0 --container-runtime=docker --hostname-override=127.0.0.1 --cloud-provider= --cloud-config= --address=127.0.0.1 --kubeconfig /var/run/kubernetes/kubelet.kubeconfig --feature-gates=AllAlpha=false --cpu-cfs-quota=true --enable-controller-attach-detach=true --cgroups-per-qos=true --cgroup-driver=cgroupfs  --eviction-soft= --eviction-pressure-transition-period=1m --pod-manifest-path=/var/run/kubernetes/static-pods --fail-swap-on=false --cluster-dns=10.0.0.10 --cluster-domain=cluster.local --port=10250# 开始调试dlv connect 127.0.0.1:1234(dlv) b main.main(dlv) c(dlv) args(dlv) p 

备注:

  1. 这只是我初步实现的一个方案,并没有结合它深度使用,后续有新技能再更新上来
  2. 如果照着我的步骤卡住了,考虑下是不是配个梯子( )

转载地址:http://kqwfx.baihongyu.com/

你可能感兴趣的文章
Kibana登录认证设置
查看>>
volley 应用 GET POST请求 图片异步加载
查看>>
BZOJ-4325: NOIP2015 斗地主 (搜索神题)
查看>>
HDU-1222 Wolf and Rabbit (欧几里得定理)
查看>>
Camera Calibration 相机标定:原理简介(五)
查看>>
ClassCastException:ColorDrawable cannot be cast to RoundRectDrawableWithShadow
查看>>
ehcache实例
查看>>
Linux多线程与同步
查看>>
MS CRM 2011的自定义和开发(9)——编程模型介绍
查看>>
MySQL使用说明
查看>>
python 匿名函数
查看>>
设置UITableViewCell右侧的箭头
查看>>
Android Fragment 深度解析
查看>>
Codeforces Round #455 (Div. 2)E. Coprocessor[dfs]
查看>>
JavaScript - Iterable和遍历
查看>>
Professional C# 6 and .NET Core 1.0 - 40 ASP.NET Core
查看>>
字段为空sql语句,设置当前模式
查看>>
github 生成配置ssh 秘钥方法详解
查看>>
【转】CATALINA_BASE与CATALINA_HOME的区别
查看>>
Win7 windows update更新失败 正在还原 无法开机 双系统下的解决方案
查看>>