【3.工程開發】-docker/k8s/雲

https://segmentfault.com/a/11... 容器,隔離,雲的概述。這篇對其中用途普遍的docker,k8s作詳細介紹,並給出雲搭建的生態環境體系。mysql

docker

1.與其餘VM等對比

容器發展,詳見上面提到的文章linux

chroot 1979
Linux Vserver 2001
process container 2006
LXC 2008
Docker 2013
windows container 2017

典型圖:VM與container對比,差別在於OSgit

clipboard.png

VM container
隔離 OS kernel namespace
可配額,可度量 硬件頁映射 cgroups
移動性 snapshot,image AUFS
安全 gresc patch

缺點github

隔離性相比KVM之類的虛擬化方案仍是有些欠缺,全部container公用一部分的運行庫
網絡管理相對簡單,主要是基於namespace隔離
cgroup的cpu和cpuset提供的cpu功能相比KVM的等虛擬化方案相比難以度量(因此dotcloud主要是安內存收費)
docker對disk的管理比較有限(disk quota)
container隨着用戶進程的中止而銷燬,container中的log等用戶數據不便收集

優勢:sql

輕量級的特色,其啓動快,並且docker可以只加載每一個container變化的部分,這樣資源佔用小
docker不僅是容器,高級容器引擎,應用部署平臺,應用鏡像商店

2.docker生態圈————不僅是容器

clipboard.png

  • Image 一個包含運行環境的只讀 模板
  • Container 鏡像的運行態,docker利 用容器運行應用
  • Registry 存儲容器鏡像的倉庫
  • Dockerfile 包含構建鏡像一系列命令 和參數的腳本

3.執行過程

