Docker容器技术原理解析(自定义创建容器2个办法)

Jenna ·
更新时间:2024-09-21
· 785 次阅读

想要完成一个基本的容器,容器所需要做的六项隔离 Linux 内核中就提供了这六种命名空间(namespace) 隔离的系统调用
序号 Name space 系统调用参数 隔离内容
1 UTS CLONE_NEWUTS 主机名与域名
2 IPC CLONE_NEWIPC 信号量、共享内存
3 PID CLONE_NEWPID 进程编号
4 Network CLONE_NEWNET 网络设备
5 Mount CLONE_NEWNS 挂载点、文件系统
6 User CLONE_NEWUSER 用户和用户组
Linux 内核实现namespace 的主要目的就是为了实现轻量级虚拟化(容器)服务.在同一个namespace 下的进程可以感知彼此的变化,面对外界的进程一无所知,这样就可以让容器中的进程产生错觉 创建虚拟根 [root@es2 ~]# mkdir vroot [root@es2 ~]# yum -y install --installroot=/root/vroot bash yum coreutils [root@es2 ~]# cd vroot [root@es2 vroot]# ls

bin dev home lib64 mnt proc run srv tmp var
boot etc lib media opt root sbin sys usr

查看隔离空间命令的帮助信息命令 [root@es2 ~]# man unshare [root@es2 ~]# man setns 例如: 序号(1) :主机名隔离空间的使用 (以下使用同一台机器,两个终端,以1,2区别) 2]# ushare --uts //开启命名空间 2]# hostname bbb //设置主机名 2]# bash 2]# exit 1]# echo $HOSTNAME //终端2改变了,但是终端1未影响 序号(2) : 文件系统mount 与用户user 隔离 unshare --mount

--------- 终端1----------

1]# mount -l // 查看可用的mount 文件 1]# cd /var/tmp 1]# lftp 192.168.1.254 lftp 192.168.1.254:-> ls lftp 192.168.1.254:/> cd ios/ lftp 192.168.1.254:/iso>get RHEL7-extras.iso lftp 192.168.1.254:/iso> bye tmp]# ls tmp]# unshare --mount tmp]# mount -t iso9660 -o loop,ro RHEL7-extras.iso /mnt/ tmp]# mount -l | grep iso

--------- 终端2----------

2]# mount -l | grep iso 终端2 看不见 序号(3) : IPC & PID 隔离 unshare --pid --ipc --fork --mount --proc /bin/bash
--------- 终端1---------- 1]# ps -ef 1]# systemctl stop docker 1]# pstree -p systemd(1) 1]# unshare --pid --ipc --fork --mount-proc /bin/bash 1]#pstree -p bash(1) 1]# kill -9 2346 //在终端2上随便找一个进程杀死,由于已隔离,无法杀死

--------- 终端2----------
(下列操作为关闭docker及删除网卡.如果未开启docker ,无需做下面内容)

2]# yum install bridge-utils 2]# ip link set dev docker0 down 2]# ip help link 2]# ip link help link 2]# ip link del link dev docker0 2]# brctl show 2]# ifconfig 序号(4) : Network 网络隔离 unshare --net /bin/bash
--------- 终端1--------- 1]# ifconfig

--------- 终端2----------

2]# unshare --net /bin/bash 2]# ifconfig //已无网卡 2]# ifconfig -a //仅有本地回环地址 2]# ifconfig lo up //启动回环 制作网络虚拟交换机 1]# ip link add name docker0 type bridge stp_state 1 //docker可改任意名 bridge 虚拟交换机 stp_state 1 打开协议 1]# ifconfig -a 1]# ip link set dev docker0 up //开启虚拟交换机电源 1]# ifconfig 1]# ip addr add 172.17.0.1/16 brd 172.17.255.255 dev docker0 //设置ip地址 1]# ifconfig 制作虚拟网卡(一对两口的设备) 1]# ip link add lnic0 type veth peer name rnic0 //lnic0 本地网卡 rnic0 容器插入网卡 1]# ifconfig -a //能看见,但未使用 1]# ip netns list //查看命名空间 1]# mkdir -p /var/run/netns 1]# cd /var/run/netns 1]# ls

