容器管理
创建一个容器:
[root@shuai-01 ~]# docker create -it centos6 bash
7fdfbd19b39dae117ea1a54a1681d3cf151b6c16503efcff1af33a19ec4ce0c0
[root@shuai-01 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7fdfbd19b39d centos6 "bash" 9 seconds ago Created confident_mirzakhani
通过docker create 创建的容器,该容器没有启动
启动容器:
[root@shuai-01 ~]# docker start 7fdfbd19b39d
7fdfbd19b39d
[root@shuai-01 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7fdfbd19b39d centos6 "bash" 2 minutes ago Up 20 seconds confident_mirzakhani
这时的启动容器,没有进入到伪终端。进入终端还是得用docker exec -it 7fdfbd19b39d bash
docker run 相当于先create 在 start
docker run -it centos bash
这样进入了一个虚拟终端里面,我们可以运行一些命令,使用命令exit或者ctrl d 退出该bash,当退出后这个容器也会停止。
docker run -d 可以让容器在后台运行
给容器自定义名字:
[root@shuai-01 ~]# docker run -itd --name centos6_shuai centos6 bash
3207565dbe27a54c4d5052d979c670dec418e9392c4bc47fd07a2ec2a494192d
[root@shuai-01 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3207565dbe27 centos6 "bash" 13 seconds ago Up 11 seconds centos6_shuai
7fdfbd19b39d centos6 "bash" 14 minutes ago Up 12 minutes confident_mirzakhani
0850110acb98 centos6 "bash" About an hour ago Up About an hour compassionate_cori
cf4d1603dde4 centos "/bin/bash" 9 hours ago Up 9 hours gracious_lalande
[root@shuai-01 ~]# docker exec -it centos6_shuai bash
[root@3207565dbe27 /]#
查看历史信息:
docker logs 可以获取到容器的运行历史信息,用法如下
docker logs container_id
docker rm container_id //container_id是ps的时候查看到的,这样就可以把container删除,如果是运行的容器,可以加-f
导出容器:
docker export container_id > file.tar // 导出容器,可以迁移到其他机器上,需要导入
导入镜像:
cat file.tar |docker import - aming_test //这样会生成aming_test的镜像
仓库管理
创建私有仓库
下载registry镜像:
[root@shuai-01 ~]# docker pull registry
Using default tag: latest
latest: Pulling from library/registry
d6a5679aa3cf: Pull complete
ad0eac849f8f: Pull complete
2261ba058a15: Pull complete
f296fda86f10: Pull complete
bcd4a541795b: Pull complete
Digest: sha256:5a156ff125e5a12ac7fdec2b90b7e2ae5120fa249cf62248337b6d04abc574c8
Status: Downloaded newer image for registry:latest
用registry镜像来启动容器:
[root@shuai-01 ~]# docker run -d -p 5000:5000 registry
fde6ebc8164e4b48f8bf8dbaf5db98e793dc1222da3ed1d79a93a1e626b68c43
[root@shuai-01 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fde6ebc8164e registry "/entrypoint.sh /etc…" 22 seconds ago Up 8 seconds 0.0.0.0:5000->5000/tcp serene_franklin
以registry镜像启动容器,-p会把容器的端口映射到宿主机上,:左边为宿主机监听端口,:右边为容器监听端口
访问:
[root@shuai-01 ~]# curl 127.0.0.1:5000/v2/_catalog
{"repositories":[]}
5000端口是通的
把centos6的镜像传到私有仓库里去:
先给centos6镜像打一个标签:这个标签要带有宿主机的IP和端口
[root@shuai-01 ~]# docker tag centos6 192.168.176.135:5000/centos6
[root@shuai-01 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos6 latest 64326114b1ef 2 hours ago 512MB
192.168.176.135:5000/centos6 latest 64326114b1ef 2 hours ago 512MB
接着就可以push上仓库去
错误;
[root@shuai-01 ~]# docker push 192.168.176.135:5000/centos6
The push refers to repository [192.168.176.135:5000/centos6]
Get https://192.168.176.135:5000/v2/: http: server gave HTTP response to HTTPS client
需求的是使用HTTPS
解决:改配置文件/etc/docker/daemon.json
[root@shuai-01 ~]# vim /etc/docker/daemon.json
{
"insecure-registries":["192.168.176.135:5000"]
}
重启docker服务
[root@shuai-01 ~]# systemctl restart docker
启动registry容器:
[root@shuai-01 ~]# docker start fde6ebc8164e
fde6ebc8164e
接着push:
[root@shuai-01 ~]# docker push 192.168.176.135:5000/centos6
The push refers to repository [192.168.176.135:5000/centos6]
0a2f11f7b1ef: Pushing 66.78MB/512.1MB
查看私有仓库里面的镜像:
[root@shuai-01 ~]# curl 127.0.0.1:5000/v2/_catalog
{"repositories":["centos6"]}
从私有仓库上下载镜像:
从另一台机器上来pull私有仓库里的镜像
先在另一台上配置/etc/docker/daemon.json
[root@shuai-01 ~]# vim /etc/docker/daemon.json
{
"insecure-registries":["192.168.176.135:5000"]
}
启动docker服务后
docker pull 192.168.176.135:5000/centos6
docker数据管理
你设置在容器里面的应用写下的数据,一旦关闭容器,停掉了docker服务,数据就会没了。可以通过把宿主机的目录挂载到容器上去,则容器产生新的数据,都会写在磁盘上。
挂载本地目录到容器上
把宿主机上的/data/目录挂载到容器的/data/目录上。
[root@shuai-01 ~]# docker run -itd -v /data/:/data centos-with-net bash
44fa1d75eb8e350652d06f6beb053639d04c525c012ecbefadfc6d48b15081e9
[root@shuai-01 ~]# ls /data/
gitroot mysql svnroot wwwroot
[root@shuai-01 ~]# docker exec -it 44fa1d75 bash
[root@44fa1d75eb8e /]# ls /data
gitroot mysql svnroot wwwroot
挂载数据卷
其实我们挂载目录的时候,可以指定容器name,如果不指定就随机定义了。比如上面我们没有指定,它就生成了一个名字为relaxed_franklin,这个名字可以使用命令 docker ps 看最右侧一列
docker run -itd --volumes-from relaxed_franklin aming123 bash
这样,我们使用aming123镜像创建了新的容器,并且使用了 relaxed_franklin 容器的数据卷
[root@shuai-01 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
44fa1d75eb8e centos-with-net "bash" 8 minutes ago Up 8 minutes upbeat_swirles
[root@shuai-01 ~]# docker run -itd --volumes-from upbeat_swirles centos6 bash
71bceddca2c79fcd4ba4a7ea792752fd4c31191e2e1c2fbcdac0a05cace08b2f
[root@shuai-01 ~]# docker exec -it 71bceddca bash
[root@71bceddca2c7 /]# ls /data/
gitroot mysql svnroot wwwroot
定义数据卷容器
有时候,我们需要多个容器之间相互共享数据,类似于linux里面的NFS,所以就可以搭建一个专门的数据卷容器,然后其他容器直接挂载该数据卷。
首先建立数据卷容器
docker run -itd -v /data/ --name testvol centos bash //注意这里的/data/是容器的/data目录,并非本地的/data/目录。
然后让其他容器挂载该数据卷
docker run -itd --volumes-from testvol aming123 bash
数据卷的备份和恢复
当你的docker容器做过宿主机目录映射,只用定期备份宿主机目录即可备份数据。
容器没映射宿主机目录,这时需要建一个新的容器,
宿主机上的/data/backup目录与新建容器的/backup/目录做过映射,数据卷容器/data/目录挂载新建容器/data/目录,将新建容器的/data/目录拷贝到新建容器的/backup目录,就实现了数据卷容器的数据的备份。
备份
mkdir /data/backup
docker run --volumes-from testvol -v /data/backup/:/backup centos tar cvf /backup/data.tar /data/
说明:首先我们需要使用testvol数据卷新开一个容器,同时我们还需要把本地的/vol_data_backup/目录挂载到该容器的/backup下,这样在容器中/backup目录里面新建的文件,我们就可以直接在/data/backup/目录中看到了。 然后再把/data/目录下面的文件打包到成data.tar文件放到/backup目录下面。
恢复
思路: 先新建一个数据卷容器,再建一个新的容器并挂载该数据卷容器,然后再把tar包解包。
新建数据卷容器:docker run -itd -v /data/ --name testvol2 centos bash
挂载数据卷新建容器,并解包:docker run --volumes-from testvol2 -v /data/backup/:/backup centos tar xf /backup/data.tar
docker的网络模式
host模式,使用docker run时使用–net=host指定
docker使用的网络实际上和宿主机一样,在容器内看到的网卡ip是宿主机ip
container模式,使用–net=container:container_id/container_name
多个容器使用共同的网络,看到的ip是一样的
none模式,使用–net=none指定
这种模式下,不会配置任何网络
bridge模式,使用–net=bridge指定默认模式,不用指定默认就是这种网络模式。这种模式会为每个容器分配一个独立的Network Namespace。类似于vmware的nat网络模式。同一个宿主机上的所有容器会在同一个网段下,相互之间是可以通信的
平时,docker容器是不能被外部机器访问到的,只是它于宿主机之间的通信。要想被外部机器访问,需要做端口映射。
首先使用centos镜像新建一个容器,然后在该容器中安装httpd服务,并启动
再把该容器导成一个新的镜像(centos-httpd),然后再使用新镜像创建容器,并指定端口映射
docker run -itd -p 5123:80 centos-httpd bash //-p 可以指定端口映射,本例中将容器的80端口映射为本地的5123端口
docker exec -it container_id bash
启动httpd: httpd -k start
编辑1.html: vi /var/www/html/1.html 随便写点东西
退出该容器:exit
测试: curl 127.0.0.1:5123/1.html
-p后面也支持IP:port:ip:port 的格式,比如
-p 127.0.0.1:8080:80
也可以不写本地的端口,只写ip,这样会随意分配一个端口
-p 127.0.0.1::80 //注意这里是两个冒号
先在一台容器中安装Nginx服务,然后将容器其打包成镜像。
[root@44fa1d75eb8e /]# yum install -y epel-release
[root@44fa1d75eb8e /]# yum install -y nginx
[root@shuai-01 ~]# docker commit -m "install nginx" -a "shuailinux" 44fa1d75eb8e centos_with_nginx
sha256:314a7e96e276fb0cfa3d611c3f28cd1337cc679ef60ef9d4f674ca3162b07d28
将这个新产生的镜像运行一个容器,将宿主机的8088端口映射到容器的80端口。
[root@shuai-01 ~]# docker run -itd -p 8088:80 centos_with_nginx bash
a897bfe5c0e2876f1ef185d80eab7c821f47551beaa3c8834dbdf128582a20c0
问题:
[root@a897bfe5c0e2 /]# systemctl start nginx
Failed to get D-Bus connection: Operation not permitted
解决:
这是因为dbus-daemon没有启动,解决该问题可以这样做
启动容器时,要加上–privileged -e “container=docker” ,并且最后面的命令改为/usr/sbin/init
docker run -itd --privileged -e “container=docker” centos_with_nginx /usr/sbin/init
[root@shuai-01 ~]# docker run -itd --privileged -e "container=docker" -p 8088:80 centos_with_nginx /usr/sbin/init
452fac8efe00cddcc86874df158144c6d39d0839a609f9d825700eb9854752d5
[root@shuai-01 ~]# docker exec -it 452fac8efe bash
[root@452fac8efe00 /]# systemctl start nginx
在容器里访问80端口:
[root@452fac8efe00 /]# curl localhost:80
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Test Page for the Nginx HTTP Server on Fedora</title>
在宿主机里访问8088:
[root@shuai-01 ~]# curl localhost:8088
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Test Page for the Nginx HTTP Server on Fedora</title>
在其他机器上访问:
[root@shuai-02 ~]# curl 192.168.176.135:8088
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Test Page for the Nginx HTTP Server on Fedora</title>
配置桥接网络
使用pipwork
为了使本地网络中的机器和Docker容器更方便的通信,我们经常会有将Docker容器配置到和主机同一网段的需求。这个需求其实很容易实现,我们只要将Docker容器和宿主机的网卡桥接起来,再给Docker容器配上IP就可以了
首先在宿主机上搞一个虚拟网卡br0
[root@shuai-01 ~]# cd /etc/sysconfig/network-scripts/
[root@shuai-01 network-scripts]# cp ifcfg-ens33 ifcfg-br0
ens33配置:
[root@shuai-01 network-scripts]# vi ifcfg-ens33
TYPE=Ethernet
BOOTPROTO=none
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=ens33
#UUID=d23205fd-677c-4490-92f0-dd3d07af7abf
DEVICE=ens33
ONBOOT=yes
#DNS1=119.29.29.29
#IPADDR=192.168.176.135
#PREFIX=24
#GATEWAY=192.168.176.2
IPV6_PEERDNS=yes
IPV6_PEERROUTES=yes
BRIDGE=br0
br0配置:
[root@shuai-01 network-scripts]# vi ifcfg-br0
TYPE=Bridge
BOOTPROTO=none
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=br0
#UUID=d23205fd-677c-4490-92f0-dd3d07af7abf
DEVICE=br0
ONBOOT=yes
DNS1=119.29.29.29
IPADDR=192.168.176.135
PREFIX=24
GATEWAY=192.168.176.2
IPV6_PEERDNS=yes
IPV6_PEERROUTES=yes
vi ifcfg-eth0 //增加BRIDGE=br0,删除IPADDR,NETMASK,GATEWAY,DNS1
vi ifcfg-br0//修改DEVICE为br0,Type为Bridge,把eth0的网络设置设置到这里来
重启网络服务:
[root@shuai-01 network-scripts]# systemctl restart network
[root@shuai-01 network-scripts]# ifconfig
br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.176.135 netmask 255.255.255.0 broadcast 192.168.176.255
inet6 fe80::6bfe:e3e3:8ec6:5546 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:a1:0e:2c txqueuelen 1000 (Ethernet)
RX packets 18 bytes 1272 (1.2 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 24 bytes 2112 (2.0 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
inet6 fe80::42:51ff:fe37:b0f6 prefixlen 64 scopeid 0x20<link>
ether 02:42:51:37:b0:f6 txqueuelen 0 (Ethernet)
RX packets 7526 bytes 326444 (318.7 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 11309 bytes 25200479 (24.0 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
ether 00:0c:29:a1:0e:2c txqueuelen 1000 (Ethernet)
RX packets 22562 bytes 26001982 (24.7 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 12064 bytes 1044199 (1019.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
设置成功后,ens33没有ip,br0有
安装pipwork
[root@shuai-01 ~]# git clone https://github.com/jpetazzo/pipework
正克隆到 'pipework'...
remote: Enumerating objects: 501, done.
remote: Total 501 (delta 0), reused 0 (delta 0), pack-reused 501
接收对象中: 100% (501/501), 172.97 KiB | 76.00 KiB/s, done.
处理 delta 中: 100% (264/264), done.
[root@shuai-01 ~]#
[root@shuai-01 pipework]# cp pipework /usr/local/bin/
开启一个容器:
[root@shuai-01 ~]# docker run -itd --net=none centos_with_nginx bash
82cb449e8e65887a1552ff74742769ea806cfc6ab502f7a883319b1fa4dc87fe
[root@shuai-01 ~]# docker exec -it 82cb449e8 bash
[root@82cb449e8e65 /]#
查看容器网络:
[root@82cb449e8e65 /]# ifconfig
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
给容器配置网络,用pipework命令:
[root@shuai-01 ~]# pipework br0 82cb449e8 192.168.176.137/[email protected]
[root@shuai-01 ~]# docker exec -it 82cb449e8e65 bash
[root@82cb449e8e65 /]# ifconfig
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.176.137 netmask 255.255.255.0 broadcast 192.168.176.255
ether ce:7a:5b:4e:8f:50 txqueuelen 1000 (Ethernet)
RX packets 10 bytes 768 (768.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1 bytes 42 (42.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0