1. 创建网络命名空间
ip netns add <ns>
2. 创建虚拟网络设备对
ip link add <vname1> type veth peer name <vname2>
3. 将虚拟网络设备对一端放入网络命名空间中
ip link set <vname2> netns <ns>
4. 分配IP地址给虚拟网络设备对并启动
ifconfig <vname1> <ip> netmask <mask> up
ip netns exec <ns> ifconfig <vname2> <ip> netmask <mask> up
ip netns exec <ns> ip addr add <ip>/<mask> dev <v2name>
ip netns exec <ns> ip link set <v2name> up
ip netns exec <ns> ip link set lo up
ip addr add <ip>/<mask> dev <v1name>
ip link set <v1name> up
5. 命令空间中添加路由网关
ip netns exec <ns> route add default gw <vname1_ip>
6. 主机开启路由转发 -- ip_forward
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
sysctl -p
7. 配置SNAT,将网络空间内的数据包源地址更改为主机网卡(eth0)地址
iptables -t nat -A POSTROUTING -s <ip/mask> -o eth0 -j MASQUERADE
8. 添加主机网络到虚拟网卡forward规则
iptables -t filter -A FORWARD -i eth0 -o <vname1> -j ACCEPT
iptables -t filter -A FORWARD -o eth0 -i <vname1> -j ACCEPT
9. 连接测试
ping 192.168.45.3
ip netns exec haproxy ping <eth0_ip>
ip netns exec haproxy ping 192.168.0.185
ping [www.python.org](http://www.python.org/)
ip netns exec haproxy ping 151.101.108.223
10. runc部署nginx测试
mkdir -p `pwd `/nginx/rootfs && cd `pwd `/nginx && runc spec
docker export $(docker run -d nginx) -o nginx-rootfs.tgz
tar -xf nginx-rootfs.tgz -C rootfs
useradd nginx -s /sbin/nologin
chown -R nginx:nginx rootfs config.json
11. Nginx -- runc_config.json内容
{
"ociVersion" : "1.0.2-dev" ,
"process" : {
"terminal" : true ,
"user" : {
"uid" : 1000 ,
"gid" : 1000
} ,
"args" : [
"/docker-entrypoint.sh" ,
"nginx" ,
"-g" ,
"daemon off;"
] ,
"env" : [
"PATH=/usr/local/[sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin](http://sbin/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin)" ,
"TERM=xterm" ,
"NGINX_VERSION=1.21.4" ,
"NJS_VERSION=0.7.0" ,
"PKG_RELEASE=1~bullseye"
] ,
"cwd" : "/" ,
"capabilities" : {
"bounding" : [
"CAP_AUDIT_WRITE" ,
"CAP_KILL" ,
"CAP_NET_BIND_SERVICE"
] ,
"effective" : [
"CAP_AUDIT_WRITE" ,
"CAP_KILL" ,
"CAP_NET_BIND_SERVICE"
] ,
"inheritable" : [
"CAP_AUDIT_WRITE" ,
"CAP_KILL" ,
"CAP_NET_BIND_SERVICE"
] ,
"permitted" : [
"CAP_AUDIT_WRITE" ,
"CAP_KILL" ,
"CAP_NET_BIND_SERVICE"
] ,
"ambient" : [
"CAP_AUDIT_WRITE" ,
"CAP_KILL" ,
"CAP_NET_BIND_SERVICE"
]
} ,
"rlimits" : [
{
"type" : "RLIMIT_NOFILE" ,
"hard" : 102400 ,
"soft" : 102400
} ,
{
"hard" : 102400 ,
"soft" : 102400 ,
"type" : "RLIMIT_NPROC"
}
] ,
"noNewPrivileges" : true
} ,
"root" : {
"path" : "rootfs" ,
"readonly" : true
} ,
"hostname" : "nginx" ,
"mounts" : [
{
"destination" : "/proc" ,
"type" : "proc" ,
"source" : "proc"
} ,
{
"destination" : "/dev" ,
"type" : "tmpfs" ,
"source" : "tmpfs" ,
"options" : [
"nosuid" ,
"strictatime" ,
"mode=755" ,
"size=65536k"
]
} ,
{
"destination" : "/dev/pts" ,
"type" : "devpts" ,
"source" : "devpts" ,
"options" : [
"nosuid" ,
"noexec" ,
"newinstance" ,
"ptmxmode=0666" ,
"mode=0620" ,
"gid=5"
]
} ,
{
"destination" : "/dev/shm" ,
"type" : "tmpfs" ,
"source" : "shm" ,
"options" : [
"nosuid" ,
"noexec" ,
"nodev" ,
"mode=1777" ,
"size=65536k"
]
} ,
{
"destination" : "/dev/mqueue" ,
"type" : "mqueue" ,
"source" : "mqueue" ,
"options" : [
"nosuid" ,
"noexec" ,
"nodev"
]
} ,
{
"destination" : "/sys" ,
"type" : "sysfs" ,
"source" : "sysfs" ,
"options" : [
"nosuid" ,
"noexec" ,
"nodev" ,
"ro"
]
} ,
{
"destination" : "/sys/fs/cgroup" ,
"type" : "cgroup" ,
"source" : "cgroup" ,
"options" : [
"nosuid" ,
"noexec" ,
"nodev" ,
"relatime" ,
"ro"
]
} ,
{
"destination" : "/etc/hostname" ,
"options" : [
"rbind" ,
"rprivate"
] ,
"source" : "/etc/hostname" ,
"type" : "bind"
} ,
{
"destination" : "/etc/hosts" ,
"options" : [
"rbind" ,
"rprivate"
] ,
"source" : "/etc/hosts" ,
"type" : "bind"
}
] ,
"linux" : {
"resources" : {
"devices" : [
{
"allow" : false ,
"access" : "rwm"
}
]
} ,
"namespaces" : [
{
"type" : "pid"
} ,
{
"path" : "/var/run/netns/haproxy" ,
"type" : "network"
} ,
{
"type" : "ipc"
} ,
{
"type" : "uts"
} ,
{
"type" : "mount"
}
] ,
"maskedPaths" : [
"/proc/acpi" ,
"/proc/asound" ,
"/proc/kcore" ,
"/proc/keys" ,
"/proc/latency_stats" ,
"/proc/timer_list" ,
"/proc/timer_stats" ,
"/proc/sched_debug" ,
"/sys/firmware" ,
"/proc/scsi"
] ,
"readonlyPaths" : [
"/proc/bus" ,
"/proc/fs" ,
"/proc/irq" ,
"/proc/sys" ,
"/proc/sysrq-trigger"
]
}
}
12. 通过runc启动nginx
runc run -d -b <path-to>/nginx <container_name>
runc list
cat /run/runc/<container_name>/state.json
curl http://192.168.45.3:80
13. Runc 使用 host network
删除 config.json 中 namespace 配置中 network配置项
{
"path" : "/var/run/netns/haproxy" ,
"type" : "network"
},
如果不删除则:always put your container in a new network namespace
文档:https://github.com/opencontainers/runc/issues/1552
curl [http://localhost:80](http://localhost/)
14. 使用systemd管理 – 编写service文件
[Unit]
Description=runc run nginx
[Service]
ExecStart=/usr/bin/runc run -d -b /root/work/nginx --pid-file /run/nginx.pid nginx
ExecStop=/usr/bin/runc kill nginx
ExecStopPost=/usr/bin/runc delete nginx
PIDFile=/run/nginx.pid
[Install]
WantedBy=multi-user.target
15. 保存并启动
vim /usr/lib/systemd/system/nginx.service
systemctl daemon-reload
systemctl enable nginx && systemctl start nginx
systemctl status nginx
curl [http://localhost:80](http://localhost/)
- Runc -- GitHub地址:GitHub - opencontainers/runc: CLI tool for spawning and running containers according to the OCI spec
- Host network issue:https://github.com/opencontainers/runc/issues/1552
- Runc -- linux-config文档地址:https://github.com/opencontainers/runtime-spec/blob/main/config.md
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】