去另一个终端查看命名空间进程

2 ]# echo $$ // (以12345为例) 12345

返回终端

1]# ln -s /proc/12345/ns/net /var/run/netns/12345 1]# ll 1]# ip netns list 1]# ifconfig -a 1]# ip link set rnic0 netns 12345 name eth0 2]# ifconfig -a //会出现eth0 2]# ifconfig eth0 up 1]# ip netns exec 12345 ip addr add dev eth0 172.17.0.2/16 brd 172.17.255.255 //设置ip地址 2]# ifconfig 2]# ping 172.17.0.1 //ping 不通 (虚拟交换机只连接了一头) 1]# ip link set dev lnic0 master docker0 // (设置虚拟交换机连接容器) 1]# ip link set dev lnic0 up //启动 2]# ping 172.17.0.1 //ping 不通 (未开启路由转发) 1]#sysctl -w net.ipv4.ip_forward=1 //开启路由转发 2]# ping 172.17.0.1 2]# ping 192.168.1.254 //ping不通 (未设置网关) 2]# ip route replace default via 172.17.0.1 //设置网关 2]# ping 192.168.1.254 //ping通 2]# pstree -p systemd(1) 开启并运行容器 完整版1(终端2) 2]# cd vroot/ 2]#touch docker //为了区别真实根和虚拟根 2]# ushare --uts --mount --pid --ipc --fork --mount-proc 2]# mount --bind /proc /root/vroot/proc 2]# hostname mydocker 2]# /usr/sbin/chroot /root/vroot 2]# yum install psmisc vim net-tools 2]# ls / 2]# pstree -p bash(1) 2]# ifconfig eth0 :172.17.0.2 2]# 完整版2 (终端1) 1]# systemd-nspawn -M aabb -D /root/vroot --network-bridge=docker0 ooxx]# ifconfig -a ooxx]# yum -y install iproute ooxx]# ip link set host0 name eth0 ooxx]# ifconfig -a ooxx]# ifconfig eth0 172.17.0.3/16 ooxx]# ip route replace ddefault via 172.17.0.1 ooxx]# yum provides ping ooxx]# yum -y install iputils 补充及总结命令 没有网卡怎么办?创建虚拟设备,加入命名空间 ip link add lnic0 type veth peer name rnic0 mkdir -p /var/run/netns ln -s /proc/${PID}/ns/net /var/run/netns/${PID} ip link set rnic0 netns ${PID} name eth0 命名空间 加chroot 构建容器 创建命名空间vhost ip netns add vhost ip netns list 设置虚拟交换机 ip link add name docker0 type bridge stp_state 1 ip link set dev docker0 up ip addr add 172.17.0.1/16 brd 172.17.255.255 dev docker0 创建虚拟网卡,并添加虚拟交换机 ip link add name global_nic type veth peer name ns_nic ip link set dev global_nic promisc on ip link set dev global _nic promisc on ip link set dev global_nic master docker0 把虚拟网卡添加进命名空间,并设置ip 网关 (vhost为pid号) ip link set ns_nic netns vhost name eth0 ip netns exec vhost ip link set dev lo up ip netns exec vhost ip link set dev eth0 up ip netns exec vhost ip addr add dev eth0 172.17.0.2/16 brd 172.17.255.255 开启路由转发,让命名空间极其可以访问外部网络 sysctl -w net.ipv4.ip_forward=1 创建命名空间,与 根目录,并进入命名空间 ushare --uts --mount --pid --ipc --fork --mount -proc 虚拟目录 映射访问内存 mount --bind /proc /root/vroot/proc 设置主机名 hostname vhost 进入虚拟目录 ip netns exec vhost /usr/sbin/chroot /root/vroot 这么多步骤太麻烦怎么办? 一条命令搞定(利用系统本身的命令) systemd-nspawn -M aabb -D /root/vroot --network-bridge=docker0
作者:A?J'aime?



自定义 技术原理 Docker

需要 登录 后方可回复, 如果你还没有账号请 注册新账号