Docker教程前端有這篇就夠了!!!

Docker

前言

日趨複雜的運維開發環境,對虛擬服務器及應用服務的要求更加的多元化。咱們須要更加容易擴展、性能優越、方便監控的管理服務,容器化應用、容器化運維應運而生。javascript

【工欲善其事,必先利其器】須要準備的環境(三選一):php

  • Linux環境(Centos 7以上/Debian 8以上/Ubuntu 16.04LTS以上版本)
  • Windows 64位專業版/企業版/教育版(Build 15063以上)
  • macOS Sierra 10.12以上的版本

若是,你有了上面的環境,就能夠很快速的學習。html

【收穫什麼】:前端

  1. 理解/安裝docker容器技術
  2. 秒級快速部署mysql、nginx、tomcat等服務
  3. 搭建本身的git服務器
  4. 使用容器技術發佈nodejs + mongodb + koa + vue的應用

概念

1. 什麼是容器化?

容器化是將應用程序或服務、其依賴項及其配置(抽象化爲部署清單文件)一塊兒打包爲容器映像的一種軟件開發方法。vue

軟件容器充當軟件部署的標準單元,其中能夠包含不一樣的代碼和依賴項。 按照這種方式容器化軟件,開發人員和 IT 專業人員只需進行極少修改或不修改,便可將其部署到不一樣的環境。java

容器化應用程序在容器主機上運行,而容器主機在 OS(Linux 或 Windows)上運行。所以,容器的佔用比虛擬機 (VM) 映像小得多。node

【容器化的特色】:mysql

  • 一致的運行環境
  • 可伸縮性
  • 更方便的移植
  • 隔離性

2. 瞭解Docker

Docker是用GO語言開發的應用容器引擎,基於容器化,沙箱機制的應用部署技術。可適用於自動化測試、打包,持續集成和發佈應用程序等場景,包括阿里雲,亞馬遜在內的雲計算服務商都採用了docker來打造serverless服務平臺。它不只僅能夠部署項目,還能夠用於數據庫搭建,nginx服務搭建,nodejs、php等編程語言環境搭建。nginx

PS: docker現已更名爲mobygit

Docker中的三個重要概念

鏡像(image)

分片的(只讀)文件系統,由Dockerfile建立,它獨立、易擴展、更效率

容器(container):

由Docker進程建立和管理的:文件系統 + 系統資源 + 網絡配置 + 日誌管理 Docker是docker鏡像的運行環境,因此容器的概念就比較好理解了

倉庫(registry):

用來遠端存儲docker鏡像版本控制、變動管理、爲持續集成與快速部署提供便利

image.png 容器與鏡像的關係相似於面向對象編程中的對象與類。

Docker 使用客戶端-服務器 (C/S) 架構模式,使用遠程API來管理和建立Docker容器。

Docker 容器經過 Docker 鏡像來建立。

image.png

image.png

3. Docker vs 虛擬機

image.png

【區別】:

  1. 容器是應用層的抽象,它將代碼和依賴關係打包在一塊兒。 多個容器能夠在同一臺機器上運行,並與其餘容器共享操做系統內核,每一個容器在用戶空間中做爲獨立進程運行。 容器佔用的空間比VM少(容器映像的大小一般爲幾十MB),能夠處理更多的應用程序,而且須要更少的VM和操做系統。
  2. 虛擬機(VM)是物理硬件的抽象,將一臺服務器轉變爲多臺服務器。 管理程序容許多臺VM在單臺機器上運行。 每一個VM都包含操做系統的完整副本,應用程序,必要的二進制文件和庫 - 佔用數十GB。 虛擬機也可能很慢啓動。

【總結】:

特性 容器 虛擬機
啓動 秒級 分鐘級
硬盤使用 通常爲 MB 通常爲 GB
性能 接近原生 弱於
系統支持量 單機支持上千個容器 通常幾十個
開發/環境定製 方便(命令行、面向對象式) 進入虛擬機

【相同點】:

  1. 文件隔離/文件共享(沙箱)
  2. 資源隔離
  3. 網絡隔離
  4. 支持多種宿主環境(擴展)
  5. 快照/鏡像(版本控制/變動管理)

【不一樣點】:

  1. 不一樣的資源管理/依賴//釋放(虛擬機佔用更多的系統資源)
  2. 不一樣的應用運行環境
  3. Docker是寫時複製
  4. 不一樣的日誌方式(Docker收集日誌,而虛擬機須要在虛擬系統裏面看日誌)
  5. 不一樣的交互方式(Docker偏shell,虛擬機偏GUI)

