亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
慕課專欄

目錄

索引目錄

跟 BAT 技術專家學 Docker + K8S

原價 ¥ 68.00

立即訂閱
02 成王敗寇:容器的發展之路
更新時間:2020-07-21 18:58:26
既然我已經踏上這條道路,那么,任何東西都不應妨礙我沿著這條路走下去。——康德

這篇文章我們來回顧一下 Docker 容器的發展之路,如何在巨頭中嶄露頭角,并在群雄逐鹿中脫穎而出的。在了解了這些歷史背景之后,我們就能明白 Docker 容器技術的必然性和其偉大之處。

1. 歷史環境:PaaS

我們從 2013 年開始說起,那時候云計算技術逐漸開始落地,各項主流技術也開始蓬勃發展。這里面的代表有如日中天的 AWS 和 IBM 的 OpenStack,以及后起之秀——誕生于 VMware 的 Cloud Foundry。我們下面以 Cloud Foundry 介紹一下 PaaS 的理念和核心問題。

圖片描述

Cloud Foundry 號稱是業界第一個開源 PaaS 云平臺,它支持多種框架、語言、運行時環境、云平臺及應用服務,使開發人員能夠在幾秒鐘內進行應用程序的部署和擴展,無需擔心任何基礎架構的問題。該軟件最初由VMWare開發,于2014年轉入 Pivotal 和 open source。2015年,Cloud Foundry 基金會成立。

PaaS 的核心在于為應用提供一套打包和分發機制,Cloud Foundry 為多種主流語言都提供了一種打包格式。所謂打包就是將我們的應用程序的可執行文件和啟動腳本打成一個壓縮包,然后上傳到 Cloud Foundry 的存儲中心,然后有調度器選擇將壓縮包分發到特定的虛擬機上。

以 Cloud Foundary 為例,把本地的應用部署到云端只需要一條命令:

$ cf push "應用"

在應用部署完之后,要在同一臺虛擬機上啟動來自不同用戶的多個應用。Cloud Foundry 會使用 Linux 提供的 NameSpace 和 CGroup 技術對不同的應用進行隔離和資源限制。

稍微了解容器技術的同學,應該知道 Linux 容器也是采用了這個技術。嚴格意義上來說,Cloud Foundry 也是使用的容器技術。所以在 Docker 誕生之后,Cloud Foundry 的產品經理 James Bayer 就在社區進行了一次詳細的對比,最后結論是 Docker 使用的技術和 Cloud Foundry 沒有本質區別,不值得關注,言下之意就是 Docker 難以撼動 Cloud Foundry 的市場地位。但是我們知道,這次Cloud Foundry 判斷錯了。

2. 嶄露頭角

Docker 確實是也是使用 NameSpace 和 CGroup 技術沒有錯,但是 Docker 相比于各種 PaaS 云平臺技術的核心優勢其實是它的鏡像技術。正是利用鏡像技術,Docker 在誕生之后的幾個月在各大 PaaS 軟件還沒有反應過來的時候迅速占領市場的有力地位。

圖片描述

PaaS 軟件在運行用戶的應用上和 Docker 技術沒有區別,但是在打包應用上卻顯得極為繁瑣。以 Cloud Foundry 為例,它為不同的主流編程語言定義不同的打包方式,維護起來極其繁瑣且容易出問題,用戶往往也是因為這個環節苦不堪言。那么 Docker 鏡像是如何解決這個問題呢?

很簡單,Docker 鏡像是一套操作系統文件 + 應用程序。鏡像一般都會有一個 base 鏡像,而這個 base 鏡像一般都是操作系統或者其 mini 版本。這樣如果我們的應用在云端是運行在 Centos 7.4 上面,那么我們的 base 鏡像直接使用 Centos 7.4 的操作系統文件即可,這樣就解除了用戶要保持本地環境和云上環境的底層一致的心智負擔。簡單來說,Docker 鏡像的精髓是保證了環境的一致性

除此之外,Docker 鏡像技術是一套統一的技術,我們再也不需要根據我們應用的開發語言不同而選擇不同的打包方式。在 Docker 中,我們打包鏡像使用的技術叫做 Dockerfile 技術,我們只需要按照鏡像技術的規范去編寫 Dockerfile 即可,下面是一個簡單的 Dockerfile 例子。

FROM        quay.io/prometheus/busybox:glibc
LABEL maintainer="The Prometheus Authors <[email protected]>"

COPY node_exporter /bin/node_exporter

EXPOSE      9100
USER        nobody
ENTRYPOINT  [ "/bin/node_exporter" ]

其中第一行 FROM 就是引用基礎鏡像,這里的 busybox 就是一個精簡版的操作系統鏡像,相當于 Docker 鏡像中 hello world。第 4 行將我們本地的可執行文件拷貝到鏡像中;第 6 行和第 7 行設置端口和用戶,最后一行設置應用的啟動入口。如果沒有看懂,也沒有關系,后面我們會針對 Dockerfile 的編寫有一節單獨的內容說明。

