当前位置: 首页 > news >正文

使用 Kubernetes 运行 non-root .NET 容器

翻译自 Richard Lander 的博客

Rootless 或 non-root Linux 容器一直是 .NET 容器团队最需要的功能。我们最近宣布了所有 .NET 8 容器镜像都可以通过一行代码配置为 non-root 用户。今天的文章将介绍如何使用 Kubernetes 处理 non-root 托管。

您可以尝试使用我们的 non-root Kubernetes 示例在集群上托管 non-root 容器。它是我们正在处理的一组更大的 Kubernetes 示例的一部分。

runAsNonRoot

我们将要讨论的大部分内容都与 Kubernetes 清单的 SecurityContext 部分有关。它包含 Kubernetes 应用的安全配置。

spec:      containers:      - name: aspnetapp        image: dotnetnonroot.azurecr.io/aspnetapp        securityContext:          runAsNonRoot: true

此 securityContext 对象验证容器将以 non-root 用户运行。

runAsNonRoot 测试用户(通过 UID)是 non-root 用户(> 0),否则 pod 创建将失败。Kubernetes 仅为该测试读取容器镜像元数据。它不会读取/etc/passwd,因为这需要启动容器(这违背了测试的目的)。这意味着 USER(在 Dockerfile 中)必须由 UID 设置。如果 USER 按名称设置,将会失败。

我们可以使用 docker inspect 模拟相同的测试。

% docker inspect dotnetnonroot.azurecr.io/aspnetapp -f "{{.Config.User}}"64198

我们的示例镜像通过 UID 设置用户。但是,whoami 仍会将用户报告为应用程序。

runAsUser 是一个相关的设置,尽管在上面的示例中没有使用。只有当容器镜像未设置 USER、通过名称而非 UID 进行设置,或者其他情况不需要时,才应该使用 runAsUser。我们已经让使用新应用程序用户作为 UID 变得非常容易,这样 .NET 应用程序应该会不再需要 runAsUser了。

USER 最佳实践

我们建议在 Dockerfile 中设置 USER 时使用以下模式。

USER $APP_UID

USER 指令通常放在 ENTRYPOINT 之前,尽管顺序无关紧要。此模式导致 USER 被设置为 UID,同时避免在 Dockerfile 中使用幻数。环境变量已经定义了 .NET 镜像声明的 UID 值。

您可以看到 .NET 镜像中设置的环境变量。​​​​​​​

% docker run mcr.microsoft.com/dotnet/runtime-deps:8.0-preview bash -c "export | grep UID"declare -x APP_UID="64198"

non-root 示例根据此模式通过 UID 设置用户。因此,它适用于 runAsNonRoot。

non-root 托管

让我们看看使用 non-root Kubernetes 示例进行 non-root 容器托管的体验。

我们正在为本地集群使用 minikube,但任何兼容 Kubernetes 的环境都应该能很好地与 kubectl 配合使用。​​​​​​​

$ kubectl apply -f https://raw.githubusercontent.com/dotnet/dotnet-docker/main/samples/kubernetes/non-root/non-root.yamldeployment.apps/dotnet-non-root createdservice/dotnet-non-root created$ kubectl get poNAME                           READY   STATUS    RESTARTS   AGEdotnet-non-root-68f4cd45c-687zp   1/1     Running   0          13s

该应用程序正在运行。让我们检查一下用户。​​​​​​​

$ kubectl exec dotnet-non-root-68f4cd45c-687zp -- whoamiapp

我们也可以在应用程序上调用一个端点。首先,我们需要创建一个代理来连接它。

% kubectl port-forward service/dotnet-non-root 8080

我们现在可以调用端点,它也将用户报告为 app。​​​​​​​

% curl http://localhost:8080/Environment{"runtimeVersion":".NET 8.0.0-preview.3.23174.8","osVersion":"Linux 5.15.49-linuxkit #1 SMP PREEMPT Tue Sep 13 07:51:32 UTC 2022","osArchitecture":"Arm64","user":"app","processorCount":4,"totalAvailableMemoryBytes":4124512256,"memoryLimit":0,"memoryUsage":35004416}

