由於如今的環境還在CentOS5下,但新的庫只有在CentOS6下才能用。而後用Docker啓動完整OS,這樣相對於ESX省資源一點點。python
目前的環境是宿主機是ubuntu 16.04, 而後容器就 centos5 和 centos6docker
首先直接從官方下載相關底包ubuntu
docker pull centos:5.11 docker pull centos:6.8
而後直接在底包上組安裝相關軟件centos
yum groupinstall ...
CentOS6 直接組安裝完成後,直接啓動可能會卡在 sulogin,此時能夠編輯bash
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是輕量級的,這樣違背了他的初衷了。dom
要引導完整系統run後面的參數就是 /sbin/initide
在安裝好 autofs 後,想啓動它發現提示:oop
Starting automount: automount: test mount forbidden or incorrect kernel protocol version, kernel protocol version 5.00 or above required. [FAILED]
搜索後發現原來是權限不夠。ui
直接在 run 時加上 --privileged 便可,如:.net
docker run --rm --privileged -p 3000:22 -v /root/centos6:/root centos6/d1103:D /sbin/init
容器啓動後,在宿主機發現 agetty 進程CPU佔用100%,再次放狗,解決辦法以下
systemctl list-units *getty* systemctl stop getty@tty1.service #主要是這個中止後就OK systemctl stop system-getty.slice systemctl stop getty.target
另外容器還要固定IP,而後用的macvlan辦法,寫了一個小腳本用來啓動容器並設置IP
#!/bin/bash # start container and setting container IP address if [[ $# -lt 2 ]] || [[ $# -gt 3 ]] then echo "./script.sh p_w_picpath_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 p_w_picpaths "$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
#!/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] p_w_picpath = os.popen("""docker p_w_picpaths | awk '/%s/{print $1":"$2;exit}'""" % sys.argv[1]).read()[:-1] if p_w_picpath: 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],p_w_picpath)) 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],p_w_picpath)) # enter container #nsenter --target=$docker_pid --net --mount --uts --pid
在使用過程當中發現由於沒有設置主機名從而致使NFS出現下面的錯誤:
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 搞定.
#!/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