3. 群雄逐鹿

容器技術的繁榮促進其生態快速發展,這其中最重要的就是容器編排技術。對于規模稍微大一點應用,在生存環境中,需要發布的容器數量很可能極其龐大,這也就意味著如何管理容器之間的聯系和拓撲結構并不是一件簡單的事情。

舉個例子,對于一個成熟的 web 應用,首先要具備高可用架構,其次其內部可能包含數據庫、緩存等各種依賴,除此之外還有很多運維管理需求,比如監控告警等。對于這些操作,通過人工來管理肯定是不現實的。這個時候我們就需要定義容器集群的編排和部署工具。

說到容器編排,不得不提三劍客:Compose、Machine 和 Swarm。

compose

為了展示容器編排的內容,我們這里簡單展示一下如何去部署一個 Flask 應用。Flask 應用如下,定義一個 route:"/",當訪問到來的時候,redis 會做一個訪問計數。

from flask import Flask
from redis import Redis
import os

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

@app.route('/')
def hello():
    redis.incr('hits')
    return "Hello World. I am a Flask App!"

if __name__ == "__main__":
    app.run(host="0.0.0.0", debug=True)

然后我們要生成一個 Docker 鏡像,打包鏡像只需要定義一個 Dockerfile,如下:

From python:2.7
ADD . /code
WORKDIR /code
RUN pip install flask
RUN pip install redis

最后我們通過 compose.yml 來定義部署拓撲。

web:
  build: .
  command: python app.py
  ports:
    - "5000:5000"
  volumes:
    - .:/code
  links:
    - redis
redis:
  image: redis

這里是編排部署的核心,這里定義了兩個最高級別的 key: web 和 redis,也就是說 compose 定義了由兩個 ”服務“ (web 和 redis)組成的 Docker ”集群“。這里 compose 部署的 docker 集群其實是在一臺機器上的。

通過 compose 定義完 Docker 集群之后,通過 docker-compose up 就可以將服務部署起來了。限于篇幅,我們這里不對這些 yaml 的編排規范做過多解釋。

Machine

Machine 的主要功能是幫助用戶在不同的云主機提供商上創建和管理虛擬機,并在虛擬機中安裝 Docker。除了搭建環境之外,Machine 還可以幫助用戶配置 Docker 的連接參數等、管理 Docker 主機,比如啟動、關閉、重啟、刪除等操作。

Machine 簡單來說就是一個統一管理工具,成功的關鍵與否還是要看各大云廠商買不買單,接不接入。目前來看,情況不太樂觀。

Swarm

Swarm 也是 Docker 集群的編排和管理工具,和 Compose 不同的是,這里的集群是真正的由多個主機組成的集群。

Docker 生態依托 Compose、Machine 和 Swarm 重新定義了一個容器生態的 PaaS。

Marathon

但是現實往往伴隨著攪局者,這個攪局者就是 Mesosphere,Mesosphere 公司成名作是 Mesos,屬于 Apache 社區,具有和大數據調度系統 Yarn 一樣的統治力。但是 Mesos 由于其初衷是針對大數據系統的調度,讓它來處理 Docker 典型應用 long-running 應用并不是具有太大的優勢。

Mesosphere 隨之提出了針對容器系統編排的 Marathon,相比如 Docker 公司這個年輕后生,Mesosphere 具有足夠大規模集群資源管理的經驗,2014 年,Mesos 就能夠管理 10000 規模的集群調度。

Marathon 誕生之后就以 Swarm 的強力競爭者而存在,但是由于 Mesosphere 公司的 Apache 屬性,生態顯得略微封閉,同時 Swarm 作為 Docker 的親兒子,與 Marathon 競爭起來并沒有顯現出過多的頹勢,說勢均力敵也不為過。

Kubernetes

真正的轉機出現在 2015 年,隨著 Docker 技術的火熱,容器領域的玩家開始對 Docker 公司體現出的強硬態度開始不滿。自然而然地,幾家大公司開始商量對 Docker 公司的話語權進行切割,于是一個中立的基金會成立了,這個基金會叫做 CNCF。

CNCF,全名 Cloud Native Computing Foundation,由 Google、RedHat 等開源基礎設施領域玩家們共同發起。這個基金會的目的其實很容易理解:它希望以 Kubernetes 項目為基礎,建立一個由開源基礎設施領域廠商主導的、按照獨立基金會方式運營的平臺級社區,來對抗以 Docker 公司為核心的容器商業生態。而為了打造出這樣一個圍繞 Kubernetes 項目的“護城河”,CNCF 社區就需要至少確保兩件事情:

  • Kubernetes 項目必須能夠在容器編排領域取得足夠大的競爭優勢;
  • CNCF 社區必須以 Kubernetes 項目為核心,覆蓋足夠多的場景。

