Docker的简单介绍

1、docker是什么?

docker 是一个开源的应用容器引擎,基于Go语言实现,属于操作系统层面的虚拟技术。

docker可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何安装有docker的电脑上。

容器是完全使用沙盒机制,相互之间不会有任何接口(类似 iphone 的 app),更重要的是容器性能开销较低

2、docker能够做什么?

docker可以解决虚拟机能够解决的问题,同时也能够解决虚拟机由于电脑资源要求过高而无法解决的问题

3、为什么使用docker

1更快速的交付和部署

对开发和运维员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。

例如:开发者可以使用一个标准的镜像来构建一套开发容器,开发完成之后,运维人员可以直接使用这个容器来部署代码。Docker 容器很轻很快!容器的启动时间是秒级的,大量地节约开发、测试、部署的时间。节约安装各种开发环境的软件的时间。解决开发环境和生产环境不一致的问题。

2、更轻松的迁移和扩展:

Docker 容器几乎可以在任意的平台上运行,包括物理机、虚拟机、公有云、私有云、个人电脑、服务器等。 这种兼容性可以让用户把一个应用程序从一个平台直接迁移到另外一个。

3、更高的资源利用率:

Docker 是容器技术,和虚拟机非常像,都可以在主机上隔离出多个独立的子系统,它们最大的区别在于虚拟机是从主机中完全隔离出一个系统来,而容器技术和主机是共享系统内核的。因为这些Docker 对系统资源的利用率很高,一台主机上可以同时运行数千个 Docker 容器。容器除了运行其中应用外,基本不消耗额外的系统资源,使得应用的性能很高,同时系统的开销尽量小。传统虚拟机方式运行 10 个不同的应用就要起 10 个虚拟机,而Docker 只需要启动 10 个隔离的应用容器即可。

总结:

Docker背后的想法是创建软件程序可移植的轻量级容器,让其可以在任何安装了Docker的机器上运行,并不用关心底层操作系统,就像野心勃勃的造船者们成功创建了集装箱而不需要考虑装在哪种船舶上一样。

只有一个共同目标:简化部署流程,提高生产力!

4、Docker快速体验-wordpress搭建

WordPress是使用PHP语言开发的博客平台,用户可以在支持PHP和MySQL数据库的服务器上架设属于自己的网站。也可以把 WordPress当作一个内容管理系统(CMS)来使用。
wordpress的运行环境已经全部打包好了,同时wordpress也被打包进去了,所以紧紧几个命令就可以搞定了。

首先下载mysql

1
docker pull mysql:5.7

*下载wordpress镜像 *

1
docker pull wordpress

*安装MySQL容器 *

1
docker run --name mysql -e MYSQL_ROOT_PASSWORD=admin -p 3306:3306 -d mysql:5.7

安装wordpress

1
docker run -itd --name wordpress -e WORDPRESS_DB_HOST=mysql -e WORDPRESS_DB_PASSWORD=admin -p 8080:80  --link  mysql:mysql -d wordpress

*访问wordpress *

1
localhost:8080或者127.0.0.1:8080

5、docker 项目架构

如果我们相对docker有个深入的理解我们必须先认识docker的项目架构

Docker使用C/S架构,通过docker客户端连接到Docker服务器上从而管理Docker服务器里面的镜像和容器,类似于git的架构。

6、Docker的基本概念

镜像(images)

Docker 镜像(Image)就是一个只读的模板。例如:一个镜像可以包含一个完整的操作系统环境,里面仅安装了 Apache 或用户需要的其它应用程序。镜像可以用来创建 Docker 容器,一个镜像可以创建很多容器。Docker 提供了一个很简单的机制来创建镜像或者更新现有的镜像,用户甚至可以直接从其他人那里下载一个已经做好的镜像来
直接使用。

容器(Conrainer)

Docker 利用容器(Container)来运行应用。容器是从镜像创建的运行实例。它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。可以把容器看做是一个易版的 Linux 环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。

文件系统隔离技术使得Docker成为了一个非常有潜力的虚拟化技术。在容器中可以对文件进行修改、删除、创建。

仓库(Registry)

仓库(Repository)是集中存放镜像文件的场所。有时候会把仓库和仓库注册服务器(Registry)混为一谈,并不严格区分。实际上,仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。