clipboard.png

  • Docker Daemon 能夠認爲是經過 Docker Server 模塊接受 Docker Client 的請求,並在 Engine 中處理請求,而後根據請求類型,建立出指定的 Job 並運行。 Docker Daemon 運行在 Docker host 上,負責建立、運行、監控容器,構建、存儲鏡像。
  • job運行過程的做用有如下幾種可能:
    向 Docker Registry 獲取鏡像
    經過 graphdriver 執行容器鏡像的本地化操做
    啓動容器
  • graph
    Graph在Docker架構中扮演已下載容器鏡像的保管者,以及已下載容器鏡像之間關係的記錄者。
    一方面,Graph存儲着本地具備版本信息的文件系統鏡像,另外一方面也經過GraphDB記錄着全部文件系統鏡像彼此之間的關係。
    GraphDB是一個構建在SQLite之上的小型圖數據庫,實現了節點的命名以及節點之間關聯關係的記錄。它僅僅實現了大多數圖數據庫所擁有的一個小的子集,可是提供了簡單的接口表示節點之間的關係。
    Graph的本地目錄中,關於每個的容器鏡像,具體存儲的信息有:該容器鏡像的元數據,容器鏡像的大小信息,以及該容器鏡像所表明的具體rootfs。
  • networkdriver 執行容器網絡環境的配置
    networkdriver的用途是完成Docker容器網絡環境的配置,其中包括Docker啓動時爲Docker環境建立網橋;Docker容器建立時爲其建立專屬虛擬網卡設備;以及爲Docker容器分配IP、端口並與宿主機作端口映射,設置容器防火牆策略等。
  • execdriver 執行容器內部運行的執行工做
    execdriver做爲Docker容器的執行驅動,負責建立容器運行命名空間,負責容器資源使用的統計與限制,負責容器內部進程的真正運行等。在execdriver的實現過程當中,原先可使用LXC驅動調用LXC的接口,來操縱容器的配置以及生命週期,而如今execdriver默認使用native驅動,不依賴於LXC。具體體如今Daemon啓動過程當中加載的ExecDriverflag參數,該參數在配置文件已經被設爲"native"。這能夠認爲是Docker在1.2版本上一個很大的改變,或者說Docker實現跨平臺的一個先兆
  • libcontainer
    Docker架構中一個使用Go語言設計實現的庫,設計初衷是但願該庫能夠不依靠任何依賴,直接訪問內核中與容器相關的API。
    正是因爲libcontainer的存在,Docker能夠直接調用libcontainer,而最終操縱容器的namespace、cgroups、apparmor、網絡設備以及防火牆規則等。這一系列操做的完成都不須要依賴LXC或者其餘包。
    libcontainer提供了一整套標準的接口來知足上層對容器管理的需求。docker

    docker run過程
    (1) Docker Client接受docker run命令,解析完請求以及收集完請求參數以後,發送一個HTTP請求給Docker Server,HTTP請求方法爲POST,請求URL爲/containers/create? +xxx;
    (2) Docker Server接受以上HTTP請求,並交給mux.Router,mux.Router經過URL以及請求方法來肯定執行該請求的具體handler;
    (3) mux.Router將請求路由分發至相應的handler,具體爲PostContainersCreate;
    (4) 在PostImageCreate這個handler之中,一個名爲"create"的job被建立,並開始讓該job運行;
    (5) 名爲"create"的job在運行過程當中,執行Container.Create操做,該操做須要獲取容器鏡像來爲Docker容器建立rootfs,即調用graphdriver;
    (6) graphdriver從Graph中獲取建立Docker容器rootfs所須要的全部的鏡像;
    (7) graphdriver將rootfs全部鏡像,加載安裝至Docker容器指定的文件目錄下;
    (8) 若以上操做所有正常執行,沒有返回錯誤或異常,則Docker Client收到Docker Server返回狀態以後,發起第二次HTTP請求。請求方法爲"POST",請求URL爲"/containers/"+container_ID+"/start";
    (9) Docker Server接受以上HTTP請求,並交給mux.Router,mux.Router經過URL以及請求方法來肯定執行該請求的具體handler;
    (10) mux.Router將請求路由分發至相應的handler,具體爲PostContainersStart;
    (11) 在PostContainersStart這個handler之中,名爲"start"的job被建立,並開始執行;
    (12) 名爲"start"的job執行完初步的配置工做後,開始配置與建立網絡環境,調用networkdriver;
    (13) networkdriver須要爲指定的Docker容器建立網絡接口設備,併爲其分配IP,port,以及設置防火牆規則,相應的操做轉交至libcontainer中的netlink包來完成;
    (14) netlink完成Docker容器的網絡環境配置與建立;
    (15) 返回至名爲"start"的job,執行完一些輔助性操做後,job開始執行用戶指令,調用execdriver;
    (16) execdriver被調用,初始化Docker容器內部的運行環境,如命名空間,資源控制與隔離,以及用戶命令的執行,相應的操做轉交至libcontainer來完成;
    (17) libcontainer被調用,完成Docker容器內部的運行環境初始化,並最終執行用戶要求啓動的命令。

4.docker技術

clipboard.png

隔離 命名空間

一、進程命名空間:每一個命名空間獨立維護本身的進程號,父子關係結構,子空間的進程對父空間是可見的,新fork出的進程 在父命名空間和子命名空間都會生成一個進程號
 二、網絡命名空間:實現網絡隔離 徹底獨立的網絡協議視圖,包括網絡設備接口、IPV4 IPV6協議棧,路由表,防火牆規則,sockers等,採用虛擬網絡設備,將容器中的虛擬網卡綁定在本地主機的docker0的網橋上
 三、ipc命名空間 進程間交互,信號量、消息隊列,和共享內存,同一個IPC空間的能夠交互,不一樣的不能夠
 四、掛載命名空間 相似chroot, 將一個進程放到一個特定的目錄執行。容許不一樣命名空間的進程看到的文件結構不一樣,文件目錄被隔離 chroot(PATH)這個function必須具備 root的身份才能執行,執行後會將根目錄切換到PATH 所指定的地方。