Kubernetes 項目就是在這樣的環境下開始飛速成長。但是這并不是說 Kubernetes 是靠著 “政治” 取勝的,Kubernetes 項目具有非常優秀的設計理念和健康的社區基礎,其對于開發者的開放態度也迅速吸引著大量的開發者。

from flask import Flask
from redis import Redis
import os

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

@app.route('/')
def hello():
    redis.incr('hits')
    return "hello world. I am a Flask App"

if __name__ == "__main__":
    app.run(host="0.0.0.0", debug=True)

4. 鹿死誰手

鹿死誰手,這兩年市場已經告訴了我們答案,贏家是 Kubernetes 了。Kubernetes 憑借其優秀的設計理念和 Google 背后的技術領導力加持,迅速在市場上占據大部分和容器相關場景。早期的容器編排軟件逐漸退出了歷史舞臺,比如阿里云的容器服務就宣布自 2019 年 12 月份將不再支持 Swarm,而形成鮮明對比的是,基于 Kubernetes 的產品形態卻越來越多。

Kubernetes 的特點主要包括如下幾個方面:

優秀的設計理念

Kubernetes 并不是憑空設計出來的,其前身來自 Google 內部的 Borg 和 Omega 系統。我們可以看一下下圖,感受一下 Borg 和 Omega 系統在 Google 內部的位置。

圖片描述

Borg 亦或是 Omega 在 Google 內部是作為底層調度系統存在的,并且是經過系統內部多年的生產環境考驗的。Kubernetes 相當于 Borg 和 Omega 針對容器的調度系統,這里的容器可以是 Docker 也可以是其他 Linux 容器,目前默認是 Docker。關于優秀的設計理念,這里簡單舉一個例子:Pod

如果我們有兩個容器 A 和 B 需要調度在一臺機器上,其中 A 和 B 各需要內存 1 G,但是這個時候機器只有 1.5 G,如果先調度 A,A 是可以被調度到機器上的,但是后面的 B 調度卻會有問題了。要想解決這個問題,如果 A 和 B 單獨調度,往往需要考慮非常多的場景和復雜的解決算法。

Kubernetes 針對這個問題提出了 Pod 的概念,Pod 是一組容器的集合,類似進程組,Pod 是 Kubernetes 中一個最小的調度單位,也就是說同一個 Pod 中的不同容器一定會被調度到一臺機器上,并且可以互相共享 NameSpace。Pod 的提出解決了很多調度需要考慮的復雜問題。

聲明式 API

所謂聲明式 API,是直接描述我們要什么或者要達到一種什么狀態。與之對于是命令式 API,命令式 API 對應的則是一個具體的動作:比如 “創建容器”,“修改容器” 等。

聲明式 API 的一個典型例子就是 SQL,在下面的 SQL 中,我們直接說明我們需要的東西是 a, b, c 三個字段,現在條件是 id > 123。但是我們并不需要管這條 SQL 如果是數據庫引擎中的真正的執行計劃是什么樣的。

select a, b, c from table where id > 123;

那么在 Kubernetes 中,我們如何去聲明我們需要什么呢?下面是一個創建兩個 nginx 副本的 Deployment。其中的 replicas 就是我們最終需要的副本數,也就是最終狀態需要有兩個副本運行,Kubernetes 如何去保證,我們不需要關心。

apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2 # tells deployment to run 2 pods matching the template
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

聲明式 API 的最大好處是解放開發者的心智負擔,讓編程變得簡單。

開放的生態

我們看一下下面的 Kubernetes 分層架構圖。
圖片描述

在上圖的最底部包含了很多開放生態,包括容器運行時,網絡插件,存儲插件、以及云廠商 Provider。這樣各大云廠商在將 Kubernetes 運行在自己的云上環境的時候就可以很方便的將自己的存儲以及網絡產品以一種插件式的方式集成到 Kubernetes 中。

Kubernetes 正是靠著這種開放的開發者生態,吸引了越來越多的開發者投入其中,并樂此不疲。反過來,生態的繁榮也促進 Kubernetes 在歷史車輪的推動下不斷向前。

5. 結語

在本篇文章中,我們回顧了 Docker 技術的誕生和發展,以及 Kubernetes 的簡介。后面專欄中,這些內容我們將會進行由淺入深的討論。

}
立即訂閱 ¥ 68.00

你正在閱讀課程試讀內容,訂閱后解鎖課程全部內容

千學不如一看,千看不如一練

手機
閱讀

掃一掃 手機閱讀

跟 BAT 技術專家學 Docker + K8S
立即訂閱 ¥ 68.00

舉報

0/150
提交
取消