docker学习笔记

  • 时间:2015-09-29
  • 方式:

目录


一、简介
    1、基本概念
二、Docker实战
    2.1、安装Docker
    2.2、HelloWorld
    2.3、Docker本地仓库
        2.3.1、本地仓库安装(v1)
        2.3.2、本地仓库使用(v1)
        2.3.3、新版本仓库(v2)
    2.4、Docker集成SSH
        2.4.1、DockerFile
    2.5、Docker网络配置
        2.5.1、Docker网络配置命令
        2.5.2、对外映射端口
        2.5.3、网桥模式
        2.5.4、网桥模式-静态IP
    2.6、Flannel
        2.6.1、Flannel简介
        2.6.2、Flannel安装使用
    2.7、shipyard
        2.7.1、shipyard安装
        2.7.2、shipyard使用
        2.7.3、shipyard优缺点
    2.8、k8s(待完成)
三、Docker常用命令
    3.1、镜像管理
        3.1.1、search
        3.1.2、pull
        3.1.3、push
        3.1.4、images
        3.1.5、tag
        3.1.6、rmi
    3.2、容器管理
        3.2.1、run
        3.2.2、ps
        3.2.3、inspect
        3.2.3、rm
        3.2.4、attach
        3.2.5、logs
        3.2.6、start&stop
        3.2.7、exec
    3.3、镜像构建
        3.3.1、commit
        3.3.2、build & DockerFile
        3.3.3、save & load
    3.3、docker信息
        3.4.1、info
        3.4.2、version
四、DockerAPI使用
    4.1、打开api的远程调用
    4.2、常用API
        4.2.1、容器操作
        4.2.2、镜像操作
        4.2.3、其他指令
    4.3、官方lib
五、Docker性能测试

简介


Docker 是一个开源项目,诞生于 2013 年初;Docker 项目的目标是实现轻量级的操作系统虚拟化解决方案。 Docker 的基础是 Linux 容器(LXC)等技术。

在 LXC 的基础上 Docker 进行了进一步的封装,让用户不需要去关心容器的管理,使得操作更为简便。用户操作 Docker 的容器就像操作一个快速轻量级的虚拟机一样简单。

作为一种新兴的虚拟化方式,Docker 跟传统的虚拟化方式相比具有众多的优势。

  • 一键部署,部署原子化:我们可以狭隘的把 docker 理解成是一个应用打包解决方案:把运维环境、代码进行打包,在部署的时候,只需要载入该镜像,则服务被运行起来。这个过程是原子化的,所以很大程度避免了部署过程中人为或者不可预料的意外。同时也大大加快了部署过程,基本上可以在1分钟内部署好一个业务,因此也具有很大的弹性扩展优势。
  • 隔离和性能:docker专注于隔离,并且镜像是只读的。于是提高了业务的安全性——复用主机的各业务之间,一旦被黑,影响的因素会少很多。并且 docker 仅仅做了隔离,并不虚拟硬件,所以和虚拟机比,没有虚拟化带来的性能消耗。

基本概念

  • 镜像:一个可以被运行的打包好程序,用来创建容器;一个镜像可以包含操作系统、需要运行的程序等;
  • 容器:镜像的实例;它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台;
  • 仓库:用于存放镜像;可以有私有仓库和公开仓库;

Docker实战


安装Docker


Docker的安装比较简单;现在已经默认的加到了centos等系统的源中;运行下述命令即可安装docker;

yum install -y docker-io

docker 命令安装后需要启动docker服务;运行下述命令可以启动docker服务;

service docker start        #启动docker服务
docker version              #查看docker版本信息

可以看到类似如下信息证明安装成功;

dockerversion.png

docker默认会使用在/var/lib/docker目录作为数据文件的存放地址;如果这个目录下空间较小;可以将这个文件移动到其他目录下然后软链下就可以了;

cd /var/lib/docker
mkdir -p /data/DockerData/
mv docker/ /data/DockerData/docker/
ln -s /data/DockerData/docker/ docker

HelloWorld


[root@h0022062 ~]# docker run docker.io/hello-world

Hello from Docker.
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker Hub account:
 https://hub.docker.com

For more examples and ideas, visit:
 https://docs.docker.com/userguide/

Docker本地仓库


由于大部分人使用docker都是内部使用;所有肯定不能把镜像托管到公共的仓库内;

可以通过以下方法安装docker本地仓库;

本地仓库安装

首先需要安装一些基本依赖;

sudo yum install -y python-devel libevent-devel gcc xz-devel open-ssl

由于测试机器上没有python-pip的源;所以需要再单独安装python-pip

wget --no-check-certificate https://github.com/pypa/pip/archive/1.5.5.tar.gz

tar 1.5.5.tar.gz
cd pip-1.5.5/
python setup.py install

由于这里的python-pip不是最近版本;所以需要更新以下

pip install -U pip

git clone https://github.com/docker/docker-registry.git
cd docker-registry
python setup.py install

如果遇到如下问题: /usr/include/openssl/opensslconf.h:31: Error: CPP #error ""This openssl-devel package does not work your architecture?"". Use the -cpperraswarn option to continue swig processing. error: command 'swig' failed with exit status 1

这里是M2Crypto安装不上;需要手动处理下,然后再继续安装:

wget https://pypi.python.org/packages/source/M/M2Crypto/M2Crypto-0.22.3.tar.gz#md5=573f21aaac7d5c9549798e72ffcefedd

tar zxvf M2Crypto-0.22.3.tar.gz

M2Crypto

python setup.py build
本地仓库使用

1、启动本地仓库;这里使用gunicorn来启动docker_registry 服务;在启动之前有一些环境需要初始化;

pip install gevent werkzeug  jinjia2 itsdangerous redis

#如果发现启动如下命令时还有没有安装的包;使用pip安装即可
#-c后面默认的目录是你机器上py的目录;如果找不到;根据提示的目录地址再把文件拷贝过去即可
gunicorn -c contrib/gunicorn.py docker_registry.wsgi:application

启动后即可使用本地仓库;使用方法为

#将本地容器推送给本地仓库
docker push 127.0.0.1:5000/centos

#从本地仓库中查询镜像
docker search 127.0.0.1:5000/centos

#从本地仓库中拉取镜像
docker pull 127.0.0.1:5000/centos

在其他机器上使用本地仓库需要修改docker配置文件;

[root@h00xxxxxx ~]# cat /etc/sysconfig/docker
# /etc/sysconfig/docker
#
# Other arguments to pass to the docker daemon process
# These will be parsed by the sysv initscript and appended
# to the arguments list passed to docker -d
other_args="--insecure-registry 192.168.xx.xx:5000"


service docker restart

Docker集成SSH


由于docker的基础镜像都较小;为了方便使用;我们需要做一些基础镜像;如ssh;这里只示例如何集成SSH

DockerFile
FROM 127.0.0.1:5010/centos

RUN yum install -y openssh-server openssh openssh-clients sysstat net-tools
RUN mkdir /var/run/sshd
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key
COPY sshd /etc/pam.d/sshd
RUN /bin/echo 'root:xxxxxx' |chpasswd
EXPOSE 22
CMD /usr/sbin/sshd -D

由于某些机器存在ssh连接后秒断的情况;需要修改sshd的默认配置文件:

cat sshd

#%PAM-1.0
auth       required     pam_sepermit.so
auth       substack     password-auth
auth       include      postlogin
account    required     pam_nologin.so
account    include      password-auth
password   include      password-auth
# pam_selinux.so close should be the first session rule
session    required     pam_selinux.so close
#这一行注释掉
#session    required     pam_loginuid.so
# pam_selinux.so open should only be followed by sessions to be executed in the user context
session    required     pam_selinux.so open env_params
session    optional     pam_keyinit.so force revoke
session    include      password-auth
session    include      postlogin

Docker网络配置


Docker网络配置命令

Docker的网络配置分为2种; 一个是在Docker服务启动的时候,这是可以指定网桥、网关、是否开启IP6等信息; 另一个是Docker Run在启动容器的时候;这时可以指定多种网络模式;有网桥、无网络、主机绑定、容器绑定等;

Docker重要配置参数

  • -b :指定使用的网桥;默认为docker0
  • --default-gateway=IP:为容器的eth0网卡分配默认的网关地址;如果这个地址不指定;则默认分配网桥的地址;
  • --bip=CIDR;为docker0指定一个IP地址和子网掩码,格式为192.168.1.5/24
  • --fixed-cidr:设置docker0的子网地址的范围;格式为192.168.1.0/25;必须是—bip的子集
  • -H SOCKET;Docker服务监听哪个SOCKET地址;用于远程API
  • --icc:如果icc==true;docker启动时会往iptables的FORWARD中添加一条全局的ACCEPT的规则;而icc未false时会把这个策略修改为DROP;
  • --iptables;当这个值为flase时;docker启动时不会更改主机的iptables的配置;
  • --dns:设置dns服务器的ip地址;写入到容器的/etc/resolv.conf文件

DockerRun启动时的网络配置命令

  • -h:设置主机名称
  • --link:格式为—link=<容器ID或者是名称>:别名,作用是设置容器间的访问
  • -P:用于暴漏端口,识别所有dockerfile中开放的端口,并随机映射到49000-49900之间
  • -p:更常用,指定端口映射;格式为-p <本地端口>:<容器端口>
  • --net=bridge|none|container|host;这里是选择启动容器的连接方式;有四个选择
    • --net=bridge;默认选项,不需要指定;用网桥的方式来连接docker容器
    • --net=none 告诉docker为docker分配网络接口,但是不做地址分配;可以参考”网桥模式-静态IP”
    • --net=host:使用宿主机器的网络接口;
    • --net=container:使用已有容器的网络接口;

示例: TestHost

TestC1

TestC2

对外映射端口

对外映射端口的方式比较简单;在启动docker容器的时候使用-p命令即可;如

docker run -p 33061:3306 -d mysql /usr/bin/mysqld_safe

这样你在访问本地33061端口的时候就会映射到容器内的3306端口; 对外暴漏端口的好处时使用简单;原生的docker即可支持; 对外映射端口的坏处是需要我们去做好端口的管理、规划工作;去避免端口的冲突;

