Docker 入门
容器技术是和我们的宿主机共享硬件资源及操作系统,可以实现资源的动态分配。
容器包含应用和其所有的依赖包,但是与其他容器共享内核。
容器在宿主机操作系统中,在用户空间以分离的进程运行。
通过使用容器,我们可以轻松打包应用程序的代码、配置和依赖关系,将其变成容易使用的构建块,从而实现环境一致性、运营效率、开发人员生产力和版本控制等诸多目标。
Docker 属于 Linux 容器的一种封装,提供简单易用的容器使用接口。它是目前最流行的 Linux 容器解决方案。
而 Linux 容器是 Linux 发展出的另一种虚拟化技术,简单来讲, Linux 容器不是模拟一个完整的操作系统,而是对进程进行隔离,相当于是在正常进程的外面套了一个保护层。
对于容器里面的进程来说,它接触到的各种资源都是虚拟的,从而实现与底层系统的隔离。
Docker 将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。
总体来说,Docker 的接口相当简单,用户可以方便地创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。
Docker 中包括三个基本的概念:
Image(镜像)
Container(容器)
Repository(仓库)
Image(镜像)
镜像是 Docker 运行容器的前提,仓库是存放镜像的场所,可见镜像更是 Docker 的核心。
镜像可以看作是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。
镜像不包含任何动态数据,其内容在构建之后也不会被改变。镜像(Image)就是一堆只读层(read-only-layer)的统一视角,也许这个定义有些难以理解,下面的这张图能够帮助读者理解镜像的定义:
统一文件系统(Union File System)技术能够将不同的层整合成一个文件系统,为这些层提供了一个统一的视角。这样就隐藏了多层的存在,在用户的角度看来,只存在一个文件系统。
Container(容器)
容器(Container)的定义和镜像(Image)几乎一模一样,也是一堆层的统一视角,唯一区别在于容器的最上面那一层是可读可写的。
由于容器的定义并没有提及是否要运行容器,所以实际上,容器 = 镜像 + 读写层。
Repository(仓库)
Docker 仓库是集中存放镜像文件的场所。镜像构建完成后,可以很容易的在当前宿主上运行。
如果需要在其他服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry(仓库注册服务器)就是这样的服务。
Docker的安装和使用
官方文档获取最新的 Docker 支持情况
https://docs.docker.com/install/。
Docker 对于内核支持的功能,即内核的配置选项也有一定的要求
(比如必须开启 Cgroup 和 Namespace 相关选项,以及其他的网络和存储驱动等)。
Docker CE 的安装请参考官方文档:
MacOS:https://docs.docker.com/docker-for-mac/install/
Windows:https://docs.docker.com/docker … tall/
Ubuntu:https://docs.docker.com/instal … untu/
Debian:https://docs.docker.com/instal … bian/
CentOS:https://docs.docker.com/instal … ntos/
Fedora:https://docs.docker.com/instal … dora/
其他 Linux 发行版:https://docs.docker.com/instal … ries/
例如:
由于 Docker-CE 支持 64 位版本的 CentOS 7 ,并且要求内核版本不低于 3.10,首先我们需要卸载掉旧版本的
$ sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-selinux \docker-engine-selinux \docker-engine
#我们执行以下安装命令去安装依赖包:
yum install -y yum-utils \device-mapper-persistent-data \lvm2yum install docker
检验是否安装成功
docker versionordocker info
启动 Docker-CE:
systemctl enable docker
systemctl start docker
我们直接运行下面的命令,将名为 hello-world 的 image 文件从仓库抓取到本地:
docker pull library/hello-world
抓取成功以后,就可以在本机看到这个 image 文件了:
docker images
现在,我们可以运行 hello-world 这个 image 文件:
docker run hello-world
当镜像通过 RUN 命令运行成功后,这个运行的镜像就是一个 Docker 容器啦。
容器可以理解为一个轻量级的沙箱,Docker 利用容器来运行和隔离应用,容器是可以被启动、停止、删除的,这并不会影响 Docker 镜像。
Docker 使用的是 C/S 结构,即客户端/服务器体系结构。
Docker 的核心组件包括:
- Docker Client
- Docker Daemon
- Docker Image
- Docker Registry
- Docker Container
Docker Client ,也称 Docker 客户端。它其实就是 Docker 提供命令行界面(CLI)工具
Docker Daemon 是服务器组件,以 Linux 后台服务的方式运行,是 Docker 最核心的后台进程,我们也把它称为守护进程。
Docker Daemon 的架构如下所示:
Docker Daemon 运行在 Docker Host 上,负责创建、运行、监控容器,构建、存储镜像。运行过程的作用有以下几种可能:
向 Docker Registry 获取镜像。
通过 GraphDriver 执行容器镜像的本地化操作。
通过 NetworkDriver 执行容器网络环境的配置。
通过 ExecDriver 执行容器内部运行的执行工作。
1、启动 Docker Daemon:
#启动 Docker Daemon 时,一般可以使用以下命令来完成:docker --daemon = truedocker –d
docker –d = true
2、重启 Docker Daemon:
systemctl daemon-reload
systemctl restart docker.service
3、我们通过以下命令即可实现与远程服务器通信:
docker -H 服务器IP地址 info
-H 是用来指定服务器主机,info 子命令用于查看 Docker 服务器的信息。
Docker Image
Docker 镜像可以看作是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。
镜像不包含任何动态数据,其内容在构建之后也不会被改变。我们可将 Docker 镜像看成只读模板,通过它可以创建 Docker 容器。
镜像有多种生成方法:
- 从无到有开始创建镜像
- 下载并使用别人创建好的现成的镜像
- 在现有镜像上创建新的镜像
我们可以将镜像的内容和创建步骤描述在一个文本文件中,这个文件被称作 Dockerfile ,通过执行 docker build <docker-file>命令可以构建出 Docker 镜像。
Docker Registry
Docker Registry 是存储 Docker Image 的仓库
Docker Daemon 负责Get/Put 该文本文件
运行 docker push、docker pull、docker search 时,实际上是通过 Docker Daemon 与 Docker Registry 通信。
Docker Container
Docker 容器就是 Docker 镜像的运行实例,是真正运行项目程序、消耗系统资源、提供服务的地方。
Docker Container 提供了系统硬件环境,我们可以使用 Docker Images 这些制作好的系统盘,再加上我们所编写好的项目代码,Run 一下就可以提供服务啦。
容器启动过程如下:
- Docker 客户端执行 docker run 命令。
- Docker Daemon 发现本地没有 hello-world 镜像。
- Daemon 从 Docker Hub 下载镜像。
- 下载完成,镜像 hello-world 被保存到本地。
- Docker Daemon 启动容器。
可以通过 Docker Images 可以查看到 hello-world 已经下载到本地 可以通过 Docker Ps 或者 Docker
Container ls 显示正在运行的容器
Docker的常用命令
docker pull image_name
docker pull centos:latest
docker images
docker ps -a
docker start container_name/container_id
docker restart container_name/container_id
docker stop container_name/container_id
docker attach container_name/container_id #进入容器
docker stop container_name/container_id
docker run -t -i container_name/container_id /bin/bash
docker rm container_name/container_id
docker rmi image_name
Dockerfile 常用的指令
- 由于 Dockerfile 中所有的命令都是以下格式:INSTRUCTION argument
,指令(INSTRUCTION)不分大小写.
FROM
用于指定基础的 images ,一般格式为 FROM <image> or FORM <image>:<tag>。
所有的 Dockerfile 都应该以 FROM 开头,FROM 命令指明 Dockerfile 所创建的镜像文件以什么镜像为基础,FROM 以后的所有指令都会在 FROM 的基础上进行创建镜像。
可以在同一个 Dockerfile 中多次使用 FROM 命令用于创建多个镜像。比如我们要指定 Python 2.7 的基础镜像,我们可以像如下写法一样:FROM python:2.7
MAINTAINER
MAINTAINER 是用于指定镜像创建者和联系方式,一般格式为 MAINTAINER <name>。
COPY
COPY 是用于复制本地主机的 <src> (为 Dockerfile 所在目录的相对路径)到容器中的 <dest>。
当使用本地目录为源目录时,推荐使用 COPY 。一般格式为 COPY <src><dest> 。
例如我们要拷贝当前目录到容器中的 /app 目录下,我们可以这样操作:COPY . /app
WORKDIR
可以设置多次,如果是相对路径,则相对前一个 WORKDIR 命令。默认路径为/。一般格式为 WORKDIR /path/to/work/dir。
例如我们设置 /app 路径,我们可以进行如下操作:
WORKDIR /app
RUN
RUN 用于容器内部执行命令。每个 RUN 命令相当于在原有的镜像基础上添加了一个改动层,原有的镜像不会有变化。一般格式为 RUN <command>。
例如我们要安装 Python 依赖包,我们做法如下:
RUN pip install -r requirements.txt
EXPOSE
EXPOSE 命令用来指定对外开放的端口。一般格式为 EXPOSE <port> [<port>…]。
例如上面那个例子,开放5000端口:
EXPOSE 5000
ENTRYPOINT
ENTRYPOINT 可以让你的容器表现得像一个可执行程序一样。一个 Dockerfile 中只能有一个 ENTRYPOINT,如果有多个,则最后一个生效。
我们要将 Python 镜像变成可执行的程序,我们可以这样去做:
ENTRYPOINT ["python"]
CMD
CMD 命令用于启动容器时默认执行的命令,CMD 命令可以包含可执行文件,也可以不包含可执行文件。
例如我们要启动 /app ,我们可以用如下命令实现:
CMD ["app.py"]
一个 Dockerfile 中只能有一个 CMD,如果有多个,则最后一个生效。而 CMD 的 Shell 形式默认调用 /bin/sh -c 执行命令。
CMD 命令会被 Docker 命令行传入的参数覆盖:docker run busybox /bin/echo Hello Docker 会把 CMD 里的命令覆盖。
构建 Dockerfile
mkdir static_web
cd static_web
touch Dockerfile
然后 vi Dockerfile 开始编辑该文件,输入 i 开始编辑。以下是我们构建的 Dockerfile 内容:
FROM nginx
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
docker build -t angelkitty/nginx_web:v1 .
-t 是为新镜像设置仓库和名称
angelkitty 为仓库名
nginx_web 为镜像名
:v1 为标签(不添加为默认 latest )
docker run --name nginx_web -d -p 8080:80 angelkitty/nginx_web:v1
这条命令会用 Nginx 镜像启动一个容器,命名为 nginx_web ,并且映射了 8080 端口。
这样我们可以用浏览器去访问这个 Nginx 服务器:http://localhost:8080/ 或者 http://本机的 IP 地址:8080/,页面返回信息: