docker笔记(8)—— Container的生命周期

docker create创建一个containerdocker start则启动这个container

docker run相当于docker create加上docker start。需要注意的是,一旦执行完container需要做的工作,container就会退出:

# docker run hello-world

Hello from Docker.
......

# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
62a13663511f        hello-world         "/hello"            5 seconds ago       Exited (0) 4 seconds ago                       compassionate_ptolemy

停止container可以使用下列两个命令:
docker kill:向container发送SIGKILL信号;
docker stop:先向container发送SIGTERM信号,过一段时间再发送SIGKILL信号。

彻底干掉container使用docker rm命令。移除所有已经停止的container可以使用下列命令:

$ docker rm $(docker ps -a -q)

参考资料:
Docker Cookbook

 

docker笔记(7)—— Index,registry和repository

看一下对三个词的英文解释:

An index manages user accounts, permissions, search, tagging, and all that nice stuff that’s in the public web interface.

A registry stores and serves up the actual image assets, and it delegates authentication to the index. Docker registry is a service that is storing your docker images.

Docker repository is a collection of different docker images with same name, that have different tags.

Index是管理docker的服务(包含用户账户,操作权限,等等)。Registry是存储docker image的服务。Repository则是包含同名不同tagdocker image的集合。

参考资料:
Difference between Docker registry and repository
Where are Docker images stored?

 

docker笔记(6)—— 在docker container中执行命令的脚本

下面脚本的功能是循环地在各个container中执行命令:

#!/bin/bash -x

for i in {1..2}
do
        docker exec -i hammerdb_net${i} bash <<-EOF
        su oracle
        source /tmp/ora_env
        cd /data/oracle/tablespaces/
        rm -f *.html
        ./create_awr.sh
        mv awr.html awr_${i}.html
        EOF
done

需要注意的是在dodone之间应该使用tab而不是空格。

参考资料:
Indenting bourne shell here documents
How to write a bash script which automate entering “docker container” and doing other things?
Can’t indent heredoc to match nesting’s indent

 

docker笔记(5)—— Volume

Docker image是一系列的read-only layer。当启动container以后,在read-only layer之上会增加一个read-write layer。当需要对文件进行修改时,就要把数据从read-only layer拷贝到read-write layer。因此,image的数据不会被破坏,container相当于操作的是image数据的副本。这种read-only layerread-write layer的结合称之为Union File System

因此,为使对数据的修改能够保存下来,docker引入了volume概念:volume即是位于主机文件系统上,而不是Union File System上的目录和文件。

(1)

$ docker run -it --name container-test -h CONTAINER -v /data debian /bin/bash
root@CONTAINER:/# ls /data
root@CONTAINER:/#   

container-test中的/data目录位于主机的位置:

$ docker inspect -f {{.Volumes}} container-test
map[/data:/var/lib/docker/vfs/dir/cde167197ccc3e138a14f1a4f7c0d65b32cecbada822b0db4cc92e79059437a9] 

(2)

$ docker run -v /home/adrian/data:/data debian ls /data

这种方式直接把主机上的目录映射到container中的一个目录。

参考资料:
Understanding Volumes in Docker

docker笔记(4)—— 如何进入一个正在运行的“docker container”?

docker attach [container-id]”命令有时会hang住,执行Ctrl+C命令也不起作用:

[root@localhost ~]# docker attach a972e69ab444
^C^C^C^C^C^C^C^C^C^C

使用pstack命令查看函数调用栈:

[root@localhost ~]# pstack 29744
Thread 5 (Thread 0x7f9079bd8700 (LWP 29745)):
#0  runtime.futex () at /usr/lib/golang/src/pkg/runtime/sys_linux_amd64.s:269
#1  0x0000000000417717 in runtime.futexsleep () at /usr/lib/golang/src/pkg/runtime/os_linux.c:49
#2  0x0000000001161c58 in runtime.sched ()
#3  0x0000000000000000 in ?? ()
Thread 4 (Thread 0x7f90792d7700 (LWP 29746)):
#0  runtime.futex () at /usr/lib/golang/src/pkg/runtime/sys_linux_amd64.s:269
#1  0x0000000000417782 in runtime.futexsleep () at /usr/lib/golang/src/pkg/runtime/os_linux.c:55
#2  0x00007f907b830f60 in ?? ()
#3  0x0000000000000000 in ?? ()
Thread 3 (Thread 0x7f9078ad6700 (LWP 29747)):
#0  runtime.futex () at /usr/lib/golang/src/pkg/runtime/sys_linux_amd64.s:269
#1  0x0000000000417717 in runtime.futexsleep () at /usr/lib/golang/src/pkg/runtime/os_linux.c:49
#2  0x00000000011618a0 in text/template.zero ()
#3  0x0000000000000000 in ?? ()
Thread 2 (Thread 0x7f9073fff700 (LWP 29748)):
#0  runtime.futex () at /usr/lib/golang/src/pkg/runtime/sys_linux_amd64.s:269
#1  0x0000000000417717 in runtime.futexsleep () at /usr/lib/golang/src/pkg/runtime/os_linux.c:49
#2  0x000000c2080952f0 in ?? ()
#3  0x0000000000000000 in ?? ()
Thread 1 (Thread 0x7f907b9e1800 (LWP 29744)):
#0  runtime.epollwait () at /usr/lib/golang/src/pkg/runtime/sys_linux_amd64.s:385
#1  0x00000000004175dd in runtime.netpoll () at /usr/lib/golang/src/pkg/runtime/netpoll_epoll.c:78
#2  0x00007fff00000004 in ?? ()
#3  0x00007fff58720fd0 in ?? ()
#4  0xffffffff00000080 in ?? ()
#5  0x0000000000000000 in ?? ()

