如何使用 Containerfile/Dockerfile 构建 .net 镜像?

news2024/9/24 3:29:35

Podman 简介

PodmanRed Hat 开发的一款容器管理工具,它允许用户在没有守护进程的情况下运行、构建、管理和推送容器。Podman 是一个无守护进程的容器引擎,这意味着它不需要一个持续运行的后台进程来管理容器,这与 Docker 的守护进程模式不同。Podman 支持 Open Container Initiative (OCI) 标准,可以与 Docker 镜像兼容,并且可以在大多数 Linux 平台上使用,包括 RHEL、Fedora、CentOS、Debian、Ubuntu、openEuler 等。

podman

Podman 的主要特点包括:

  • 无守护进程:Podman 不需要守护进程,可以直接通过命令行工具控制容器。
  • root 用户权限(Rootless):Podman 允许非 root 用户运行容器,只需要适当配置 SELinuxAppArmor
  • 容器组(Pods):Podman 支持容器组的概念,可以将多个容器作为一个整体进行管理,类似于 KubernetesPod 概念。
  • 容器持久化:即使重启系统,Podman 管理的容器状态也会被保存。
  • Podman 可以很好的过渡到 k8sk8s yaml 文件转换到 Podman 环境。

构建镜像知识回顾

Alpine 镜像及其常用工具简介

Alpine Linux 是一个基于 musl libcBusyBox 的轻量级 Linux 发行版,因此它的默认镜像非常小,只包含了运行系统所必需的基本工具和库。

Alpine 的默认镜像通常包括以下一些常用工具:

  • ash shell - 默认的 shell,它是 BusyBox 的一部分。
  • BusyBox - 包含了多种 Unix 工具的单个可执行文件,如 cat, cp, ls, grep, find, ifconfig, netstat, ping, telnet, wget, curl 等。
  • apk - Alpine 的包管理器,用于安装和升级软件包。
  • OpenSSH - 提供 SSH 服务,用于远程登录和文件传输。
  • mke2fse2fsprogs - 用于管理 ext2, ext3ext4 文件系统的工具。
  • iproute2 - 提供网络配置工具,如 ip 命令。
  • DNS resolver - 用于 DNS 查询的工具,如 host
  • libc6-compat - 提供 glibc 兼容性层,使得某些需要 glibc 的二进制文件可以运行。
  • ca-certificates - 提供预装的 SSL/TLS 证书,用于 HTTPS 连接验证。
  • musl - Alpine 使用的 libc 实现,提供了标准 C 库的功能。
  • Alpine 的镜像默认是非常精简的,如果需要额外的工具或库,你需要使用 apk add 命令来安装它们。例如,如果需要 Python,可以运行 apk add python3

由于 Alpine 的小尺寸和低资源消耗,它在容器和嵌入式设备中非常受欢迎。然而,它的轻量级特性也意味着对于某些复杂的应用场景可能需要手动安装更多的工具和库。

基镜像【aspnet:8.0-alpine】简介

mcr.microsoft.com/dotnet/aspnet:8.0-alpine 镜像是 Microsoft 提供的一个基于 Alpine Linux.NET Runtime 镜像,用于运行 .NET 8.0ASP.NET Core 应用。这个镜像主要包含了运行 .NET 8.0 应用所需的运行时组件,以及 Alpine Linux 的基础工具集。

使用 podman pull 命令下载镜像:

podman pull mcr.microsoft.com/dotnet/aspnet:8.0-alpine

具体来说,这个镜像会包含但不限于以下组件:

  • .NET 8.0 运行时 - 用于执行 .NET 8.0 的应用程序。
  • Alpine Linux - 一个轻量级的 Linux 发行版,它使用 musl libcBusyBox
  • BusyBox - 一个集合了众多常见 Unix 工具的小型可执行文件,例如:cat, cp, ls, grep, find, ifconfig, netstat, ping, telnet, wget, curl 等。
  • APK - Alpine 的包管理器,用于安装和管理软件包。
  • OpenSSH - 提供 SSH 服务,用于远程登录和文件传输。
  • DNS Resolver - 用于 DNS 查询的工具。
  • CA Certificates - 用于 HTTPS 连接验证的预装 SSL/TLS 证书。
  • musl libc - Alpine 使用的 libc 实现,提供了标准 C 库的功能。
  • iproute2 - 提供网络配置工具,如 ip 命令。