删除资源。​​​​​​​

$ kubectl delete -f https://raw.githubusercontent.com/dotnet/dotnet-docker/main/samples/kubernetes/non-root/non-root.yamldeployment.apps "dotnet-non-root" deletedservice "dotnet-non-root" deleted

在撰写本文时,官方示例尚未移动到使用 non-root 用户。当我们将示例移动到 .NET 8 时,可能 .NET 8 RC1,我们会这样做。可以使用 aspnetapp 镜像来演示当 runAsNonRoot 与使用 root 的镜像一起使用时会发生什么。它应该失败,对吧?稍微更改一下清单,让我们从没有 securityContext 部分开始。​​​​​​​

  spec:      containers:      - name: aspnetapp

检查一下用户。​​​​​​​

$ kubectl apply -f non-root.yamldeployment.apps/dotnet-non-root createdservice/dotnet-non-root created$ kubectl get poNAME                            READY   STATUS    RESTARTS   AGEdotnet-non-root-85768f6c55-pb5gh   1/1     Running   0          1s$ kubectl exec dotnet-non-root-85768f6c55-pb5gh -- whoamiroot

不出所料。现在,把 runAsNonRoot 加回来。​​​​​​​

spec:      containers:      - name: aspnetapp        image: mcr.microsoft.com/dotnet/samples:aspnetapp        securityContext:          allowPrivilegeEscalation: false          runAsNonRoot: true​​​​​​​
$ kubectl apply -f non-root.yamldeployment.apps/dotnet-non-root createdservice/dotnet-non-root created$ kubectl get poNAME                            READY   STATUS                       RESTARTS   AGEdotnet-non-root-6df9cb77d8-74t96   0/1     CreateContainerConfigError   0          5s

失败了,但就是我们想要的。我们可以更多地了解下原因。​​​​​​​

$ kubectl describe po | grep Error      Reason:       CreateContainerConfigError  Warning  Failed     7s (x2 over 8s)  kubelet            Error: container has runAsNonRoot and image will run as root (pod: "dotnet-non-root-6df9cb77d8-74t96_default(d4df0889-4a69-481a-adc4-56f41fb41c63)", container: aspnetapp)

我们可以尝试 kubectl exec 到 pod,但它会失败。这表明 Kubernetes 阻止了容器的创建(如错误状态所示)。​​​​​​​

$ kubectl exec dotnet-non-root-6df9cb77d8-74t96 -- whoamierror: unable to upgrade connection: container not found ("aspnetapp")

dotnet-monitor

dotnet-monitor 是一种诊断工具,用于从正在运行的应用程序中捕获诊断工件。我们为其提供了一个 dotnet/monitor 容器镜像。它适用于 non-root 主机。

hello-dotnet Kubernetes 示例演示了以 non-root 用户身份运行的 ASP.NET 和 dotnet-monitor。它还继续演示如何在云端和本地收集 Prometheus 指标数据。

您可以通过几个简单的配置更改在 Kubernetes 中切换到 non-root 托管。您的应用程序将更加安全,对攻击也更具弹性。这种方法还使应用程序符合 Kubernetes Pod 强化最佳实践。这是一项小变革,但对深度防御有着巨大影响。

希望我们的容器安全计划能够让整个 .NET 容器生态系统都转向 non-root 托管,我们致力于使云中的 .NET 应用程序高效且安全。

 点我前往原博客~

相关文章:

使用 Kubernetes 运行 non-root .NET 容器

翻译自 Richard Lander 的博客 Rootless 或 non-root Linux 容器一直是 .NET 容器团队最需要的功能。我们最近宣布了所有 .NET 8 容器镜像都可以通过一行代码配置为 non-root 用户。今天的文章将介绍如何使用 Kubernetes 处理 non-root 托管。 您可以尝试使用我们的 non-root…...

为什么大量失业集中爆发在2023年?被裁?别怕!失业是跨越职场瓶颈的关键一步!对于牛逼的人,这是白捡N+1!...

