docker compose实战部署django

第一步,因为应用将要运行在一个满足所有环境依赖的 Docker 容器里面,那么我们可以通过编辑 Dockerfile 文件来指定 Docker 容器要安装内容。内容如下:

FROM python:3

ENV PYTHONUNBUFFERED 1

RUN mkdir /code

WORKDIR /code

ADD requirements.txt /code/

RUN pip install -r requirements.txt

ADD . /code/

第二步,在 requirements.txt 文件里面写明需要安装的具体依赖包名。

Django>=1.8,<2.0

psycopg2

第三步, docker-compose.yml 文件将把所有的东西关联起来。它描述了应用的构成(一个web 服务和一个数据库)、使用的 Docker 镜像、镜像之间的连接、挂载到容器的卷,以及服务开放的端口。

version: "3"

services:

    db:

        image: postgres

    web:

        build: .

        command: python3 manage.py runserver 0.0.0.0:8000

        volumes:

            – .:/code

        ports:

            – "8000:8000"

        links:

            – db

现在我们就可以使用 docker-compose run 命令启动一个 Django 应用了。

$ docker-compose run web django-admin.py startproject django_example .

Compose 会先使用 Dockerfile 为 web 服务创建一个镜像,接着使用这个镜像在容器里运行django-admin.py startproject composeexample 指令。这将在当前目录生成一个 Django 应用。

$ ls

Dockerfile docker-compose.yml django_example manage.py requ

irements.txt

如果你的系统是 Linux,记得更改文件权限。

sudo chown -R $USER:$USER .

首先,我们要为应用设置好数据库的连接信息。用以下内容替换 django_example/settings.py文件中 DATABASES = … 定义的节点内容。

DATABASES = {

    'default': {

        'ENGINE': 'django.db.backends.postgresql',

         'NAME': 'postgres',

         'USER': 'postgres',

         'HOST': 'db',

         'PORT': 5432,

    }

}

这些信息是在 postgres 镜像固定设置好的。然后,运行 docker-compose up :

$ docker-compose up

django_db_1 is up-to-date

Creating django_web_1 …

Creating django_web_1 … done

Attaching to django_db_1, django_web_1

db_1 | The files belonging to this database system will be owned by user "postgres".

db_1 | This user must also own the server process.

db_1 |

db_1 | The database cluster will be initialized with locale "en_US.utf8".

db_1 | The default database encoding has accordingly been set to "UTF8".

db_1 | The default text search configuration will be set to "english".

web_1 | Performing system checks…

web_1 |

web_1 | System check identified no issues (0 silenced).

web_1 |

web_1 | November 23, 2017 – 06:21:19

web_1 | Django version 1.11.7, using settings 'django_example.settings'

web_1 | Starting development server at http://0.0.0.0:8000/

web_1 | Quit the server with CONTROL-C.

这个 Django 应用已经开始在你的 Docker 守护进程里监听着 8000 端口了。打开127.0.0.1:8000 即可看到 Django 欢迎页面。

你还可以在 Docker 上运行其它的管理命令,例如对于同步数据库结构这种事,在运行完docker-compose up 后,在另外一个终端进入文件夹运行以下命令即可:

$ docker-compose run web python manage.py syncdb

Docker Compose 常用命令

docker-compose 命令

大多数Compose命令都是运行于一个或多个服务的,如果服务没有指定,该命令将会应用到所有服务,如果要获得所有可用信息,使用命令:docker-compose [COMMAND] –help

build
创建或者再建服务
服务被创建后会标记为project_service(比如composetest_db),如果改变了一个服务的Dockerfile或者构建目录的内容,可以使用docker-compose build来重建它

help
显示命令的帮助和使用信息

kill
通过发送SIGKILL的信号强制停止运行的容器,这个信号可以选择性的通过,比如:
docker-compose kill -s SIGKINT

logs
显示服务的日志输出

logs 后面什么都不加,则输出该项目所有服务的日志信息

docker-compose logs SERVICE 则输出该服务的日志信息

port

为端口绑定输出公共信息

ps
显示容器

pull
拉取服务镜像

rm
删除停止的容器

run
在服务上运行一个一次性命令,比如:
docker-compose run web python manage.py shell

scale
设置为一个服务启动的容器数量,数量是以这样的参数形式指定的:service=num,比如:
docker-compose scale web=2 worker=3

start
启动已经存在的容器作为一个服务

stop
停止运行的容器而不删除它们,它们可以使用命令docker-compose start重新启动起来

up
为一个服务构建、创建、启动、附加到容器
连接的服务会被启动,除非它们已经在运行了
默认情况下,docker-compose up会集中每个容器的输出,当存在时,所有的容器会停止,运行docker-compose up -d会在后台启动容器并使它们运行

top

显示容器中运行的进程

选项

–verbose
显示更多输出

–version
显示版本号并退出

-f,–file FILE
指定一个可选的Compose yaml文件(默认:docker-compose.yml)

-p,–project-name NAME
指定可选的项目名称(默认:当前目录名称)

使用 Docker Compose 本地部署基于 Sentinel 的高可用 Redis 集群

说明

项目地址:github.com/TomCzHen/re…

根据官方文档 Redis Sentinel Documentation 中的 Example 2: basic setup with three boxes 示例创建的实例,但因为是单机部署,所以不满足 Redis 实例 与 Sentinel 实例分别处于 3 台机器的要求,因此仅用于开发环境测试与学习。

使用方法

  • 使用 docker-compose up -d 部署运行。

  • 使用 docker-compose pause master 可以模拟对应的 Redis 实例不可用。

  • 使用 docker-compose pause sentinel-1 可以模拟对应的 Sentinel 实例不可用。

  • 使用 docker-compose unpause service_name 将暂停的容器恢复运行。

  • 使用支持 Sentinel 的客户端连接 localhost:62379 进行应用测试。

注:Windows 和 Mac 可能需要修改 Volumes 挂载参数。

注意事项

Sentinel, Docker, NAT, and possible issues

https://redis.io/topics/sentinel#sentinel-docker-nat-and-possible-issues

将容器端口 EXPOSE 时,Sentinel 所发现的 master/slave 连接信息(IP 和 端口)对客户端来说不一定可用。

例如:将 Reids 实例端口 6379 EXPOSE 为 16379, Sentinel 容器使用 LINK 的方式访问 Redis 容器,那么对于 Sentinel 容器 6379 端口是可用的,但对于外部客户端是不可用的。

解决方法是 EXPOSE 端口时保持内外端口一致,或者使用 host 网络运行容器。如果你想使用本项目中的编排文件部署的集群对外部可用,那么只能将 Redis 容器运行在 host 网络之上。

注:实际上 bridge 模式下 Redis 性能也会受到影响。

文件结构