4. Docker的工做原理(重點)

Docker是容器化部署技術,它主要做用在於經過運行容器來實現應用部署,而容器基於鏡像運行。

簡單地說,就是將你的項目和依賴包(基礎鏡像)打成一個帶有啓動指令的項目鏡像,而後在服務器建立一個容器,讓鏡像在容器內運行,從而實現項目的部署。

服務器就是容器的宿主機,docker容器與宿主機之間是相互隔離的。

Docker 的基礎是Linux容器(LXC:Linux Containers)等技術。

通常狀況流程:

image.png

Docker流程:

image.png

這其中,發生了什麼?

  1. Docker會本身拉取鏡像,若本地已經存在該鏡像,則不用到網上去拉取
  2. 建立新的容器
  3. 分配文件系統而且掛着一個可讀寫的層,任何修改容器的操做都會被記錄在這個讀寫層上,你能夠保存這些修改爲新的鏡像,也能夠選擇不保存,那麼下次運行改鏡像的時候全部修改操做都會被消除
  4. 分配網絡\橋接接口,建立一個容許容器與本地主機通訊的網絡接口
  5. 設置ip地址,從池中尋找一個可用的ip地址附加到容器上,換句話說,localhost並不能訪問到容器
  6. 運行你指定的程序
  7. 捕獲而且提供應用輸出,包括輸入、輸出、報錯信息

Docker的價值:

從應用架構角度:統一複雜的構建環境;

從應用部署角度:解決依賴不一樣、構建麻煩的問題,結合自動化工具(如jenkins)提升效率。

從集羣管理角度:規範的服務調度,服務發現,負載均衡

應用

1. Docker安裝和配置(偷個懶)

  1. 安裝教程地址:

    www.runoob.com/docker/maco…

  2. 配置鏡像加速地址:

    www.runoob.com/docker/dock…

2. Docker的命令

1. 查看docker版本

docker --version
複製代碼

2. 運行第一個Docker應用

// 使用docker run命令

docker run hell-world

// 下載ubuntu鏡像打印「from ububtu」
// -i: 以交互模式運行容器,一般與 -t 同時使用
// -t: 爲容器從新分配一個僞輸入終端,一般與 -i 同時使用

docker run -it ubuntu echo "from ubuntu"  

複製代碼

3. 查看容器運行狀態

使用docker ps命令來查看正在運行的容器的狀態,-a參數來查看全部的已經運行的容器(不管是否中止)

4. 重要命令

run 建立一個新的容器並運行一個命令

exec能夠進入到容器裏面去

-it是提供交互式的終端工具

-d 是讓鏡像容器在後臺去持續運行

--name 指定容器的名稱

-p 容器內部端口映射到主機的端口

-v 掛載宿主機的文件目錄到鏡像裏面去

-e 設置環境變量

// 運行鏡像 
docker run -it -d  --name test ubuntu
// 進入容器
docker exec -it test /bin/bash 
// 把本機的Downloads文件映射到ubuntu的home文件下
docker run -v ~/Downloads/:/home -itd --name test1 ubuntu

複製代碼

5.容器的管理

  • 啓動start
  • 中止stop
  • 重啓restart
  • 刪除已中止容器rm
docker stop test
複製代碼

3. 常見的應用場景介紹

Docker提供了輕量級的虛擬化,相比於虛擬機,能夠在同一臺機器上建立更多數量的容器。

【常見的應用場景】:

  1. 快速部署
  2. 隔離應用
  3. 提升開發效率
  4. 版本控制

1. 快速部署

咱們嘗試着來部署一個mysql:

docker run -d --name mysql-test -e MYSQL_ROOT_PASSWORD=123456 mysql
複製代碼

1.gif

一樣的道理,咱們來部署一個nginx:

2.gif

注意:這裏沒有映射服務端口,因此在80端口是看不到index.html中的內容的。須要加入-p參數來映射端口!!

docker run -d --name web -p 8000:80 -v ${your_dir}:/usr/share/nginx/html nginx
複製代碼

2. 隔離應用

咱們能夠同時跑兩個mysql,兩個nginx,指定不一樣的端口進行映射:

mysql-test1映射到8001端口,把mysql-test2映射到8002端口。

docker run -d --name mysql-test1 -p 8001:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql
docker run -d --name mysql-test2 -p 8002:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql
複製代碼

把web1映射到8100端口,把web2映射到8200端口。

docker run -d --name web1 -p 8100:80 -v ${your_dir}:/usr/share/nginx/html nginx
docker run -d --name web2 -p 8200:80 -v ${your_dir}:/usr/share/nginx/html nginx
複製代碼

