在kubernetes下轻松debug
在容器化大行其道的今天,经常有需求要检查容器内部状态,debug容器内的应用。
今天总结介绍一下几个场景与解决方案。
docker debug
有时候我们的容器应用A会有些网络问题,或是cpu memory io占用过高,我们想看看容器内到底什么在作怪。
然而一般的应用镜像的基础镜像是精简镜像,它几乎没什么调试查看工具。
这时候就需要利用namespace(控制资源隔离)的相关知识,启动一个tools-B容器来检查目标容器A。
# 以下命令本质上是启动一个新的容器,但是新容器的namespace使用的是A容器的,所以可以对A容器下的pid、网络等进行读写
# 开启后,即可使用ping、telnet等各种命令进行环境检查啦
docker run --rm -it --network=container:container_A --pid=container:container_A busybox
当然,你也可以将这条命令写入bashrc,以便未来更方便的使用它。因为我用的是zsh,我将如下代码写在.zshrc配置中
# docker debug
function dockerdebug() {
docker run --rm -it --network=container:$1 --pid=container:$1 busybox;
}
source后或者打开新的终端后,就可以使用命令dockerdebug 容器名
进入容器了。
kubectl debug
以上介绍了docker进入容器debug的问题,k8s中,怎么做呢?
-
安装kubectl
- mac使用
brew install aylei/tap/kubectl-debug
安装 - 其它安装方式
- mac使用
-
命令行进入debug
# 如果k8s集群不在本机,可以先拉取k8s集群的kubeconfig(一个包含了certificate、authority、地址等信息的文件)到本地,再设置环境变量
export KUBECONFIG=/xxx/xxx/admin.conf
# 进入选取pod进入调试
kubectl debug pod_name
此时,可以看见启动了一个debug-agent-pod-xxx,如果失败,一般是需要集群机器上需要docker pull docker.io/nicolaka/netshoot:latest
,类似上文docker debug的busybox镜像。
还有更多功能可以参见官方文档
当我们需要调试本地应用,访问集群上的其它服务
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
# nginx-service NodePort 11.11.198.200 <none> 88:32267/TCP 7d19h
# 如果非本地集群,需要设置kubeconfig环境变量即可
export KUBECONFIG=/xxx/xxx/admin.conf
# 方式一:将流量通过本地8888转发到service的88端口上,此时访问本地8888端口即相当于访问了service的88端口
kubectl port-forward service/nginx-service 8888:88
# 方式二:将流量通过本地9999端口转发到对应deployment中的pod的80端口上
kubectl port-forward deployment/nginx-deployment 9999:80
Telepresence
上面描述了访问集群中的服务,本地调试的方法。下面介绍下被调试的应用需要被集群中服务调用,应当如何做。
即将集群中的流量转发到本地应用。
Telepresence安装
- OS X
brew install --cask osxfuse
brew install datawire/blackbird/telepresence
- Ubuntu 16.04 or later
curl -s https://packagecloud.io/install/repositories/datawireio/telepresence/script.deb.sh | sudo bash
sudo apt install --no-install-recommends telepresence
Telepresence使用
假设我们集群有a、b、c三个服务,他们分别由deployement管理,service-a、service-b、service-c。
服务a依赖服务b的某个接口,b依赖c。
忽然,服务b的这个接口出了点问题,我们想定位下原因或调试下,难道要重新打包制作个镜像、上传到服务器再调试吗?
大可不必,我们用下面的步骤实现本地调试。
-
在本地改好服务b程序
-
运行命令,admin.conf是目标k8s集群的kubeconfig
export KUBECONFIG=/xxx/xxx/admin.conf
- 使用本地程序接收集群中的流量
# service-b 是deployment名称
# 8081是本地监听端口(注意本地的服务b也需要监听8081端口)
# 80是线上服务b的pod的监听端口
# binary-b是本地的二进制可执行文件
telepresence --swap-deployment service-b --expose 8081:80 --run ./binary-b
- 使用本地debug
telepresence --swap-deployment service-b --expose 8081:80
# 再使用编辑器debug启动web服务,这样就可以本地debug集群中的请求了
-
如果需要集群中的环境变量
-
5.1 安装EnvFile插件并重启Goland
-
5.2 使用telepresence –swap-deployment service-b –expose 8081:80后;将环境变量写入文件
env > k8s.env
-
5.3 编辑debug启动项
-