.
├── docker-compose.yaml
├── nginx
│   └── nginx.conf
├── README.md
├── .env
└── sentinel
    ├── docker-entrypoint.sh
    ├── Dockerfile-sentinel
    └── sentinel.conf.sample

Sentinel

镜像使用 Dockerfile-sentinel 构建,运行时根据环境变量生成 sentinel.conf 文件,详细配置说明请查看 sentinel.conf.sample 内容。

docker-entrypoint.sh

使用 Reids 官方镜像中的 docker-entrypoint.sh 脚本修改而来,添加了生成 sentienl.conf 语句。

...
# create sentinel.conf
if [ ! -e ${SENTINEL_CONF_PATH} ]; then
    envsubst < /etc/redis/sentinel.conf.sample > ${SENTINEL_CONF_PATH}
    chown redis:redis /etc/redis/sentinel.conf
fi
...

修改配置 Sentinel 的环境变量后需要重新创建容器才能生效。

可用环境变量

SENTINEL_CONF_PATH=/etc/redis/sentinel.conf
SENTINEL_PORT=26379
SENTINEL_MASTER_NAME=redis-master
SENTINEL_REDIS_IP=127.0.0.1
SENTINEL_REDIS_PORT=6379
SENTINEL_REDIS_PWD=
SENTINEL_QUORUM=2
SENTINEL_DOWN_AFTER=30000
SENTINEL_PARALLEL_SYNCS=1
SENTINEL_FAILOVER_TIMEOUT=180000

docker-compose.yaml

可以使用 docker-compose config 可查看完整的编排内容。

Redis 实例运行参数

详细可用参数请查看官方示例文件 Redis Configuration File Example,需要注意 port 参数需要与编排中的 PORTS 保持一致,或修改编排文件让容器网络使用 host 模式。

由于 master 会被 Sentinel 切换为 slave ,因此最好保持每个 Redis 实例的口令一致。

master:
    image: redis:4.0.8-alpine
    ports:
      - 6379:6379
    volumes:
      - type: volume
        source: master-data
        target: /data
    command: [
      '--requirepass "${REDIS_PWD}"',
      '--masterauth "${REDIS_PWD}"',
      '--maxmemory 512mb',
      '--maxmemory-policy volatile-ttl',
      '--save ""',
    ]

Sentinel 实例运行参数

详细可用参数请查看 sentinel 目录下的 sentinel.conf.sample 文件。由于容器使用的配置文件是运行时根据环境变量生成的,因此使用 environment 进行配置,可用环境变量请查看文档 Sentinel 部分。

最后使用了 Nginx 作为 Sentinel 实例的代理,因此 Sentinel 容器不需要对外访问。

sentinel-1: &sentinel
    build:
      context: ./sentinel
      dockerfile: Dockerfile-sentinel
    image: redis-sentinel:dev
    environment:
      - SENTINEL_REDIS_PWD=${REDIS_PWD}
      - SENTINEL_REDIS_IP=${SENTINEL_MASTER_NAME}
      - SENTINEL_QUORUM=2
      - SENTINEL_DOWN_AFTER=3000
    command: [
      '${SENTINEL_CONF_PATH}',
      '--sentinel'
    ]
    depends_on:
      - master
      - node-1
      - node-2
    links:
      - master:${SENTINEL_MASTER_NAME}
      - node-1
      - node-2
  sentinel-2:
    <<: *sentinel
  sentinel-3:
    <<: *sentinel

Nginx

使用 Nginx 作为 Sentinel 负载均衡以及高可用代理。

  nginx:
    image: nginx:1.13.9-alpine
    ports:
      - 26379:26379
    volumes:
      - type: bind
        source: ./nginx/nginx.conf
        target: /etc/nginx/nginx.conf
        read_only: true
    depends_on:
      - sentinel-1
      - sentinel-2
      - sentinel-3

修改 nginx 目录下的 nginx.conf 进行配置。

...
stream {
    server {
        listen 26379;
        proxy_pass redis_sentinel;
    }

    upstream redis_sentinel {
        server sentinel-1:26379;
        server sentinel-2:26379;
        server sentinel-3:26379;
    }
}
...

你离ELK只有一句docker-compose的距离

未分类

引言

刚接触Elk的时候,我用github.com/deviantony/…,部署了第一个测试环境,这是一个很优秀的项目,几乎没什么配置就可以部署成功。
但有一个问题就是对于一个初学者如此洁净的环境,我完全不知道从何入手,也弄不清这个框架的优势是什么(连个Dashboard样本都没有)。还有 x-pack 的配置,metricbeat 的接入都踩过不少坑,才部署成一个像样的学习环境。之后在写 docker-compose.yml 脚本的时候又是各种踩雷,终于实现了快速一键部署。同时支持 DaoCloud 的 Stack 脚本 持续集成
在这里分享给大家,好像想入坑的同学少走些弯路。

你需要准备什么

一个 docker 环境, 还有…… 没了

注:win 和 macOS 下不支持 docker-metricbeat 的 system 监控,需手动关闭

我要怎么做

在这里看下注意事项

本地部署

$ git clone "https://github.com/wilfordw/docker-elk-example.git"
$ cd docker-elk-example
$ docker-compose up -d

DaoCloud Stack 部署

先下载项目到服务器,复制项目绝对路径

$ git clone "https://github.com/wilfordw/docker-elk-example.git"
$ cd docker-elk-example
$ pwd

把 dao-docker-compose.yml 内容复制进 Stack 的 YAML, 把上面克隆项目的 pwd 替换里面的 /root/app/docker-elk/, 点击部署就可以

想要自己创建镜像也可以,把你创建好的镜像地址替换 yml 里的 image

部署完可以看到什么?

未分类

未分类

未分类

未分类

未分类

未分类

继续更新

目前只做了 System Docker Nginx 的监控案列, 之后会继续集成

  • Metricbeat Mysql 监听
  • Metricbeat NodeJs 监听
  • Metricbeat Golang 监听
  • Metricbeat Kubernetes 监听
  • X-pack 权限解析
  • ELK 集群

docker-compose中启动镜像失败的问题

正常的docker run启动

java:8u111-jdk是java官方镜像,如下命令可以成功启动一个该镜像的容器:

docker run --name test001 -idt java:8u111-jdk

以上命令创建的容器,可用docker exec -it test001 /bin/bash进入容器,执行我们所需的操作;

docker-compose启动失败

这里写个最简单的docker-compose.yml,然后用docker-compse,内容如下:

master:
  image: java:8u111-jdk

在此文件所在目录下执行docker-compose up -d启动容器,再执行docker ps -a查看容器状态,信息如下所示:

root@rabbitmq:/usr/local/work/test# docker-compose up -d
Creating test_master_1 ... done
root@rabbitmq:/usr/local/work/test# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS                          PORTS               NAMES
bb433fe9984d        java:8u111-jdk      "/bin/bash"         About a minute ago   Exited (0) About a minute ago                       test_master_1

