皮皮网

【鬼吹灯辅助源码】【火力指标源码】【头条监控源码】containerd源码

2024-11-19 09:34:54 来源:雷电c 源码

1.Containerd容器管理机制
2.runc hang 导致 Kubernetes 节点 NotReady
3.scoop install dark安装失败?
4.Apache HTTP Server 2.4.49 路径穿越漏洞
5.Kind介绍
6.如何在新版本kubernetes中使用docker?源码

containerd源码

Containerd容器管理机制

       containerd是一个高级容器运行时,由Docker项目衍生,源码实现CRI规范,源码现为CNCF托管,源码提供新的源码容器解决方案的基础。k8s通过containerd创建容器时,源码鬼吹灯辅助源码containerd生成containerd-shim进程,源码此进程操作容器以避免containerd挂断导致所有容器退出的源码问题。containerd-shim用于执行命名空间、源码cgroups配置,源码挂载根文件系统等操作。源码标准化实现由OCI指定,源码runc为参考实现。源码

       containerd-shim调用runc启动容器,源码而runc执行后立即退出,源码containerd-shim则成为容器的父进程,负责监控、状态收集和子进程清理,确保无僵尸进程。

       containerd初始化操作通过方法实现。具体创建过程包括容器对象内部处理的多项操作。初始化后,启动容器操作则由上述方法执行。

       关于详细实现代码,请参考相关源码:github.com/containerd/c...

       深入理解containerd创建、启动容器的代码实现,请访问进一步分析:qikqiak.com/post/contai...

       更多讨论和细节分析见:colstuwjx.github.io/...

