news 2026/5/3 10:45:49

Linux内核中的容器技术详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux内核中的容器技术详解

Linux内核中的容器技术详解

引言

容器技术是现代云计算和DevOps的基础,Linux内核通过namespace和cgroups等机制实现了容器化隔离。本文将深入探讨Linux容器技术的底层实现原理,包括资源隔离、容器编排和容器安全等方面。

容器技术概述

1. 容器 vs 虚拟机

特性容器虚拟机
启动时间秒级分钟级
资源占用
隔离级别进程级硬件级
性能接近原生有损耗

2. 容器生态

  • Docker:最流行的容器平台
  • Podman:Docker的无守护进程替代品
  • containerd:容器运行时
  • runc:容器运行器
  • Kubernetes:容器编排平台

Linux内核支持

1. 必需的内核配置

# 检查内核支持 grep -E "CONFIG_NAMESPACES|CONFIG_CGROOPS|CONFIG_OVERLAY_FS" /boot/config-$(uname -r) # 必需的配置选项 CONFIG_NAMESPACES=y CONFIG_UTS_NS=y CONFIG_IPC_NS=y CONFIG_PID_NS=y CONFIG_NET_NS=y CONFIG_CGROUPS=y CONFIG_CGROUP_NS=y CONFIG_OVERLAY_FS=y

2. 内核模块

# 加载必要的模块 modprobe overlay modprobe br_netfilter # 检查已加载的模块 lsmod | grep -E "overlay|bridge|iptable"

namespace隔离

1. namespace类型

#define CLONE_NEWNS 0x00020000 // Mount namespace #define CLONE_NEWUTS 0x04000000 // UTS namespace #define CLONE_NEWIPC 0x08000000 // IPC namespace #define CLONE_NEWPID 0x20000000 // PID namespace #define CLONE_NEWNET 0x40000000 // Network namespace #define CLONE_NEWUSER 0x10000000 // User namespace

2. 创建namespace

#define _GNU_SOURCE #include <sched.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> int child(void *arg) { printf("I'm in child namespace\n"); printf("PID in namespace: %d\n", getpid()); // 执行shell execl("/bin/bash", "/bin/bash", NULL); return 0; } int main() { char *stack; pid_t pid; // 分配栈空间 stack = malloc(4096 * 1024); if (!stack) return 1; // 创建PID namespace pid = clone(child, stack + 4096 * 1024, CLONE_NEWPID | CLONE_NEWUTS | SIGCHLD, NULL); if (pid < 0) { perror("clone"); return 1; } printf("Parent: child PID = %d\n", pid); waitpid(pid, NULL, 0); return 0; }

3. Network namespace

# 创建network namespace ip netns add myns # 在namespace中执行命令 ip netns exec myns ip link list # 添加网络接口到namespace ip link add veth0 type veth peer name veth1 ip link set veth1 netns myns # 配置namespace中的接口 ip netns exec myns ip addr add 10.0.0.2/24 dev veth1 ip netns exec myns ip link set veth1 up # 删除namespace ip netns del myns # 查看所有namespace ip netns list ls /var/run/netns

4. Mount namespace

# 创建mount namespace unshare --mount # 挂载proc mount -t proc proc /proc # 挂载sys mount -t sysfs sys /sys # 创建新的挂载点 mount -t tmpfs tmpfs /tmp # 查看挂载 mount cat /proc/self/mountinfo

cgroups资源控制

1. cgroups层次结构

cgroup root ├── system.slice ├── user.slice └── docker.slice ├── abc123.service └── def456.service

2. cgroups v1

# 创建cgroup mkdir /sys/fs/cgroup/cpu/mycontainer # 设置CPU限制 echo 50000 > /sys/fs/cgroup/cpu/mycontainer/cpu.cfs_quota_us # 50% CPU echo 100000 > /sys/fs/cgroup/cpu/mycontainer/cpu.cfs_period_us # 设置内存限制 echo 512M > /sys/fs/cgroup/memory/mycontainer/memory.limit_in_bytes echo 256M > /sys/fs/cgroup/memory/mycontainer/memory.soft_limit_in_bytes # 设置IO限制 echo "8:0 wbps=10485760" > /sys/fs/cgroup/blkio/mycontainer/blkio.throttle.write_bps_device # 添加进程 echo <pid> > /sys/fs/cgroup/cpu/mycontainer/tasks # 查看统计 cat /sys/fs/cgroup/cpu/mycontainer/cpu.stat

