Docker快速入门
Docker能解决什么问题?
长期以来,应用程序的部署面临一个很头疼的问题:应用程序的运行依赖于环境和配置,比如一个基于Node.js的程序,在A机器上可以运行,到了B机器上却报错,原因是B机器上的Node.js版本和A机器上的不一样,直接的解决方案当然是在B机器上再安一个与A同版本的Node.js,但如果另一个程序恰好依赖另一个版本的Node.js版本呢?另外,这只是一个依赖,如果有几十上百个依赖呢?再另外,这只是在一台机器上部署,如果需要部署到成千上万台机器/实例上呢?
Docker是什么?它如何解决这个问题?
Docker是一种虚拟化技术,它可以将应用及其所需的运行环境整体打包进一个“容器”里,从而可以在任何一个安装了Docker客户端的机器上直接运行,并且确保运行环境完全一致。Docker有点像虚拟机,但比虚拟机更轻量,它没有模拟硬件和操作系统,只是进程级的资源隔离,不同的Docker容器会共享内核资源。
Docker核心概念
镜像(Image)
用于创造容器的模板。可以把镜像理解为一个文件系统,存放可以运行在Linux内核之上的程序和相应的数据。
镜像有两个特点:
1. 分层(Layer)。一个镜像可以由多个中间层组成,也可以通过在已有镜像上添加一层来生成新的镜像(这也是最常用的创建新镜像的方式)。
2. 只读(read-only)。镜像一旦生成,便不能修改。因此多个容器可以共用同一个镜像。
镜像有镜像id和镜像名,前者是一串12位的hash字符串,后者由仓库名和标签组成,比如 nginx:1.19.4 这个镜像,其仓库名是nginx,标签是1.19.4。
容器(Container)
容器是镜像的运行实例,是一个运行在沙盒环境里、独立于宿主机的隔离进程,并且拥有自己的网络和命名空间。
容器其实是在镜像上面添加一层“可读可写层”来实现的。
仓库(Repository)
仓库是存放镜像的地方,就像Github存放源码、npm registry存放npm包一样,可以方便地托管并在不同的机器之间共享镜像。
Docker Hub是Docker官方提供的公共仓库,组织内部也可以自己搭建私有仓库。仓库里的镜像有标签(Tag)的概念,可以理解为版本控制。这些都非常类似于Github、npm registry,很好理解。
Docker基本操作
镜像操作
# 查看所有镜像操作 docker image --help # 从仓库拉取镜像 docker image pull [OPTIONS] NAME[:TAG|@DIGEST] # 或 docker pull [OPTIONS] NAME[:TAG|@DIGEST] # 例 docker pull nginx # 查看本地镜像 docker image ls #或 docker images
# 查看虚悬镜像(pull新版本镜像后,旧版本镜像的仓库、tag均被置为none,是为“虚悬镜像”)
docker image ls -f dangling=true
# 删除未使用的镜像
docker image prune
# 删除指定镜像
docker image rm [OPTIONS] IMAGE1,IMAGE2,...
# 或
docker rmi [OPTIONS] IMAGE1,IMAGE2,...
# 从本机指定路径导入镜像
docker load < /path/to/image.tar.gz
# 导出镜像到指定路径
docker image save /path/to/image.tar.gz
容器操作
# 查看所有容器操作 docker container --help # 创建并启动容器 docker run [OPTIONS] IMAGE # 例 # -p指定端口号(宿主:容器内部),--name指定容器名 docker run -p 80:80 nginx -name webserver nginx # 启动已有容器 docker start CONTAINER_ID # 查看本地(运行中的)容器 docker container ls # 或 docker ps # 例 # -a 查看本地所有容器,包括未运行的, -q只显示容器id docker ps -aq # 停止容器运行 docker stop CONTAINER_ID1,CONTAINER_ID2,... # 例:停止所有容器 docker stop $(docker ps -qa) # 删除容器 docker container rm CONTAINER_ID # 或 docker rm CONTAINER_ID
参考链接
1. Docker官方文档