仓库分为公开仓库(Public)和私有仓库(Private)两种形式。最大的公开仓库是 Docker Hub,存放了数量庞大的镜像供用户下载。国内的公开仓库包括 时速云 、网易云 等,可以提供大陆用户更稳定快速的访问。当然,用户也可以在本地网络内创建一个私有仓库。

当用户创建了自己的镜像之后就可以使用 push 命令将它上传到公有或者私有仓库,这样下次在另外一台机器上使用这个镜像时候,只需要从仓库上 pull 下来就可以了。Docker 仓库的概念跟 Git 类似,注册服务器可以理解为GitHub 这样的托管服务。

Dockerfile

Dockerfile 是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。
一般用来定制镜像

Docker常用的指令和参数

一般我们都是用指令操作来操作docker的

常用指令

指令 说明
docker images 查看已下载的镜像
docker rmi 镜像名称:标签名 删除已下载的镜像
docker search 镜像 从官方仓库(hub.docker.com)查找镜像
docker pull 镜像名称:标签名 标签名默认是 latest,代表最新版本。
docker run 创建容器
docker ps 列出运行中的容器(运行中)
docker ps -a 列出未运行的容器
docker rm 容器名称 删除停止的容器
docker rm -f 容器名称 删除运行中的容器
docker start 容器名称 启动容器
docker stop 容器名称 停止容器
docker restart 容器名称 重启容器
docker exec 执行容器中的指令

常用参数

下载了镜像之后,我们就可以通过镜像来创建容器,创建容器时常用的参数是:

1
docker run --name 容器名称 -d -p 主机端口:容器内端口 -e 环境变量 --link 其它容器名:容器中别名 镜像名称:标签名

参数说明:

  • –name:指定容器名称

  • -d:容器在后台运行

  • -p:绑定端口号,容器内部的端口号无法在外部访问,必须经过绑定之后才可以访问

  • –link:连接其它容器,当要访问其它容器中的内容时,需要先链接才可以使用

  • -e:设置容器中的环境变量

Docker的常用操作

创建容器

创建一个 MySQL 容器,密码是123456,绑定本地 33306 端口到容器中 3306 端口:

1
docker run --name mysql01 -d -p 33306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7

说明:MYSQL_ROOT_PASSWORD 环境变量用来设置这个容器中 MySQL 的密码

创建之后,会启动这个容器,如果启动成功,就可以使用 docker ps 指令查看到:

启动之后,这个容器内部就运行了 MySQL 服务器,在容器内部监听的是 3306 端口,我们已经将这个端口绑定到了主机的 33306 端口上,所以我们在主机上可以使用 33306 端口连接

进入容器

有时我们需要进入到一个容器内部去操作这个容器,这时我们可以使用 docker exec 指令来实现。

docker exec 指令可以执行一个运行着的容器中的命令:

1
docker exec -it 容器名称 命令

我们可以通过执行 bash 指令进入容器:

1
docker exec -it mysql01 /bin/sh

-it:以实时交互的形式运行(和 -d 正好相反)

执行之后就进入到了容器中,然后我们输入的命令是在容器中执行的

执行 exit 指令可以退出容器。

链接容器

Docker 推荐我们一个容器中只运行一个主要的应用程序,比如,我们要运行一个 PHP + MySQL 的程序,那么我们应该把 PHP 和 MySQL 放到两个容器中

默认情况下,容器之间是不能直接通信的,如果要通信必须在创建 PHP 容器时使用 --link 参数建立和 MySQL 容器的链接

建立连接的参数说明:

1
--link 要连接的容器的名称 : 别名

在容器中可以使用别名来访问连接的容器。

比如,我们现在运行了一个叫做 mysql01 的容器,现在我们要创建一个 PHP 容器并和 MySQL 容器建立链接,指令应该是:

创建一个 PHP 容器,并且设置和 mysql01 容器建立连接,在 PHP 容器中连接的别名是 mysql

1
docker run --name php01 -d --link mysql01:mysql  php

创建了链接之后,就可以在容器中使用别名来通信了:

1
2
// 连接 mysql01 容器中的 MySQL 服务器
$pdo = new PDO('mysql:host=mysql:33306;dbname=xxx', 'root', '123456')

扩展:我们可以同时添加多个 –link 来同时连接多个容器,比如同时连接mysq01和redis01两个容器:

