Docker笔记
安装
首先检查是否已经安装过Docker:yum list installed | grep docker
,如果已经安装过需要删除旧的Docker:yum remove docker-ce
,除默认的docker目录,其中包含了之前的镜像和容器文件、配置等:rm -rf /var/lib/docker
。
(如果有2017年之前的版本,需要如下删除)
yum remove docker
docker-client
docker-client-latest
docker-common
docker-latest
docker-latest-logrotate
docker-logrotate
docker-selinux
docker-engine-selinux
docker-engine
如果执行yum list时提示“Repodata is over 2 weeks old. Install yum-cron? Or run: yum makecache fast”,则运行yum makecache fast
即可(这个命令是指将软件列表缓存到本地)
官方其实有一键安装脚本(但是国内下载有点慢):
安装:
wget -qO- https://get.docker.com/ | sh
启动(CentOS 7):
systemctl start docker
给予用户权限:
sudo usermod -aG docker 用户名
记得重启一下shell。
或者直接从yum安装(centOS默认源很慢,首先需要换一下国内源,见下文添加Docker源):
#必须先更新yum源,否则找不到docker-ce,只能找到docker
yum makecache fast
#查看所有仓库中所有docker版本
yum list docker-ce --showduplicates | sort -r
#直接安装Docker CE (总会安装最新版,可能不符合你的需求)
yum -y install docker-ce
#或选择安装64位的版本:
#yum install docker-ce.x86_64
#或选择特定版本安装,比如这里的版本是19.03.0.ce:
yum -y install docker-ce-19.03.0.ce
添加Docker源
首先安装yum工具包:
yum install -y yum-utils
然后添加阿里的Docker源:
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
然后更新列表:
yum makecache fast
docker启动重启命令:
systemctl status docker
systemctl start docker
systemctl stop docker
systemctl restart docker
systemctl enable docker #开机自启
systemctl disable docker #取消开机自启
Docker介绍
Docker中的几个对象概念:
- 容器(Container)
- 镜像(Image)
- 仓库(Repository)
- 注册中心(Registry)
容器类似Java中的类的示例,镜像类似Java中的类,而仓库则是存放镜像的地方,注册中心有共有仓库和私有仓库。
完整描述一个镜像:注册中心/仓库:标记,比如:rep.itcast.cn/tomcat:9.0.12
,如果省略注册中心,默认是docker.io
或index.docker.io/v1/
。
更换Docker镜像地址
执行docker info | grep Registry
可以看到docker默认的仓库地址,这里可以更换中科大的Docker加速镜像:
# 编辑文件(没有就创建一个)
vim /etc/docker/daemon.json
在其中添加(其实这里更推荐阿里的源,要快得多,地址是这里,需要登录阿里账号):
{
"registry-mirrors": ["https://docker.mirrors.ustc.edu.cn"]
}
然后重启Docker:
systemctl daemon-reload && systemctl restart docker
然后docker info
可以看到源的镜像地址。
如果执行docker命令时出现如下警告(正常情况下貌似没有)
WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled
可以如下处理:
vim /etc/sysctl.conf
添加:
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
然后
sysctl -p
即可
镜像操作
查找镜像
docker search [选项] 搜索内容
选项参数:
Name, shorthand | Default | Description |
---|---|---|
--automated |
只展示自动构建 | |
--filter , -f |
根据条件过滤 | |
--format |
格式化输出 | |
--limit |
25 |
最大搜索结果 |
--no-trunc |
不截断输出 | |
--stars , -s |
只展示最少多少星的 |
镜像搜索还可以直接在这个网站Docker hub直接搜索。
拉取镜像
docker pull [选项] NAME[:TAG|@DIGEST]
选项参数:
Name, shorthand | Default | Description |
---|---|---|
--all-tags , -a |
下载仓库中所有目标镜像 | |
--disable-content-trust |
true |
跳过镜像验证 |
--platform |
镜像支持多平台时可以设置平台 | |
--quiet , -q |
静默下载(没有下载输出) |
如果使用默认注册中心时可以省略注册中心地址,同时还有:
- centos:7.6.1810----->下载的就是7.6.1810
- centos:7.6 ------->下载7.5.最高版本 的版本
- centos:7 ------->下载7系列最高的版本
- centos:6 ------->下载6系列最高的版本
- centos:latest ------->下载最高的版本,省略版本号时就是latest
- centos ------->下载最高的版本,省略版本号时就是latest
查看镜像
查看本地镜像:
docker search [选项] 镜像名
选项参数:
Name, shorthand | Default | Description |
---|---|---|
--automated |
只展示自动构建的镜像 | |
--filter , -f |
过滤 | |
--format |
格式化输出 | |
--limit |
25 |
最大展示数 |
--no-trunc |
不截断输出(ID长的时候会截断) | |
--stars , -s |
展示至少多少start的镜像 |
示例
#列出"centos"仓库中的所有镜像:
docker images centos
#列出标记为7.6.1810的"centos"仓库中的所有镜像:
docker images centos:7.6.1810
#列出镜像信息中有centos的镜像
docker images | grep centos
删除镜像
删除centos的镜像
docker rmi centos
删除所有镜像(慎用)
#docker images -q 展示所有镜像id
#这里的不是单引号,而是反引号
docker rmi `docker images -q`
容器操作
如果说镜像是类,那容器就是类的一个实例。
查看容器
docker ps [选项]
选项参数:
Name, shorthand | Default | Description |
---|---|---|
--all , -a |
查看所有容器 (默认只有正在运行的容器) | |
--filter , -f |
过滤 | |
--format |
格式化输出 | |
--last , -n |
-1 |
显示n个上次创建的容器(包括所有状态) |
--latest , -l |
显示最新创建的容器(包括所有状态) | |
--no-trunc |
不截断输出 | |
--quiet , -q |
仅显示数字标识 | |
--size , -s |
显示文件总大小 |
(1)列出所有正在运行的容器:
docker ps
(2)显示所有容器,包括正在运行的和停止的。
docker ps -a
- -a:显示正在运行的和停止的容器。该参数也可以写成
--all
或--all=true
。
(3)查看停止了的容器列表(一般不用)
docker ps -f status=exited
#或
docker ps -a |grep exited
- -f:过滤结果,该参数也可以写成
--filter
。 - status:是
-f
参数中的参数,指的是容器的状态,该状态的值有:created
,restarting
,running
,removing
,paused
,exited
,或dead
。
创建运行容器
一般使用docker run 镜像名
来运行一个容器。该命令参数较多,不再一一列举。
交互式容器
创建一个用于测试的容器,容器创建成功后自动分配伪终端,可进行人机交互。
创建运行一个centos的容器:
docker run -it --name=mycentos centos:7.6.1810 bash
#或
docker run -i -t --name=mycentos centos:7.6.1810 bash
#或
docker run --interactive=true --tty=true --name=mycentos centos:7.6.1810 /bin/bash
- -i:保持标准输入(STDIN)打开,可实现交互式输入输出。该参数也可以写成
--interactive=true
。 - -t:分配一个伪终端(pseudo-TTY:伪终端、虚拟控制台),用于交互式的输入输出,必须有
-i
参数。该参数也可以写成--tty =true
。 - bash:分配伪终端时要在容器上执行的执行,这里使用的linux的bash脚本命令,该命令完整写法为
/bin/bash
。
提示:
run
和镜像名字之间的选项没有顺序,但命令必须放到镜像名字之后。
优点:
创建完容器后,自动运行容器,并可以直接进入到子容器系统中操作了,主要用于测试使用。
缺点:
当退出子容器后,该容器会自动停止运行。
守护式容器:
创建一个需要长期运行的容器,就可以创建一个守护式容器(后台运行的容器),下面的命令用于在后台创建运行容器并打印容器ID:
docker run -id --name=mycentos2 centos:7.6.1810
-d
:在后台运行容器并打印容器ID。该参数也可以写成--detach
或--detach=true
。
提示:
该容器的运行需要打开标准输入(-i
参数),否则无法运行。但对于很多容器来说,无需标准输入,则无需使用-i
参数,只需要-d
即可。不管是否需要标准输入,加上-i
的参数暂无发现有副作用。
登录守护式容器方式:
docker exec -it container_name (或者 container_id) /bin/bash #exit退出时,容器不会停止
比如:
#方式1:使用名字进入
docker exec -it mycentos2 bash
#方式2:使用id进入(ID很长,可以只写前一部分)
docker exec -it 2c32a5cb4a71 bash
优点:
从守护式容器中退出,并不影响容器的运行。
缺点:
必须的手动命令进入到容器。
docker run
其实包含创建和运行两步
容器停止与挂起
容器的停止/重启
说明:
停止一个或多个正在运行的容器
docker stop/restart [选项] 容器名 [其他容器名]
选项:
Name, shorthand | Default | Description |
---|---|---|
--time , -t |
10 |
几秒之后停止 |
例如:停止正在运行的mycentos2容器:
docker stop mycentos2
容器的启动
说明:
启动一个或多个已经停止了的容器
docker start [选项] 容器名 [其他容器名...]
选项:
Name, shorthand | Default | Description |
---|---|---|
--attach , -a |
附加STDOUT/STDERR和转发信号 | |
--checkpoint |
附加STDOUT/STDERR和转发信号 | |
--checkpoint-dir |
使用自定义检查点存储目录 | |
--detach-keys |
覆盖分离容器的键序列 | |
--interactive , -i |
附加容器的STDIN |
例如:启动mycentos2容器
docker start mycentos2
三、容器的挂起与取消
docker pause 容器名 [容器名...]
docker unpause 容器名 [容器名...]
文件拷贝
# 容器中文件表示为 容器名:容器内路径
docker cp 原路径 目标路径
目录的映射挂载
docker run -v `宿主机目录`:`容器目录` [--read-only] image
- -v:将当前工作目录装载到容器中。绑定装载卷的宿主机目录不存在时,Docker会自动在宿主机上为您创建这个目录。
- --read-only:将容器的根文件系统安装为只读。卷的挂载可以与只读标志选项--read-only结合使用,用于控制容器对文件是否能写入。只读标志将容器的根文件系统挂载为只读,禁止向容器指定卷以外的位置写入。容器中只有挂载的目录是可写的,其他的目录无法写入,从而保护容器。
宿主机路径必须是绝对路径。
可能遇到的问题:
如果你共享的是多级的目录,挂载宿主机已存在目录后,在容器内对其进行操作,报“Permission denied”。可能会出现权限不足的提示。
方案一、 指定--privileged参数,以特权方式启动容器 (推荐)
--privileged=true
docker run -id --name=mycentos3 -v /root/myvolume:/myvolume --privileged centos:7.6.1810
#或
docker run -id --name=mycentos3 -v /root/myvolume:/myvolume --privileged=true centos:7.6.1810
方案二、关闭CentOS7中的安全模块selinux(了解)
1)临时关闭:
setenforce 0
2)永久关闭:修改/etc/selinux/config
或/etc/sysconfig/selinux
文件,将SELINUX的值设置为disabled。
#默认值是enforcing
SELINUX=disabled
#注释掉这行(可选)
#SELINUXTYPE=targeted
保存,退出,重启系统
不想重启,可以使用:setenforce 0
,使配置立即生效
删除容器
删除一个或多个容器。
docker rm [选项] 容器名 [其他容器名]
选项:
Name, shorthand | Default | Description |
---|---|---|
--force , -f |
强制删除正在运行的容器 | |
--link , -l |
删除指定的链接 | |
--volumes , -v |
删除与容器关联的卷 |
【示例】
(1)先停止运行的mycentos3的容器,再删除它。
docker stop mycentos3
docker rm mycentos3
提示:
上述命令默认只能删除停止了的容器。若容器是启动的状态,则可以先停止容器,再删除。
(2)直接强制删除正在运行的mycentos2容器
docker rm -f redis
#或者
docker rm --force redis
(3)强制删除所有的容器
# 注意这里是反引号,不是单引号
docker rm -f `docker ps -qa`
#或
docker rm -f $(docker ps -a -q)
(4)删除容器时,将其关联的卷也删掉
(数据卷的生命周期独立于容器)
-V
命令将删除容器及其关联的任何卷。请注意,如果使用名称指定了卷,则不会删除该卷。
#docker create -v awesome:/foo -v /bar --name hello redis
docker run -id -v /root/myvolume:/myvolume -v mycentosfoo:/foo -v /bar --name=mycentos5 centos:7.6.1810
docker rm -v mycentos5
在此示例中,/foo的卷将保持不变,但/bar的卷将被删除。对于继承了--volumes-from的卷,同样的行为也适用。
容器的开机自启
如果还未创建容器,则可以在run命令中添加--restart=always
来使该容器开机自启(推荐);
如果已经创建容器,则可以使用docker update --restart=always 容器名或容器ID
来设置容器开机自启。
部署
Redis部署
拉取Redis镜像
docker pull redis
创建Redis容器
docker run -d --name=my_redis -p 6379:6379 redis
-p
代表端口映射,宿主机映射端口:容器运行端口
MySQL部署
拉取MySQL镜像
docker pull mysql
创建运行容器,并添加端口映射并修改数据库密码
docker run -di --name=my_mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql
-e
代表添加环境变量,MYSQL_ROOT_PASSWORD是数据库root用户登录密码
几个Linux的小知识点:
- 查看端口占用:
lsof -i:端口号
- 关闭MySQL服务:
systemctl stop mysql
- 查看MySQL版本:
- shell中执行:
mysql -v
(匿名有可能不被MySQL允许) - MySQL中执行:
select version();
- shell中执行:
MySQL8的默认的密码加密策略发生了变化,之前的一些客户端的软件会出现无法登录的情况。
方式一:
使用mysql8版本的原生的客户端命令登录进去,使用之前的密码加密策略重新修改密码:
#本地登录(如果仅仅用原生的命令行在本地登录的话,可不用改)
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456';
#远程登录
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
方式二(推荐):
创建容器的时候,直接指定MySQL的默认认证插件使用mysql_native_password
:
docker run -di --name=my_mysql2 -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:8.0.17 --default-authentication-plugin=mysql_native_password
Tomcat部署
拉取Tomcat镜像:
docker pull tomcat
创建容器
docker run -id --name=my_tomcat -p 9001:8080 -v ~/myvolume:/usr/local/tomcat/webapps tomcat
#或
docker run -id --name=my_tomcat3 -p 9003:8080 -v ~/myvolume:/usr/local/tomcat/webapps --privileged=true tomcat
测试:
部署web应用
- 将程序拷贝到宿主机的~/myvolume下面。比如:再建立目录myapp,里面编辑一个index.html页面作为测试主页
- 在虚拟机的宿主机上的浏览器地址栏中输入:http://192.168.40.141:9001/myapp
备份与迁移
根据容器的更改创建新镜像,即基于原始镜像,将其运行的容器中更改的内容,来生成新的镜像。
docker commit [选项] 容器名
选项:
Name, shorthand | Default | Description |
---|---|---|
--author , -a |
作者(mailto:hannibal@a-team.com)”) | |
--change , -c |
将Dockerfile指令应用于创建的映像 | |
--message , -m |
创建信息 | |
--pause , -p |
true |
创建镜像时挂起容器 |
例:将myRedis提交为新的镜像:
docker commit myRedis my_redis:1.0.1
本地就会多一个镜像。
镜像保存
将一个或多个镜像保存到tar存档(默认流到标准输出-STDOUT)
docker save [选项] 镜像名 [其他镜像名...]
Name, shorthand | Default | Description |
---|---|---|
--output , -o |
写入文件,而不是STDOUT(标准输出) |
例:
1)创建一个镜像的备份到磁盘文件:
# 后面可以跟多个镜像名来打包成一个文件
docker save -o myredis-1.0.1.save.tar myredis:1.0.1
#或
docker save myredis:1.0.1 > myredis-1.0.1.save.tar
2)镜像打包时使用gzip压缩,可以让备份的文件更小(建议):
docker save myredis:1.0.1 | gzip > myredis-1.0.1.save.tar.gz
3)将某个仓库的所有镜像打包(不常用):
docker save -o xxx.tar 仓库名字
#如
docker save -o redis.tar redis
镜像的加载
从tar归档文件或标准输入(stdin)加载镜像,归档文件即使是使用gzip、bzip2或xz压缩后的,也能自动识别和处理。
docker load [选项]
Name, shorthand | Default | Description |
---|---|---|
--input , -i |
从文件读取,而非标准输入 | |
--quiet , -q |
静默读取 |