网桥模式

这里使用的网桥配置工具为brctl;需要先安装下;

yum install -y bridge-utils

我们先删除docker默认启动的网桥docker0

service docker stop
ip link set dev docker0 down
brctl delbr docker0
iptables -t nat -F POSTROUTING

然后我们再添加一个新的网桥

brctl addbr bridge0
ip addr add 172.17.42.1/24 dev bridge0
brctl stp bridge0 off
ip link set dev bridge0 up

修改docker的启动文件后启动docker服务即可;

[root@xxxx shipyard]# cat /etc/sysconfig/docker-network 
# /etc/sysconfig/docker-network
DOCKER_NETWORK_OPTIONS="-b=bridge0" 
service docker start

启动docker容器

dl.dockerpool.com:5000/registry   latest              8e9a29f977a7        11 months ago       430.1 MB
[root@xxxx shipyard]# docker run -d 127.0.0.1:5010/centos-sshd
61032fdc02583e45c7c403cdf08e0d50ee0bdfda1fb76044c1dafabe85ab06e2
[root@xxxx shipyard]# docker inspect --format='' 61032fdc02583e45c7c403cdf08e0d50ee0bdfda1fb76044c1dafabe85ab06e2
172.17.42.3

可以看到已经为容器分配了一个独立ip;这时如果需要从其他同物理网段机器上访问这个容器;需要添加一条路由信息;

route  add -net 172.17.42.0/24 gw 172.16.82.176

#测试登陆
[root@slave ~]# ssh root@172.17.42.3
The authenticity of host '172.17.42.3 (172.17.42.3)' can't be established.
RSA key fingerprint is 95:c2:eb:20:50:36:b3:af:ab:3b:17:33:72:c6:fc:6d.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '172.17.42.3' (RSA) to the list of known hosts.
root@172.17.42.3's password:
[root@61032fdc0258 ~]#
[root@61032fdc0258 ~]#
[root@61032fdc0258 ~]# exit
logout
Connection to 172.17.42.3 closed.
网桥模式-静态IP

如果希望使用静态IP;可以在启动时使用-net=none命令指定不分配IP;然后再使用ip netns给命名空间内的容器赋值IP; 分配IP的操作方法如下:

br_name=bridge0
cid=$(docker run -d -i --net=none -t centos-sshd)
pid=$(docker inspect -f '' $cid)
mkdir -p /var/run/netns
ln -s /proc/$pid/ns/net /var/run/netns/$pid
ip link add q$pid type veth peer name r$pid
brctl addif $br_name q$pid
ip link set q$pid up
fixed_ip='172.17.42.4/24'
gateway='172.17.42.1'
ip link set r$pid netns $pid
ip netns exec $pid ip link set dev r$pid name eth0
ip netns exec $pid ip link set eth0 up
ip netns exec $pid ip addr add $fixed_ip dev eth0
ip netns exec $pid ip route add default via $gateway

注意:其他机器访问还是需要添加路由

清理IP地址的操作方法如下:

docker stop $cid
docker rm $cid
ip netns delete $pid

flannel


shipyard介绍

使用docker原生的网络配置可以实现多台宿主机器上的容器互联;但是需要配置网关;较为繁琐; flannel使用了(overlay networks)技术;可以让为主机分配一个单独的虚拟子网;可以很方便的另多台宿主机之间的容器进行通信;

盗图一张:

flannel 数据从源容器中发出后,经由所在主机的docker0虚拟网卡转发到flannel0虚拟网卡; Flannel通过Etcd服务维护了一张节点间的路由表

源主机的flanneld服务将原本的数据内容UDP封装后根据自己的路由表投递给目的节点的flanneld服务,数据到达以后被解包,然后直 接进入目的节点的flannel0虚拟网卡,然后被转发到目的主机的docker0虚拟网卡,最后就像 本机容器通信一下的有docker0路由到达目标容器。

shipyard安装使用

flannel使用需要安装etcd及flannel;只可以在github下载到的最新的编译版本;

主节点:

#下载安装包
wget http://vpn.violetgo.com/etcd-v2.2.0-linux-amd64.tar.gz
wget http://vpn.violetgo.com/flannel-0.5.3-linux-amd64.tar.gz
tar zxvf flannel-0.5.3-linux-amd64.tar.gz
tar zxvf etcd-v2.2.0-linux-amd64.tar.gz

#启动etch服务
cd ./etcd-v2.2.0-linux-amd64/
./etcd --listen-client-urls http://0.0.0.0:4001 --listen-peer-urls http://0.0.0.0:7001

#设置地址范围;这个key是flannel默认使用的key
etcdctl set /coreos.com/network/config '{ "Network": "172.17.0.0/16" }'

#启动flannel服务并且配置docker地址
./flanneld &
./mk-docker-opts.sh –i
source /run/flannel/subnet.env

#重启docker;
service docker stop
ifconfig docker0 ${FLANNEL_SUBNET}
service docker start

其他节点;

scp -r root@192.168.77.114:/data/docker/flannel/  /data/docker/
./flanneld -etcd-endpoints=http://192.168.77.114:4001
source /run/flannel/subnet.env

#重启docker;
service docker stop
ifconfig docker0 ${FLANNEL_SUBNET}
service docker start

验证,在82.176上启动

TestF1

另一台机器上

TestF2

启动IP为172.17.3.9

TestF3

shipyard


shipyard是一款docker的管理页面;之所以想用他是因为他支持跨机器的管理功能;

环境依赖:Docker1.6 如果是1.6一下的docker;在使用swarm时会出现一下错误;

[root@h0082176 shipyard]# docker run -t swarm m --replication --addr 172.16.82.176:3375 --host tcp://0.0.0.0:3375 consul://192.168.77.114:8500
INFO[0000] Listening for HTTP                            addr=0.0.0.0:3375 proto=tcp
INFO[0000] Leader Election: Cluster leadership lost     
INFO[0000] New leader elected: 192.168.77.114:3375      
ERRO[0000] engine 172.16.82.176:2375 is running an unsupported version of Docker Engine. Please upgrade to at least 1.6.0 
INFO[0000] Registered Engine h0022062 at 192.168.77.114:2375 
shipyard安装

我这边的网络不好;很多docker的镜像都无法下载;所以我的选择是在境外vps上使用docker pull 下载镜像后再导出导入到本地; 未测试过直接使用代理行不行; 在主节点上安装shipyard

docker load < alpine.tar
docker load < consul.tar
docker load < curl.tar
docker load < proxy.tar
docker load < rethinkdb.tar
docker load < shipyard.tar
docker load < swarm.tar

cat testDeploy.sh | bash -s

在从点上安装shipyard

1、修改配置地址

[root@h0082176 ~]# vim /etc/sysconfig/docker

  1 # /etc/sysconfig/docker
  2 #
  3 # Other arguments to pass to the docker daemon process
  4 # These will be parsed by the sysv initscript and appended
  5 # to the arguments list passed to docker -d
  6
  7 other_args="--insecure-registry 192.168.77.114:5010 -H 0.0.0.0:2375 -H unix:///var/run/docker.sock

2、修改testDeploy.sh文件,需要将"$ACTION" = "node"下的startproxy、startswarm_manager这两行注释掉;

302 
303     echo "Adding Node"
304     echo " -> Starting Cert Volume"
305     start_certs
306     echo " -> Starting Proxy"
307     #start_proxy
308     echo " -> Starting Swarm Manager"
309     #start_swarm_manager $DISCOVERY

3、部署节点

docker load < alpine.tar
docker load < consul.tar
docker load < curl.tar
docker load < proxy.tar
docker load < rethinkdb.tar
docker load < shipyard.tar
docker load < swarm.tar

cat testDeploy.sh | ACTION=node DISCOVERY=consul://192.168.77.114:8500 bash -s
shipyard使用

shipyard的主要页面大概有以下几个;

第一个是docker的所有的容器列表;这个页面可以帮助我们创建、了解现有容器的状态;

这里可以看到所有节点上的启动的容器和没有启动的容器;

可以进行的操作包括重启、停止、销毁、重命名、查看状态、attach操作、查看控制台的输出日志等

容器

点击容器页面上的放大镜图标可以进入详情页面;

这个页面是容器的一些详细信息;

包括容器的运行命令、开放的端口、进程信息、运行主机和主机上的cpu、内存等;

详情

镜像页面可以看到所有的镜像、镜像所在的主机、镜像大小等信息;

可以删除和拉取新的镜像;

镜像

所有部署docker节点的机器的基本信息;

包括IP、容器数、cpu核心、内存大小、内核版本等;

节点

可以添加一个仓库地址;点击仓库地址进入后可以看到这个仓库上所有的镜像以及镜像依赖、镜像大小信息;

仓库

在仓库页面中点击放大镜;可以看到镜像的生产过程;包括每一步执行的命令和添加到镜像的最终大小等信息;

DockerFile的生产过程

shipyard优缺点
优点
  • 部署使用较为简单
  • 可以在一个页面上对所有的节点进行管理
  • 可以清楚的看到每个容器的运行情况
  • 可以清楚的看到每个镜像的生成过程
缺点
  • 无法push容器,也就是容器的操作无法保存
  • 不支持docker无法编译出新的镜像
  • 目前只有测试版可以使用、需要修改改编译脚本才能在子节点上通过
  • 开发组成员只有两个;活跃度不高
  • 只支持v1版本的仓库;
shipyard的缺陷

1、页面无法删除有特殊名称的仓库 2、容器页面经常无法打开

k8s

TODO

Docker常用命令


镜像管理


search

命令格式: docker search

作用是搜索仓库上的镜像;注意 如果需要查询私服上的镜像;需要带完整的私服名,如:

docker search 192.168.77.114:5000/centos

如果查询时提示如下信息,按照提示在你需要查询的机器上的docker的配置文件中添加 --insecure-registry 192.168.77.114:50000

 If this private registry supports only HTTP or HTTPS with an unknown CA certificate, please add `--insecure-registry 192.168.77.114:50000` to the daemon's arguments. 
pull

命令格式: docker pull

作用是拉取镜像,如果需要拉取私服镜像;则跟上完整的私服路径,如:

