博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Docker容器引导完整CentOS
阅读量:6116 次
发布时间:2019-06-21

本文共 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
本文转自 nonono11 51CTO博客,原文链接:http://blog.51cto.com/abian/1869550,如需转载请自行联系原作者
你可能感兴趣的文章
Vue.js的复用组件开发流程
查看>>
小程序过期时间设置
查看>>
mdb格式数据文件导入postgresQL数据库
查看>>
selenium系列->Actions命令实例整理->captrueEntirePageScr...
查看>>
中琅领跑条码打印软件打开时找不到Sentinel锁的解决方案
查看>>
linux nginx
查看>>
应用上云可以有多快?
查看>>
MySQL存储引擎
查看>>
1、UML概述
查看>>
linux:yum和apt-get的区别
查看>>
Sentinel 1.5.0 正式发布,引入 Reactive 支持
查看>>
如何对网站进行归档
查看>>
数据库之MySQL
查看>>
2019/1/15 批量删除数据库相关数据
查看>>
数据类型的一些方法
查看>>
Mindjet MindManager 2019使用教程:
查看>>
这3条将是云计算2019年发展趋势
查看>>
游戏设计的基本构成要素有哪些?
查看>>
详解 CSS 绝对定位
查看>>
AOP
查看>>