信息显示我们启动的容器状态为Exited (0) About a minute ago,也就是说虽然创建了容器,但是该容器并未正常运行;

控制终端缺失

启动失败是因为缺失了控制终端的配置,这里有两种方式修复;

使用tty参数(推荐使用)

修改docker-compose.yml,增加一个配置tty:true,如下:

master:
  image: java:8u111-jdk
  tty: true

先执行docker-compose down将之前的容器删除,再执行docker-compose up -d启动,可以发现启动成功,并且可以成功进入容器进行操作:

root@rabbitmq:/usr/local/work/test# docker-compose up -d
Creating test_master_1 ... done
root@rabbitmq:/usr/local/work/test# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
f51debaa26ec        java:8u111-jdk      "/bin/bash"         2 seconds ago       Up 2 seconds                            test_master_1
root@rabbitmq:/usr/local/work/test# docker exec -it test_master_1 /bin/bash
root@f51debaa26ec:/# java -version
openjdk version "1.8.0_111"
OpenJDK Runtime Environment (build 1.8.0_111-8u111-b14-2~bpo8+1-b14)
OpenJDK 64-Bit Server VM (build 25.111-b14, mixed mode)

使用exec重新创建容器(不推荐)

这种方式并不推荐,因为这样做虽然可以启动容器,但是只能重新创建一个容器,具体方法如下:

  1. 使用docker-compose up -d命令启动后,由于没有tty:true的配置,容器就退出了;

  2. 这时候执行命令docker-compose run master /bin/bash,会创建一个容器,并且进入这个容器;

  3. 在当前电脑再打开一个控制台,执行docker ps命令,发现新建了一个容器,状态正常;

ubuntu16.04安装最新版docker、docker-compose、docker-machine

安装前说明:

本文将介绍在ubuntu16.04系统下安装和升级docker、docker-compose、docker-machine。

docker:有两个版本:docker-ce(社区版)和docker-ee(企业版)。

    笔者这里介绍安装或升级的是最新版docker-ce(社区版)。

    参考官网地址:https://docs.docker.com/engine/installation/linux/docker-ce/ubuntu/#os-requirements

docker-compse:可运行和管理多个docker容器。

docker-machine:docker官方提供的docker管理工具。可管理多个docker主机,可搭建swarm集群。

一、docker安装

1、卸载旧版本docker

全新安装时,无需执行该步骤

$ sudo apt-get remove docker docker-engine docker.io

2、更新系统软件

$ sudo apt-get update

3、安装依赖包

$ sudo apt-get install 
    apt-transport-https 
    ca-certificates 
    curl 
    software-properties-common

4、添加官方密钥

执行该命令时,如遇到长时间没有响应说明网络连接不到docker网站,需要使用代-理进行。

$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

显示OK,表示添加成功.

5、添加仓库

$ sudo add-apt-repository 
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu 
   $(lsb_release -cs) 
   stable"

6、再次更新软件

经实践,这一步不能够省略,我们需要再次把软件更新到最新,否则下一步有可能会报错。

$ sudo apt-get update

7、安装docker

如果想指定安装某一版本,可使用 sudo apt-get install docker-ce= 命令,把替换为具体版本即可。

以下命令没有指定版本,默认就会安装最新版

$ sudo apt-get install docker-ce

8、查看docker版本

$ docker -v

显示“Docker version 17.09.0-ce, build afdb6d4”字样,表示安装成功。

二、docker-compose安装

1、下载docker-compose

$ sudo curl -L https://github.com/docker/compose/releases/download/1.17.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

2、授权

$ sudo chmod +x /usr/local/bin/docker-compose

3、查看版本信息

$ docker-compose --version

显示出版本信息,即安装成功。

三、docker-machine安装

说明:docker-machine的使用是要基于virtualBox的。如果没有安装安装过,请先安装virtualBox。

1、安装virtualBox

登录virtualBox官网:https://www.virtualbox.org/wiki/Linux_Downloads

找到”Ubuntu 16.04 (“Xenial”) i386 | AMD64″字样,点击“AMD64”进行下载。

下载后,执行以下命令进行安装:

$ sudo dpkg -i virtualbox-5.2_5.2.0-118431_Ubuntu_xenial_amd64.deb

2、下载并安装docker-machine

$ curl -L https://github.com/docker/machine/releases/download/v0.13.0/docker-machine-`uname -s`-`uname -m` >/tmp/docker-machine &&
chmod +x /tmp/docker-machine &&
sudo cp /tmp/docker-machine /usr/local/bin/docker-machine

3、查看版本信息

$ docker-machine version

显示出版本信息,即安装成功。

用 Docker Compose 搭建 Rails 开发环境

Docker 是目前最热门的容器格式,Docker Compose 是用于管理包含多个 Docker 容器的应用的工具,借助 Docker 和 Docker Compose,我们可以轻松搭建可复现的开发环境。

这篇教程展示如何从零开始用 Docker Compose 搭建 Rails/PostgreSQL 开发环境。

本文主要参考了 Quickstart: Compose and Rails。但原文有一点问题,于是我加上自己的见解写成这篇博客。

安装 Docker

首先,需要在自己的开发机上安装 Docker,你可以在 https://www.docker.com/ 找到适合自己操作系统的 Docker 安装方式。

安装完毕后,可以在命令行中使用 docker 命令:

$ docker --version
Docker version 17.03.1-ce, build c6d412e

创建项目

创建项目目录:

$ mkdir myapp
$ cd myapp

接着,创建一个 Gemfile 文件,包含以下内容:

source 'https://rubygems.org'

gem 'rails', '5.1.0.rc2'

然后,创建一个空的 Gemfile.lock 文件:

$ touch Gemfile.lock

之所以这么做,是因为不希望在主机环境安装 Ruby 和其它依赖,而是都放到镜像中。这两个文件用于在镜像中安装 Rails。

接着,创建一个 Dockerfile 文件,该文件用于定义如何构建 Rails 镜像:

FROM ubuntu:16.04

RUN apt-get update && apt-get install -y curl apt-transport-https && 
  curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && 
  echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list

RUN apt-get update && apt-get install -y 
  build-essential 
  libpq-dev 
  nodejs 
  ruby 
  ruby-dev 
  tzdata 
  yarn 
  zlib1g-dev

WORKDIR /app

RUN gem install bundler
ADD Gemfile /app/Gemfile
ADD Gemfile.lock /app/Gemfile.lock
RUN bundle install
ADD . /app

这个 Dockerfile 基于 Ubuntu 16.04,安装了创建 Rails 项目所需要的基础包,并将项目目录设定在 /app。你可以阅读 https://docs.docker.com/ 学习怎么定制 Dockerfile。

