docker入门命令——image、container、network、dockerfile、docker-compose、docker swarm、docker stack
docker
docker version
docker info
docker --help
镜像操作image
docker images # 本地仓库镜像信息
结果解释:
REPOSITORY(镜像名称) TAG(标签|版本) IMAGE ID(镜像id) CREATED(创建时间) SIZE(大小)
flask-dev1-web_api latest 472cfb286905 19 hours ago 1.06GB
redis 6.0.9-alpine c678242f9116 2 years ago 31.6MB
参数:
-a 可以展示所有创建的镜像(包括一些中介镜像)
-q 只展示镜像的id值
docker pull 镜像地址|镜像名 # 从远程仓库拉取镜像,如果是官方仓库镜像,可以使用镜像名:标签拉取
docker search 镜像名 # 搜索,不怎么用,建议直接去仓库网站去搜索
docker rmi 镜像id|镜像名 【镜像2,3,4……】 # 删除本地对应的镜像(镜像不被引用情况下正常删除)
参数:
-f # 强制删除
docker rmi -f `docker images redis` # 批量删除redis的镜像
# 镜像打包和解包(便于本地镜像的传递,不用走仓库)
docker save 镜像名:tag -o 路径/tar包名 #(建议包含镜像名和tag信息)
docker load -i tar包
容器操作container
docker ps # 查看运行中的容器
结果解释:
CONTAINER ID # (容器id)
IMAGE #(基于的镜像)
COMMAND #(启动容器时内部执行的命令)
CREATED #(创建时间)
STATUS #(运行状态:运行了多少时间|什么时候退出的|暂停了|)
PORTS #(端口映射)
NAMES #(容器名)
参数:
-a 展示所有的容器(包括不在运行态的)
-q 只展示id号
-f 根据过滤条件展示,形式为-f name=关键字
-l 最近一次创建的容器
-n int 最近n次创建的容器
-s 展示size
docker run 【-选项】 镜像名:tag|镜像id # 通过镜像运行容器
参数:
-d 守护进程式
--name 给容器制定一个容器名称(名字必须唯一)
-v 挂载目录 宿主目录:容器目录 # 可挂载多个
-p 映射端口 宿主端口:容器端口 # 可映射多个
# 容器启停操作
docker start 容器id|容器名 # 启动容器,run之后自动会start
docker stop 容器id|容器名 # 停止容器
docker rm 容器id|容器名 # 删除容器(-f强制删除,可以删除运行中的容器)
docker restart 容器id|容器名 # 重启容器
docker pause 容器id|容器名 # 暂停容器
docker unpause 容器id|容器名 # 恢复容器
docker kill id|name # 关闭容器(内部直接终止,而stop停止是容器内部正常停止)
# 容器日志
docker logs 【-options】 id|name # 查看容器内部的日志输出
参数:
-f 实时监控容器中的日志
-t 加上时间戳
# 执行容器内的命令
docker exec -it id|name bin/bash # 以交互的形式执行了容器内的bash窗口
docker attach id|name # 相当于上面这句
exit # 退出容器|其实是退出bash
# 容器与宿主间的文件拷贝
容器--》宿主
docker cp 容器名|id:容器目录、文件 宿主目录、文件
宿主--》容器
docker cp 宿主目录、文件 容器名|id:容器目录、文件
# 查看容器内运行进程
docker top 容器id|name
# 查看容器内详细信息
docker inspect 容器id|name # 详细信息足够详细,很多
可以关注:
- Workdir 工作目录
- Volumes 挂载的数据卷
- Gateway 网关
- ...(键是大写打头,所以grep筛选时注意)
# 容器数据卷机制
作用:主机与容器的数据同步的更新,挂载,对于重要数据,一定要挂载到宿主机中管理,交给容器管理则很危险。
使用:只有在容器 "首次" 启动即创建容器时才能设置,也就是在run命令时通过-v时可以设置(有其他的方式创建容器,如docker-compose)
特性:
- 在做挂载数据卷时,选择的容器内的路径如果有则会清空并与宿主的文件保持一致,如果没有相应路径,则会创建相应的路径。
- 可以选择ro(read only)使容器内的挂载目录不能更改,只能随着宿主变化
- 选择的宿主机路径不存在,则会在宿主机中自动创建,绝对路径正常创建,相对路径如果是不带分割的(别名)会在.../docker/voluemes/中被创建维护,这些被维护的volumes可以被docker的一些指令管理
- docker volume ls
- docker inspect 数据卷别名
- docker volume rm 数据卷别名
- docker volume create 数据卷别名
# 容器打包成镜像
docker commit [-options] 容器id|name 镜像名:tag
参数:
-m "描述信息" # 可选
-a "作者信息" # 可选,但一般发布的版本都是要写的
容器网络通信
- 所有容器默认都会连接到宿主机的docker0网桥上,默认连在docker0的容器都可以通过容器ip互相通信
- 容器ip可能发生变化,所以一般会通过容器名作为hostname去作为容器ip使用。
问题:多个服务集群启动的容器可能有名称冲突,都连docker0会冲突,承载量也有限
- docker网络类型
- bridge
- host
- null
# 创建自定义网桥
docker network create -d bridge 网络名称
-d # 指定网络驱动类型,默认为网桥
# 查看网络
docker network ls # 查看所有网络
docker network inspect 网络id|name # 查看单个网络的细节
# 删除网络(不被使用的网络才能被删除)
docker network rm 网络id|name # 指定删除
docker network prune # 删除从未被用到的网络
# 运行容器在指定的网络下
- 默认会运行在docker0,指定的话run后加--network 网络名
- 启动的容器可以加入到网络中
docker network connect 网络名 容器id|name
## docker inspect
先找容器id|name---》再找网络id|容器name----》最后找数据卷id|name
其实都有完整的指令:
docker container inspect
docker network inspect
docker volume inspect
Dockerfile
# 镜像的描述文件,通过这个Dockerfile可以构建镜像(build)
docker build -t 镜像名:tag context/Dockerfilem名 # 可以只写context路径,默认以该路径下命名为Dockerfile的文件构建镜像
# 如:docker build -t my-image:tag1 . 这里的 . 表明当前文件夹下的Dockerfile
# 注意:
- context下的所有文件都会被打包发送给docker server
- 可以通过.dockerignore文件来制定哪些文件不被发送
- 讲义将dockerfile相关的文件存放在一个文件夹
Dockerfile命令
FROM 镜像:标签tag # 从哪里构建镜像,默认从官方仓库拿镜像,也可以直接写镜像地址
USER 用户名 # 创建者
WORKDIR 工作目录 # 工作目录,如果没有指定目录则自动创建,指定这个后,后续的RUN命令所运行的环境也就在这个工作目录
COPY 宿主路径 容器路径 # 将宿主机指定文件复制到容器的指定位置
ADD 宿主路径 容器路径 # 与copy指令基本一致,自带解压,也可以从url复制内容,功能更丰富
RUN shell命令 # 构建镜像时会执行的命令,且产生中间分层镜像(用于节省重复构建时间的)
CMD 命令(可以是["cat","1.txt"]形式)# 启动容器时会执行的命令,可以被run指令后跟随的指令覆盖
ENTRYPOINT 命令 # 优先级高于CMD,如果直接写命令,则忽略cmd,如果写数组形式,则拼接cmd
# 配合使用用法:ENTRYPOINT写命令,CMD写参数,run可以覆盖参数部分的指令
EXPOSE 端口 # 暴露端口(不暴露问题也不大,主要是提醒构建镜像后启动的容器要做哪些端口映射)
VOLUEME 容器目录 # 映射目录(声明,但是实际启动容器还是要挂载)
ENV A=10 # 环境变量,容器中一直存在
ARG B=11 # 构建参数,只有在构建时才能当变量使用,构建完成后就消失了
LABEL k1="v1" # 建立标识?
ONBUILD ENV C=100 # 如果有另外一个镜像基于本镜像构建,则会执行该指令
STOPSIGNAL
HEALTHCHECK
SHELL
$变量名 # 对变量值进行引用(如环境变量中的A,$A就可以引用了)ß
docker-compose.yml
三大组成部分:
version:
docker-compose 文件版本,可在https://docs.docker.com/compose/compose-file/compose-versioning/ 查看docker-compose文件版本支持特定的 Docker 版本
services:
最重要的组成部分,书写了有哪些服务,服务以什么形式组织起来,容器服务的各项属性如构建镜像、挂载目录、映射端口等等,与docker run命令的选项有对应。
networks:
定义网络,决定了这个服务集群在哪个网络上部署
compose-demo.yml
version: '3' # yml的k: v键值对的v需要再:后空一格或者换行,可以用#来注释
services:
web_api: # 服务名,其下都是web_api服务的配置
build: # 使用dockerfile构建
context: . # Dockerfile上下文,也是其目录
dockerfile: Dockerfile # 基于的Dockerfile全称
args: # 构建时应用的参数
- NAME: lee
volumes:
- .:/tmp # 宿主相对路径基于的是yml文件的目录
- /home/web_api/:tmp/ # 容器内的相对路径是基于工作路径
depends_on:
- service2 # 此服务依赖service2,也就是让service2优先启动
restart: always # 是否随docker服务启动重启
environment:
# - TZ=Asia/Shanghai # 为容器提供环境变量,容器内一直存在
MYSQL_HOST: ${MYSQL_HOST} # 也可以按照这种形式写键值对,但是不能同时使用
workdir: /home/web_api # 工作目录
command: python3 app.py
mysql:
hostname: ${MYSQL_HOST} # ip的host,因为多次用到host,所以将其配置在.env的文件中,可以${}调用
image: mysql:5.7 # 使用镜像
command: [ # command会覆盖容器默认的指令
'--character-set-server=utf8mb4', #设置数据库表的数据集
'--collation-server=utf8mb4_unicode_ci', #设置数据库表的数据集
'--default-time-zone=+8:00' #设置mysql数据库的时区问题
]
privileged: true # 让root用户真的有root权限
restart: always
networks: ... # 这个可以自己配置,但是默认yml编排,会自动创建一个网络,让所有容器挂载上此网络
compose相关指令
docker-compose up # 启动当前文件夹下的docker-compose.yml文件
参数:
-f /data/docker/docker-compose.yml # 指定yml文件
-d # 后台运行
docker-compose down # 停止当前环境下的组件
docker-compose config # 查看当前环境实际的编排配置(可以将一些.env填充到yml中,显示一些没写的默认配置)
docker swarm
多机编排docker集群
Swarm:
docker集群需要swarm管理,可以在当前机器初始化启动swarm,也可以加入其他的swarm
Node:
一个节点是docker引擎集群的一个实例。您还可以将其视为Docker节点。
一个机器上可以有多个节点,但一般来说一个生产集群的多个节点是分布在很多机器上的。·
Manager节点:执行集群的管理功能,维护集群的状态。会选举一个leader节点去执行调度的任务
Worker节点:接收和执行任务,仅用于承载task。
Service:
一个服务是任务的定义,在节点上执行,创建服务时,需要指定使用的容器镜像。
Task:
任务实在docker容器中执行的命令,Manager节点根据指定数量的任务副本分配任务给worker节点
# 集群管理
docker swarm init|join|leave|update.. # 初始化最初节点|作为节点加入|离开集群|刷新一下
# 节点管理
docker node accept|promote|demote|inspect|update|tasks|ls|rm
# 服务管理
docker service create|inspect|update|remove|tasks|ls
用docker swarm及相关的node、service指令去管理集群有一个缺点,就是手动操作比较多,我们通过compose组件管理多个容器时,就是想快速的把多个容器服务启动起来并加以配合,我们当然也希望将多机的服务集群也能快速的启动起来。
docker stack
docker stack结合了docker compose快速构建完整服务和docker swarm可多机编排的特性,可以快速的在多台机器上部署服务,而docker stack的编排依赖yaml文件。而它所支持的关键字会有所区别。
需要注意的是,docker stack不支持build关键字,不能通过Dockerfile去构建镜像和容器,必须去拉取构建好的镜像。
在这里补充一个deploy关键字,在使用了swarm后,swarm会有其调度策略,我们使用时只需要关注我们要启动几个服务(replicas)
docker stack相关指令:
docker stack deploy [OPTIONS] STACK
# 根据 Stack 文件(通常是 docker-compose.yml)部署和更新 Stack 服务的命令,常用选项如下:
-c:指定compose文件路径
–with-registry-auth:服务创建的时候,各个工作节点同步管理节点的私有仓库登录凭证,从而各个节点可用拉取私有仓库镜像
# stack启动后,我们就可以以集群服务为单位管理应用了,而关于其中有什么服务,建议使用yml文件统一编排好。
docker stack ls [OPTIONS]
# 列出 Swarm 集群中的全部 Stack,包括每个 Stack 拥有多少服务。
docker stack ps [OPTIONS] STACK
# 列出某个已经部署的 Stack 相关详情。该命令支持 Stack 名称作为其主要参数。
# 在服务启动失败时,docker stack ps 命令是首选的问题定位方式。该命令展示了 Stack 中每个服务的概况,包括服务副本所在节点、当前状态、期望状态以及异常信息,再配合 docker service logs 查看某个具体服务或任务的详细信息。
docker stack services [OPTIONS] STACK
# 列出某个已经部署的 Stack 的服务,包括服务的模式,使用的镜像,端口映射等。
docker stack rm [OPTIONS] STACK [STACK…]
# 从 Swarm 集群中移除 一个或多个 Stack。移除操作执行前并不会进行二次确认。
stack总结,以yaml文件为多机编排的蓝本,不要通过命令的方式去操作集群中的某些服务。一旦stack启动起来,我们就以stack为单位运行命令,主要是启动集群、查看集群的状态或者停止集群服务