3. 提升開發效率

  1. 一致的運行環境

    因爲 Docker 確保了執行環境的一致性,使得應用的遷移更加容易。Docker 能夠在不少平臺上運行,不管是物理機、虛擬機、公有云、私有云,甚至是筆記本,其運行結果是一致的。所以用戶能夠很輕易的將在一個平臺上運行的應用,遷移到另外一個平臺上,而不用擔憂運行環境的變化致使應用沒法正常運行的狀況。

  2. 更快速的啓動時間

    傳統的虛擬機技術啓動應用服務每每須要數分鐘,而 Docker 容器應用,因爲直接運行於宿主內核,無需啓動完整的操做系統,所以能夠作到秒級、甚至毫秒級的啓動時間。大大的節約了開發、測試、部署的時間。

  3. 更高效的複用系統資源

    因爲容器不須要進行硬件虛擬以及運行完整操做系統等額外開銷,Docker 對系統資源的利用率更高。不管是應用執行速度、內存損耗或者文件存儲速度,都要比傳統虛擬機技術更高效。所以,相比虛擬機技術,一個相同配置的主機,每每能夠運行更多數量的應用。

  4. 倉庫/鏡像機制

    使用倉庫能夠方便的在任何有docker進程的虛擬機/服務器/主機上運行docker應用,環境的統一,讓它們的部署變的很是的簡單。

4. 版本控制

Docker容器還能夠像git倉庫同樣,可讓你提交變動到Docker鏡像中並經過不一樣的版原本管理它們,來看看下面的例子:

咱們以前建立了一個mysql,如今,咱們使用commit命令就能夠給它作一個快照,打上一個tag

3.gif 在後面的課程中,咱們會詳細的介紹Docker的常見命令

4. 製做Docker鏡像

Dockerfile 是一個由一堆命令+參數構成的腳本,使用 docker build 便可執行腳本構建鏡像,自動的去作一些事,主要用於進行持續集成。

通常,Dockerfile 共包括四部分:

  • 基礎鏡像信息
  • 維護者信息
  • 鏡像操做指令
  • 容器啓動時執行指令

1. Dockerfile文件示例:

FROM node:10

LABEL maintainer=atiedan666666@163.com

# 建立 app 目錄
WORKDIR /app

# 把 package.json,package-lock.json(npm@5+) 或 yarn.lock 複製到工做目錄(相對路徑)
COPY ["package.json","*.lock","./"]

# 打包 app 源碼
# 特別注意:要指定工做目錄中的文件名
COPY src ./src

# 使用.dockerignore文件,上面兩個COPY合併成一個
# COPY . .

# 使用Yarn安裝 app 依賴
# 若是你須要構建生產環境下的代碼,請使用:
# --prod參數
RUN yarn --prod --registry=https://registry.npm.taobao.org

# 對外暴露端口 -p 4000:3000
EXPOSE 3000

CMD [ "node", "src/index.js" ]
複製代碼

2. 本地生成node應用

當Node.js碰見Docker,下面介紹Docker在前端中的應用:

一個簡單的Koa應用:

const Koa = require('koa');
const app = new Koa();

// response
app.use(ctx => {
  ctx.body = 'Hello Koa!!';
});

app.listen(3000);
複製代碼

3. 打包鏡像

使用docker build打包:

docker build -t ${your_name}/${image_name}:${tag} .
複製代碼

這裏的your_name表明的是遠程倉庫中的用戶名,或者倉庫地址; image_name爲鏡像名稱,tag是給鏡像打的標籤,用於版本控制。. 表明當前目錄例如:

docker build -t tiedan/node-demo:1.0 .
複製代碼

4. 使用鏡像

使用docker run運行

// 運行
docker run -d --name nodedemo -p 4000:3000 tiedan/node-demo:1.0
// 查看
docker ps
複製代碼

5. Docker-compose

經過 Docker-Compose 用戶能夠很容易地用一個配置文件定義一個多容器的應用,而後使用一條指令安裝這個應用的全部依賴,完成構建。Docker-Compose 解決了容器與容器之間如何管理編排的問題。

Compose 中有兩個重要的概念:

  • 服務 (service) :一個應用的容器,實際上能夠包括若干運行相同鏡像的容器實例。
  • 項目 (project) :由一組關聯的應用容器組成的一個完整業務單元,在 docker-compose.yml 文件中定義。

Docker Compose 是 Docker 的獨立產品,所以須要安裝 Docker 以後在單獨安裝 Docker Compose .

1. 安裝