可以使用“docker exec -it [container-id] bash”命令进入正在运行的container

[root@localhost ~]# docker exec -it a972e69ab444 bash
bash-4.1# ls
bin   dev  home  lib64  mnt  pam-1.1.1-17.el6.src.rpm  root      sbin     srv  tmp  var
boot  etc  lib   media  opt  proc                      rpmbuild  selinux  sys  usr
bash-4.1#

docker attach相当于复用了container当前使用的tty,因此在docker attach内执行exit,会导致正在运行的container退出。而docker exec会新建立一个tty,在docker exec中执行exit不会导致container退出。

 

参考资料:
(1)Docker – Enter Running Container with new TTY

docker笔记(3)—— selinux导致docker工作不正常

最近几天在研究docker备份文件(操作系统是RHEL7docker版本是1.5.0)。仿照docker文档,执行如下命令:

[root@localhost data]#docker create -v /dbdata --name dbdata training/postgres /bin/true
[root@localhost data]#docker run -d --volumes-from dbdata --name db1 training/postgres
[root@localhost data]# docker run --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata
tar: /backup/backup.tar: Cannot open: Permission denied
tar: Error is not recoverable: exiting now

看到Permission denied这个提示,自然首先怀疑用户没有写权限的问题。检查一下当前目录的权限:

[root@localhost data]# ls -alt
total 4
drwxrwxrwx.  2 root root    6 May  7 21:33 .
drwxrwx-w-. 15 root root 4096 May  7 21:33 ..

应该是没问题的。经过在stackoverflow上的一番讨论,得到的建议是有可能是selinux捣的鬼。查看了一下selinux状态:

[root@localhost root]# sestatus
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   enforcing
Mode from config file:          enforcing
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Max kernel policy version:      28

果断把模式改为permissive:

[root@localhost data]# setenforce 0
[root@localhost data]# sestatus
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   permissive
Mode from config file:          enforcing
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Max kernel policy version:      28

马上工作正常:

[root@localhost data]# docker run --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata
tar: Removing leading `/' from member names
/dbdata/

因为时间原因,没有往下深究。总之,在使用docker时,要留意一下selinux,有可能会引起很奇怪的问题。

更新:

最近又碰到这个问题,可以参考这篇总结

参考资料:
(1)Why does docker prompt “Permission denied” when backing up the data volume?
(2)How to disable SELinux without restart?
(3)Quick-Tip: Turning off or disabling SELinux

docker笔记(2)——“docker daemon”,“image”和“container”

使用“service docker start”命令实际上是启动docker daemon程序,可以用“ps”命令查看一下:

[root@localhost ~]# ps -ef | grep docker
root     24791     1  0 Mar18 ?        00:00:03 /usr/bin/docker -d --selinux-enabled
root     24969 24950  0 03:25 pts/0    00:00:00 grep --color=auto docker

-d”选项表明开启daemon模式。

Docker中最重要的概念是imagescontainersimages可以比做虚拟机软件(VirtualBox或者VMware)的虚拟磁盘镜像文件(VirtualBox的格式是*.vdiVMware*.vmdk)。从images可以创建一个或多个containers进程,这个可以比做从虚拟磁盘镜像文件创建出虚拟机程序。

使用docker run命令可以创建一个containers,并且在containers中运行命令,如下所示:

[root@localhost ~]# docker run --rm -ti ubuntu /bin/bash
root@88129ebf9b61:/# ls

新的containers运行的是一个ubuntu镜像,并且进入bash交互模式。

docker笔记(1)—— RHEL 7.0安装docker

官方RHEL 7.0安装docker的文档在这里。由于这个需要用户注册,所以在这里我介绍另一种方法:使用CentOSdocker rpm包。

(1)CentOS的软件包在这里:http://cbs.centos.org/repos/virt7-testing/x86_64/os/,你可以配置到yum源(软件仓库)的配置文件里,类似这样:

[centos-extra]
name=centos extra
baseurl=http://cbs.centos.org/repos/virt7-testing/x86_64/os/
enabled=1
gpgcheck=0

(2)运行“yum install docker”命令。

(3)安装成功后,运行“docker version”命令:

[root@localhost yum.repos.d]# docker version
Client version: 1.5.0
Client API version: 1.17
Go version (client): go1.3.3
Git commit (client): a8a31ef/1.5.0
OS/Arch (client): linux/amd64
FATA[0000] Get http:///var/run/docker.sock/v1.17/version: dial unix /var/run/docker.sock: no such file or directory. Are you trying to connect to a TLS-enabled daemon without TLS?

可以看到有“FATA[0000]......”提示,原因是没有启动docker daemon程序,使用“service docker start”可以启动docker程序。再次执行“docker version”命令:

[root@localhost bin]# docker version
Client version: 1.5.0
Client API version: 1.17
Go version (client): go1.3.3
Git commit (client): a8a31ef/1.5.0
OS/Arch (client): linux/amd64
Server version: 1.5.0
Server API version: 1.17
Go version (server): go1.3.3
Git commit (server): a8a31ef/1.5.0

可以看到“FATA[0000]......”提示没有了。

(4)接下来的步骤可参考这里