1、基本结构

 

Nova Docker driver OpenStack集成流程图

 

支持容器创建/删除/软删除/重启/暂停/解除暂定/停止/开始。

支持对容器创建快照,支持基于快照恢复容器。

支持对容器设置插拔网卡。

查询docker节点上CPU/内存使用情况/查询可用节点。

查询docker容器。

查询容器console输出。

支持neutron网络/nova-network网络。

支持绑定浮动IP。 

 

 

不支持共享存储。

不支持挂卷/卸卷操作。

不支持迁移,rescue等操作。   

不支持设置安全组规则。(从代码上看,留的有框架,但是目前并不支持。使用的NoopFirewallDriver)

容器使用的是本地存储,不能使用cinder共享存储。

2、openstack上安装docker

计算节点和glance节点安装Docker

wget https://get.docker.com/builds/Linux/x86_64/docker-latest -O docker

#chmod +x docker

#mv docker /usr/bin/

#docker -d &

或者

#docker -d -l debug

计算节点

#usermod -G docker nova

#service nova-compute restart

3、安装nova docker驱动

# pip install -e git+https://github.com/stackforge/nova-docker#egg=novadocker

Install the required modules:

# cd src/novadocker/

#git checkout -b stable/juno origin/stable/juno

#pip install -U .

# python setup.py install

或者

# git clone https://github.com/stackforge/nova-docker

# cd nova-docker

# git checkout stable/juno

# sudo python setup.py install

4、nova计算节点配置

修改/etc/nova/nova.conf/etc/nova/nova-compute.conf,内容如下:

[DEFAULT]

compute_driver = novadocker.virt.docker.DockerDriver

在目录/etc/nova/rootwrap.d下创建docker.filters,内容如下

# nova-rootwrap command filters for setting up network in the docker driver

# This file should be owned by (and only-writeable by) the root user

 

[Filters]

# nova/virt/docker/driver.py: 'ln', '-sf', '/var/run/netns/.*'

ln: CommandFilter, /bin/ln, root

5、Glance配置

修改/etc/glance/glance-api.conf,内容如下:

[DEFAULT]

container_formats = ami,ari,aki,bare,ovf,docker

6、docker镜像下载和上传(默认连网,在glance处进行)

下载镜像

# docker pull arahman/docker-oracle-xe-11g

# docker pull rastasheep/ubuntu-sshd:14.04

# docker pull tutum/tomcat

# docker pull tutum/mysql

上传至glance

docker save rastasheep/ubuntu-sshd:14.04 | glance image-create --is-public=True --container-format=docker --disk-format=raw --name rastasheep/ubuntu-sshd:14.04

#glance image-list

7、启动虚拟机

通过horizon界面,镜像启动虚拟机,待虚拟机Active,登录至计算节点,docker ps查看,确认容器已经成功创建。

root@cn17548:/home/nsccgzcldadm/hpc# docker ps

CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS              PORTS               NAMES

1cb14e8247d0        hpc:latest          "/bin/sh -c '/usr/sb   2 hours ago         Up 2 hours                              nova-c8335397-82ca-4bad-9085-d1d528ca7c7b   

fdd569db83f9        hpc:latest          "/bin/sh -c '/usr/sb   5 hours ago         Up 5 hours          22/tcp              angry_bohr                                  

8、制作高性能docker镜像

a) tar --numeric-owner --exclude=/proc --exclude=/sys -cvf hpc-base.tar /

b) mkdir hpc-base && tar -xvf hpc-base.tar -C hpc-base && cd hpc-base && tar -c . | docker import - hpc-base

或者

cat hpc-base.tar | docker import - hpc-base

c) 查看镜像,也可以直接进入hpc-base查看

docker images ;查看生成的所有生成的镜像

docker run -i -t hpc-base /bin/bash ; 进终端(没有ssh服务)-i 分配终端,-t表示在前台执行,-d表示在后台执行

