一、Docker使用模板创建镜像

首先下载一个模板

http://download.openvz.org/template/precreated/

//下载速度不快,下载了一个centos6的模板centos-6-x86-minimal.tar.gz

[root@fuxi01 ~]# wget http://download.openvz.org/template/precreated/centos-6-x86-minimal.tar.gz

导入该镜像的命令为:

# cat centos-6-x86-minimal.tar.gz|docker import - centos6
sha256:cdce38ce7fb223b243043be905be88f24635036cf850ceae013007f60a2dda51

# docker images  //查看导入的镜像
# docker run -itd centos6 bash
79ce4ee106cb84aadbc411489dafadd37d06a92e81b1682199b9e573c224ea6d
[root@fuxi01 ~]# docker exec -it 79ce4ee1 bash
[root@79ce4ee106cb /]# cat /etc/issue  //查看它的版本
CentOS release 6.8 (Final)
Kernel \r on an \m
[root@79ce4ee106cb /]# uname -a
Linux 79ce4ee106cb 3.10.0-693.el7.x86_64 #1 SMP Tue Aug 22 21:09:27 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
[root@79ce4ee106cb /]# exit
[root@fuxi01 ~]# uname -a
Linux fuxi01 3.10.0-693.el7.x86_64 #1 SMP Tue Aug 22 21:09:27 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

由此可见,docker容器的内核和Linux机器的内核是同一个3.10.0的内核,所以说docker容器是基于Linux内核的。

把现有镜像,导出为一个文件:

# docker save -o centos7_with_nettool.tar centos_with_net

//save -o后先跟文件名,再跟镜像名。save和load是一对。

