介绍
介绍
Docker是一个容器(Container)服务,用来管理容器。
容器就是一个运行环境,可以部署任何软件运行环境,且环境内只包含最小的操作系统所需要的系统文件,轻量级的运行环境保证了系统的性能,干净的系统环境保证了系统的安全。
容器可以有自己的IP地址,可以有自己的service系统,可以有自己的hosts,可以有自己的crontab...所以,容器很像虚拟机,在容器里面运行的软件就像在独立的Linux里面运行的效果一样。
Docker还是一个镜像(Image)服务,可以管理镜像。
镜像就是从一个稳定的容器打包出来的一个静态的包,通过镜像可以快速地创建一个一模一样的容器。镜像就像是Git里面的Tag,我们可以给调试好的容器进行导出镜像操作,然后在需要的地方进行镜像还原容器操作,这样可以方便的模板化创建容器。
基本信息
安装环境
CentOS:CentOS Linux release 7.6.1810 (Core)
Linux:Linux version 3.10.0-1062.el7.x86_64
GCC:gcc version 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC)
安装Docker
安装
使用yum安装docker
yum -y install docker
验证
输入命令
[root@tfdev ~]# docker -v Docker version 1.13.1, build 0be3e21/1.13.1
启动
关闭SELinux,这玩意和docker合不来
打开selinux的配置文件
vi /etc/sysconfig/selinux
修改文件内容,将参数 SELINUX 修改为 disabled
SELINUX=disabled
重启服务器
reboot
重启docker
systemctl restart docker
自动启动
systemctl enable docker
Docker创建私有仓库(repository)
第一步
拉一个registry镜像下来
docker pull registry
第二步
运行仓库
docker run -d -p 5000:5000 -v /opt/registry:/tmp/registry docker.io/registry
第三步
验证
docker ps -a
查看镜像
V1版本是
curl 127.0.0.1:5000/v1/search
V2版本是
curl 127.0.0.1:5000/v2/_catalog
创建镜像
第一步
先拉一个镜像从远程仓库
docker pull centos
第二步
修改tag到本地
docker tag docker.io/centos 127.0.0.1:5000/centos:tongfu
第三步
上传镜像到本地仓库
docker push 127.0.0.1:5000/centos:tongfu
Docker容器操作(container)
创建容器
docker run -tid --name [容器名称] [镜像名称]
进入容器
采用attach进入容器后,通过exit退出的话,容器会停止运行
docker attach [容器名称]
在容器内执行命令
docker exec [容器名称] /bin/bash -c "命令"
停止容器
docker stop [容器名称]
启动容器
docker start [容器名称]
退出容器
正常进入容器后退出的话,容器会停止运行,那么如何保证退出后容器一直运行呢?
答案是通过 exec 进入容器,命令如下:
docker exec -ti [容器名称] /bin/bash
这样也可以进入容器,同时这样退出不会导致容器停止运行
删除容器
要删除一个容器之前必须要先停止这个容器
docker rm [容器名称]
Docker网络配置(network)
创建网络
注意:虚拟网络的IP网段千万不要和本地物理网络冲突,否则会导致容器内部网络不通的情况!!!
docker network create --subnet=10.16.1.0/16 --gateway=10.16.1.1 --opt "com.docker.network.bridge.name"="bridge2" bridge2
使用新网络创建容器
docker run -tid --name=base --net=bridge2 --ip=10.16.1.100 -p 8000:80 docker.tongfu.net:5000/centos
这样新创建的容器的IP地址就是bridge2网络的地址,通过网关IP可以与宿主机互相通讯,同时我们将容器的80端口映射给了宿主机8000端口。
容器IP地址:10.16.1.100
宿主机IP地址:10.16.1.1
容器端口:80
宿主机端口:8000
查看网络列表
[root@tongfunet]# docker network ls NETWORK ID NAME DRIVER SCOPE 2f03bb8a8a13 bridge bridge local 3919c34c3c33 bridge2 bridge local 305e882739a3 host host local 363c4d747119 none null local
删除网络
注意默认的几个网络不要动(bridge、host、none)
[root@tongfunet]# docker network rm bridge2 bridge2
查看网络列表
[root@tongfunet]# docker network ls NETWORK ID NAME DRIVER SCOPE 2f03bb8a8a13 bridge bridge local 305e882739a3 host host local 363c4d747119 none null local
Docker导出与导入(export/import)
导出
将容器内容导出到一个压缩包内
[root@tongfunet]# docker export [容器名称] > [压缩包名称].tar
导入
从一个压缩包内导入数据到镜像里
[root@tongfunet]# docker import [压缩包名称].tar [镜像名称]
另一种导入命令
[root@tongfunet]# cat [压缩包名称].tar | docker import - [镜像名称]
Docker容器生成镜像(image)
提交到仓库
我们辛辛苦苦调试好的容器,不想一个不小心就丢了,还想给其他人用,怎么办?
我们可以通过comment命令将自己的容器提交到仓库
base是现有容器名称
base-net是新的镜像名称
docker commit -m "m" -a "a" base docker.tongfu.net:5000/centos:base-net
查看镜像列表
看我们的容器变成了镜像,可以通过run使用了
# docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker.tongfu.net:5000/centos base-net e026052245dc 44 seconds ago 303.7 MB
删除镜像
删除一个镜像必须要删除所有基于这个镜像创建的容器
docker rmi [镜像id]
查看镜像
我们可以查看镜像信息,包括创建参数,依赖镜像等等
# docker history [镜像id] IMAGE CREATED CREATED BY SIZE COMMENT ec7d21826858 12 months ago /usr/sbin/init 56.69 MB Web server 2.4.27 for CentOS 7 b6bac0adfc18 12 months ago /usr/sbin/init 141.7 MB The pure CentOS with net-tools , crontabs , gcc , make ff426288ea90 12 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0 B <missing> 12 months ago /bin/sh -c #(nop) LABEL name=CentOS Base Ima 0 B <missing> 12 months ago /bin/sh -c #(nop) ADD file:6bba01fe946852a560 207.2 MB
Docker备份与还原(backup/restore)
备份
我们要将做好的镜像备份起来,可以使用下面的命令
docker save docker.tongfu.net:5000/centos:base -o /tongfu.net/docker/backup/base.tgz
还原
我们要使用备份的文件还原,可以使用下面的命令
docker load -i /tongfu.net/docker/backup/base.tgz
Docker数据目录迁移(move data directory)
迁移数据目录
停止服务
systemctl stop docker
移动数据目录
mv /var/lib/docker /data/docker
建立符号链接
ln -s /data/docker /var/lib/docker
启动服务
systemctl start docker
Docker常见问题
save/load和export/import区别
save/load生成的镜像包含容器的依赖镜像的每一层信息,容量比较大。
export/import生成的镜像没有历史镜像信息,无法进行回滚操作,相对容量比较小。
Docker的存储驱动(Storage Driver)
介绍
docker有这么几种存储驱动,OverlayFS(overlay),AUFS(aufs),Btrfs(btrfs),Device Maper(devicemapper),VFS*(vfs),ZFS(zfs)
其中旧版本默认采用的驱动是devicemapper,最新版本1.13.x默认采用的驱动是overlay2
区别
overlay
这里面根据笔者的经验,我们只谈谈overlay这种驱动。
在使用最新版本1.13.x进行镜像设计的过程中发现了一个bug,就是通过images开启的容器内部,如果要删除镜像自带目录会被告知:Directory not emtpy。
很迷惑的一个提示。。
笔者一开始以为是被进程占用了,各种查找,各种重启容器,重启docker,各种reboot,各种重建容器,依然解决不了问题。
但是映射进来的目录就完全正常!
最后发现这是overlay的一大特性,出于对镜像模板内容的保护,删除操作会被禁止,用户内容需要通过映射目录方式实现。
好吧~~这是好事,习惯了就好~~
那个不知所谓的 Directory not empty 是迷糊“黑客”的。。
devicemapper
这种方式下,我们操作容器内的内容没有任何限制
网上一些文章倡导用这种驱动替代overlay驱动,解决不能rm -rf的问题
我个人的主张,没有必要,要学会接受新鲜事物~~
当然,学习如何切换存储驱动到是可以的!
常见错误
Pull镜像报错
使用pull命令拉取镜像时候报错
Get https://registry-1.docker.io/v2/library/registry/manifests/latest: net/http: TLS handshake timeout
解决方法,设置国内镜像地址(设置后需要重启docker服务)
[root@tfdev ~]# cat /etc/docker/daemon.json { "registry-mirrors":[ "https://registry.docker-cn.com" ] }
容器无法联网
创建容器的时候,报如下警告信息
WARNING: IPv4 forwarding is disabled. Networking will not work.
解决方法
echo "net.ipv4.ip_forward=1" >> /usr/lib/sysctl.d/00-system.conf systemctl restart network systemctl restart docker
使用yum报错
使用yum报错rpmdb open failed信息
error: rpmdb: BDB0004 fop_read_meta: /var/lib/rpm/Packages: unexpected file type or format error: cannot open Packages index using db5 - Invalid argument (22) error: cannot open Packages database in /var/lib/rpm CRITICAL:yum.main: Error: rpmdb open failed
解决方法
rm -f /var/lib/rpm/* rpm --rebuilddb yum clean all