被裁究竟是因为自身能力不行,还是因为大环境不行? 一位网友说: 被裁后找不到工作,本质上还是因为原来的能力就配不上薪资。如果确实有技术在身,根本不怕被裁,相当于白送n1! 有人赞同楼主的观点&…...

Word控件Spire.Doc 【脚注】字体(3):将Doc转换为PDF时如何使用卸载的字体

Spire.Doc for .NET是一款专门对 Word 文档进行操作的 .NET 类库。在于帮助开发人员无需安装 Microsoft Word情况下,轻松快捷高效地创建、编辑、转换和打印 Microsoft Word 文档。拥有近10年专业开发经验Spire系列办公文档开发工具,专注于创建、编辑、转…...

keil5使用c++编写stm32控制程序

keil5使用c编写stm32控制程序 一、前言二、配置图解三、std::cout串口重定向四、串口中断服务函数五、结尾废话 一、前言 想着搞个新奇的玩意玩一玩来着,想用c编写代码来控制stm32,结果在keil5中,把踩给我踩闷了,这里简单记录一下…...

中国社科院与美国杜兰大学金融管理硕士项目——在职读研的日子里藏着我们未来无限可能

人生充满期待,梦想连接着未来。每一天都可以看作新的一页,要努力去成为最好的自己。在职读研的光阴里藏着无限的可能,只有不断的努力,不断的强大自己,未来会因为你的不懈坚持而发生改变,纵使眼前看不到希望…...

hardhat 本地连接matemask钱包

Hardhat 安装 https://hardhat.org/hardhat-runner/docs/getting-started#quick-start Running a Local Hardhat Network Hardhat greatly simplifies the process of setting up a local network by having an in-built local blockchain which can be easily run through a…...

【华为OD机试真题】1001 - 在字符串中找出连续最长的数字串含-号(Java C++ Python JS)| 机试题+算法思路+考点+代码解析

文章目录 一、题目🔸题目描述🔸输入输出二、代码参考🔸Java代码🔸 C++代码🔸 Python代码🔸 JS代码作者:KJ.JK🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🍂个人博客首页: KJ.JK 💖系列专栏:华为OD机试(Java C++ Python JS)...

CrackMapExec 域渗透工具使用

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、CrackMapExec 是什么?二、简单使用1、获取帮助信息2、smb连接执行命令3、使用winrm执行命令(躲避杀软)4、smb 协议常用枚…...

Modbus协议学习

