最详细的 docker 随手记
- 前言
- 一、docker 环境搭建
- 1、环境准备
- 1.1、yum 包更新
- 1.2、安装依赖
- 1.3、设置yum源为阿里云
- 补充:关闭防火墙
- 2、docker安装
- 2.1 下载安装
- 2.2 docker版本检查
- 3、docker启动
- 3.1 启动
- 3.2 开机启动
- 3.3 重启
- 3.4 关闭
- 3.5 检查
- 4、docker 镜像源设置
- 二、docker常用命令
- 1、基本信息
- 2、镜像相关命令
- 2.1 查看本地镜像
- 2.2 搜索镜像
- 2.3 拉取镜像
- 2.4 删除镜像
- 3、容器相关命令
- 3.1 查看容器
- 3.2 创建与启动容器
- 3.3 停止与启动容器
- 3.4 文件拷贝
- 3.5 目录挂载
- 3.6 查看容器IP地址
- 3.7 删除容器
- 3.8 查看容器日志
- 3.9 设置容器伴随Docker服务启动
- 三、常用应用部署
- 1、MySQL部署
- 2、tomcat部署
- 3、Nginx部署
- 4、Redis部署
- 四、迁移与备份
- 1、容器保存为镜像
- 2、镜像备份
- 3、镜像恢复与迁移
- 五、Dockerfile
- 1、常用命令
- 2、使用脚本创建镜像
- 六、Docker 私有仓库
- 私有仓库搭建与配置
- 七、镜像操作之私有仓库
- 1、私有仓库 - 镜像上传与下载
- 2、私有仓库 - 镜像查询
- 3、私有仓库 - 镜像删除
- 4、私有仓库 - 镜像删除 - 脚本删除
- 八、其他问题处理
- 1、修改已创建好的容器配置,如端口映射,目录挂载等
前言
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。
博主在学习工作中,使用docker总结了一点心得,这里将其整理记录下来,供自己和大家参考。
一、docker 环境搭建
1、环境准备
docker 官方建议基于 ubuntu
进行安装与使用。
如果你使用的是 centOS
系统,建议使用 centOS7.x
,即内核版本为3.1
及其以上。
如果你使用的是 centOS6.x
,由于内核版本较低,有些特性无法使用,需要先升级系统内核。这里请自行百度,这里就不再赘述。
博主这里使用的是centOS7
进行安装。centOS7
镜像下载地址:阿里云 centOS7镜像下载.
1.1、yum 包更新
安装好镜像后启动,先更新 yum 库
sudo yum update
1.2、安装依赖
yum-util 提供 yum-config-manager功能,另外两个是 devicemapper驱动依赖的
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
1.3、设置yum源为阿里云
设置源为阿里云,后面下载速度会快很多
# 备份原文件
sudo cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
# 修改yum源
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
补充:关闭防火墙
如果遇到一些网络问题或其他问题,可尝试关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
2、docker安装
2.1 下载安装
docker-ce 社区版
docker-ee 企业版
sudo yum install -y docker-ce
2.2 docker版本检查
安装完成后,检查docker版本
docker -v
3、docker启动
3.1 启动
# centos 7.x
systemctl start docker
# centos 6.x
service docker start
3.2 开机启动
systemctl enable docker
3.3 重启
# centos 7.x
systemctl restart docker
# centos 6.x
sudo service docker restart
3.4 关闭
# centos 7.x
systemctl stop docker
# centos 6.x
service docker stop
3.5 检查
docker ps -a
systemctl status docker
4、docker 镜像源设置
ustc是老牌的linux镜像提供者。ustc的docker镜像加速器速度很快。ustc docker mirror的优势之一就是无需注册,是真正的公共服务器。
- 先启动docker,此时系统会自动生成
/etc/docker
文件夹 - 在
/etc/docker
下创建并编辑daemon.json
文件
vi /etc/docker/daemon.json
- 输入如下内容(指定镜像下载地址)
{
"registry-mirrors": ["https://docker.mirrors.ustc.edu.cn"]
}
注意:如果 daemon.json 配置不生效
# 修改 docker.service 配置文件
vi /lib/systemd/system/docker.service
# 添加如下内容(在 ExecReload=/bin/kill -s HUP $MAINPID 之下添加)
EnvironmentFile=-/etc/docker/daemon.json
# 重启docker
systemctl restart docker
二、docker常用命令
1、基本信息
# 基本信息查看
docker info
# 帮助
docker -h/--help
# 版本
docker -v/--version
2、镜像相关命令
2.1 查看本地镜像
镜像存在docker宿主机的 /var/lib/docker
目录下
第一次安装docker时,本地是没有镜像的,可以通过下面的指令查看本地镜像
# 查看本地镜像
docker images
# -q 查出所有镜像ID
docker images -q
REPOSITORY TAG IMAGE ID CREATED SIZE
镜像名称 镜像标签 镜像ID 镜像的创建时间 镜像大小
2.2 搜索镜像
从网络中获取镜像
docker search 镜像名
docker search centos
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
仓库名称 镜像描述 用户评价 是否官方 自动构建(表示该镜像是否由Docker Hub自动构建流程创建的)
2.3 拉取镜像
从中央仓库中下载镜像到本地
前面设置 ustc 镜像仓库加速器,便是为了提高镜像下载速度
docker pull 镜像名
docker pull centos:7
2.4 删除镜像
按镜像ID(或镜像名)删除镜像
docker rmi 镜像ID(或镜像名:tag)
docker rmi 5e35e350aded(centos:7)
删除所有镜像
docker rmi `docker images -q`
3、容器相关命令
3.1 查看容器
# 查看正在运行的容器
docker ps
# 查看所有容器
docker ps -a
# 查看最后一次运行的容器
docker ps -l
# 查看停止的容器
docker ps -f status=exited
3.2 创建与启动容器
docker run
--restart=alwarys:docker重启的时候,此容器一起启动
-i : 运行容器
-t : 容器启动后会进入其命令行。加入这两个参数后,容器创建就能登陆进去,即分配一个伪终端
-d : 表示创建一个守护式容器在后台运行(不会自动分配伪终端)
--name : 为创建的容器命名(需要赋值: --name=redis)
-v : 表示目录映射关系(前者是宿主机目录,后者是映射到容器内的目录)可以使用多个-v映射多个目录或文件。
注意:最好做目录映射 在宿主机上做修改,然后共享到容器上。
-p : 端口映射(前者是宿主机端口,后者是容器内的映射端口)可以使用多个-p映射多个端口
- 交互式方式创建容器
docker run -it --name=centos7 centos:7 /bin/bash
- 退出当前容器,会导致当前容器停止
exit
- 守护式方式创建容器
docker run -di --name=centos7 centos:7
- 登陆守护式容器方式
# 退出时,不会导致容器停止(推荐使用)
docker exec -it 容器id /bin/bash
# 退出时,会退出时,不会
docker attach 容器id
- 映射方式创建容器
# 使用镜像 nginx:latest,以后台模式启动一个容器
# 将容器的 80 端口映射到主机的 90 端口
# 主机的目录 /opt 映射到容器的 /data。
docker run -p 90:80 -v /opt:/data -d nginx:latest
3.3 停止与启动容器
- 停止容器
docker stop 容器名(或容器ID)
- 启动容器
docker start 容器名(或容器ID)
- 重启容器
docker restart 容器名(或容器ID)
3.4 文件拷贝
- 从宿主机拷贝文件到容器
docker cp 宿主机上待拷贝的文件或目录 容器名称:容器目录
- 从容器拷贝文件到宿主机
docker cp 容器名称:容器目录 宿主机上待拷贝的文件或目录
3.5 目录挂载
将宿主机目录挂载到容器。从而达到修改宿主机文件而影响容器
# 宿主机目录:容器目录
docker run -di -v /opt/test:/opt/vtest --name=centos-20200319-1700 centos:7
如果共享多级目录,可能会出现权限不足提示
因为CentOS7
中的安全模块selinux
把权限禁掉了。我们需添加参数 --privlleged=true
来解决
3.6 查看容器IP地址
docker inspect 容器名(或容器ID)
docker inspect --format ='{{.NetworkSettings.IPAddress}}' 容器名(或容器ID)
3.7 删除容器
docker rm 容器名(或容器ID)
3.8 查看容器日志
docker logs -f 457f9d9c6bde --tail=500
3.9 设置容器伴随Docker服务启动
docker container update --restart=always 容器名(或容器ID)
三、常用应用部署
1、MySQL部署
- 拉取mysql镜像
docker pull centos/mysql-57-centos7
- 创建容器
docker run -di --name=mysql-57-p33306 -p 33306:3306 -e MYSQL_ROOT_PASSWORD=123456 centos/mysql-57-centos7
-p: 端口映射。格式:宿主机映射端口:容器运行端口
-e: 添加环境变量。MYSQL_ROOT_PASSWORD 是root用户的登陆密码
- 进入mysql容器
docker exec -it mysql-57-p33306 /bin/bash
- 登陆 mysql
# 在容器中执行
mysql -u root -p
- 远程登陆 mysql
打开远程连接工具,连接mysql -> 宿主IP:33306
2、tomcat部署
- 拉取tomcat镜像
docker pull tomcat:7
docker pull tomcat:7-jre7
docker pull tomcat:8
docker pull tomcat:8-jre8
- 创建容器
docker run -di --name=tomcat-8-p9800 -p 9800:8080 -v /opt/tomcat/docker-tomcat/tomcat-8-p9800/webapps:/usr/local/tomcat/webapps tomcat:8
-p: 端口映射。格式:宿主机映射端口:容器运行端口
-v: 目录挂载。宿主机tomcat-8-jre8-p9801/webapps挂载至/usr/local/tomcat/webapps
- tomcat访问
# 宿主机IP:映射端口
http://192.168.0.233:9800
- 注意:访问前,由于将容器的 webapps挂载到宿主机了,宿主机相应目录下为空(即没有index等页面)这时访问会找不到主页。
解决方法:可将其他tomcat下的wabapps目录copy至挂载的宿主机目录下,再次访问即可。
比如我上面将容器的webapps目录挂载至宿主机的/opt/tomcat/docker-tomcat/tomcat-8-p9800/webapps/
目录
3、Nginx部署
- 拉取nginx镜像
docker pull nginx:1.17.9
- 创建nginx容器
docker run -di --name=nginx-p80 -p 80:80 nginx:1.17.9
- 进入容器
# 进入容器
docker exec -it nginx-p80 /bin/bash
# 查看nginx主配置
cat /etc/nginx/nginx.conf
# 根据主配置查看导入的默认配置 (默认静态文件位置 /usr/share/nginx/html)
cat /etc/nginx/conf.d/default.conf
# 将宿主机静态文件拷贝至默认文件位置
docker cp /opt/nginx/docker-nginx/public nginx-p80:/usr/share/nginx/html/
# 最后浏览器访问
http://192.168.0.233/public/images/idea3.jpg
- 进入nginx容器,查看主配置文件
根据主配置文件,查找导入的配置文件
将宿主机静态文件拷贝至默认文件位置
最后浏览器访问nginx的静态文件
4、Redis部署
- 拉取redis镜像
docker pull redis
- 创建redis容器
docker run -di --name=redis-p16379 -p 16379:6379 redis
- 远程连接
# win下,打开CMD窗口,cd到redis-cli.exe同目录下,利用客户端连接工具连接
redis-cli -h 192.168.0.233 -p 16379
- 或者直接使用redis客户端管理工具连接
四、迁移与备份
1、容器保存为镜像
# 容器名 保存后的镜像名
docker commit -a "swotxu" -m "add new_nginx" nginx-p80 nginx_p80:v1.0
2、镜像备份
# 保存后的文件名 镜像名
docker save -o nginx-p80-v1_0.tar nginx_p80:v1.0
3、镜像恢复与迁移
# 将备份的镜像tar文件,载入docker
docker load -i nginx-p80.tar
-i: 输入的文件
五、Dockerfile
1、常用命令
命令模板 | 示例 | 解释 |
FROM image_name:tag | FROM centos:7 | 定义了使用哪个基础镜像启动构建流程 |
MAINTAINER user_name | MAINTAINER swotxu | 声明镜像的创建者 |
ENV key value | ENV env dev | 设置环境变量 |
RUN command | RUN chmod 755 /usr/share/fonts/special/* | 构建时执行指令RUN ["./test.php", “dev”, “offline”] 等价于 RUN ./test.php dev office |
ADD source_dir/file dest_dir/file | ADD office-service-1.0.jar ./ | 将宿主机文件复制到镜像,若是压缩文件,会自动解压 |
COPY source_dir/file dest_dir/file | COPY office-service-1.0.jar ./ | 和ADD相似,但不会自动解压 |
WORKDIR path_dir | WORKDIR /usr/share/fonts/special/ | 设置工作目录 |
EXPOSE port | EXPOSE 8082 | 声明端口 |
CMD command | CMD java $JAVA_OPTS -jar myweb.jar | RUN在docker build时运行CMD在docker run时运行 |
ENTRYPOINT command | ENTRYPOINT java $JAVA_OPTS -jar myweb.jar | 定参,不会被docker run -e时覆盖 |
更多参数详情参见: runoob.com.
2、使用脚本创建镜像
模拟制作 JDK8 镜像
- 在宿主机创建目录
/opt/docker/docker-jdk8/
,将 jdk8.tar.gz 压缩包放入其中 - 创建
Dockerfile
文件
注意:Dockerfile
文件名注意大小写,文件无后缀
# cd到当前目录
cd /opt/docker/docker-jdk8/
# 创建 Dockerfile文件
vi Dockerfile
- 编辑 Dockerfile 文件
# 基于centos7镜像制作
#FROM 192.168.0.233:5000/common/centos7-ext-fonts:v1.0
FROM centos:7
MAINTAINER swotxu
#设置工作目录
WORKDIR /usr
#在镜像中创建文件夹
RUN mkdir /usr/local/java
#将宿主机的 jdk.tar 解压至容器的/usr/local/java/目录
ADD jdk-8u161-linux-x64.tar.gz /usr/local/java/
# 设置jdk所需环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_161
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/bin/dt.jar:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib:$CLASSPATH
ENV PATH $JAVA_HOME/bin:$PATH
# 将环境变量写入系统配置文件
RUN echo 'export JAVA_HOME=/usr/local/java/jdk1.8.0_161' >> /etc/profile
RUN echo 'export PATH=$JAVA_HOME/bin:$PATH' >> /etc/profile
RUN echo 'export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar' >> /etc/profile
- 执行命令生成镜像
docker build -t="jdk1.8" .
-t: 指定构建后镜像名称
.: 指定当前目录
- 启动 jdk1.8
docker run -dt --name=jdk1.8 192.168.0.233:5000/common/jdk1.8:v1.0
- 进入 jdk1.8
docker exec -it jdk1.8 /bin/bash
# 测试jdk环境是否安装成功
Java -version
# 退出镜像
exit
- 导出 jdk1.8镜像 (将镜像导出到宿主机本地,此步省略)
docker save -o jdk1.8-v1_0.tar 192.168.0.233:5000/common/jdk1.8:v1.0
- 导入 jdk1.8镜像 (从宿主机本地导入镜像,此步省略)
docker load -i jdk1.8-v1_0.tar
六、Docker 私有仓库
私有仓库搭建与配置
- 拉取私有仓库镜像
docker pull registry
- 启动私有仓库容器
启动私有仓库时,最好挂载配置文件config.yml
(宿主机新建此配置文件)便于后面对私有仓库中镜像的修改
# 方式一:直接启动(建议使用下面方式启动)
docker run -di --name=registry-p5000 -p 5000:5000 --restart=alwarys registry
# 方法二:挂载配置文件启动
docker run -di --name=registry-p5000 --restart=alwarys -p 5000:5000 -v /opt/docker/registry:/var/lib/registry -v /opt/docker/registry-data/config.yml:/etc/docker/registry/config.yml registry
--restart=alwarys:docker重启的时候,此容器一起启动
config.yml
配置如下:storage:delete:enabled: true
允许删除私有仓库镜像
version: 0.1
log:
fields:
service: registry
storage:
delete:
enabled: true
cache:
blobdescriptor: inmemory
filesystem:
rootdirectory: /var/lib/registry
http:
addr: :5000
headers:
X-Content-Type-Options: [nosniff]
health:
storagedriver:
enabled: true
interval: 10s
threshold: 3
- 浏览器检查仓库是否搭建成功
页面看到 {“repositories” : []} 表示私有仓库搭建成功并且内容为空
# 浏览器访问(宿主ip:容器映射端口)
http://192.168.0.233:5000/v2/_catalog
# 命令行访问
curl -X GET 192.168.0.233:5000/v2/_catalog
- 修改docker配置文件
daemon.json
前面我们修改过docker的配置文件(设置ustc镜像仓库地址)
现在我们配置私有仓库地址 - 添加如下配置:
vi /etc/docker/daemon.json
"insecure-registries" : ["192.168.0.233:5000"]
七、镜像操作之私有仓库
1、私有仓库 - 镜像上传与下载
命名规则:宿主机ip:私有仓库映射端口/仓库自定文件夹/文件名:版本
- 标记此镜像为私有仓库的镜像
docker tag jdk1.8 192.168.0.233:5000/jdk1.8:v1.0
- 上传标记的镜像到私服
docker push 192.168.0.233:5000/jdk1.8:v1.0
- 下载标记的镜像从私服
docker pull 192.168.0.233:5000/jdk1.8:v1.0
2、私有仓库 - 镜像查询
- 列出私有仓库中所有镜像
# 浏览器访问
http://192.168.0.233:5000/v2/_catalog
# 命令行访问
curl -X GET 192.168.0.233:5000/v2/_catalog
- 列出某个镜像所有tag
# 浏览器访问 <repository>: 镜像名
http://ip:端口/v2/<repository>/tags/list
# 例如
http://192.168.0.233:5000/v2/common/jdk1.8/tags/list
# 命令行
curl -X GET http://192.168.0.233:5000/v2/common/jdk1.8/tags/list
- 列出某个tag的详细信息
# 浏览器访问
# <repository>: 镜像名
# <tag>: tag号
http://ip:端口/v2/<repository>/manifests/<tag>
# 例如
http://192.168.0.233:5000/v2/common/jdk1.8/manifests/v1.0
# 命令行访问
curl -X GET http://192.168.0.233:5000/v2/common/jdk1.8/manifests/v1.0
- 获取某个tag的digest
curl --header "Accept: application/vnd.docker.distribution.manifest.v2+json" -I -XGET <私有库ip>:端口号/v2/<镜像repository>/manifests/<镜像tag>
# 示例如下
curl --header "Accept: application/vnd.docker.distribution.manifest.v2+json" -I -XGET 192.168.0.233:5000/v2/jdk1.8/manifests/v1.0
3、私有仓库 - 镜像删除
- 修改
config.yml
配置文件
私有库默认是不支持删除镜像的,需要修改config.yml
配置文件,在storage
节点下加入delete: enabled: true
,然后重启私有库。
注:config.yml
文件为私有仓库容器创建时,挂载的新建的文件/opt/docker/registry-data/config.yml
- 获取私有仓库中镜像 push 时的 digest:sha256 值
curl --header "Accept: application/vnd.docker.distribution.manifest.v2+json" -I -XGET <私有库ip>:端口号/v2/<镜像repository>/manifests/<镜像tag>
// 示例如下
curl --header "Accept: application/vnd.docker.distribution.manifest.v2+json" -I -XGET 192.168.0.233:5000/v2/test/nginx1.17.9-p80/manifests/v1.0
- 发送 HTTP DELETE 请求
# <repository>: 镜像名
# <reference>: 上一步查到的 digest:sha256 值
http://ip:端口/v2/<repository>/manifests/sha256:<reference>
# 可通过命令执行
curl -I -X DELETE http://ip:端口/v2/<repository>/manifests/<reference>
# 示例如下
curl -I -X DELETE http://192.168.0.233:5000/v2/test/nginx1.17.9-p80/manifests/sha256:39695eb0e4b5841667482d382ce0a5fb481e26dd80a7c30babcf228fc22347d9
- 检查是否删除成功
# 此步查询,依然能看到被删除的镜像,delete删除是逻辑删除
curl -X GET 192.168.0.233:5000/v2/_catalog
# 检查被删除的镜像tag
curl -X GET 192.168.0.233:5000/v2/test/nginx1.17.9-p80/tags/list
- 进入私有仓库容器执行清理命令
前面的删除为逻辑删除,实际还是占用磁盘大小。我们需要刷新整理仓库容器,来完全删除
# 进入私有仓库容器
docker exec -it 容器ID sh
# 进行垃圾回收
registry garbage-collect /etc/docker/registry/config.yml
# 也可以一步到位
docker exec -it <私有库的容器ID或者容器名> sh -c 'registry garbage-collect /etc/docker/registry/config.yml'
4、私有仓库 - 镜像删除 - 脚本删除
具体介绍可查看: [docker-delete] 自定义指令介绍 - swotXu.
- 下载脚本,并配置相关环境
#先下载脚本到/usr/local/bin/目录下
curl https://gitee.com/swotxu/docker-delete/raw/master/docker-delete.sh | sudo tee /usr/local/bin/docker-delete >/dev/null
#赋予可执行权限
chmod a+x /usr/local/bin/docker-delete
#私有库镜像存储目录路径全局环境变量(该路径就是运行私有库容器时,用-v 命令将私有库容器内 /var/lib/registry目录挂载到本机的路径)
#例: /opt/docker/registry/是我运行容器时私有库镜像存储目录挂载到本地的目录
echo "export DOCKER_REGISTRY_DIR=/opt/docker/registry" >>/etc/profile
#运行私有库容器ID全局环境变量设置(正在运行的私有库容器的 ID)
#例: 404d729f6edf是我的私有库库容器的id
echo "export DOCKER_REGISTRY_CONTAINER_ID=404d729f6edf" >>/etc/profile
#使配置生效
source /etc/profile
- 指令使用
# 查询所有镜像
docker-delete -sr
# 查询镜像所有 tag
docker-delete -st test/nginx1.17.9-p80
# 删除镜像指定的tag
docker-delete -dt test/nginx1.17.9-p80 v1.0
# 删除镜像
docker-delete -dr test/nginx1.17.9-p80
八、其他问题处理
1、修改已创建好的容器配置,如端口映射,目录挂载等
- 方法一:删除原容器,重新创建
- 方法二:修改容器配置文件
# 查看容器的 CONTAINER ID
docker ps -a
docker inspect 容器名
# 进入 containers 文件夹下,根据上面查找出的ID,查找文件夹
cd /var/lib/docker/containers/
# 修改容器的配置文件
cat /var/lib/docker/containers/[hash_of_the_container]/hostconfig.json
# 例如:
cat /var/lib/docker/containers/7dad134a4c1f04c4d4d73f32d72b7e2002671db8d37b6f325115c1af71f57a9d/hostconfig.json