Docker三十分鐘快速入門(下)

阿豪聊乾貨發表於2018-01-12

一、背景

  上篇文章我們進行了Docker的快速入門,基本命令的講解,以及簡單的實戰,那麼本篇我們就來實戰一個真實的專案,看看怎麼在產線上來通過容器技術來執行我們的專案,來達到學會容器間通訊以及docker-compose學習以及docker網路模型學習的目的。

二、專案描述

  • 建立Todo應用,功能很簡單,實現建立Task關聯Task分類,以及更新Task的完成狀態的功能。

  • 專案執行後的主介面如下:

    

三、啟動專案

  • 因為是使用git管理的maven java專案,所以需要首先在伺服器上安裝java、maven、git 三大件

    傳送門:Centos7下Java開發基本環境搭建

  • Git入門教程傳送門:談談分散式版本管理工具Git

  • 接著把github上的專案原始碼clone到本地

    git clone https://github.com/hafizzhang/mysql-spring-boot-todo.git
  • 進入到專案根目錄

    cd mysql-spring-boot-todo
  • 使用maven命令進行打包專案並且使用docker命令進行build映象

    mvn clean package docker:build
  • 用容器啟動mysql 5.6版本

    docker run --name mysql -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=tododb -e MYSQL_USER=user -e MYSQL_PASSWORD=pass -d mysql:5.6
  • 檢視mysql日誌輸出,確保mysql服務啟動沒有問題

    docker logs mysql (因為上步中我們已經指定了執行mysql容器的名稱為mysql,所以這裡可以直接用容器名檢視日誌)
  • 用容器啟動todo映象

    docker run -p 8080:8080 --name todo -d hafiz/todo-demo:1.0.0
  • 檢視todo容器的日誌,觀察容器是否啟動成功

    docker logs todo

    我們會發現出現了以下錯誤:

    這就說明了,同一個主機上的各個容器之間是相互隔離的,也就是他們直接不能直接相互訪問,那我們怎麼解決這個問題呢?最簡單的辦法我們可以直接在啟動容器的時候指定--link引數把該容器連結到mysql容器上(雖說這種方式已經官方已經不推薦,但是對於同一個主機的不同容器間的通訊卻是最簡單的,後面會介紹別的方式實現),這樣我們的目標容器todo就可以跟mysql源容器進行通訊了,來,說幹就幹

    docker rm -f todo 首先刪除已經存在的容器todo
    docker run -p 8080:8080 --name todo --link mysql -d hafiz/todo-demo:1.0.0

    再檢視todo容器啟動的日誌,發現可以成功啟動了,然後開啟瀏覽器輸入主機ip:8080可以看到todo的執行主介面

  • 我們在todo主介面上新增一條記錄,然後通過mysql容器進行檢視已經新增的記錄,如下:

    docker exec -t -i mysql bash 進入到mysql容器
    mysql -uuser -ppass 使用者名稱為user,密碼為pass
    select category, IF(complete,'true','false') complete, name from todo_item;

    可以看到我們儲存的記錄已經進到mysql中了

四、使用link實現Docker容器間的通訊的原理

todo專案和mysql專案的啟動後通訊模型如下:

  

那我們上面已經通過link方式實現了todo容器可以訪問相同主機的mysql容器,那麼這種方式如何實現的呢?

我們檢視todo容器的/etc/hosts檔案就會明白了,如下:

  

可以看出link的工作原理是在todo的hosts檔案中寫入mysql容器的地址資訊

使用容器連線的好處

  • 執行在同一主機的獨立容器間可以相互通訊

  • 容器間建立一個安全通訊隧道而不需要暴露容器的任何埠

五、使用Docker Compose管理多個容器

為什麼需要使用Docker Compose管理多個容器

答:當多個容器相互之間需要通訊時,手動配置容器間連線變得非常複雜,而且官方也已經不推薦使用了。

什麼是Docker Compose

  • Docker Compose是一個定義和管理多個Docker容器的工具

  • 它通過YAML檔案定義Docker應用執行時的資訊,如:埠、網路等。

  • 使用Docker Compose,一個簡單命令可以管理多個容器應用。

Docker Compose使用場景

  • 快速構建開發環境

  • 自動化測試環境

  • 單一主機部署多個容器

安裝Docker Compose

如何使用Docker Compose

  • 定義構建各個映象所需的Dockerfile檔案

  • 定義docker-compose.yml檔案

  • 在docker-compose.yml和Dockerfile檔案所在的目錄下,通過docker-compose up [-d]啟動docker-compose.yml 所定義的多個Docker應用

深入瞭解Docker Compose

  • 幾個重要的Docker Compose命令

    • docker-compose up 啟動YAML中定義的所有容器

    • docker-compose ps [-a] 檢視[所有的]執行的容器

    • docker-compose logs containerId/containerName 檢視執行的容器的日誌

    • docker-compose stop containerId/containerName 停止執行的容器

    • docker-compose rm containerId/containername 刪除已停止的容器

    • docker-compose build 重新建立所有的映象

  • Tips

    • docker-compose只有在Docker映象不存在的時候才建立映象

    • 更新Dockerfile後一定要執行docker-compose build重新建立映象才能生效

六、Docker網路模型

  

docker daemon啟動以後,會預設建立一個名稱為docker0的網橋,容器預設情況下是通過這個docker0網橋來和主機進行通訊的。

