一、Docker 简介
1.1、Docker 简介
为了提高你对Docker的理解及兴趣,首先,我得先说说这玩意到底能干啥,举个简单的例子:
当你要部署数台 Nginx+PHP 或者 JRE 环境时,按照以往的老办法,你需要 ssh 连接每台机器,分别进行编译安装相关软件环境,费时费力,效率低下;然而现在,你可以通过 Docker 在本地构建一个 Nginx+PHP 或者 JRE 的镜像,然后将这些镜像分别分发至你要部署服务的机器上,这样不但能大大提高工作效率,同时也保证了开发、测试、线上环境的一致性。如果你使用传统方式部署一套服务,当服务器故障或者环境故障后,恢复起来一般是相当麻烦的(排除那种特别完善的系统架构),得各种排查定位问题、解决问题、故障恢复,这个过程应该是要花费点时间的;而如果你使用 Docker 部署一套服务,如果出现问题,你可以重新再启动一个Docker,至于问题排查,过后可以进行,这个过程一般也就几秒、十几秒,而且通过 Docker 编排工具,你可以实现自动故障恢复。
你可以想象成在你的服务器上运行了一个“虚拟机”,但是这个“虚拟机”跟平时我们所讲的“虚拟机”不一样的地方在于,它是运行在系统内核上的,所以,可以更高效的使用物理硬件资源,而且它要比“虚拟机”轻量级很多,这也使得它更加的灵活(但它并不是虚拟机,而是一种容器技术,这么说只是为了便于理解)。
Docker 是一个开源的应用容器引擎,Docker 具有可移植性和轻量级的特性,让开发者可以打包他们的应用以及依赖包到一个容器中,让后将此容器打包成镜像发布到其他运行了 Docker 的机器上,以供其他人使用,达到程序一致、环境一致、方便快捷的效果。
Docker 的容器是完全使用沙箱机制,相互之间不会有任何接口,这种隔离和安全性允许在一台主机上同时运行多个容器。
容器是轻量级的,因为它们直接在主机的内核中运行。这意味着,与使用虚拟机相比,你可以在同一台机器上运行更多的容器,甚至可以在虚拟机的主机中运行Docker容器!
我们经常说的Docker,实际上指的是 Docker Engine,即Docker 引擎,Docker Engine的组成部分:
- Docker Daemon:守护进程,它是长期运行的程序。
- Docker REST API:用于与守护进程进行通信,并指示其执行操作的接口。
- Docker Client :客户端,命令行界面(CLI)docker命令
- Docker Image :镜像
- Docker Container :容器
不懂没关系,下面会对这些概念做详细说明的。
Docker Client
使用 Docker REST API
通过脚本或命令来控制 Docker Daemon
或与其进行交互, Docker Daemon
创建并管理 Docker 对象,如 Docker Image
、Docker Container
、网络和卷。
Docker Engine的整体结构如下图所示
图片来自Docker
Docker的典型应用场景
- 自动化部署、打包应用
- 创建轻量、私密的 PAAS 环境
- 实现自动化测试和持续的集成/部署
- 部署与扩展webapp、数据库等服务
1.2、Docker 体系结构
- Docker Daemon
Docker 守护进程(dockerd
)监听Docker API请求并管理 Docker对象,如 镜像、容器、网络和数据卷。守护进程还可以与其他守护进程通信来管理Docker服务。
- Docker Client
Docker客户端(docker
)是用户与Docker交互的主要方式。当你使用命令时,如:docker run
,客户端就会发送这些命令给dockerd
,守护进程会将其执行。
Docker客户端是可以与多个守护进程进行通信的。
- Docker Registries
Docker Registries存储Docker镜像,你可以理解成像 GitHub 一样,我们可以在上面获取或发布资源。Docker Hub和Docker Cloud是任何人都可以使用的公共 Registries,并且 Docker 默认配置为在 Docker Hub即https://hub.docker.com/上查找镜像。
当你使用docker pull
或docker run
命令时,所需的镜像将从您配置的 Registries 中提取。当您使用docker push
命令时,您的镜像被推送到您配置的 Registries 中。
Docker对象Docker的对象包括:镜像,容器,网络,卷,插件和其他对象。本节简要介绍其中一些对象。
- 镜像-Image
镜像是一个只读的模板。通常,一个镜像是基于另一个镜像补充一些额外的自定义功能所构建的。
例如,您可以在 Docker Hub 上 pull 一个centos
镜像,然后安装 Nginx Web 服务器,并附带所需的配置文件,这样你便构建了一个基于centos
镜像的镜像。
构建新的镜像通常使用 Dockerfile 命令,后面会提到。
- 容器-Container
上面说过,image 是只读的,他负责应用的存储、分发,而 container 则是通过 image 创建的可读写的层,是 image 的可运行实例,负责运行应用程序。你可以使用 Docker Client (调用 Docker API或CLI ) 创建、启动、停止、移动或删除 container 。你可以将 container 连接到一个或多个网络,甚至可以根据其当前状态创建新 image。
默认情况下,容器与其他容器及其主机相对隔离。您可以控制容器的网络、存储或其他底层子系统与其他容器或主机的隔离程度。
- 总结
Docker使用客户端 – 服务器(C/S)体系结构。Docker Client 与 Docker Daemon 通信,Docker Daemon 负责对 Images、Docker Container 进行相关操作,如 获取/构建/分发新镜像、运行/停止/删除容器、查看镜像/容器详细信息 。
Docker客户端和守护进程可以在同一个系统上运行,也可以将Docker客户端连接到远程Docker守护进程。Docker客户端和守护进程使用REST API进行通信。
图片来自Docker
二、安装 Docker
2.1、安装要求
- 在 Linux 安装 Docker 需要内核版本不低于 3.10 ,建议 3.8 以上
- 必须是 64 位操作系统
不同操作系统安装方法可以看官方文档,很详细,https://docs.docker.com
本机使用 CentOS 7.3,详细信息为:
$ sudo cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core)
$ sudo uname -r
3.10.0-514.el7.x86_64
2.2、安装 Docker
- 官方推荐通过 设置Docker的源(repository) 进行安装和升级。
- 在测试和开发环境中,一些用户选择使用自动 脚本来安装Docker。
2.2.1、设置存储库
1.1、安装依赖
$ sudo yum install -y yum-utils device-mapper-persistent-data lvm2
1.2、添加稳定的 Docker 源
$ sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
2.2.2、安装Docker社区版
$ sudo yum install -y docker-ce
docker官方提供了脚本安装,你可以在服务器上运行如下命令安装dockercurl -fsSL get.docker.com -o get-docker.sh && sh get-docker.sh
2.2.3、启动Docker
$ sudo systemctl start docker
三、第一个 Docker 镜像跟容器
3.1、第一个 Docker 镜像
要获取 Docker ,可以使用命令 docker pull
在 Docker Registries 上拉取,格式如下 :
docker pull [OPTIONS] NAME[:TAG|@DIGEST] [flags]
Docker 各种命令有好多参数,你可以使用 –help 来查看
上面我们说过,Docker 是在 Docker Registries 上获取镜像的,所以我们可以去 Docker 默认的 Registries (即 https://hub.docker.com)去获取镜像。
首先获取一个简单的 Hello world 镜像(这是个很小的 Docker 镜像)。
打开网站后查找 “hello”,然后选择第一个,你便可以看到如下所示的一个页面,该页面提示你如何获取这个镜像
按照提示获取此镜像
$ sudo docker pull hello-world
Using default tag: latest //最新版本
latest: Pulling from library/hello-world //正在获取镜像
9bb5a5d4561a: Pull complete //获取完成
Digest: sha256:f5233545e43561214ca4891fd1157e1c3c563316ed8e237750d59bde73361e77 //摘要
Status: Downloaded newer image for hello-world:latest //状态
这里需要注意一下,国内用户从这个站点获取镜像资源可能会很慢,所以,国内有些厂商也开放了相应的 Docker Hub 镜像,如阿里云 、道客云、网易蜂巢等,你也可以在这里搜索你需要的镜像,这些站点会同步 Docker 官方的镜像。
查看获取到的镜像
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest e38bc07ac18e 2 days ago 1.85kB
由此可以看到我们成功获取到了这个镜像,而它的大小也只有 1.85 kb
3.2、运行第一个 Docker 容器
通过使用docker run
创建运行一个 container,格式为
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
$ sudo docker run hello-world
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/engine/userguide/
请对照前文第二张图片,详细阅读以上内容,以便加深对Docker工作模式的理解
请对照前文第二张图片,详细阅读以上内容,以便加深对Docker工作模式的理解
请对照前文第二张图片,详细阅读以上内容,以便加深对Docker工作模式的理解
3.3、查看 container 状态
$ sudo docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
$ sudo docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2c72e9c99b96 hello-world "/hello" 34 seconds ago Exited (0) 33 seconds ago happy_montalcini
上面两条命令,第一条是指 “查看当前运行的所有 container”;第二条指的是 “查看已经结束的和正在运行的所有容器”。因为 “hello-world” image打包的其实就是一个可执行文件,作用就是 print 第2点中显示的那些内容,不会作为后台程序执行,所以,当你运行这个容器后,它会自动退出。
四、Docker 化的 Nginx
4.1、获取 Nginx 镜像
通过在 Docker Hub 官网查询,得到了 Nginx 镜像的获取方法
你也可以通过 docker search 命令查找需要的镜像
# 查找镜像
$ sudo docker search nginx
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
nginx Official build of Nginx. 8341 [OK] jwilder/nginx-proxy Automated Nginx reverse proxy for docker con… 1316 [OK]
richarvey/nginx-php-fpm Container running Nginx + PHP-FPM capable of… 545 [OK]
# 获取镜像
$ sudo docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
2a72cbf407d6: Pull complete
04b2d3302d48: Pull complete
e7f619103861: Pull complete
Digest: sha256:18156dcd747677b03968621b2729d46021ce83a5bc15118e5bcced925fb4ebb9
Status: Downloaded newer image for nginx:latest
查看 Nginx 镜像
$ sudo docker images nginx
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest b175e7467d66 3 days ago 109MB
4.2、运行一个容器
$ sudo docker run -p 80:80 -d nginx
b1b5c2b5c0c5ff0e145a77281792a6f9057dd115438402931a629ec70fb28771
参数说明:
有一些参数我没加,你可以自己加上测试对比
- -d:后台运行。
- -p 80:80:容器的80端口映射到主机的80端口
- --name mynginx:将容器命名为mynginx
- -v $PWD/www:/www:将主机中当前目录下的www挂载到容器的/www
- -v $PWD/conf/nginx.conf:/etc/nginx/nginx.conf:将主机中当前目录下的nginx.conf挂载到容器的/etc/nginx/nginx.conf
- -v $PWD/logs:/wwwlogs:将主机中当前目录下的logs挂载到容器的/wwwlogs
检查容器是否运行成功
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b315e64b5e68 nginx "nginx -g 'daemon of…" 4 minutes ago Up 4 minutes 0.0.0.0:80->80/tcp silly_cori
# 使用curl命令访问本地80端口,检查Nginx服务是否正常运行
$ sudo curl 127.0.0.1 |grep Welcome
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 612 100 612 0 0 685k 0 --:--:-- --:--:-- --:--:-- 597k
<title>Welcome to nginx!</title>
<h1>Welcome to nginx!</h1>
4.3、进入容器操作
docker exec :与运行的容器进行交互,一般情况后跟 -it 参数使用,命令格式: docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
- -i : 即使没有附加也保持STDIN 打开
- -t : 分配一个伪终端
$ sudo docker exec -it b315e64b5e68 /bin/bash
root@b315e64b5e68:/# pwd
/
root@b315e64b5e68:/# ls
bin dev home lib64 mnt proc run srv tmp var
boot etc lib media opt root sbin sys usr
b315e64b5e68 是启动的 Nginx 容器的 ID,可以看出这是一个基于 Linux 的镜像
五、构建自己的 Docker 镜像
5.1、使用 Dcokerfile 构建新镜像
Dockerfile 也是一个大的知识点,本文就不详细介绍了。这个需要你自己去读官方文档或者查阅相关资料。
除了像上面介绍的那种方式来获取一个 Docker 化的 Nginx 镜像,你也可以自己制作,我们之前有说过,一个镜像是基于另一个镜像补充一些额外的自定义功能所构建的,这次,我们的目标是基于 CentOS 作为基础镜像,构建一个自己的 httpd 镜像
使用Dockerfile创建镜像需要用到一个命令 docker build
语法:docker build [OPTIONS] PATH | URL | -
1、Dockerfile 文件
$ sudo cat Dockerfile
FROM centos
MAINTAINER admin@xxx.com
RUN yum install -y httpd
EXPOSE 80
2、pull centos 基础镜像
$ sudo docker pull centos
3、构建 httpd 镜像
$ sudo docker build -t sasss/httpd .
-t 指定一个 tag,可以带上版本号
注意最后那个 “.”,表示在当前目录下获取 Dockerfile 文件
在这个过程中,你可以看到 docker 具体都做了哪些操作
4、查看构建好的 httpd 镜像
$ sudo docker images sasss/httpd
REPOSITORY TAG IMAGE ID CREATED SIZE
sasss/httpd latest 7d0ba5b27646 42 seconds ago 334MB
5、运行一个容器并运行 httpd 服务
$ sudo docker run --name http1 -it -p 8000:80 sasss/httpd /bin/bash
[root@0da77799e292 /]# /usr/sbin/httpd -k start
6、检查端口映射情况,端口是否处于
$ sudo netstat -lntup|grep 8000
tcp6 0 0 :::8000 :::* LISTEN 100407/docker-proxy
7、本地测试是否运行成功
# 使用 Ctrl+p+q 键让容器转在后台运行
# 然后在终端执行Curl命令,检查是否返回正确的信息
$ sudo curl 127.0.0.1:8000
5.2、通过手动修改容器创建镜像
1、pull centos 基础镜像,前面 pull 过的可以省略此步骤
$ sudo docker pull centos
2、进入镜像,安装 httpd 服务
$ sudo docker run --name httpdserver -it centos /bin/bash
[root@db8221cd115b /]# yum -y install httpd
- –name,为容器指定名称
3、退出容器,构建镜像
$ sudo docker commit httpdserver httpd
sha256:67f7c81a5bc8f75c4c74c4b4fdc6f5944fca6db87dd5bbca3186e594c2012580
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
httpd latest 67f7c81a5bc8 16 seconds ago 334MB
- docker commit,根据容器的更改创建新镜像
- 格式:docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
六、补充
当你运行过大量的 container 后,需要删除的时候,可以用如下方法
$ sudo docker rm $(docker container ls -aq)
- -aq 只获取每个 container 的 ID
- 通过 $取值,进而达到批量删除
另外,如果你当前列表中只有两个 container ,他们的 ID 分别是 “42e7f5623927” 和 “26eb41c428b6”,那么你如果要删除一个的话,不必将 ID 写全,只需要填写能区分要删除的 ID 和别的 ID 不同的首部即可,比如,你要删除第一个container,则只需执行 “# docker rm 4”
Docker 包含了大量的命令及大量参数,不可能一天两天就完全掌握,这个需要你在日后工作学习中,遇到不懂的地方及时查找资料解决问题,用以巩固所学知识,日复一日,自然熟练。
学习重要的一点就是找到一个好的学习方法,像 Docker 这种比较大的知识体系,一篇文章肯定没法完全的阐述清楚每个概念,也不可能覆盖到所有的知识点。
本文只是抛砖引玉,简单介绍了 Docker ,希望你能通过本文,掌握合适的学习方法,为 Docker 学习奠定一个小基础。
本文通过 慕课网 学习总结
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。