第 1 部分中,我们讲解了 Kubernetes 的核心组件,Kubernetes 是一种开源容器编排器,用于在分布式环境中部署和扩展应用程序;我们还讲解了如何在集群中部署一个简单的应用程序,然后更改其副本数量以扩大或缩小其规模。

在本文中,我们将为您深入讲解 Kubernetes 提供的网络和监控功能,为您将自己的应用推广到具有公开网络服务和良好可观察性的生产环境中做准备。

Kubernetes 网络功能

Kubernetes 包含一套全面的网络功能,用于将 Pod 连接在一起,并让它们在集群外可见。这里总结了一些较常使用的基础组件。

Service

Service 是 Kubernetes 对象,用于公开在集群中的 Pod 中运行的网络应用程序。网络流量流经服务,被引到正确的 Pod。

Service 有时会让开发人员感到困惑,因为其术语有时会与传统观点重叠。开发人员通常认为 Service 就是他们在集群中运行的应用程序,但在 Kubernetes 中,Service 具体是指允许访问应用程序的网络组件,是将 Kubernetes 对象联网的基本资源。在部署工作负载时,如果 Pods 需要在它们之间或集群外部进行通信,就需要使用服务。

Serivce 模型在部署副本之间分配流量时需要被使用到。例如,如果您为一个应用程序接口部署了四个副本,那么这四个 Pod 就应该共享网络流量。创建 Service 可以实现这一点,您的应用程序可以连接到服务的 IP 地址,然后该 IP 地址会将网络流量转发到其中一个兼容的 Pod。每个 Service 还分配了一个可预测的集群内 DNS 名称,以方便自动发现服务。

Kubernetes 支持几种不同类型的 Service,以适应常见的网络用例。主要有三种:

  • ClusterIP:这种类型的服务分配了一个 IP 地址,只能在群集内访问。这可以防止 Pod 被外部调用。由于这是最安全的服务类型,因此在未指定其他服务类型时,它也是默认服务类型。

  • NodePort:这些服务也会分配一个内部 IP 地址,但会额外绑定到节点上的指定端口。如果在端口 80 上创建了 NodePort 服务,且其 Pod 由节点 192.168.0.1托管,则可以通过本地网络上的 192.168.0.1:80 连接到 Pod。

  • LoadBalancerLoadBalancer Service 将外部 IP 地址映射到群集中。在使用亚马逊 EKS 或 Google GKE 等托管 Kubernetes 解决方案时,创建LoadBalancer Service 会自动在云账户中提供一个新的LoadBalancer资源。LoadBalancer 公共 IP 的流量会路由到 Service 背后的 Pod。当打算将 Pod 公开暴露在群集之外时,请使用此 Service 类型。LoadBalancer 允许您首先在群集的物理节点之间路由流量,然后将流量路由到每个节点上的正确 Pod。

1. 创建 Service

下面的 YAML 清单示例定义了一个 ClusterIP 服务,该服务将其 80 端口的流量导向带有 app.kubernetes.io/name: demo 标签的 Pod 的 8080 端口:

<span class="hljs-attribute">apiVersion</span>: v1
<span class="hljs-attribute">kind</span>: Service
<span class="hljs-attribute">metadata</span>:
<span class="hljs-attribute">name</span>: demo
<span class="hljs-attribute">spec</span>:
<span class="hljs-attribute">selector</span>:
app.kubernetes.io/<span class="hljs-attribute">name</span>: demo
<span class="hljs-attribute">ports</span>:
- <span class="hljs-attribute">protocol</span>: TCP
<span class="hljs-attribute">port</span>: <span class="hljs-number">80</span>
<span class="hljs-attribute">targetPort</span>: <span class="hljs-number">8080</span>

将文件保存为 service.yaml,然后使用 kubectl 将其应用到集群中:

$ kubectl <span class="hljs-built_in">apply</span> -f service.yaml
service/<span class="hljs-built_in">demo</span> created

运行 get services 命令显示分配给 Service 的群集 IP:

$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
demo ClusterIP <span class="hljs-number">10.99</span>
<span class="hljs-number">.219</span>
<span class="hljs-number">.177</span> &lt;none&gt;
<span class="hljs-number">80</span>/TCP
<span class="hljs-number">10</span>s

集群中的 Pod 现在可以与该 IP 地址(10.99.219.177)通信,以连接标有 app.kubernetes.io/name: demo 的相邻 Pod。由于 Service 会自动发现,您还可以使用分配给它的 DNS 主机名访问服务,其形式为