1
docker run --name php01 -d --link mysql01:mysql --link redis01:redis php

挂载硬盘

问题一、数据是保存在容器里的,如果容器删除了数据也就删除了。

问题二、每次要修改容器时,必须要进入到容器中去修改,比如要修改my.cnf。

为了能够保存(持久化)数据以及共享容器间的数据,Docker 提出了 Volume 的概念。

可以使用 -v 这个参数,将容器中的一个目录或者文件 和主机上的目录和文件进行绑定,绑定之后,修改主机上的这个文件就相当于修改了容器中的文件,删除容器之后,绑定的目录和文件还在主机(不会被删除)。

为了实现主机和容器之间的数据共享,我们可以在创建容器时添加 -v 参数:

1
docker run ... -v 主机目录:容器中的目录 ...

示例:创建 mysql 容器并将数据目录挂载到主机:

1
docker run --name mysql02 -d -v /home/home/code/docker-volume-data/testmysql:/var/lib/mysql -p 33307:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7.24

示例:启动一个 Nginx 服务器并将 nginx 的主目录搭载到主机上

1、下载 nginx

1
docker pull nginx:1.14.1-alpine

2、到容器中查看网站根目录的路径

1
2
docker run --name testnginx -d nginx:1.14.1-alpine   ## 创建容器
docker exec -it testnginx /bin/sh ## 进入容器

在容器中使用 vi 编辑器查看配置文件:

1
vi /etc/nginx/conf.d/default.conf

查看网站根目录是 usr/share/nginx/html

删除该容器

1
docker rm -f testnginx

3、创建 nginx 容器并将 /usr/share/nginx/html 挂载到本地

1
docker run --name nginx01 -d -p 30080:80 -v 本地目录:/usr/share/nginx/html nginx.1.14.1-alpine

复制文件

我们可以使用 docker cp 指令向容器中复制文件,或者从容器中复制文件到主机。

1
docker cp 源目录  目标目录
  • 复制主机文件到容器
    1
    docker cp C:/my.cnf mysql01:/etc/mysql/my.cnf
  • 从容器复制文件到主机
    1
    docker cp  mysql01:/etc/mysql/my.cnf C:/my.cnf

使用 Docker 搭建 LNMP 环境

平时在做开发时,为了简单、方便常用以下开发环境:
1、WAMP
2、Visual AMP\NMP
3、PHP 内置 WEB 服务器,如 php -S localhost:9999 -t 还有 Laravel 中的 php artisan serve --port 801
以上这三种只适用于开发时使用,在真正的线上环境我们需要安装更加稳定并且能够支撑高并发的运行环境,目前 PHP 的生产环境最常用的就是 LNMP

LNMP:Linux + Nginx + MySQL + PHP

Nginx

Nginx 是目前最流行的高性能、高并发的开源、免费的 WEB 服务器,俄罗斯人开发的。

Nginx 使用 Linux 中最流行的 epoll 做为事件处理机制,并且 Nginx 在运行时只消耗极少的系统资源,所以可以轻松实现上万的并发请求,Nginx 除了可以做为 WEB 服务器之外,还可以做为Email、反向代理、负载均衡、流媒体等服务器。
Nginx 和其它脚本语言(如PHP)一起工作时一般使用 FastCGI 机制。

方案

方案一、一个容器中同时运行 nginx php-mpm
​ 好处:简单、方便
​ 缺点:不利于每个软件的横向扩展
方案二、把 nginx、php-fpm、MySQL 分别放到三个容器中
​ 好处:有利于单独扩展每个系统
​ 缺点:部署相对复杂
我选择的是方案二

LNMP 模型图

创建三个容器:Nginx、PHP-FPM、MySQL,它们之间的关系是:
(说明:图中端口可以任意修改)

总结:Nginx 负载处理静态文件,如果用户访问的是 PHP 文件,就转发给 PHP 服务器的9000来处理,PHP服务器处理完之后,把结果返回给 nginx,然后nginx再返回给前端。

1、下载镜像

下载 nginx 镜像(alpine版的更小)

1
docker pull nginx:1.14-1-alpine

下载 MySQL 镜像

1
docker pull mysql:5.7

下载 PHP-FPM 镜像

1
docker pull php:7.2-fpm-alpine

