本文共 5930 字,大约阅读时间需要 19 分钟。
因为现在的环境还在CentOS5下,但新的库只有在CentOS6下才能用。然后用Docker启动完整OS,这样相对于ESX省资源一点点。
目前的环境是宿主机是ubuntu 16.04, 然后容器就 centos5 和 centos6
首先直接从官方下载相关底包
1 2 | docker pull centos:5.11 docker pull centos:6.8 |
然后直接在底包上组安装相关软件
1 | yum groupinstall ... |
CentOS6 直接组安装完成后,直接启动可能会卡在 sulogin,此时可以编辑
1 2 3 4 5 6 7 8 9 10 11 12 13 | vi /etc/rc .d /rc .sysinig 426 if [ -z "$fastboot" -a "$READONLY" != "yes" ]; then 427 428 STRING=$ "Checking filesystems" 429 echo $STRING 430 fsck -T -t noopts=_netdev -A $fsckoptions #不清楚为什么还要检查磁盘,加入下面这行算是禁用一下。 431 echo "Disable FSCK" > /dev/null 432 rc=$? 433 434 if [ "$rc" - eq "0" ]; then 435 success "$STRING" 436 echo |
引导完整系统官方是不推荐这样做的,毕竟Docker是轻量级的,这样违背了他的初衷了。
要引导完整系统run后面的参数就是 /sbin/init
在安装好 autofs 后,想启动它发现提示:
1 2 | Starting automount: automount: test mount forbidden or incorrect kernel protocol version, kernel protocol version 5.00 or above required. [FAILED] |
搜索后发现原来是权限不够。
直接在 run 时加上 --privileged 即可,如:
1 | docker run -- rm --privileged -p 3000:22 - v /root/centos6 : /root centos6 /d1103 :D /sbin/init |
容器启动后,在宿主机发现 agetty 进程CPU占用100%,再次放狗,解决办法如下
1 2 3 4 | systemctl list- units *getty* systemctl stop getty@tty1.service #主要是这个停止后就OK systemctl stop system-getty.slice systemctl stop getty.target |
另外容器还要固定IP,然后用的macvlan办法,写了一个小脚本用来启动容器并设置IP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | #!/bin/bash # start container and setting container IP address if [[ $ # -lt 2 ]] || [[ $# -gt 3 ]] then echo "./script.sh image_name container_ip hostname [ip_dev_name]" echo "" echo "./script.sh centos5/new:A 192.168.10.5/26 test1 [enp4s0]" echo "" exit fi if [[ $ # -eq 4 ]] then if [[ `ip link | awk -vdev=$4 '$2==dev":"{a=1}END{print a}' ` - ne 1 ]] then echo "ip dev name error" exit fi ip_dev=$4 fi if [[ $ # -eq 3 ]] then ip_dev=`ip -4 a | awk -F '[ :]+' '/UP group/{print $2;exit}' ` fi config= /docker if [[ `docker images "$1" 2> /dev/null | wc -l` - ne 2 ]] then echo "Docker Images Not Found" exit fi if [[ ` ping ${2%/*} -c 3 | grep -c "100% packet loss" ` - eq 0 ]] then echo "IP address Already Use" exit fi docker run -d --privileged --net=none --name ${1%/*} - v $config /config/ ${1%/*}: /root - v $config /local_home : /local_home -h $3 $1 /sbin/init sleep 8 docker_pid=$(docker inspect -f '``.`State`.`Pid`' ${1%/*}) ip link add "$ip_dev" .d link "$ip_dev" type macvlan mode bridge ip link set netns "$docker_pid" "${ip_dev}.d" nsenter -t "$docker_pid" -n ip link set "${ip_dev}.d" up nsenter -t "$docker_pid" -n ip route del default nsenter -t "$docker_pid" -n ip addr add "$2" dev "${ip_dev}.d" nsenter -t "$docker_pid" -n ip route add default via `ip r | awk '/default/{print $3}' ` dev "${ip_dev}.d" # enter container #nsenter --target=$docker_pid --net --mount --uts --pid |
上面的脚本用了一段时间,感觉还是太麻烦,要敲太多东西了.然后又折腾了一个python的
这个脚本不要再想最新的镜像是什么,然后比较方便的commit
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | #!/usr/bin/env python import time import sys import os ser = { "centos5" :[ "test09" , "192.168.10.5/24" ], "centos6" :[ "test10" , "192.168.10.6/24" ]} config = { 0 : None , 1 : "run" , 2 : None , 3 : None } # 0:os, 1:run_type, 2:ip, 3:netcard if len (sys.argv) = = 1 : print ''' ./script.py os [run(default)|commit] [ipaddress] [netcard] ./script.py centos5 ''' sys.exit( 1 ) for i,j in enumerate (sys.argv[ 1 :]): config[i] = j if config[ 0 ] not in ser: print "Docker Image Not Found" sys.exit( 1 ) if not config[ 3 ]: config[ 3 ] = os.popen( "ip -4 a | awk -F'[ :]+' '/UP group/{print $2;exit}'" ).read()[: - 1 ] if not config[ 2 ]: config[ 2 ] = ser[config[ 0 ]][ 1 ] image = os.popen( """docker images | awk '/%s/{print $1":"$2;exit}'""" % sys.argv[ 1 ]).read()[: - 1 ] if image: if sys.argv[ 1 ] in os.popen( "docker ps" ).read(): print "Docker Container Allready Running!" sys.exit() os.system( "docker rm %s" % sys.argv[ 1 ]) if config[ 1 ] = = "run" : os.system( "docker run -d --privileged --net=none --name %s -v /docker/config/%s:/root -v /local_home:/local_home --hostname %s %s /sbin/init" % (config[ 0 ],config[ 0 ],ser[config[ 0 ]][ 0 ],image)) time.sleep( 8 ) pid = os.popen( "docker inspect -f '``.`State`.`Pid`' %s" % sys.argv[ 1 ]).read()[: - 1 ] os.system( 'ip link add %s.d link %s type macvlan mode bridge' % (config[ 3 ],config[ 3 ])) os.system( 'ip link set netns %s %s.d' % (pid,config[ 3 ])) os.system( 'nsenter -t %s -n ip link set %s.d up' % (pid,config[ 3 ])) os.system( 'nsenter -t %s -n ip route del default' % pid) os.system( 'nsenter -t %s -n ip addr add %s dev %s.d' % (pid,config[ 2 ],config[ 3 ])) os.system( "nsenter -t %s -n ip route add default via `ip r | awk '/default/{print $3}'` dev %s.d" % (pid,config[ 3 ])) else : os.system( "docker run --rm -it --privileged --name %s -v /docker/config/%s:/root -v /local_home:/local_home %s bash" % (config[ 0 ],config[ 0 ],image)) # enter container #nsenter --target=$docker_pid --net --mount --uts --pid |
在使用过程中发现因为没有设置主机名从而导致NFS出现下面的错误:
1 2 3 4 5 | Dec 1 13:44:39 localhost rpc.statd[8211]: gethostbyname error for localhost.localdomain Dec 1 13:44:39 localhost rpc.statd[8211]: STAT_FAIL to localhost.localdomain for SM_MON of 192.168.10.7 Dec 1 13:44:54 localhost rpc.statd[8211]: gethostbyname error for localhost.localdomain Dec 1 13:44:54 localhost rpc.statd[8211]: STAT_FAIL to localhost.localdomain for SM_MON of 192.168.10.7 Dec 1 13:44:54 localhost kernel: [2062569.786565] lockd: cannot monitor test04 |
更改上面的docker启动脚本, 加入 -h 这个参数,但发现 -h 只会更改 /etc/hostname
而 /etc/hosts 和 /etc/sysconfig/network 没有变化。于是把下面的脚本加入 /etc/rc.local 搞定.
1 2 3 4 5 6 7 | #!/bin/bash # setting hostname hostname ` cat /etc/hostname ` name=` hostname ` echo "127.0.0.1 ${name} ${name}.test.net" >> /etc/hosts sed -i "s/\(HOSTNAME=\).*$/\1$name/" /etc/sysconfig/network |