[Docker] Docker 基础教程(概念/原理/基础操作)
1 概述
1.1 定义
Docker is a platform that allows you to "build ,ship ,and run any app, anywhere. "
- Docker是一个平台,它提供哪些服务呢?任何一台装有Docker的机器上你都可以
构建
、发布
、运行
你的应用程序。
It has come a long way in an incredibly short time and is now considered a standard way of solving one of the costliest aspects of software: deployment.
- Docker在很短的时间内就走得很远,如今它基本是解决软件最昂贵的环节:部署的标准解决方案。
在Docker出现之前,有一堆与软件部署的工具软件,虚拟机、配置管理工具、打包管理工具、复杂的webs库依赖。所有这些工具都需要专业的工程师去管理和维护,多数软件有一套独特的配置方法。
小结:
-
Docker
是一个开源的引擎,可以轻松的为任何应用创建一个轻量级的、可移植的、自给自足的容器。
开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何支持 docker 的机器上运行。
容器是完全使用沙箱机制,相互之间不会有任何接口调用。 -
Docker
使用Google公司推出的Go
语言进行开发实现,基于Linux内核的cgroup
,namespace
,以及AUFS
类的UnionFS
等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术。
由于隔离的进程独立于
宿主机(真实机器)
和其它的隔离的进程,因此也称其为容器
。Docker最初实现是基于LXC
。
1.2 使用Docker来干什么?
比较一下Docker诞生前和诞生后软件开发的变化就能感受到Docker可以用来干嘛了。
Docker诞生标志着软件工程领域进入新纪元
1.3 为什么要使用Docker?
1.4 优缺点
1.4.1 优点
1)快
运行时的性能快,管理操作(启动,停止,开始,重启等等) 都是以秒或毫秒为单位的。
2)敏捷
像虚拟机一样敏捷,而且会更便宜,在 bare metal(裸机)上布署像点个按钮一样简单。
3)灵活
将应用和系统“容器化”,不添加额外的操作系统
4)轻量
在一台服务器上可以布署 100~1000 个 Containers 容器。
5)便宜
开源的,免费的,低成本的。
1.4.2 缺点
所有容器共用 linux kernel 资源,资源能否实现最大限度利用,所以在安全上也会存在漏洞。
1.5 版本
目前最近的2个版本
- docker-ce
docker-ce-18.06.3.ce-3.el7
- docker-ee
1.6 Docker 应用场景
-
Web 应用的自动化打包和发布。
-
自动化测试和持续集成、发布。
-
在服务型环境中部署和调整数据库或其他的后台应用。
-
从头编译或者扩展现有的 OpenShift 或 Cloud Foundry 平台来搭建自己的 PaaS 环境。
2 Docker的原理与概念
2.0 Docker的架构与模式
2.0.1 体系结构
- VM是在宿主机器操作系统的基础上创建虚拟化的操作系统,需要重新加载一个Guest OS。
- Docker是在宿主操作系统上运行Docker引擎,在引擎的基础上再安装应用。
- Docker是共享宿主机的内核,有着比VM更少的抽象层。
2.0.2 部署架构/运行架构
概念 | 说明 |
---|---|
Docker 镜像(Images) | Docker 镜像是用于创建 Docker 容器的模板,比如 Ubuntu 系统。 |
Docker 容器(Container) | 容器是独立运行的一个或一组应用,是镜像运行时的实体。 |
Docker 客户端(Client) | Docker 客户端通过命令行或者其他工具使用 Docker SDK (https://docs.docker.com/develop/sdk/) 与 Docker 的守护进程通信。 |
Docker 主机(Host) | 一个物理或者虚拟的机器用于执行 Docker 守护进程和容器。 |
Docker Registry | Docker 仓库用来保存镜像,可以理解为代码控制中的代码仓库。Docker Hub(https://hub.docker.com) 提供了庞大的镜像集合供使用。一个 Docker Registry 中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。 |
Docker Machine | Docker Machine是一个简化Docker安装的命令行工具,通过一个简单的命令行即可在相应的平台上安装Docker,比如VirtualBox、 Digital Ocean、Microsoft Azure。 |
- Docker 使用了
client
/server
的架构模式,如下图所示 - Docker daemon 是后台总管,对外提供了REST API,当收到 Docker Client 发送的请求时,执行诸如镜像、容器、网络、存储等一系列操作
2.1 镜像(Image) ≈ 容器的静态模板
Docker的
image
可以理解是一个只读的静态模板
,类似于我们在装系统的时候用到的.iso
文件
操作系统分为内核
和用户空间
。
对于Linux而言,内核启动后,会挂载root文件系统为其提供用户空间支持。
而Docker镜像
(Image
),就相当于是一个root文件系统。
现在重新理解一下我们使用一个linux系统的过程:
我们开机时,linux内核会先启动;然后,挂载root文件系统作为用户空间;
而Docker镜像就相当于是一个root文件系统,每开一个就有了一个独立的用户空间。
2.2 容器(Container) ≈ 镜像的动态实例
container
则相对而言是一个动态的instance
。
或说可以理解为我们装好了系统之后的某一台计算机,可以开机,关机,重启等等,也可以被格式化(删除)
如果我们想在另一台计算机上复现我这台计算机的系统,则可以ghost一个新的镜像,然后去安装(虽然这种操作通常不行,因为底层硬件的驱动可能不匹配)。
2.2.1 镜像(Image)与容器(Container)的关系
镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的类,容器是镜像运行时的实体。
容器可以被创建、启动、停止、删除、暂停等 。
容器的实质是进程
,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间。
前面讲过镜像使用的是分层存储,容器也是如此。
按照Docker最佳实践的要求,
容器
不应该向其存储层
内写入任何数据 ,容器存储层
要保持无状态化。
所有的文件写入操作,都应该使用数据卷
(Volume)、或者绑定宿主目录
,在这些位置的读写会跳过容器存储层
,直接对宿主
(或网络存储
)发生读写,其性能和稳定性更高。
所谓“绑定宿主目录”,就是在run一个container的时候使用-v命令把宿主机的存储目录映射进container。
我们可以这样理解:
image是分层存储的,我们每做一次修改就会在原本的Image存储层上多搭一层,记录这个更改;而新搭的这层是静态、且可以持久化存储的。
Container也是相同额存储架构,但是每次修改新搭的一层是动态的,而且并不是持久化存储的;
当容器被remove,或者重启计算机(内存断电)之后,container没了,相应的这些容器存储层也没了。
因此,要尽量保持容器存储层无状态化,所有的contain里产生的数据(比如container里的程序的运行结果)都要通过挂载宿主目录直接写进宿主硬盘里。
2.3 仓库(Repository) ≈ 模板仓库
2.3.1 Docker Hub 和 Docker Registry
-
Docker Hub 是一个公共的镜像注册中心,开发者可以在其中找到大量官方和社区维护的 Docker 镜像。同时,您也可以在 Docker Hub 上创建自己的账户,并上传自己构建的镜像供他人使用。
-
Docker Registry 则是 Docker 镜像的私有仓库,它允许您在自己的服务器上存储和管理镜像。企业和组织通常使用 Docker Registry 来保护和控制访问其内部构建的镜像。
最常使用的
Registry
公开服务是官方的Docker Hub
,这也是默认的Registry
,并拥有大量的高质量的官方镜像
2.3.2 Docker Registry
我们可以把
构建好后的镜像
(Image
)上传到服务器,从而可以在任何地方使用到这个镜像。
- 一个
Docker Registry
中可以包含多个仓库
(Repository
) - 每个
仓库
可以包含多个标签
(Tag
) - 每个
标签
对应一个镜像
(Image
)
通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本 。
我们可以通过<仓库名>:<标签>
的格式来指定具体是这个软件哪个版本的镜像
。
如果不给出标签
,将以latest
作为默认标签
。
2.4 Docker Container 生命周期
Docker 容器的生命周期包括以下几个关键阶段:
- 创建(Create):基于镜像创建一个新的容器实例。
- 启动(Start):启动已创建的容器,使其处于运行状态。
- 运行(Run):在容器中运行应用程序,处理请求等。
- 停止(Stop):停止正在运行的容器,但并不会删除它。
- 删除(Delete):从主机系统中删除已停止的容器实例。
- 监控(Monitor):监控容器的运行状态和资源使用情况。
3 docker的基本用法
3.0 docker服务管理
3.0.1 查看安装信息(CENTOS7)
whereis docker
which docker
3.0.2 版本信息
docker version
3.0.3 服务启停(CENTOS7)
systemctl start docker
systemctl status docker
3.0.4 开启自启(CENTOS7)
systemctl enable docker
3.1 镜像操作
创建镜像
- 创建镜像
Docker build 是一个 Docker 命令,用于构建 Docker 镜像
docker build [OPTIONS] PATH | URL | -
-f,--file
指定Dockerfile文件的路径。不指定时,默认会读取上下文路径下的 dockerfile-t,--tag
指定构建的镜像名和 tag。例如,构建的镜像指定多个 tag:docker build -t shykes/myapp:1.0.2 -t shykes/myapp:latest .
--add-host
可以使用一个或多个--add-host
标志将其他主机添加到容器的/etc/hosts
文件中。如:docker build --add-host=docker:10.180.0.1 .
--no-cache
构建镜像时不使用缓存--network
在构建过程中为 RUN 指令设置网络模式
更多参数可以看官方文档: https://docs.docker.com/engine/reference/commandline/build/
[case 1] 使用当前目录的 Dockerfile 创建镜像,标签为 runoob/ubuntu:v1
format:docker build -t <image_name>[:<tag, defaultValue=latest>] .
docker build -t runoob/ubuntu:v1 .
[case 2] 使用URL github.com/creack/docker-firefox 的 Dockerfile 创建镜像
docker build github.com/creack/docker-firefox
[case 3] 可以通过 -f Dockerfile 文件的位置:
$ docker build -f /path/to/a/Dockerfile .
[case 4] 在 Docker 守护进程执行
Dockerfile
中的指令前,首先会对 Dockerfile 进行语法检查,有语法错误时会返回:
$ docker build -t test/myapp .
Sending build context to Docker daemon 2.048 kB
Error response from daemon: Unknown instruction: RUNCMD
从 dockerhub 查找镜像
- 方法1:基于 dockerhub 官网 或 github dockerhub 官方镜像库 【推荐】
这样能搜索支持的具体版本有哪些、使用文档、注意事项等 (以 mysql 镜像为例)
https://hub-stage.docker.com/_/mysql
https://github.com/docker-library/mysql/blob/3288a66368f16deb6f2768ce373ab36f92553cfa/5.7/Dockerfile
- 方法2: search 命令行方式:
docker search [options] {某个镜像的名称}
- 查找对应DockerHub仓库中的镜像
--filter=stars=50
: 列出收藏数不小于指定值的镜像
docker search tomcat
...
docker search centos
解释说明:
NAME
: 镜像仓库源的名称DESCRIPTION
: 镜像的描述OFFICIAL
: 是否docker 官方发布stars
: 类似Github 里面的star,表示点赞、喜欢的意思。AUTOMATED: 自动构建。
补充
[root@guoweixin ~]# docker search --help
Usage: docker search [OPTIONS] TERM
Search the Docker Hub for images
Options:
-f, --filter filter Filter output based on conditions provided
根据提供的条件过滤器输出
--format string Pretty-print search using a Go template
⽤Go模板打印出漂亮的搜索结果
--limit int Max number of search results (default 25)
搜索结果的最⼤数量(默认值为25)
--no-trunc Don't truncate output
不要截断输出
下载镜像
docker pull [选项] [Docker Registey 地址[:端口号]/] 仓库名[:标签]
从 Docker 镜像仓库获取镜像
- Docker 镜像仓库地址: 地址的格式一般是
< 域名 /IP>[: 端口号 ]
。默认地址是Docker Hub
。- 仓库名:这里的仓库名是两段式名称, 即
< 用户名 >/< 软件名 >
。对于 Docker Hub ,如果不给出用户名,则默认为 library ,也就是官方镜像。
docker pull centos
又例如:我们需要一个tomcat的镜像来作为我们的web服务。通过 docker pull获取镜像
docker pull tomcat:版本号 //不写 :版本号 代表laster版本
查看本地镜像
要想列出已下载下来的镜像,可以使用 docker image ls 命令
列表包含了 仓库名、标签、镜像 ID、创建时间 以及 所占用的空间。其中,仓库名、标签在之前的基础概念已经介绍过了。
镜像 ID 则是镜像的唯一标识,一个镜像可以对应多个标签。
因此,如果拥有相同的 ID,因为它们对应的是同一个镜像。
docker images
-a
:--all
,列出所有镜像-q
:--quiet
,只显示镜像的id--digests
: 显示镜像的摘要信息
REPOSITORY 镜像的仓库源
TAG 镜像的标签
IMAGE ID 镜像的 ID
CREATED 镜像创建时间
SIZE 镜像大小
同一个仓库源可以有多个 TAG,代表这个仓库源的不同版本,我们使用REPOSITORY:TAG 定义不同的镜像;
如果你不定义镜像的标签版本,docker将默认使用 lastest 镜像!
将镜像做成离线压缩包/将Docker镜像导出到本地
- 将Docker镜像导出到本地
format:
docker save -o <保存路径/文件名.tar> <镜像名:标签>
docker save -o centos.tar.gz centos
ls ./
加载镜像到本地Docker引擎
- 将Docker镜像加载到本地Docker引擎中
format:
docker load -i <path to image tar file>
- 其中
-i
参数指定要加载的镜像tar文件的路径
docker load -i centos.tar.gz
更新容器
docker update
命令可以用于更新一个或多个 Docker容器 的配置。该命令后面的CONTAINER
可以是容器Id
,或是容器名
。
您可以使用此命令来防止容器消耗 Docker 主机的过多资源。使用单个命令,您可以对单个容器或多个容器进行限制。要指定多个容器,请提供以空格分隔的容器名称或 ID 列表。
- 语法格式
# docker update [OPTIONS] CONTAINER [CONTAINER...]
注:
Windows
容器不支持docker update
命令
-
命令参数
| 参数 | 描述 |
| -------------- | -------------- |
| --cpu-rt-runtime | 将CPU实时运行时间限制在微秒级 |
| --cpu-rt-period | 限制CPU实时周期(以微秒为单位) |
| --cpu-quota | 限制CPU CFS(完全公平调度程序)配额 |
| --cpu-period | 限制CPU CFS(完全公平调度程序)周期 |
| --blkio-weight | 块 IO(相对权重),介于 10 到 1000 之间,或 0 禁用(默认 0) |
| --cpu-shares,-c | 更新 cpu-shares。 |
| --cpus | cpu数量 |
| --cpuset-cpus | 允许执行的 CPU (0-3, 0,1) |
| --cpuset-mems | 允许执行的 MEM (0-3, 0,1) |
| --kernel-memory | 更新内核内存限制。 |
| --memory,-m | 更新内存限制。 |
| --memory-reservation | 内存软限制 |
| --memory-swap | 交换限制等于内存加交换:-1 启用无限制交换 |
| --pids-limit | API 1.40+ 调整容器 pid 限制(设置 -1 表示无限制) |
| --restart | 更新重启策略。(容器退出时应用的重新启动策略) | -
案例:更新
cpu-shares
使用
docker create -it
命令,创建一个 dokcer 容器。
# docker create -it --name cnter centos
efb5ecbf143c4e1a7e62c0d7d55a4d271923c5e37148837d3b11ae23ad886d40
使用 docker update 命令,更新容器的 cpu-shares。
# docker update --cpu-shares 512 cnter
使用
docker kill
和docker rm
命令,删除所有容器。
docker kill `docker ps -qa` ; docker rm `docker ps -aq`
- 案例:更新内存限制
使用
docker create -it
命令,创建一个dokcer
容器。
docker create -it --name cnter centos
efb5ecbf143c4e1a7e62c0d7d55a4d271923c5e37148837d3b11ae23ad886d40
使用 docker update 命令,更新容器的内存限制。
docker update -m 512M cnter
使用 docker kill 和 docker rm 命令,删除所有容器。
docker kill `docker ps -qa` ; docker rm `docker ps -aq`
- 案例
要将容器的 cpu 份额限制为 512,请首先确定容器名称或 ID。您可以使用 docker ps 来查找这些值。您还可以使用从命令返回的 ID docker run 。然后,执行以下操作:
docker update --cpu-shares 512 abebf7571666
- 案例
要更新多个容器的多个资源配置:
$ docker update --cpu-shares 512 -m 300M abebf7571666 hopeful_morse
删除镜像
- 根据镜像的 ID 或名称删除指定镜像
format:
docker rmi <镜像ID 或 名称>
docker rmi -f centos:latest
3.2 容器操作
创建 + 运行容器(run)
- 命令格式
docker [container] run [OPTIONS] IMAGE [COMMAND] [ARG...]
Usage: Run a command in a new container
意译:通过run命令创建一个新的容器(container)
注:container
参数可省略之
- 常用选项说明
- -d, --detach=false, 指定容器运行于前台还是后台,默认为false
- -i, --interactive=false, 打开STDIN,用于控制台交互
- -t, --tty=false, 分配tty设备,该可以支持终端登录,默认为false
-itd
: 以交互模式(i)运行容器,支持命令交互(i)、支持终端登录(t)、容器以后台方式(d)运行
- -u, --user="", 指定容器的用户
- -a, --attach=[], 登录容器(必须是以docker run -d启动的容器)
- -w, --workdir="", 指定容器的工作目录
- -c, --cpu-shares=0, 设置容器CPU权重,在CPU共享场景使用
- -e, --env=[], 指定环境变量,容器中可以使用该环境变量
- -m, --memory="", 指定容器的内存上限
- -P, --publish-all=false, 指定容器暴露的端口
- -p, --publish=[], 指定容器暴露的端口
- -h, --hostname="", 指定容器的主机名
- -v, --volume=[], 给容器挂载存储卷,挂载到容器的某个目录
- --volumes-from=[], 给容器挂载其他容器上的卷,挂载到容器的某个目录
- --cap-add=[], 添加权限,权限清单详见:http://linux.die.net/man/7/capabilities
- --cap-drop=[], 删除权限,权限清单详见:http://linux.die.net/man/7/capabilities
- --cidfile="", 运行容器后,在指定文件中写入容器PID值,一种典型的监控系统用法
- --cpuset="", 设置容器可以使用哪些CPU,此参数可以用来容器独占CPU
- --device=[], 添加主机设备给容器,相当于设备直通
- --dns=[], 指定容器的dns服务器
- --dns-search=[], 指定容器的dns搜索域名,写入到容器的/etc/resolv.conf文件
- --entrypoint="", 覆盖image的入口点
- --env-file=[], 指定环境变量文件,文件格式为每行一个环境变量
- --expose=[], 指定容器暴露的端口,即修改镜像的暴露端口
- --link=[], 指定容器间的关联,使用其他容器的IP、env等信息
- --lxc-conf=[], 指定容器的配置文件,只有在指定--exec-driver=lxc时使用
- --name="", 指定容器名字,后续可以通过名字进行容器管理,links特性需要使用名字
- --net="bridge", 容器网络设置:
- bridge 使用docker daemon指定的网桥
- host //容器使用主机的网络
- container:NAME_or_ID >//使用其他容器的网路,共享IP和PORT等网络资源
- none 容器使用自己的网络(类似--net=bridge),但是不进行配置
- --privileged=false, 指定容器是否为特权容器,特权容器拥有所有的capabilities
- --restart="no", 指定容器停止后的重启策略:
- no:容器退出时不重启
- on-failure:容器故障退出(返回值非零)时重启
- always:容器退出时总是重启
- --rm=false, 指定容器停止后自动删除容器(不支持以docker run -d启动的容器)
- --sig-proxy=true, 设置由代理接受并处理信号,但是SIGCHLD、SIGSTOP和SIGKILL不能被代理
- 示例
- 运行一个在后台执行的容器,同时,还能用控制台管理:
docker run -i -t -d ubuntu:latest
-i
,--interactive
,以交互模式运行容器,并保持终端激活。
注:交互就是用户输入命令,机器执行命令,并提供返回结果。那么在哪里输入命令呢?得有一个终端吧,所以这个命令必须与
-a
或-t
命令配合使用。
-a
选项用于指定将容器的标准输出连接到终端。使用-t
选项创建的容器会分配一个伪终端,并将容器的标准输入、输出和错误连接到该终端。
-t
,--tty
:为容器分配一个伪终端。
补充(网友观点,尚未验证):
docker exec -it ...
中的-it
参数和docker run -it
中相同。
但docker exec
中的-it
不会受docker run
的参数影响。他们是两个工具,只要docker run
把容器启动了,docker exec
执行什么命令是它的事。
- 创建、并运行容器,同时在镜像内执行shell命令
# ↓ 仅用于调试 (用于容器运行后,通过 docker logs baili-web 来查验镜像内 /app 的目录结构)
# docker run -it --name xxxx-web -d -p 8003:3003 xxxx-web:latest /bin/sh -c "ls -la /app"
- 运行一个带命令在后台不断执行的容器,不直接展示容器内部信息:
docker run -d ubuntu:latest ping www.docker.com
- 运行一个在后台不断执行的容器,同时带有命令,程序被终止后还能重启继续跑,还能用控制台管理:
docker run -d --restart=always ubuntu:latest ping www.docker.com
- 为容器指定一个名字
docker run -d --name=ubuntu_server ubuntu:latest
- 容器暴露80端口,并指定宿主机80端口与其通信(: 之前是宿主机端口,之后是容器需暴露的端口)
docker run -d --name=ubuntu_server -p 80:80 ubuntu:latest
- 指定容器内目录与宿主机目录共享(: 之前是宿主机文件夹,之后是容器需共享的文件夹)
docker run -d --name=ubuntu_server -v /etc/www:/var/www ubuntu:latest
操纵容器/容器内执行命令(exec)
- 官方文档
docker exec
命令用于在运行中的容器内执行命令。
使用
docker exec
命令可以无需进入容器,在容器内执行命令,方便管理复杂多容器环境。
- 语法
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
说明:
- OPTIONS:可选项,用于指定一些选项,具体可以查看docker exec --help命令获取;
- CONTAINER:必选项,指定容器名称或容器ID;
- COMMAND:必选项,指定要在容器内执行的命令;
- ARG:可选项,指定命令要使用的参数。
常用选项:
- -i,--interactive:以交互模式运行容器。
- -t,--tty:为容器分配一个虚拟终端/tty。
- -d,--detach:在后台模式下运行容器。
- -u,--user[=""]:以指定的用户名或UID运行容器中的命令。
- -w,--workdir=" ":指定命令的工作目录。
- 举例:
- 【综合案例】在宿主机中执行 mysql 容器 的 命令
- 方法1
docker exec -it mysql bash
> mysql -uroot -p${MYSQL_ROOT_PASSWORD} --port=3306 -h127.0.0.1 -e 'show databases;'
> exit
- 方法2:
docker exec -it mysql sh -c "mysql -uroot -p${MYSQL_ROOT_PASSWORD} --port=3306 -h127.0.0.1 -e 'show databases;'"
注: MYSQL_ROOT_PASSWORD 也是 mysql container 内的内置环境变量
- 执行一个交互式的bash终端:
docker exec -it container_name bash
docker exec -it container_name /bin/bash
- 执行一个命令:
docker exec container_name ls -a
docker exec container_name /path/to/my_script.sh
- 在后台模式下执行命令:
docker exec -d container_name ls -a
- 在指定用户下执行命令:
docker exec -u user_name container_name ls -a
- 指定命令工作目录:
docker exec -w /usr/src/myapp container_name ls -a
- 容器间通信
我们可以使用docker exec -it
命令在不同的容器之间进行通信。例如,假设我们有两个容器container1
和container2
,我们可以通过以下命令在container1
中执行一个命令,并将结果发送到container2
:
docker exec -it container1 sh -c "echo 'Hello' > /tmp/message.txt"
docker exec -it container2 cat /tmp/message.txt
总结:docker exec命令是一个很好的容器管理工具,使用起来非常简单方便。掌握这个命令可以更好地管理容器的生命周期和维护运行环境。
查看容器
- 查看容器
# 查看运行中的容器
docker [container] ps
# 查看全部容器
docker [container] ps -a
注:
container
参数可省略之
输出详情介绍:
- CONTAINER ID: 容器 ID。
- IMAGE: 使用的镜像。
- COMMAND: 启动容器时运行的命令。
- CREATED: 容器的创建时间。
- STATUS: 容器状态。
状态有7种:
- created(已创建)
- restarting(重启中)
- running 或 Up(运行中)
- removing(迁移中)
- paused(暂停)
- exited(停止)
- dead(死亡)
- PORTS: 容器的端口信息和使用的连接类型(tcp\udp)。
- NAMES: 自动分配的容器名称。
查看容器的COMMAND详情
在显示容器列表的命令后面加上--no-trunc
(大意:不省略)
docker ps -a --no-trunc
查看容器的运行日志
- 查看日志
在宿主主机内使用docker logs <containerId>
命令,查看容器内的标准输出:
root@xxx:~$ docker logs 2b1b7a428627
root@xxx:~$ docker logs nginx
- 实时查看/跟踪日志
docker logs -f nginx
- 实时查看/跟踪最近的10条日志
docker logs -f --tail {lineNum} {containerName/containerId}
- 查看最近XX分钟的日志
docker logs --since {xxm} {containerName/containerId}
如最近1分钟:docker logs --since 1m nginx
- 查看指定日期至今的所有日志
如:查看2023-01-16至今的所有日志
docker logs -f --since "2023-01-16" nginx
启动/停止容器
- 启动停止容器
format:
docker start/stop {containerName | containerId}
停止容器(stop container),并不意味着容器物理上不存在了,其实它依旧存在。如果此时,新建同名容器时,将报类似如下错误:
docker: Error response from daemon: Conflict. The container name "/mysql" is already in use by container "c08e6zzzzd274e5fxxxxcb883d55f3yyyy5b54efff". You have to remove (or rename) that container to be able to reuse that name.
- demo
docker stop nginx
删除容器
- 删除容器
如果容器为运行状态,则:需停止容器成功后才能被成功删除
# 删除指定的容器
docker rm [-f] <containerid|containerName>
# 删除未启动成功的容器
docker rm $(docker ps -a|grep Created|awk '{print $1}')
或
docker rm $(docker ps -qf status=created)
# 删除退出状态的容器
docker rm $(docker ps -a|grep Exited|awk '{print $1}')
或
docker rm $(docker ps -qf status=exited)
# 删除所有未运行的容器
# 注:正在运行的删除不了,所有未运行的都被删除了
docker rm $(docker ps -a -q)
或
# 注:Docker 1.13版本以后,可以使用 docker containers prune 命令,删除孤立的容器 (prune ,修剪之意)
docker container prune
查看容器(元)信息(inspect)
docker inspect <containerName|containerId>
docker inspect [OPTIONS] NAME|ID [NAME|ID...]
-f 指定返回值的模板文件
-s 如果类型为容器,则显示文件总大小
--type 返回指定类型的JSON
- 案例
# 获取容器 IP
docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $CONTAINER_ID
# 获取IP地址
docker inspect tomcat7 | grep IPAddress
# 获取日志路径
docker inspect --format='{{.LogPath}}' $CONTAINER_ID
卷标管理(volume)
# 新增卷标
docker volume create my-vo
# 查看所有卷标
docker volume ls
# 查看批量的卷标
docker volume ls | grep mysql
# 查看具体的volume对应的真实地址
docker volume inspect my-vo
# 删除卷标
docker volume rm my-vol
容器与主机间的数据拷贝(cp)
- 语法
docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
OPTIONS说明:
-L
: 保持源目标中的链接
- 案例1:将主机/www/a 目录拷贝到容器96f7f14e99ab的/www目录下
docker cp /www/a 96f7f14e99ab:/www/
- 案例2:将主机/www/a目录拷贝到容器96f7f14e99ab中,目录重命名为www
docker cp /www/a 96f7f14e99ab:/www
- 案例3:将容器96f7f14e99ab的/www目录拷贝到主机的/tmp目录中
docker cp 96f7f14e99ab:/www /tmp/
//docker cp mysql:/var/log/mysqld.log /opt/mysql/log/mysqld.log
//docker cp mysql:/var/lib/mysql /opt/mysql/data
//docker cp mysql:/etc/mysql/conf.d /opt/mysql/conf
//docker cp mysql:/etc/my.cnf /opt/mysql
3.3 Docker 仓库管理
- 仓库(Repository)是集中存放镜像的地方。
3.3.1 Docker Hub(官方公共仓库)
目前 Docker 官方维护了一个公共仓库 ·Docker Hub·。
大部分需求都可以通过在 Docker Hub 中直接下载镜像来实现。
- Step1 注册
在
https://hub.docker.com
免费注册一个 Docker 账号。
- Step2 登录和退出
登录需要输入用户名和密码,登录成功后,我们就可以从 docker hub 上拉取自己账号下的全部镜像。
$ docker login
- Step3 退出
退出
docker hub
可以使用以下命令:
$ docker logout
- Step4 拉取镜像
你可以通过 docker search 命令来查找官方仓库中的镜像,并利用 docker pull 命令来将它下载到本地。
以 ubuntu 为关键词进行搜索:
$ docker search ubuntu
- Step4 使用 docker pull 将官方 ubuntu 镜像下载到本地:
$ docker pull ubuntu
- Step5 推送镜像
用户登录后,可以通过 docker push 命令将自己的镜像推送到 Docker Hub。
以下命令中的 username 请替换为你的 Docker 账号用户名。
$ docker tag ubuntu:18.04 username/ubuntu:18.04
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED ...
ubuntu 18.04 275d79972a86 6 days ago ...
username/ubuntu 18.04 275d79972a86 6 days ago ...
$ docker push username/ubuntu:18.04
$ docker search username/ubuntu
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
username/ubuntu
3.4 Docker Dockerfile
3.4.1 什么是 Dockerfile?
Dockerfile
是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
DockerFile
是Docker
的一个配置文件,本质上来说它只是一个文本文件,它是用来构建【Docker镜像】的。
DockerFile
配置文件中包含了一系列的指令
和配置信息
,用于描述如何构建镜像以及如何运行容器。
通过编写Dockerfile
,我们可以将构建 Docker 镜像的【过程】自动化,实现应用程序的快速部署和迭代。
3.4.2 Dockerfile的基本结构
Dockerfile
由一行行命令语句组成,并且支持以#
开头的注释行。一般而言,Dockerfile,分为四部分:
- 基础镜像信息;
- 维护者信息;
- 镜像操作指令;
- 和容器启动时执行指令
例如:
# This Dockerfile uses the ubuntu image
# VERSION 2 - EDITION 1
# Author: docker_user
# Command format: Instruction [arguments / command] ..
# Base image to use, this must be set as the first line
FROM ubuntu
# Maintainer: docker_user <docker_user at email.com> (@docker_user)
MAINTAINER docker_user docker_user@email.com
# Commands to update the image
RUN echo "deb http://archive.ubuntu.com/ubuntu/ raring main universe" >> /etc/apt/
sources.list
RUN apt-get update && apt-get install -y nginx
RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf
# Commands when creating a new container
CMD /usr/sbin/nginx
其中,一开始必须指明【所基于的镜像名称】,接下来一般是说明维护者信息,后面则是镜像操作指令,例如 RUN 指令,RUN 指令将对镜像执行跟随的命令。每运行一条 RUN 指令,镜像就添加新的一层,并提交。最后是 CMD 指令,用来指定运行容器时的操作命令。
3.4.3 Dockerfile 如何编写与使用?(详解)
3.4.x Dockerfile/DockerComposeYml中Service的expose和ports的区别
- 背景描述
形如: 对宿主机开放 3307 端口,容器内部使用 3306 端口的 mysql container:
# docker-compose.yml
...
services:
mysql:
container_name: openmetadata_mysql
image: docker.getcollate.io/openmetadata/db:1.3.0
command: "--sort_buffer_size=10M"
restart: always
environment:
MYSQL_ROOT_PASSWORD: password
expose:
- 3306
ports:
- "3307:3306"
volumes:
- ./docker-volume/db-data:/var/lib/mysql
networks:
- app_net
healthcheck:
test: mysql --user=root --password=$$MYSQL_ROOT_PASSWORD --silent --execute "use openmetadata_db"
interval: 15s
timeout: 10s
retries: 10
...
- 解释/辨析:
expose
和ports
在Docker中都用于容器的网络配置,但它们的用途和方式略有不同。
expose
: 这是Dockerfile的指令,用于在创建镜像时声明容器打算使用的端口。它是对构建服务的人的一种文档性的声明,意味着运行的容器会监听某个端口。然而,只有当容器启动时使用了-P(大写)或-p(小写)参数,这些端口才会在主机上映射。此外,EXPOSE不会让容器的端口对外界可见。ports
: 这是docker-compose.yml文件中的一个字段,用于定义容器的端口映射。这实际上在主机上打开了端口,使得外部世界可以访问到容器的网络服务。它的格式通常为: 。例如,如果你想在主机的8080端口上运行一个在80端口上运行的web服务器,你可以使用ports配置如下:- "8080:80"。
总的来说,expose主要用于在构建阶段声明容器需要使用的端口,而ports主要用于在运行阶段定义主机和容器之间的端口映射关系。
形如:
ports 3307:3306
, 是指 宿主机的端口(3307)映射到容器的端口(3306)
- 参考文献
4 综合应用场景
4.1 docker 环境下,设置容器自动启动
- 方法1:使用 docker run 命令运行时
增加
--restart=always
参数即可
- 方法2:使用 docker-compose 命令运行时
在 yml 文件中,需要自启动的 service 下
增加 restart: always 项目即可
- 方法3:已运行的容器修改其自启动策略
执行命令:
docker update --restart=always {容器名或容器ID}
docker container update --restart=【容器策略】 容器名称
容器策略:
# no 容器退出时不重启容器
# on-failure 只有在非零状态退出时才重新启动容器
--restart=on-failure:【重启次数】
# always 无论退出状态如何都
K FAQ/问题集
Q1 配置docker镜像加速器?
- Step1 登陆阿里云镜像仓库
https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
如果没有开通,可开通阿里云的镜像服务
编辑
/etc/docker/daemon.json
- Step2 重启docker
systemctl daemon-reload
systemctl restart docker
Q2 docker hub官网进不去?
问题分析
docker hub进不去是因为“hub.docker.com”是在国外的,所以访问速度很慢,导致无法访问该网址。
解决方法
- 1、找到“daemon.json”文件
- 2、使用vim命令将其打开
- 3、添加“{ "registry-mirrors" :["https://docker.mirrors.ustc.edu.cn"]}”内容
- 4、重启docker即可
参考文献
Q3 怎么理解docker中的registry(注册表) 和repository(仓库)?
- Registry:(英译:注册表、登记处)
A service responsible for hosting and distributing images. The default registry is the Docker Hub.
Docker registry 能够被第三方组织host,作为共有或者私有的registry,下面就是一些registries:
- Repository:(英译:仓库)
A collection of related images (usually providing different versions of the same application or service).
相关映像的集合(通常提供相同应用程序或服务的不同版本)。
Docker repository is a collection of different docker images with same name, that have different tags.
Docker存储库是不同Docker映像的集合,具有相同的名称,具有不同的标签。
也就是说repository是关于同一种镜像(如python)的不同版本”tag“的“集合地”,例如 https://hub.docker.com/r/library/python/tags/。这里有许多不同tag的官方python镜像,官方python repository中所有的版本都位于Docker hub这个registry内!
- Tag:(英译:标签)
An alphanumeric identifier (字母数字的标志符)attached to images within a repository (e.g., 14.04 or stable ).
对于 [image name] = [repository] : [tag] ,其中的“repository”是对镜像而言,某一个镜像可以有好多的tag。
所以有一种“仓库”的概念在里面,看某些书的时候会发现,有这样的的语句“每个repository可以有多个tag”。
有过创建自己的私有registry经历的就会知道,我们会重新“命名”我们的本地的image,例如:myregistryhost:5000/namespace/repo-name:tag;
此外,我们在docker hub 上面上传自己的docker 镜像的时候也会填上自己的 namespace(用户名),即你在docker hub上面注册的账号。
Y 推荐资源
Y.1 核心资源/核心链接
- Docker 官网主页
- Docker 官方博客:
- Docker 官方文档:
- Docker github
https://hub.docker.com
https://hub-stage.docker.com
https://github.com/moby/moby 【Docker 源代码仓库】
https://docs.docker.com/release-notes/ 【Docker 发布版本的历史】
- Dockerhub 镜像站官网
https://hub-stage.docker.com/
https://registry.hub.docker.com
- Docker 官方 registry 镜像加速
- Docker Store:
- Docker Cloud:
- Docker 常见问题:
- Docker 远端应用 API:
Y.2 Docker Hub 镜像加速器列表
- Docker 官方镜像
镜像加速器 | 镜像加速器地址URL | 专属加速器 | 其他加速 |
---|---|---|---|
Docker 中国官方镜像站 | https://registry.docker-cn.com | ... | Docker Hub |
Dao Cloud 镜像站 | http://f136db2.m.daocloud.io/ https://www.daocloud.io/mirror#accelerator-doc |
可登录,系统分配 | Docker Hub |
Azure 中国镜像站 | https://dockerhub.azk8s.cn | Docker Hub / GCR / Quay | |
科大镜像站 | https://docker.mirrors.ustc.edu.cn | ... | Docker Hub / GCR / Quay |
阿里云 | https://docker.mirrors.ustc.edu.cn | 需登录,系统分配 | Docker Hub |
七牛云 | https://reg-mirror.qiniu.com | ... | Docker Hub / GCR / Quay |
网易云 | https://hub-mirror.c.163.com | ... | Docker Hub |
腾讯云 | https://mirror.ccs.tencentyun.com | ... | Docker Hub |
ustc 镜像 | https://docker.mirrors.ustc.edu.cn | ... | -- |
Y.3 其他
-
容器镜像服务/制品中心 - 阿里云
https://cr.console.aliyun.com/cn-hangzhou/instances/artifact
X 参考文献
- Docker Compose 基础教程 - 博客园/千千寰宇
- Docker 官网
- Docker容器基础 - CSDN
- Docker镜像 - CSDN
- docker run 参数详解 - 博客园
- Docker基本概念和原理理解 - Zhihu
- Docker build 命令 - 菜鸟教程
- Docker Dockerfile - 菜鸟教程
- 怎么理解docker中的registry 和repository? - CSDN
- Docker 教程 - 菜鸟教程
- docker update 命令及用法详解 - 脚本之家
待阅读
本文链接: https://www.cnblogs.com/johnnyzen
关于博文:评论和私信会在第一时间回复,或直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
日常交流:大数据与软件开发-QQ交流群: 774386015 【入群二维码】参见左下角。您的支持、鼓励是博主技术写作的重要动力!