请注意,这个镜像主要关注于提供运行 .NET 8.0 应用所需的基础环境,因此它不会包含大量额外的工具或库。如果需要其他工具或库,比如数据库驱动、额外的编程语言或构建工具,你可能需要在 ContainerfileDockerfile 中使用 RUN apk add 命令进行安装。

为了确保镜像的轻量化和安全性,Microsoft 的官方镜像通常会避免包含不必要的软件,这样可以减少镜像的大小并降低潜在的安全风险。

如何构建 .NET 轻量级镜像?

构建轻量级的 .NET Core 镜像通常涉及到几个关键步骤,主要是选择正确的基础镜像、使用多阶段构建、优化文件结构以及清理不必要的文件。以下是详细的步骤:

  1. 选择基础镜像
  • 选择一个轻量级的基础镜像非常重要,因为它直接影响最终镜像的大小。对于 .NET Core,推荐使用以下基础镜像之一:
# 用于构建阶段,包含 SDK。
mcr.microsoft.com/dotnet/sdk:<version>-alpine 
# 用于最终运行时镜像,仅包含运行时。
mcr.microsoft.com/dotnet/aspnet:<version>-alpine
  • Alpine Linux 版本的镜像通常比基于 DebianUbuntu 的镜像更小,因为它们使用了更小的 libc 实现(musl libc)和 BusyBox 工具集。
  1. 多阶段构建
  • 多阶段构建允许你使用不同的 Dockerfile 阶段来构建和打包你的应用,这样可以将构建过程产生的中间文件和缓存从最终镜像中剔除,从而减小镜像大小。示例演示请查看后面的【镜像构建步骤】。
  1. 使用 .dockerignore 文件
  • .dockerignore 文件可以排除不需要的文件或目录,避免它们被添加到镜像中。例如,你可以排除 .git 目录、objbin 文件夹等。
  1. 清理不必要的文件
  • 在每个阶段的末尾,使用 RUN 命令来清理任何不再需要的文件,例如编译缓存或构建工具。
  1. 最终镜像优化
  • 确保最终镜像只包含运行应用程序所需的文件。使用 -o 参数指定输出目录,然后在最终镜像中只复制这个目录。

通过以上步骤,你可以构建出轻量级的 .NET Core 镜像,这对于云原生环境和资源受限的部署场景尤其重要。

镜像构建步骤

要使用 Containerfile(或 Dockerfile)构建 .NET Core.NET Framework 的应用(app)镜像,你可以遵循以下步骤。这里以 .NET Core 为例,因为 .NET Framework 的容器化通常需要更复杂的 Windows 基础镜像,而 .NET Core 则有轻量级的 Linux 镜像可供选择。

说明:.net core /.net8 使用 alpine 构建镜像可以减少一半镜像体积。

步骤 1: 创建 Containerfile

在你的项目根目录下创建一个名为 Containerfile 的文件(也可以命名为 Dockerfile)。这个文件将包含用于构建 Podman/Docker 镜像的所有指令。

步骤 2: 编写 Containerfile

下面是一个基本的 Containerfile 示例,用于构建 .NET Core 应用:

# 第一阶段:构建
# 使用官方的 .NET Core SDK 镜像作为基础镜像
FROM mcr.microsoft.com/dotnet/sdk:8.0-alpine AS build-env

# 设置工作目录
WORKDIR /app

# 指定后续指令的用户上下文
USER app

# 将当前目录的内容复制到容器中的 /app 目录
COPY ["./", "/app/"]

# 运行 dotnet restore 命令来下载所有依赖项
RUN dotnet restore 