docker網路模型有以下幾種分類:

1. None網路模型

  

  • 實現了最大限度的網路隔離

  • 容器間不能通過網路通訊提供服務或者提供網路服務

  • 儘管None網路模型可以提供非常好的安全隔離,但其適用場景非常有限

2. Bridge網路模型(預設)

  

  • Bridge網路模型下預設有兩個網路介面:loopback和eth0

  • 同一主機上相同bridge網路的所有容器可以相互間通訊

  • 同一主機上不同bridge網路上所有容器間不能直接通訊

  • 不同主機間bridge網路的容器不能直接通訊

  • 演示:

    docker run --rm -d --net bridge --name c1 imageName:imageTag sleep 1000
    docker run --rm -d --net bridge --name c2 imageName:imageTag sleep 1000
    docker exec -ti c1 ping c2 ip  顯示網路訪問成功

3. Host網路模型(和主機共享網路)

  • Host網路安全性相對於其他網路模型如:None、Bridge較低

  • Host網路跟主機共享網路棧

  • 所有主機可見的網路介面對以Host網路模型執行的容器均可見

  • 容器間網路不具有隔離性

  • 由於使用Host網路容器的請求無需經過docker0和Iptable的處理,它提供非常好的效能

  • 演示:

    docker run --rm -d --net host --name c1 imageName:imageTag sleep 1000
    docker exec -ti c1 ping 主機ip 

4. Overlay網路模型

  • 支援多主機間容器直接通訊

  • Swarm模式下使用overlay網路模型無需外部鍵值儲存系統

  • 非Swarm模式下使用overlay網路模型需要外部鍵值儲存系統,如Consul等

Docker網路管理命令

  • docker network ls 產看當前所有的docker網路

  • docker network create [-d] network-name 建立指定驅動的網路

    • -d選項可選,用來指定建立網路使用的驅動型別,但好像只能建立bridge驅動的網路

  • docker network rm network-name 刪除自定義網路

  • docker network inspect network-name 檢視指定docker網路的資訊

  • docker network connect network-name containerId/containerName 把指定的容器連結到指定的網路上

七、使用Docker Compose管理網路

  • 預設執行docker-compose時將建立新網路

  • 新網路名字以docker-compose.yml當前所在目錄名字跟預設driver的組合,比如當前目錄為test,則docker-compose.yml不指定具體網路的時候,建立的網路名稱為:test_default

  • 可以建立自定義的網路,在docker-compose.yml中自定義networks,如下圖的標註1

  • 指定service使用特定的網路,如下圖的標註2

    

八、如何在產線執行容器化的服務

我們要想在產線去執行容器叢集,那我們首先需要COE(Container Orchestration Engine)工具。

  

1. COE的主要功能如下:

  • 主機配置(Provisioning)

  • 容器編排

  • 自我修復

  • Scale up/down 容器

  • 暴露服務給外界

  • 服務發現

2. COE工具:

  • Docker Swarm Mode

    • 原生整合Docker Engine的叢集管理

    • 去中心化的設計

    • 宣告式服務模型

    • Scale up/down 服務

    • 支援多主機網路

    • 服務發現

    • 負載均衡

    • 安全性高

    • 支援滾動升級

  • Kubernates

  • Mesos/Marathon

    • 高可用

    • 支援有狀態服務

    • 支援多種容器引擎

    • 服務發現和負載均衡

    • 健康檢測

    • 事件訂閱

    • 豐富的API支援

    • 容器排程約束

  • Hashicorp Nomad

    • 簡單且輕量級

    • 多雲支援

    • 維護簡單

    • 支援混合工作負載

    • 高可用

    • 支援多區域多資料中心

3. COE選擇的準則

  • 抽象程度(Level of abstraction):支援混合還是隻支援基於容器的工作負載(Hybrid Workloads)

  • 工具鏈(Tooling):編排工具相關生態圈,工具的整合程度

  • 架構(Architecture): 是否支援高可用、高穩定性以及災難恢復

4. 如何選擇COE工具

  • 是否支援企業DevOps框架和編排

  • 是否提供豐富的API

  • 叢集支援主機數量大小

  • 容器執行在什麼平臺?物理機、私有云還是公有云?

  • 是否具有自我修復功能

  • 是否提供服務負載均衡

  • 如何Provision容器

  • 運維複雜性高低

  • 是否支援混合工作負載

  • 生態圈發展是否成熟

  • 社群是否活躍

5. 監控及指標

常用監控工具

  • Sensu

  • Prometheus

  • Grafana

  • Influxdb

  • Telegraf

  • Zabbix

  • cAdvisor

  • Sysdig

6. 日誌

  • EFK(Elasticsearch Fluentd Kibana)

  • ELK (Elasticsearch Logstash Kibana)

  • Graylog

九、總結

  通過本文,我們就知道如何讓同一主機上的不同容器進行通訊,如何進行docker 網路的管理,Docker的網路模型都有哪幾種?如何在docker-compose.yml檔案中自定義docker網路,如何給其中定義的service指定使用自定義的網路?如何在產線執行容器化服務?如何選擇COE工具?以及容器化以後我們要注意的地方。對於不同主機間的容器通訊,本文沒有設計,以後有機會,我們再來慢慢談起。

相關文章