docker入门命令——image、container、network、dockerfile、docker-compose、docker swarm、docker stack

发布时间 2023-05-29 20:06:19作者: leethon

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为单位运行命令,主要是启动集群、查看集群的状态或者停止集群服务