# 使用 dotnet publish 命令构建应用程序发布文件
RUN dotnet publish -c Release -o out

# 第二阶段:最终镜像
# 使用更小的运行时镜像来部署应用
FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine

#  添加镜像的元数据,使用键值对的形式。为了在 LABEL 的值里面可以包含空格,你可以在命令行解析中使用引号和反斜杠
LABEL maintainer=“chait@qq.com” \
      description=“This is my .net app”

# 设置工作目录
WORKDIR /app

# 复制从第一阶段构建的输出
COPY --from=build-env /app/out .

# 声明容器运行时监听的特定网络端口,指定监听协议是TCP还是UDP,若未指定协议,则默认为TCP。
EXPOSE [8080/tcp, 443/tcp]

# 在容器内部设置环境变量
ENV ASPNETCORE_ENVIRONMENT=Production \
    ASPNETCORE_URLS=http://+:8080;https://+:443;
 
# 设置时间
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# 创建匿名数据卷挂载点
VOLUME ["/wwwroot/resource","/AppData/Configuration","/AppData/Database"] 

# 设置入口点,容器创建时的主要命令(不可被覆盖)
ENTRYPOINT ["dotnet", "YourAppName.dll"]
  • 命令解释(LABEL/ENV/RUN

一个镜像可以有多个 labelsENV/RUN 类似)。你可以组合多个 labels 在一个 LABEL 里来指定多重 labels。在Docker 1.10 之前,这种做法可以降低最终镜像的大小,但现在不是这样。你仍然可以选择一个指令指定多个labels,使用以下的 2 种方法中其中一种:

LABEL maintainer=“chait@qq.com” \
      description=“This is my .net app”
# or
LABEL maintainer=“chait@qq.com” description=“This is my .net app”

Labels 包含在基镜像或者父母镜像(在 FROM 行的镜像)继承到你的镜像。如果 label 本身已经存在但是值不一样,最后的赋值将会覆盖前面的复制。

如果要查看镜像的 labels,可以使用 podman inspect 命令。