3. cgroups v2

# 检查cgroups v2 mount | grep cgroup2 # 创建cgroup mkdir /sys/fs/cgroup/mycontainer # 设置CPU限制 echo "max 50000 100000" > /sys/fs/cgroup/mycontainer/cpu.max # 设置内存限制 echo "max 512M" > /sys/fs/cgroup/mycontainer/memory.max # 设置IO限制 echo "8:0 rbps=max wbps=max" > /sys/fs/cgroup/mycontainer/io.max # 添加进程 echo <pid> > /sys/fs/cgroup/mycontainer/cgroup.procs

4. libcgoup编程

#include <libcgroup.h> int main() { struct cgroup *cgroup; struct cgroup_controller *cgc; int ret; cgroup_init(); // 创建cgroup cgroup = cgroup_new_cgroup("mycontainer"); if (!cgroup) return 1; // 添加CPU控制器 cgc = cgroup_add_controller(cgroup, "cpu"); cgroup_controller_set_uint64(cgc, "cpu.cfs_quota_us", 50000); cgroup_controller_set_uint64(cgc, "cpu.cfs_period_us", 100000); // 添加内存控制器 cgc = cgroup_add_controller(cgroup, "memory"); cgroup_controller_set_uint64(cgc, "memory.limit_in_bytes", 512 * 1024 * 1024); // 创建cgroup ret = cgroup_create_cgroup(cgroup, 0); if (ret) { fprintf(stderr, "Failed to create cgroup\n"); return 1; } // 添加进程 ret = cgroup_add_task(cgroup, getpid()); // 清理 cgroup_free(cgroup); return 0; }

Union文件系统

1. OverlayFS

OverlayFS将多个目录合并成单一的视图。

overlay ├── lower (只读) │ └── usr/ │ └── bin/ ├── upper (读写) │ └── var/ └── work (工作目录)

2. OverlayFS挂载

# 创建目录 mkdir -p /mnt/overlay/{lower,upper,work,mnt} # lower层(镜像内容) mount -t overlay overlay -o lowerdir=/var/lib/docker/overlay2/lower,\ upperdir=/var/lib/docker/overlay2/upper,\ workdir=/var/lib/docker/overlay2/work \ /mnt/overlay/mnt

3. OverlayFS在内核中

#include <linux/overlayfs.h> // OverlayFS通过VFS实现,不需要额外的系统调用 // 容器使用overlay存储驱动时,Docker自动处理挂载

容器网络

1. 网络模型

  • bridge:默认网络模式
  • host:共享主机网络
  • overlay:跨主机网络
  • macvlan:为容器分配MAC地址
  • none:禁用网络

2. Bridge网络

# 创建网桥 ip link add br0 type bridge ip addr add 172.17.0.1/16 dev br0 ip link set br0 up # 创建veth对 ip link add veth0 type veth peer name veth1 # 一端连接到网桥 ip link set veth0 master br0 ip link set veth0 up # 另一端移到容器namespace ip link set veth1 netns <container_pid> ip netns exec <container_pid> ip addr add 172.17.0.2/16 dev veth1 ip netns exec <container_pid> ip link set veth1 up

3. iptables规则

# NAT规则 iptables -t nat -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE # 端口映射 iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 172.17.0.2:80 # 过滤规则 iptables -A FORWARD -i docker0 -o docker0 -j ACCEPT

容器存储

1. 存储驱动

  • overlay2:当前推荐,性能好
  • aufs:早期Docker使用
  • devicemapper:块级存储
  • btrfs:文件系统级存储
  • zfs:高级存储功能

2. 数据卷

# 创建volume docker volume create myvolume # 挂载volume docker run -v myvolume:/data debian # 绑定挂载主机目录 docker run -v /host/path:/container/path debian # tmpfs挂载 docker run --tmpfs /run debian

3. 存储驱动切换

# 查看当前存储驱动 docker info | grep "Storage Driver" # 修改存储驱动(编辑/etc/docker/daemon.json) { "storage-driver": "overlay2" }

容器安全

1. Seccomp