2、创建容器

我们创建三个容器 Nginx、PHP-FPM、MySQL,这里需要注意的是它们创建的顺序:

MySQL => PHP-FPM => Nginx

创建 MySQL 容器

1
docker run --name mysql01 -d -p 33306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7

创建 php 容器

1
docker run --name phpfpm7.2 -d --link mysql01:mysql php:7.2-fpm-alpine

创建 nginx 容器

1
docker run --name nginx -d -p 8988:80 --link phpfpm7.2:php nginx:1.14.1-alpine

3、配置 Nginx
Nginx 只能对静态文件(html,css,js,图片等)进行处理,无法处理动态文件(php、python等),我们需要配置 nginx 将动态脚本转发给 PHP 服务器。
a. 进入 nginx 容器

1
docker exec -it nginx /bin/sh

b、查找配置文件位置

1
find / -name nginx.conf

c、修改 Nginx 的配置文件
/etc/nginx/conf.d/default.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
server {
...
location / {
root /usr/share/nginx/html; # 网站根目录
index index.html index.htm;
}

...
location ~ \.php$ {
fastcgi_pass php:9000; # 转发到 PHP 服务器的地址,PHP是容器的别名
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /php$fastcgi_script_name; # 转发的文件名
include fastcgi_params;
}
...
}

说明:
$fastcgi_script_name :代表当前访问的文件名,比如,如果访问的是 localhost/1.php ,那么这一项的值就是 1.php
d、退出 nginx 容器并重新启该容器
因为我们修改了 nginx 的配置文件,所以我们需要重启服务器

1
docker restart nginx

e、进入 phpfpm 容器创建 /php 目录
在 nginx 中我们配置了,当遇到 PHP 脚本时,就转发 /php$fastcgi_script_name; 这个路径到 php 容器,所以PHP会到它的 /php 目录下去查找,所以我们需要进入 PHP 创建中并创建这个目录。
进入PHP容器

1
docker exec -it phpfpm7.2 /bin/sh

进入容器之后,创建目录

1
mkdir /php

然后我们就可以在 /php 目录中创建 php 脚本了,这些脚本就可以通过浏览器运行访问了。
Nginx 运行PHP的流程:

a、nginx 判断访问的文件以 .php 结尾
b、nginx 将 /php/1.php 这个路径传给 PHP 的9000端口
c、PHP接收到nginx传过来的路径,就在本机中读取这个文件并运行
d、PHP将运行结果返回给 nginx
e、NGINX将结果返回给用户

两个问题

lnmp环境搭建好了,但是还有些问题需要考虑
1、为PHP容器中安装扩展
我们使用的是 PHP 默认的镜像,这个镜像中缺少很多必要的 PHP 扩展,比如 gd、redis、pdo_mysql 等,这些扩展都需要单独安装。
不过官方提供了安装扩展的两种方法:
​ 核心扩展(pdo_mysql,gd等) 使用 docker-php-ext-install
如安装 gd 库:(先进入PHP容器,然后执行以下命令)

1
docker-php-ext-install gd

​ 其它扩展(redis、yaf、swoole等)使用 pecl
如安装 redis:(先进入PHP容器,然后执行以下命令)

1
2
pecl install redis
docker-php-ext-enable redis

2、把两个容器代码的目录都绑定到一个目录中
现在我们需要把静态页保存到 nginx 容器中,然后把 php 脚本写到 php 容器中,这样在放代码时比较麻烦,所以我们可以将两个服务器的代码目录都绑定到本机,这样直接在本机就可以编写代码了。
a、在本机创建一代码目录
b、删除nginx容器重新创建一个新的容器

1
docker run --name nginx -d -p 8888:80 -v 本地目录:/usr/share/nginx/html --link phpfpm7.2:php nginx:1.14.1-alpine

通过 -v 我们就把 nginx 中网站根目录绑定球果一地的目录中了。
创建 nginx 容器之后,重新向前面一样修改一下 /etc/nginx/conf.d/default.conf 配置文件,然后重新启动即可。
c、删除PHP容器然后重新创建一个新的容器

1
docker run --name phpfpm7.2 -d -v 本地目录:/php --link mysql01:mysql php:7.2-fpm-alpine

 评论


本站使用 Material X 作为主题 , 总访问量为 次 。
隐藏