1,安装
CentOS6
# rpm -ivh http://mirrors.yun-idc.com/epel/6/i386/epel-release-6-8.noarch.rpm
#rpm -ivh http://mirrors.ustc.edu.cn/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm
#yum install docker-io
源码安装
http://blog.rage.net/2013/08/04/installing-docker-on-centos-6/
CentOS7
#yum install docker
安装之后启动 Docker 服务,并让它随系统启动自动加载。
2,启动docker
#service docker start
#chkconfig docker on
3,获取镜像
获取官方镜像
+# docker pull centos:latest 官方镜像
+# docker pull docker.cn/docker/centos:centos6 国内镜像
搜索镜像
[root@localhost ~]# docker search centos
定制docker镜像
+openVZ模板的下载地址为:http://wiki.openvz.org/Download/template/precreated
+#cat centos-5-x86.tar.gz | docker import - centos:5
本地制作docker镜像
+安装镜像制作工具febootstrap
+#yum -y install febootstrap
+使用febootstrap 制作CentOS5镜像目录
+febootstrap -i bash -i wget -i yum -i iputils -i iproute -i man -i vim-minimal -i openssh-server -i openssh-clients -i cronie-anacron -i crontabs centos5 centos5-image http://mirrors.aliyun.com/centos/5/os/x86_64/
+将镜像导入到Docker
+cd centos5-image && tar -c . | docker import - centos5-base
++执行rpm -qa报错:http://www.opstool.com/article/318
从dockerfile创建
后面会详细介绍
节点之间的导入导出docker镜像
+首先需要运行docker镜像,如果不运行镜像,执行docker ps -a,就没有正在运行的container。
+[root@localhost ~]# docker run -i -t treasureboat/centos6 /bin/bash
+[root@ef6ad6a64086 /]# ifconfig
+[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ef6ad6a64086 treasureboat/centos6:latest "/bin/bash" 23 seconds ago Exited (0) 8 seconds ago mad_mclean
+[root@localhost ~]# docker commit ef6ad6a64086 centos6.6.image
4e6e72b4387d8fe6c1c94a0546b105ab738cecee32a7332e93e13edf816cbcf2
+有两种方法导出
++[root@localhost ~]# docker export centos6.6.image > centos6.6.img
++[root@localhost ~]# docker save centos6.6.image > centos6.6.image
+导入docker镜像
++[root@localhost ~]# docker load < /root/centos6.6.img
4,搭建私有仓库
+方法一
++直接pull registry镜像
[root@localhost ~]# docker pull registry
++默认情况下,会将仓库存放于容器内的/tmp/registry目录下,这样如果容器被删除,则存放于容器中的镜像也会丢失,所以我们一般情况下会指定本地一个目录挂载到容器内的/tmp/registry下,如下:
[root@localhost ~]#docker run -d -p 5000:5000 -v /opt/data/registry:/tmp/registry registry
35bdd9ed60d8653102ee17cf956099bd6114b68061fcdc172657ea3140a16be6
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7ec1030ff3bf registry:latest "docker-registry" 3 seconds ago Up 1 seconds 0.0.0.0:5000->5000/tcp desperate_elion
可以看到启动了一个容器,地址为,本地ip地址:5000
+方法二
++使用git上的源码创建
++首先登陆到docker在git上面的源码页面,https://registry.hub.docker.com/_/registry/下载,解压。
++安装registry到本地服务器上
++yum install build-essential python-dev libevent-dev python-pip liblzma-dev
++pip install docker-registry
++运行registry
++gunicorn --access-logfile - --debug -k gevent -b 0.0.0.0:5000 -w 1 docker_registry.wsgi:application
+方法三
++基于方法二的源码,build成image,然后执行image
++在docker——registry目录里
++docker build -t registry
++docker run -d -p 5000:5000 -v /opt/data/registry:/tmp/registry registry
上面的方法都需要指定-v来修改镜像默认的存放位置,还可以修改配置文件:
[root@localhost ~]#git clone https://github.com/dotcloud/docker-registry
[root@localhost ~]#cd docker-registry
[root@localhost ~]#cp config_sample.yml config.yml
[root@localhost ~]#vi config.yml
...
# This is the default configuration when no flavor is specified
dev:
storage: local
storage_path: /home/vpsee/registry
loglevel: debug
...
[root@localhost ~]#mkdir /home/vpsee/registry
Docker-Registry 实际上是个基于 Flask 的 web app,安装成功后就cb可以这样运行了:
[root@localhost ~]#gunicorn --access-logfile - --debug -k gevent -b 0.0.0.0:80 -w 1 wsgi:application
打开浏览器,访问 IP 地址就可以看到 docker-registry 私有仓库在运行了
使用私有仓库
+查看一下现有系统上已经有了哪些镜像:
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
centos6.6.image latest 4e6e72b4387d About an hour ago 465.7 MB
<none> <none> cf73ddbcb12b 10 days ago 375 MB
treasureboat/centos6 latest 09365809850b 4 months ago 465.7 MB
+将centos6.6.image这个镜像上传(pull)到创建的私有仓库中(ip地址就是本地的ip地址),初次pull会提示设置用户名/密码。
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
centos6.6.image latest 4e6e72b4387d About an hour ago 465.7 MB
registry latest 70d8f0edf5c9 7 days ago 413.9 MB
treasureboat/centos6 latest 09365809850b 4 months ago 465.7 MB
+只有images中的镜像可以pull。
[root@localhost ~]# docker tag 4e6e72b4387d 10.1.5.96:5000/c6.6
经测试,在centos6.6 docker1.5 无法push镜像
[root@localhost ~]# docker push 10.1.5.96:5000/c6.6
FATA[0004] Error: v1 ping attempt failed with error: Get https://10.1.5.96:5000/v1/_ping: EOF. If this private registry supports only HTTP or HTTPS with an unknown CA certificate, please add `--insecure-registry 10.1.5.96:5000` to the daemon's arguments. In the case of HTTPS, if you have access to the registry's CA certificate, no need for the flag; simply place the CA certificate at /etc/docker/certs.d/10.1.5.96:5000/ca.crt
说明:docker1.3.× 以后,docker registry交互默认使用https,然而搭建的私有仓库只提供http服务,所以当与私有仓库交互是就会报上面的错误,为了解决这个问题需要在启动docker server时增加启动参数为默认使用http访问。
解决方法:
修改docker配置文件
vi /etc/sysconfig/docker
DOCKER_OPTS="--insecure-registry 10.1.5.96:5000"
重启docker
service docker restart
--------------------------------------------------------------------------------
docker数据管理
1,挂载本地目录
#docker run -it --privileged=true -v /data/test:/usr/local/test treasureboat/centos6 /bin/bash
-v参数,冒号前为宿主机目录,必须为觉得路径,冒号后为镜像内挂载的路径。
默认挂载的路径权限为读写,如果指定只读可以用:ro
#docker run -it --privileged=true -v /data/test:/usr/local/test:ro treasureboat/centos6 /bin/bash
遇到的问题:
使用docker run -v /data:/mnt -i -t ubuntu 来共享docker容器和主机目录,但是在docker容器里文件只可以读不可以写。如果共享的不是主机data目录,文件也会变得不可以读,用ls命令会得出ls: cannot open directory .: Permission denied这样的提示,根本查看不了目录。
解决:
selinux 原因。
两种方法:1.selinux模式为permissive模式 setenforce 0
2.容器启动,添加--privileged=true
数据卷
数据卷:就是一个正常的容器,专门用来提供数据卷供其他容器挂载
实例:
#docker run --privileged=true -v /data/test:/usr/local/test --name mydata docker.io/treasureboat/centos6 /bin/bash
创建一个数据卷
#docker run -it --privileged=true --volumes-from mydata docker.io/treasureboat/centos6 /bin/bash
创建一个容器,挂载数据卷容器,并做操作
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c10abf449ad4 docker.io/treasureboat/centos6:latest "/bin/bash" About a minute ago Exited (0) About a minute ago thirsty_mclean
ce8dc9e26363 docker.io/treasureboat/centos6:latest "/bin/bash" 18 minutes ago Exited (0) 18 minutesago mydata
[root@localhost ~]# docker run -it --privileged=true --volumes-from mydata docker.io/treasureboat/centos6 /bin/bash
[root@c10abf449ad4 /]# echo "aaa" > /usr/local/test/aaa.txt
[root@c10abf449ad4 /]# exit
exit
[root@localhost ~]# cat /data/test/aaa.txt
aaa
备份
新建一个数据卷
docker run --privileged=true -v /root/data:/data --name mydata docker.io/plaken/centos6.5:latest data
挂载数据卷,并将数据卷中的/data打包保存到本地目录/root/test下
[root@localhost ~]# docker run --privileged=true --volumes-from mydata -v /root/test:/backup docker.io/plaken/centos6.5:latest tar zcvf /backup/backup.tar.gz /data
tar: Removing leading `/' from member names
/data/
/data/bbb.txt
[root@localhost ~]# cd test/
[root@localhost test]# ls
backup.tar.gz
恢复
删除原有的文件
[root@localhost ~]# cd data/
[root@localhost data]# ls
bbb.txt
[root@localhost data]# rm -rf bbb.txt
挂载数据卷,并将本地的备份文件/root/test/backup.tar.gz 解压到数据卷中的/data中,也就是本地的/root/data/data/bbb.txt
[root@localhost ~]# docker run --privileged=true --volumes-from mydata -v /root/test:/backup docker.io/plaken/centos6.5:latest tar zxvf /backup/backup.tar.gz -C /data
data/
data/bbb.txt
[root@localhost ~]# ll data/data/bbb.txt
-rw-r--r--. 1 root root 4 7月 9 03:12 data/data/bbb.txt
2,docker配置sshd
1>,进入交互模式
[root@localhost ~]# docker run -i -t docker.io/treasureboat/centos6 /bin/bash
2>,安装sshd服务
[root@c1915e9fa3fc /]# yum install openssh-server
3>,修改密码
[root@c1915e9fa3fc /]# passwd root
4>,关闭selinux
[root@c1915e9fa3fc /]#setenforce 0
[root@c1915e9fa3fc /]#echo "setenforce 0" >> /etc/rc.d/rc.local
5>,修改配置文件
vi /etc/ssh/sshd_config
UsePAM yes 修改为 UsePAM no
7>,commit改容器
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c1915e9fa3fc docker.io/treasureboat/centos6:latest "/bin/bash" 15 minutes ago Exited (0) 4 seconds ago high_davinci
[root@localhost ~]# docker commit c1915e9fa3fc centos6:sshd
8>,使用docker.io/treasureboat/centos6:latest /usr/sbin/sshd -D
[root@localhost ~]# docker run -d -p 60022:22 docker.io/treasureboat/centos6:latest /usr/sbin/sshd -D
3,使用网络
外部访问容器
要让外部访问容器的端口可以通过-p或-P参数来指定端口映射
当使用-P参数时,会随机一个49000~49900的端口到内部容器开放的网络端口
格式:
1>hostPort:contarnerPort
docker run -d -p 60022:22 docker.io/treasureboat/centos6:latest /usr/sbin/sshd -D
2>ip:hostPort:contarnerPort
docker run -d -p 127.0.0.1:60022:22 docker.io/treasureboat/centos6:latest /usr/sbin/sshd -D
3>ip::contarnerPort
docker run -d -p 127.0.0.1::22 docker.io/treasureboat/centos6:latest /usr/sbin/sshd -D
4>指定udp端口
docker run -d -p 127.0.0.1:600161:161/udp docker.io/treasureboat/centos6:latest /bin/snmp -D
查看映射端口配置
docker port mydocker 5000
127.0.0.1:5000
容器互联
A服务器(172.17.0.100)
[root@localhost ~]# docker run -i -t --name client docker.io/nepalez/ubuntu-ssh:latest /usr/sbin/sshd -D
B服务器(172.17.0.101)
[root@localhost ~]# docker run -i -t --link=client:lianjie docker.io/nepalez/ubuntu-ssh:latest /bin/bash
root@84a8b509cd82:/# ping lianjie
PING lianjie (172.17.0.100) 56(84) bytes of data.
64 bytes from lianjie (172.17.0.100): icmp_seq=1 ttl=64 time=0.049 ms
64 bytes from lianjie (172.17.0.100): icmp_seq=2 ttl=64 time=0.040 ms
64 bytes from lianjie (172.17.0.100): icmp_seq=3 ttl=64 time=0.047 ms
容器间db链接
打开mysql容器
[root@localhost ~]# docker run -a stdout --name mydb -P docker.io/umrigark/centos6-ssh-mysql /run.sh &
========================================================================
ssh -p <port> root@<host>
Password for the root user is : mz0pbPqWgWgD
Please remember to change the above password as soon as possible!
========================================================================
....
========================================================================
MySQL Password for user: admin is : ePpd2cBEXwTn
Please remember to change the above password as soon as possible!
========================================================================
打开应用容器
[root@localhost ~]# docker run -t -i --link mydb:db docker.io/umrigark/centos6-ssh-mysql /bin/bash
安装mysql客户端,连接mysql服务器
bash-4.1# mysql -h db -P3306 -uadmin -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 12
Server version: 5.1.73 Source distribution
Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| test |
+--------------------+
3 rows in set (0.00 sec)
mysql>
4,高级网络设置
配置dns
1>默认情况下容器的dns配置是利用虚拟文件来挂载到容器的三个文件。所以当宿主机的DNS配置改变,容器也跟着改变。
bash-4.1# mount
...
/dev/sda3 on /etc/resolv.conf type xfs (rw,seclabel,relatime,attr2,inode64,noquota)
/dev/sda3 on /etc/hostname type xfs (rw,seclabel,relatime,attr2,inode64,noquota)
/dev/sda3 on /etc/hosts type xfs (rw,seclabel,relatime,attr2,inode64,noquota)
...
2>手动指定容器配置
在创建容器的时候添加以下参数
-h HOSTNAME 或者 --hostname=HOSTNAME 设定容器的主机名。它会被写到容器内的/etc/hostname和/etc/hosts,但在容器外部看不到,既不会在docker ps中显示,也不会在其他的容器/etc/hosts看到
--dns=IP_ADDRESS 添加DNS服务器到容器的/etc/resolv.conf
3>访问控制
利用iptables对容器的访问进行控制
iptables使用问题
[root@localhost ~]# docker run -i -t docker.io/plaken/centos6.5 /bin/bash
bash-4.1# iptables -nL
FATAL: Could not load /lib/modules/3.10.0-229.7.2.el7.x86_64/modules.dep: No such file or directory
iptables v1.4.7: can't initialize iptables table `filter': Permission denied (you must be root)
Perhaps iptables or your kernel needs to be upgraded.
解决方法:
[root@localhost ~]# docker run -i -t --privileged=true docker.io/plaken/centos6.5 /bin/bash
bash-4.1# iptables -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
4>自定义docker网桥
创建容器的时候,默认会创建一个docker0的网桥,该网桥和其他虚拟机的网桥的功能是一样的,可以使用brctl show来查看。
*brctl的安装包是bridge-utils
[root@localhost ~]# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.56847afe9799 no veth40bd9a4
vethee0474f
除了默认的docker0网桥,用户也可以指定网桥来连接各个容器
在启动docker服务的时候使用-b BRIDGE或 --bridge=BRIDGE来指定使用的网桥
自定义网桥:
停止docker服务
[root@localhost ~]# service docker stop
[root@localhost ~]# ip link set dev docker0 down
[root@localhost ~]# brctl delbr docker0
创建一个网桥
[root@localhost ~]# brctl addbr bridge0
[root@localhost ~]# ip addr add 192.168.5.1/24 dev bridge0
[root@localhost ~]# ip link set dev bridge0 up
查看新建的网桥
[root@localhost ~]# ip addr show bridge0
231: bridge0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN
link/ether 7a:7b:a6:44:4e:eb brd ff:ff:ff:ff:ff:ff
inet 192.168.5.1/24 scope global bridge0
valid_lft forever preferred_lft forever
inet6 fe80::787b:a6ff:fe44:4eeb/64 scope link
valid_lft forever preferred_lft forever
配置 Docker 服务,默认桥接到创建的网桥上。
[root@localhost ~]# echo 'DOCKER_OPTS="-b=bridge0"' >> /etc/default/docker
[root@localhost ~]# service docker start
启动 Docker 服务。 新建一个容器,可以看到它已经桥接到了 bridge0 上。
在容器中可以使用 ip addr 和 ip route 命令来查看 IP 地址配置和路由信息。
*工具
pipework
Jérôme Petazzoni 编写了一个叫 pipework 的 shell 脚本,可以帮助用户在比较复杂的场景中完成容器的连接。
playground
Brandon Rhodes 创建了一个提供完整的 Docker 容器网络拓扑管理的 Python库,包括路由、NAT 防火墙;以及一些提供 HTTP, SMTP, POP, IMAP, Telnet, SSH, FTP 的服务器。
5>配置固定ip,不是公网ip,docker不能配置公网ip
http://www.xiaomastack.com/2015/02/06/docker-static-ip/
6>点对点连接
5,实 例
1>通过supervisor来管理进程
Dockerfile配置
[root@localhost dockerfile]# cat Dockerfile
FROM centos:6.6
MAINTAINER duxuefeng@oasgames.com
RUN yum -y update
RUN yum install -y openssh-server nginx supervisor
#官方源是没有nginx和supervisor的,需要执行完Dockerfile后进入交互模式安装,后commit。
|--------------------------------------------------------------------------------------------
|[root@de8aff6c9df4 /]# cat /etc/yum.repos.d/nginx.repo
|[nginx]
|name=nginx repo
|baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
|gpgcheck=0
|enabled=1
|
|yum install nginx -y
|
|#配置supervisor
|yum install python-setuptools
|easy_install supervisor
|-------------------------------------------------------------------------------------------
RUN mkdir -p /var/run/sshd
RUN mkdir /var/log/supervisor
COPY supervisord.conf /etc/supervor/conf.d/supervisord.conf
|--------------------------------------------------------------------------------------
|#supervisord.conf
|[supervisord]
|nodaemon=true
|[program:sshd]
|command=/usr/sbin/sshd -D
|
|[program:nginx]
|command=/usr/sbin/nginx -c /etc/nginx/nginx.conf
---------------------------------------------------------------------------------------
EXPOSE 22 80
CMD ["/usr/bin/supervisord"]
#使用
非交互模式
docker run -d -p 22 -p 80 duxuefeng/supervisor:3.0 /usr/bin/supervisord -c /etc/supervor/conf.d/supervisord.conf
交互模式
docker run -d -p 22 -p 80 duxuefeng/supervisor:3.0
-------------------------------------------------------------------------------------
docker run 命令
docker run [OPTIONS] IMAGE[:TAG][COMMAND][ARG...]
OPTIONS分为两类
1,设定操作执行方式
+1,设定container的运行方式,前台还是后台执行
+2,设定container的id
+3,设定network参数
+4,设定container的cpu和内存参数
+5,设定权限和LXC参数
2,设定image的默认资源
Usage: docker run [OPTIONS] IMAGE[:TAG] [COMMAND] [ARG...]
Run a command in a new container
-a=map[]: 附加标准输入、输出或者错误输出
-c=0: 共享CPU格式(相对重要)
-cidfile="": 将容器的ID标识写入文件
-d=false: 分离模式,在后台运行容器,并且打印出容器ID
-e=[]:设置环境变量
-h="": 容器的主机名称
-i=false: 保持输入流开放即使没有附加输入流
-privileged=false: 给容器扩展的权限
-m="": 内存限制 (格式:<number><optional unit>, unit单位 = b, k, m or g)
-n=true: 允许镜像使用网络
-p=[]: 匹配镜像内的网络端口号
-rm=false:当容器退出时自动删除容器 (不能跟 -d一起使用)
-t=false: 分配一个伪造的终端输入
-u="": 用户名或者ID
-dns=[]: 自定义容器的DNS服务器
-v=[]: 创建一个挂载绑定:[host-dir]:[container-dir]:[rw|ro].如果容器目录丢失,docker会创建一个新的卷
-volumes-from="": 挂载容器所有的卷
-entrypoint="": 覆盖镜像设置默认的入口点
-w="": 工作目录内的容器
-lxc-conf=[]: 添加自定义-lxc-conf="lxc.cgroup.cpuset.cpus = 0,1"
-sig-proxy=true: 代理接收所有进程信号(even in non-tty mode)
-expose=[]: 让你主机没有开放的端口
-link="": 连接到另一个容器(name:alias)
-name="": 分配容器的名称,如果没有指定就会随机生成一个
-P=false: Publish all exposed ports to thehost interfaces 公布所有显示的端口主机接口
1,设定操作执行方式
++设定运行方式
-d:加上该参数确定这个容器是在后台运行。反之在前台运行,container的所有输出都可以在当前窗口中看到
+-a=[],指定挂载标准数据流,‘STDIN’,‘STDOUT’,‘STDERR’
+-i -t ,对于执行容器内的交互操作,例如,shell脚本,我们必须使用-i -t申请一个控制台同容器进行数据交互。
docker run -a stdin -a stdout -i -t ubuntu /bin/bash
+但是当通过管道同容器交互就不能使用-t,如:echo test | run -i busybox cat
-p 指定container绑定到宿主机的端口,-P从49153-65535中随机分配未被占用的端口绑定到宿主机上。--link container间内网访问
++设定id
+给container命名有三种方式:
1,使用uuid长命名,提交副本时产生的uuid。
2,使用uuid短命名, IMAGE ID。
3,使用name,docker images中的REPOSITORY
+当运行docker时有自动化要求,可以要求docker将ID输出到指定的文件中,方便后续操作,--cidfile=“”
++IPC设定
默认情况先,所有容器都开启了IPC命名空间。共享那次可以提高进程数据的交互速度。
++网络设定
默认情况下所有的container都开启了网络接口,同时可以接受任何外部数据的请求。
+--dns,默认情况下,container使用host的DNS设置,通过--dns来覆盖container内的dns的设置。
+--net=""
none:关闭container内的网络连接,内部只会有一个lookback接口。
bridge:默认选项,通过veth接口来连接
host:允许container使用host的网络堆栈信息
container:使用另一个container的网络堆栈信息
+--add-host="",动态向container中的/etc/hosts添加hostname信息
clean up
--rm ,需要短期运行一个前台container,产生的数据不需要保留,在使用完毕之后自动清理产生的数据。
安全配置
--security-opt
cpu和内存的配置
-m="",调整内存。
-c="", 调整cpu优先级。默认情况下所有的container享有相同的cpu优先级和cpu调度周期。-c="0"表示赋予当前container 1024个cpu共享周期。比如说:-c="0"启动c0,-c="512"启动c1,这时c0可以使用100%的cpu资源,c1可以使用50%的cpu资源。
runtime privilege linux capabilities LXC configuration
--privileged 加上该参数后,docker可以访问宿主机所有设备的权限。
--device=[],默认情况下,container对设备的读,写,创建设备文件的权限,使用:rwm来配合--device,控制这些权限。
docker run --device=/dev/sda:/dev/xvdc:rwm --rm -it centos fidsk /dev/xvdc
--cap-add/--cap-drop,配合--privileged,你可以更细致的控制container,默认使用这两个参数的情况下,可以有修改内核的权限,
例如:如果想让某个container拥有除了MKNOD之外的所有内核权限:docker run --cap-add=ALL --cap-drop=MKNOD
如果需要修改网络接口数据:docker run --cap-add=NET_ADMIN centos ip link add dummy0 type dummy
如果要挂载FUSE文件系统:docker run --cap-add SYS_ADMIN --device /dev/fuse sshfs
-v 当docker创建一个数据卷并挂载到容器中时使用-v来标记。
例如:docker -v /opt/app:/home/app -p 80:8000 -d --name centos
2,设定image的默认资源,也就是image使用者可以用此命令来覆盖image开发者在build阶段所设定的默认值
当开发者使用dockerfile进行build或者commit时,开发者可以设定一些image参数。这些参数有四个无法进行覆盖:FROM,MAINTARNER,RUN,ADD,其余参数都可以通过docker run进行覆盖。
+cmd,可选,可用用新命令覆盖旧命令
+--entrypoint="",指定当container执行时,需要启动那些进程。
例子:docker run -i -t --entrypoint /bin/bash example/redis -c ls -l
+--expose,dockerfile在网络方面除了提供一个expose之外,没有提供其他选项。
-p 指定container绑定到宿主机的端口,-P从49153-65535中随机分配未被占用的端口绑定到宿主机上。--link container间内网访问
+ENV
当container启动时,会自动在contarner中初始化变量:HOME,HOSTNAME,PATH,TERM。
可以通过-e来设定任意的环境变量,甚至覆盖原有的环境变量,或者是在dockerfile中通过ENV设定的环境变量。
+volume
设置共享文件系统
+user
container中默认的用户是root,-u,来覆盖默认用户
+workdir
container中默认的工作目录是根目录,-w,来覆盖默认工作目录。
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
dockerfile讲解
[root@localhost centos7]# cat Dockerfile
#
# MAINTAINER Carson,C.J.Zeong <zcy@nicescale.com>
# DOCKER-VERSION 1.6.2
#
# Dockerizing CentOS7: Dockerfile for building CentOS images
#
FROM centos:centos7.1.1503 #基础镜像也就是父镜像,docker-hub上pull下来
MAINTAINER Carson,C.J.Zeong <zcy@nicescale.com> #维护者信息
ENV TZ "Asia/Shanghai" #设置时区环境变量
ENV TERM xterm #
#ADD和copy都是复制文件,add比copy多了两个功能,1,被拷贝可以是链接地址,2,可以是压缩文件,拷贝到目的地后自动解压
ADD aliyun-mirror.repo /etc/yum.repos.d/CentOS-Base.repo
ADD aliyun-epel.repo /etc/yum.repos.d/epel.repo
#docker每执行一条命令都生成docker镜像的一层,docker镜像是分层的
RUN yum install -y curl wget tar bzip2 unzip vim-enhanced passwd sudo yum-utils hostname net-tools rsync man && \
yum install -y gcc gcc-c++ git make automake cmake patch logrotate python-devel libpng-devel libjpeg-devel && \
yum install -y --enablerepo=epel pwgen python-pip && \
yum clean all
#安装服务
RUN pip install supervisor
ADD supervisord.conf /etc/supervisord.conf
RUN mkdir -p /etc/supervisor.conf.d && \
mkdir -p /var/log/supervisor
#映射端口,宿主机随机匹配一个端口映射到22端口
EXPOSE 22
#docker每次启动的时候需要执行的命令
ENTRYPOINT ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisord.conf"]
[root@localhost centos7]# docker build -t csphere/centos:7.1 .
#-t 名字
#最后加dockerfile的路径
CM和ENTRYPOINT的区别
Dockerfile 用于自动化构建一个docker镜像。Dockerfile里有 CMD 与 ENTRYPOINT 两个功能咋看起来很相似的指令,开始的时候觉得两个互用没什么所谓,但其实并非如此:
CMD指令:
The main purpose of a CMD is to provide defaults for an executing container.
CMD在容器运行的时候提供一些命令及参数,用法如下:
CMD ["executable","param1","param2"] (exec form, this is the preferred form)
CMD ["param1","param2"] (as default parameters to ENTRYPOINT)
CMD command param1 param2 (shell form)
第一种用法:运行一个可执行的文件并提供参数。
第二种用法:为ENTRYPOINT指定参数。
第三种用法(shell form):是以”/bin/sh -c”的方法执行的命令。
如你指定:
CMD [“/bin/echo”, “this is a echo test ”]
build后运行(假设镜像名为ec):
docker run ec
就会输出: this is a echo test
是不是感觉很像开机启动项,你可以暂时这样理解。
注意点:
docker run命令如果指定了参数会把CMD里的参数覆盖: (这里说明一下,如:docker run -it ubuntu /bin/bash 命令的参数是指/bin/bash 而非 -it ,-it只是docker 的参数,而不是容器的参数,以下所说参数均如此。)
同样是上面的ec镜像启动:
docker run ec /bin/bash
就不会输出:this is a echo test,因为CMD命令被”/bin/bash”覆盖了。
ENTRYPOINT
字面意思是进入点,而它的功能也恰如其意。
An ENTRYPOINT allows you to configure a container that will run as an executable.它可以让你的容器功能表现得像一个可执行程序一样。
容器功能表现得像一个可执行程序一样,这是什么意思呢?
直接给个例子好说话:
例子一:
使用下面的ENTRYPOINT构造镜像:
ENTRYPOINT ["/bin/echo"]
那么docker build出来的镜像以后的容器功能就像一个/bin/echo程序:
比如我build出来的镜像名称叫imageecho,那么我可以这样用它:
docker run -it imageecho “this is a test”
这里就会输出”this is a test”这串字符,而这个imageecho镜像对应的容器表现出来的功能就像一个echo程序一样。 你添加的参数“this is a test”会添加到ENTRYPOINT后面,就成了这样 /bin/echo “this is a test” 。现在你应该明白进入点的意思了吧。
例子二:
ENTRYPOINT ["/bin/cat"]
构造出来的镜像你可以这样运行(假设名为st):
docker run -it st /etc/fstab
这样相当: /bin/cat /etc/fstab 这个命令的作用。运行之后就输出/etc/fstab里的内容。
ENTRYPOINT有两种写法:
写法一:
ENTRYPOINT ["executable", "param1", "param2"] (the preferred exec form)
写法二:
ENTRYPOINT command param1 param2 (shell form)
你也可以在docker run 命令时使用–entrypoint指定(但是只能用写法一)。
下面是我把ENTRYPOINT设为[“/bin/sh -c”]时候运行的情况:
linux-oj9e:/home/lfly/project/docker # docker run -it t2 /bin/bash
root@4c8549e7ce3e:/# ps
PID TTY TIME CMD
1 ? 00:00:00 sh
9 ? 00:00:00 bash
19 ? 00:00:00 ps
可以看到PID为1的进程运行的是sh,而bash只是sh的一个子进程,/bin/bash只是作为 /bin/sh -c后面的参数。
CMD可以为ENTRYPOINT提供参数,ENTRYPOINT本身也可以包含参数,但是你可以把那些可能需要变动的参数写到CMD里而把那些不需要变动的参数写到ENTRYPOINT里面例如:
FROM ubuntu:14.10
ENTRYPOINT ["top", "-b"]
CMD ["-c"]
把可能需要变动的参数写到CMD里面。然后你可以在docker run里指定参数,这样CMD里的参数(这里是-c)就会被覆盖掉而ENTRYPOINT里的不被覆盖。
注意点1:
ENTRYPOINT有两种写法,第二种(shell form)会屏蔽掉docker run时后面加的命令和CMD里的参数。
注意点2:
网上有资料说ENTRYPOINT的默认值是[”/bin/sh -c”],但是笔者在试验的时候得到的结果并不是这样的。
笔者使用ENTRYPOINT [“/bin/sh -c”] 指令构造一个以/bin/sh -c为进入点的镜像,命名为sh,然后我可以这样运行:
docker run -it sh “while(ture ) do echo loop; done”
运行结果就是无限输出loop。但如果直接运行一个ubuntu:14.10镜像,情况不是这样的:
docker run -it ubuntu:14.10 “while(ture ) do echo loop; done”
得到这样的错误:
linux-oj9e:/home/lfly # docker run -it ubuntu:14.10 “while(true) do echo this; done” 2014/11/16 18:07:53 Error response from daemon: Cannot start container 4bfe9c6faeec3ed465788a201a2f386cb1af35aba197dbc78b87c0d5dda1f88e: exec: “while(true) do echo this; done”: executable file not found in $PATH
可以猜想默认情况下ENTRYPOINT并不是[“/bin/sh -c”]。
而且直接运行ubuntu:14.10列出程序也可以看到PID为1的程序并不是sh。所以更否定了网友的说法,ENTRYPOINT并不默认为[“/bin/sh -c”] 。
-------------------------------------------------------
docker命令
搜索镜像
#docker search centos6
安装镜像
#docker pull treasureboat/centos6
查看安装的镜像
#docker images
删除一个镜像
#docker rmi centos7
查看一个镜像的历史
#docker history centos7啊
运行容器的shell界面
# docker run -i -t docker.cn/docker/centos:centos6 /bin/bash
删除一个容器
#docker rm name/id
停止、启动、杀死一个容器
#docker stop Name/ID
#docker start Name/ID
#docker kill Name/ID
从一个容器中取日志
#docker diff Name/ID
显示一个运行的容器里面的进程信息
#docker top Name/ID
从容器里面拷贝文件/目录到本地一个路径
#docker cp Name:/container_path to_path
#docker cp ID:/container_path to_path
重启一个正在运行的容器
#docker restart Name/ID
退出再进
#docker exec -it websit /bin/bash
------------------------------------
渗透执行
如果想通过ssh进入container,需要安装nsenter,安装步骤如下:
wget https://www.kernel.org/pub/linux/utils/util-linux/v2.24/util-linux-2.24.tar.gz
tar -zxf-cd util-linux-2.24
./configure –without-ncurses
make
cp nsenter /usr/local/bin/
这个地方有个坑,之前我写的是make && make install,经阿里云的技术团队测试,make之后千万不能make install,make install后会替代操作系统底层的一些东西,直接影响linux操作系统的启动,在阿里云上会导致ubuntu14.0.4不能启动,其实只需要把nsenter 复制到/usr/local/bin目录下即可。国内其他文档介绍安装nsenter的时候都没说明这些,在此特别写篇博客记录一下。
找到mysql容器的第一个进程的pid
pid=`docker inspect --format "{{ .State.pid }}" mysql_1 `
然后渗入(需要root权限)
sudo nsenter --target $PID --mount --uts --ipc --net --pid