docker是什么?
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。
Docker的本质就是一个进程
Docker 使用 Google 公司推出的 Go 语言 进行开发实现,基于 Linux 内核的
cgroup,namespace,以及OverlayFS 类的 Union FS 等技术,对进程进行封装隔离,属于 操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。最初实现是基于 LXC,从 0.7 版本以后开始去除 LXC,转而使用自行开发的 libcontainer,从 1.11 版本开始,则进一步演进为使用 runC 和containerd。
runc 是一个 Linux 命令行工具,用于根据 OCI容器运行时规范 创建和运行容器。
containerd 是一个守护程序,它管理容器生命周期,提供了在一个节点上执行容器和管理镜像的最小功能集。
Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容器的创建和维护。使得 Docker 技术比虚拟机技术更为轻便、快捷。
Docker有三个重要的概念:仓库、镜像和容器 ,它们是Docker的三大基础组件。
是一个特殊的文件系统。它除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(例如环境变量)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。
在 Dockerfile 中, 每一条指令都会创建一个镜像层,继而会增加整体镜像的大小。
镜像运行时的实体,容器包括应用程序以及所有的依赖项,作为操作系统的独立进程运行。容器可以被创建、启动、停止、删除、暂停等。
容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的 命名空间。因此容器可以拥有自己的 root 文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。这种特性使得容器封装的应用比直接在宿主运行更加安全。也因为这种隔离的特性,很多人初学 Docker时常常会混淆容器和虚拟机。
集中存放镜像文件的地方,一个 Docker Registry中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。
通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过<仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。
以 Ubuntu 镜像 为例,ubuntu 是仓库的名字,其内包含有不同的版本标签,如,16.04, 18.04。我们可以通过 ubuntu:16.04,或者 ubuntu:18.04 来具体指定所需哪个版本的镜像。如果忽略了标签,比如ubuntu,那将视为ubuntu:latest。
Docker支持64位版本的CentOS 7和CentOS 8及更高版本,它要求Linux内核版本不低于3.10。
查看Linux版本的命令:lsb_release -a 或 cat /etc/redhat -release
报错:
[root@localhost ~]# lsb_release -a
-bash: lsb_release: command not found
安装一下即可:
[root@localhost ~]# yum install -y redhat-lsb
lsb_release -a 查看效果:
[root@localhost ~]$ lsb_release -a
LSB Version: :core-4.1-amd64:core-4.1-noarch
Distributor ID: CentOS
Description: CentOS Linux release 7.6.1810 (Core)
Release: 7.6.1810
Codename: Core
cat /etc/redhat-release 查看版本效果:
[root@localhost ~]# cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core)
显然,当前Linux系统为CentOS7。再查一下内核版本是否不低于3.10。
查看内核版本有三种方式:
[root@localhost ~]# cat /proc/version
Linux version 3.10.0-957.el7.x86_64 (mockbuild@kbuilder.bsys.centos.org) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) ) #1 SMP Thu Nov 8 23:39:32 UTC 2018
[root@localhost ~]# uname -a
Linux localhost 3.10.0-957.el7.x86_64 #1 SMP Thu Nov 8 23:39:32 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
[root@localhost ~]# uname -r
3.10.0-957.el7.x86_64
Docker官方和国内daocloud都提供了一键安装的脚本,使得Docker的安装更加便捷。
官方的一键安装方式:
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
国内 daocloud一键安装命令:
curl -sSL https://get.daocloud.io/docker | sh
启动Docker的命令:
systemctl start docker
设置成开机自启:
systemctl enable docker
docker验证
通过运行hello-world镜像来验证是否正确安装了Docker Engine-Community。
#拉取镜像
docker pull hello-world
#执行hello-world
docker run hello-world
如果执行之后,控制台显示如下信息,则说明Docker安装和启动成功:
[root@iZ8vb8pfb2awsz4qy7vm7qZ ~]# docker run hello-world
Hello from Docker!
This message shows that your installation appears to be working correctly.
……
或者使用docker version验证安装是否成功(有client和service两部分表示docker安装启动都成功了)
除了启动Docker,一些其他启动相关的命令:
Docker是一个Client-Server结构的系统,Docker守护进程运行在主机上,然后通过Socket连接从客户端访问,守护进程从客户端接受命令并管理运行在主机上的容器。
当新建一个虚拟机时,虚拟机软件需要加载Guest OS,返个新建过程是分钟级别的。而Docker由于直接利用宿主机的操作系统,则省略了返个过程,因此新建一个Docker容器只需要几秒钟。
搜索仓库镜像:docker search 镜像名
拉取镜像:docker pull 镜像名
查看正在运行的容器:docker ps
查看所有容器:docker ps -a
删除容器:docker rm 容器ID
查看镜像:docker images
删除镜像:docker rmi 镜像ID
启动(停止的)容器:docker start 容器ID
停止容器:docker stop 容器ID
重启容器:docker restart 容器ID
启动(新)容器:docker run -it ubuntu /bin/bash
进入容器: docker attach 容器ID 或 docker exec -it 容器ID /bin/bash(推荐使用后者)
#进入正在运行的容器并以命令行交互:
#1.直接进入容器启动命令的终端,不会启动新的进程
# docker attach 容器ID
#2.是在容器中打开新的终端,并且可以启动新的进程
# docker exec -it 容器ID bashShell
查看自己服务器中docker 镜像列表
docker images = docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 2d389e545974 2 days ago 142MB
REPOSITORY:表示镜像的仓库源
TAG:镜像的标签
IMAGE ID:镜像ID
CREATED:镜像创建时间
SIZE:镜像大小
[root@localhost ~]# docker image --help
Usage: docker image COMMAND
Manage images
Commands:
build Build an image from a Dockerfile
history Show the history of an image
import Import the contents from a tarball to create a filesystem image
inspect Display detailed information on one or more images
load Load an image from a tar archive or STDIN
ls List images
prune Remove unused images
pull Pull an image or a repository from a registry
push Push an image or a repository to a registry
rm Remove one or more images
save Save one or more images to a tar archive (streamed to STDOUT by default)
tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
Run 'docker image COMMAND --help' for more information on a command.
搜索镜像
docker search 镜像名 (从http://hub.docker.com)
也可从docker hub上下载,search命令就是搜索的这个仓库
下载镜像(拉取镜像)
docker pull 镜像名称[:TAG]
不加TAG(版本号) 即拉取docker仓库中 该镜像的最新版本latest 加:TAG 则是拉取指定版本
有时候由于网络原因,国外的镜像国内通过网络下载不是很顺利,因此需要配置国内镜像进行加速
[root@localhost docker]# vim /etc/docker/daemon.json
{
"registry-mirrors": [
"https://sopn42m9.mirror.aliyuncs.com",
"https://hub-mirror.c.163.com",
"https://mirror.baidubce.com"
]
}
配置完之后需要重载守护进程并且重启docker:
systemctl daemon-reload
systemctl restart docker
删除镜像
当前镜像没有被任何容器使用才可以删除,否则会报错:
Error response from daemon: You cannot remove a running container ef9c...... Stop the container before attempting removal or force remove
#删除一个
docker rmi -f 镜像名/镜像ID
#删除多个
docker rmi -f 镜像名1/TAG 镜像名2/TAG
#删除全部镜像 -q 意思为只显示镜像ID, -a 意思为显示全部(可以通过 --help命令查看)
docker rmi -f $(docker images -qa)
[root@localhost ~]# docker images --help
Usage: docker images [OPTIONS] [REPOSITORY[:TAG]]
List images
Options:
-a, --all Show all images (default hides intermediate images)
--digests Show digests
-f, --filter filter Filter output based on conditions provided
--format string Pretty-print images using a Go template
--no-trunc Don't truncate output
-q, --quiet Only show image IDs
有镜像了才能创建容器
docker ps [OPTIONS] 查看正在运行的容器
OPTIONS说明(常用):
•-a : 查看所有容器(列出当前所有正在运行的容器+历史上运行过的)
•-l : 显示最近创建的容器。
•-n:显示最近n个创建的容器。
•-q : 静默模式,只显示容器编号。
•–no-trunc : 不截断输出。
[root@localhost ~]# docker ps --help
Usage: docker ps [OPTIONS]
List containers
Options:
-a, --all Show all containers (default shows just running)
-f, --filter filter Filter output based on conditions provided
--format string Pretty-print containers using a Go template
-n, --last int Show n last created containers (includes all states) (default -1)
-l, --latest Show the latest created container (includes all states)
--no-trunc Don't truncate output
-q, --quiet Only display container IDs
-s, --size Display total file sizes
新建并启动容器
docker run [OPTION] IMAGE [COMMAND][ARG...]
•–name=“容器新名字”: 为容器指定一个名称;
•-d: 后台运行容器,并返回容器ID,也即启动守护式容器;
•-i:以交互模式运行容器,通常与 -t 同时使用;
•-t:为容器重新分配一个伪输入终端,通常与 -i 同时使用;
•-P: 随机端口映射;将容器内部开放的网络端口随机映射到宿主机的一个端口上
•-p: 指定端口映射,一个指定端口上只可以绑定一个容器
容器实质是一种进程隔离的技术。容器为进程提供了一个隔离的环境,容器内的进程无法访问容器外的进程。
我们无法通过宿主机(安装docker的服务器)端口来直接访问容器的 ,因为docker容器自己隔离环境的端口与宿主机端口没有联系。如果外部想要访问容器,就必须得让容器中的端口与宿主机的端口建立联系,即容器端口映射。有了端口映射,就可以将宿主机端口与容器端口绑定起来,比如:我们建立宿主机的80端口与容器nginx80端口绑定起来,那么再访问宿主机80 就可以访问到对应的容器了。
使用选项 -p进行指定端口映射,有以下四种格式:
【-p 宿主机端口:容器端口】
docker run -it -d -p 127.0.0.1:5000:5000 docker.io/centos:latest /bin/bash
#镜像如果本地没有,则run命令会先下载镜像再运行容器
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ef9c03c5836f centos:latest "/bin/bash" 40 hours ago Up 20 minutes 127.0.0.1:5000->5000/tcp flamboyant_mirzakhani
docker run -it -d -p 127.0.0.1::4000 docker.io/centos:latest /bin/bash
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ba84ba307b80 centos:latest "/bin/bash" 9 seconds ago Up 7 seconds 127.0.0.1:49153->4000/tcp sharp_kirch
#会将容器的ip127.0.0.1和4000端口,随机映射到宿主机的一个端口上。
docker run -it -d -p 8000:80 docker.io/centos:latest /bin/bash
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3a2c00ffe426 centos:latest "/bin/bash" 3 seconds ago Up 1 second 0.0.0.0:8000->80/tcp, :::8000->80/tcp reverent_matsumoto
#上边的操作默认会绑定本地所有接口上的所有地址。
docker run -it --name mycentos 5d0da3dc9764
#(5d0da3dc9764为centos镜像ID)
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a6754d31e8e9 5d0da3dc9764 "/bin/bash" 3 minutes ago Up 3 minutes mycentos
现在已经新建好容器了,那怎么进入容器呢?
方式一:docker attach 容器ID
方式二:docker exec -it 容器ID /bin/bash(推荐)
进入正在运行的容器并以命令行交互:
1.直接进入容器启动命令的终端,不会启动新的进程
docker attach 容器名/容器ID
2.是在容器中打开新的终端,并且可以启动新的进程
docker exec -it 容器名/容器ID bashShell
OK,那进入容器之后又怎么退出容器呢?
从容器退出到自己宿主机(服务器)中
#容器停止并退出 未添加-d(持久化运行容器) 时 执行此参数 容器会被关闭(用ps命令查看不到,需要用ps -a命令进行查看并且可以发现STATUS为Exited)
exit
# 容器不停止退出 --- 无论是否添加-d 参数 执行此命令容器都不会被关闭
Ctrl + p + q
删除容器
#删除已停止容器
docker rm 容器ID
#强制删除容器
docker rm -f 容器ID
#删除一个容器
docker rm -f 容器名/容器ID
#删除多个容器
docker rm -f 容器名/容器ID 容器名/容器ID 容器名/容器ID
#删除全部容器
docker rm -f $(docker ps -aq)
容器常用操作命令
启动容器
docker start 容器ID/容器名
停止容器
docker stop 容器ID/容器名
重启容器
docker restart 容器ID/容器名
强制停止容器
docker kill 容器ID/容器名
查看容器日志
docker logs -f --tail 倒数几条 容器ID
查看容器内部细节
docker inspect 容器ID
容器拷贝文件
#无论容器是否开启 都可以进行拷贝
从容器内拷贝文件到主机上:
docker cp 容器ID:容器内路径 目标主机路径
更换容器名
docker rename 容器ID/容器名 新容器名