<service-name>.<namespace-name>.svc.<cluster-domain>

在本例中,主机名为

demo.default.svc.cluster.local

2. 针对内部和外部 IP 使用正确的 Service 类型

不同情况不同选择,正确的 Service 类型取决于您需要实现的目标。

如果 Pod 只需要在集群内部访问,例如其他集群内应用程序使用的数据库,则使用 ClusterIP 即可。这样可以防止 Pod 意外暴露在外部,提高集群安全性。对于应从外部访问的应用程序,如 API 和网站部署,则应使用 LoadBalancer

NodePort Service 需要谨慎。它们允许你设置自己的负载平衡解决方案,但经常被误用而造成意想不到的后果。当你手动指定端口范围时,请确保避免冲突。NodePort 服务还会绕过大多数 Kubernetes 网络安全控制,让 Pod 暴露在外。

Ingress资源

Service 只能在 IP 和端口级别上运行,因此它们通常与 Ingress 对象配对。Ingress 是用于 HTTP 和 HTTPS 路由的专用资源。Ingress 根据主机名和 URI 等请求特征,将 HTTP 流量映射到集群中的不同服务。它们还提供负载平衡和 SSL 终止功能

重要的是,Ingresses 本身并不是服务。它们位于服务前面,将服务暴露给外部流量。您可以使用 LoadBalancer 服务直接公开一组 Pod,但这会在没有任何过滤或路由支持的情况下推送流量。而使用 Ingress,您可以在服务之间切换流量,例如将 api.example.com 发送到您的 API 以及将 app.example.com 发送到您的前端。

要使用 Ingress,必须在集群中安装一个 Ingress 控制器。它负责将传入流量与您的 Ingress 对象进行匹配。

Kubernetes 默认情况下不捆绑任何选项;NGINX Ingress 和 Traefik 是易于配置的推荐选项。

Ingress 定义了一个或多个 HTTP 路由及其映射到的 Service。下面是一个将来自 example.com 的流量导向您的 demo 服务的基本示例:

<span class="hljs-attribute">apiVersion</span>: networking.k8s.io/v1
<span class="hljs-attribute">kind</span>: Ingress
<span class="hljs-attribute">metadata</span>:
<span class="hljs-attribute">name</span>: demo
<span class="hljs-attribute">spec</span>:
<span class="hljs-attribute">ingressClassName</span>: nginx
<span class="hljs-attribute">rules</span>:
- <span class="hljs-attribute">host</span>: example.com
<span class="hljs-attribute">http</span>:
<span class="hljs-attribute">paths</span>:
- <span class="hljs-attribute">path</span>: /
<span class="hljs-attribute">pathType</span>: Prefix
<span class="hljs-attribute">backend</span>:
<span class="hljs-attribute">service</span>:
<span class="hljs-attribute">name</span>: demo
<span class="hljs-attribute">port</span>:
<span class="hljs-attribute">number</span>: <span class="hljs-number">80</span>

spec.ingressClassName 的正确值取决于您使用的 Ingress 控制器。

网络策略

网络策略是一种机制,用于控制哪些 Pod 可以相互联网。在没有网络策略的情况下,无论 Pods 是否被 Service 公开,都可以自由通信。

每个策略使用选择器(selector)针对一个或多个 Pod。策略可以列出单独的 Ingress 和 Egress 规则: Ingress规则定义目标 Pod 可以从哪些 Pod 接收流量;Egress 规则限制目标 Pod 的流量流向

下面是一个示例:

<span class="hljs-attribute">apiVersion</span>: networking.k8s.io/v1
<span class="hljs-attribute">kind</span>: NetworkPolicy
<span class="hljs-attribute">metadata</span>:
<span class="hljs-attribute">name</span>: demo-policy
<span class="hljs-attribute">spec</span>:
<span class="hljs-attribute">podSelector</span>:
<span class="hljs-attribute">matchLabels</span>:
<span class="hljs-attribute">app-component</span>: database
<span class="hljs-attribute">policyTypes</span>:
- Ingress
- Egress
<span class="hljs-attribute">ingress</span>:
- <span class="hljs-attribute">from</span>:
- <span class="hljs-attribute">ipBlock</span>:
<span class="hljs-attribute">cidr</span>: <span class="hljs-number">172.17</span>.<span class="hljs-number">0.0</span>/<span class="hljs-number">16</span>
- <span class="hljs-attribute">podSelector</span>:
<span class="hljs-attribute">matchLabels</span>:
<span class="hljs-attribute">app-component</span>: api
<span class="hljs-attribute">ports</span>:
- <span class="hljs-attribute">protocol</span>: TCP
<span class="hljs-attribute">port</span>: <span class="hljs-number">3306</span>
<span class="hljs-attribute">egress</span>:
- <span class="hljs-attribute">to</span>:
- <span class="hljs-attribute">ipBlock</span>:
<span class="hljs-attribute">cidr</span>: <span class="hljs-number">172.17</span>.<span class="hljs-number">0.0</span>/<span class="hljs-number">16</span>
- <span class="hljs-attribute">podSelector</span>:
<span class="hljs-attribute">matchLabels</span>:
<span class="hljs-attribute">app-component</span>: api
<span class="hljs-attribute">ports</span>:
- <span class="hljs-attribute">protocol</span>: TCP
<span class="hljs-attribute">port</span>: <span class="hljs-number">3306</span>

该策略规定,只有标有 app-component: api 的 Pod 可以与标有 app-component: database 的 Pod 通信。

策略可以包括多个 Ingress 和 Egress 规则,也可以选择完全忽略一种流量类型。如果流量类型被排除在外,过滤则不适用。如果多个网络策略针对一个 Pod,那么流量需要满足组合列表中的每一条规则。

为所有 Pod 设置网络策略是一种良好做法。这样有助于防止受到攻击的 Pod 向群集中的其他工作负载发送恶意流量。虽然默认情况下流量不进行过滤,但您可以创建名称空间级的 deny all 规则,防止与缺乏更具体策略的 Pod 进行通信:

<span class="hljs-symbol">apiVersion:</span> networking.k8s.io/v1
<span class="hljs-symbol">kind:</span> NetworkPolicy
<span class="hljs-symbol">metadata:</span>
<span class="hljs-symbol"> name:</span> deny-all
<span class="hljs-symbol">spec:</span>
<span class="hljs-symbol"> podSelector:</span> {}
<span class="hljs-symbol"> policyTypes:</span>
- Ingress
- Egress

Secrets 和 ConfigMap

Kubernetes 集群中的工作负载经常使用到机密信息,如数据库密码和 API 密钥。这些值一旦暴露,就会构成严重的安全威胁。Kubernetes ConfigMap 对象是向 Pod 提供键值数据的标准方式。它们封装了 Pod 所需的任意配置值。

下面是带有几个数据字段的简单 ConfigMap 的 YAML 定义:

<span class="hljs-symbol">apiVersion:</span> v1
<span class="hljs-symbol">kind:</span> ConfigMap
<span class="hljs-symbol">metadata:</span>
<span class="hljs-symbol"> name:</span> app-config
<span class="hljs-symbol">data:</span>
<span class="hljs-symbol"> default_auth_token_lifetime:</span> <span class="hljs-number">900</span>
<span class="hljs-symbol"> default_user_name:</span> <span class="hljs-string">"admin"</span>
<span class="hljs-symbol"> external_auth_enabled:</span> true

你可以在 Pod 中以环境变量或挂载卷的形式使用 ConfigMap。前一种策略允许你通过访问命名的环境变量来检索 ConfigMap 密钥的值,而后一种策略则使用挂载卷将 ConfigMap 的内容存入容器文件系统中的文件。

由于 ConfigMap 数据是以纯文本形式未加密存储的,因此用户不会将其用于密码和 API 密钥等用途。相反,在与敏感数据交互时,请创建一个 Secret 对象。Secrets 对象的工作原理与 ConfigMap 类似,但它们是专为更安全的凭证处理而设计的。Secrets 对象默认以 Base64 编码显示值,并将其与应用程序的常规配置分开,从而降低了无意暴露的风险。这样就能最大限度地降低意外暴露的风险。

你可以在启动集群时配置 Kubernetes API 服务器,选择启用 Secrets 数据加密。

Kubernetes 中的监控和日志记录

继安全性之后,有效的监控和日志记录功能应成为 Kubernetes 的下一个优先事项。对工作负载性能的良好可见性能让你在新出现的问题造成更大问题之前快速做反应。您可以使用指标警报日志来跟踪集群活动。

Metrics API

Kubernetes Metrics Server 是一个可以安装在集群中的插件。它提供一个 API,用于从节点和 Pod 中提取资源利用率数据。

