K8s 之端口暴露(The Port of K8s is Exposed)

K8s 之端口暴露

Kubernetes 是一个用于管理容器化应用程序的流行工具。然而,关于它的工作原理存在一些误解。最常见的误解之一是关于 Kubernetes Pod 中的端口暴露。本文将解释 Kubernetes 中端口暴露的真相。

1 误解

像许多 Kubernetes 新手一样,我最初认为只有在 Pod 清单中指定的端口才会被暴露和访问。YAML 文件中的 ports 字段似乎是一个定义哪些端口应该被打开的自然位置,就像配置传统防火墙一样。这种假设让我认为任何未明确声明的端口都将被关闭且无法访问。

这种误解是可以理解的。毕竟,在许多其他系统中,明确定义开放端口是一种常见的安全实践。然而,对于 Kubernetes 来说,情况有所不同。

2  Kubernetes 网络的实际工作原理

要理解 Kubernetes 中的端口暴露,我们首先需要了解 Kubernetes 网络的基础知识。Kubernetes 遵循一种扁平网络模型,默认情况下,所有 Pod 都可以相互通信,无论它们运行在哪个节点上。这是通过容器网络接口(CNI)实现的,CNI 是一个为容器设置网络的插件。

在这种模型中,每个 Pod 在集群网络中都有自己的 IP 地址。这个 IP 地址在集群内是完全可路由的,这意味着任何 Pod 都可以使用该 IP 地址访问其他 Pod。

3 端口暴露的真相

关键点如下:

在 Kubernetes 中,默认情况下,集群网络内的所有端口都是潜在可访问的。

Pod 或容器清单中的 ports 字段主要用于文档和服务发现目的。它实际上并不限制或控制对这些端口的网络流量。

这意味着,如果你的容器中的进程正在监听某个端口,那么该端口可以从集群中的其他 Pod 访问,无论你是否在 YAML 清单中指定了它。

4 行为演示

让我们通过一个实际示例来说明这种行为:我们将创建一个简单的 Pod,运行一个监听端口 8080、9090 和 5000 的 Python 应用程序。

import http.server
import socketserver
from http.server import SimpleHTTPRequestHandler
import threading