runc hang 导致 Kubernetes 节点 NotReady

       Kubernetes 1..3 OS: CentOS 7.9. Kernel: 5.4.-1.el7.elrepo.x_ Docker: ..6

       线上告警提示集群中存在 2-3 个 K8s 节点处于 NotReady 的状态,并且 NotReady 状态一直持续。问题的火力指标源码解决可以通过两种方法,我们先来看看 A 方案。

       针对 docker hang 住这样的现象,通过搜索资料后发现了以下两篇文章里也遇到了相似的问题。这两篇文章都提到了是由于 pipe 容量不够导致 runc init 往 pipe 写入卡住了,将 /proc/sys/fs/pipe-user-pages-soft 的限制放开,就能解决问题。查看问题主机上 /proc/sys/fs/pipe-user-pages-soft 设置的是 。所以将它放大 倍 echo > /proc/sys/fs/pipe-user-pages-soft,然而 kubelet 还是没有恢复正常,pleg 报错日志还在持续,runc init 程序也没有退出。考虑到 runc init 是 kubelet 调用 CRI 接口创建的,可能需要将 runc init 退出才能使 kubelet 退出。通过文章中的说明,只需要将对应的 pipe 中的内容读取掉,runc init 就能退出。尝试了几个后,runc init 果然退出了。再次检查,节点状态切换成 Ready,pleg 报错日志也消失了,观察一天也没有出现节点 NotReady 的情况,问题(临时)解决。

       对解决方案 A 的疑问,虽然问题解决了,但是仔细读 /proc/sys/fs/pipe-user-pages-soft 参数的说明文档,发现这个参数跟本次问题的根本原因不太对得上。pipe-user-pages-soft 含义是头条监控源码对没有 CAP_SYS_RESOURCE CAP_SYS_ADMIN 权限的用户使用 pipe 容量大小做出限制,默认最多只能使用 个 pipe,一个 pipe 容量大小为 k。这里就有疑问:为什么容器 root 用户 pipe 容量会超过限制。

       定位问题最直接的方法,就是阅读源码。先查看下 Linux 内核跟 pipe-user-pages-soft 相关的代码。线上内核版本为 5.4.-1,切换到对应的版本进行检索。在创建 pipe 时,内核会通过 too_many_pipe_buffers_soft 检查是否超过当前用户可使用 pipe 容量大小。如果发现已经超过,则将容量大小从 个 PAGE_SIZE 调整成 2 个 PAGE_SIZE。通过机器上执行 getconf PAGESIZE 可以获取到 PAGESIZE 是 字节,也就是说正常情况下 pipe 大小为 字节,但是由于超过限制,pipe 大小被调整成 字节,这就有可能出现数据无法一次性写入 pipe 的问题。

       找到问题根本原因的第一步,往往是在线下环境复现问题。由于线上环境已经通过方案 A 做了紧急修复,因此,需要找到一种必现的手段。功夫不负有心人,在 issue 中找到了相同的问题,并且可以通过以下方法复现。执行命令之后,立刻就出现 runc init 卡住的情况。通过 lsof -p 查看 runc init 打开的春天还会源码文件句柄情况,可以看到 fd4、fd5、fd6 都是 pipe 类型,其中,fd4 和 fd6 编号都是 ,是同一个 pipe。如何来获取 pipe 大小来实际验证下「疑问 2」中的猜想呢?Linux 下没有现成的工具可以获取 pipe 大小,但是内核开放了系统调用 fcntl(fd, F_GETPIPE_SZ)可以获取到,代码如下。编译好之后,查看 pipe 大小情况如下。重点看下 fd4 和 fd6,两个句柄对应的是同一个 pipe,获取到的容量大小是 = 2 * PAGESIZE。所以的确是因为 pipe 超过软限制导致 pipe 容量被调整成了 2 * PAGESIZE。

       对解决方案 A 疑问的探索,对解决方案 B 的考虑,线上应该如何做修复呢?是否需要把 docker 所有组件都升级呢?如果把 dockerd/containerd/runc 等组件都升级的话,就需要将业务切走然后才能升级,整个过程相对比较复杂,并且风险较高。因此考虑是否可以单独升级 runc?因为在 Kubernetes v1. 版本中还没有弃用 dockershim,因此运行容器整个调用链为:kubelet → dockerd → containerd → containerd-shim → runc → container。不同于 dockerd/containerd 是后台运行的服务端,containerd-shim 调用 runc,实际是调用了 runc 二进制来启动容器。因此,只需要升级 runc,雷电接口源码对于新创建的容器,就会使用新版本的 runc 来运行容器。

       通过测试环境验证,的确不会出现 runc init 卡住的情况了。最终,逐步将线上 runc 升级成 v1.1.1,并将 /proc/sys/fs/pipe-user-pages-soft 调整回原默认值。runc hang 住的问题圆满解决。

       总结,本次故障的原因是,操作系统对 pipe-user-pages-soft 有软限制,但是由于容器 root 用户的 UID 与宿主机一致都是 0,内核统计 pipe 使用量时没有做区分,导致当 UID 为 0 的用户 pipe 使用量超过软限制后,新分配的 pipe 容量会变小。而 runc 1.0.0-rc 正好会因为 pipe 容量太小,导致数据无法完整写入,写入阻塞,进而 runc init 卡住,kubelet pleg 状态异常,节点 NotReady。修复方案是 runc 通过 goroutine 及时读取 pipe 内容,防止写入阻塞。

