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

想要完成一个基本的容器,容器所需要做的六项隔离
Linux 内核中就提供了这六种命名空间(namespace) 隔离的系统调用
序号Name space系统调用参数隔离内容
1UTSCLONE_NEWUTS主机名与域名
2IPCCLONE_NEWIPC信号量、共享内存
3PIDCLONE_NEWPID进程编号
4NetworkCLONE_NEWNET网络设备
5MountCLONE_NEWNS挂载点、文件系统
6UserCLONE_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
补充及总结命令
  1. 没有网卡怎么办?创建虚拟设备,加入命名空间
  2. ip link add lnic0 type veth peer name rnic0 mkdir -p /var/run/netns
  3. ln -s /proc/${PID}/ns/net /var/run/netns/${PID}
  4. ip link set rnic0 netns ${PID} name eth0
命名空间 加chroot 构建容器
  • 创建命名空间vhost
  1. ip netns add vhost
  2. ip netns list
  • 设置虚拟交换机
  1. ip link add name docker0 type bridge stp_state 1
  2. ip link set dev docker0 up
  3. ip addr add 172.17.0.1/16 brd 172.17.255.255 dev docker0
  • 创建虚拟网卡,并添加虚拟交换机
  1. ip link add name global_nic type veth peer name ns_nic
  2. ip link set dev global_nic promisc on
  3. ip link set dev global _nic promisc on
  4. ip link set dev global_nic master docker0
  • 把虚拟网卡添加进命名空间,并设置ip 网关 (vhost为pid号)
  1. ip link set ns_nic netns vhost name eth0
  2. ip netns exec vhost ip link set dev lo up
  3. ip netns exec vhost ip link set dev eth0 up
  4. ip netns exec vhost ip addr add dev eth0 172.17.0.2/16 brd 172.17.255.255
  • 开启路由转发,让命名空间极其可以访问外部网络
  1. sysctl -w net.ipv4.ip_forward=1
  • 创建命名空间,与 根目录,并进入命名空间
  1. ushare --uts --mount --pid --ipc --fork --mount -proc
  • 虚拟目录 映射访问内存
  1. mount --bind /proc /root/vroot/proc
  • 设置主机名
  1. hostname vhost
  • 进入虚拟目录
  1. ip netns exec vhost /usr/sbin/chroot /root/vroot
这么多步骤太麻烦怎么办?
  • 一条命令搞定(利用系统本身的命令)
  1. systemd-nspawn -M aabb -D /root/vroot --network-bridge=docker0
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值