五、 UTS命名空間 UNIX Time-sharing System 容許每一個容器擁有獨立的主機名和域名,默認主機名爲容器ID
 六、用戶命名空間 每一個容器能夠有不一樣的用戶和組id,能夠在容器內使用特定的內部用戶執行程序。每一個容器都有root帳號數據庫

可配額,可度量

1.cpu,io,mem等等:cgroups
2.網卡
docker建立容器的過程:
     一、建立一對虛擬接口 veth pair ,分別放在本地主機和新容器的命名空間中
     二、本地主機一端的虛擬接口 鏈接到默認的docker0網橋上,或指定網橋,並具備一個veth開頭的惟一名字
     三、容器一端的虛擬接口,放到新的容器中,修更名字爲eth0,只在容器中可見
     四、從網橋可用地址中 分配一個空閒的給 eth0,(172.17.0.2/16) 並設置默認路由網卡爲 docker0的ip (172.17.42.1/16)
clipboard.png
Veth pair 是一對虛擬網卡,從一張veth網卡發出的數據包能夠直接到達它的peer veth,二者之間存在着虛擬鏈路。不一樣網絡命名空間之間交互
Veth 網卡和常規的以太網區別僅在於xmit接口:將數據發送到其peer,觸發peer的Rx 過程。
3.disk/network quota
雖然cgroup提供IOPS之類的限制機制,可是從限制用戶能使用的磁盤大小和網絡帶寬上仍是很是有限的。
Disk/network的quota如今有兩種思路:
1).經過docker run -v命令將外部存儲mount到container的目錄下,quota從Host方向限制,在device mapper driver中更採用實際的device所以更好控制。
2).經過使用disk quota來限制AUFS的可操做文件大小。維護一個UID池,每次建立container都從中取一個user name, 在container裏和Host上用這個username建立用戶,在Host上用set quota限制該username的UID的disk. 網絡上因爲docker採用veth的方式,能夠採用tc來控制host上的veth的設備。segmentfault

移植 portable

REDHAT實現AFUS的driver(RHEL DEVIDE MAPPER)windows

  • 功能 採用AUFS做爲docker的container的文件系統,可以提供以下好處:
    1)節省存儲空間 - 多個container能夠共享base image存儲
    2)快速部署 - 若是要部署多個container,base image能夠避免屢次拷貝
    3)內存更省 - 由於多個container共享base image, 以及OS的disk緩存機制,多個container中的進程命中緩存內容的概率大大增長
    4)升級更方便 - 相比於 copy-on-write 類型的FS,base-image也是能夠掛載爲可writeable的,能夠經過更新base image而一次性更新其之上的container
    5)容許在不更改base-image的同時修改其目錄中的文件 - 全部寫操做都發生在最上層的writeable層中,這樣能夠大大增長base image能共享的文件內容。
    以上5條 1-3 條能夠經過 copy-on-write 的FS實現, 4能夠利用其餘的union mount方式實現, 5只有AUFS實現的很好。這也是爲何Docker一開始就創建在AUFS之上。
  • AUFS工做過程:
    1.啓動:bootfs+rootfs
    bootfs (boot file system) 主要包含 bootloader 和 kernel, bootloader主要是引導加載kernel, 當boot成功後 kernel 被加載到內存中後 bootfs就被umount了。
    rootfs (root file system) 包含的就是典型 Linux 系統中的 /dev, /proc,/bin, /etc 等標準目錄和文件。
    2.典型的Linux在啓動後,首先將 rootfs 設置爲 readonly, 進行一系列檢查, 而後將其切換爲 "readwrite" 供用戶使用。在Docker中,初始化時也是將 rootfs 以readonly方式加載並檢查,然而接下來利用 union mount 的方式將一個 readwrite 文件系統掛載在 readonly 的rootfs之上,而且容許再次將下層的 FS(file system) 設定爲readonly 而且向上疊加, 這樣一組readonly和一個writeable的結構構成一個container的運行時態, 每個FS被稱做一個FS層。
    3.得益於AUFS的特性, 每個對readonly層文件/目錄的修改都只會存在於上層的writeable層中。這樣因爲不存在競爭, 多個container能夠共享readonly的layer。 因此docker將readonly的層稱做 "image" - 對於container而言整個rootfs都是read-write的,但事實上全部的修改都寫入最上層的writeable層中, image不保存用戶狀態,能夠用於模板、重建和複製。