Window和Mac 的 Docker 桌面版和 Docker Toolbox 已經包括 Compose 和其餘 Docker 應用程序,所以 Mac 用戶不須要單獨安裝 Compose, Linux 上咱們能夠從 Github 上下載它的二進制包來使用,

#下載
sudo curl -L https://github.com/docker/compose/releases/download/1.20.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
#安裝
chmod +x /usr/local/bin/docker-compose
#查看版本
docker-compose --version
複製代碼

2. 使用

docker-compose.yml改寫:

version: '3'
services:
  mysql:
    image: mysql
    container_name: test-mysql
    ports:
    - "8001:3306"
    environment:
    - MYSQL_ROOT_PASSWORD=123456
複製代碼

在此文件的當前目錄下,使用docker-compose up -d來執行。

生命週期管理:

建立:run/up

啓動/中止/刪除/重啓:start/stop/rm/restart

檢視/日誌:logs/ps

3. 應用

搭建本地mongo + mongo-express服務

# docker-compose.mongo.yml配置文件
version: '3.1'
services:
  mongo:
    image: mongo
    restart: always
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: 123456

  mongo-express:
    image: mongo-express
    restart: always
    ports:
      - 8081:8081
    environment:
      ME_CONFIG_MONGODB_ADMINUSERNAME: root
      ME_CONFIG_MONGODB_ADMINPASSWORD: 123456
複製代碼

執行:

# 執行 docker-compose.mongo.yml 若是不加 docker-compose -f 默認執行 docker-compose.mongo.yml
docker-compose -f docker-compose.mongo.yml up -d
複製代碼

4. 搭建git服務器

項目地址: github.com/sameersbn/d…

docker-compose.git.yml文件

// 運行該文件 docker-compose -f docker-compose.git.yml up -d
version: '2.3'