scoop install dark安装失败?

       1 概述

       作为一名使用 win 的开发者,搭建开发环境往往是一件比较痛苦的事,需要从网上下载各种软件,在电脑上配置不同软件运行环境,对软件进行各种设置,不仅耗时,而且容易出现各种问题。搭建的环境还会存在下面一些问题:

       安装大量程序造成路径污染。安装和卸载比较麻烦。开发环境不能迁移,重装系统或者换电脑需要重新搭建开发环境。软件版本不好控制。为了解决上面这些问题,我们可以使用 WSL+Docker+Scoop 搭建开发环境,取代通过图形界面安装软件和 VMware 安装 Linux 环境的传统方式。

       WSL 是适用于 Linux 的 Windows 子系统, 可让开发人员按原样运行 GNU/Linux 环境 - 包括大多数命令行工具、实用工具和应用程序 - 且不会产生传统虚拟机或双启动设置开销。

       Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器或 Windows 机器上。

       Scoop 是 Windows 的命令行安装程序,可以让我们从命令行以最小的安装量安装程序, 它消除了安装界面和安装程序造成的路径污染,它安装和卸载软件只需一行命令就可以完成,它还可以随意切换软件的版本。

       一个完整的开发环境组成:首先使用 WSL 搭建一个 Linux 环境,然后在 Linux 环境里安装 Docker 应用,使用 Docker 来安装一些常用软件,比如数据库、web 环境等,Scoop 则是在本机上安装一些开发用到的软件,比如 jdk、maven、idea 等。WSL 和 Scoop 都是比较容易备份和还原的,这两个搭建好了,我们利用备份还原可以快速在另一台机器上搭建同样的一套环境,下面是搭建环境的具体流程。

       2 WSL

       2.1 WSL 安装

       使用 WINDOWS 键 + R,输入 winver,检查 win 版本,确保内部版本号是 . 以上,否则更新 win 到最新版本。

       

       2. 以管理员身份打开 PowerShell 并运行下面命令:

       dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart

       dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

       

       3. 重新启动计算机。

       4. 下载 Linux内核更新包[1],然后安装。

       5. 将 wsl2 设置为默认版本, 以管理员身份打开 PowerShell 并运行下面命令:

       wsl --set-default-version 2

       

       6. 安装 Ubuntu . LTS, 打开 Microsoft Store[2],搜索 Ubuntu . LTS[3] 安装, 安装完成后打开 Ubuntu . LTS, 等候几分钟会提示设置用户名和密码,如果不设置用户名和密码直接关闭窗口则默认以 root 登录,这里我们直接关闭窗口,不设置用户名和密码。

       

       7. 然后重新打开 Ubuntu . LTS 就会进入 Ubuntu . LTS了,我们也可以在 powershell 使用 wsl 这个命令进入 Ubuntu . LTS。

       2.2 WSL 配置

       WSL 每次启动后,windows 都会给它分配一个随机的 IP 地址,这样是不利于我们访问 docker 里的服务的,为了解决这个问题,我们可以创建一个脚本文件 wsl2-ip.bat来给 wsl 分配一个固定的 IP,在每次启动 wsl 后用管理员权限运行这个脚本,文件内容如下:

       @echo off

       setlocal enabledelayedexpansion

       :: set wsl2 ip

       wsl -u root ip addr | findstr "...2" > nul

       if !errorlevel! equ 0 (

       echo wsl ip has set

       ) else (

       wsl -d Ubuntu-. -u root ip addr add ...2/ broadcast ... dev eth0 label eth0:1

       echo set wsl ip success: ...2

       )

       :: set windows ip

       ipconfig | findstr "...1" > nul

       if !errorlevel! equ 0 (

       echo windows ip has set

       ) else (

       netsh interface ip add address "vEthernet (WSL)" ...1 ...

       echo set windows ip success: ...1

       )

       pause

       其中 ...2 表示 Linux 的 IP 地址, ...1 表示主机的 IP 地址。

       有时会遇到 Ubuntu . LTS 无法连接网络,这个非常重要,我们可以运行下面命令解决:

       sed -i '4d' /etc/resolv.conf

       sed -i '3a\nameserver 8.8.8.8' /etc/resolv.conf

       sed -i '4a\nameserver ...' /etc/resolv.conf

       2.3 Ubuntu 配置

       2.3.1 替换镜像源

       1. 备份 sources.list 文件,运行下面命令:

       mv /etc/apt/sources.list /etc/apt/sources.list.bak

       2. 创建 source.list 文件,运行下面命令:vim /etc/apt/sources.list

       3. 然后在文件里添加下面内容,下面源任选其一即可。

       # 清华源

       # 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释

       deb /ubuntu/ focal main restricted universe multiverse

       # deb-src /ubuntu/ focal main restricted universe multiverse

       deb /ubuntu/ focal-updates main restricted universe multiverse

       # deb-src /ubuntu/ focal-updates main restricted universe multiverse

       deb /ubuntu/ focal-backports main restricted universe multiverse

       # deb-src /ubuntu/ focal-backports main restricted universe multiverse

       deb /ubuntu/ focal-security main restricted universe multiverse

       # deb-src /ubuntu/ focal-security main restricted universe multiverse

       # 预发布软件源,不建议启用

       # deb /ubuntu/ focal-proposed main restricted universe multiverse

       # deb-src /ubuntu/ focal-proposed main restricted universe multiverse

       # 阿里源

       deb /ubuntu/ focal main restricted universe multiverse

       #deb-src /ubuntu/ focal main restricted universe multiverse

       deb /ubuntu/ focal-updates main restricted universe multiverse

       #deb-src /ubuntu/ focal-updates main restricted universe multiverse

       deb /ubuntu/ focal-backports main restricted universe multiverse

       #deb-src /ubuntu/ focal-backports main restricted universe multiverse

       deb /ubuntu/ focal-security main restricted universe multiverse

       #deb-src /ubuntu/ focal-security main restricted universe multiverse

       deb /ubuntu/ focal-proposed main restricted universe multiverse

       #deb-src /ubuntu/ focal-proposed main restricted universe multiverse

       #网易源

       deb /"]

       }

       3 Scoop

       3.1 Scoop 安装

       1. 以管理员权限打开 PowerShell 。

       2. 自定义用户软件和全局软件安装位置,运行下面命令:

       $env:SCOOP='D:\Softwares\Scoop\LocalApps'

       [Environment]::SetEnvironmentVariable('SCOOP', $env:SCOOP, 'User')

       $env:SCOOP_GLOBAL='D:\Softwares\Scoop\GlobalApps'

       [Environment]::SetEnvironmentVariable('SCOOP_GLOBAL', $env:SCOOP_GLOBAL, 'Machine')

       

       3. 配置安全策略以及安装 Scoop,运行下面命令:

       Set-ExecutionPolicy RemoteSigned -scope CurrentUser

       Invoke-Expression (New-Object System.Net.WebClient).DownloadString('域名,查询对应的 IP 地址。

       

       3. 配置 C:\Windows\System\drivers\etc\hosts文件,在修改前赋予 hosts 文件读写权限。

       

       

       

       4. 修改 host 文件内容如下,第一列是查询出来的ip地址,第二列是其对应的域名,中间有个空格。

       

       5. 保存后重新运行安装命令。

       Invoke-Expression (New-Object System.Net.WebClient).DownloadString('/chawyehsu/dorado

       scoop bucket add Ash /Ash/Scoop-Ash.git

       scoop bucket add pleiades /jfut/scoop-pleiades.git

       scoop bucket add Scoop-Apps /ACooper/scoop-apps

       scoop bucket add scoop-zapps /kkzzhizhou/scoop-zapps

       scoop bucket add lemon /hoilc/scoop-lemon

       scoop bucket add raresoft /L-Trump/scoop-raresoft

       

       4. 如果软件仓库添加失败,还是因为网络的原因,大家可以把这些仓库 fork 到自己的码云账户下,然后再添加。

       5. 使用 aria2 来加速软件的安装:

       scoop install aria2 -g

       scoop config aria2-max-connection-per-server

       scoop config aria2-split

       scoop config aria2-min-split-size 1M

       如果想关闭 aria2,可以运行 scoop config aria2-enabled false命令。

       3.4 Scoop 常用命令

       # 搜索app

       scoop search <应用名>

       # 检查哪些软件有更新

       scoop status

       # 版本切换

       scoop reset <应用名>@<版本切换>

       # 禁止某app更新

       scoop hold <应用名>

       # 更新所有app

       scoop update

*

       # 安装app

       scoop install <应用名>

       #全局安装app

       scoop install -g <应用名>

       #安装extras软件源下的app

       scoop install extras/<应用名>

       # 卸载app

       scoop uninstall <应用名>

       # 卸载全局安装的app

       scoop uninstall -g <应用名>

       4 总结

       开发环境软件的安装与配置到这里就完成了,利用上面这些软件,你可以快速搭建 Java、Go、C++、Python等开发环境。

       参考资料

       [1]Linux内核更新包: /store/apps/9n6svws3rx

       [4]IP地址查询网站: /

Apache HTTP Server 2.4. 路径穿越漏洞

       Apache HTTP Server 2.4.路径穿越漏洞是安全风险中的一种,此漏洞允许攻击者通过不安全的路径访问服务器上的文件,甚至执行任意命令。漏洞存在条件包括:Apache HTTP Server版本为2.4.且配置允许穿越的目录被访问,如Require all granted。攻击者可利用该漏洞读取Apache服务器Web目录外的文件,访问脚本文件源码,或在开启了cgi或cgid的服务器上执行任意命令。

       为了搭建漏洞环境,首先部署Docker容器虚拟化平台。安装Docker环境依赖,配置国内Docker的YUM源,并安装epel扩展仓库,随后安装Docker CE、Docker CLI、containerd.io和Docker Compose。启动并设置Docker开机自启动,使用阿里云Docker镜像加速器以提升pull速度。创建Docker配置文件daemon.json并设置镜像仓库地址为阿里云。使用Docker Compose编译及运行Apache HTTPd 2.4.版本服务器,执行命令进行部署。

       部署完成后,通过浏览器访问Apache服务器并验证其正常运行。接下来,进行漏洞复现:尝试任意文件读取,如通过curl命令访问特定图标文件。同时,探索任意命令执行的可能,以了解漏洞的危害程度。总结,通过上述步骤,我们不仅能够搭建漏洞环境,还能深入理解路径穿越漏洞的复现过程,进而加强对网络安全防护的理解。

Kind介绍

        Kind 是一种使用 Docker 容器作为 node 节点,运行本地 Kubernetes 集群的工具,在 K8s 中有着非常广泛的应用。

        什么是 Kind

        Kind(Kubernetes IN Docker)[1]是一个用来快速创建和测试 kubernetes 的工具,它把环境的依赖降低到最小,仅需要机器安装了 Docker 即可使用。

        Kind 可以做什么?

        Kind 有哪些优势?

        使用 Kind

        Kind 的原理

        Kind 使用一个 container 来模拟一个 node,在 container 里面跑 systemd ,并用 systemd 托管 kubelet 以及 containerd,然后通过容器内部的 kubelet 把其他 K8s 组件,比如 kube-apiserver、etcd、CNI 等跑起来。

        它可以通过配置文件的方式创建多个 container 来模拟创建多个 node,并以这些 node 构建一个多节点的 Kubernetes 集群。

        Kind 内部使用的集群部署工具是 kubeadm,借助 kubeadm 提供的 Alpha 特性,它可以部署包括 HA master 的高可用集群。同时,在 HA master 下, 它还额外部署了一个 Nginx,用来提供负载均衡 vip。

        构建镜像

        Kind 的镜像分为两个,一个 node 镜像,一个 base 镜像。

        node 镜像

        node 镜像的构建比较复杂,需要通过运行 base 镜像,并在 base 镜像内执行操作,再保存此容器内容为镜像的方式来完成构建。它包含的操作有:

        具体的逻辑,可以参考 node.go[2]。

        base 镜像

        base 镜像目前使用了 Ubuntu:. 作为基础镜像,做了以下调整:

        具体的逻辑,可以参考构建的 Dockerfile[3]。

        创建集群

        Kind 创建集群的基本过程为:

        关于每个容器是如何作为 node 跑起来的,这里简单讲解下原理:根据不同的角色,调用不同的函数创建节点 nodes.go[5]。

        节点(容器)创建时,通过配置 --privileged、挂载 tmpfs、修改主机名等,来运行节点 create[6]。

        更多

        Kind 是一个比较简单有趣的项目,它的 scope [7]定得比较明确具体,也比较小。开发者可以借助 Kind 或 Kind 的思想做更多事情,比如:

        此外,文中提及到的 Kind 借助 kubeadm 新特性实现 HA master 高可用集群、借助 join 的方式扩容 master 节点达到 HA master,其内部实现方式也有优缺点,感兴趣的读者可以参考 kubeadm 源码[8]。

        参考文献

        1. /kubernetes-sigs/kind

        2. /kubernetes-sigs/kind/blob/master/pkg/build/node/node.go

        3. /kubernetes-sigs/kind/blob/master/images/base/Dockerfile

        4. /kubernetes-sigs/kind/blob/master/pkg/cluster/internal/create/create.go#L

        5. /kubernetes-sigs/kind/blob/master/pkg/cluster/internal/create/nodes.go#L

        6. /kubernetes-sigs/kind/blob/master/pkg/cluster/nodes/create.go#L

        7. /kubernetes/kubernetes/tree/master/cmd/kubeadm

如何在新版本kubernetes中使用docker?

       kubernetes采用dockershim来与docker进行连接。然而,dockershim在kubernetes 1.版本后已被从源代码中移除。为了兼容,用户应弃用docker转而使用kubernetes支持的containerd或CRI-O。

       为了使用户在新版本的kubernetes中继续使用docker,Mirantis公司与Docker公司合作开发了cri-dockerd。若需在新版kubernetes中使用docker,请参考cri-dockerd。

       具体操作,可参考k8s官网提供的从dockershim迁移到cri-dockerd的指南。这将帮助用户顺利过渡,继续在kubernetes中使用docker。