然后,创建一个 docker-compose.yml 文件,该文件用于定义 docker-compose 如何启动应用:

version: '2'
services:
  web:
    build: .
    command: bundle exec rails s -p 3000 -b 0.0.0.0
    volumes:
      - .:/app
    ports:
      - 3000:3000
    depends_on:
      - db
  db:
    image: postgres

在这个文件里,我们定义了两个服务。web 服务用于运行 Rails,镜像将根据当前目录的 Dockerfile 构建;db 服务用于运行 PostgreSQL 进程,镜像使用 Docker 官方提供的 postgres。你可以在 https://docs.docker.com/compose/compose-file/ 找到其它配置的定义。

接下来,执行以下命令:

$ docker-compose run web rails new . --force --database=postgresql

该命令会在当前目录创建 Rails 项目:

$ ls -l
total 72
-rw-r--r--   1 rei  staff   522  4 25 22:59 Dockerfile
-rw-r--r--   1 rei  staff  1989  4 25 23:02 Gemfile
-rw-r--r--   1 rei  staff  4847  4 25 23:03 Gemfile.lock
-rw-r--r--   1 rei  staff   374  4 25 23:02 README.md
-rw-r--r--   1 rei  staff   227  4 25 23:02 Rakefile
drwxr-xr-x  10 rei  staff   340  4 25 23:02 app
drwxr-xr-x   9 rei  staff   306  4 25 23:03 bin
drwxr-xr-x  14 rei  staff   476  4 25 23:02 config
-rw-r--r--   1 rei  staff   130  4 25 23:02 config.ru
drwxr-xr-x   3 rei  staff   102  4 25 23:02 db
-rw-r--r--   1 rei  staff   206  4 25 22:59 docker-compose.yml
drwxr-xr-x   4 rei  staff   136  4 25 23:02 lib
drwxr-xr-x   3 rei  staff   102  4 25 23:02 log
-rw-r--r--   1 rei  staff    61  4 25 23:02 package.json
drwxr-xr-x   9 rei  staff   306  4 25 23:02 public
drwxr-xr-x  11 rei  staff   374  4 25 23:02 test
drwxr-xr-x   4 rei  staff   136  4 25 23:02 tmp
drwxr-xr-x   3 rei  staff   102  4 25 23:02 vendor

接着,重建 Docker 镜像:

$ docker-compose build

每当修改了 Dockerfile,你都需要重建镜像。如果修改了 Gemfile,还需要先在容器内运行 bundle,然后重建镜像:

$ docker-compose run web bundle
$ docker-compose build

连接数据库

现在我们已经可以让 Rails 跑起来,但还需要修改一些配置让 Rails 连上数据库。默认情况下,Rails 的 development 和 test 环境会连接 localhost 主机上的数据库,根据之前的 docker-compose.yml 配置,我们需要将数据库的主机名改为 db。另外,还需要修改 username 以适配 postgres 镜像的默认配置。修改后的 database.yml 配置如下:

development:
  <<: *default
  database: app_development
  host: db
  username: postgres

test:
  <<: *default
  database: app_test
  host: db
  username: postgres

现在可以启动 Rails 进程了:

$ docker-compose up

如果一切正常,你会看到一些 postgres 的日志,然后是 Rails 启动日志:

web_1  | => Booting Puma
web_1  | => Rails 5.1.0.rc2 application starting in development on http://0.0.0.0:3000
web_1  | => Run `rails server -h` for more startup options
web_1  | Puma starting in single mode...
web_1  | * Version 3.8.2 (ruby 2.3.1-p112), codename: Sassy Salamander
web_1  | * Min threads: 5, max threads: 5
web_1  | * Environment: development
web_1  | * Listening on tcp://0.0.0.0:3000
web_1  | Use Ctrl-C to stop

如果你需要运行数据库迁移,可以打开另一个终端运行:

$ docker-compose run web rails db:create
$ docker-compose run web rails db:migrate

TIP: 以后运行 rails 命令,都需要在前面加上 docker-compose run web。

用浏览器访问 http://localhost:3000 ,你会看到 Rails 的欢迎信息:

未分类

将 Dockerfile docker-compose.yml 与项目文件一并提交到版本控制里,这样新开发者参与项目的时候就可以用 docker-compose up 一键启动开发环境。

.NET Core容器化之多容器应用部署@Docker-Compose

未分类

1. 引言

紧接上篇.NET Core容器化@Docker,这一节我们先来介绍如何使用Nginx来完成.NET Core应用的反向代理,然后再介绍多容器应用的部署问题。

2. Why Need Nginx

.NET Core中默认的Web Server为Kestrel。

Kestrel is great for serving dynamic content from ASP.NET, however the web serving parts aren’t as feature rich as full-featured servers like IIS, Apache or Nginx. A reverse proxy-server can allow you to offload work like serving static content, caching requests, compressing requests, and SSL termination from the HTTP server.

Kestrel可以很好的用来为ASP.NET提供动态内容,然而在Web服务方面没有IIS、Apache、Nginx这些全功能的服务器完善。我们可以借助一个反向代理服务器接收来自互联网的HTTP请求并在经过一些初步处理(比如请求的缓存和压缩、提供静态内容、SSL Termination)后将其转发给Kestrel。

未分类

未分类

借助反向代理服务器(本文使用Nginx),不仅可以给我们的Web网站提供了一个可选的附加层配置和防御,而且可以简化负载均衡和SSL设置。而更重要的是,反向代理服务器可以很好的与现有的基础设施进行整合。

3. Hello Nginx

同样我们还是基于Docker来试玩一下Nginx。

//拉取Nginx镜像
$ docker pull nginx
//启动Nginx容器
$ docker run -d -p 8080:80 --name hellonginx nginx

上面我们以后台运行的方式启动了一个命名为hellonginx的nginx容器,其端口映射到宿主机的8080端口,我们现在可以通过浏览器直接访问http://:8080即可看到nginx的欢迎界面。

未分类

至此,一个Nginx容器就启动完毕了。那如何进行反向代理呢?别急,我们一步一步来。

4. 反向代理.NET Core MVC

4.1. 启动Web容器

还记得我们上一篇本地打包MVC项目创建的hellodocker.web的镜像吗?这里我们再启动该镜像创建一个容器:

//启动一个helodocker.web的镜像并命名容器为hellodocker.web.nginx
#  docker run -d -p 5000:5000 --name hellodocker.web.nginx hellodocker.web
160166b3556358502a366d1002567972e242f0c8be3a751da0a525f86c124933
//尝试访问刚刚运行的容器
[root@iZ288a3qazlZ ~]# curl -I http://localhost:5000
HTTP/1.1 200 OK
Date: Sun, 24 Dec 2017 02:48:16 GMT
Content-Type: text/html; charset=utf-8
Server: Kestrel
Transfer-Encoding: chunked