5.部署平臺

用戶每次向Git服務器的push提交都會通知給Jenkins(基於Java開發的一種持續集成工具),Jenkins觸發build。Maven(是一個採用Java編寫的開源項目管理工具,咱們最經常使用的就是該工具的構建功能)構建全部的相關代碼,包括Docker鏡像。
Maven會把完成的鏡像推送到私有的Registry保存
最後Jenkins會觸發Docker Registry pull下載鏡像到宿主機本地,並自動啓動應用容器。後端

k8s

k8s是一個容器集羣管理系統,其提供應用部署、維護、 擴展機制等功能,利用 Kubernetes 能方便地管理跨機器運行容器化的應用。其架構圖以下:
clipboard.png

  • Labels 是用於區分 Pod、Service、Replication Controller 的 key/value 鍵值對
  • master 包含Replication Controller,API Server
  • Replication Controller:
    會確保 Kubernetes 集羣中指定的 pod 副本 (replicas) 在運行, 即便在節點出錯時。經過修改 Replication Controller 的副本 (replicas) 數量來水平擴展或者縮小運行的pods,一個一個地替換pods來 rolling updates 服務,labels維度的Multiple release tracks
  • API Server 的主要聲明,包括 Pod Registry、Controller Registry、Service Registry、Endpoint Registry、Minion Registry、Binding Registry、RESTStorage 以及 Client

    clipboard.png

    Minion Registry 負責跟蹤 Kubernetes 集羣中有多少 Minion(Host):能夠對 Minion Registry Create、Get、List、Delete
    Pod Registry 負責跟蹤 Kubernetes 集羣中有多少 Pod 在運行,以及這些 Pod 跟 Minion 是如何的映射關係,對 Pod 進行 Create、Get、List、Update、Delete 操做。
    ……
    Endpoints Registry 負責收集 Service 的 endpoint,好比 Name:"mysql",Endpoints: ["10.10.1.1:1909","10.10.2.2:8834"],Create、Get、List、Update、Delete 以及 watch
    Binding Registry 綁定的 Pod 被綁定到一個 host
    Scheduler 收集和分析當前 Kubernetes 集羣中全部 Minion 節點的資源 (內存、CPU) 負載狀況,而後依此分發新建的 Pod 到 Kubernetes 集羣中可用的節點

  • Kubelet
    是 Kubernetes 集羣中每一個 Minion 和 Master API Server 的鏈接點,Kubelet 運行在每一個 Minion 上,是 Master API Server 和 Minion 之間的橋樑,接收 Master API Server 分配給它的 commands 和 work,與持久性鍵值存儲 etcd、file、server 和 http 進行交互,讀取配置信息。Kubelet 的主要工做是管理 Pod 和容器的生命週期,其包括 Docker Client、Root Directory、Pod Workers、Etcd Client、Cadvisor Client 以及 Health Checker 組件
  • Proxy
    是爲了解決外部網絡可以訪問跨機器集羣中容器提供的應用服務而設計的,從上圖 3-3 可知 Proxy 服務也運行在每一個 Minion 上。Proxy 提供 TCP/UDP sockets 的 proxy,每建立一種 Service,Proxy 主要從 etcd 獲取 Services 和 Endpoints 的配置信息,或者也能夠從 file 獲取,而後根據配置信息在 Minion 上啓動一個 Proxy 的進程並監聽相應的服務端口,當外部請求發生時,Proxy 會根據 Load Balancer 將請求分發到後端正確的容器處理。