docker pull 192.168.77.114:5000/centos
push

命令格式: docker push

作用是推送镜像到服务器,如果需要推送到私服;则跟上完整的私服路径,如:

docker push 192.168.77.114:5000/centos

这里要求你的镜像名称既包含私服的名称,如果不包含;需要使用tag重新标记

tag

命令格式:docker tag <原有名称> <仓库路径>/<镜像名称>

docker tag centos 127.0.0.1:5000/centos
images

命令格式: docker images

作用为列出本机的所有镜像;

-q 只列出ID --filter "dangling=true" 只列出tag=的镜像

rmi

命令格式: docker images

按名称或者是镜像ID删除镜像;在删除镜像时需要保证所有基于该镜像的容器全部处于退出状态;

容器管理


run

docker run命令是从镜像启动容器的一个命令;基本上是所有docker操作的一个入口;命令格式

docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

重要参数

  • -m :内存大小限制,如 -m 100m
  • -c
  • -d :是否以后天的形式运行容器
  • -p :对外暴漏的端口,格式为-p <本地端口>:<容器端口>,可以指定多个
  • -v :挂载一个目录作为数据卷,格式 -v <本地目录>:<容器目录>
  • --rm :在容器退出时自动删除
  • -name :容器的名称
  • --link :连接其他的容器;格式为 --link <容器名称>:<容器内名称> 可以指定多个
  • -i : 容器会接受控制台的指令,无法和-d同时使用
  • -t : 分配一个伪tty,通常和-i一起使用
  • --net :设置容器的网络模式;有四种
    • bridge为默认,走网桥自动分配;
    • none不分配网络地址需要手动配置;
    • container复用另一个容器的网络堆栈;如--net container:redis
    • host复用主机的网络堆栈

参数后面跟的是镜像需要执行的命令;默认为docker的CMD;可以另行指定;如

docker run -t -i centos /bin/bash

ps

列出docker中挣扎运行的容器;

命令格式为:

docker ps [OPTIONS]

重要参数:

  • -a:列出所有容器,默认只列出运行的
  • --filter:过滤,k=v的格式,如只列出状态为退出的容器,--filter=status=exited
  • -q: 只列出ID
inspect

命令格式 docker inspect [OPTIONS] CONTAINER|IMAGE

作用返回容器或者是镜像的信息;

重要参数

  • --format="":docker inspect返回的格式为json,format可以按json相应的关键字进行过滤;如

    [root@h0082176 ~]# docker inspect --format="" b01643f3931a
    172.17.0.5
    
rm

删除容器;

docker rm 容器id1 容器id2
attach

连接上一个目标容器,可以看到容器在控制台的输出、并且容器可以接受到控制台的输入

格式为 docker attach 容器id

logs

docker 的输出日志查看;格式为docker logs 容器id

start&stop

启动和停止容器。

格式为docker start|stop 容器id

exec

在一个正在运行的容器中运行命令;格式

docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

重要参数

  • -d:是否后台运行命令
  • -i : 容器会接受控制台的指令,无法和-d同时使用
  • -t : 分配一个伪tty,通常和-i一起使用

示例:

[root@h0082176 ~]# docker ps
CONTAINER ID        IMAGE                            COMMAND                CREATED             STATUS              PORTS                    NAMES
b01643f3931a        violetgo/shadowsocks-server-go   "/shadowsocks-server   3 months ago        Up 2 days           0.0.0.0:1011->1011/tcp   sserver                
[root@h0082176 ~]# docker exec b01643f3931a /shadowsocks-server --help
Usage of /shadowsocks-server:
  -c="config.json": specify config file
  -core=0: maximum number of CPU cores to use, default is determinied by Go runtime
  -d=false: print debug message
  -k="": password
  -m="": encryption method, default: aes-256-cfb
  -p=0: server port
  -t=300: timeout in seconds
  -version=false: print version

镜像构建


commit

将容器提交成一个镜像;可以用于保存容器中的操作;作为镜像的创建方法之一;

命令格式:docker commit [REPOSITORY[:TAG]]

示例:

[root@h0082176 ~]# docker commit b01643f3931a 192.168.77.114:5010/shadowsocks-server-go
4c5e52aa27a5030592964889b76862125871feccf6b70aded5ac6e6c9998c576

[root@h0082176 ~]# docker images
REPOSITORY                                  TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
192.168.77.114:5010/shadowsocks-server-go   latest              4c5e52aa27a5        32 seconds ago      5.309 MB
build

将dockerfile编译成docker镜像;命令格式为

docker build [OPTIONS] PATH | URL | -

重要参数:

  • --rm:编译完成后删除中间容器
  • -t:编译后的tag
  • PATH:DockerFile所在的目录,必须是相对目录;

DockerFile用来创建一个自定义的image,包含了用户指定的软件依赖等;是一种比较常见的docker镜像的创建方法;

重要关键字

  • FROM:基于哪个镜像
  • MAINTAINER:镜像的创建人
  • RUN:运行命令,一般用于安装软件;每条RUN会提交一个新的镜像,所有CD等操作并不会被保留
  • EXPOSE:对外保留的端口
  • ENV:指定环境变量;格式为env key value ;如ENV JAVA_HOME /usr/server/jdk/
  • COPY:复制文件到容器
  • CMD:Docker容器启动时执行的命令,只有最后一条生效;
  • WORKDIR:工作目录,用于cd
save & load

save命令是将docker镜像导成本地文件;用法为

docker save -o 导出文件名 镜像名称

load命令是将docker镜像导成的文件再倒入成镜像

docker load < 导出文件名

docker信息


info

显示docker的基本信息,包括容器数、镜像数、存储目录等;用法 docker info

也可以用来显示远程主机上的docker信息,用法为 docker -H remoteIP:port info

version

显示docker的版本号;用法 docker version

DockerAPI使用


打开api的远程调用


Docker Remote API 提供了Http接口用来可以远程的操作Docker;为了打开Docker Remote API;需要在docker启动的配置文件中增加如下配置:

 -H tcp://0.0.0.0:1234 -H unix:///var/run/docker.sock

如果是从节点;端口可以修改为2375(swarm默认);

常用API


容器操作

1、获取容器

URL:GET /containers/json

重要参数:

  • all 是否显示所有容器
  • limit 限制返回数量
  • size 是否显示容器大小
  • filters 使用json编码的map格式;可用的值有
    • exited= – 容器退出码为
    • status 容器的状态为以下几种(restarting|running|paused|exited)

示例:

curl http://127.0.0.1:1234/containers/json?all=1\&limit=1

[{"Id":"3405c3b121d59eb2caf46a3465d5b8303cfa3be196aad82439db32f3e01395db","Names":["/thirsty_turing"],"Image":"127.0.0.1:5010/centos-flume","Command":"/bin/sh -c /start.sh","Created":1443172047,"Ports":[{"PrivatePort":22,"Type":"tcp"}],"Labels":{"License":"GPLv2","Vendor":"CentOS","com.docker.swarm.id":"f99423ba2c02dca0a5360df52f9ab6b3fa0c346e4adc1e08be8f4faff52e67ca"},"Status":"Up 2 days"}]

2、创建容器

URL:POST /containers/create?name=xx

重要参数:

  • name:容器的名字

请求体为容器的配置,容器的配置参考docker run命令

{
     "Hostname":"",     
     "Domainname": "",  
     "User":"",
     "Memory":0,
     "MemorySwap":0,
     "CpuShares": 512,
     "Cpuset": "0,1",
     "AttachStdin":false,
     "AttachStdout":true,
     "AttachStderr":true,
     "PortSpecs":null,
     "Tty":false,
     "OpenStdin":false,
     "StdinOnce":false,
     "Env":null,
     "Cmd":[
             "date"
     ],
     "Image":"ubuntu",
     "Volumes":{
             "/tmp": {}
     },
     "WorkingDir":"",
     "NetworkDisabled": false,
     "ExposedPorts":{
             "22/tcp": {}
     },
     "RestartPolicy": { "Name": "always" }
}

返回容器的ID

3、容器信息

URL: GET /containers/<容器ID>/json

示例