[root@fuxi01 ~]# docker ps 
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
79ce4ee106cb        centos6             "bash"              4 days ago          Up 4 days                               kind_pasteur
b15b83c7c7a2        centos_with_net     "/bin/bash"         5 days ago          Up 5 days                               infallible_lalande
7ae3b5eb6e41        ubuntu              "/bin/bash"         12 days ago         Up 12 days                              admiring_diffie
43aae89a76ae        centos              "/bin/bash"         13 days ago         Up 13 days                              serene_kare
[root@fuxi01 ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos6             latest              cdce38ce7fb2        4 days ago          512MB
centos_with_net     latest              2803335f23a6        5 days ago          261MB
ubuntu              latest              549b9b86cb8d        3 weeks ago         64.2MB
centos              latest              0f3e07c0138f        3 months ago        220MB
yw_centos           latest              0f3e07c0138f        3 months ago        220MB
[root@fuxi01 ~]# docker rm -f b15b83c7c7a2
b15b83c7c7a2
[root@fuxi01 ~]# docker rmi 2803335f23a6
Untagged: centos_with_net:latest
Deleted: sha256:2803335f23a68731a68ffbc860d6e72c15feb2e922cc8aefb1e013fd174b604e
Deleted: sha256:c7d34cfde22ae64c7556234eed73668e4a7b4b2803e51bde4cbbdbd25bb5a2cb

还可以用该文件恢复本地镜像:

# docker load --input centos7_with_nettool.tar  或者
# docker load < centos7_with_nettool.tar
# docker push image_name

docker push  //可以把自己的镜像传到dockerhub官方网站上去,但前提是需要先注册一个用户,后续如果有需求再研究吧。


二、容器管理

# docker create -it centos6 bash

//这样可以创建一个容器,但该容器并没有启动,docker create就像创建虚拟机一样。和docker run基本一样的用法。创建后,需要用docker ps -a才能看到,状态是Created。

# docker start container_id

//启动容器后,可以使用 docker ps 查看到,有start 就有stop,和restart。

之前我们使用的docker run 相当于先create再start

# docker run -it centos bash


这样进入了一个虚拟终端里面,我们可以运行一些命令,使用命令exit或者ctrl d 退出该bash,当退出后这个容器也会停止。执行docker ps -a可以看到它的状态是Exited的状态了。

# docker run -d  可以让容器在后台运行

比如:docker run -d centos bash -c "while :; do echo "123"; sleep 2; done"

# docker run --name centos6_1 -itd centos6 bash  // --name 给容器自定义名字,如果不定义,docker ps时最右侧的NAMES就是随机字符串。
# docker exec -it centos6_1 bash  //进入容器就可以直接写定义的名字了,不用去写它的ID了。

# docker run --rm -it centos bash -c "sleep 30" //--rm 可以让容器退出后直接删除,在这里命令执行完容器就会退出。-c,在容器里执行命令。


docker logs 可以获取到容器的运行历史信息,用法如下:

docker logs  container_id  

[root@fuxi01 ~]# docker run -itd centos bash -c "echo 12345"
7c2e09481628fa13df86bdc858d2641ea094a88ee4fbdc0feeda6f3efa059048
[root@fuxi01 ~]# docker logs 7c2e09
12345

docker attach 可以进入一个后台运行的容器,比如

# docker attach  container_id    
//但是attach命令不好用,比如我们想要退出终端,就得exit了,这样容器也就退出stop了,还有一种方法:
# docker exec -it container_id  bash  
//可以临时打开一个虚拟终端,并且exit后,容器依然运行着。
# docker rm container_id  
//container_id是docker ps -a的时候查看到的,这样就可以把container删除,如果是运行的容器,需要用rm -f。
# docker  export container_id  > file.tar  
// 导出容器,可以迁移到其他机器上,需要导入,导入是docker load --input。
# cat file.tar |docker import - aming_test   
//这样会生成aming_test的镜像


三、仓库管理

# docker pull registry


//下载registry 镜像,registy为docker官方提供的一个镜像,我们可以用它来创建本地的docker私有仓库。拉取registry时如果没有加速器会很慢。加速器:/etc/docker/daemon.json

重启docker之后所有容器都会停止,要想批量自动启动所有容器,

执行:systemctl restart docker &&  docker start  $(docker ps -a -q)

docker中 启动所有的容器命令

# docker start $(docker ps -a | awk '{ print $1}' | tail -n +2)

docker中 关闭所有的容器命令

# docker stop $(docker ps -a | awk '{ print $1}' | tail -n +2)


# docker run -d -p 5000:5000 registry

//以registry镜像启动容器,-p会把容器的端口映射到宿主机上,:左边为宿主机监听端口,:右边为容器监听端口。也可以写其他端口,自定义。

//要想访问容器里的80 端口,就需要做一个端口映射。   比如centos容器里的ip为172.17.0.2,这个IP是对内的,但是宿主机的192.168.255.128是对外的,而宿主机到容器的80端口是可以ping通的。

# curl 127.0.0.1:5000/v2/_catalog   //可以访问它
{"repositories":[]}

什么内容也没有,我们需要把镜像传到仓库里去,传到仓库里才能看到。

下面来把其中一个镜像上传到私有仓库

# docker tag centos 192.168.255.128:5000/centos   //标记一下tag,首先是宿主机的IP,必须要带有私有仓库的ip:port
# docker push 192.168.255.128:5000/centos   //把标记的镜像给推送到私有仓库

此时并不会成功,Get https://192.168.255.128:5000/v2/: http: server gave HTTP response to HTTPS client  报错,这里用的是https。

解决方法:

更改配置文件:

# vi /etc/docker/daemon.json   //更改为这一条内容,之前的加速器需要删掉,不然push不成功。不使用HTTPS,使用HTTP。
 { "insecure-registries":["192.168.255.128:5000"] }
# systemctl restart docker 
# docker ps -a //查看容器已经关闭,还需要启动
# docker start  id //这里的id为registry容器id

再次push

# docker push 192.168.255.128:5000/centos
# curl 127.0.0.1:5000/v2/_catalog //可以查看到推送上来的镜像
{"repositories":["centos"]}
//这里的centos,就是在push的时候,最后面的字符串。

# docker tag ubuntu 192.168.255.128:5000/ubuntu   //打标签,推送,就能在私有仓库查看到了。
# docker push 192.168.255.128:5000/ubuntu
# curl 127.0.0.1:5000/v2/_catalog
{"repositories":["centos","ubuntu"]}

新机器从私有仓库拉镜像:
先安装docker,然后定义仓库地址vi /etc/docker/daemon.json,启动docker,然后pull就可以了:
# docker pull 192.168.255.128:5000/ubuntu
//加上IP:port就是在私有仓库下载,不加就是在官方下载。


四、数据管理

容器是由镜像启动的,容器里产生的新数据,在容器停止或删除时,数据会一并消除,这样就意味数据有一定风险。所以想到一个办法,把宿主机的目录挂载到容器里去,这样即使容器被停止或删除,数据还是依然在宿主机的目录里。

1. 挂载本地的目录到容器里

# docker run -tid -v /data/:/data centos bash
266bc8cd6fe8fe57c919acddbd958a756bbbdeeb1d6cecf9a49938ee0cd746ab
[root@fuxi01 ~]# ls /data
change.log  ftp  gitroot  mariadb  mysql  tomcat-instance  user_passwd  wwwroot
[root@fuxi01 ~]# docker exec -it 266bc8c bash
[root@266bc8cd6fe8 /]# ls /data
change.log  ftp  gitroot  mariadb  mysql  tomcat-instance  user_passwd	wwwroot
[root@266bc8cd6fe8 /]# 
//这样,容器里的data目录和宿主机的data目录就是数据同步的了,更改也会同步。

//-v 用来指定挂载目录,:前面的/data/为宿主机本地目录,:后面的/data/为容器里的目录,会在容器中自动创建。


2. 挂载数据卷(--volumes-from)

其实我们挂载目录的时候,可以使用--name指定容器name,如果不指定就随机定义了。比如上面没有指定,它就生成了一个名字为heuristic_almeida,这个名字可以使用命令 docker ps  看最右侧一列。

# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
266bc8cd6fe8        centos              "bash"                   23 hours ago        Up 23 hours                                  heuristic_almeida
# docker run -itd --volumes-from heuristic_almeida centos6 bash
53ad0ecc0ea797915dd62ce03e886c05f86171136404b35a1f8049542cf57358

这样,我们使用centos6镜像创建了新的容器,并且把 heuristic_almeida 容器作为了数据卷,进入这个centos6的容器可以ls /data看到内容和centos的是一样的,centos容器的data目录是什么样的,它centos6这里就是什么样的,是关联在一起的。


3. 定义数据卷容器

有时候,我们需要多个容器之间相互共享数据,类似于linux里面的NFS,所以就可以搭建一个专门的数据卷容器,然后其他容器直接挂载该数据卷。

首先建立数据卷容器

# docker run -itd -v /data/ --name testvol centos  bash

//注意这里的/data/是容器的/data目录,并非本地的/data/目录。 就是不需要宿主机的目录做映射。把这个目录共享出来,作为公共的目录。

然后让其他容器挂载该数据卷

# docker run -itd  --volumes-from testvol centos6 bash