Linux Capabilities 入门
目录
Linux capabilities 是什么?
capabilities 的赋予和继承
线程的 capabilities
Permitted
Effective
Inheritable
Bounding
Ambient
文件的 capabilities
Permitted
Inheritable
Effective
运行 execve() 后 capabilities 的变化
案例
Linux capabilities 是什么?
Capabilities
机制是在 Linux 内核 2.2
之后引入的,原理很简单,就是将之前与超级用户 root(UID=0)关联的特权细分为不同的功能组,Capabilites 作为线程(Linux 并不真正区分进程和线程)的属性存在,每个功能组都可以独立启用和禁用。其本质上就是将内核调用分门别类,具有相似功能的内核调用被分到同一组中。
这样一来,权限检查的过程就变成了:在执行特权操作时,如果线程的有效身份不是 root,就去检查其是否具有该特权操作所对应的 capabilities,并以此为依据,决定是否可以执行特权操作。
Capabilities 可以在进程执行时赋予,也可以直接从父进程继承。所以理论上如果给 nginx 可执行文件赋予了 CAP_NET_BIND_SERVICE(
允许绑定到小于 1024 的端口 )
capabilities,那么它就能以普通用户运行并监听在 80 端口上。
capability 名称 | 描述 |
---|---|
CAP_AUDIT_CONTROL | 启用和禁用内核审计;改变审计过滤规则;检索审计状态和过滤规则 |
CAP_AUDIT_READ | 允许通过 multicast netlink 套接字读取审计日志 |
CAP_AUDIT_WRITE | 将记录写入内核审计日志 |
CAP_BLOCK_SUSPEND | 使用可以阻止系统挂起的特性 |
CAP_CHOWN | 修改文件所有者的权限 |
CAP_DAC_OVERRIDE | 忽略文件的 DAC 访问限制 |
CAP_DAC_READ_SEARCH | 忽略文件读及目录搜索的 DAC 访问限制 |
CAP_FOWNER | 忽略文件属主 ID 必须和进程用户 ID 相匹配的限制 |
CAP_FSETID | 允许设置文件的 setuid 位 |
CAP_IPC_LOCK | 允许锁定共享内存片段 |
CAP_IPC_OWNER | 忽略 IPC 所有权检查 |
CAP_KILL | 允许对不属于自己的进程发送信号 |
CAP_LEASE | 允许修改文件锁的 FL_LEASE 标志 |
CAP_LINUX_IMMUTABLE | 允许修改文件的 IMMUTABLE 和 APPEND 属性标志 |
CAP_MAC_ADMIN | 允许 MAC 配置或状态更改 |
CAP_MAC_OVERRIDE | 忽略文件的 DAC 访问限制 |
CAP_MKNOD | 允许使用 mknod() 系统调用 |
CAP_NET_ADMIN | 允许执行网络管理任务 |
CAP_NET_BIND_SERVICE | 允许绑定到小于 1024 的端口 |
CAP_NET_BROADCAST | 允许网络广播和多播访问 |
CAP_NET_RAW | 允许使用原始套接字 |
CAP_SETGID | 允许改变进程的 GID |
CAP_SETFCAP | 允许为文件设置任意的 capabilities |
CAP_SETPCAP | 参考 capabilities man page |
CAP_SETUID | 允许改变进程的 UID |
CAP_SYS_ADMIN | 允许执行系统管理任务,如加载或卸载文件系统、设置磁盘配额等 |
CAP_SYS_BOOT | 允许重新启动系统 |
CAP_SYS_CHROOT | 允许使用 chroot() 系统调用 |
CAP_SYS_MODULE | 允许插入和删除内核模块 |
CAP_SYS_NICE | 允许提升优先级及设置其他进程的优先级 |
CAP_SYS_PACCT | 允许执行进程的 BSD 式审计 |
CAP_SYS_PTRACE | 允许跟踪任何进程 |
CAP_SYS_RAWIO | 允许直接访问 /devport、/dev/mem、/dev/kmem 及原始块设备 |
CAP_SYS_RESOURCE | 忽略资源限制 |
CAP_SYS_TIME | 允许改变系统时钟 |
CAP_SYS_TTY_CONFIG | 允许配置 TTY 设备 |
CAP_SYSLOG | 允许使用 syslog() 系统调用 |
CAP_WAKE_ALARM | 允许触发一些能唤醒系统的东西(比如 CLOCK_BOOTTIME_ALARM 计时器) |
capabilities 的赋予和继承
Linux capabilities 分为进程 capabilities 和文件 capabilities。对于进程来说,capabilities 是细分到
线程的,即每个线程可以有自己的capabilities。对于文件来说,capabilities 保存在文件的扩展属
性中。
下面分别介绍线程(进程)的 capabilities 和文件的 capabilities。
线程的 capabilities
每一个线程,具有 5 个 capabilities 集合,每一个集合使用 64
位掩码来表示,显示为 16
进制格式。这 5 个 capabilities 集合分别是:
-
Permitted
-
Effective
-
Inheritable
-
Bounding
-
Ambient
Permitted
定义了线程能够使用的 capabilities 的上限。它并不使用线程的 capabilities,而是作为一个规定。也就是说,线程可以通过系统调用 capset()
来从 Effective
或 Inheritable
集合中添加或删除 capability,前提是添加或删除的 capability 必须包含在 Permitted
集合中(其中 Bounding 集合也会有影响,具体参考下文)。 如果某个线程想向 Inheritable
集合中添加或删除 capability,首先它的 Effective
集合中得包含 CAP_SETPCAP
这个 capabiliy。
Effective
内核检查线程是否可以进行特权操作时,检查的对象便是 Effective
集合。如之前所说,Permitted
集合定义了上限,线程可以删除 Effective 集合中的某 capability,随后在需要时,再从 Permitted 集合中恢复该 capability,以此达到临时禁用 capability 的功能。
Inheritable
当执行exec()
系统调用时,能够被新的可执行文件继承的 capabilities,被包含在 Inheritable
集合中。这里需要说明一下,包含在该集合中的 capabilities 并不会自动继承给新的可执行文件,即不会添加到新线程的 Effective
集合中,它只会影响新线程的 Permitted
集合。
Bounding
Bounding
集合是 -
集合的超集,如果某个 capability 不在 Bounding
集合中,即使它在 Permitted
集合中,该线程也不能将该 capability 添加到它的 Inheritable
集合中。
Bounding 集合的 capabilities 在执行 fork()
系统调用时会传递给子进程的 Bounding 集合,并且在执行 execve
系统调用后保持不变。
-
当线程运行时,不能向 Bounding 集合中添加 capabilities。
-
一旦某个 capability 被从 Bounding 集合中删除,便不能再添加回来。
-
将某个 capability 从 Bounding 集合中删除后,如果之前
Inherited
集合包含该 capability,将继续保留。但如果后续从Inheritable
集合中删除了该 capability,便不能再添加回来。
Ambient
Linux 4.3
内核新增了一个 capabilities 集合叫 Ambient
,用来弥补 Inheritable
的不足。Ambient
具有如下特性:
-
Permitted
和Inheritable
未设置的 capabilities,Ambient
也不能设置。 -
当
Permitted
和Inheritable
关闭某权限(比如CAP_SYS_BOOT
)后,Ambient
也随之关闭对应权限。这样就确保了降低权限后子进程也会降低权限。 -
非特权用户如果在
Permitted
集合中有一个 capability,那么可以添加到Ambient
集合中,这样它的子进程便可以在Ambient
、Permitted
和Effective
集合中获取这个 capability。现在不知道为什么也没关系,后面会通过具体的公式来告诉你。
Ambient
的好处显而易见,举个例子,如果你将 CAP_NET_ADMIN
添加到当前进程的 Ambient
集合中,它便可以通过 fork()
和 execve()
调用 shell 脚本来执行网络管理任务,因为 CAP_NET_ADMIN
会自动继承下去。
文件的 capabilities
文件的 capabilities 被保存在文件的扩展属性中。如果想修改这些属性,需要具有 CAP_SETFCAP
的 capability。文件与线程的 capabilities 共同决定了通过 execve()
运行该文件后的线程的 capabilities。
文件的 capabilities 功能,需要文件系统的支持。如果文件系统使用了 nouuid
选项进行挂载,那么文件的 capabilities 将会被忽略。
类似于线程的 capabilities,文件的 capabilities 包含了 3 个集合:
-
Permitted
-
Inheritable
-
Effective
这3个集合的具体含义如下:
Permitted
这个集合中包含的 capabilities,在文件被执行时,会与线程的 Bounding 集合计算交集,然后添加到线程的 Permitted
集合中。
Inheritable
这个集合与线程的 Inheritable
集合的交集,会被添加到执行完 execve()
后的线程的 Permitted
集合中。
Effective
这不是一个集合,仅仅是一个标志位。如果设置开启,那么在执行完 execve()
后,线程 Permitted
集合中的 capabilities 会自动添加到它的 Effective
集合中。对于一些旧的可执行文件,由于其不会调用 capabilities 相关函数设置自身的 Effective
集合,所以可以将可执行文件的 Effective bit 开启,从而可以将 Permitted
集合中的 capabilities 自动添加到 Effective
集合中。
详情请参考 Linux capabilities 的 man pagehttp://man7.org/linux/man-pages/man7/capabilities.7.html
运行 execve() 后 capabilities 的变化
上面介绍了线程和文件的 capabilities,你们可能会觉得有些抽象难懂。下面通过具体的计算公式,来说明执行 execve()
后 capabilities 是如何被确定的。
我们用 P
代表执行 execve()
前线程的 capabilities,P'
代表执行 execve()
后线程的 capabilities,F
代表可执行文件的 capabilities。那么:
P'(ambient) = (file is privileged) ? 0 : P(ambient) P'(permitted) = (P(inheritable) & F(inheritable)) |(F(permitted) & P(bounding)) | P'(ambient) P'(effective) = F(effective) ? P'(permitted) : P'(ambient) P'(inheritable) = P(inheritable) [i.e., unchanged] P'(bounding) = P(bounding) [i.e., unchanged]
我们一条一条来解释:
-
如果用户是 root 用户,那么执行
execve()
后线程的Ambient
集合是空集;如果是普通用户,那么执行execve()
后线程的Ambient
集合将会继承执行execve()
前线程的Ambient
集合。 -
执行
execve()
前线程的Inheritable
集合与可执行文件的Inheritable
集合取交集,会被添加到执行execve()
后线程的Permitted
集合;线程执行前 bounding 集合与可执行文件的Permitted
集合取交集,也会被添加到执行execve()
后线程的Permitted
集合;同时执行execve()
后线程的Ambient
集合中的 capabilities 会被自动添加到该线程的Permitted
集合中。 -
如果可执行文件开启了 Effective 标志位,那么在执行完
execve()
后,线程Permitted
集合中的 capabilities 会自动添加到它的Effective
集合中。 -
执行
execve()
前线程的Inheritable
集合会继承给执行execve()
后线程的Inheritable
集合。
这里有几点需要着重强调:
-
上面的公式是针对系统调用
execve()
的,如果是fork()
,那么子线程的 capabilities 信息完全复制父进程的 capabilities 信息。 -
可执行文件的
Inheritable
集合与线程的Inheritable
集合并没有什么关系,可执行文件Inheritable
集合中的 capabilities 不会被添加到执行execve()
后线程的Inheritable
集合中。如果想让新线程的Inheritable
集合包含某个 capability,只能通过capset()
将该 capability 添加到当前线程的Inheritable
集合中(因为 P’(inheritable) = P(inheritable))。 -
如果想让当前线程
Inheritable
集合中的 capabilities 传递给新的可执行文件,该文件的Inheritable
集合中也必须包含这些 capabilities(因为 P’(permitted) = (P(inheritable) & F(inheritable))|…)。 -
将当前线程的 capabilities 传递给新的可执行文件时,仅仅只是传递给新线程的
Permitted
集合。如果想让其生效,新线程必须通过capset()
将 capabilities 添加到Effective
集合中。或者开启新的可执行文件的 Effective 标志位(因为 P’(effective) = F(effective) ? P’(permitted) : P’(ambient))。 -
在没有
Ambient
集合之前,如果某个脚本不能调用capset()
,但想让脚本中的线程都能获得该脚本的Permitted
集合中的 capabilities,只能将Permitted
集合中的 capabilities 添加到Inheritable
集合中(P’(permitted) = P(inheritable) & F(inheritable)|…),同时开启 Effective 标志位(P’(effective) = F(effective) ? P’(permitted) : P’(ambient))。有Ambient
集合之后,事情就变得简单多了,后续的文章会详细解释。 -
如果某个 UID 非零(普通用户)的线程执行了
execve()
,那么Permitted
和Effective
集合中的 capabilities 都会被清空。 -
从 root 用户切换到普通用户,那么
Permitted
和Effective
集合中的 capabilities 都会被清空,除非设置了 SECBIT_KEEP_CAPS 或者更宽泛的 SECBIT_NO_SETUID_FIXUP。
案例
最后拿 docker 举例,如果你使用普通用户来启动官方的 nginx 容器,会出现以下错误:
bind() to 0.0.0.0:80 failed (13: Permission denied)
因为 nginx 进程的 Effective
集合中不包含 CAP_NET_BIND_SERVICE
capability,且不具有 capabilities 感知能力(普通用户),所以启动失败。要想启动成功,至少需要将该 capability 添加到 nginx 文件的 Inheritable
集合中,同时开启 Effective 标志位,并且在 Kubernetes Pod 的部署清单中的 securityContext –> capabilities 字段下面添加 NET_BIND_SERVICE
(这个 capability 会被添加到 nginx 进程的 Bounding
集合中),最后还要将 capability 添加到 nginx 文件的 Permitted
集合中。如此一来就大功告成了,参考公式:P’(permitted) = …|(F(permitted) & P(bounding)))|…,P’(effective) = F(effective) ? P’(permitted) : P’(ambient)。
如果容器开启了 securityContext/allowPrivilegeEscalation
,上述设置仍然可以生效。如果 nginx 文件具有 capabilities 感知能力,那么只需要将 CAP_NET_BIND_SERVICE
capability 添加到它的 Inheritable
集合中就可以正常工作了。
当然了,除了上述使用文件扩展属性的方法外,还可以使用 Ambient
集合来让非 root 容器进程正常工作,但 Kubernetes 目前还不支持这个属性,具体参考 Kubernetes 项目的 issuehttps://github.com/kubernetes/kubernetes/issues/56374
相关文章:
Linux Capabilities 入门
目录 Linux capabilities 是什么? capabilities 的赋予和继承 线程的 capabilities Permitted Effective Inheritable Bounding Ambient 文件的 capabilities Permitted Inheritable Effective 运行 execve() 后 capabilities 的变化 案例 Linux capab…...
驱动 day6
关于设备树的理解: 设备树(Device Tree)是一种用于特定硬件设备的解释语法树。它用来表示存储有关主板硬件和CPU架构信息的数据在内核中的传递格式,使内核可以更好地了解硬件并支持它们,而不必编写固定的代码。设备节点…...
附录2-tensorflow目标检测
源码来自作者Bubbliiiing,我对参考链接的代码略有修改,网盘地址 链接:百度网盘 请输入提取码 提取码:dvb1 目录 1 参考链接 2 环境 3 数据集准备 3.1 VOCdevkit/VOC2007 3.2 model_data/voc_classes.txt 3.3 voc_an…...
常见的EMC问题
电磁兼容设计的目的就在于满足产品功能要求、减少调试时间,使产品满足电磁兼容标准的要求,并且使产品不会对系统中的其它设备产生电磁干扰。 电磁兼容设计中常见的问题有哪些? 1、电磁兼容设计可以从电路设计(包括器件选择&…...
Redis内存存储效率问题
目录 内存碎片是如何形成的? 如何判断是否有内存碎片? 如何清理内存碎片? INFO命令 面向 Prometheus 的 Redis-exporter 监控 实习期间,了解到,企业级开发中多个项目使用Redis,运行Redis实例的有可能是…...
3.28 haas506 2.0开发教程-example-蓝牙多设备扫描(仅支持M320,HD1)
haas506 2.0开发教程-example-蓝牙多设备扫描案例说明蓝牙信息克隆1.手机蓝牙改名信息克隆代码测试案例说明 开发板扫描蓝牙设备,获取并打印蓝牙设备mac地址。mac地址每个设备不同,且不能更改。本案例仅适用于M320开发板和HD1-RTU。案例使用手机与iBeac…...
C语言经典编程题100例(41~60)
目录41、习题4-4 特殊a串数列求和42、习题4-6 水仙花数43、习题4-7 最大公约数和最小公倍数44、习题7-5 找鞍点45、练习5-1 求m到n之和46、练习5-2 找两个数中最大者47、练习5-3 数字金字塔48、习题5-1 符号函数49、习题5-2 使用函数求奇数和50、习题5-3 使用函数计算两点间的距…...
git日常使用命令
实习这段时间使用了很多git指令来提交代码,简单记录一下日常使用的指令: 提交代码通常顺序: 1.git status 查看本地修改项 2.git add . 提交全部文件 (这个 .是全部文件)到暂存区 3.git commit -m ‘本次提交的说明’…...
ES6对象展开运算符浅拷贝or深拷贝
ES6中提出的对象展开运算符“…”就是用来展开元素的。有了它就不用代码循环遍历了,偷懒专用。 1. 合并数组 展开原有数组中的所有元素,可以合并成一个新的数组。 var a[1,2,3]; var b[4,5,6]; var c[...a,...b]; console.log(c) // 输出:…...
leaflet 上传包含shp的zip文件,在map上解析显示图形(059)
第059个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+leaflet中本地上传包含shp的zip文件,利用shapefile读取shp数据,并在地图上显示图形。 直接复制下面的 vue+openlayers源代码,操作2分钟即可运行实现效果 文章目录 示例效果加载shapefile.js方式安装引用jszip(…...
CAN总线详细介绍
1.1 CAN是什么? CAN 最终成为国际标准 ( ISO11898(高速应用)和 ISO11519(低速应用)),是国际上应用最广泛的现场总线之一。 1.2 CAN总线特点 多主方式: 可以多主方式工作,网络上任意一个节点…...
python如何完成对 Excel文件的解密后读取?
通常为了防止重要的Excel文件数据内容的泄露,需要对文件整体进行加密与解密的操作。 对于文件的加解密过程,python也有很多非标准库来帮助我们完成操作,这里主要说明如何完成对Excel文件的解密与读取操作。 这里我们使用到的是msoffcrypto-…...
微服务实战--高级篇:RabbitMQ高级
服务异步通信-高级篇 消息队列在使用过程中,面临着很多实际问题需要思考: 1.消息可靠性 消息从发送,到消费者接收,会经理多个过程: 其中的每一步都可能导致消息丢失,常见的丢失原因包括: 发送…...
autoCAD2022 - 设置新的原点
文章目录autoCAD2022 - 设置新的原点概述笔记UCS原点设置功能的菜单位置ENDautoCAD2022 - 设置新的原点 概述 上次整板子的dxf时, 原来的原点不合适, 想调整一下. 当时整完了, 没记录. 这次用的时候, 又找半天… 设置新原点的功能, 不在顶部菜单中, 而是在视图右上角的UCS图标…...
spring boot 配置 mybatis-plus多数据源
简介Mybatis-puls 多数据源的使用,采用的是官方提供的dynamic-datasource-spring-boot-starter包的 DS 注解,具体可以参考官网:https://gitee.com/baomidou/dynamic-datasource-spring-boot-starterpom.xml文件引入如下依赖主要引入dynamic-d…...
独立产品灵感周刊 DecoHack #047 - 安卓手机上最有用的APP
本周刊记录有趣好玩的独立产品设计开发相关内容,每周发布,往期内容同样精彩,感兴趣的伙伴可以点击订阅我的周刊。为保证每期都能收到,建议邮件订阅。欢迎通过 Twitter 私信推荐或投稿。💻 产品推荐 1. Bouncer Tempor…...
【面试题】JavaScript中递归的理解
大厂面试题分享 面试题库后端面试题库 (面试必备) 推荐:★★★★★地址:前端面试题库递归 RecursionTo iterate is human, to recurse, divine. 理解迭代,神理解递归。本文会以 JavaScript为主、有部分 Rust 举例说明。…...
PyTorch学习笔记
PyTorch学习笔记(一):PyTorch环境安装 往期学习资料推荐: 1.Pytorch实战笔记_GoAI的博客-CSDN博客 2.Pytorch入门教程_GoAI的博客-CSDN博客 安装参考: 1.视频教程:3分钟深度学习【环境搭建】CUDA Anacon…...
SpringBoot2知识点记录
SpringBoot2知识点记录1.SpringBoot2基础入门1.1 环境要求1.1.1 maven设置1.2 第一个程序 HelloWorld1.2.1 创建maven工程1.2.2 引入依赖1.2.3 创建主程序1.2.4 编写业务1.2.5 测试1.2.6 简化配置1.2.7 简化部署1.3 自动装配1.3.1 SpringBoot特点1.3.1.1 依赖管理1.3.1.2 自动装…...
Mysql
1 Sql编写 count(*) //是对行数目进行计数 count(column_name) //是对列中不为空的行进行计数 SELECT COUNT( DISTINCT id ) FROM tablename; //计算表中id不同的记录有多少条 SELECT DISTINCT id, type FROM tablename; //返回表中id与type同时不同的结果 X.1 连表子查询 sel…...
Q4营收利润增长背后估值持续偏低,全球支付巨头PayPal前景如何?
作为国际版的“支付宝”,全球第三方支付巨头PayPal的业务横跨欧美市场,覆盖了全球200多个国家和地区。同时,PayPal也是首家进军中国支付市场的外资机构,实力强劲。然而,近两年,PayPal的市值一路从3000亿跌至…...
【自然语言处理】【大模型】BLOOM:一个176B参数且可开放获取的多语言模型
BLOOM:一个176B参数且可开放获取的多语言模型《BLOOM: A 176B-Parameter Open-Access Multilingual Language Model》论文地址:https://arxiv.org/pdf/2211.05100.pdf 相关博客 【自然语言处理】【大模型】用于大型Transformer的8-bit矩阵乘法介绍 【自然…...
小红书穿搭博主推广费用是多少?
小红书作为一个种草属性非常强的平台,商业价值是有目共睹的。很多爱美的女性都会在小红书上被种草某个商品,所以很多服装品牌都会在小红书上布局推广。 穿搭作为小红书的顶梁柱类目,刷小红书就能总是看到好看的穿搭博主分享美美的衣服&#…...
网络安全-PHPstudy环境搭建
网络安全-PHPstudy环境搭建 网络搭建我是专家,安全我懂的不多,所以可能很基础。。因为我自己都不懂,都是跟着课程学的 PHPstudy 这个东东是一个在windwos下可以快速部署的web开发环境,安装了就能用,也支持iis和ngin…...
operator的两种用法(重载和隐式类型转换)
文章目录重载隐式类型转换构造函数的隐式类型转换补充operator算子的隐式类型转换重载 略 隐式类型转换 构造函数的隐式类型转换 利用operator进行的隐式类型转换成为operator算子的隐式类型转换,讲这个之前先了解构造函数的隐式类型转换,请看以下代…...
vue常用指令
介绍 vue是以数据驱动和组件化开发为核心的前端框架,可以快速搭建前端应用 常用指令 指令:页面数据的操作(以数据去驱动DOM) <div v-xxx""></div>v-if:做元素的插入(append&…...
MATLAB | 有关数值矩阵、颜色图及颜色列表的技巧整理
这是一篇有关数值矩阵、颜色矩阵、颜色列表的技巧整合,会以随笔的形式想到哪写到哪,可能思绪会比较飘逸请大家见谅,本文大体分为以下几个部分: 数值矩阵用颜色显示从颜色矩阵提取颜色从颜色矩阵中提取数据颜色列表相关函数颜色测…...
C++模板元编程详细教程(之九)
前序文章请看: C模板元编程详细教程(之一) C模板元编程详细教程(之二) C模板元编程详细教程(之三) C模板元编程详细教程(之四) C模板元编程详细教程(之五&…...
PhysioNet2017分类的代码实现
PhysioNet2017数据集介绍可参考文章:https://wendy.blog.csdn.net/article/details/128686196。本文主要介绍利用PhysioNet2017数据集对其进行分类的代码实现。 目录一、数据集预处理二、训练2.1 导入数据集并进行数据裁剪2.2 划分训练集、验证集和测试集2.3 设置训…...
正大期货本周财经大事抢先看
美国1月CPI、Fed 等央行官员谈话 美国1月超强劲的非农就业人口,让投资人开始上修对这波升息循环利率顶点的预测,也使本周二 (14 日) 的美国 1月 CPI 格外受关注。 介绍正大国际期货主账户对比国内期货的优势 第一点:权限都在主账户 例如…...
沈阳网站建设哪里的公司比较好/佛山网站优化
一、概述。MapReduce是一种可用于数据处理的编程模型。Hadoop能够执行由各种语言编写的MapReuce程序。MapReduce分为Map部分和Reduce部分。二、MapReduce的机制MapReduce分为几大过程input、Mapper、shufle、reduce、output1、input阶段是指将原始文件复制到HDFS中。2、通过Map…...
征集二级网站建设意见 通知/线上营销推广
之前我发布过一篇对urp的内置shader lit的结构解析,发现自己说的也不完善,这次直接对源码进行一个解析,并提升一下自己的记忆。 如果你找不到这个shader,那么就有可能你不是urp渲染管线。自己搜索。 在前向渲染pass里面…...
哪个浏览器可以做网站/千锋教育
提供:ZStack云计算 系列教程 本教程为如何利用SNMP实现网络监控与管理系列三篇中的第三篇。 内容介绍 相当一部分系统管理员正在积极收集与服务器及基础设施相关的信息。可供选择的工具与方案多种多样,而其中相当一部分以SNMP技术为基础。 SNMP的全…...
新手怎样在手机上做电商/seo服务方案
(《partner4java 讲述jBPM4》仅为技术储备 -- 本人并没有jBPM4实战方面丰富的经验;学习本内容最好有Hibernate的基础) 代码下载地址:文章中贴出的代码可能有所改动,以下载地址为准http://download.csdn.net/detail/pa…...
wordpress 中文图片/网页制作与设计教程
肖战作为“X玖少年团”的主唱,在《陈情令》饰演夷陵老祖魏无羡)走红,并一直坚持抗强扶弱的信念,在《陈情令》中演唱了魏无羡主题曲“曲尽陈情”和合唱团“无羁”。他的演技得到了大家的认可,随后的一系列活动巩固了他的最高地位。…...
网站app推广怎么做/产品推广方案ppt
下载地址:http://curl.haxx.se/download.html 设置环境变量 测试 先启动elasticsearch 启动elasticsearch目录下的elastisearch.bat(windows环境) curl “http://localhost:9200/?pretty” 坑:windows下最好用双引号,不要用单引号&#x…...