services:
  redis:
    restart: always
    image: redis:5.0.9
    command:
    - --loglevel warning
    volumes:
    - redis-data:/var/lib/redis:Z

  postgresql:
    restart: always
    image: sameersbn/postgresql:12-20200524
    volumes:
    - postgresql-data:/var/lib/postgresql:Z
    environment:
    - DB_USER=gitlab
    - DB_PASS=password
    - DB_NAME=gitlabhq_production
    - DB_EXTENSION=pg_trgm,btree_gist

  gitlab:
    restart: always
    image: sameersbn/gitlab:13.11.2
    depends_on:
    - redis
    - postgresql
    ports:
    - "10080:80"
    - "10022:22"
    volumes:
    - gitlab-data:/home/git/data:Z
    healthcheck:
      test: ["CMD", "/usr/local/sbin/healthcheck"]
      interval: 5m
      timeout: 10s
      retries: 3
      start_period: 5m
    environment:
    - DEBUG=false

    - DB_ADAPTER=postgresql
    - DB_HOST=postgresql
    - DB_PORT=5432
    - DB_USER=gitlab
    - DB_PASS=password
    - DB_NAME=gitlabhq_production

    - REDIS_HOST=redis
    - REDIS_PORT=6379

    - TZ=Asia/Kolkata
    - GITLAB_TIMEZONE=Kolkata

    - GITLAB_HTTPS=false
    - SSL_SELF_SIGNED=false

    - GITLAB_HOST=localhost
    - GITLAB_PORT=10080
    - GITLAB_SSH_PORT=10022
    - GITLAB_RELATIVE_URL_ROOT=
    - GITLAB_SECRETS_DB_KEY_BASE=long-and-random-alphanumeric-string
    - GITLAB_SECRETS_SECRET_KEY_BASE=long-and-random-alphanumeric-string
    - GITLAB_SECRETS_OTP_KEY_BASE=long-and-random-alphanumeric-string

    - GITLAB_ROOT_PASSWORD=12345678
    - GITLAB_ROOT_EMAIL=atiedan666666@163.com

    - GITLAB_NOTIFY_ON_BROKEN_BUILDS=true
    - GITLAB_NOTIFY_PUSHER=false

    - GITLAB_EMAIL=notifications@example.com
    - GITLAB_EMAIL_REPLY_TO=noreply@example.com
    - GITLAB_INCOMING_EMAIL_ADDRESS=reply@example.com

    - GITLAB_BACKUP_SCHEDULE=daily
    - GITLAB_BACKUP_TIME=01:00

    - SMTP_ENABLED=false
    - SMTP_DOMAIN=www.example.com
    - SMTP_HOST=smtp.gmail.com
    - SMTP_PORT=587
    - SMTP_USER=mailer@example.com
    - SMTP_PASS=password
    - SMTP_STARTTLS=true
    - SMTP_AUTHENTICATION=login

    - IMAP_ENABLED=false
    - IMAP_HOST=imap.gmail.com
    - IMAP_PORT=993
    - IMAP_USER=mailer@example.com
    - IMAP_PASS=password
    - IMAP_SSL=true
    - IMAP_STARTTLS=false

    - OAUTH_ENABLED=false
    - OAUTH_AUTO_SIGN_IN_WITH_PROVIDER=
    - OAUTH_ALLOW_SSO=
    - OAUTH_BLOCK_AUTO_CREATED_USERS=true
    - OAUTH_AUTO_LINK_LDAP_USER=false
    - OAUTH_AUTO_LINK_SAML_USER=false
    - OAUTH_EXTERNAL_PROVIDERS=

    - OAUTH_CAS3_LABEL=cas3
    - OAUTH_CAS3_SERVER=
    - OAUTH_CAS3_DISABLE_SSL_VERIFICATION=false
    - OAUTH_CAS3_LOGIN_URL=/cas/login
    - OAUTH_CAS3_VALIDATE_URL=/cas/p3/serviceValidate
    - OAUTH_CAS3_LOGOUT_URL=/cas/logout

    - OAUTH_GOOGLE_API_KEY=
    - OAUTH_GOOGLE_APP_SECRET=
    - OAUTH_GOOGLE_RESTRICT_DOMAIN=

    - OAUTH_FACEBOOK_API_KEY=
    - OAUTH_FACEBOOK_APP_SECRET=

    - OAUTH_TWITTER_API_KEY=
    - OAUTH_TWITTER_APP_SECRET=

    - OAUTH_GITHUB_API_KEY=
    - OAUTH_GITHUB_APP_SECRET=
    - OAUTH_GITHUB_URL=
    - OAUTH_GITHUB_VERIFY_SSL=

    - OAUTH_GITLAB_API_KEY=
    - OAUTH_GITLAB_APP_SECRET=

    - OAUTH_BITBUCKET_API_KEY=
    - OAUTH_BITBUCKET_APP_SECRET=
    - OAUTH_BITBUCKET_URL=

    - OAUTH_SAML_ASSERTION_CONSUMER_SERVICE_URL=
    - OAUTH_SAML_IDP_CERT_FINGERPRINT=
    - OAUTH_SAML_IDP_SSO_TARGET_URL=
    - OAUTH_SAML_ISSUER=
    - OAUTH_SAML_LABEL="Our SAML Provider"
    - OAUTH_SAML_NAME_IDENTIFIER_FORMAT=urn:oasis:names:tc:SAML:2.0:nameid-format:transient
    - OAUTH_SAML_GROUPS_ATTRIBUTE=
    - OAUTH_SAML_EXTERNAL_GROUPS=
    - OAUTH_SAML_ATTRIBUTE_STATEMENTS_EMAIL=
    - OAUTH_SAML_ATTRIBUTE_STATEMENTS_NAME=
    - OAUTH_SAML_ATTRIBUTE_STATEMENTS_USERNAME=
    - OAUTH_SAML_ATTRIBUTE_STATEMENTS_FIRST_NAME=
    - OAUTH_SAML_ATTRIBUTE_STATEMENTS_LAST_NAME=

    - OAUTH_CROWD_SERVER_URL=
    - OAUTH_CROWD_APP_NAME=
    - OAUTH_CROWD_APP_PASSWORD=

    - OAUTH_AUTH0_CLIENT_ID=
    - OAUTH_AUTH0_CLIENT_SECRET=
    - OAUTH_AUTH0_DOMAIN=
    - OAUTH_AUTH0_SCOPE=

    - OAUTH_AZURE_API_KEY=
    - OAUTH_AZURE_API_SECRET=
    - OAUTH_AZURE_TENANT_ID=

volumes:
  redis-data:
  postgresql-data:
  gitlab-data:
複製代碼

5. 實戰案例

docker-compose在前端裏面的使用:

Nodejs + mongodb + koa + vue的應用組合:

docker-compose.yml

version: '3'
services:
  web:
    image: web:1.0
    ports:
    - "8080:80"

  server:
    image: server:1.0
    ports:
    - "3000:3000"
    depends_on:
    - mongodb
    links:
    - mongodb:db

  mongodb:
    image: mongo
    restart: always
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: 123456
複製代碼

depends_on 決定了容器加載的前後順序,這裏mongdbweb先加載,mongdb建立完成以後,再來建立server

相關文章
相關標籤/搜索