OK,我们开放了宿主机的5000端口用来映射我们启动的MVC容器。

4.2. 配置反向代理

下面我们就来配置Nginx来反向代理我们刚启动的Web容器。
要想Nginx成功代理指定的容器内运行的Web网站,首先我们得知道容器对应的IPAddress。使用docker inspect 即可查到。

//查看正在运行的容器列表
$ docker ps 
CONTAINER ID        IMAGE                          COMMAND                  CREATED             STATUS              PORTS                            NAMES
d046b7b878a0        hellodocker.web                "dotnet run"             5 seconds ago       Up 3 seconds        0.0.0.0:5000->5000/tcp           hellodocker.web.nginx

//使用`|`管道操作符加上`grep`过滤操作符可以直接提取我们要查找的关键字
$ docker inspect hellodocker.web.nginx | grep IPAddress
            "SecondaryIPAddresses": null,
            "IPAddress": "192.168.0.5",
                    "IPAddress": "192.168.0.5",

从上面可以看到我的Web容器运行在宿主机的192.168.0.5:5000。下面我们配置Nginx转发请求到192.168.0.5:5000即可完成反向代理。

Nginx配置反向代理的配置文件路径为:/etc/nginx/conf.d/default.conf。
我们可以通过本地创建一个配置文件挂载到Nginx的容器内部进行反向代理配置。

$ cd demo
$ mkdir nginx
//创建my_nginx.conf文件
$ touch my_nginx.conf
$ vi my_nginx.conf
server {
  listen 80;

  location / {
    proxy_pass http://192.168.0.5:5000;
  }
}

上面我们通过指定listen配置nginx去监听80端口,指定proxy_pass为我们Web容器的IP和端口完成反向代理文件的配置。
接下来就是启动一个新的Nginx容器并通过挂载的方式将配置文件共享到容器内部。

$ docker run -d -p 8080:80 
> -v $HOME/demo/nginx/my_nginx.conf:/etc/nginx/conf.d/default.conf 
> nginx
95381aa56a336f65b6d01ff9964ae3364f37d25e5080673347c1878b3a5bb514
/usr/bin/docker-current: Error response from daemon: driver failed programming external connectivity on endpoint elated_mccarthy (5a576d5991dd164db69b1c568c94c15e47ec7c67e43a3dd6982a2e9b83b60e08): Bind for 0.0.0.0:8080 failed: port is already allocated.

我们发现容器启动失败,原因是8080端口被我们刚刚第一次启动的nginx容器占用了。怎么办?两个方法:第一种就是将刚才创建的nginx容器干掉;第二种就是映射到新的端口。这里选择第一种。

$ docker ps
1bd630b60019        nginx                          "nginx -g 'daemon off"   59 minutes ago      Up 59 minutes       0.0.0.0:8080->80/tcp             hellonginx
//使用docker rm <container id>删除容器,指定-f进行强制删除
$ docker rm 1bd630b60019 -f
//重新启动Nginx容器
$ docker run -d -p 8080:80 
> -v $HOME/demo/nginx/my_nginx.conf:/etc/nginx/conf.d/default.conf 
> nginx
793d4c62ec8ac4658d75ea0ab4273a0b1f0a9a68f9708d2f85929872888b121d

启动成功后,我们再在浏览器中访问http://:8080,发现返回的不再是Nginx的默认欢迎页,而是我们启动的Web容器中运行的MVC的首页,说明反向代理配置成功!

未分类

5. Docker Compose让一切更简单

上面的步骤虽然简单,但要分两步进行:第一个就是我们的Web和Nginx要分两次部署,第二个就是我们必须知道Web容器的IP和端口号,以完成反向代理文件的配置。

对于需要多个容器(比如需要Nginx、SqlServer、Redis、RabbitMQ等)协调运行的复杂应用中,使用以上方式进行部署时,很显然会很麻烦,而且还要为各个容器之间的网络连接而苦恼。
还好,Docker体贴的为我们想到了这一点。借助Compose模块,我们可以编写一个docker-compose.yml文件,使用声明性语法启动一系列相互连接的容器,即可一步完成上面的任务。

Docker Compose是一个用来定义和运行复杂应用的Docker工具。使用Compose,你可以在一个文件中定义一个多容器应用,然后使用一条命令来启动你的应用,完成一切准备工作。

5.1. 安装Docker Compose

依次执行以下命令:

$ sudo curl -L https://github.com/docker/compose/releases/download/1.18.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
$ docker-compose --version
docker-compose version 1.18.0, build 1719ceb

5.2. 编写第一个docker-compose.yml

dockers-compose.yml文件要定义在我们项目的文件夹下,我们的项目文件夹位于$HOME/demo/HelloDocker.Web。

$ cd $HOME/demo/HelloDocker.Web
$ touch docker-compose.yml
$ vi docker-compose.yml
version: '2'
services:
    hellodocker-web:
        container_name: hellodocker.web.compose
        build: .

    reverse-proxy:
        container_name: reverse-proxy
        image: nginx
        ports:
         - "9090:8080"
        volumes:
         - ./proxy.conf:/etc/nginx/conf.d/default.conf

简单介绍下上面的配置文件,其中定义了两个服务:一个是hellodocker-web,即以我们当前项目目录来构建镜像并启动一个叫hellodocker.web.compose的容器。一个是reverse-proxy,用来使用nginx镜像进行反向代理,其中又通过指定volumes来使用挂载的方式进行配置。

$ touch proxy.conf
$ vi proxy.conf
server {
    listen 8080;

    location / {
      proxy_pass http://hellodocker-web:5000;
    }
}
$ ls
[root@iZ288a3qazlZ HelloDocker.Web]# ls
appsettings.Development.json  Controllers             Models      Startup.cs
appsettings.json              docker-compose.yml      obj         Views
bin                           Dockerfile              Program.cs  wwwroot
bundleconfig.json             HelloDocker.Web.csproj  proxy.conf
[root@iZ288a3qazlZ HelloDocker.Web]#

其中要注意反向代理的配置:proxy_pass http://hellodocker-web:5000;,其中ip部分直接指定的是docker-compose.yml中定义的第一个服务的名称hellodocker-web。
下面我们就来启动Compose:

$ docker-compose up -d
Building hellodocker-web
Step 1 : FROM microsoft/dotnet:latest
 ---> 7d4dc5c258eb
Step 2 : WORKDIR /app
 ---> Using cache
 ---> 98d48a4e278c
Step 3 : COPY . /app
 ---> 0cb9fc540afe
Removing intermediate container 9fecf088f03f
Step 4 : RUN dotnet restore
 ---> Running in 4bb7f34edbbe
  Restore completed in 597.13 ms for /app/HelloDocker.Web.csproj.
  Restoring packages for /app/HelloDocker.Web.csproj...
  Restore completed in 1.76 sec for /app/HelloDocker.Web.csproj.
 ---> 6869609ece23