[root@h0022062 ~]# curl http://127.0.0.1:1234/containers/210448f1802c/json
    {"Id":"210448f1802c49f23fb45b5f35d52461e9fb24424648e771d3676a8b276c11e8","Created":"2015-09-25T07:21:38.29666668Z","Path":"rethinkdb","Args":["--bind","all"],"State":{"Running":true,"Paused":false,"Restarting":false,"OOMKilled":false,"Dead":false,"Pid":10165,"ExitCode":0,"Error":"","StartedAt":"2015-09-25T07:21:38.754120768Z","FinishedAt":"0001-01-01T00:00:00Z"},"Image":"bb270de71f333226b16a694f85a472a4353079c9566071416f5e03ea31002687","NetworkSettings":{"Bridge":"bridge0","EndpointID":"c9ff03643b025d3c8f50221f7c2fd2be2238b50b13ce717997b9aae4c479c5cb","Gateway":"172.17.42.1","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"HairpinMode":false,"IPAddress":"172.17.42.29","IPPrefixLen":24,"IPv6Gateway":"","LinkLocalIPv6Address":"","LinkLocalIPv6PrefixLen":0,"MacAddress":"02:42:ac:11:2a:1d","NetworkID":"c2fb14ff4c24761f7d36f0feb52533d6d448b888afa14db8e57b35a9c8f275e9","PortMapping":null,"Ports":{"28015/tcp":null,"29015/tcp":null,"8080/tcp":null},"SandboxKey":"/var/run/docker/netns/210448f1802c","SecondaryIPAddresses":null,"SecondaryIPv6Addresses":null},"ResolvConfPath":"/data/DockerData/docker/containers/210448f1802c49f23fb45b5f35d52461e9fb24424648e771d3676a8b276c11e8/resolv.conf","HostnamePath":"/data/DockerData/docker/containers/210448f1802c49f23fb45b5f35d52461e9fb24424648e771d3676a8b276c11e8/hostname","HostsPath":"/data/DockerData/docker/containers/210448f1802c49f23fb45b5f35d52461e9fb24424648e771d3676a8b276c11e8/hosts","LogPath":"/data/DockerData/docker/containers/210448f1802c49f23fb45b5f35d52461e9fb24424648e771d3676a8b276c11e8/210448f1802c49f23fb45b5f35d52461e9fb24424648e771d3676a8b276c11e8-json.log","Name":"/shipyard-rethinkdb","RestartCount":0,"Driver":"devicemapper","ExecDriver":"native-0.2","MountLabel":"","ProcessLabel":"","Volumes":{"/data":"/data/DockerData/docker/volumes/7c9a685750faa858e441df835dd905464c134b4564c921a9e78f8572c366238c/_data"},"VolumesRW":{"/data":true},"AppArmorProfile":"","ExecIDs":null,"HostConfig":{"Binds":null,"ContainerIDFile":"","LxcConf":[],"Memory":0,"MemorySwap":0,"CpuShares":0,"CpuPeriod":0,"CpusetCpus":"","CpusetMems":"","CpuQuota":0,"BlkioWeight":0,"OomKillDisable":false,"Privileged":false,"PortBindings":{},"Links":null,"PublishAllPorts":false,"Dns":null,"DnsSearch":null,"ExtraHosts":null,"VolumesFrom":null,"Devices":[],"NetworkMode":"bridge","IpcMode":"","PidMode":"","UTSMode":"","CapAdd":null,"CapDrop":null,"RestartPolicy":{"Name":"always","MaximumRetryCount":0},"SecurityOpt":null,"ReadonlyRootfs":false,"Ulimits":null,"LogConfig":{"Type":"json-file","Config":{}},"CgroupParent":""},"Config":{"Hostname":"210448f1802c","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"PortSpecs":null,"ExposedPorts":{"28015/tcp":{},"29015/tcp":{},"8080/tcp":{}},"Tty":true,"OpenStdin":true,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","RETHINKDB_PACKAGE_VERSION=2.1.3~0jessie"],"Cmd":["rethinkdb","--bind","all"],"Image":"rethinkdb","Volumes":{"/data":{}},"VolumeDriver":"","WorkingDir":"/data","Entrypoint":null,"NetworkDisabled":false,"MacAddress":"","OnBuild":null,"Labels":{},"Init":""}}

4、容器内的运行程序查询

URL:GET /containers/(id)/top

[root@h0022062 ~]# curl http://127.0.0.1:1234/containers/210448f1802c/top
{"Processes":[["root","10165","3788","0","Sep25","pts/3","00:02:12","rethinkdb --bind all"],["root","10737","10165","0","Sep25","pts/3","00:00:00","rethinkdb --bind all"]],"Titles":["UID","PID","PPID","C","STIME","TTY","TIME","CMD"]}

4、容器log

URL:GET /containers/(id)/logs

重要参数:

  • follow:是否返回stream
  • stdout:是否返回stdout
  • stderr:是否返回stderr
  • tail:返回多少行
  • timestamps:是否返回时间戳

示例

[root@h0022062 ~]# curl http://127.0.0.1:1234/containers/210448f1802c/logs?tail=10\&stdout=1
Listening for intracluster connections on port 29015
error: Failed to create sockets for listener on port 28015, falling back to IPv4 only
Listening for client driver connections on port 28015
error: Failed to create sockets for listener on port 8080, falling back to IPv4 only
Listening for administrative HTTP connections on port 8080
Listening on addresses: 127.0.0.1, 172.17.42.29
Server ready, "210448f1802c_dvi" 3631a825-b6c4-4deb-9bfd-281d364d52ef
warn: Problem when checking for new versions of RethinkDB: HTTP request to update.rethinkdb.com failed.
warn: Problem when checking for new versions of RethinkDB: HTTP request to update.rethinkdb.com failed.
warn: Problem when checking for new versions of RethinkDB: HTTP request to update.rethinkdb.com failed.

5、导出容器

URL:GET /containers/(id)/export

返回包为容器的stream

6、启动停止容器

启动容器

URL:GET /containers/(id)/start

停止容器

URL:GET /containers/(id)/stop?t=xx

t为停止时等待的秒数

7、删除容器

URL:DELETE /containers/(id)

参数: * v:是否删除数据卷 * force:是否强制删除

镜像操作

1、镜像列表

URL:GET /images/json?all=0

重要参数

  • all:是否显示所有镜像
  • filters:使用json编码的map格式;可用的值有
    • dangling=true
  • filter:只返回指定名称的镜像

示例:

[root@h0022062 ~]# curl http://127.0.0.1:1234/images/json?filter=centos
[{"Id":"0f73ae75014f435e279d85ad31edc67e46c4a5d692b61840ff51e9d05f3b01ec","ParentId":"f37e6a610a37349d4ad2ffe4ea163463787109c8ee5d1163c68777b619c5198f","RepoTags":["docker.io/centos:latest"],"RepoDigests"

2、push

URL:POST /images/(name)/push

3、tag

URL:POST /images/(name)/tag

重要参数:

  • repo:重命名后的名称
  • tag:tag名称
  • force:是否强制tag

示例:

[root@h0022062 ~]# docker images
REPOSITORY                        TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
127.0.0.1:5010/centos-redis       latest              dda89eda0992        4 days ago          808.4 MB
[root@h0022062 ~]# curl http://127.0.0.1:1234/images/127.0.0.1:5010/centos-redis/tag?repo=127.0.0.1:5010/test\&tag=v1 -d ""
[root@h0022062 ~]# docker images
REPOSITORY                        TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
127.0.0.1:5010/centos-redis       latest              dda89eda0992        4 days ago          808.4 MB
127.0.0.1:5010/test               v1                  dda89eda0992        4 days ago          808.4 MB

4、删除镜像

URL:DELETE /images/(name)

重要参数:

  • force:是否强制删除

5、查询镜像

URL:GET /images/search

重要参数:

  • term:查询的名称

示例

[root@h0022062 ~]# curl http://127.0.0.1:1234/images/search?term=127.0.0.1:5010/centos
[{"index_name":"127.0.0.1:5010","registry_name":"127.0.0.1:5010","star_count":0,"is_official":false,"name":"library/centos","is_trusted":false,"is_automated":false,"description":""},{"index_name":"127.0.0
[root@h0022062 ~]# curl http://127.0.0.1:1234/images/search?term=centos
[{"index_name":"docker.io","registry_name":"docker.io","star_count":1397,"is_official":true,"name":"centos","is_trusted":false,"is_automated":false,"description":"The official build of CentOS."},{"index_"
其他指令

1、构建

URL:POST /build

输入为stream,stream为DockerFile的文件流

2、镜像提交

URL:POST /commit

重要参数:

  • container:源容器
  • repo:提交后的名称
  • tag:提交后的tag
  • comment:注释
  • author:作者

示例:

[root@h0022062 ~]# curl http://127.0.0.1:1234/commit?container=3405c3b121d5\&repo=mycentos -d "" -H "Content-Type:application/json"
{"Id":"bd9be0c4f0e86feb2ea3e69bc4b529e845ba560366504f25acb792546e1fe2a5"}
[root@h0022062 ~]# docker images
REPOSITORY                        TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
mycentos                          latest              bd9be0c4f0e8        23 seconds ago      1.545 GB

3、info

URL:GET /info

Docker信息获取

4、ping

URL:GET /_ping

ping docker服务器确认是否正常

返回值为OK

官方lib


Docker官方给出的java版本的lib名称为docker-java; 地址为:https://github.com/docker-java/docker-java

使用方法;

pom.xml

<dependency>
  <groupId>com.github.docker-java</groupId>
  <artifactId>docker-java</artifactId>
  <version>2.1.1</version>
</dependency>


TestDocker.java

import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.model.Info;
import com.github.dockerjava.core.DockerClientBuilder;

/**
 * @author weigao
 * @since 15/9/28
 */
public class TestDockerJ {

    public static void main(String []a){
        DockerClient dockerClient = DockerClientBuilder.getInstance("http://192.168.77.114:1234").build();
        Info info = dockerClient.infoCmd().exec();
        System.out.println(info);
    }
}

输出:
com.github.dockerjava.api.model.Info@7049a366[containers=10,debug=false,DockerRootDir=/data/DockerData/docker,driver=devicemapper,driverStatuses=[[Pool Name, docker-8:6-2147518861-pool], [Pool Blocksize, 65.54 kB], [Backing Filesystem, xfs], [Data file, /dev/loop0], [Metadata file, /dev/loop1], [Data Space Used, 5.461 GB], [Data Space Total, 107.4 GB], [Data Space Available, 101.9 GB], [Metadata Space Used, 7.713 MB], [Metadata Space Total, 2.147 GB], [Metadata Space Available, 2.14 GB], [Udev Sync Supported, true], [Deferred Removal Enabled, false], [Data loop file, /data/DockerData/docker/devicemapper/devicemapper/data], [Metadata loop file, /data/DockerData/docker/devicemapper/devicemapper/metadata], [Library Version, 1.02.93-RHEL7 (2015-01-28)]],executionDriver=native-0.2,ID=P2IT:IVN6:MGI3:ODW2:EMHU:JNOU:UJ7B:7VJ6:OBQ2:CUDB:ICTT:HZFA,IPv4Forwarding=true,images=144,IndexServerAddress=https://index.docker.io/v1/,initPath=/usr/libexec/docker/dockerinit,initSha1=746ed18aa31881222705e93bd724e7f61f44ebec,kernelVersion=3.10.0-229.el7.x86_64,Labels=<null>,memoryLimit=true,memTotal=33553391616,name=h0022062,NCPU=16,nEventListener=1,NFd=58,NGoroutines=104,OperatingSystem=Red Hat Enterprise Linux Server 7.1 (Maipo),sockets=<null>,swapLimit=true]

Docker性能测试

性能对比;使用netty和tomcat分别在容器内及容器外进行压测;对比性能损失;

容器内的tps损耗大约为10%-15%之间

1、netty对比测试

容器内,netty测试

docker-netty

容器外,netty测试

netty

  • netty容器内tps为9440
  • netty容器外tps为10595
  • 损失tps约为 (10595-9440)/10595=0.11

2、tomcat对比测试

容器内,tomcat测试

docker-tomcat

容器外,tomcat测试

tomcat

  • netty容器内tps为9709
  • netty容器外tps为11684

* 损失tps约为 (11684-9709)/11684=0.17

目录


一、简介
    1、基本概念
二、Docker实战
    2.1、安装Docker
    2.2、HelloWorld
    2.3、Docker本地仓库
        2.3.1、本地仓库安装
        2.3.1、本地仓库使用
    2.4、Docker集成SSH
        2.4.1、DockerFile
    2.5、Docker网络配置
        2.5.1、Docker网络配置命令
        2.5.2、对外映射端口
        2.5.3、网桥模式
        2.5.4、网桥模式-静态IP
    2.6、Flannel
        2.6.1、Flannel简介
        2.6.2、Flannel安装使用
    2.7、shipyard
        2.7.1、shipyard安装
        2.7.2、shipyard使用
        2.7.3、shipyard优缺点
    2.8、k18s(待完成)
三、Docker常用命令
    3.1、镜像管理
        3.1.1、search
        3.1.2、pull
        3.1.3、push
        3.1.4、images
        3.1.5、tag
        3.1.6、rmi
    3.2、容器管理
        3.2.1、run
        3.2.2、ps
        3.2.3、inspect
        3.2.3、rm
        3.2.4、attach
        3.2.5、logs
        3.2.6、start&stop
        3.2.7、exec
    3.3、镜像构建
        3.3.1、commit
        3.3.2、build & DockerFile
        3.3.3、save & load
    3.3、docker信息
        3.4.1、info
        3.4.2、version
四、DockerAPI使用
    4.1、打开api的远程调用
    4.2、常用API
        4.2.1、容器操作
        4.2.2、镜像操作
        4.2.3、其他指令
    4.3、官方lib
五、Docker性能测试

简介


Docker 是一个开源项目,诞生于 2013 年初;Docker 项目的目标是实现轻量级的操作系统虚拟化解决方案。 Docker 的基础是 Linux 容器(LXC)等技术。

在 LXC 的基础上 Docker 进行了进一步的封装,让用户不需要去关心容器的管理,使得操作更为简便。用户操作 Docker 的容器就像操作一个快速轻量级的虚拟机一样简单。

作为一种新兴的虚拟化方式,Docker 跟传统的虚拟化方式相比具有众多的优势。

  • 一键部署,部署原子化:我们可以狭隘的把 docker 理解成是一个应用打包解决方案:把运维环境、代码进行打包,在部署的时候,只需要载入该镜像,则服务被运行起来。这个过程是原子化的,所以很大程度避免了部署过程中人为或者不可预料的意外。同时也大大加快了部署过程,基本上可以在1分钟内部署好一个业务,因此也具有很大的弹性扩展优势。
  • 隔离和性能:docker专注于隔离,并且镜像是只读的。于是提高了业务的安全性——复用主机的各业务之间,一旦被黑,影响的因素会少很多。并且 docker 仅仅做了隔离,并不虚拟硬件,所以和虚拟机比,没有虚拟化带来的性能消耗。

基本概念

  • 镜像:一个可以被运行的打包好程序,用来创建容器;一个镜像可以包含操作系统、需要运行的程序等;
  • 容器:镜像的实例;它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台;
  • 仓库:用于存放镜像;可以有私有仓库和公开仓库;

Docker实战


安装Docker


Docker的安装比较简单;现在已经默认的加到了centos等系统的源中;运行下述命令即可安装docker;

yum install -y docker-io

docker 命令安装后需要启动docker服务;运行下述命令可以启动docker服务;

service docker start        #启动docker服务
docker version              #查看docker版本信息

可以看到类似如下信息证明安装成功;

dockerversion.png

docker默认会使用在/var/lib/docker目录作为数据文件的存放地址;如果这个目录下空间较小;可以将这个文件移动到其他目录下然后软链下就可以了;

cd /var/lib/docker
mkdir -p /data/DockerData/
mv docker/ /data/DockerData/docker/
ln -s /data/DockerData/docker/ docker

HelloWorld


[root@h0022062 ~]# docker run docker.io/hello-world

Hello from Docker.
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker Hub account:
 https://hub.docker.com

For more examples and ideas, visit:
 https://docs.docker.com/userguide/

Docker本地仓库


由于大部分人使用docker都是内部使用;所有肯定不能把镜像托管到公共的仓库内;

可以通过以下方法安装docker本地仓库;

本地仓库安装

首先需要安装一些基本依赖;

sudo yum install -y python-devel libevent-devel gcc xz-devel open-ssl

由于测试机器上没有python-pip的源;所以需要再单独安装python-pip

wget --no-check-certificate https://github.com/pypa/pip/archive/1.5.5.tar.gz

tar 1.5.5.tar.gz
cd pip-1.5.5/
python setup.py install

由于这里的python-pip不是最近版本;所以需要更新以下

pip install -U pip

git clone https://github.com/docker/docker-registry.git
cd docker-registry
python setup.py install

如果遇到如下问题: /usr/include/openssl/opensslconf.h:31: Error: CPP #error ""This openssl-devel package does not work your architecture?"". Use the -cpperraswarn option to continue swig processing. error: command 'swig' failed with exit status 1

这里是M2Crypto安装不上;需要手动处理下,然后再继续安装:

wget https://pypi.python.org/packages/source/M/M2Crypto/M2Crypto-0.22.3.tar.gz#md5=573f21aaac7d5c9549798e72ffcefedd

tar zxvf M2Crypto-0.22.3.tar.gz

M2Crypto

python setup.py build
本地仓库使用

1、启动本地仓库;这里使用gunicorn来启动docker_registry 服务;在启动之前有一些环境需要初始化;

pip install gevent werkzeug  jinjia2 itsdangerous redis

#如果发现启动如下命令时还有没有安装的包;使用pip安装即可
#-c后面默认的目录是你机器上py的目录;如果找不到;根据提示的目录地址再把文件拷贝过去即可
gunicorn -c contrib/gunicorn.py docker_registry.wsgi:application

启动后即可使用本地仓库;使用方法为

#将本地容器推送给本地仓库
docker push 127.0.0.1:5000/centos

#从本地仓库中查询镜像
docker search 127.0.0.1:5000/centos

#从本地仓库中拉取镜像
docker pull 127.0.0.1:5000/centos

在其他机器上使用本地仓库需要修改docker配置文件;

[root@h00xxxxxx ~]# cat /etc/sysconfig/docker
# /etc/sysconfig/docker
#
# Other arguments to pass to the docker daemon process
# These will be parsed by the sysv initscript and appended
# to the arguments list passed to docker -d
other_args="--insecure-registry 192.168.xx.xx:5000"


service docker restart

Docker集成SSH


由于docker的基础镜像都较小;为了方便使用;我们需要做一些基础镜像;如ssh;这里只示例如何集成SSH

DockerFile
FROM 127.0.0.1:5010/centos

RUN yum install -y openssh-server openssh openssh-clients sysstat net-tools
RUN mkdir /var/run/sshd
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key
COPY sshd /etc/pam.d/sshd
RUN /bin/echo 'root:xxxxxx' |chpasswd
EXPOSE 22
CMD /usr/sbin/sshd -D

由于某些机器存在ssh连接后秒断的情况;需要修改sshd的默认配置文件:

cat sshd

#%PAM-1.0
auth       required     pam_sepermit.so
auth       substack     password-auth
auth       include      postlogin
account    required     pam_nologin.so
account    include      password-auth
password   include      password-auth
# pam_selinux.so close should be the first session rule
session    required     pam_selinux.so close
#这一行注释掉
#session    required     pam_loginuid.so
# pam_selinux.so open should only be followed by sessions to be executed in the user context
session    required     pam_selinux.so open env_params
session    optional     pam_keyinit.so force revoke
session    include      password-auth
session    include      postlogin

Docker网络配置


Docker网络配置命令

Docker的网络配置分为2种; 一个是在Docker服务启动的时候,这是可以指定网桥、网关、是否开启IP6等信息; 另一个是Docker Run在启动容器的时候;这时可以指定多种网络模式;有网桥、无网络、主机绑定、容器绑定等;

Docker重要配置参数

  • -b :指定使用的网桥;默认为docker0
  • --default-gateway=IP:为容器的eth0网卡分配默认的网关地址;如果这个地址不指定;则默认分配网桥的地址;
  • --bip=CIDR;为docker0指定一个IP地址和子网掩码,格式为192.168.1.5/24
  • --fixed-cidr:设置docker0的子网地址的范围;格式为192.168.1.0/25;必须是—bip的子集
  • -H SOCKET;Docker服务监听哪个SOCKET地址;用于远程API
  • --icc:如果icc==true;docker启动时会往iptables的FORWARD中添加一条全局的ACCEPT的规则;而icc未false时会把这个策略修改为DROP;
  • --iptables;当这个值为flase时;docker启动时不会更改主机的iptables的配置;
  • --dns:设置dns服务器的ip地址;写入到容器的/etc/resolv.conf文件

DockerRun启动时的网络配置命令

  • -h:设置主机名称
  • --link:格式为—link=<容器ID或者是名称>:别名,作用是设置容器间的访问
  • -P:用于暴漏端口,识别所有dockerfile中开放的端口,并随机映射到49000-49900之间
  • -p:更常用,指定端口映射;格式为-p <本地端口>:<容器端口>
  • --net=bridge|none|container|host;这里是选择启动容器的连接方式;有四个选择
    • --net=bridge;默认选项,不需要指定;用网桥的方式来连接docker容器
    • --net=none 告诉docker为docker分配网络接口,但是不做地址分配;可以参考”网桥模式-静态IP”
    • --net=host:使用宿主机器的网络接口;
    • --net=container:使用已有容器的网络接口;

示例:

TestHost

TestC1

TestC2

对外映射端口

对外映射端口的方式比较简单;在启动docker容器的时候使用-p命令即可;如

docker run -p 33061:3306 -d mysql /usr/bin/mysqld_safe

这样你在访问本地33061端口的时候就会映射到容器内的3306端口; 对外暴漏端口的好处时使用简单;原生的docker即可支持; 对外映射端口的坏处是需要我们去做好端口的管理、规划工作;去避免端口的冲突;

网桥模式

这里使用的网桥配置工具为brctl;需要先安装下;

yum install -y bridge-utils

我们先删除docker默认启动的网桥docker0

service docker stop
ip link set dev docker0 down
brctl delbr docker0
iptables -t nat -F POSTROUTING

然后我们再添加一个新的网桥

brctl addbr bridge0
ip addr add 172.17.42.1/24 dev bridge0
brctl stp bridge0 off
ip link set dev bridge0 up

修改docker的启动文件后启动docker服务即可;

[root@xxxx shipyard]# cat /etc/sysconfig/docker-network 
# /etc/sysconfig/docker-network
DOCKER_NETWORK_OPTIONS="-b=bridge0" 
service docker start

启动docker容器

dl.dockerpool.com:5000/registry   latest              8e9a29f977a7        11 months ago       430.1 MB
[root@xxxx shipyard]# docker run -d 127.0.0.1:5010/centos-sshd
61032fdc02583e45c7c403cdf08e0d50ee0bdfda1fb76044c1dafabe85ab06e2
[root@xxxx shipyard]# docker inspect --format='' 61032fdc02583e45c7c403cdf08e0d50ee0bdfda1fb76044c1dafabe85ab06e2
172.17.42.3

可以看到已经为容器分配了一个独立ip;这时如果需要从其他同物理网段机器上访问这个容器;需要添加一条路由信息;

route  add -net 172.17.42.0/24 gw 172.16.82.176

#测试登陆
[root@slave ~]# ssh root@172.17.42.3
The authenticity of host '172.17.42.3 (172.17.42.3)' can't be established.
RSA key fingerprint is 95:c2:eb:20:50:36:b3:af:ab:3b:17:33:72:c6:fc:6d.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '172.17.42.3' (RSA) to the list of known hosts.
root@172.17.42.3's password:
[root@61032fdc0258 ~]#
[root@61032fdc0258 ~]#
[root@61032fdc0258 ~]# exit
logout
Connection to 172.17.42.3 closed.
网桥模式-静态IP

如果希望使用静态IP;可以在启动时使用-net=none命令指定不分配IP;然后再使用ip netns给命名空间内的容器赋值IP; 分配IP的操作方法如下:

br_name=bridge0
cid=$(docker run -d -i --net=none -t centos-sshd)
pid=$(docker inspect -f '' $cid)
mkdir -p /var/run/netns
ln -s /proc/$pid/ns/net /var/run/netns/$pid
ip link add q$pid type veth peer name r$pid
brctl addif $br_name q$pid
ip link set q$pid up
fixed_ip='172.17.42.4/24'
gateway='172.17.42.1'
ip link set r$pid netns $pid
ip netns exec $pid ip link set dev r$pid name eth0
ip netns exec $pid ip link set eth0 up
ip netns exec $pid ip addr add $fixed_ip dev eth0
ip netns exec $pid ip route add default via $gateway

注意:其他机器访问还是需要添加路由

清理IP地址的操作方法如下:

docker stop $cid
docker rm $cid
ip netns delete $pid

flannel


shipyard介绍

使用docker原生的网络配置可以实现多台宿主机器上的容器互联;但是需要配置网关;较为繁琐;

flannel使用了(overlay networks)技术;可以让为主机分配一个单独的虚拟子网;可以很方便的另多台宿主机之间的容器进行通信;

盗图一张:

flannel

数据从源容器中发出后,经由所在主机的docker0虚拟网卡转发到flannel0虚拟网卡;

Flannel通过Etcd服务维护了一张节点间的路由表

源主机的flanneld服务将原本的数据内容UDP封装后根据自己的路由表投递给目的节点的flanneld服务,数据到达以后被解包,然后直 接进入目的节点的flannel0虚拟网卡,然后被转发到目的主机的docker0虚拟网卡,最后就像

本机容器通信一下的有docker0路由到达目标容器。

shipyard安装使用

flannel使用需要安装etcd及flannel;只可以在github下载到的最新的编译版本;

主节点:

#下载安装包
wget http://vpn.violetgo.com/etcd-v2.2.0-linux-amd64.tar.gz
wget http://vpn.violetgo.com/flannel-0.5.3-linux-amd64.tar.gz
tar zxvf flannel-0.5.3-linux-amd64.tar.gz
tar zxvf etcd-v2.2.0-linux-amd64.tar.gz

#启动etch服务
cd ./etcd-v2.2.0-linux-amd64/
./etcd --listen-client-urls http://0.0.0.0:4001 --listen-peer-urls http://0.0.0.0:7001

#设置地址范围;这个key是flannel默认使用的key
etcdctl set /coreos.com/network/config '{ "Network": "172.17.0.0/16" }'

#启动flannel服务并且配置docker地址
./flanneld &
./mk-docker-opts.sh –i
source /run/flannel/subnet.env

#重启docker;
service docker stop
ifconfig docker0 ${FLANNEL_SUBNET}
service docker start

其他节点;

scp -r root@192.168.77.114:/data/docker/flannel/  /data/docker/
./flanneld -etcd-endpoints=http://192.168.77.114:4001
source /run/flannel/subnet.env

#重启docker;
service docker stop
ifconfig docker0 ${FLANNEL_SUBNET}
service docker start

验证,在82.176上启动

TestF1

另一台机器上

TestF2

启动IP为172.17.3.9

TestF3

shipyard


shipyard是一款docker的管理页面;之所以想用他是因为他支持跨机器的管理功能;

环境依赖:Docker1.6 如果是1.6一下的docker;在使用swarm时会出现一下错误;

[root@h0082176 shipyard]# docker run -t swarm m --replication --addr 172.16.82.176:3375 --host tcp://0.0.0.0:3375 consul://192.168.77.114:8500
INFO[0000] Listening for HTTP                            addr=0.0.0.0:3375 proto=tcp
INFO[0000] Leader Election: Cluster leadership lost     
INFO[0000] New leader elected: 192.168.77.114:3375      
ERRO[0000] engine 172.16.82.176:2375 is running an unsupported version of Docker Engine. Please upgrade to at least 1.6.0 
INFO[0000] Registered Engine h0022062 at 192.168.77.114:2375 
shipyard安装

我这边的网络不好;很多docker的镜像都无法下载;所以我的选择是在境外vps上使用docker pull 下载镜像后再导出导入到本地; 未测试过直接使用代理行不行; 在主节点上安装shipyard

docker load < alpine.tar
docker load < consul.tar
docker load < curl.tar
docker load < proxy.tar
docker load < rethinkdb.tar
docker load < shipyard.tar
docker load < swarm.tar

cat testDeploy.sh | bash -s

在从点上安装shipyard

1、修改配置地址

[root@h0082176 ~]# vim /etc/sysconfig/docker

  1 # /etc/sysconfig/docker
  2 #
  3 # Other arguments to pass to the docker daemon process
  4 # These will be parsed by the sysv initscript and appended
  5 # to the arguments list passed to docker -d
  6
  7 other_args="--insecure-registry 192.168.77.114:5010 -H 0.0.0.0:2375 -H unix:///var/run/docker.sock

2、修改testDeploy.sh文件,需要将"$ACTION" = "node"下的startproxy、startswarm_manager这两行注释掉;

302 
303     echo "Adding Node"
304     echo " -> Starting Cert Volume"
305     start_certs
306     echo " -> Starting Proxy"
307     #start_proxy
308     echo " -> Starting Swarm Manager"
309     #start_swarm_manager $DISCOVERY

3、部署节点

docker load < alpine.tar
docker load < consul.tar
docker load < curl.tar
docker load < proxy.tar
docker load < rethinkdb.tar
docker load < shipyard.tar
docker load < swarm.tar

cat testDeploy.sh | ACTION=node DISCOVERY=consul://192.168.77.114:8500 bash -s
shipyard使用

shipyard的主要页面大概有以下几个;

第一个是docker的所有的容器列表;这个页面可以帮助我们创建、了解现有容器的状态;

这里可以看到所有节点上的启动的容器和没有启动的容器;

可以进行的操作包括重启、停止、销毁、重命名、查看状态、attach操作、查看控制台的输出日志等

容器

点击容器页面上的放大镜图标可以进入详情页面;

这个页面是容器的一些详细信息;

包括容器的运行命令、开放的端口、进程信息、运行主机和主机上的cpu、内存等;

详情

镜像页面可以看到所有的镜像、镜像所在的主机、镜像大小等信息;

可以删除和拉取新的镜像;

镜像

所有部署docker节点的机器的基本信息;

包括IP、容器数、cpu核心、内存大小、内核版本等;

节点

可以添加一个仓库地址;点击仓库地址进入后可以看到这个仓库上所有的镜像以及镜像依赖、镜像大小信息;

仓库

在仓库页面中点击放大镜;可以看到镜像的生产过程;包括每一步执行的命令和添加到镜像的最终大小等信息;

DockerFile的生产过程

shipyard优缺点
优点
  • 部署使用较为简单
  • 可以在一个页面上对所有的节点进行管理
  • 可以清楚的看到每个容器的运行情况
  • 可以清楚的看到每个镜像的生成过程
缺点
  • 无法push容器,也就是容器的操作无法保存
  • 不支持docker无法编译出新的镜像
  • 目前只有测试版可以使用、需要修改改编译脚本才能在子节点上通过
  • 开发组成员只有两个;活跃度不高

k18s

TODO

Docker常用命令


镜像管理


search

命令格式: docker search

作用是搜索仓库上的镜像;注意 如果需要查询私服上的镜像;需要带完整的私服名,如:

docker search 192.168.77.114:5000/centos

如果查询时提示如下信息,按照提示在你需要查询的机器上的docker的配置文件中添加 --insecure-registry 192.168.77.114:50000

 If this private registry supports only HTTP or HTTPS with an unknown CA certificate, please add `--insecure-registry 192.168.77.114:50000` to the daemon's arguments. 
pull

命令格式: docker pull

作用是拉取镜像,如果需要拉取私服镜像;则跟上完整的私服路径,如:

docker pull 192.168.77.114:5000/centos
push

命令格式: docker push

作用是推送镜像到服务器,如果需要推送到私服;则跟上完整的私服路径,如:

docker push 192.168.77.114:5000/centos

这里要求你的镜像名称既包含私服的名称,如果不包含;需要使用tag重新标记

tag

命令格式:docker tag <原有名称> <仓库路径>/<镜像名称>

docker tag centos 127.0.0.1:5000/centos
images

命令格式: docker images

作用为列出本机的所有镜像;

-q 只列出ID --filter "dangling=true" 只列出tag=的镜像

rmi

命令格式: docker images

按名称或者是镜像ID删除镜像;在删除镜像时需要保证所有基于该镜像的容器全部处于退出状态;

容器管理


run

docker run命令是从镜像启动容器的一个命令;基本上是所有docker操作的一个入口;命令格式

docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

重要参数

  • -m :内存大小限制,如 -m 100m
  • -c
  • -d :是否以后天的形式运行容器
  • -p :对外暴漏的端口,格式为-p <本地端口>:<容器端口>,可以指定多个
  • -v :挂载一个目录作为数据卷,格式 -v <本地目录>:<容器目录>
  • --rm :在容器退出时自动删除
  • -name :容器的名称
  • --link :连接其他的容器;格式为 --link <容器名称>:<容器内名称> 可以指定多个
  • -i : 容器会接受控制台的指令,无法和-d同时使用
  • -t : 分配一个伪tty,通常和-i一起使用
  • --net :设置容器的网络模式;有四种
    • bridge为默认,走网桥自动分配;
    • none不分配网络地址需要手动配置;
    • container复用另一个容器的网络堆栈;如--net container:redis
    • host复用主机的网络堆栈

参数后面跟的是镜像需要执行的命令;默认为docker的CMD;可以另行指定;如

docker run -t -i centos /bin/bash

ps

列出docker中挣扎运行的容器;

命令格式为:

docker ps [OPTIONS]

重要参数:

  • -a:列出所有容器,默认只列出运行的
  • --filter:过滤,k=v的格式,如只列出状态为退出的容器,--filter=status=exited
  • -q: 只列出ID
inspect

命令格式 docker inspect [OPTIONS] CONTAINER|IMAGE

作用返回容器或者是镜像的信息;

重要参数

  • --format="":docker inspect返回的格式为json,format可以按json相应的关键字进行过滤;如

    [root@h0082176 ~]# docker inspect --format="" b01643f3931a
    172.17.0.5
    
rm

删除容器;

docker rm 容器id1 容器id2
attach

连接上一个目标容器,可以看到容器在控制台的输出、并且容器可以接受到控制台的输入

格式为 docker attach 容器id

logs

docker 的输出日志查看;格式为docker logs 容器id

start&stop

启动和停止容器。

格式为docker start|stop 容器id

exec

在一个正在运行的容器中运行命令;格式

docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

重要参数

  • -d:是否后台运行命令
  • -i : 容器会接受控制台的指令,无法和-d同时使用
  • -t : 分配一个伪tty,通常和-i一起使用

示例:

[root@h0082176 ~]# docker ps
CONTAINER ID        IMAGE                            COMMAND                CREATED             STATUS              PORTS                    NAMES
b01643f3931a        violetgo/shadowsocks-server-go   "/shadowsocks-server   3 months ago        Up 2 days           0.0.0.0:1011->1011/tcp   sserver                
[root@h0082176 ~]# docker exec b01643f3931a /shadowsocks-server --help
Usage of /shadowsocks-server:
  -c="config.json": specify config file
  -core=0: maximum number of CPU cores to use, default is determinied by Go runtime
  -d=false: print debug message
  -k="": password
  -m="": encryption method, default: aes-256-cfb
  -p=0: server port
  -t=300: timeout in seconds
  -version=false: print version

镜像构建


commit

将容器提交成一个镜像;可以用于保存容器中的操作;作为镜像的创建方法之一;

命令格式:docker commit [REPOSITORY[:TAG]]

示例:

[root@h0082176 ~]# docker commit b01643f3931a 192.168.77.114:5010/shadowsocks-server-go
4c5e52aa27a5030592964889b76862125871feccf6b70aded5ac6e6c9998c576

[root@h0082176 ~]# docker images
REPOSITORY                                  TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
192.168.77.114:5010/shadowsocks-server-go   latest              4c5e52aa27a5        32 seconds ago      5.309 MB
build

将dockerfile编译成docker镜像;命令格式为

docker build [OPTIONS] PATH | URL | -

重要参数:

  • --rm:编译完成后删除中间容器
  • -t:编译后的tag
  • PATH:DockerFile所在的目录,必须是相对目录;

DockerFile用来创建一个自定义的image,包含了用户指定的软件依赖等;是一种比较常见的docker镜像的创建方法;

重要关键字

  • FROM:基于哪个镜像
  • MAINTAINER:镜像的创建人
  • RUN:运行命令,一般用于安装软件;每条RUN会提交一个新的镜像,所有CD等操作并不会被保留
  • EXPOSE:对外保留的端口
  • ENV:指定环境变量;格式为env key value ;如ENV JAVA_HOME /usr/server/jdk/
  • COPY:复制文件到容器
  • CMD:Docker容器启动时执行的命令,只有最后一条生效;
  • WORKDIR:工作目录,用于cd
save & load

save命令是将docker镜像导成本地文件;用法为

docker save -o 导出文件名 镜像名称

load命令是将docker镜像导成的文件再倒入成镜像

docker load < 导出文件名

docker信息


info

显示docker的基本信息,包括容器数、镜像数、存储目录等;用法 docker info

也可以用来显示远程主机上的docker信息,用法为 docker -H remoteIP:port info

version

显示docker的版本号;用法 docker version

DockerAPI使用


打开api的远程调用


Docker Remote API 提供了Http接口用来可以远程的操作Docker;为了打开Docker Remote API;需要在docker启动的配置文件中增加如下配置:

 -H tcp://0.0.0.0:1234 -H unix:///var/run/docker.sock

如果是从节点;端口可以修改为2375(swarm默认);

常用API


容器操作

1、获取容器

URL:GET /containers/json

重要参数:

  • all 是否显示所有容器
  • limit 限制返回数量
  • size 是否显示容器大小
  • filters 使用json编码的map格式;可用的值有
    • exited= – 容器退出码为
    • status 容器的状态为以下几种(restarting|running|paused|exited)

示例:

curl http://127.0.0.1:1234/containers/json?all=1\&limit=1

[{"Id":"3405c3b121d59eb2caf46a3465d5b8303cfa3be196aad82439db32f3e01395db","Names":["/thirsty_turing"],"Image":"127.0.0.1:5010/centos-flume","Command":"/bin/sh -c /start.sh","Created":1443172047,"Ports":[{"PrivatePort":22,"Type":"tcp"}],"Labels":{"License":"GPLv2","Vendor":"CentOS","com.docker.swarm.id":"f99423ba2c02dca0a5360df52f9ab6b3fa0c346e4adc1e08be8f4faff52e67ca"},"Status":"Up 2 days"}]

2、创建容器

URL:POST /containers/create?name=xx

重要参数:

  • name:容器的名字

请求体为容器的配置,容器的配置参考docker run命令

{
     "Hostname":"",     
     "Domainname": "",  
     "User":"",
     "Memory":0,
     "MemorySwap":0,
     "CpuShares": 512,
     "Cpuset": "0,1",
     "AttachStdin":false,
     "AttachStdout":true,
     "AttachStderr":true,
     "PortSpecs":null,
     "Tty":false,
     "OpenStdin":false,
     "StdinOnce":false,
     "Env":null,
     "Cmd":[
             "date"
     ],
     "Image":"ubuntu",
     "Volumes":{
             "/tmp": {}
     },
     "WorkingDir":"",
     "NetworkDisabled": false,
     "ExposedPorts":{
             "22/tcp": {}
     },
     "RestartPolicy": { "Name": "always" }
}

返回容器的ID

3、容器信息

URL: GET /containers/<容器ID>/json

示例

[root@h0022062 ~]# curl http://127.0.0.1:1234/containers/210448f1802c/json
    {"Id":"210448f1802c49f23fb45b5f35d52461e9fb24424648e771d3676a8b276c11e8","Created":"2015-09-25T07:21:38.29666668Z","Path":"rethinkdb","Args":["--bind","all"],"State":{"Running":true,"Paused":false,"Restarting":false,"OOMKilled":false,"Dead":false,"Pid":10165,"ExitCode":0,"Error":"","StartedAt":"2015-09-25T07:21:38.754120768Z","FinishedAt":"0001-01-01T00:00:00Z"},"Image":"bb270de71f333226b16a694f85a472a4353079c9566071416f5e03ea31002687","NetworkSettings":{"Bridge":"bridge0","EndpointID":"c9ff03643b025d3c8f50221f7c2fd2be2238b50b13ce717997b9aae4c479c5cb","Gateway":"172.17.42.1","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"HairpinMode":false,"IPAddress":"172.17.42.29","IPPrefixLen":24,"IPv6Gateway":"","LinkLocalIPv6Address":"","LinkLocalIPv6PrefixLen":0,"MacAddress":"02:42:ac:11:2a:1d","NetworkID":"c2fb14ff4c24761f7d36f0feb52533d6d448b888afa14db8e57b35a9c8f275e9","PortMapping":null,"Ports":{"28015/tcp":null,"29015/tcp":null,"8080/tcp":null},"SandboxKey":"/var/run/docker/netns/210448f1802c","SecondaryIPAddresses":null,"SecondaryIPv6Addresses":null},"ResolvConfPath":"/data/DockerData/docker/containers/210448f1802c49f23fb45b5f35d52461e9fb24424648e771d3676a8b276c11e8/resolv.conf","HostnamePath":"/data/DockerData/docker/containers/210448f1802c49f23fb45b5f35d52461e9fb24424648e771d3676a8b276c11e8/hostname","HostsPath":"/data/DockerData/docker/containers/210448f1802c49f23fb45b5f35d52461e9fb24424648e771d3676a8b276c11e8/hosts","LogPath":"/data/DockerData/docker/containers/210448f1802c49f23fb45b5f35d52461e9fb24424648e771d3676a8b276c11e8/210448f1802c49f23fb45b5f35d52461e9fb24424648e771d3676a8b276c11e8-json.log","Name":"/shipyard-rethinkdb","RestartCount":0,"Driver":"devicemapper","ExecDriver":"native-0.2","MountLabel":"","ProcessLabel":"","Volumes":{"/data":"/data/DockerData/docker/volumes/7c9a685750faa858e441df835dd905464c134b4564c921a9e78f8572c366238c/_data"},"VolumesRW":{"/data":true},"AppArmorProfile":"","ExecIDs":null,"HostConfig":{"Binds":null,"ContainerIDFile":"","LxcConf":[],"Memory":0,"MemorySwap":0,"CpuShares":0,"CpuPeriod":0,"CpusetCpus":"","CpusetMems":"","CpuQuota":0,"BlkioWeight":0,"OomKillDisable":false,"Privileged":false,"PortBindings":{},"Links":null,"PublishAllPorts":false,"Dns":null,"DnsSearch":null,"ExtraHosts":null,"VolumesFrom":null,"Devices":[],"NetworkMode":"bridge","IpcMode":"","PidMode":"","UTSMode":"","CapAdd":null,"CapDrop":null,"RestartPolicy":{"Name":"always","MaximumRetryCount":0},"SecurityOpt":null,"ReadonlyRootfs":false,"Ulimits":null,"LogConfig":{"Type":"json-file","Config":{}},"CgroupParent":""},"Config":{"Hostname":"210448f1802c","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"PortSpecs":null,"ExposedPorts":{"28015/tcp":{},"29015/tcp":{},"8080/tcp":{}},"Tty":true,"OpenStdin":true,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","RETHINKDB_PACKAGE_VERSION=2.1.3~0jessie"],"Cmd":["rethinkdb","--bind","all"],"Image":"rethinkdb","Volumes":{"/data":{}},"VolumeDriver":"","WorkingDir":"/data","Entrypoint":null,"NetworkDisabled":false,"MacAddress":"","OnBuild":null,"Labels":{},"Init":""}}

4、容器内的运行程序查询

URL:GET /containers/(id)/top

[root@h0022062 ~]# curl http://127.0.0.1:1234/containers/210448f1802c/top
{"Processes":[["root","10165","3788","0","Sep25","pts/3","00:02:12","rethinkdb --bind all"],["root","10737","10165","0","Sep25","pts/3","00:00:00","rethinkdb --bind all"]],"Titles":["UID","PID","PPID","C","STIME","TTY","TIME","CMD"]}

4、容器log

URL:GET /containers/(id)/logs

重要参数:

  • follow:是否返回stream
  • stdout:是否返回stdout
  • stderr:是否返回stderr
  • tail:返回多少行
  • timestamps:是否返回时间戳

示例

[root@h0022062 ~]# curl http://127.0.0.1:1234/containers/210448f1802c/logs?tail=10\&stdout=1
Listening for intracluster connections on port 29015
error: Failed to create sockets for listener on port 28015, falling back to IPv4 only
Listening for client driver connections on port 28015
error: Failed to create sockets for listener on port 8080, falling back to IPv4 only
Listening for administrative HTTP connections on port 8080
Listening on addresses: 127.0.0.1, 172.17.42.29
Server ready, "210448f1802c_dvi" 3631a825-b6c4-4deb-9bfd-281d364d52ef
warn: Problem when checking for new versions of RethinkDB: HTTP request to update.rethinkdb.com failed.
warn: Problem when checking for new versions of RethinkDB: HTTP request to update.rethinkdb.com failed.
warn: Problem when checking for new versions of RethinkDB: HTTP request to update.rethinkdb.com failed.

5、导出容器

URL:GET /containers/(id)/export

返回包为容器的stream

6、启动停止容器

启动容器

URL:GET /containers/(id)/start

停止容器

URL:GET /containers/(id)/stop?t=xx

t为停止时等待的秒数

7、删除容器

URL:DELETE /containers/(id)

参数: * v:是否删除数据卷 * force:是否强制删除

镜像操作

1、镜像列表

URL:GET /images/json?all=0

重要参数

  • all:是否显示所有镜像
  • filters:使用json编码的map格式;可用的值有
    • dangling=true
  • filter:只返回指定名称的镜像

示例:

[root@h0022062 ~]# curl http://127.0.0.1:1234/images/json?filter=centos
[{"Id":"0f73ae75014f435e279d85ad31edc67e46c4a5d692b61840ff51e9d05f3b01ec","ParentId":"f37e6a610a37349d4ad2ffe4ea163463787109c8ee5d1163c68777b619c5198f","RepoTags":["docker.io/centos:latest"],"RepoDigests"

2、push

URL:POST /images/(name)/push

3、tag

URL:POST /images/(name)/tag

重要参数:

  • repo:重命名后的名称
  • tag:tag名称
  • force:是否强制tag

示例:

[root@h0022062 ~]# docker images
REPOSITORY                        TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
127.0.0.1:5010/centos-redis       latest              dda89eda0992        4 days ago          808.4 MB
[root@h0022062 ~]# curl http://127.0.0.1:1234/images/127.0.0.1:5010/centos-redis/tag?repo=127.0.0.1:5010/test\&tag=v1 -d ""
[root@h0022062 ~]# docker images
REPOSITORY                        TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
127.0.0.1:5010/centos-redis       latest              dda89eda0992        4 days ago          808.4 MB
127.0.0.1:5010/test               v1                  dda89eda0992        4 days ago          808.4 MB

4、删除镜像

URL:DELETE /images/(name)

重要参数:

  • force:是否强制删除

5、查询镜像

URL:GET /images/search

重要参数:

  • term:查询的名称

示例

[root@h0022062 ~]# curl http://127.0.0.1:1234/images/search?term=127.0.0.1:5010/centos
[{"index_name":"127.0.0.1:5010","registry_name":"127.0.0.1:5010","star_count":0,"is_official":false,"name":"library/centos","is_trusted":false,"is_automated":false,"description":""},{"index_name":"127.0.0
[root@h0022062 ~]# curl http://127.0.0.1:1234/images/search?term=centos
[{"index_name":"docker.io","registry_name":"docker.io","star_count":1397,"is_official":true,"name":"centos","is_trusted":false,"is_automated":false,"description":"The official build of CentOS."},{"index_"
其他指令

1、构建

URL:POST /build

输入为stream,stream为DockerFile的文件流

2、镜像提交

URL:POST /commit

重要参数:

  • container:源容器
  • repo:提交后的名称
  • tag:提交后的tag
  • comment:注释
  • author:作者

示例:

[root@h0022062 ~]# curl http://127.0.0.1:1234/commit?container=3405c3b121d5\&repo=mycentos -d "" -H "Content-Type:application/json"
{"Id":"bd9be0c4f0e86feb2ea3e69bc4b529e845ba560366504f25acb792546e1fe2a5"}
[root@h0022062 ~]# docker images
REPOSITORY                        TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
mycentos                          latest              bd9be0c4f0e8        23 seconds ago      1.545 GB

3、info

URL:GET /info

Docker信息获取

4、ping

URL:GET /_ping

ping docker服务器确认是否正常

返回值为OK

官方lib


Docker官方给出的java版本的lib名称为docker-java; 地址为:https://github.com/docker-java/docker-java

使用方法;

pom.xml

<dependency>
  <groupId>com.github.docker-java</groupId>
  <artifactId>docker-java</artifactId>
  <version>2.1.1</version>
</dependency>


TestDocker.java

import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.model.Info;
import com.github.dockerjava.core.DockerClientBuilder;

/**
 * @author weigao
 * @since 15/9/28
 */
public class TestDockerJ {

    public static void main(String []a){
        DockerClient dockerClient = DockerClientBuilder.getInstance("http://192.168.77.114:1234").build();
        Info info = dockerClient.infoCmd().exec();
        System.out.println(info);
    }
}

输出:
com.github.dockerjava.api.model.Info@7049a366[containers=10,debug=false,DockerRootDir=/data/DockerData/docker,driver=devicemapper,driverStatuses=[[Pool Name, docker-8:6-2147518861-pool], [Pool Blocksize, 65.54 kB], [Backing Filesystem, xfs], [Data file, /dev/loop0], [Metadata file, /dev/loop1], [Data Space Used, 5.461 GB], [Data Space Total, 107.4 GB], [Data Space Available, 101.9 GB], [Metadata Space Used, 7.713 MB], [Metadata Space Total, 2.147 GB], [Metadata Space Available, 2.14 GB], [Udev Sync Supported, true], [Deferred Removal Enabled, false], [Data loop file, /data/DockerData/docker/devicemapper/devicemapper/data], [Metadata loop file, /data/DockerData/docker/devicemapper/devicemapper/metadata], [Library Version, 1.02.93-RHEL7 (2015-01-28)]],executionDriver=native-0.2,ID=P2IT:IVN6:MGI3:ODW2:EMHU:JNOU:UJ7B:7VJ6:OBQ2:CUDB:ICTT:HZFA,IPv4Forwarding=true,images=144,IndexServerAddress=https://index.docker.io/v1/,initPath=/usr/libexec/docker/dockerinit,initSha1=746ed18aa31881222705e93bd724e7f61f44ebec,kernelVersion=3.10.0-229.el7.x86_64,Labels=<null>,memoryLimit=true,memTotal=33553391616,name=h0022062,NCPU=16,nEventListener=1,NFd=58,NGoroutines=104,OperatingSystem=Red Hat Enterprise Linux Server 7.1 (Maipo),sockets=<null>,swapLimit=true]

Docker性能测试

性能对比;使用netty和tomcat分别在容器内及容器外进行压测;对比性能损失;

容器内的tps损耗大约为10%-15%之间

1、netty对比测试

容器内,netty测试

docker-netty

容器外,netty测试

netty

  • netty容器内tps为9440
  • netty容器外tps为10595
  • 损失tps约为 (10595-9440)/10595=0.11

2、tomcat对比测试

容器内,tomcat测试

docker-tomcat

容器外,tomcat测试

tomcat

  • tomcat容器内tps为9709
  • tomcat容器外tps为11684
  • 损失tps约为 (11684-9709)/11684=0.17