第一部分、Docker 入门

一、Docker 简介

1.1、Docker 简介

        为了提高你对Docker的理解及兴趣,首先,我得先说说这玩意到底能干啥,举个简单的例子:

        当你要部署数台 Nginx+PHP 或者 JRE 环境时,按照以往的老办法,你需要ssh连接每台机器分别进行编译安装,费时费力;然而现在,你可以通过 Docker 在本地构建一个 Nginx+PHP 或者 JRE 的镜像,然后将这些镜像分别分发至你要部署服务的机器上,大大提高工作效率,同时保证了环境的一致性。

        你可以想象成在你的服务器上运行了一个“虚拟机”,但是这个“虚拟机”跟平时我们所讲的“虚拟机”不一样的地方在于,它是运行在系统内核上的,所以,可以更高效的使用物理硬件资源,而且它要比“虚拟机”轻量级很多,这也使得它更加的灵活(但它并不是虚拟机,而是一种容器技术)。

        Docker 是一个开源的应用容器引擎,Docker 具有可移植性和轻量级的特性,让开发者可以打包他们的应用以及依赖包到一个容器中,然后发布到其他运行了 Docker 的机器上。

        Docker 的容器是完全使用沙箱机制,相互之间不会有任何接口,这种隔离和安全性允许在一台主机上同时运行多个容器。

        容器是轻量级的,因为它们直接在主机的内核中运行。这意味着,与使用虚拟机相比,你可以在同一台机器上运行更多的容器,甚至可以在虚拟机的主机中运行Docker容器!

Docker Engine的组成部分

  1. Docker Daemon:守护进程,它是长期运行的程序。
  2. Docker REST API:用于与守护进程进行通信,并指示其执行操作的接口。
  3. Docker Client :客户端,命令行界面(CLI)docker命令
  4. Docker Image :镜像
  5. Docker Container :容器
不懂没关系,下面会对这些概念做详细说明的。

Docker Client 使用 Docker REST API 通过脚本或命令来控制 Docker Daemon 或与其进行交互, Docker Daemon 创建并管理 Docker 对象,如 Docker ImageDocker Container,网络和卷。

Docker Engine的整体结构如下图所示

第一部分、Docker 入门_第1张图片

图片来自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 HubDocker Cloud是任何人都可以使用的公共 Registries,并且 Docker 默认配置为在 Docker Hubhttps://hub.docker.com/上查找镜像。

        当你使用docker pulldocker 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通过UNIX套接字或网络接口进行通信。

第一部分、Docker 入门_第2张图片

图片来自Docker

二、安装 Docker

2.1、安装要求

  1. 在 Linux 安装 Docker 需要内核版本不低于 3.10 ,建议 3.8 以上
  2. 必须是 64 位操作系统

不同操作系统安装方法可以看官方文档,很详细,https://docs.docker.com

本机使用 CentOS 7.3,具体为:

$ sudo cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core) 
$ sudo uname -a
Linux Docker 3.10.0-514.el7.x86_64 #1 SMP Tue Nov 22 16:42:41 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

2.2、安装 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官方提供了脚本安装,你可以在服务器上运行如下命令安装docker
curl -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 pull [OPTIONS] NAME[:TAG|@DIGEST] [flags]

        Docker 各种命令有好多参数,你可以使用 –help 来查看

        上面我们说过,Docker 是在 Docker Registries 上获取镜像的,所以我们可以去 Docker Hub 即https://hub.docker.com上查找获取镜像。

        首先获取一个简单的 Hello world 镜像(这是个很小的 Docker 化的例子)。

        打开网站后查找 “hello”,然后选择第一个,你便可以看到如下所示的一个页面,该页面提示你如何获取这个镜像

第一部分、Docker 入门_第3张图片

        按照提示获取此镜像

$ 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

Welcome to nginx!

Welcome to nginx!

4.3、进入容器操作

        docker exec :与运行的容器进行交互

        命令格式: docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

  • -d : 分离模式: 在后台运行
  • -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 [email protected]
RUN yum install -y httpd
EXPOSE 80

2、pull centos 基础镜像

$ sudo docker pull centos

3、构建 httpd 镜像

$ sudo docker build -t sasss/httpd .
        注意最后那个 “.”,表示在当前目录下获取 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 学习奠定一个小基础。


本文通过 慕课网 学习总结

更详细的内容,可通过Docker官网,或者菜鸟教程学习

你可能感兴趣的:(docker,devops)