运行以下 kubectl 命令来部署 Metrics Server:

$ kubectl apply -f https:<span class="hljs-regexp">//gi</span>thub.com<span class="hljs-regexp">/kubernetes-sigs/m</span>etrics-server<span class="hljs-regexp">/releases/</span>latest<span class="hljs-regexp">/download/</span>components.yaml

安装完成后,使用 kubectl top 查看集群节点和 Pod 的 CPU 和内存利用率:

$ kubectl top nodes
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
minikube <span class="hljs-number">265</span>m
<span class="hljs-number">6</span>%
<span class="hljs-number">640</span>Mi
<span class="hljs-number">8</span>% $ kubectl top pod
NAME CPU(cores) MEMORY(bytes)
nginx <span class="hljs-number">0</span>m
<span class="hljs-number">4</span>Mi

Kube State Metrics 是另一个度量数据源。它提供与集群内对象相关的指标,如运行中的部署、失败的 Pod 和有效任务的数量。

警报和仪表板

如果你必须手动查询才能获得所需的信息,那么度量指标就不会特别有用。而设置警报和仪表板可确保您了解重要的集群事件,如资源利用率攀升或 Pod 出现故障

Kubernetes 项目没有为这些功能提供内置解决方案。因此最好部署一个专用的可观察性平台,如 Prometheus。Prometheus 的 Alertmanager 可以在特定事件发生时向通信平台发送通知。将 Prometheus 与 Grafana 等仪表盘工具搭配使用,可将数据可视化并发现指标趋势。

设置操作仪表盘是监控集群的有效方法,可让您对 Kubernetes 和应用程序的健康状况和性能一目了然。

日志整合

显然,了解指标变化或 Pod 失效的原因至关重要,应用程序生成的日志应该能揭示这些信息。

您可以使用 kubectl logs 命令按 Pod 检索日志,但使用 Fluentd、Logstash 或 Loki 等整合工具可以更轻松地收集、过滤和归档记录。这些解决方案能将集群中的日志流式传输到单独的存储平台,以供长期参考。

日志整合还能让搜索日志和分析重复消息变得更容易。它们会对报文内容进行索引,因此您无需使用 shell 工具手动解析日志,就能对其进行查询。这有助于您发现应用程序中的新错误,追踪问题的根本原因,并在出现异常时及时发现。

总 结

本系列由两部分组成,介绍了 Kubernetes 的基础知识,包括为什么它是开发人员亟需的技能,以及它的抽象如何有效地模拟不同的应用组件。通过该文章,您应该已经了解了如何创建部署、设置网络和安全以及监控集群内的工作负载。

无论您是从事开发还是运维工作,Kubernetes 知识都很有价值。它能让你更深入地了解云原生应用如何在生产中运行、操作员为何偏爱某些技术、哪里可能出现问题,以及您的系统如何映射到基础设施资源。当然,使用本地 Kubernetes 集群进行开发也有助于避免环境之间的差异

参考链接

https://komodor.com/blog/a-software-developers-guide-to-getting-started-with-kubernetes-part-1/

