因为现在的环境还在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
|
本文转自 nonono11 51CTO博客,原文链接:http://blog.51cto.com/abian/1869550,如需转载请自行联系原作者