# Docker默认seccomp配置 docker run --security-opt seccomp=default.json debian # 自定义seccomp docker run --security-opt seccomp=/path/to/profile.json debian # 无seccomp限制 docker run --security-opt seccomp=unconfined debian

2. Capabilities限制

# 查看默认能力 docker run --rm debian cat /proc/self/status | grep Cap # 删除能力 docker run --cap-drop=NET_RAW debian # 添加能力 docker run --cap-add=NET_ADMIN debian # 完全删除能力 docker run --privileged debian

3. AppArmor/SELinux

# AppArmor docker run --security-opt "apparmor=profile" debian # SELinux docker run --security-opt "label=type:container_file_t" debian # 禁用安全标签 docker run --security-opt "label=disable" debian

runc容器运行

1. runc概述

runc是OCI容器运行时的参考实现。

# 创建spec runc spec # 运行容器 runc run mycontainer # 列出容器 runc list # 停止容器 runc kill mycontainer # 删除容器 runc delete mycontainer

2. spec文件

{ "ociVersion": "1.0.2", "process": { "terminal": true, "user": { "uid": 0, "gid": 0 }, "args": ["/bin/bash"], "cwd": "/" }, "root": { "path": "rootfs", "readonly": true }, "hostname": "container", "mounts": [ { "destination": "/proc", "type": "proc", "source": "proc" } ], "linux": { "namespaces": [ {"type": "pid"}, {"type": "network"}, {"type": "ipc"}, {"type": "uts"}, {"type": "mount"} ] } }

容器编排

1. Kubernetes架构

  • Control Plane
    • kube-apiserver
    • etcd
    • kube-controller-manager
    • kube-scheduler
  • Node
    • kubelet
    • kube-proxy
    • container runtime

2. Pod

Pod是Kubernetes最小的调度单位。

apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx:1.21 ports: - containerPort: 80 resources: limits: memory: "128Mi" cpu: "500m" requests: memory: "64Mi" cpu: "250m"

3. Deployment

apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.21 ports: - containerPort: 80

结论

Linux容器技术通过namespace实现资源隔离,通过cgroups实现资源限制,通过overlayfs实现高效的镜像管理。这些内核机制共同构成了现代容器技术的基础。理解这些底层原理对于容器开发、运维和安全加固都有重要意义。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/3 10:43:08

逻辑分析仪实测:I2C通信中SCL占空比到底怎么调才稳定?

逻辑分析仪实战&#xff1a;I2C通信中SCL占空比优化全指南 当你在调试I2C设备时突然遇到传感器无响应或数据错误&#xff0c;是否曾怀疑过那不起眼的时钟信号质量&#xff1f;上周我在调试一个基于STM32的BMP280气压传感器项目时&#xff0c;就遭遇了这样的困境——传感器在室温…

作者头像 李华
网站建设 2026/4/10 18:44:32

.NET源码生成器基于partial范式开发和nuget打包迸

1 安装与初始化 # 全局安装 OpenSpec npm install -g fission-ai/openspeclatest # 在项目目录下初始化 cd /path/to/your-project openspec init 初始化时&#xff0c;OpenSpec 会提示你选择使用的 AI 工具&#xff08;Claude Code、Cursor、Trae、Qoder 等&#xff09;。 3 O…

作者头像 李华
网站建设 2026/4/10 18:43:28

【JavaScript高级编程】拆解函数流水线 上呕

一、什么是setuptools&#xff1f; setuptools 是一个用于创建、分发和安装 Python 包的核心库。 它可以帮助你&#xff1a; 定义 Python 包的元数据&#xff08;如名称、版本、作者等&#xff09;。 声明包的依赖项&#xff0c;确保你的包能够正确运行。 构建源代码分发包&…

作者头像 李华
网站建设 2026/4/10 18:42:27

大厂裁员潮下,技术人的“稳定性”从哪里来?

重新定义“稳定”2026年的科技行业震荡持续发酵&#xff0c;Meta、亚马逊等巨头的裁员名单不断延伸。当AI工具批量生成测试用例、自动化脚本接管回归测试时&#xff0c;软件测试从业者面临灵魂拷问&#xff1a;真正的职业稳定性&#xff0c;究竟锚定在何处&#xff1f; 本文从行…

作者头像 李华