软件开发人员 Kubernetes 入门指南|Part 2的更多相关文章

  1. Let’s do this!新手程序员的入门指南(转)

    计算机科学(Computer Science)无疑是现在最热门的学科之一,这领域的工作薪水高.工作时间弹性,而且科技业对工程师.开发者的需求至今有增无减,科技龙头们随时虎视眈眈着出色的程式开发者.创意 ...

  2. Java程序员的Golang入门指南(下)

    Java程序员的Golang入门指南(下) 4.高级特性 上面介绍的只是Golang的基本语法和特性,尽管像控制语句的条件不用圆括号.函数多返回值.switch-case默认break.函数闭包.集合 ...

  3. Java程序员的Golang入门指南(上)

    Java程序员的Golang入门指南 1.序言 Golang作为一门出身名门望族的编程语言新星,像豆瓣的Redis平台Codis.类Evernote的云笔记leanote等. 1.1 为什么要学习 如 ...

  4. ReactJS入门指南

    ReactJS入门指南 本文旨在介绍ReactJS的基本知识,并一步步详细介绍React的基本概念和使用方法等,以及相应的Demo.本文在很大程度上参考了React官方文档和官方指南.如果你英语还不错 ...

  5. Microsoft Orleans 之 入门指南

    Microsoft Orleans 在.net用简单方法构建高并发.分布式的大型应用程序框架. 原文:http://dotnet.github.io/orleans/ 在线文档:http://dotn ...

  6. web前端基础知识及快速入门指南

    web前端基础知识及快速入门指南 做前端开发有几个月了,虽然说是几个月,但是中间断断续续的上课.考试以及其它杂七杂八的事情,到现在居然一直感觉自己虽然很多前端的知识很眼熟,却也感觉自己貌似也知识在门口 ...

  7. (转载)李剑英的CSLight入门指南结合NGUI热更新

    原地址:http://www.xuanyusong.com/archives/3075 李剑英的CSLight入门指南文档撰写者:GraphicQQ: 1065147807 一. CSLIGHT 作者 ...

  8. 【转】tmux入门指南

    按照官方说明,tmux是一个终端复用软件.我接触tmux也就是这几天的事情,但已经发现其强大.作为一个文艺程序员,有必要向大家分享一下,这么好的东东怎敢藏着掖着. 先用起来再说 假设你已经装好tmux ...

  9. ASP.NET SignalR 2.0入门指南

    ASP.NET SignalR 2.0入门指南 介绍SignalR ASP.NET SignalR 是一个为 ASP.NET 开发人员的库,简化了将实时 web 功能添加到应用程序的过程.实时Web功 ...

  10. CI Weekly #21 | iOS 持续集成快速入门指南

    搭建 iOS 持续集成环境要多久?每个 iOSer 都有不同的答案.这次我们整理了 flow.ci 的 iOS 持续集成的相关文档和最佳实践,希望帮你更快地完成构建.更新文档见: flow.ci iO ...

随机推荐

  1. Maven进阶

    前言 在项目开发的过程中,我们通常要使用到外部依赖的组件,同时也会使用某些插件来帮助我们管理项目.例如,我们访问数据库的时候需要使用到jdbc组件,我们可以下载对应的jar包去加载到我们的应用中.在我 ...

  2. 聊聊Excel解析:如何处理百万行EXCEL文件

    一.引言 Excel表格在后台管理系统中使用非常广泛,多用来进行批量配置.数据导出工作.在日常开发中,我们也免不了进行Excel数据处理. 那么,如何恰当地处理数据量庞大的Excel文件,避免内存溢出 ...

  3. Day02_Java_作业

    A:选择题 1. 若有定义:int a,b; a=a+10;则执行上述语句后,a的值是(d). A. 10 B. 11 C. 0 D. 编译产生错误 2. 以下选项中变量均已正确定义,合法的赋值语句是 ...

  4. [CF 1780B] GCD Partition

    B. GCD Partition 题意 : 给一个长度为n的序列, 并将其分成连续的k块(k > 1), 得到序列b, 使得 \(gcd(b_{1}, b_{2}, b_{3}, ..., b_ ...

  5. java_web:jdbc里的零碎笔记

    name="%"+name+"%"; 这段代码是用于构建SQL语句中的模糊查询条件的,其中name是一个字符串类型的变量,表示查询的关键字. %是通配符,在SQ ...

  6. FireflySoft.LeaderElection增加基于ZooKeeper的Leader选举

    FireflySoft.LeaderElection的第一个版本实现了基于Consul的Leader选举,考虑到ZooKeeper的一个常见用途也是选主,所以此类库把ZooKeeper也集成了进来.并 ...

  7. ITIL4与Devops(一)

    目录 一.服务管理与ITIL 1.1 服务管理现状 1.2 服务管理原则 1.3 ITIL版本发展历程 ITIL2 服务支持 服务交付 服务战略 ITIL3 框架 职能 ITIL 2011 流程的基本 ...

  8. 【Go blog】Govulncheck v1.0.0 发布了!

    我们很高兴地宣布,govulncheck v1.0.0 已经发布,同时也发布了用于集成扫描到其他工具的 API 的 v1.0.0 版本!Go 对漏洞管理的支持首次在去年九月宣布.从那时起,我们做了一些 ...

  9. 黑马2023最新版Java学习路线和资料地址

    地址:https://pan.baidu.com/s/1LxIxcHDO7SYB96SE-GZfuQ 提取码:dor4

  10. 【技术积累】Linux中的命令行【理论篇】【五】

    arpd命令 命令介绍 arpd命令是Linux系统中的一个网络工具,用于管理和操作ARP(地址解析协议)缓存.ARP协议用于将IP地址映射到MAC地址,以便在局域网中进行通信. 命令说明 arpd命 ...