文章目录
- 沙箱:一个被隔开的、安全的小环境。权限隔离
- docker核心概念
-
- 容器:轻量化的运行实例,包含应用代码、运行时环境和依赖库。基于镜像创建,与其他容器隔离,共享主机操作系统内核(比虚拟机更高效)
- 镜像:只读模板,定义了容器的运行环境(如操作系统、软件配置等)
- [dockerfile: 文本文件,描述如何自动构建镜像(例如指定基础镜像、安装软件、复制文件等](#dockerfile: 文本文件,描述如何自动构建镜像(例如指定基础镜像、安装软件、复制文件等)
- [仓库 repository:存储和分发镜像的平台](#仓库 repository:存储和分发镜像的平台)
-
- [registry (注册)→ namespace/repository(仓库) → tag 。registry:集中存放和管理镜像的大平台.repository:registry 里面的一组相关镜像。一个 repository 里可以有多个 tag 版本](#registry (注册)→ namespace/repository(仓库) → tag 。registry:集中存放和管理镜像的大平台.repository:registry 里面的一组相关镜像。一个 repository 里可以有多个 tag 版本)
- 其它仓库
- [总结:Dockerfile 定义怎么构建镜像,Image 是构建出来的静态模板,Container 是镜像运行后的实例](#总结:Dockerfile 定义怎么构建镜像,Image 是构建出来的静态模板,Container 是镜像运行后的实例)
-
- [Dockerfile 是"菜谱",构建说明](#Dockerfile 是“菜谱”,构建说明)
- image是按照菜谱做出来的模板,打包环境
- [Container 是"把镜像真正运行起来"的实例](#Container 是“把镜像真正运行起来”的实例)
- [docker desktop](#docker desktop)
-
- [Docker Desktop 是什么?帮忙把docker跑起来,准备linux运行环境,给一个可视化界面](#Docker Desktop 是什么?帮忙把docker跑起来,准备linux运行环境,给一个可视化界面)
- Containers
-
- [端口映射 = 把容器里的服务端口,接到你电脑上的一个端口,方便你访问。宿主机端口 : 容器端口](#端口映射 = 把容器里的服务端口,接到你电脑上的一个端口,方便你访问。宿主机端口 : 容器端口)
- Images
- [Volumes。容器负责运行程序,Volume 负责保存数据](#Volumes。容器负责运行程序,Volume 负责保存数据)
- Builds
- Settings
- 总结
- [docker hello world](#docker hello world)
-
- 命令在哪执行
- [docker run ubuntu:15.10 /bin/echo "Hello world". docker run:启动一个容器.ubuntu:15.10:用这个镜像./bin/echo "Hello world":容器启动后,在容器里面执行这个命令](#docker run ubuntu:15.10 /bin/echo "Hello world". docker run:启动一个容器.ubuntu:15.10:用这个镜像./bin/echo "Hello world":容器启动后,在容器里面执行这个命令)
- 交互式容器
-
- [docker run -i -t ubuntu:15.10 /bin/bash.](#docker run -i -t ubuntu:15.10 /bin/bash.)
-
- [不管有没有 -it,本质上都是"执行后面的命令。-it 在docker给这个命令分配的交互终端环境里执行](#不管有没有 -it,本质上都是“执行后面的命令。-it 在docker给这个命令分配的交互终端环境里执行)
- [-i = interactive(交互的)。 保持输入通道打开,让你可以继续往里面打字](#-i = interactive(交互的)。 保持输入通道打开,让你可以继续往里面打字)
- [-t= tty 分配一个"像真正终端一样"的界面](#-t= tty 分配一个“像真正终端一样”的界面)
- [-it 让我能以"交互式终端"的方式使用这个容器](#-it 让我能以“交互式终端”的方式使用这个容器)
- [/bin/bash 是 Linux 里的一个程序,叫 Bash shell.Linux 里的命令解释器 / 命令行程序](#/bin/bash 是 Linux 里的一个程序,叫 Bash shell.Linux 里的命令解释器 / 命令行程序)
- 启动容器(后台模式)
-
- [docker run -d ubuntu:15.10 /bin/sh -c "while true; do echo hello world; sleep 1; done"](#docker run -d ubuntu:15.10 /bin/sh -c "while true; do echo hello world; sleep 1; done")
-
- [docker run 表示:创建并启动一个新容器](#docker run 表示:创建并启动一个新容器)
- [-d = detached 让容器在后台运行](#-d = detached 让容器在后台运行)
- [使用 ubuntu:15.10 这个镜像来创建容器](#使用 ubuntu:15.10 这个镜像来创建容器)
- [/bin/sh,和 /bin/bash 类似,都是命令解释器。启动shell程序](#/bin/sh,和 /bin/bash 类似,都是命令解释器。启动shell程序)
- [-c 执行后面这段字符串命令。sh 需要通过 -c 才知道:后面这一整段不是文件名,不是参数列表,而是一段要直接执行的命令字符串。](#-c 执行后面这段字符串命令。sh 需要通过 -c 才知道:后面这一整段不是文件名,不是参数列表,而是一段要直接执行的命令字符串。)
-
- [-c 常常有两层环境:外层 shell:你当前正在敲命令的地方,sh -c / bash -c 里面那层 shell](#-c 常常有两层环境:外层 shell:你当前正在敲命令的地方,sh -c / bash -c 里面那层 shell)
-
- [取 -c 里面自己定义的变量。单引号让"外层 shell 不提前展开 name",从而把原样的 name 传给了 -c 里面那层 shell;然后是里面那层 shell 在执行时展开了它](#取 -c 里面自己定义的变量。单引号让“外层 shell 不提前展开 name”,从而把原样的 name 传给了 -c 里面那层 shell;然后是里面那层 shell 在执行时展开了它)
- [取外层已经存在的变量。双引号外层 shell 先展开变量,在传](#取外层已经存在的变量。双引号外层 shell 先展开变量,在传)
- 取传给-c的位置参数
- 单引号,双引号。外层shell,内存shell
- [总结:变量到底由哪一层 shell 来展开](#总结:变量到底由哪一层 shell 来展开)
- [docker ps: Docker 在告诉你,现在有哪些容器正在跑,它们是用什么镜像启动的、启动时跑了什么命令、现在是什么状态、有没有对外开放端口、名字叫什么](#docker ps: Docker 在告诉你,现在有哪些容器正在跑,它们是用什么镜像启动的、启动时跑了什么命令、现在是什么状态、有没有对外开放端口、名字叫什么)
-
- [CONTAINER ID: 容器 ID。是容器的唯一标识](#CONTAINER ID: 容器 ID。是容器的唯一标识)
- [IMAGE: 使用的镜像。这个容器是拿哪个镜像做出来的](#IMAGE: 使用的镜像。这个容器是拿哪个镜像做出来的)
- [COMMAND: 启动容器时运行的命令。](#COMMAND: 启动容器时运行的命令。)
- [CREATED: 容器的创建时间。](#CREATED: 容器的创建时间。)
- [STATUS: 容器状态](#STATUS: 容器状态)
- PORTS:端口映射情况
- NAMES:容器名字
- [docker ps docker ps -a.前者看正在运行的,后者看所有容器](#docker ps docker ps -a.前者看正在运行的,后者看所有容器)
- [docker logs 容器id/容器的名字 查看容器标准输出(stdout 和 stderr)日志的命令。在宿主主机内使用](#docker logs 容器id/容器的名字 查看容器标准输出(stdout 和 stderr)日志的命令。在宿主主机内使用)
-
- [docker logs -f 有新日志继续跟着显示](#docker logs -f 有新日志继续跟着显示)
- [docker stop 停止容器](#docker stop 停止容器)
- [docker 容器使用](#docker 容器使用)
-
- [docker run -itd --name ubuntu-test ubuntu /bin/bash](#docker run -itd --name ubuntu-test ubuntu /bin/bash)
-
- [--name 给容器起名字](#--name 给容器起名字)
- [都后台运行了,为什么还要 -it?-d 只决定"你看不看着它跑",-i -t 决定"容器里的进程是不是按交互式终端方式运行"。](#都后台运行了,为什么还要 -it?-d 只决定“你看不看着它跑”,-i -t 决定“容器里的进程是不是按交互式终端方式运行”。)
- [后台容器想"进去操作"时,常见有两种方式:docker attach 和 docker exe](#后台容器想“进去操作”时,常见有两种方式:docker attach 和 docker exe)
-
- [docker attach:重新接回这个容器当前正在运行的那个主进程终端](#docker attach:重新接回这个容器当前正在运行的那个主进程终端)
- [docker exec 在已经运行的容器里,再额外启动一个新命令.退出 docker exec 打开的这个 shell,不会让容器停止](#docker exec 在已经运行的容器里,再额外启动一个新命令.退出 docker exec 打开的这个 shell,不会让容器停止)
-
- [docker exec -it:在已经运行的容器里,以交互终端方式执行一个命令。](#docker exec -it:在已经运行的容器里,以交互终端方式执行一个命令。)
- 运行一个web容器
-
- -p:将容器内部使用的网络端口随机映射到我们使用的主机上。
- [docker port 用来查:某个容器里的端口,映射到了你电脑上的哪个端口](#docker port 用来查:某个容器里的端口,映射到了你电脑上的哪个端口)
- [docker top 用来查看某个容器里当前正在运行的进程.容器里面现在有哪些进程在跑](#docker top 用来查看某个容器里当前正在运行的进程.容器里面现在有哪些进程在跑)
- [docker inspect 使用 docker inspect 来查看 Docker 的底层信息。它会返回一个 JSON 文件记录着 Docker 容器的配置和状态信息。](#docker inspect 使用 docker inspect 来查看 Docker 的底层信息。它会返回一个 JSON 文件记录着 Docker 容器的配置和状态信息。)
-
- [Path + Args:容器到底在跑什么命令](#Path + Args:容器到底在跑什么命令)
- [docker ps -l 只看最后一次创建的那一个容器,不管它现在是不是还在运行](#docker ps -l 只看最后一次创建的那一个容器,不管它现在是不是还在运行)
- [docker 镜像使用](#docker 镜像使用)
-
- [docker images 查看本机已经有了哪些镜像](#docker images 查看本机已经有了哪些镜像)
-
- [IMAG 镜像名 + 标签,也就是 仓库名:标签。REPOSITORY:表示镜像的仓库源,TAG:镜像的标签。使用 REPOSITORY:TAG 来定义不同的镜像。](#IMAG 镜像名 + 标签,也就是 仓库名:标签。REPOSITORY:表示镜像的仓库源,TAG:镜像的标签。使用 REPOSITORY:TAG 来定义不同的镜像。)
- [镜像 ID。镜像内容的标识。两个条目如果 ID 一样,通常就是同一个镜像内容,只是名字或标签不同。](#镜像 ID。镜像内容的标识。两个条目如果 ID 一样,通常就是同一个镜像内容,只是名字或标签不同。)
- [DISK USAGE CONTENT SIZE EXTRA 里的 U](#DISK USAGE CONTENT SIZE EXTRA 里的 U)
- [docker pull 拉取镜像。digest 常用于验证镜像完整性和精确定位镜像版本。Digest 就是 Docker 镜像内容的唯一指纹](#docker pull 拉取镜像。digest 常用于验证镜像完整性和精确定位镜像版本。Digest 就是 Docker 镜像内容的唯一指纹)
- [docker search 查找镜像](#docker search 查找镜像)
-
- [NAME 镜像名](#NAME 镜像名)
- [DESCRIPTION 镜像描述。SATRS受欢迎程度,OFFICIAL 是否是官方的](#DESCRIPTION 镜像描述。SATRS受欢迎程度,OFFICIAL 是否是官方的)
- [AUTOMATED 镜像是不是通过 Docker Hub 的自动构建机制生成的](#AUTOMATED 镜像是不是通过 Docker Hub 的自动构建机制生成的)
- [镜像删除 docker rmi 镜像名/镜像ID](#镜像删除 docker rmi 镜像名/镜像ID)
- [构建镜像 docker build](#构建镜像 docker build)
-
- dockerfile
-
- [FROM centos:6.7](#FROM centos:6.7)
- [MAINTAINER Fisher "fisher@sudops.com"](#MAINTAINER Fisher "fisher@sudops.com")
- [RUN 是 Dockerfile 里的一个指令,意思是:在构建镜像的时候执行一条命令](#RUN 是 Dockerfile 里的一个指令,意思是:在构建镜像的时候执行一条命令)
- [EXPOSE 不是直接把端口开放到宿主机,只是声明"这个容器会用这个端口"](#EXPOSE 不是直接把端口开放到宿主机,只是声明“这个容器会用这个端口”)
- [CMD 容器启动时默认执行这个命令。](#CMD 容器启动时默认执行这个命令。)
- [怎么构建这个镜像?假设这个文件就叫 Dockerfile,在当前目录下执行:](#怎么构建这个镜像?假设这个文件就叫 Dockerfile,在当前目录下执行:)
- [设置镜像标签 docker tag 镜像ID。docker tag 不是"复制出一个新镜像",而是"给同一个镜像再起一个新名字"](#设置镜像标签 docker tag 镜像ID。docker tag 不是“复制出一个新镜像”,而是“给同一个镜像再起一个新名字”)
沙箱:一个被隔开的、安全的小环境。权限隔离





docker核心概念
Dockerfile → Image → Container → Registry
用 Dockerfile 构建 Image,把 Image 上传到 Registry,需要运行时再用 Image 创建 Container。
容器:轻量化的运行实例,包含应用代码、运行时环境和依赖库。基于镜像创建,与其他容器隔离,共享主机操作系统内核(比虚拟机更高效)

镜像:只读模板,定义了容器的运行环境(如操作系统、软件配置等)

dockerfile: 文本文件,描述如何自动构建镜像(例如指定基础镜像、安装软件、复制文件等

仓库 repository:存储和分发镜像的平台

registry (注册)→ namespace/repository(仓库) → tag 。registry:集中存放和管理镜像的大平台.repository:registry 里面的一组相关镜像。一个 repository 里可以有多个 tag 版本
registry是放镜像的,下面有repository,同一类的镜像就是一个repository,使用registry下会有很多repository.
repository 本质上就是"镜像分类目录"
tag 是为了在同一个 repository 下面区分具体版本
registry 解决"放在哪里"repository 解决"这是哪一类"
tag 解决"这是这一类里的哪一个版本"






见digest章节

namespace = 用户名、组织名,或官方名下的目录名,用来表示"这是谁名下的"



完整的镜像名,大致可以写成:registry/namespace/repository:tag
如果镜像引用里省略了 registry,Docker 默认用 docker.io;如果省略了 namespace,对官方镜像默认用 library
library 是 Docker Hub 上官方镜像默认所在的 namespace(命名空间)。


其它仓库

总结:Dockerfile 定义怎么构建镜像,Image 是构建出来的静态模板,Container 是镜像运行后的实例


Dockerfile 是"菜谱",构建说明

image是按照菜谱做出来的模板,打包环境

Container 是"把镜像真正运行起来"的实例

docker desktop
Docker Desktop 是什么?帮忙把docker跑起来,准备linux运行环境,给一个可视化界面
Docker Desktop 就是 Docker 官方做的一套本地容器工具箱:里面既有 Docker 的核心引擎,又有跑 Linux 容器需要的底层环境,还有图形界面和各种方便开发者使用的功能。


docker engine

Linux VM

gui

开发者体验优化

本地容器化开发环境


集成 Kubernetes(可选):专门用来管理很多容器的大管家

Containers

端口映射 = 把容器里的服务端口,接到你电脑上的一个端口,方便你访问。宿主机端口 : 容器端口







Images

Volumes。容器负责运行程序,Volume 负责保存数据







Builds

Settings

总结
Images 是模板,Containers 是模板跑起来后的实例,Volumes 是实例用的数据盘,Builds
是模板的制作记录,Settings 是整个 Docker Desktop 的总开关
docker hello world
命令在哪执行

镜像下载到哪里了?容器占用的空间




docker run ubuntu:15.10 /bin/echo "Hello world". docker run:启动一个容器.ubuntu:15.10:用这个镜像./bin/echo "Hello world":容器启动后,在容器里面执行这个命令
- 先检查你本地有没有 ubuntu:15.10 这个镜像
- 没有的话就去拉取
- 基于这个镜像临时创建一个容器
- 在容器里执行 /bin/echo "Hello world"
- 输出 Hello world 后容器结束

交互式容器
docker run -i -t ubuntu:15.10 /bin/bash.
docker run:启动一个容器
-it:让我能交互地使用它
ubuntu:15.10:用这个镜像
/bin/bash:容器启动后运行 bash 这个命令行程序





不管有没有 -it,本质上都是"执行后面的命令。-it 在docker给这个命令分配的交互终端环境里执行



z
-i = interactive(交互的)。 保持输入通道打开,让你可以继续往里面打字


-t= tty 分配一个"像真正终端一样"的界面

-it 让我能以"交互式终端"的方式使用这个容器

/bin/bash 是 Linux 里的一个程序,叫 Bash shell.Linux 里的命令解释器 / 命令行程序



启动容器(后台模式)
docker run -d ubuntu:15.10 /bin/sh -c "while true; do echo hello world; sleep 1; done"
docker run 表示:创建并启动一个新容器

-d = detached 让容器在后台运行

使用 ubuntu:15.10 这个镜像来创建容器

/bin/sh,和 /bin/bash 类似,都是命令解释器。启动shell程序

-c 执行后面这段字符串命令。sh 需要通过 -c 才知道:后面这一整段不是文件名,不是参数列表,而是一段要直接执行的命令字符串。


-c 常常有两层环境:外层 shell:你当前正在敲命令的地方,sh -c / bash -c 里面那层 shell

取 -c 里面自己定义的变量。单引号让"外层 shell 不提前展开 name",从而把原样的 name 传给了 -c 里面那层 shell;然后是里面那层 shell 在执行时展开了它


取外层已经存在的变量。双引号外层 shell 先展开变量,在传
export 只在当前shell 以及 子shell有效,关闭终端无效



取传给-c的位置参数

单引号,双引号。外层shell,内存shell




总结:变量到底由哪一层 shell 来展开
单引号 '...':外层 shell 基本不展开,尽量原样传进去
双引号 "...":外层 shell 会展开变量
export:把变量放进环境里,子进程里的 shell 也能看到。
单引号 '...'
先别动,原样送进去。
所以常常是内层展开。
双引号 "..."
外层先看一眼,能替换的先替换。
所以常常是外层展开。





docker ps: Docker 在告诉你,现在有哪些容器正在跑,它们是用什么镜像启动的、启动时跑了什么命令、现在是什么状态、有没有对外开放端口、名字叫什么
CONTAINER ID: 容器 ID。是容器的唯一标识

IMAGE: 使用的镜像。这个容器是拿哪个镜像做出来的

COMMAND: 启动容器时运行的命令。

CREATED: 容器的创建时间。

STATUS: 容器状态

PORTS:端口映射情况

tcp、udp,它们都是网络传输协议。电脑之间传数据时,约定好的两种"送货方式"。








NAMES:容器名字

docker ps docker ps -a.前者看正在运行的,后者看所有容器

docker logs 容器id/容器的名字 查看容器标准输出(stdout 和 stderr)日志的命令。在宿主主机内使用


docker logs -f 有新日志继续跟着显示

docker stop 停止容器
docker 容器使用
docker run -itd --name ubuntu-test ubuntu /bin/bash


--name 给容器起名字

都后台运行了,为什么还要 -it?-d 只决定"你看不看着它跑",-i -t 决定"容器里的进程是不是按交互式终端方式运行"。
因为有些程序即使在后台跑,也仍然需要一个终端环境才能正常挂着




后台容器想"进去操作"时,常见有两种方式:docker attach 和 docker exe
docker attach 是连到容器原来的主进程终端,docker exec 是在容器里另外启动一个新命令
docker attach:重新接回这个容器当前正在运行的那个主进程终端


docker exec 在已经运行的容器里,再额外启动一个新命令.退出 docker exec 打开的这个 shell,不会让容器停止





docker exec -it:在已经运行的容器里,以交互终端方式执行一个命令。






运行一个web容器
-p:将容器内部使用的网络端口随机映射到我们使用的主机上。
docker port 用来查:某个容器里的端口,映射到了你电脑上的哪个端口



docker top 用来查看某个容器里当前正在运行的进程.容器里面现在有哪些进程在跑


docker inspect 使用 docker inspect 来查看 Docker 的底层信息。它会返回一个 JSON 文件记录着 Docker 容器的配置和状态信息。

Path + Args:容器到底在跑什么命令



docker ps -l 只看最后一次创建的那一个容器,不管它现在是不是还在运行


docker 镜像使用
docker images 查看本机已经有了哪些镜像

IMAG 镜像名 + 标签,也就是 仓库名:标签。REPOSITORY:表示镜像的仓库源,TAG:镜像的标签。使用 REPOSITORY:TAG 来定义不同的镜像。


镜像 ID。镜像内容的标识。两个条目如果 ID 一样,通常就是同一个镜像内容,只是名字或标签不同。

DISK USAGE CONTENT SIZE EXTRA 里的 U

docker pull 拉取镜像。digest 常用于验证镜像完整性和精确定位镜像版本。Digest 就是 Docker 镜像内容的唯一指纹




docker search 查找镜像
NAME 镜像名


DESCRIPTION 镜像描述。SATRS受欢迎程度,OFFICIAL 是否是官方的

AUTOMATED 镜像是不是通过 Docker Hub 的自动构建机制生成的

镜像删除 docker rmi 镜像名/镜像ID
构建镜像 docker build
dockerfile
FROM centos:6.7
表示:以这个镜像为起点;没有就先下载
也就是"先拿一个现成的 CentOS 6.7 系统,再在它上面继续加工"。
MAINTAINER Fisher "fisher@sudops.com"
表示:镜像维护者是谁。 不过现在这个写法已经比较旧了,通常更推荐用 LABEL 来写作者信息。


RUN 是 Dockerfile 里的一个指令,意思是:在构建镜像的时候执行一条命令






EXPOSE 不是直接把端口开放到宿主机,只是声明"这个容器会用这个端口"
注意: EXPOSE 不是直接把端口开放到宿主机,只是声明"这个容器会用这个端口"


CMD 容器启动时默认执行这个命令。


怎么构建这个镜像?假设这个文件就叫 Dockerfile,在当前目录下执行:

设置镜像标签 docker tag 镜像ID。docker tag 不是"复制出一个新镜像",而是"给同一个镜像再起一个新名字"
docker tag = 给已有镜像再起一个新名字,不会重新构建,也不会多出一份镜像内容




