首页>>后端>>Python->如何在k8s中调试Django(k8s 调试)

如何在k8s中调试Django(k8s 调试)

时间:2023-12-09 本站 点击:0

导读:本篇文章首席CTO笔记来给大家介绍有关如何在k8s中调试Django的相关内容,希望对大家有所帮助,一起来看看吧。

K8s ConfigMap

原文地址:

description: "分离配置与镜像,提高可移植性"

date: 2020.11.22 10:34

categories:

- K8s

tags: [K8s, DevOps]

keywords: K8s, ConfigMap, subPath

在 k8s 集群中部署第一个应用 中,完成了一个基本的 NGINX 服务的部署,但在真实环境中使用 NGINX 时,一般都需要定制其配置文件,使满足实际代理需求。K8s 提供了一个 ConfigMap 的概念,允许将配置文件与镜像文件分离,以使容器化的应用程序具有可移植性。

可以按字面方式,将 ConfigMap,理解为一个 Config 的 Map:

一个 ConfigMap 中可以包含多个 Key / Value 对。

可以使用 kubectl create configmap 命令基于 目录、文件 或字符串来创建 ConfigMap,也可以直接编写 yaml 文件进行定义:

之后可使用 kubectl apply -f nginx-config.yml 完成 ConfigMap 的创建。

ConfigMap 有多种定义形式,也有多种使用形式,详细情况可以查阅 官方文档 。本文仍以 NGINX 配置文件为例,说明一下 ConfigMap 中定义的配置文件的使用方式。

上面的 nginx-config.yml 定义了两个 ConfigMap,目标是放到 NGINX 容器中的如下两个位置:

可以将 ConfigMap 添加到 Volume 中,再进行挂载以使用,如:

有两个地方需要说明一下:

比如上例中的 mountPath: /etc/nginx/conf.d ,此时可指定挂载 ConfigMap 中的某个配置到该路径下的具体文件,也可将整个 ConfigMap 中的所有配置以多个文件的形式挂载到指定路径下。

不论哪种方式,都会将容器中原路径下所有先前的文件清除,需注意。

若想将配置文件挂载至容器中某个具体文件处,不影响该文件所在路径的其他文件,可按上例中的 nginx.conf 文件方式:

即 mountPath 直接指定到具体文件,并通过 subPath 表明文件名。

更新已经在数据卷中使用的 ConfigMap 时,已映射的配置内容最终也会被自动更新。 kubelet 在每次定期同步时都会检查已挂载的 ConfigMap 是否是最新的。但是,它使用其本地的基于 TTL 的缓存来获取 ConfigMap 的当前值。因此,从更新 ConfigMap 到将新值映射到 Pod 的总延迟,可能与 kubelet 同步周期 + ConfigMap 在 kuelet 中缓存的 TTL 一样长。

另外,使用 ConfigMap 作为 subPath 的数据卷将不会收到 ConfigMap 更新。

以上面配置为例,当更新 ConfigMap 中 NGINX 配置文件内容并 apply 到集群之后,可以稍等一会,然后进入到容器中观察配置文件, nginx.conf 文件的内容不会随 ConfigMap 文件更新同步,但 /etc/nginx/conf.d 路径下内容,会按更新周期,自动同步 confd-config 中的所有变更,包括配置文件内容,以及配置文件个数。

本文中完整的 K8s 配置如下:

kubectl apply -f nginx-test.yml 完成部署之后,可通过集群的 30081 端口访问容器内 2020 端口的服务,并可以修改 ConfigMap 中内容,进入到容器中观察 NGINX 对应配置文件的变化。

k8s 基本使用(上)

本文将介绍 k8s 中的一些最基本的命令,并辅以解释一些基本概念来方便理解,也就是说,本文是一篇偏向实用性而非学术性的文章,如果你想提前了解一下 k8s 相关的知识的话,可以通过以下链接进行学习:

k8s 是经典的一对多模型,有一个主要的管理节点 master 和许多的工作节点 slaver 。当然,k8s 也可以配置多个管理节点,拥有两个以上的管理节点被称为 高可用 。k8s 包括了许多的组件,每个组件都是单运行在一个 docker 容器中,然后通过自己规划的虚拟网络相互访问。你可以通过 kubectl get pod -n kube-system 查看所有节点上的组件容器。

在管理节点中会比工作节点运行更多的 k8s 组件,我们就是靠着这些多出来的组件来对工作节点发号施令。他们都叫什么这里就不详细提了。反正对于”基本使用“来说,这些名字并不重要。

要想理解一个东西就要先明白它的内在理念。通俗点就是,k8s 做了什么?为了提供更加可靠的服务,就要增加服务器的数量,减少每个服务器的体量来平摊负载,而越来越多的虚拟机就会带来越来越高的运维成本。如何让少量的运维人员就可以管理数量众多的服务器及其上的服务呢?这就是 k8s 做的工作。

k8s 把数量众多的服务器重新抽象为一个统一的资源池 ,对于运维人员来说,他们面前没有服务器1、服务器2的概念,而是一个统一的资源池,增加新的服务器对运维人员来说,只是增加自资源池的可用量。不仅如此,k8s 把所有能用的东西都抽象成了资源的概念,从而提供了一套更统一,更简洁的管理方式。

接下来,我会把每个基本命令当做一节来进行介绍,并辅以介绍一些基本概念。本文介绍的命令涵盖了增删改查四方面,可参加下面表格,因为篇幅较长,我们将 create 及之后的不那么常用的命令放在下一篇文章 k8s 基本使用(下) 里讲:

接下来进入正题,首先来了解一下 k8s 中最最最常用的命令 kubectl get ,要记住,k8s 把所有的东西都抽象成了资源,而 kubectl get 就是用来查看这些资源的。最常见的资源就是 pod 。

不仅我们自己的服务是要包装成 pod 的,就连 k8s 自己也是运行在一堆 pod 上。接下来就让我们查看一下 k8s 的 pod :

-n 参数指定了要查看哪个命名空间下的 pod 。 k8s 所有的 pod 都被放置在 kube-system 命名空间下。

执行了 kubectl get pod -n kube-system 命令后,你就可以看到如下内容:

其中每一行就是一个资源,这里我们看到的资源是 pod 。你看到的 pod 数量可能和我的不一致,因为这个列表里包含了 k8s 在所有节点上运行的 pod ,你加入的节点越多,那么显示的 pod 也就越多。我们来一列一列的看:

kubectl get 可以列出 k8s 中所有资源

这里只介绍了如何用 kubectl 获取 pod 的列表。但是不要把 get 和 pod 绑定在一起,pod 只是 k8s 中的一种服务,你不仅可以 get pod ,还可以 get svc ( 查看服务 )、 get rs ( 查看副本控制器 )、 get deploy ( 查看部署 )等等等等,虽然说 kubectl get pod 是最常用的一个,但是如果想查看某个资源而又不知道命令是什么, kbuectl get 资源名 就对了。

如果你想看更多的信息,就可以指定 -o wide 参数,如下:

加上这个参数之后就可以看到资源的所在 ip 和所在节点 node 了。

记得加上 -n

-n 可以说是 kubectl get 命令使用最频繁的参数了,在正式使用中,我们永远不会把资源发布在默认命名空间。所以,永远不要忘记在 get 命令后面加上 -n 。

kubectl get 命令可以列出 k8s 中的资源,而 kubectl get pod 是非常常用的查看 pod 的命令。而 -n 参数则可以指定 pod 所在的命名空间。

kubectl describe 命令可以用来查看某一资源的具体信息,他同样可以查看所有资源的详情, 不过最常用的还是查看 pod 的详情 。他也同样可以使用 -n 参数指定资源所在的命名空间。

举个例子,我们可以用下面命令来查看刚才 pod 列表中的某个 pod,注意不要忘记把 pod 名称修改成自己的:

然后你就可以看到很多的信息,咱们分开说,首先是基本属性,你可以在详细信息的开头找到它:

基本属性

其中几个比较常用的,例如 Node 、 labels 和 Controlled By 。通过 Node 你可以快速定位到 pod 所处的机器,从而检查该机器是否出现问题或宕机等。通过 labels 你可以检索到该 pod 的大致用途及定位。而通过 Controlled By ,你可以知道该 pod 是由那种 k8s 资源创建的,然后就可以使用 kubectl get 资源名 来继续查找问题。例如上文 DaemonSet/kube-flannel-ds-amd64 ,就可以通过 kubectl get DaemonSet -n kube-system 来获取上一节资源的信息。

内部镜像信息

在中间部分你可以找到像下面一样的 Containers 段落。该段落详细的描述了 pod 中每个 docker 容器的信息,常用的比如 Image 字段,当 pod 出现 ImagePullBackOff 错误的时候就可以查看该字段确认拉取的什么镜像。其他的字段名都很通俗,直接翻译即可。

事件

在 describe 查看详情的时候,最常用的信息获取处就是这个 Event 段落了,你可以在介绍内容的末尾找到它,如下:

是的,如果你看到上面这样,没有任何 Events 的话,就说明该 pod 一切正常。当 pod 的状态不是 Running 时,这里一定会有或多或少的问题,长得像下面一样,然后你就可以通过其中的信息分析 pod 出现问题的详细原因了:

kubectl describe 资源名 实例名 可以查看一个资源的详细信息,最常用的还是比如 kubectl describe pod pod名 -n 命名空间 来获取一个 pod 的基本信息。如果出现问题的话,可以在获取到的信息的末尾看到 Event 段落,其中记录着导致 pod 故障的原因。

如果你想查看一个 pod 的具体日志,就可以通过 kubectl logs pod名 来查看。注意,这个只能查看 pod 的日志。通过添加 -f 参数可以持续查看日志。例如,查看 kube-system 命名空间中某个 flannel pod 的日志,注意修改 pod 名称:

然后就可以看到如下输出:

如果你发现某个 pod 的服务有问题,但是状态还是显示 Running ,就可以使用 kubectl logs 来查看其详细日志。

在本篇文章里,我们了解了 k8s 的宗旨和一些基本概念,并知道了最为常用的 get 、 descibe 及 logs 命令,知道了这三条命令之后就几乎可以从 k8s 中获取所有常用信息了。接下来的 k8s 基本使用(下) 里,我们会更深一步,来了解 k8s 中如何创建、修改及删除资源。

k8s部署nginx的url反向代理初探

  团队中做一个项目,使用Django开发多个应用,如app1、app2等,均采用docker镜像部署到k8s环境中,整体架构为:

  常规处理方案:

  此种方案简单清晰,对于api接口及静态页面(如django中的admin管理台页面)不会产生任何问题,因为一个app对应一个域名,从逻辑上看是一对一的访问,app之间互相隔离。

  有了这些问题,那么我们就尝试用url前缀去识别路由分发,实现通过url前缀进行反向代理,而不是通过域名去反向代理。

  比如/A/xxx这种url就路由到app1,/B/xxx这种url就路由到app2,依次类推。

  刚开始配置还是很简单的,nginx配置如下:

  此配置大概意思是当匹配到带/A/这种前缀的url时,就将请求路由到app1_addr:app1_port/中。具体location指令请参考nginx手册。

  api接口访问正常,但在请求 ,使用django自带的管理台时,无法进行302的跳转。在新的url页面无法访问。

  经分析,过程是这样的:

  此问题出现在第4步,需要nginx在遇到301或302时,重新修改response header中location值,这样浏览器就能按添加前缀/A/后的url进行请求了。

  修改配置后如下:

  新增加一行proxy_redirect指令,具体指令说明请参见nginx手册,大概意思是告诉nginx,当遇到301或302服务器端重定向时,按^/(.*)$进行正则匹配,即匹配/xxxx这种url。当匹配成功后,将响应header中location值修改成 ,再将响应继续返回给浏览器。其中$1表示正则匹配中(...)中的元组序号。

  当然,根据实际需求,还可以再添加多个proxy_rediect指令,原理一样:

  现在api、admin管理台能访问了,但发现管理台的js/css/html/jpg这些静态资源都访问失败。

  分析如下,当django返回html到浏览器后,浏览器会解析html中静态资源url并请求,此时静态资源的url为/static/admin/xx/x.js或/admin/xxx/xxx这种格式。浏览器去请求这些url当然不存在,nginx便会直接报不存在资源。

  此时,可以有两种方案:

  第一种方法找了找,发现不好修改,毕竟admin是django集成在安装包中的,工程里并不会去直接继承或二次封装admin模块,因此放弃了。

  第二种方法找到了nginx中sub_filter指令,再次修改如下:

  新增加sub_filter*三行指令,具体指令用法请参见手册,大概意思是nginx根据sub_filter_types(本文没写,默认是text/html),去检查每次的响应内容,若内容为text/html,则进行替换操作,将响应内容中的【/admin/】字符串替换成【/A/admin/】字符串,即增加前缀操作,static同理。最后再添加sub_filter_once off;表明上面的替换是替换响应内容的所有地方,如果不加这句指令,则只会替换一次。

  若工程中还存在其它子应用的静态工程,也可照此来进行替换操作。

  这种替换后,原工程不用修改,不影响本地开发调试,感觉还是不错的。

  现在api接口、admin管理台都能正常访问了。完成了通过url前缀方式来反向代理功能。

  实现了浏览器或外部系统只需要通过

  这种格式的URL访问即可,只需一个域名,仅通过/A/这种前缀来区分不同的子应用。

  一般我们会使用前后端分离去开发项目,若有必要,也可以使用sub_filter去替换相应的请求内容。

结语:以上就是首席CTO笔记为大家整理的关于如何在k8s中调试Django的全部内容了,感谢您花时间阅读本站内容,希望对您有所帮助,更多关于如何在k8s中调试Django的相关内容别忘了在本站进行查找喔。


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