Docker零基礎到實戰 三劍客之 Compose

背景與介紹

容器從根本上改變了人們開發、發佈以及運行軟件的方式。軟件開發者能夠在本地構建軟件,由於他們知道軟件可以在任何主機環境下運行,不管是 IT 部門的機房、用戶的筆記本電腦,仍是雲端集羣,並且運行時並沒有差別。運維工程師只需專一於維護網絡和資源, 保證正常運行時間,減小了花在配置環境及解決系統依賴關係上的時間。從規模很小的創業公司,到規模龐大的企業,容器的使用率和理解程度正以驚人的速度提高。能夠預見,在將來幾年,開發者和運維工程師將以不一樣形式普遍使用容器技術。容器是對應用程序及其依賴關係的封裝。乍一看容器只是個輕量級的虛擬機,它和虛擬機同樣擁有一被隔離的操做系統實例,用來運行應用程序。但容器擁有一些優勢,使它能實現一些傳統虛擬機很難實現甚至沒法實現的用例。node

  • 容器能與主機的操做系統共享資源,於是它的效率高出一個數量級。啓動和中止容器均只需一瞬間。相比在主機上直接運行程序,容器的性能損耗很是低,甚至是零損耗。
  • 容器具備可移植性,這極有可能完全解決因爲運行環境的些許改變而致使的問題,甚至有可能完全終止開發者的抱怨:「但是程序在個人計算機上能正常工做!」
  • 容器是輕量的,這意味着開發者能同時運行數十個容器,並能模擬分佈式系統在真實運行環境下的狀況。運維工程師在一臺主機上能運行的容器數量,遠遠超過僅使用虛擬機時。
  • 對於最終用戶及開發者而言,容器的優點不只僅體如今雲端部署。用戶能夠下載並執行復雜的應用程序,而無需花費大量時間在配置和安裝的問題上,也無需擔憂對系統自己的改動。另外一方面,應用程序的開發者不用再操心用戶環境的差別,以及依賴關係是否知足。更重要的是,虛擬機和容器的根本目標不盡相同。虛擬機的目的是要完整地模擬另外一個環境,而容器的目的則是使應用程序可以移植,並把全部依賴關係包含進去。

補充個知識點: 從容器內部訪問宿主機ip: mac:docker.for.mac.host.internal 其餘:docker.for.host.internalgit

通常手動的部署方式?

你如今作了一個 xxxx 系統 or xxx 軟件。可是你這個項目所用到的技術面很是的多,若是咱們按照正常手動的部署方式,那就是折騰服務器下載各類依賴、軟件、插件... 亂七八糟的各類配置。OK 對於喜歡愛折騰的人來講,我以爲這也是能夠使人接受的,可是想一想有一天你服務器崩了,或者須要換服務器,是否是又要來一遍騷操做,想想你的項目若是之後又增長了什麼功能有須要什麼依賴支持,那是否是還要折騰。github

爲何要使用 Docker?

使用 Docker 的好處不少,不光能夠解決上述的問題,並且還有如下幾點:redis

  • 不管是安裝應用、搭建環境、部署應用、環境配置仍是切換應用都很是方便靈活
  • 節省資源開銷
  • 靈活遷移你開發的應用程序
  • 一致的運行環境
  • 更輕鬆維護和擴展

...docker

並且會 docker 會讓你找工做時多加幾分,同事之間談起來多幾分資本npm

Docker 的基本概念

鏡像 Images

Docker 鏡像是一個特殊的文件系統,除了提供容器運行時所需的程序、庫、資源、配置等文件外,還包含了一些爲運行時準備的一些配置參數(如匿名卷、環境變量、用戶等)。鏡像不包含任何動態數據,其內容在構建以後也不會被改變json

容器 Container

容器是鏡像的實例化,實質運行與本身的獨立命名空間的進程。所以容器具備本身的 root 系統、網絡配置、進程空間、用戶ID空間等 相對於鏡像來講容器是動態的,容器在啓動的時候,以鏡像爲基礎層建立一層可寫層做爲最上層ubuntu

容器與虛擬機對比數組

倉庫 Repository

倉庫的概念跟 git 相似,註冊服務器能夠理解爲 github、codding、gitlab、碼雲... 這樣的託管服務bash

交互圖

畫的比較醜 不懂能夠直接問我