Removing intermediate container 4bb7f34edbbe
Step 5 : EXPOSE 5000
 ---> Running in a97febf01e5a
 ---> 9b2639862a94
Removing intermediate container a97febf01e5a
Step 6 : ENV ASPNETCORE_URLS http://*:5000
 ---> Running in 4e2f4af28a8d
 ---> 0069661e891a
Removing intermediate container 4e2f4af28a8d
Step 7 : ENTRYPOINT dotnet run
 ---> Running in cbbf08d906f9
 ---> 0bbeef249b30
Removing intermediate container cbbf08d906f9
Successfully built 0bbeef249b30
WARNING: Image for service hellodocker-web was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Creating hellodocker.web.compose ... done
Starting reverse-proxy ... done
//执行docker-compose ps验证启动的服务
$ docker-compose ps
         Name                   Command          State               Ports
---------------------------------------------------------------------------------------
hellodocker.web.compose   dotnet run             Up      5000/tcp
reverse-proxy             nginx -g daemon off;   Up      80/tcp, 0.0.0.0:9090->8080/tcp
//使用curl指令验证nginx的反向代理
$  curl -I http://localhost:9090
HTTP/1.1 200 OK
Server: nginx/1.13.7
Date: Sun, 24 Dec 2017 04:37:35 GMT
Content-Type: text/html; charset=utf-8
Connection: keep-alive

可以看到,通过执行curl -I http://localhost:9090验证代理服务器配置成功,我们再通过浏览器访问http://:9090发现正确返回了我们MVC项目的默认首页。

// 查看当前运行的容器
$ docker ps
CONTAINER ID        IMAGE                            COMMAND                  CREATED             STATUS              PORTS                            NAMES
a52830499cff        hellodockerweb_hellodocker-web   "dotnet run"             7 minutes ago       Up 7 minutes        5000/tcp                         hellodocker.web.compose
e1fe109e10bc        nginx                            "nginx -g 'daemon off"   11 minutes ago      Up 4 minutes        80/tcp, 0.0.0.0:9090->8080/tcp   reverse-proxy

我们同时也发现通过docker-compose正确的创建了两个容器hellodocker.web.compose和reverse-proxy。

6. 最后

经过以上的练习,我们对Nginx有了一定的了解,且知道如何进行配置。同时了解了如何借助docker-compose打包运行需要多容器的复杂应用。

使用docker-compose一键部署分布式文件系统FastDFS

什么是FastDFS

百度百科:FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载)等,解决了大容量存储和负载均衡的问题。特别适合以文件为载体的在线服务,如相册网站、视频网站等等。
FastDFS为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。

FastDFS是由余庆所开发的开源、免费的分布式文件系统,GitHub项目地址请点这里,其基本架构图如下:

未分类

FastDFS仅提供源码包,必须从源码编译安装,且其提供了nginx插件,也必须与nginx源码一起编译安装nginx,安装过程较为繁复。为快速搭建简易的开发、测试环境,我采用docker方式将源码下载、编译、配置过程完全自动化,采用docker-compose来组织docker容器,并采用一台tracker+一台storage的最小系统架构,且部署在一个容器内,这样就以最小的系统代价、最快的速度搭建起fastdfs使用环境了。标题中的”一键”稍显夸张,但事实上下载GitHub项目文件到本地后,只需两三条命令即可搞定一个最简单的FastDFS环境搭建。

**关于docker及docker-compose的安装,请见《Ubuntu安装docker和docker-compose》。&&

创建Dockerfile

本DockerFile采用的软件版本:

  • fastdfs:5.11
  • libfastcommon:1.0.36
  • fastdfs-nginx-module: 最新版(截至2017/11/28,为1.20)
  • nginx: 1.12.2

各源码均为在线下载。

DockerFile内容如下:

# 使用超小的Linux镜像alpine
FROM alpine:3.6

MAINTAINER YoungCoding <[email protected]>

ENV HOME /root

# 安装准备
RUN    apk update 
        && apk add --no-cache --virtual .build-deps bash gcc libc-dev make openssl-dev pcre-dev zlib-dev linux-headers curl gnupg libxslt-dev gd-dev geoip-dev

# 下载fastdfs、libfastcommon、nginx插件的源码
RUN     cd /root 
        && curl -fSL https://github.com/happyfish100/libfastcommon/archive/V1.0.36.tar.gz -o fastcommon.tar.gz 
        && curl -fSL  https://codeload.github.com/happyfish100/fastdfs/tar.gz/V5.11 -o fastfs.tar.gz 
        && curl -fSL  https://github.com/happyfish100/fastdfs-nginx-module/archive/master.tar.gz -o nginx-module.tar.gz 
        && tar zxf fastcommon.tar.gz 
        && tar zxf fastfs.tar.gz 
        && tar zxf nginx-module.tar.gz

# 安装libfastcommon
RUN     cd ${HOME}/libfastcommon-1.0.36/ 
        && ./make.sh 
        && ./make.sh install

# 安装fastdfs v5.11
RUN     cd ${HOME}/fastdfs-5.11/ 
        && ./make.sh 
        && ./make.sh install

# 配置fastdfs: base_dir
RUN     cd /etc/fdfs/ 
        && cp storage.conf.sample storage.conf 
        && cp tracker.conf.sample tracker.conf 
        && cp client.conf.sample client.conf 
        && sed -i "s|/home/yuqing/fastdfs|/var/local/fdfs/tracker|g" /etc/fdfs/tracker.conf 
        && sed -i "s|/home/yuqing/fastdfs|/var/local/fdfs/storage|g" /etc/fdfs/storage.conf 
        && sed -i "s|/home/yuqing/fastdfs|/var/local/fdfs/storage|g" /etc/fdfs/client.conf 

# 获取nginx源码,与fastdfs插件一起编译
RUN     cd ${HOME} 
        && curl -fSL http://nginx.org/download/nginx-1.12.2.tar.gz -o nginx-1.12.2.tar.gz 
        && tar zxf nginx-1.12.2.tar.gz 
        && chmod u+x ${HOME}/fastdfs-nginx-module-master/src/config 
        && cd nginx-1.12.2 
        && ./configure --add-module=${HOME}/fastdfs-nginx-module-master/src 
        && make && make install

# 设置nginx和fastdfs联合环境,并配置nginx
RUN     cp ${HOME}/fastdfs-nginx-module-master/src/mod_fastdfs.conf /etc/fdfs/ 
        && sed -i "s|^store_path0.*$|store_path0=/var/local/fdfs/storage|g" /etc/fdfs/mod_fastdfs.conf 
        && sed -i "s|^url_have_group_name =.*$|url_have_group_name = true|g" /etc/fdfs/mod_fastdfs.conf 
        && cd ${HOME}/fastdfs-5.11/conf/ 
        && cp http.conf mime.types anti-steal.jpg /etc/fdfs/ 
        && echo -e "
events {n
    worker_connections  1024;n
}n
http {n
    include       mime.types;n
    default_type  application/octet-stream;n
    server {n
        listen 8888;n
        server_name localhost;n

        location ~ /group[0-9]/M00 {n
            ngx_fastdfs_module;n
        }n
    }n
}">/usr/local/nginx/conf/nginx.conf

# 清理文件
RUN rm -rf ${HOME}/*
RUN apk del .build-deps gcc libc-dev make openssl-dev linux-headers curl gnupg libxslt-dev gd-dev geoip-dev
RUN apk add bash pcre-dev zlib-dev


# 配置启动脚本,在启动时中根据环境变量替换nginx端口、fastdfs端口
# 默认nginx端口
ENV WEB_PORT 8888
# 默认fastdfs端口
ENV FDFS_PORT 22122
# 创建启动脚本
RUN     echo -e "
mkdir -p /var/local/fdfs/storage/data /var/local/fdfs/tracker; n
ln -s /var/local/fdfs/storage/data/ /var/local/fdfs/storage/data/M00; nn
sed -i "s/listen .*$/listen $WEB_PORT;/g" /usr/local/nginx/conf/nginx.conf; n
sed -i "s/http.server_port=.*$/http.server_port=$WEB_PORT/g" /etc/fdfs/storage.conf; nn
if [ "$IP" = "" ]; then n
    IP=`ifconfig eth0 | grep inet | awk '{print $2}'| awk -F: '{print $2}'`; n
fi n
sed -i "s/^tracker_server=.*$/tracker_server=$IP:$FDFS_PORT/g" /etc/fdfs/client.conf; n
sed -i "s/^tracker_server=.*$/tracker_server=$IP:$FDFS_PORT/g" /etc/fdfs/storage.conf; n
sed -i "s/^tracker_server=.*$/tracker_server=$IP:$FDFS_PORT/g" /etc/fdfs/mod_fastdfs.conf; nn
/etc/init.d/fdfs_trackerd start; n
/etc/init.d/fdfs_storaged start; n
/usr/local/nginx/sbin/nginx; n
tail -f /usr/local/nginx/logs/access.log 
">/start.sh 
&& chmod u+x /start.sh

# 暴露端口。改为采用host网络,不需要单独暴露端口
# EXPOSE 80 22122

ENTRYPOINT ["/bin/bash","/start.sh"]

docker-compose.yaml

在DockerFile所在目录创建docker-compose.yaml,内容如下:

version: '3.0'

services:
    fastdfs:
        build: .
        image: youngcoding/fastdfs:5.11
        # 该容器是否需要开机启动+自动重启。若需要,则取消注释。
        #restart: always
        container_name: fastdfs
        environment:
            # nginx服务端口
            - WEB_PORT=8888
            # docker所在主机的IP地址
            - IP=192.168.56.110
        volumes:
            # 将本地目录映射到docker容器内的fastdfs数据存储目录,将fastdfs文件存储到主机上,以免每次重建docker容器,之前存储的文件就丢失了。
            - ${HOME}/docker-data/fdfs:/var/local/fdfs
        # 使docker具有root权限以读写主机上的目录
        privileged: true
        # 网络模式为host,即直接使用主机的网络接口
        network_mode: "host"

准备

$ cd <保存Dockerfile文件的路径>
# 检查文件夹下各文件是否齐全
$ ls
docker-compose.yaml     Dockerfile      log.sh

# 确保本机供挂载的存储文件夹存在,如不存在,则创建。注意,此文件夹需与docker-compose.yaml中设置的volume挂载目录一致,可以自行更改到其他文件夹。
$ mkdir -p ${HOME}/docker-data/fdfs

启动

$ docker-compose up -d
# 因为要下载软件包和源码,并编译,所以过程比较漫长,期间可能会出现红字的warning,不必理会。若报错,请根据提示排查。
...
Successfully built 4baafa5d2e75
Successfully tagged youngcoding/fastdfs:5.11
WARNING: Image for service fastdfs was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Creating fastdfs ...
Creating fastdfs ... done

# 查看容器运行状态
$ docker ps
或 $ docker-compose ps
CONTAINER ID        IMAGE                       COMMAND                 CREATED             STATUS              PORTS               NAMES
2a294bc410bd        youngcoding/fastdfs:5.11    "/bin/bash /start.sh"   4 minutes ago       Up 4 minutes                            fastdfs

测试

# 进入docker容器内终端
$ docker exec -it fastdfs或ID的前几位 /bin/bash

# 在容器内部终端执行上传测试
bash-4.3$ echo "Hello FastDFS!">index.html
bash-4.3$ fdfs_test /etc/fdfs/client.conf upload index.html
This is FastDFS client test program v5.11
...
[2017-11-28 14:05:25] DEBUG - base_path=/var/local/fdfs/storage, connect_timeout=30, network_timeout=60, tracker_server_count=1, anti_steal_token=0, anti_steal_secret_key length=0, use_connection_pool=0, g_connection_pool_max_idle_time=3600s, use_storage_id=0, storage server id count: 0
tracker_query_storage_store_list_without_group:
        server 1. group_name=, ip_addr=192.168.56.110, port=23000
group_name=group1, ip_addr=192.168.56.110, port=23000
storage_upload_by_filename
group_name=group1, remote_filename=M00/00/00/wKg4blodbSWAImI9AAAADwA12ic71.html
source ip address: 192.168.56.110
file timestamp=2017-11-28 14:05:25
file size=15
file crc32=3529255
example file url: http://192.168.56.110/group1/M00/00/00/wKg4blodbSWAImI9AAAADwA12ic71.html

# 下载测试
bash-4.3$ fdfs_test /etc/fdfs/client.conf download group1 M00/00/00/wKg4blodbSWAImI9AAAADwA12ic71.html
...
storage=192.168.56.110:23000
download file success, file size=15, file save to wKg4blodbSWAImI9AAAADwA12ic71.html

# 外部http访问测试
# 在主机或其他同局域网内机器上用浏览器访问上面的url。注意:若nginx的端口设置不为80,则需加上端口号
http://192.168.56.110:8888/group1/M00/00/00/wKg4blodbSWAImI9AAAADwA12ic71.html
# 网页显示:Hello FastDFS!

# 删除测试
bash-4.3$ fdfs_test /etc/fdfs/client.conf delete group1 M00/00/00/wKg4blodbSWAImI9AAAADwA12ic71.html
storage=192.168.56.110:23000
delete file success

# 退出容器终端
bash-4.3$ exit

管理容器

# 停止容器
$ docker stop <容器NAMES,也可以为容器ID的前几位>
或 $ docker-compose stop

# 更改compose或Dockerfile后重新生成并运行
$ docker-compose stop
$ docker-compose build
$ docker-compose up -d
或 $ docker-compose up -d --build #本条命令可代替上述三条命令

# 删除容器
$ docker rm <容器NAMES,也可以为容器ID的前几位>
或 $ docker-compose rm

查看日志

为避免每次需要查看日志都要执行 docker exec -it <fdfs ID> /usr/bin/tail -f <log_file> 命令,我将常见的查看日志命令封装到一个脚本中,每次只需要执行脚本就能查看不同服务的日志了。

新建日志监控脚本log.sh

新建log.sh,用来快速查看日志。内容如下:

#!/bin/bash
STORAGE=/var/local/fdfs/storage/logs/storaged.log
TRACKER=/var/local/fdfs/tracker/logs/trackerd.log
NGINX=/usr/local/nginx/logs/access.log

ID=`docker ps|grep fastdfs|awk '{print $1}'`
echo fastdfs.ID:$ID
echo 'Use param tracker|storage|nginx to see log of each service such as "./log.sh tracker". No param equals to "storage".'
CAT=$1
LOG=""
if [[ "${CAT}" = "tracker" ]];then
    LOG=${TRACKER}
elif [[ "${CAT}" = "nginx" ]]; then
    LOG=${NGINX}
else 
    LOG=${STORAGE}
fi

docker exec -it $ID /usr/bin/tail -f ${LOG}

给log.sh添加执行权限

$ chmod u+x log.sh

查看日志

$ ./log.sh tracker或storage或nginx

# 查看nginx日志,可以看到刚刚从外部http方式访问fastdfs文件的日志
$ ./log.sh nginx
192.168.56.100 - - [28/Nov/2017:14:10:33 +0000] "GET /group1/M00/00/00/wKg4blodbSWAImI9AAAADwA12ic71_big.html HTTP/1.1" 200 15 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 Safari/537.36"

至此,fastDFS简易测试环境搭建完毕,开发搞起来!!完。

Ubuntu安装docker和docker-compose

未分类

百度百科:Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。

我的理解:docker就是轻量化的虚拟机,不需要你在每个虚拟机里安装操作系统,做到最简单的新建、运行、修改、删除;而且容器内服务直接调用本机的操作系统API,性能更高;可以用来实现快速虚拟化、快速部署、持续集成等等,是运维同学的神器。

本人不是搞运维的,主要做开发工作。为什么学习docker呢?主要是用来快速部署开发、测试环境,比如你开发、测试时要用redis、zookeeper、activemq、分布式存储等等,在个人电脑上该怎么玩儿?搭建N台虚拟机?不光内存不够,硬盘也不够啊,而且现在内存价格很贵,加不起。我之前开了6台虚拟机做zookeeper+redis集群,本机再开个eclipse、浏览器,8G内存见底,卡得不要不要的,而且虚拟机文件就有10G以上,苦也。这时候就需要docker这种轻量化的容器大显身手了。docker化后,开一台1G内存虚拟机,开个zookeeper+redis集群+activeMQ+fastdfs轻轻松松,具体应用可以看下一篇博文《docker超快速搭建redis集群、zookeeper集群、activeMQ、fastdfs分布式存储教程》。

测试平台系统: Ubuntu 16.04。如果想在Windows上玩儿Docker,可以去官方下载docker-toolbox或者先安装一台Ubuntu虚拟机。(ps: 其实docker-toolbox底层也是用的VirtualBox软件新建一台Linux虚拟机来实现的,因为当前docker只支持Linux。建议自建虚拟机安装docker,因为toolbox默认安装的虚拟机系统是tiny-core-linux,毕竟是一个超小型的非常用的linux,而且用的ISO镜像系统,无法安装软件。下面开始正题。)

1. 修改Ubuntu APT源为国内源

备份并编辑source.list

$ sudo cp /etc/apt/source.list /etc/apt/source.list.bak
$ sudo nano /etc/apt/source.list

注释掉光盘源及官方源

注释掉以下面开头的源(注释即在行首加#)

# deb cdrom:[Ubuntu-Server 16.04.3 LTS _Xenial Xerus
# deb http://cn.archive.ubuntu.com/ubuntu/
# deb http://security.ubuntu.com/ubuntu 

添加国内源

在文件末尾加入如下内容。注意:下面的xenial仅对应Ubuntu 16.04,其他版本的Ubuntu请自行更改为对应的版本名称

# 163 注释掉源码源
deb http://mirrors.163.com/ubuntu/ xenial main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ xenial-security main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ xenial-updates main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ xenial-proposed main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ xenial-backports main restricted universe multiverse
# deb-src http://mirrors.163.com/ubuntu/ xenial main restricted universe multiverse
# deb-src http://mirrors.163.com/ubuntu/ xenial-security main restricted universe multiverse
# deb-src http://mirrors.163.com/ubuntu/ xenial-updates main restricted universe multiverse
# deb-src http://mirrors.163.com/ubuntu/ xenial-proposed main restricted universe multiverse
# deb-src http://mirrors.163.com/ubuntu/ xenial-backports main restricted universe multiverse

# aliyun 注释掉src源
deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ xenial-proposed main restricted universe multiverse 
# 源码
# deb-src http://mirrors.aliyun.com/ubuntu/ xenial main restricted universe multiverse
# deb-src http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted universe multiverse
# deb-src http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted universe multiverse
# deb-src http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse
# deb-src http://mirrors.aliyun.com/ubuntu/ xenial-proposed main restricted universe multiverse

2. 安装docker-ce

安装必要环境

$ sudo apt-get update
$ sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common

添加docker-ce仓库

两个安装源,二选一即可

使用阿里云docker-ce repository(版本基本同官方,速度快,推荐)

$ curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
$ sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"

使用官方docker-ce repository(版本最新,速度稍慢)

$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

安装docker-ce

$ sudo apt-get -y update
$ sudo apt-get -y install docker-ce

# 添加当前用户到docker用户组
$ sudo usermod -aG docker `whoami`

# 检查docker
$ docker -v
Docker version 17.09.0-ce, build afdb6d4

修改镜像地址

$ sudo vim /etc/docker/daemon.json

# 输入如下内容:(此处采用docker中国官方镜像地址,若要采用aliyun等镜像仓库,请自行更改网址)
{
  "registry-mirrors": ["https://registry.docker-cn.com"]
}

# 重启docker
$ sudo /etc/init.d/docker restart

安装 docker-compose

$ sudo curl -L https://github.com/docker/compose/releases/download/1.17.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
$ docker-compose --version
docker-compose version 1.17.1, build 1719ceb

完。