d) 根据基础镜像制作sshdocker镜像

  制作ssh登录镜像,最主要的就是Dockerfile(当然这里说的就是Dockerfile这种方法),在某个目录中新建一个Dockerfile文件(命名一定要为Dockerfile

Dockerfile文件

#Dockerfile  

FROM hpc-base  #表示把某个镜像作为基础镜像,相当于面向对象语言中继承,表示生成的镜像里面包含了基础镜像的一些服务

MAINTAINER kylincloud #这是个镜像作者信息

RUN ssh-keygen -q -N "" -t dsa -f /etc/ssh/ssh_host_dsa_key

RUN ssh-keygen -q -N "" -t rsa -f /etc/ssh/ssh_host_rsa_key

RUN sed -ri 's/session    required     pam_loginuid.so/#session    required     pam_loginuid.so/g' /etc/pam.d/sshd

RUN mkdir -p /root/.ssh && chown root.root /root && chmod 700 /root/.ssh

#上面几行都是配置ssh登录目录和登录验证的,而ssh的安装是在基础镜像hpc-base中完成的(-i openssh-server -i openssh-clients

EXPOSE 22  #表示开启哪个端口号,22号端口是给ssh服务使用的;如果不需要端口号可以注释掉这行

RUN echo 'root:kylincloud' | chpasswd  #这是修改root密码,其实这种方法不是很好,因为这是设置root密码,不是更改

#RUN yum install -y yum-priorities && rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm && rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6

#RUN yum install tar gzip gcc vim wget -y

#上面是安装些工具和源

ENV LANG en_US.UTF-8

ENV LC_ALL en_US.UTF-8  #设置环境

CMD /usr/sbin/sshd -D  #设置开启的服务,每个镜像只能有一个CMD有效

#End

  根据Dockerfile文件生成镜像:docker build -t 生成镜像名称  Dockerfile位置;假设:镜像名为hpcDockerfile~/docker/里面

cd hpc-base && docker build -t hpc ~/docker/ #就可以生成一个hpcssh镜像了。 用docker images查看下所有镜像,你会看到两个镜像:hpc-basehcp。这样hpc就是ssh登录的docker镜像了。

e) 镜像测试

i.  第一步:查看镜像信息,可以看到有镜像名称和镜像的id以及生成的时间

docker images

ii. 第二步:用测试镜像生成一个容器,可以根据镜像名称或者镜像id来生成。最后会得到一连串数字和字母组成的信息,应该就是容器标识ID

docker run -d xxx(镜像名称或者id)

或者

docker create xxx(镜像名称或者id)

dokcer ps -a(查看创建的容器)

docker start xxx(启动容器,id)

iii.  第三步:利用上一步生成的容器ID,来查看测试镜像生成的容器信息。这一步会得到有关容器的详细信息,其中包括iP地址

docker inspect xxx(容器id)

iv. 利用上一步中得到的ip地址,ssh登陆

ssh root@xxx (容器IP)

v. 测试服务,这里ssh服务在登陆时已经测试完了。如果是其他镜像,比如mysql:那么这一步就是进入镜像测试MySQL服务了,不同服务用不同方法测试

f) 上传openstack进行测试

docker save hpc | glance image-create --is-public=True --container-format=docker --disk-format=raw --name hpc

glance image-list

+--------------------------------------+------------------------------+-------------+------------------+------------+--------+

| ID                                   | Name                         | Disk Format | Container Format | Size       | Status |

+--------------------------------------+------------------------------+-------------+------------------+------------+--------+

| 8aa374d5-044a-4941-b9a8-a7bdceece8f2 | cirros                       | raw         | bare             | 41126400   | active |

| fb9f24f4-ad71-48bd-864d-b649cad7a97d | hpc                          | raw         | docker           | 1012604928 | active |

+--------------------------------------+------------------------------+-------------+------------------+------------+--------+

启动虚拟机看看是否成功

nova list

+--------------------------------------+------+--------+------------+-------------+-------------------------+

| ID                                   | Name | Status | Task State | Power State | Networks                |

+--------------------------------------+------+--------+------------+-------------+-------------------------+

| c8335397-82ca-4bad-9085-d1d528ca7c7b | hpc  | ACTIVE | -          | Running     | admin-net=192.168.0.151 |

+--------------------------------------+------+--------+------------+-------------+-------------------------+

9、镜像的操作

a) 查看镜像:docker images

