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) 根据基础镜像制作ssh的docker镜像
制作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位置;假设:镜像名为hpc,Dockerfile在~/docker/里面
cd hpc-base && docker build -t hpc ~/docker/ #就可以生成一个hpc的ssh镜像了。 用docker images查看下所有镜像,你会看到两个镜像:hpc-base和hcp。这样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
或
FROM
这个设置基本的镜像,为后续的命令使用,所以应该作为Dockerfile的第一条指令。
比如:
FROM ubuntu
如果没有指定 tag ,则默认tag是latest,如果都没有则会报错。
b) RUN 命令
RUN命令会在上面FROM指定的镜像里执行任何命令,然后提交(commit)结果,提交的镜像会在后面继续用到。
两种格式:
RUN
或:
RUN ["executable", "param1", "param2" ... ] (exec form)
RUN命令等价于:
docker run image command
docker commit container_id
c) MAINTAINER 命令
MAINTAINER
MAINTAINER命令用来指定维护者的姓名和联系方式
如:
MAINTAINER Guillaume J. Charmes, [email protected]
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
比如memcached使用端口 11211,可以把这个端口暴露在外,这样容器外可以看到这个端口并与其通信。
EXPOSE 11211
g) ENV 命令
用于设置环境变量
ENV
h) ADD 命令
从src复制文件到container的dest路径:
ADD
i) VOLUME 命令
VOLUME ["
如:
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
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
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
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
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(...)函数中,增加try、catch:
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