"Labels": {
    "com.example.vendor": "ACME Incorporated"
    "com.example.label-with-value": "foo",
    "version": "1.0",
    "description": "This text illustrates that label-values can span multiple lines.",
    "multi.label1": "value1",
    "multi.label2": "value2",
    "other": "value3"
},
  • 命令解释(VOLUME

运行容器时可以从本地主机或其他容器挂载数据卷,一般用来存放数据库和需要保持的数据等;

VOLUME ["/wwwroot/resource","/AppData/Configuration","/AppData/Database"] 

注意:必须使用双引号,不能使用单引号。

这里的 ["/wwwroot/resource","/AppData/Configuration","/AppData/Database"] 目录就会在运行时自动挂载为匿名卷,任何向 ["/wwwroot/resource","/AppData/Configuration","/AppData/Database"] 中写入的信息都不会记录进容器存储层,从而保证了容器存储层的无状态化。

容器运行时使用,可以覆盖这个挂载设置。

# 命令语法
podman run -v <主机目录>:<容器目录>
# 举例说明
podman run -v app/data/resource:/wwwroot/resource \
           -v app/data/config:/AppData/Configuration \
           -v app/data/database:/AppData/Database

说明:在目标主机上面提前创建好 app/data/resource,app/data/config,app/data/database 三个文件目录,此处依据 .net core 应用自身情况,这里只是举例说明。

  • 重新发布 .net app 程序

之前在本机发布的时候,运行时选的是 linux-x64,这样发布出来的可执行文件是依赖 glibc 的,但是 alpine 基础镜像里是 musl libc。所以需要选择 linux-musl-x64 这个运行时,然后重新发布。

dotnet publish -r linux-musl-x64 -c Release -o out

如果使用 .net app 应用程序编译发布文件,Containerfile 可以简化如下:

FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine
LABEL maintainer=“chait@qq.com” \
      description=“This is my .net app”
USER app
RUN sudo dnf update && sudo dnf upgrade

WORKDIR /app
COPY . .
EXPOSE [8080/tcp, 443/tcp]
ENV ASPNETCORE_ENVIRONMENT=Production \
    ASPNETCORE_URLS=http://+:8080;https://+:443 \
    TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
VOLUME ["/wwwroot/resource","/AppData/Configuration","/AppData/Database"] 

ENTRYPOINT ["dotnet", "YourAppName.dll"]

步骤 3: 构建 Podman 镜像

在包含 Containerfile 的目录中,运行以下命令来构建 Podman 镜像:

podman build -t your-image-name:[tag] .

这将创建一个名为 your-image-namePodman 镜像。

# 不指定 tag,默认是 latest
podman run -it --rm -p 8080:8080 your-image-name:[tag]

这将启动一个容器,并将宿主机的 8080 端口(左边)映射到容器的 8080 端口(右边)。

注意事项:

  • 确保你的 .NET Core 应用支持跨平台,这样它才能在 Podman 容器中正确运行。
  • 如果你的应用依赖于环境变量或配置文件,确保在Containerfile 中正确处理这些依赖。
  • 考虑使用多阶段构建来减小最终镜像的大小,如上例所示。
  • 测试你的 Podman 镜像,确保在不同的环境中都能正常运行。

关于 .net8 对云原生的支持

.NET 8 在云原生方面的支持有了显著的增强,这些改进旨在提高性能、减少资源消耗、简化部署流程以及提升应用程序的可观察性和可维护性。以下是 .NET 8 在云原生方面的一些关键特性和改进:

1、Garbage Collection (GC) 改进

  • .NET 8GC 堆对云原生环境进行了优化,能够更好地在多租户和资源受限的环境中运行,如 Kubernetes 集群。
  • GC 操作现在更加高效,减少了对其他线程的影响,从而提高了应用程序的响应速度和吞吐量。

2、Native AOT (Ahead-Of-Time) 编译

  • .NET 8 引入了更完善的 Native AOT 支持,允许在部署前将应用程序编译成本地机器代码,而不是在运行时进行 JIT 编译。
  • 这样做可以显著减少应用程序的启动时间和内存占用,同时减小程序的可执行文件大小,非常适合云原生环境的快速部署和资源效率需求。

3、性能提升

  • 根据 TechEmpower 的基准测试,.NET 8JSON API 方案中性能提高了 18%,并且使用 ASP.NET Core Minimal API 能够达到每秒近 100 万个请求的处理能力。
  • 这些性能提升有助于云原生应用在高并发场景下保持稳定和高效。

4、可观察性和可监测性

  • .NET 8 改进了云原生 ASP.NET Core 程序的可观察性和可监测性,这对于分布式应用程序的调试和故障排查至关重要。
  • 改进的日志记录、健康检查、指标收集和追踪机制使得开发人员能够更好地理解应用程序在生产环境中的行为。

5、云原生工具和框架集成

  • .NET 8 支持与云原生工具和框架的深度集成,如:Kubernetes、Docker、Service Meshes 等,简化了在云环境中的部署和管理流程。

6、云原生安全

  • .NET 8 强调了安全性和合规性,提供了更强大的安全功能,如 TLS 1.3 支持、安全的默认配置和加密算法,以及与云安全最佳实践的紧密集成。

这些改进共同作用,使 .NET 8 成为构建和部署云原生应用的理想选择,无论是对于微服务架构还是无服务器架构,.NET 8 都能提供强大的支持。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

科普文:详解23种设计模式

概叙 设计模式是对大家实际工作中写的各种代码进行高层次抽象的总结&#xff0c;其中最出名的当属 Gang of Four&#xff08;GoF&#xff09;的分类了&#xff0c;他们将设计模式分类为 23 种经典的模式&#xff0c;根据用途我们又可以分为三大类&#xff0c;分别为创建型模式…

Anything in Any Scene:无缝融入任何场景,实现逼真视频对象插入技术

人工智能咨询培训老师叶梓 转载标明出处 现实世界的视频捕获虽然因其真实性而宝贵&#xff0c;但常常受限于长尾分布的问题&#xff0c;即常见场景过度呈现&#xff0c;而关键的罕见场景却鲜有记录。这导致了所谓的"分布外问题"&#xff0c;在模拟复杂环境光线、几何…

在Centos上安装MySQL

目录 在Centos上安装MySQL1.确认当前的系统版本2.添加 MySQL Yum 源2.1访问MySQL开发者专区2.2根据当前系统选择对应的发布包2.3补充 3.MySQL的历史发行版本4.安装发布包5.安装MySQL5.1启动MySQL服务器5.2查看服务器状态5.3开机自启动5.4 登入MySQL5.5修改密码 在Centos上安装M…

今日总结,没啥特别学习到的,还是省市县三级,和一些开发的规范和git的冲突解决。(maven clean)

20240718 一、对于省市县三级联动告一段落二、修改开发好的接口三、对于git&#xff08;每天都有他的问题&#xff09;的推送和拉取问题 一、对于省市县三级联动告一段落 省市县三级联动&#xff0c;直接前端连接一个组件就可以直接实现&#xff0c;好家伙&#xff0c;白费我时…

【深度学习】inpaint图像中的alpha混合图的边缘处理

比如原图是&#xff1a; 红圈内就是文字水印&#xff0c;经过inpaint后得到图和原图混合&#xff0c;如何处理边界呢&#xff0c;这个代码可以干这事&#xff1a; 越是中心就直接用inpaint图&#xff0c;否则就用原图&#xff0c;这样进行alpha混合。 import numpy as np i…

计算机网络技术期末复习

一. 填空 在采用电信号表达数据的系统中&#xff0c;数据有 数字数据 和 模拟数据 两种。域名系统DNS是一个 分布式数据库 系统。TCP/IP的网络层最重要的协议是 IP互连网协议&#xff0c;它可将多个网络连成一个互连网。 4. 在TCP/IP层次模型的网络层中包括的协议主要有ARP 、…

计算机毕业设计-基于Springboot的养老院管理系统-源码程序文档

项目源码&#xff0c;请关注❥点赞收藏并私信博主&#xff0c;谢谢~ 本系统开发采用技术为JSP、Bootstrap、Ajax、SSM、Java、Tomcat、Maven 此文章为本人亲自指导加编写&#xff0c;禁止任何人抄袭以及各类盈利性传播&#xff0c; 相关的代码部署论文ppt代码讲解答辩指导文件…

【C++】类的默认成员函数--构造,析构,拷贝,重载

文章目录 前言一、类的默认成员函数是什么&#xff1f;二、构造函数1.构造函数概述2.构造函数特点3.构造函数代码示例 三.析构函数1.析构函数概述2.析构函数特点3.析构函数代码示例 四.拷贝构造函数1.拷贝构造函数概述2.拷贝构造函数特点拷贝构造函数代码示例 五. 赋值运算符重…

学习008-01-03 Customize the Application UI and Behavior(自定义应用程序UI和行为)

Customize the Application UI and Behavior&#xff08;自定义应用程序UI和行为&#xff09; In XAF, the data model defines the database structure and UI. Changes to your entity classes affect the UI. For example, if you add a new property to an entity class, …

解决PDF文件无法打印的困扰:快速排查与修复指南

在日常工作和学习中&#xff0c;PDF文件因其跨平台兼容性和良好的格式保持特性而广受欢迎。然而&#xff0c;当我们急需打印一份重要的PDF文件时&#xff0c;却遇到了“PDF无法打印”的尴尬情况&#xff0c;这无疑会让人感到焦急。别担心&#xff0c;本文将为你提供一系列快速排…

摄像馆唯美结婚摄影团队网站模版源码 自适应网站源码系统 前后端分离 带完整的安装代码包以及搭建教程

系统概述 摄像馆唯美结婚摄影团队网站模版源码&#xff0c;是一款集美观性、功能性与易用性于一体的网站解决方案。该系统采用最新的前端技术栈&#xff0c;如HTML5、CSS3、JavaScript等&#xff0c;结合响应式设计理念&#xff0c;确保网站能够在不同尺寸的设备上&#xff08…

在 Apifox 中如何高效批量添加接口请求 Body 参数?

在使用 Apifox 进行 API 设计时&#xff0c;你可能会遇到需要添加大量请求参数的情况。想象一下&#xff0c;如果一个接口需要几十甚至上百个参数&#xff0c;若要在接口的「修改文档」里一个个手动添加这些参数&#xff0c;那未免也太麻烦了&#xff0c;耗时且易出错。这时候&…

Python实现人脸识别

直接上代码&#xff1a; import face_recognition import time from PIL import Image, ImageDraw def faceRecognition(fileName): # 加载图片image face_recognition.load_image_file(fileName)# 人脸定位beginTime time.time()face_locations face_recognition.face_lo…

Python酷库之旅-第三方库Pandas(024)

目录 一、用法精讲 61、pandas.to_numeric函数 61-1、语法 61-2、参数 61-3、功能 61-4、返回值 61-5、说明 61-6、用法 61-6-1、数据准备 61-6-2、代码示例 61-6-3、结果输出 62、pandas.to_datetime函数 62-1、语法 62-2、参数 62-3、功能 62-4、返回值 62-…

为ppt中的文字配色

文字的颜色来源于ppt不可删去的图像的颜色 从各类搜索网站中搜索ppt如何配色&#xff0c;有如下几点&#xff1a; 1.可以使用对比色&#xff0c;表示强调。 2.可以使用近似色&#xff0c;使得和谐统一。 3.最好一张ppt中&#xff0c;使用的颜色不超过三种主要颜色。 但我想强调…

hot100 | 十四、贪心

1-leetcode121. 买卖股票的最佳时机 注意&#xff1a; Labuladong的套路太厉害了&#xff0c;分析的很清晰状态转移方程 public int maxProfit(int[] prices) {int n prices.length;int[][] dp new int[n][2];for (int i 0; i < n; i) {if (i-1 -1){// base casedp[…

【C语言】结构体,枚举,联合超详解!!!

目录 结构体 结构体声明 结构体成员的访问 结构体自引用 结构体变量定义&#xff0c;初始化&#xff0c;传参 结构体内存对齐 位段 枚举 联合(共用体) 结构体 结构体声明 1. 概念 1. 结构体是一些值的集合&#xff0c;这些值称为成员变量。 2. 结构体的每个成员可…

基于SpringBoot+Vue的广场舞团系统(带1w+文档)

基于SpringBootVue的广场舞团系统(带1w文档) 基于SpringBootVue的广场舞团系统(带1w文档) 广场舞团&#xff0c;为用户随时随地查看广场舞团信息提供了便捷的方法&#xff0c;更重要的是大大的简化了管理员管理广场舞团信息的方式方法&#xff0c;更提供了其他想要了解广场舞团…

Java强软弱虚引用的特点以及应用场景(面试重点)

强&#xff1a;即使OOM也不回收软&#xff1a;内存溢出前回收弱&#xff1a;只要垃圾收集就死虚&#xff1a;对垃圾收集没关系&#xff0c;只有得到通知&#xff08;插眼&#xff0c;也操作不了对象、只能看到它还活着&#xff09; 一、软引用 代码示例&#xff1a; public cl…

快手开源LivePortrait,实现表情姿态极速迁移,GitHub 6.5K Star

近日&#xff0c;快手可灵大模型团队开源了名为LivePortrait的可控人像视频生成框架&#xff0c;能够准确、实时地将驱动视频的表情、姿态迁移到静态或动态人像视频上&#xff0c;生成极具表现力的视频结果。如下动图所示&#xff1a; 来自网友测试LivePortrait 来自网友测试Li…