Docker 基本命令

  • docker start 容器名(容器ID也能夠)
  • docker stop 容器名(容器ID也能夠)
  • docker run 命令加 -d 參數,docker 會將容器放到後臺運行
  • docker ps 正在運行的容器
  • docker top 容器名 查看容器內部運行的進程
  • docker exec -d 容器名 touch /etc/new_config_file 經過後臺命令建立一個空文件
  • docker inspect 容器名 對容器進行詳細的檢查,能夠加 --format='{(.State.Running)}' 來獲取指定的信息
  • docker rm 容器ID 刪除容器,注:運行中的容器沒法刪除
  • docker rm docker ps -a -q 這樣能夠刪除全部的容器
  • docker images 列出鏡像
  • docker pull 鏡像名:標籤 拉鏡像
  • docker search 查找docker Hub 上公共的可用鏡像
  • docker login 登錄到Docker Hub,我的認證信息將會保存到$HOME/.dockercfg
  • docker history 鏡像ID 深刻探求鏡像是如何構建出來的
  • docker push 鏡像名 將鏡像推送到 Docker Hub
  • docker rmi 鏡像名 刪除鏡像
  • docker attach 容器ID 進入容器
  • docker network create --subnet=172.171.0.0/16 docker-at 選取172.172.0.0網段

...

安裝 Docker

請你們 移步 到另外一篇文章,裏面有詳細講解安裝 dockerdocker-compose

運行咱們的第一個鏡像

查找鏡像

咱們經過 docker search 來查看鏡像是否存在

$ docker search redis
複製代碼

拉取鏡像

接下來咱們經過 docker pull 來拉取鏡像

$docker pull redis

注意 tag:latest 這表示咱們拉取的最新的鏡像,如需其餘版本 在 docker pull redis:xxxx 跟上版本

查看鏡像列表

$ docker images
複製代碼

查看鏡像詳情信息

docker inspect 查看鏡像元數據

$ docker inspect redis:latest
複製代碼

容器

生成容器

咱們使用 redis 這個鏡像來生成咱們的第一個容器

docker run -p 6379:6379 -v $PWD/data:/data --name redis-server -d redis:latest
複製代碼
  • -p 容器中能夠運行一些網絡應用,要讓外部也能夠訪問這些應用,能夠經過 -P(大寫) 或 -p (小寫) 參數來指定端口映射
  • -v 將主機中當前目錄下的data掛載到容器的/data
  • --name 自定義容器名稱
  • -i 展現容器輸入信息
  • -t 命令行交互模式
  • -u 設置用戶名
  • -w 指定容器內的目錄
  • -e 設置環境變量
  • -d 後臺運行

docker ps 顯示當前正在運行的容器 若是再加上 -a 是全部容器

是否是感受比咱們本身在服務器下載一個redis要方便的多啊 不要急 慢慢往下看

進入容器

docker exec 是須要容器處於運行中且 PID1 進程也處於運行中才能執行的操做。命令執行後會進入容器的默認工做目錄

$ docker exec -it redis-server /bin/sh
複製代碼

對容器的一些操做

$ docker stop redis-server # 中止
$ docker start redis-rever # 啓動
$ docker rm redis-server   # 刪除

複製代碼

有些人感受命令也很繁瑣 並且輸入錯了還要從頭來一次 並且不少東西也沒有配置 docker 也就這樣啊, 也是拉取一個個的鏡像而後構建容器配置

咱們繼續...

使用 Dockerfile 構建redis容器

FROM ubuntu          

MAINTAINER ruifengyun "push_over@163.com"

RUN apt-get update &&  apt-get -y install epel-release && apt-get -y install redis && apt-get -y install net-tools

EXPOSE 6379
ENTRYPOINT [ "/usr/bin/redis-server" ]
CMD []
複製代碼
  • FROM 是做爲鏡像的基礎
  • MAINTAINER 指定維護者信息
  • RUN 能夠理解爲在FROM下來的鏡像作一些環境的部署
  • CMD 是建立容器後,會運行的命令
  • EXPOSE 是暴露的端口
  • MAINTAINER 通知的郵件
  • ADD 至關於把主機的start.sh腳本傳遞給了容器裏面
  • VOLUME 是本地的路徑的映射
  • WORKDIR 是執行的路徑,也就是cmd entrypoint執行的路徑
  • ENV 用於指定環境變量,這些環境變量,後續能夠被RUN指令使用,容器運行起來以後,也能夠在容器中獲取這些環境變量
  • -ENTRYPOINT 配置容器啓動時的執行命令
  • COPY 複製本地主機目錄或文件到容器的目錄,不存在時會自動建立
  • USER 指定容器運行時的用戶名或UID,後續的RUN也會使用指定的用戶

建立後以後咱們就能夠執行 docker build . . 不能被省略 切記必定要在Dockerfile文件所在的目錄

咱們經過 docker images 查看當前鏡像列表是否是多了一個ubuntu

們簡單說一下整個Dockerfile的內容:

首先選擇了基礎鏡像是ubuntu的最新版,而後填寫做者信息, 再以後更新軟件源, 下載安裝一些所須要的依賴並下載redis,隨即咱們又開放了6379端口