b) 下载镜像:docker pull ubuntu

c) 查找镜像:docker search ubuntu14.04

d) 导入镜像:cat ubuntu-14.04.tar.gz | docker import - ubuntu:14.04

e) 存出镜像:docker save -o ubuntu_14.04.tar ubuntu:14.04

或者docker save > ubuntu_14.04.tar

#要导出镜像到本地文件

f) 载入镜像:docker load --input ubuntu_14.04.tar或者docker load < ubuntu_14.04.tar

#使用 docker load 从导出的本地文件中再导入到本地镜像库,docker实现增量修改和维护的原理:每个镜像都由很多层次构成,Docker 使用 Union FS 将这些不同的层结合到一个镜像中去

10、容器的操作

a) 每测试完一个镜像都要删除掉所有的容器,避免占用的空间过大。查看下当前有哪些容器在运行:docker ps -a

b) 创建容器:docker create xxx(镜像名称或者id)

c) 启动容器:docker start xxx(启动容器,id)

d) 查看容器详细信息:docker inspect xxx(容器id)

e) 停止容器:docker stop xxx(CONTAINER ID)

f) 删除容器:docker rm xxx(CONTAINER ID)

g) 删除所有容器:docker stop $(docker ps -a -q) && docker rm $(docker ps -a -q)

11、Dockerfile

所有的 Dockerfile 命令格式都是:

INSTRUCTION arguments

虽然指令忽略大小写,但是建议使用大写。

a) FROM 命令

FROM <image>

FROM <image>:<tag>

这个设置基本的镜像,为后续的命令使用,所以应该作为Dockerfile的第一条指令。

比如:

FROM ubuntu

如果没有指定 tag ,则默认taglatest,如果都没有则会报错。

b) RUN 命令

RUN命令会在上面FROM指定的镜像里执行任何命令,然后提交(commit)结果,提交的镜像会在后面继续用到。

两种格式:

RUN <command> (the command is run in a shell - `/bin/sh -c`)

:

RUN ["executable", "param1", "param2" ... ]  (exec form)

RUN命令等价于:

docker run image command

docker commit container_id

c) MAINTAINER 命令

MAINTAINER <name>

MAINTAINER命令用来指定维护者的姓名和联系方式

:

MAINTAINER Guillaume J. Charmes, guillaume@dotcloud.com

d) ENTRYPOINT 命令

有两种语法格式,一种就是上面的(shell方式):

ENTRYPOINT cmd param1 param2 ...

第二种是 exec 格式:

ENTRYPOINT ["cmd", "param1", "param2"...]

:

ENTRYPOINT ["echo", "Whale you be my container"]

ENTRYPOINT 命令设置在容器启动时执行命令

root@docker:~# cat Dockerfile

FROM ubuntu

ENTRYPOINT echo "Welcome!"

root@docker:~# docker run 62fda5e450d5

Welcome!

e) USER 命令

比如指定 memcached 的运行用户,可以使用上面的 ENTRYPOINT 来实现:

ENTRYPOINT ["memcached", "-u", "daemon"]

更好的方式是:

ENTRYPOINT ["memcached"]

USER daemon

f) EXPOSE 命令

EXPOSE 命令可以设置一个端口在运行的镜像中暴露在外

EXPOSE <port> [<port>...]

比如memcached使用端口 11211,可以把这个端口暴露在外,这样容器外可以看到这个端口并与其通信。

EXPOSE 11211

g) ENV 命令

用于设置环境变量

ENV <key> <value>

h) ADD 命令

src复制文件到containerdest路径:

ADD <src> <dest>

<src> 是相对被构建的源目录的相对路径,可以是文件或目录的路径,也可以是一个远程的文件url

<dest> container中的绝对路径

i) VOLUME 命令

VOLUME ["<mountpoint>"]

:

VOLUME ["/data"]

创建一个挂载点用于共享目录

j) WORKDIR 命令

WORKDIR /path/to/workdir

配置RUN, CMD, ENTRYPOINT 命令设置当前工作路径

可以设置多次,如果是相对路径,则相对前一个 WORKDIR 命令

比如:

WORKDIR /a WORKDIR b WORKDIR c RUN pwd