以下内容从参考文章学习提炼 [参考文章](https://www.cnblogs.com/The-explosion/p/11512677.html) ## 基本概念 Modbus用的是主从通讯技术,主设备操作查询从设备。可以通过物理接口,可选用串口(RS232、RS485、RS422)&#xff0c…...

camunda如何处理流程待办任务

在 Camunda 中处理流程任务需要使用 Camunda 提供的 API 或者用户界面进行操作。以下是两种常用的处理流程任务的方式: 1、通过 Camunda 任务列表处理任务:在 Camunda 任务列表中,可以看到当前需要处理的任务,点击任务链接&#…...

git部分文件不想提交解决方案

正确的做法应该是:git rm --cached logs/xx.log,然后更新 .gitignore 忽略掉目标文件,最后 git commit -m "We really dont want Git to track this anymore!" 具体的原因如下: 被采纳的答案虽然能达到(暂…...

2023年全国最新道路运输从业人员精选真题及答案58

百分百题库提供道路运输安全员考试试题、道路运输从业人员考试预测题、道路安全员考试真题、道路运输从业人员证考试题库等,提供在线做题刷题,在线模拟考试,助你考试轻松过关。 69.根据《公路水路行业安全生产风险管理暂行办法》,…...

Zimbra 远程代码执行漏洞(CVE-2019-9670)漏洞分析

Zimbra 远程代码执行漏洞(CVE-2019-9670)漏洞分析 漏洞简介 Zimbra是著名的开源系统,提供了一套开源协同办公套件包括WebMail,日历,通信录,Web文档管理和创作。一体化地提供了邮件收发、文件共享、协同办公、即时聊天等一系列解决…...

【数据结构初阶】第七节.树和二叉树的性质

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 前言 一、树 1.1 树的概念 1.2 树的结点分类 1.3 结点之间的关系 1.4 树的存储结构 1.5 其他相关概念 二、 二叉树 2.1 二叉树的概念 2.2 特殊的二叉树 2.3 二叉树的性质 2.4…...

车载软件架构——闲聊几句AUTOSAR BSW(一)

我是穿拖鞋的汉子,魔都中坚持长期主义的工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 人生是用来体验的,不是用来演绎完美的。我慢慢能接受自己身上那些灰暗的部分,原谅自己的迟钝和平庸,允许自己出错,允许自己偶尔断电,带着缺憾拼命绽放,…...

我国元宇宙行业分析:政策、技术、资金助推行业探索多元化应用场景

1.元宇宙行业概述、特征及产业链图解 元宇宙是人类运用数字技术构建的,由现实世界映射或超越现实世界,可与现实世界交互的虚拟世界,具备新型社会体系的数字生活空间,主要具有沉浸式体验、开放性、虚拟身份、不断演化、知识互动、…...

都已经那么卷了,用户还需要开源的 API 管理工具么

关于 API 管理工具,如今的市场已经把用户教育的差不多了,毫不夸张地说,如果我随机抽取一位幸运读者,他都能给我罗列出一二三四款大家耳熟能详的工具。可说到开源的 API 管理工具,大家又能知道多少呢? 我们是…...

工信部教育与考试中心-软件测试工程师考试题A卷-答

软件测试工程师考试题 姓名________________ 学号_________________ 班级__________________ 题号 一 二 三 四 五 总分 分数 说明:本试卷分五部分,全卷满分100分。考试用时100分钟。 注 意 事 项:1、本此考试为闭卷…...

【设计模式】模板方法模式--让你的代码更具灵活性与可扩展性

文章目录 前言模板方法模式的定义核心组成模板方法模式与其他设计模式的区别 代码实现抽象类具体类Client 经典类图spring中的例子 总结 前言 在软件开发中,设计模式是一种经过实践检验的、可复用的解决方案,它们可以帮助我们解决某一特定领域的典型问题…...

搞明白Redis持久化机制

Redis是一种内存数据库,其内存中的数据存储在计算机的内存中,如果服务器发生崩溃或者重启,内存中的数据将会丢失。为了避免这种情况发生,Redis提供了两种持久化机制:RDB和AOF。 一、RDB持久化 Redis支持将当前数据状…...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...

Git常用命令完全指南:从入门到精通

Git常用命令完全指南:从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...

LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用

中达瑞和自2005年成立以来,一直在光谱成像领域深度钻研和发展,始终致力于研发高性能、高可靠性的光谱成像相机,为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...

热烈祝贺埃文科技正式加入可信数据空间发展联盟

2025年4月29日,在福州举办的第八届数字中国建设峰会“可信数据空间分论坛”上,可信数据空间发展联盟正式宣告成立。国家数据局党组书记、局长刘烈宏出席并致辞,强调该联盟是推进全国一体化数据市场建设的关键抓手。 郑州埃文科技有限公司&am…...

Unity VR/MR开发-VR开发与传统3D开发的差异

视频讲解链接:【XR马斯维】VR/MR开发与传统3D开发的差异【UnityVR/MR开发教程--入门】_哔哩哔哩_bilibili...

DAY 45 超大力王爱学Python

来自超大力王的友情提示:在用tensordoard的时候一定一定要用绝对位置,例如:tensorboard --logdir"D:\代码\archive (1)\runs\cifar10_mlp_experiment_2" 不然读取不了数据 知识点回顾: tensorboard的发展历史和原理tens…...

【动态规划】B4336 [中山市赛 2023] 永别|普及+

B4336 [中山市赛 2023] 永别 题目描述 你做了一个梦,梦里有一个字符串,这个字符串无论正着读还是倒着读都是一样的,例如: a b c b a \tt abcba abcba 就符合这个条件。 但是你醒来时不记得梦中的字符串是什么,只记得…...