學習使用 Docker Compose

前面咱們使用 Docker 的時候,定義 Dockerfile 文件,而後使用 docker build、docker run 等命令操做容器。然而微服務架構的應用系統通常包含若干個微服務,每一個微服務通常都會部署多個實例,若是每一個微服務都要手動啓停,那麼效率之低,維護量之大可想而知

使用 Docker Compose 能夠輕鬆、高效的管理容器,它是一個用於定義和運行多容器 Docker 的應用程序工具

Docker Compose 將所管理的容器分爲三層,分別是工程(project)、服務(service)、容器(container) Docker Compose 運行目錄下的全部文件(docker-compose.yml)組成一個工程,一個工程包含多個服務,每一個服務中定義了容器運行的鏡像、參數、依賴,一個服務可包括多個容器實例

Docker Compose 經常使用命令與配置

ps 列出全部運行容器

$ docker-compose ps
複製代碼

logs 查看服務日誌輸出

$ docker-compose logs
複製代碼

build 構建或者從新構建服務 必須在docker-compose.yml 文件同級下

$ docker-compose build
複製代碼

start 啓動指定服務已存在的容器

$ docker-compose start
複製代碼

stop 中止已運行的服務的容器

$ docker-compose stop
複製代碼

up 構建、啓動容器

$ docker-compose up 
-d 後臺運行
複製代碼

docker-compose.yml 命令

  • version 指定 docker-compose.yml 文件的寫法格式
  • services 多個容器集合
  • build 配置構建時,Compose 會利用它自動構建鏡像,該值能夠是一個路徑,也能夠是一個對象,用於指定 Dockerfile 參數
  • command 覆蓋容器啓動後默認執行的命令
  • dns 配置 dns 服務器,能夠是一個值或列表
  • dns_search 配置 DNS 搜索域,能夠是一個值或列表
  • environment 環境變量配置,能夠用數組或字典兩種方式
  • env_file 從文件中獲取環境變量,能夠指定一個文件路徑或路徑列表,其優先級低於 environment 指定的環境變量
  • expose 暴露端口,只將端口暴露給鏈接的服務,而不暴露給主機
  • image 指定服務所使用的鏡像
  • network_mode 設置網絡模式
  • ports 對外暴露的端口定義,和 expose 對應
  • links 將指定容器鏈接到當前鏈接,能夠設置別名,避免ip方式致使的容器重啓動態改變的沒法鏈接狀況
  • volumes 卷掛載路徑
  • logs 日誌輸出信息

docker-compose 實戰

咱們作一個簡單的實例

選擇一個目錄建立 Dockerfiledocker-compose.yml 文件

咱們來擼 docker-compose.yml

version: '3'
services:
  redis:
    image: redis
    ports:
      - 6379:6379
    restart: always

  mongo:
    image: mongo
    ports:
      - 27017:27017
    restart: always
    volumes:
      - ./mongo:/data/db

  app:
    build: .    # 咱們接下來要擼的Dcokerfile
    restart: always
    command: npm start
    environment:
      - TZ=Asia/Shanghai
    # volumes:
    # - .:/app
      # - /app/node_modules
    ports:
      - 7001:7001
    depends_on:
      - redis
      - mongo
    links:
      - redis:redis
      - mongo:mongo

複製代碼

繼續擼 Dcokerfile

FROM node:lts

# LABEL maintainer = "gaozan <push_over@163.com>"

# 環境變量
ENV NODE_ENV production  

# 建立app目錄
# RUN mkdir /app

# 設置工做目錄
WORKDIR /app

# 拷貝package.json文件到工做目錄
# !!重要:package.json須要單獨添加。
# Docker在構建鏡像的時候,是一層一層構建的,僅當這一層有變化時,從新構建對應的層。
# 若是package.json和源代碼一塊兒添加到鏡像,則每次修改源碼都須要從新安裝npm模塊,這樣木有必要。
# 因此,正確的順序是: 添加package.json;安裝npm模塊;添加源代碼
COPY package*.json ./

# 安裝npm依賴(使用淘寶的鏡像源)
# 若是使用的境外服務器,無需使用淘寶的鏡像源,即改成`RUN npm i`。
RUN npm install --registry=https://registry.npm.taobao.org && npm install egg-scripts --save

# 指定時區
# RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# 拷貝全部源代碼到工做目錄
COPY ./ /app

USER root
# 暴露容器端口
EXPOSE 7001
複製代碼

而後咱們須要執行 docker-compose up -d 啓動並在後臺運行

結尾

到這就是 docker 的一個簡單介紹和小demo 寫的很差的地方多多包含, 謝謝你們 請關注個人博客

相關文章
相關標籤/搜索