其实是在 /a/b/c 下执行 pwd

k) CMD 命令

有三种格式:

CMD ["executable","param1","param2"] (like an exec, preferred form)

CMD ["param1","param2"] (as default parameters to ENTRYPOINT)

CMD command param1 param2 (as a shell)

一个Dockerfile里只能有一个CMD,如果有多个,只有最后一个生效。

12、镜像制作和dockerfile参考

http://blog.csdn.net/YuZhiHui_No1/article/details/41129985

http://blog.tankywoo.com/docker/2014/05/08/docker-2-dockerfile.html

13、问题与解决

a) ERRO[0000] [warning]: couldn't run auplink before unmount: exec: "auplink": executable file not found in $PATH

apt-get install aufs-tools

apt-get install cgroup-lite

b) from requests.compat import IncompleteRead ImportError: cannot import name IncompleteRead

       sudo apt-get remove python-pip

       sudo apt-get autoremove

wget https://raw.github.com/pypa/pip/master/contrib/get-pip.py --no-check-certificate

sudo python get-pip.py

c) NoSuchOptError: no such option: my_ip

INFO nova.openstack.common.periodic_task [-] Skipping periodic task _periodic_update_dns because its interval is negative

INFO nova.virt.driver [-] Loading compute driver 'novadocker.virt.docker.DockerDriver'

CRITICAL nova [-] NoSuchOptError: no such option: my_ip

TRACE nova Traceback (most recent call last):

TRACE nova   File "/usr/bin/nova-compute", line 10, in <module>

TRACE nova     sys.exit(main())

TRACE nova   File "/usr/lib/python2.7/dist-packages/nova/cmd/compute.py", line 72, in main

TRACE nova     db_allowed=CONF.conductor.use_local)

TRACE nova   File "/usr/lib/python2.7/dist-packages/nova/service.py", line 275, in create

TRACE nova     db_allowed=db_allowed)

TRACE nova   File "/usr/lib/python2.7/dist-packages/nova/service.py", line 148, in __init__

TRACE nova     self.manager = manager_class(host=self.host, *args, **kwargs)

TRACE nova   File "/usr/lib/python2.7/dist-packages/nova/compute/manager.py", line 631, in __init__

TRACE nova     self.driver = driver.load_compute_driver(self.virtapi, compute_driver)

TRACE nova   File "/usr/lib/python2.7/dist-packages/nova/virt/driver.py", line 1402, in load_compute_driver

TRACE nova     virtapi)

TRACE nova   File "/usr/lib/python2.7/dist-packages/nova/openstack/common/importutils.py", line 52, in import_object_ns

TRACE nova     return import_class(import_str)(*args, **kwargs)

TRACE nova   File "/usr/lib/python2.7/dist-packages/nova/openstack/common/importutils.py", line 27, in import_class

TRACE nova     __import__(mod_str)

TRACE nova   File "/usr/local/lib/python2.7/dist-packages/novadocker/virt/docker/__init__.py", line 20, in <module>

TRACE nova     from novadocker.virt.docker import driver

TRACE nova   File "/usr/local/lib/python2.7/dist-packages/novadocker/virt/docker/driver.py", line 54, in <module>

TRACE nova     CONF.import_opt('my_ip', 'nova.netconf')

TRACE nova   File "/usr/local/lib/python2.7/dist-packages/oslo_config/cfg.py", line 2039, in import_opt

TRACE nova     self._get_opt_info(name, group)

TRACE nova   File "/usr/local/lib/python2.7/dist-packages/oslo_config/cfg.py", line 2384, in _get_opt_info

TRACE nova     raise NoSuchOptError(opt_name, group)

TRACE nova NoSuchOptError: no such option: my_ip

解决:

# cd src/novadocker/

#git checkout -b stable/juno origin/stable/juno

#pip install -U .

# python setup.py install

d) olso_xxx改成olso.xxx

/usr/local/lib/python2.7/dist-packages/oslo_concurrency/lockutils.py

from oslo_config import cfg -> from oslo.config import cfg

 

/usr/local/lib/python2.7/dist-packages/oslo_concurrency/_i18n.py

oslo_i18n -> oslo.i18n

 