class CustomHandler(SimpleHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-type', 'text/plain')
        self.end_headers()
        response = f"Hello from port {self.server.server_address[1]}!"
        self.wfile.write(response.encode())

def run_server(port):
    with socketserver.TCPServer(("", port), CustomHandler) as httpd:
        print(f"Serving on port {port}")
        httpd.serve_forever()

if __name__ == "__main__":
    ports = [8080, 9090, 5000]
    threads = []
    for port in ports:
        thread = threading.Thread(target=run_server, args=(port,))
        threads.append(thread)
        thread.start()

    for thread in threads:
        thread.join()

然后我们创建 Dockerfile 来打包它:

FROM python:3.9-slim

WORKDIR /app

COPY multi_ports.py .

CMD ["python", "multi_ports.py"]

之后,我们构建它并将其推送到一个容器注册表,稍后我们可以从集群中拉取它——在这个示例中是一个公共的 AWS ECR:

docker buildx build --platform linux/amd64,linux/arm64 -t public.ecr.aws/t1i1g9m6/multi-port-app:latest --push .

然后我们创建部署清单并仅指定端口 8080:

apiVersion: apps/v1
kind:Deployment
metadata:
name:multi-port-app
spec:
replicas:1
selector:
    matchLabels:
      app:multi-port-app
template:
    metadata:
      labels:
        app:multi-port-app
    spec:
      containers:
      -name:multi-port-app
        image:public.ecr.aws/t1i1g9m6/multi-port-app
        ports:
        -containerPort:8080
---
apiVersion:v1
kind:Service
metadata:
name:multi-port-app-service
spec:
selector:
    app:multi-port-app
ports:
    -protocol:TCP
      port:8080
      targetPort:8080

最后我们部署它:

kubectl apply -f kubernetes-ports-exposure/multi_ports_dep_svc.yaml

一旦 Pod 启动并运行,我们可以通过运行一个 curler Pod 来检查端口:

kubectl run curler-pod --image=curlimages/curl --restart=Never -- sleep infinity

并查看应用程序 Pod 暴露的端口:

kubectl exec -it curler-pod -- curl http://<pod-ip>:<port>

输出:

图片

如你所见,端口 9090 和 5000 也是开放并监听的,尽管我们只在清单中指定了端口 8080。

5 控制端口访问

那么,如果 ports 字段不控制访问,我们如何保护我们的应用程序呢?

这就是 Kubernetes 网络策略的用武之地。

网络策略允许你定义规则,指定哪些 Pod 可以相互通信以及使用哪些端口。它们充当 Pod 的防火墙,为你提供对集群网络流量的细粒度控制。

图片

以下是一个简单的网络策略示例,仅允许对先前应用程序的端口 8080 的传入流量:

apiVersion: networking.k8s.io/v1
kind:NetworkPolicy
metadata:
name:allow-only-8080
spec:
podSelector:
    matchLabels:
      app:multi-port-app
policyTypes:
-Ingress
ingress:
-from:
    -podSelector:{}
    ports:
    -protocol:TCP
      port:8080

此策略将允许来自同一命名空间中任何 Pod 的端口 8080 的传入连接,同时阻止对所有其他端口的连接。

6 最佳实践

鉴于这种行为,以下是一些需要牢记的最佳实践:

  1. 不要依赖端口规范来确保安全:记住,Pod 规范中的 ports 字段是用于文档和服务发现的,而不是访问控制。

  2. 使用网络策略:实施网络策略以明确定义允许的流量。

  3. 遵循最小权限原则:只打开应用程序功能所需的端口。

  4. 定期审计你的集群:使用工具扫描意外开放的端口或配置错误。

  5. 注意你的基础镜像:了解容器镜像中活动的进程和端口。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

操作系统2.4

一、死锁&#xff0c;饥饿&#xff0c;死循环 死锁&#xff1a;各进程互相等待对方手里的资源&#xff0c;导致各进程都阻塞&#xff0c;无法向前推进的现象 饥饿&#xff1a;由于长期得不到想要的资源&#xff0c;某进程无法向前推进的现象&#xff0c;例如&#xff1a;短进…

解决DeepSeek服务器繁忙问题的实用指南

目录 简述 1. 关于服务器繁忙 1.1 服务器负载与资源限制 1.2 会话管理与连接机制 1.3 客户端配置与网络问题 2. 关于DeepSeek服务的备用选项 2.1 纳米AI搜索 2.2 硅基流动 2.3 秘塔AI搜索 2.4 字节跳动火山引擎 2.5 百度云千帆 2.6 英伟达NIM 2.7 Groq 2.8 Firew…

c++进阶———继承

1.引言 在一些大的项目中&#xff0c;我们可能要重复定义一些类&#xff0c;但是很麻烦&#xff0c;应该怎么办呢&#xff1f;举个简单的例子&#xff0c;我要做一个全校师生统计表&#xff0c;统计学号&#xff0c;教师编号&#xff0c;姓名&#xff0c;年龄&#xff0c;电话…

Android 平台GB28181设备接入实战指南

一、引言 随着视频监控技术的不断发展&#xff0c;国标 GB28181 协议在安防监控领域得到了广泛应用。该协议为不同厂家的视频监控设备之间的互联互通提供了统一的规范&#xff0c;使得设备的接入与管理变得更加简单和高效。在 Android 平台上实现 GB28181 设备接入&#xff0c…

细说Java 引用(强、软、弱、虚)和 GC 流程(一)

一、引用概览 1.1 引用简介 JDK1.2中引入了 Reference 抽象类及其子类&#xff0c;来满足不同场景的 JVM 垃圾回收工作&#xff1a; SoftReference 内存不足&#xff0c;GC发生时&#xff0c;引用的对象&#xff08;没有强引用时&#xff09;会被清理&#xff1b;高速缓存使用…

基于图像处理的裂缝检测与特征提取

一、引言 裂缝检测是基础设施监测中至关重要的一项任务,尤其是在土木工程和建筑工程领域。随着自动化技术的发展,传统的人工巡检方法逐渐被基于图像分析的自动化检测系统所取代。通过计算机视觉和图像处理技术,能够高效、精确地提取裂缝的几何特征,如长度、宽度、方向、面…

android ViewPager 管理 Fragment的预加载onCreate

一、前言 当ViewPager 加载多个 Fragment时候&#xff0c;怎么管理Fragment预加载。因为有些数据需要提前加载&#xff0c;第一个方便后面数据使用&#xff0c;提前初始化。或者预加载网络数据等。 二、实现示例 在onCreate方法进行数据预加载。如果在onCreateView函数里面&…

云计算架构学习之Ansible-playbook实战、Ansible-流程控制、Ansible-字典循环-roles角色

一、Ansible-playbook实战 1.Ansible-playbook安装软件 bash #编写yml [rootansible ansible]# cat wget.yml - hosts: backup tasks: - name: Install wget yum: name: wget state: present #检查playbook的语法 [rootansible ansible]…

Redis常用命令合集【二】

在合集【一】中已经介绍了redis中String类型和Hash类型&#xff0c;接下来就继续介绍剩下的List、Set、SortedSet类型。 1.List类型 Redis中的List类型与Java中的LinkedList类似&#xff0c;可以看做是一个双向链表结构。既可以支持正向检索和也可以支持反向检索。 特征也与…

挑战用Cursor实现“Cursor“的第二天

挑战用Cursor实现"Cursor"的第二天 项目地址 &#xff1a;https://github.com/Ez4Sterben/Ez4Code/tree/master 省流&#xff08;困了想睡觉了&#xff0c;就不多描述了&#xff09;&#xff1a; 干了1小时&#xff0c;文件树没问题了&#xff0c;代码能编辑了&…

已解决IDEA无法输入中文问题(亲测有效)

前言 在使用IDEA的时候&#xff0c;比如我们想写个注释&#xff0c;可能不经意间&#xff0c;输入法就无法输入中文了&#xff0c;但是在其他地方打字&#xff0c;输入法仍然能够正常工作。这是什么原因呢&#xff0c;这篇文章带你解决这个问题&#xff01; 快捷键 如果你的I…

阿里云上的网站配置HTTPS

1. 获取SSL证书 创建证书 下载证书 下载 上传 .key .pem 文件 到 阿里云服务器 /etc/nginx/ssl nginx.conf 配置 server { listen 443 ssl; server_name yuming; ssl_certificate /etc/nginx/ssl/*.pem; ssl_certificate_key /etc/nginx/ssl/*.key;

在Unity中用简单工厂模式模拟原神中的元素反应

1. 第一步创建3个脚本Factory&#xff08;反应工厂&#xff09;&#xff0c;Reactions&#xff08;具体反应&#xff09;&#xff0c;FactoryText&#xff08;测试反应的脚本&#xff09; 2.编写工厂脚本 using UnityEngine;// 定义一个元素反应的接口&#xff0c;所有具体的元…

数组和指针常见笔试题(深度剖析)

下边我来讲一下常见的面试题&#xff0c;过程很详细放心观看 #include<stdio.h>#include <string.h>int main() {char arr[] { a,b,c,d,e,f };printf("%d\n", strlen(arr));//随机值&#xff0c;因为strlen是遇到斜杠\0结束&#xff0c;统计\0之前的字符…

懒人精灵本地离线卡密验证系统教程(不联网、安全稳定、省钱、永久免费、无任何限制)

1.合集懒人精灵本地离线卡密验证系统教程(不联网、安全稳定、省钱、永久免费、无任何限制)&#xff1a;https://www.bilibili.com/video/BV1M6rdYEEog/ 备注&#xff1a; 1.本地离线卡密采用最安全的非对称加解密技术&#xff0c;设备id采用最安全多重混合加密不可逆技术生成&…

实战开发coze应用-姓氏头像生成器(上)

​欢迎关注【AI技术开发者】 上次&#xff0c;我们开发了一个对话形式的头像生成器智能体&#xff08;Agents&#xff09;&#xff0c;广受大家欢迎。 同时也接收到一些用户的反馈&#xff0c;生成前无法看到头像样式、初次使用不会用等等。 对此&#xff0c;我准备使用Coze开…

达梦:用户和模式

目录标题 数据库管理系统与用户权限管理**四权分立****用户管理与权限划分****用户管理界面与权限控制****用户创建与管理****实操**1. **默认创建用户与模式**&#xff1a;2. **用户权限和角色分配**&#xff1a;3. **命令行管理用户与角色**&#xff1a;4. 模式也可以创建 **…

【C++】类与对象全面剖析(尾卷)(构造深化、类型转换、static成员特性及内部类与匿名对象)

文章目录 一、再探构造函数二、隐式类型转换三、类中的静态成员1.静态成员变量2.静态成员函数 四、友元函数与友元类五、内部类六、匿名对象 一、再探构造函数 在之前的文章中我们大致将构造函数讲完了&#xff0c;但是还有一个比较重要的知识点当时没有讲到&#xff0c;因为如…

【部署优化篇四】《DeepSeek移动端优化:CoreML/TFLite实战对比》

手机里的AI助手能秒速回答你的问题,游戏人物能实时追踪你的表情变化,这些酷炫功能的背后都离不开移动端机器学习框架的支撑。今天我们就来撕开两个当红炸子鸡框架CoreML和TFLite的神秘面纱,看看它们在模型优化这件事上到底藏着哪些独门绝技。 一、移动端优化的生存法则 在…

SAM C++ TensorRT(实时图像分割)

SPEED SAM C TENSORRT &#x1f310; 1、概述 用于SAM&#xff08;segment anything model分割一切模型&#xff09;的TensorRT和CUDA优化的高表现C实现&#xff0c;特别适用于实时图像分割任务。 &#x1f4e2; 更新 模型转换&#xff1a;从ONNX模型构建TensorRT引擎以加速…