Docker可以解决运维与开发环境不一致的问题,可以一次对多台设备进行配置
每个Docker镜像不只有项目还可以复刻开发的所有环境
可以打包装箱,每个箱子都是互相隔离的,并且可以通过这个隔离机制,增加服务器利用率
可以更加快速的交付和部署应用,更便捷的扩展,更加便捷的运维(可以使运维开发测试环境完全一致)Docker是内核级别的虚拟化,可以在一个物理机上运行更多的容器实例
文档地址: https://docs.docker.com/reference/
概述
镜像(image):相当于一个模板,可以通过这个模板来创建容器服务,通过镜像可以创建多个容器,最终项目就是运行在容器之中的
容器(container):独立运行一个或者一组应用,通过镜像创建。容器相当于一个简易版的Linux系统
仓库(repository):存放镜像的地方
与虚拟机的区别
虚拟机虚拟出硬件运行一个完整的操作系统,然后在这个系统上运行和安装软件,资源占用十分多,冗余步骤多,启动很慢。容器内的应用可以直接运行在宿主机的内容,容器没有自己的内核,也不需要虚拟硬件,容器化技术可以充分运用操作系统资源,每个容器之间时互相隔离的,只包含最基础的核心环境
使用
如果是windows 安装需要电脑Bios开启Hyper-v和虚拟化,可以通过任务管理器中查看是否开启
在windows功能中找到Hyper-V并全部选中并重启
之后通过https://hub.docker.com/安装docker
判断安装成功
docker run hello-world
如果无法启动
cd "C:\Program Files\Docker\Docker" ./DockerCli.exe -SwitchDaemon
修改配置"experimental": true
否则可能会出现docker: no matching manifest for windows/amd64 10.0.18363 in the manifest li
的错误
registry-mirrors 添加镜像加速地址
环境查看
需要CentOS 7版本
#查看linux系统内核
uname -r
#查看系统详细版本
cat /etc/os-release
卸载Docker
安装前需要卸载之前的Docker
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
安装
# 需要yum-utils安装包
yum install -y yum-utils
# 设置阿里镜像源
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 清除缓存文件,立刻执行yum源的配置
yum makecache fast
# 安装docker ce为社区版 ee为企业版
yum install docker-ce docker-ce-cli containerd.io
# 显示docker的版本信息,判断是否安装成功
docker version
启动/关闭
# 启动
systemctl start docker
# 关闭
systemctl stop docker
使用
# helloworld
docker run hello-world
# 查看下载的镜像
docker images
# 查看容器的运行状态、内存占用
docker stats
首先会发现本地没有hello-world的镜像
自动远程拉取该镜像
显示Hello from Docker! 说明运行成功
卸载
# 卸载依赖
yum remove docker-ce docker-ce-cli containerd.io
# 删除资源
rm -rf /var/lib/docker
镜像加速
在阿里云控制台中找到镜像加速器,选择CentOS操作系统,命令依次执行
每个账号registry-mirrors唯一
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json << EOF
{
"registry-mirrors": ["https://ozxcczcb.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
帮助
# 帮助 --help
docker -h
# 查看docker某一命令的详细使用
docker [命令] --help
镜像命令
镜像是一种轻量级、可执行的软件包,用来打包运行环境和记忆运行环境开发的软件,它包含某个软件所需要的所有内容,包括代码、库、环境变量和配置文件
搜索
# 搜索镜像
docker search [镜像名]
# 过滤 --filter
docker search [镜像名] -f=[条件]
NAME 镜像名
DESCRIPTION 镜像的描述
OFFICIAL 是否官方发布
STARS 用户收藏数
AUTOMATED 自动构建
效果为查询Mysql并筛选用户收藏数大于3000的版本
docker search mysql -f='stars=3000'
下载
下载的镜像默认是最小镜像,会剔除掉不必要的文件(如tomcat的helloworld界面)
# 下载镜像,默认下载最新版本
docker pull [镜像名]
# 下载指定版本
docker pull [镜像名]:[指定版本号]
如果不指定tag则默认是latest
docker使用的是分层下载 联合文件系统 不同的版本可能共用部分内容,极大的减少了存储空间的开支
Digest是签名信息
docker io是下载的真实地址
docker pull mysql效果等价与docker pull docker.io/library/mysql:latest
联合文件系统是一种分类、轻量级、高效的文件系统,它支持对文件系统的修改作为一次提交来层层叠加,同时可以将不同目录挂载到同一个虚拟文件下。镜像可以通过分层来进行继承,基于基础镜像可以制作各种应用镜像
查看
# 查看所有镜像
docker images
# 查看所有镜像,包括中间映像层 --all
docker images -a
# 只显示镜像的id --quiet
docker images -q
REPOSITORY 镜像的仓库源
TAG 镜像的版本
IMAGE ID 镜像的ID
CREATED 镜像创建的时间
SIZE 镜像的大小
删除
# 删除指定镜像id的镜像,多个镜像id用空格隔开 --force
docker rmi -f [镜像Id]
# 使用$()传入多个参数
docker rmi -f $([docker命令])
# 删除所有无名<none>镜像
docker rmi $(docker images -f "dangling=true" -q)
删除所有镜像 将docker iamges -aq 返回的image id传入docker rmi -f,起到删除全部的效果
标记
为镜像打上标记
docker tag [镜像Id] [指定REPOSITORY]:[指定TAG]
提交
Docker镜像都是只读的,当容器启动时一个新的可写层被加载到了顶部,这一层就是容器层,容器之下的都是镜像层
# 提交修改过的镜像 --author --message
docker commit -a [名称] -m [注释] [容器id] [REPOSITORY]:[TAG]
将容器变成一个新的镜像
容器命令
创建
# 创建一个容器前需要有这个容器的镜像
docker pull centos
# 新建容器并启动,如果没有该镜像将自动下载
# 可以看到linux的主机名称改变了
docker run [参数] [镜像id/仓库名] /bin/bash
--name [名称] 为这个容器添加名称
-h [名称] 指定容器的主机名
-d 后台方式进行运行,如果没有前台进程则会立刻停止
-it 进入容器
--rm 容器停止后立刻删除(一般用于测试)
-p [映射到容器外的端口]:[容器内端口] 指定容器暴露的端口
-P 随机映射端口
-e [参数=""] 传递环境变量(如jvm内存mysql密码,可以通过dockerhub查看文档)
-dit 设置守护进程
--link [容器名称]:[给这个容器起的别名] 与该容器建立连接
--restart=[重启策略] 设置重启策略 always在容器退出时总是重启容器
--privileged 赋予内部的root账户为真正的root权限
查看
# 查看正在运行的容器
docker ps
docker container ls
# 查看曾经运行过和正在运行的容器 --all
docker ps -a
# 显示最近创建的前n个的容器 --last
docker ps -n [数字]
# 只显示容器的编号 --quiet
docker ps -q
docker ps -n=3与 docker ps 3效果相同
退出
处于容器之中的时候
# 容器停止并退出
exit
# 容器不停止退出
[Ctrl + p + q]
删除
一般需要先stop后删除
# 删除指定容器,无法删除正在运行中的容器
docker rm [容器id]
# 强制删除,可以删除正在运行中的容器 --force
docker rm -f [容器id]
删除所有容器
启停
# 启动容器
docker start [容器id]
# 重启容器
docker restart [容器id]
# 停止容器
docker stop [容器id]
# 关闭容器
docker kill [容器id]
日志
# 持续跟踪日志 --follow
docker logs -f [容器id]
# 增加时间戳 --timestamps
docker logs -t [容器id]
# 显示前n条日志(默认显示所有)
docker logs --tail [数量] [容器id]
进程信息
# 查看容器中的进程的信息
docker top [容器id]
元数据
# 查看镜像的元数据
docker inspect [镜像id]
进入容器
# 进入容器(后台方式运行中的)
# 并且开启一个新的终端
docker exec -it [容器id] /bin/bash
ps -ef查看所有进程
# 进入容器(后台方式运行中的)
# 进入正在执行的终端
docker attach [容器id]
# 如无法退出attach,另开终端使用以下方式退出
pkill -9 -f 'docker.*attach'
拷贝
# 容器复制到宿主机
docker cp [容器id]:[容器内路径] [目的主机路径]
# 宿主机到容器
docker cp [主机路径] [容器id]:[容器内路径]
即使exit退出容器,容器不存在,内的文件依然存在
将容器id为12a78ad9fa3b内目录/home/test.java 拷贝到/home
系统命令
# 清理磁盘,删除关闭的容器、无用的数据卷和网络,以及无tag镜像
docker system prune
# 提供Docker整体磁盘使用率
docker system df
# 显示docker的详细信息
docker info
# docker系统实时事件
docker system events
网络
# 列出所有网络
docker network ls
# 允许相同network的容器互联
docker run -it --rm --network my-net [镜像id] sh
# 操作系统可能需要配置允许ip转发
sysctl net.ipv4.conf.all.forwarding=1
命令一览
attach # 当前shell下attach连接指定运行镜像
buid # 通过Dockerfile定制镜像
commit # 提交当前容器为新的镜像
cp # 从容器中拷贝指定文件或者目录到宿主机中
create # 创建一个新的容器,同run,但不启动容器
diff # 查看docker容器变化
events # 从docker服务获取容器实时事件
exec # 在已存在的容器上运行命令
export # 导出容器的内容流作为一个tar归档文件[对应import]
history # 展示一个镜像形成历史
images # 列出系统当前镜像
import # 从tar包中的内容创建一个新的文件系统映像[对应export]
info # 显示系统相关信息
inspect # 查看容器详细信息
Kill # 关闭指定 docker容器
load # 从一个tar包中加载一个镜像[对应save]
login # 注册或者登陆一个docker源服务器
logout # 从当前Docker registry 退出
logs # 输出当前容器日志信息
port # 查看映射端口对应的容器内部源端
pause # 暂停容器
ps # 列出容器列表
pull # 从docker镜像源服务器拉取指定镜像或者库镜像
push # 推送指定镜像或者库镜像至docker源服务器
restart # 重启运行的容器
rm # 移除一个或者多个容器
rmi # 移除一个或多个镜像
run # 创建一个新的容器并运行一个命令
save # 保存一个镜像为tar包[对应load]
search # 在docker hub 中搜索镜像
start # 启动容器
stop # 停止容器
tag # 给源中镜像打标签
top # 查看容器中运行的进程信息
unpause # 取消暂停容器
version # 查看docker版本
wait # 截取容器停止时的退出状态值
容器数据卷
数据安全,容器的持久化和同步操作
保护重要数据不会因为容器删除而丢失
一些配置文件可能需要先将容器启动起来以后通过docker cp或者dockerfile复制出来后再挂载
否则本机路径下没有对应文件可能导致容器无法启动
# 本地目录与容器内目录内的文件会互相同步 --volume
# 可以配置多个
docker run -it -v [本地目录]:[容器内目录] [镜像id/仓库名]
docker inspect [容器id] 中的Mounts
source主机内的地址
destination 为容器内地址
设置权限
# readonly 只读
docker run -it -v [本地目录]:[容器内目录]:ro [镜像Id/仓库名]
# readwrite 可读可写
docker run -it -v [本地目录]:[容器内目录]:rw [镜像Id/仓库名]
匿名挂载
只指定容器内的路径就是匿名挂载
# 一般不建议匿名挂载
docker run -it -v [本地目录] [镜像Id/仓库名]
具名挂载
# 并且指定名称的就是具名挂载
docker run -it -v [指定名称]:[本地目录] [镜像Id/仓库名]
查看挂载的所有数据卷
# 查看所有数据卷
docker volume ls
# 其中Mountpoint就是挂载的真实地址
docker volume inspect [具名挂载的名称]
# 查看指定容器的挂载情况
docker inspect [容器名/id] | grep Mounts -A 20
可视化
docker图形化管理界面
# 安装portainer
docker run -d -p 3344:9000 \
--restart=always -v /var/run/docker.sock:/var/run/docker.sock \
--privileged=true portainer/portainer
Dockerfile
通过脚本生成镜像
创建一个dockerfile文件
建议命名为Dockerfile,这样build命令就无须-f指定dockerfile
指令需要全部大写,每个指令都会创建并提交一个新的镜像层(最后运行的时候最外层嵌套一层可写容器层)
定义变量除了可以使用ENV也可以使用ARG
不过ARG仅在构建Docker映像期间(RUN等)可用
使用dockerfile
# 构建 --file --tag
# .号的含义为构建上下文
docker build -f [dockerfile目录] -t [镜像名]:[TAG] .
DockerFile:构建文件,定义了生成镜像的一切步骤
Docker镜像:通过DockerFile构建生成镜像并最终发布
Docker容器:通过镜像运行起来提供服务
ENTRYPOINT 与 CMD的区别
使用ENTRYPOINT只有最后一个ENTRYPOINT 会执行,run时可以追加参数
FROM centos
# docker run [容器Id] -l时执行 ls -al
# docker run [容器Id] pwd执行多个命令会导致无法正常运行
ENTRYPOINT ["ls","-a"]
使用CMD只有最后一个CMD会执行,run时无法追加参数
FROM centos
# docker run [容器Id] -l时报错,无法追加参数
# docker run [容器Id] ls -al才能正常执行
# docker run [容器Id] pwd 只能执行pwd命令
CMD ["ls","-a"]
指令
FROM 基础镜像
MAINTAINER 镜像作者的姓名联系方式(姓名+邮箱)
RUN 镜像构建的时候需要运行的命令
ADD 往基础镜像中添加内容(自动解压)
WORKDIR 镜像的工作目录
VOLUME 挂载的目录
EXPOSE 暴露的端口
CMD 容器运行时会运行的命令(只有最后一个会生效)
ENTRYPOINT 容器运行时会运行的命令(可以追加命令)
ONBUILD 当构建一个被继承Dockerfile时会运行ONBUILD指令
COPY 将文件拷贝到镜像之中
ENV 构建时设置的环境变量
构建过程
# 查看本地镜像的构建历史
docker history [镜像名/镜像Id]:[版本号]
容器服务
登录
首先需要DockerHub账户
# 登录 --username
docker login -u [用户名]
$ Password: [密码]
# 之后可以无需用户名密码登录
docker login
# 退出登录
docker logout
提交镜像
提交至DockerHub
# 可以先用docker tag改变名称后提交
docker push [REPOSITORY]:[TAG]
# 拉取镜像
docker pull [REPOSITORY]:[TAG]
使用阿里云镜像服务
容器镜像服务 -> 默认实例 ->命名空间->创建命名空间
默认实例->镜像仓库->创建镜像仓库 选择命名空间 本地仓库
可以在 默认实例->访问凭证 中修改密码
# 登录阿里云Docker Registry
docker login -u=[用户名] registry.cn-shanghai.aliyuncs.com
$ Password: [密码]
# 推送镜像
docker tag [镜像Id] registry.cn-shanghai.aliyuncs.com/[命名空间]/[REPOSITORY]:[TAG]
docker push registry.cn-shanghai.aliyuncs.com/[命名空间]/[REPOSITORY]:[TAG]
归档
一般不使用归档而是直接通过push命令推送到云端容器
# 归档
docker save [本地地址] [镜像名/镜像Id]
# 导出
docker load [本地地址] -i [指定导入的镜像]
compose
docker-compose安装需要pip(pip的使用需要python)
yum -y install epel-release
yum -y install python-pip
pip install --upgrade pip
# 是否安装成功
pip --version
安装docker-compose
# 注意python和pip版本
pip install -U docker-compose
使用docker-compose
# 到指定目录下使用该命令
docker compose up -d
# 多项目隔离
# 启动
COMPOSE_PROJECT_NAME=zk_test docker compose up
# 查看状态
COMPOSE_PROJECT_NAME=zk_test docker compose ps
属性
privileged=true 使容器拥有真正的root拥有真正的root权限
depends_on 与指定容器互连
volumes 容器数据卷
日志
docker compose logs [service名称]
语法
services:
db:
image: mysql:8.0.18 # 镜像
restart: on-failure:3 # 重启策略
command: # 覆盖默认的容器启动命令
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_general_ci
volumes: # 卷挂载
- ./mysql:/var/lib/mysql
- ./mysqlBackup:/data/mysqlBackup
ports: # 端口映射
- "3306:3306"
healthcheck: # 健康检查
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "--silent"]
interval: 3s
retries: 5
start_period: 30s
environment: # 环境变量
- MYSQL_DATABASE=test
- MYSQL_ROOT_PASSWORD=123456