/usr/local/lib/python2.7/dist-packages/oslo_concurrency/openstack/common/fileutils.py

 

/usr/local/lib/python2.7/dist-packages/oslo_concurrency/processutils.py

oslo_utils -> oslo.utils

e) The neutron-plugin-openvswitch-agent can't start, it failed at some oslo/rootwrap missing. 'Traceback (most recent call last):\n  File "/usr/bin/neutron-rootwrap", line 6, in <module>\n    from oslo.rootwrap.cmd import main\nImportError: No module named rootwrap.cmd\n'

ln -s /usr/lib/python2.7/dist-packages/oslo/rootwrap/ /usr/local/lib/python2.7/dist-packages/oslo/rootwrap

f) HTTP Error: statusCode=404 No such image: rastasheep/ubuntu-sshd:14.04 

[instance: e345d375-b0ed-4eae-9a33-c996932a5512] Instance failed to spawn

 Traceback (most recent call last):

   File "/usr/lib/python2.7/dist-packages/nova/compute/manager.py", line 2231, in _build_resources

     yield resources

   File "/usr/lib/python2.7/dist-packages/nova/compute/manager.py", line 2101, in _build_and_run_ins

 

     block_device_info=block_device_info)

   File "/usr/local/lib/python2.7/dist-packages/novadocker/virt/docker/driver.py", line 388, in spawn

 

     image = self.docker.inspect_image(self._encode_utf8(image_name))

   File "/usr/local/lib/python2.7/dist-packages/novadocker/virt/docker/client.py", line 36, in wrapper

 

     out = f(*args, **kwds)

   File "/usr/local/lib/python2.7/dist-packages/docker/client.py", line 633, in inspect_image

     True

   File "/usr/local/lib/python2.7/dist-packages/docker/client.py", line 123, in _result

     self._raise_for_status(response)

   File "/usr/local/lib/python2.7/dist-packages/docker/client.py", line 119, in _raise_for_status

     raise errors.APIError(e, response, explanation=explanation)

 APIError: 404 Client Error: Not Found ("No such image: rastasheep/ubuntu-sshd:14.04")

解决:

修改 /usr/local/lib/python2.7/dist-packages/novadocker/virt/docker/driver.py 378行 def spwan(...)函数中,增加trycatch

        try:

            image = self.docker.inspect_image(self._encode_utf8(image_name))

        except errors.APIError:

            image = None

g) Cannot find any PID under container XXXX

 Traceback (most recent call last):

   File "/usr/local/lib/python2.7/dist-packages/novadocker/virt/docker/driver.py", line 369, in _start_container

 

     self._attach_vifs(instance, network_info)

   File "/usr/local/lib/python2.7/dist-packages/novadocker/virt/docker/driver.py", line 204, in _attach_vifs

 

     raise RuntimeError(msg.format(container_id))

 RuntimeError: Cannot find any PID under container "2859d1d47a96ec0d5348a1fb25a282b65e4e02e5407eb9d273b082972f4dbb5b"

 

[instance: 4e4768c4-7268-455c-9566-9bc82192c36f] Instance failed to spawn

 Traceback (most recent call last):

   File "/usr/lib/python2.7/dist-packages/nova/compute/manager.py", line 2231, in _build_resources

     yield resources

   File "/usr/lib/python2.7/dist-packages/nova/compute/manager.py", line 2101, in _build_and_run_instance

 

     block_device_info=block_device_info)

   File "/usr/local/lib/python2.7/dist-packages/novadocker/virt/docker/driver.py", line 405, in spawn

 

     self._start_container(container_id, instance, network_info)

   File "/usr/local/lib/python2.7/dist-packages/novadocker/virt/docker/driver.py", line 377, in _start_container

 

     instance_id=instance['name'])

 InstanceDeployFailure: Cannot setup network: Cannot find any PID under container "2859d1d47a96ec0d5348a1fb25a282b65e4e02e5407eb9d273b082972f4dbb5b"

镜像有问题,需要修改镜像,加入一些后台的服务,如加入SSH,具体看镜像制作。

h) 参考

http://blog.csdn.net/halcyonbaby/article/details/43501845

 

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