交互:
clipboard.png
http://tiewei.github.io/cloud...

公司雲架構圖:
clipboard.png

容器

  • 靜態容器
    固定可訪問IP,不能動態漂移,容器中無代碼,擴容較快,輕量虛擬機,支持共享卷/塊設備,日誌收集與物理機同樣。
  • 有狀態容器
    k8s的statefulstes模型,能夠較好彈性伸縮,能夠動態漂移,有代碼,擴容很快,支持共享卷/塊設備(帶雲盤),固定ip。適用於對程序數據有持久化需求的服務。
  • 無狀態容器
    k8s的deployment模型,開箱即用,能夠動態漂移,急速擴容,彈性伸縮極好,只支持共享卷(ceph這種網絡分佈式磁盤),日誌遠程收集,容器名和ip不固定,適用於無狀態微服務。只支持雲平臺變動(直接的上線系統不行),不掛載雲盤

數據

小的放ceph,大的物理機映射=>網絡抖動全換成本地磁盤(不管日誌仍是數據,數據須要單獨遷移,兩種方案均可以)

網絡

docker的虛擬網絡不少種實現,原生或者插件,通常原生的overlay用的較多
sdn overlay網絡 穩定性差(ip不受限制,所以漂移也不受限制) =》物理網絡(ip受限於tor[交換機]的網絡分配,ip只能tor切換,擴容後資源不均衡)
流量到LB後,若採起sdn,會到sdn中心節點,虛擬ip和物理ip的映射,找到物理ip的宿主機器,宿主機器經過overlay與docker通訊
若物理網絡,直接到docker,docker的ip就是分配的物理ip。漂移受tor的影響指的是在ip不變的狀況下漂移。ip變化會致使日誌等問題

  • 物理網絡
    容器ip2直接到物理機(ip1,ip2=》mac1。物理機再轉發給ip
  • docker虛擬網絡原理
    1.同host:bridge的ip模式爲例
    建立虛擬網卡。同一網卡之間均可以互相通訊
    不一樣網卡之間即便配了ip路由也會隔離,用的iptable的drop
    與外網:先默認連docker0,若是網橋 docker0 收到來自 172.17.0.0/16 網段的外出包,把它交給 MASQUERADE 處理(iptable NAT)。而 MASQUERADE 的處理方式是將包的源地址替換成 host 的地址發送出去,即作了一次網絡地址轉換(NAT)
    外網反向:ip:port(不一樣虛擬ip綁定不一樣端口),docker-proxy監聽全部port,換ip1發給docker0,與ip1通訊

    clipboard.png
    2.跨主機overlay
    Docerk overlay 網絡須要一個 key-value 數據庫用於保存網絡狀態信息,包括 Network、Endpoint、IP 等。Consul、Etcd 和 ZooKeeper 都是 Docker 支持的 key-vlaue 軟件,咱們這裏使用 Consul。
    不一樣host:基於VxLAN。VxLAN 可將二層數據封裝到 UDP 進行傳輸,VxLAN 提供與 VLAN 相同的以太網二層服務,可是擁有更強的擴展性和靈活性。
    clipboard.png
    外網:爲每一個建立了eth1能夠鏈接外網。其過程和bridge的docker0訪問外網同樣
    host內部 br0仍是直接endpoint鏈接着,另外加了一個vxlan設備,與其餘host鏈接

  • VXLAN原理
    vxlan在二層包上封裝vxlan header放在UDP中發到VTEP設備上解封(header中包含24位的ID,同一ID的能夠互相通訊)
    clipboard.pngLinux vxlan 建立一個 UDP Socket,默認在 8472 端口監聽。接收到 vxlan 包後,解包,而後根據其中的 vxlan ID 將它轉給某個 vxlan interface,而後再經過它所鏈接的 linux bridge 轉給虛機。Linux vxlan 在收到虛機發來的數據包後,將其封裝爲多播 UDP 包,從網卡發出。
相關文章
相關標籤/搜索