被忽略的後端開發神器 — Docker

剛接觸Docker的時候,覺得只是用來作運維。後來真正用的時候才發覺,這個Docker簡直是個神器。無論什麼開發場景都能輕鬆應付。想要什麼環境都能隨意生成,並且靈活性更高,更輕量,完美實現微服務的概念。python

什麼是Docker

Docker是一個開源的應用容器引擎,基於Go語言 並聽從Apache2.0協議開源。傳統虛擬機技術是虛擬出一套硬件後,在其上運行一個完整操做系統,在該系統上再運行所需應用進程;而容器內的應用進程直接運行於宿主的內核,容器內沒有本身的內核,並且也沒有進行硬件虛擬。它佔用的資源更少,能作到的事更多。linux

與傳統虛擬機的對比

特性 容器 虛擬機
啓動 秒級 分鐘級
硬盤啓動 通常爲MB 通常爲GB
性能 接近原生 弱於
系統支持量 單機支持上千個容器 通常幾十個

安裝Docker

安裝的方法都挺簡單的,我用的是mac,直接經過Docker官網下載軟件安裝,全程無障礙。nginx

Docker概念

  • 鏡像(images):Docker鏡像是一個特殊的文件系統,除了提供容器運行時所需的程序、庫、資源、配置等文件外,還包含了一些爲運行時準備的一些配置參數(如匿名卷、環境變量、用戶等)。鏡像不包含任何動態數據,其內容在構建以後也不會被改變。(直白點能夠理解爲系統安裝包)
  • 容器(container):鏡像和容器的關係,就像是面向對象程序設計中的實例同樣,鏡像是靜態的定義,容器是鏡像運行時的實體。容器能夠被建立、啓動、中止、刪除、暫停等。(能夠理解爲安裝好的系統

Docker鏡像使用

1、下載鏡像

大概瞭解了Docker的概念之後,咱們就嘗試拉取flask鏡像使用一下。 查找鏡像能夠經過hub.docker.com/網站來搜索,或者經過命令搜索。web

docker search flask
複製代碼

在這裏,我是經過Docker hub官網挑選出了python3.7 + alpine3.8組合的運行環境, alpine是精簡版的linux,體積更小、運行的資源消耗更少。

# 拉取鏡像
docker pull tiangolo/uwsgi-nginx-flask:python3.7-alpine3.8
# 下載好可查看鏡像列表是否存在
docker images
複製代碼

2、運行flask鏡像

下載鏡像之後,就開始運行下試試,感覺一下Docker的輕量、快捷。 首先建立個flask運行文件來,在這裏,我建立了/docker/flask做爲項目文件,而後在根目錄下再建立個app文件夾來存放main.py文件,代碼以下:redis

from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World from Flask!"

if __name__ == "__main__":
    # 測試環境下才開啓debug模式
    app.run(host='0.0.0.0', debug=True, port=80)
複製代碼

如今的文件結構:docker

flask
  └── app
      └── main.py
複製代碼

運行命令數據庫

docker run -it --name test -p 8080:80 -v /docker/flask/app:/app -w /app tiangolo/uwsgi-nginx-flask:python3.7-alpine3.8 python main.py
複製代碼

這裏說明一下命令的參數含義: -it 是將-i -t合併起來,做用是能夠用指定終端對容器執行命令交互。 --name 對容器進行命名。 -p 將主機的8080端口映射到容器的80端口。 -v 將主機的/docker/flask/app文件掛載到容器的/app文件,若是容器內沒有的話會自動建立。 -w 將/app文件做爲工做區,後面的執行命令都默認在該文件路徑下執行。 tiangolo/uwsgi-nginx-flask:python3.7-alpine3.8 鏡像名跟標籤。 python main.py 經過python來運行工做區的main.py文件。 運行結果:flask

如今主機跟容器的連接已經創建起來了,主機經過8080端口就能訪問到容器的網站。

自定義鏡像

在使用別人定製的鏡像時老是不能盡善盡美的,若是在本身項目裏面,不能每次都是拉取下來從新配置一下。像上面的鏡像,我可不喜歡這麼長的名字,想一想每次要敲這麼長的名字都頭疼(tiangolo/uwsgi-nginx-flask:python3.7-alpine3.8)。vim

編寫Dockerfile文件

打開咱們剛纔的/docker/flask路徑,在根目錄下建立Dockerfile文件,內容以下。瀏覽器

# 基礎鏡像
FROM tiangolo/uwsgi-nginx-flask:python3.7-alpine3.8

# 沒有vim來查看文件很不習慣,利用alpine的包管理安裝一個來
RUN apk add vim 
# 順便用pip安裝個redis包,後面用得上
RUN pip3 install redis 
# 將咱們的app文件加入到自定義鏡像裏面去
COPY ./app /app 複製代碼

如今咱們的文件結構是:

flask
├── app
│   └── main.py
└── Dockerfile
複製代碼

剩下的就跑一遍就OK啦!記得必定要在Dockerfile文件同級目錄下執行build命令。

docker build -t myflask .

Sending build context to Docker daemon  4.608kB
Step 1/4 : FROM tiangolo/uwsgi-nginx-flask:python3.7-alpine3.8
 ---> c69984ff0683
Step 2/4 : RUN apk add vim
 ---> Using cache
 ---> ebe2947fcf89
Step 3/4 : RUN pip3 install redis
 ---> Running in aa774ba9030e
Collecting redis
  Downloading https://files.pythonhosted.org/packages/f5/00/5253aff5e747faf10d8ceb35fb5569b848cde2fdc13685d42fcf63118bbc/redis-3.0.1-py2.py3-none-any.whl (61kB)
Installing collected packages: redis
Successfully installed redis-3.0.1
Removing intermediate container aa774ba9030e
 ---> 47a0f1ce8ea2
Step 4/4 : COPY ./app /app
 ---> 50908f081641
Successfully built 50908f081641
Successfully tagged myflask:latest
複製代碼

-t 指定要建立的目標路徑。 . 這裏有個點記住啦,表示是當前路徑下的Dockerfile文件,能夠指定爲絕對路徑。 編譯完後就經過docker images查看一下,就能看到myflask鏡像了,裏面能直接運行python main.py來啓動flask,而且內置了vim和redis包。

Docker Compose讓多容器成爲一個總體

咱們的每一個容器都負責一個服務,這樣容器多的時候一個個手動啓動的話是不現實的。在這種狀況咱們能夠經過Docker Compose來關聯每一個容器,組成一個完整的項目。

Compose項目由Python編寫,實現上調用了 Docker服務提供的 API 來對容器進行管理。

# 安裝docker-compose
sudo pip3 install docker-compose
複製代碼

實現能記錄訪問次數的web

在這裏,咱們經過docker-compose.yml文件來啓動flask容器和redis容器,並將兩個不一樣容器相互關聯起來。 首先在/docker/flask目錄下建立docker-compose.yml文件,內容以下:

version: '3'
services:
  flask:
      image: myflask
      container_name: myflask
      ports:
        - 8080:80
      volumes:
        - /docker/flask/app:/app
      working_dir: /app
      # 運行後執行的命令
      command: python main.py
      
  redis:
    # 若是沒有這個鏡像的話會自動下載
    image: "redis:latest"
    container_name: myredis
複製代碼

而後咱們把上面的main.py代碼修改一下,鏈接redis數據庫並記錄網站訪問次數。main.py修改後內容以下:

from flask import Flask
from redis import Redis

app = Flask(__name__)
redis = Redis(host='redis', port=6379)


@app.route("/")
def hello():
    count = redis.incr('visit')
    return f"Hello World from Flask! 該頁面已被訪問{count}次。"


if __name__ == "__main__":
    # Only for debugging while developing
    app.run(host='0.0.0.0', debug=True, port=80)
複製代碼

目前的文件結構是:

flask
├── app
│   └── main.py
└── Dockerfile
└── docker-compose.yml
複製代碼

這些編排的文件參數都是取自於Docker,基本都能看懂,其它就沒啥啦,直接命令行跑起來:

docker-compose up
複製代碼

就辣麼簡單!如今咱們在瀏覽器上訪問http://localhost:8080/就能看到結果了,而且每訪問一次這頁面都會自動增長訪問次數.

在這裏,咱們也能經過 docker ps命令查看運行中的容器:

docker ps

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                           NAMES
66133318452d        redis:latest        "docker-entrypoint.s…"   13 seconds ago      Up 12 seconds       6379/tcp                        myredis
0956529c3c9c        myflask             "/entrypoint.sh pyth…"   13 seconds ago      Up 11 seconds       443/tcp, 0.0.0.0:8080->80/tcp   myflask
複製代碼

有了Docker ComposeDocker纔是完整的Docker,有了這些之後開發簡直不要太爽,每一個容器只要維護本身的服務環境就ok了。

Docker的平常操做

鏡像經常使用操做

# 下載鏡像
docker pull name
# 列出本地鏡像
docker images
# 使用鏡像運行生成容器
docker run name:tag
# 刪除鏡像
docker rmi id/name
複製代碼

容器經常使用操做

能夠經過容器的id或者容器別名來啓動、中止、重啓。

# 查看運行中的容器
docker ps
# 查看全部生成的容器
docker ps -a
# 開始容器
docker start container
# 中止容器
docker stop container
# 重啓容器
docker restart container
# 移除不須要的容器(移除前容器必需要處於中止狀態)
docker rm container
# 進入後臺運行的容器
docker exec -it container /bin/sh
# 打印容器內部的信息(-f參數能實時觀察內部信息)
docker logs -f container
複製代碼

經過-i -t進來容器的,能夠先按ctrl + p, 而後按ctrl + q來退出交互界面組,這樣退出不會關閉容器。

docker-compose經常使用操做

# 自動完成包括構建鏡像,(從新)建立服務,啓動服務,並關聯服務相關容器的一系列操做。
docker-compose up
# 此命令將會中止 up 命令所啓動的容器,並移除網絡
docker-compose down
# 啓動已經存在的服務容器。
docker-compose start
# 中止已經處於運行狀態的容器,但不刪除它。經過start能夠再次啓動這些容器。
docker-compose stop
# 重啓項目中的服務
docker-compose restart
複製代碼

默認狀況,docker-compose up啓動的容器都在前臺,控制檯將會同時打印全部容器的輸出信息,能夠很方便進行調試。當經過Ctrl-C中止命令時,全部容器將會中止。

結語

此次接觸Docker的時間雖然不長,可是這種微服務細分的架構真的是驚豔到我了。之前玩過VM虛擬機,那個使用成本過高,不夠靈活,用過一段時間就放棄了,老老實實維護本身的本機環境。有了這個Docker之後,想要什麼測試環境都行,直接幾行代碼生成就好,一種爲所欲爲的自由。 上面寫的那些都是平常使用的命令,能應付基本的需求了,真要深刻的話建議去找詳細的文檔,我就不寫太累贅了,但願你們都能去接觸一下這個Docker,怎麼都不虧,大家也會喜歡上這小鯨魚的。

相關文章
相關標籤/搜索