<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # 第4章 示例:Web環境 我們所知的大多數公司都曾以一個很低的容器和宿主機比例(1~2個容器對應1臺宿主機)成功地使用過Docker。也就是說,要在生產環境中成功運行Docker,并不是必須要運行Apache Mesos或Kubernates。在本示例中,將對RelateIQ公司[\[1\]](part0010.xhtml#anchor41)使用Docker運行了一年多的一個真實Web服務器生產環境做詳細的說明。這個環境在運行Ubuntu的標準亞馬遜云服務(AWS)實例上,使用Docker支撐其CRM Web應用。當初使用Docker的原因有三:一是Docker能快速生成和銷毀容器,從而為客戶提供零停機時間部署;二是因為Docker為不同Web版本提供依賴隔離;三是Docker支持即時回滾。圖4-1所示為該環境的高層次示圖。 ![圖像說明文字](https://box.kancloud.cn/0fccb7fd306a6dbbdfd9f038d26df841_700x687.jpeg) 圖4-1 相信嗎?這個Web環境提供了如下功能:穩定的零停機時間部署、回滾、集中式日志、監控及分析JVM的一種方式。所有這些都是通過bash腳本編排Docker鏡像獲得的。圖4-2所示為主機的詳細情況。 ![圖像說明文字](https://box.kancloud.cn/97bc1526b8a6d6280e6c9924b7f92e20_700x612.jpeg) 圖4-2 這臺Web服務器運行于單臺AWS服務器上,并通過Docker運行著4個容器。部分容器被鏈接在一起,以便與Docker網橋上的其他容器進行通信。它給宿主機公開了多個端口,用于為性能分析提供HTTP服務和JVM監控。它使用了亞馬遜ELB負載均衡器(健康檢查在其上進行)。所有容器都將它們的日志保存在宿主機上,這樣現有的日志方案(SumoLogic)依舊適用,同時有一個簡單的bash編排腳本用于部署和設置新版本Web服務。 為了便于理解很多公司在生產環境中運行Docker時會遇到的問題,我們來看一些具體細節。 編排歸根到底就是做兩件事:一是獲取已安裝Docker的服務器,并且使之準備好運行容器的服務器;二是在服務器上啟動并運行容器。 該服務器使用標準的基本Ubuntu AMI(亞馬遜機器鏡像)在AWS上部署,并通過[Chef](http://www.chef.io/)的標準配置管理系統對宿主機進行設置。其設置過程與當下的多數環境完全相同。服務器啟動之后,Chef就會運行并設置ssh用戶、ssh密鑰,然后通過其包安裝器安裝基礎包(如iostat),安裝并配置監控代理(本例中是Datadog),集合一些臨時磁盤空間用于數據或日志存儲,安裝并配置日志代理(SumoLogic),安裝最新版Docker,最后創建bash設置腳本,并配置一個cron任務來運行它。 Chef在服務器上運行之后,宿主機就準備好在其上運行機器所需的任何容器了。Chef還配置了監控和日志軟件,用于未來的調試。這個環境可以運行任何類型的容器服務,與當下運行的大多數服務器環境,甚至是物理環境也一般無二。現在,Docker已經安裝完畢,宿主機也準備好核心操作工具,下面就可以讓宿主機上的容器開始運行Web應用了。 早期運行Docker的大多數公司一般都是使用bash腳本來設置容器的,這個環境也不例外。這個環境使用一個cron任務,每5分鐘運行一個bash腳本來進行容器的所有編排工作。腳本的核心功能是正確地設置容器并拉取最新版的Web服務器鏡像。我們來深入看一下所使用的腳本片段。 這個腳本完成以下操作。 (1)檢查容器是否正在運行(通常是的,這主要用于新機器的情況)。 (2)如果容器未運行,則部署Hipache和Redis容器并將它們鏈接在一起。 (3)拉取最新版的Web服務器鏡像并運行。 (4)等待Web服務器健康檢查通過,然后再將其添加到負載均衡器中。 (5)一旦上述操作成功,給服務器上的迷你負載均衡器`hipache`發送一條消息(本例中是使用netcat運行一個`redis-cli`命令),告知Docker為之分配的隨機端口和IP地址。 (6)保持舊容器運行,以便在需要時進行回滾。 (7)清除舊鏡像。 下面是腳本的一些片斷(為適合閱讀,刪除了部分代碼): ``` #!/bin/bash # 檢查Hipache容器 STATE=$(docker inspect hipache | jq ".[0].State.Running") if [[ "$STATE" != "true" ]]; then set +e docker rm hipache >/dev/null 2>&1 set -e mkdir -p /logs/hipache/ docker run -p 80:80 -p 6379:6379 --name hipache -v /logs/hipache:/logs -d repo.com/hipache echo "$(date +"%Y-%m-%d %H:%M:%S %Z") lpush frontend:* default" sleep 5 (echo -en "lpush frontend:* default\r\n"; sleep 1) | nc localhost 6379 fi # 拉取最新鏡像 IMAGE_ID=$(docker images | grep ${IMAGE_NAME} | grep $REMOTE_VERSION | head -n 1 | awk '{print $3}') if [ -z $IMAGE_ID ]; then docker pull $DOCKER_IMAGE_NAME fi echo $REMOTE_VERSION >$VERSION_FILE # 啟動新容器 echo "$(date +"%Y-%m-%d %H:%M:%S %Z") launching $DOCKER_IMAGE_NAME, logging to $LOG_DIR" mkdir -p $LOG_DIR NEW_WEBAPP_ID="abcdefghijklmnopqrstuvwxyz" MAX_TIMEOUT=5 set +e until [ $MAX_TIMEOUT -le 0 ] || NEW_WEBAPP_ID=$(docker run -P -h $(hostname) --link hipache:hipache $(dockerParameters $BRANCH) -d -v $LOG_DIR:/logs $DOCKER_IMAGE_NAME); do echo -n "." sleep 1 let MAX_TIMEOUT-=1 done set -e # 檢查Web應用容器是否已啟動 NEW_WEBAPP_IP_ADDR=$(docker inspect $NEW_WEBAPP_ID | jq '.[0].NetworkSettings.IPAddress' -r) if [ -z "$NEW_WEBAPP_IP_ADDR" -o "$NEW_WEBAPP_IP_ADDR" = "null" ]; then echo "$(date +"%Y-%m-%d %H:%M:%S %Z") no new webapp ip, failed to start" # send_deploy_message $HOSTNAME $BRANCH $IMAGE_NAME "error" send_webhook $HOSTNAME $BRANCH $BUILD_ID $BUILD_NUMBER "failure" exit 1 fi echo -n "$(date +"%Y-%m-%d %H:%M:%S %Z") new instance $NEW_WEBAPP_ID starting, on ip $NEW_WEBAPP_IP_ADDR" # 5分鐘 MAX_TIMEOUT=300 HEALTH_RC=1 set +e until [ $HEALTH_RC == 0 ]; do if [ $MAX_TIMEOUT -le 0 ]; then echo "$(date +"%Y-%m-%d %H:%M:%S %Z") failed to be healthy within 5 minutes, killing and exiting..." docker kill $NEW_WEBAPP_ID docker rm $NEW_WEBAPP_ID # send_deploy_message $HOSTNAME $BRANCH $IMAGE_NAME "error" send_webhook $HOSTNAME $BRANCH $BUILD_ID $BUILD_NUMBER "failure" exit 1 fi ${SCRIPT_HOME}/health.sh $NEW_WEBAPP_IP_ADDR HEALTH_RC=$? echo -n "." sleep 5 let MAX_TIMEOUT-=5 done set -e echo # 將自身作為后端添加到Redis中 (echo -en "rpush frontend:* http://${NEW_WEBAPP_IP_ADDR}:${WEBAPP_PORT}\r\n"; sleep 1) | nc localhost 6379 # 確保自己是Redis的第一個后端 (echo -en "lset frontend:* 1 http://${NEW_WEBAPP_IP_ADDR}:${WEBAPP_PORT}\r\n"; sleep 1) | nc localhost 6379 # 將Redis中所有其他后端移除 (echo -en "ltrim frontend:* 0 1\r\n"; sleep 1) | nc localhost 6379 ``` 如我們所見,這段腳本大部分都是一些很基礎的bash指令。只要有一些bash腳本的經驗,任何系統管理員或運維工程師都能完成此類編排。容器的編排可以很簡單,但必須經過幾次迭代,過一段時間腳本就會變得更強壯。即便是在出現失敗的情況下,這個腳本也能正確工作,不會將未通過健康檢查的新容器上線。隨著與Docker相關的新技術不斷出現,類似Apache Mesos和Kubernetes這樣的系統將取代bash腳本來完成編排。下面來看這個環境在其他方面是如何工作的。 只要掌握竅門,運行Docker和單一容器的宿主機網絡就很容易理解。Docker通過`docker run`命令將容器的端口公開給宿主機。服務器公開的端口包括負載均衡器監聽的80端口(ssl只傳遞到負載均衡器)、用于Java優化的優化端口、Redis用于切換負載均衡器后端的端口,以及Web服務器自身的一個端口(后續章節詳述)。服務器之外的負載均衡器只監控80端口。宿主機中的Web服務器會啟動一個隨機端口,來自80端口的請求會被Hipache代理轉發到這個端口上。 由于這是一個Web服務,存儲的需求不會太多。有時需要存儲日志、文件的緩存或加載靜態內容。本例中,使用的是宿主機的而非容器的存儲。將數據保存在宿主機上的理由很簡單。如果容器宕機了,我們仍然需要排查出現的問題。服務一般是將日志寫入到某個文件路徑中。本例中我們將Docker容器映射到宿主機文件系統中,并將持久化的日志文件從容器里重定向到宿主機上,以便未來進行日志分析。這通過`docker run`的`-v`卷參數很容易實現。 容器日志根據服務進行分類。例如,使用`/logs/Redis`、`/logs/hipache`和`/logs/webserver/`(如圖4-3所示)。這里需要特別注意,Web服務器會根據請求的日期時間戳來記錄錯誤和請求日志。容器記錄日志時,其文件名類似這樣:`/logs/webserver/2015-03-01.request.log`。如果文件存在,日志會自動追加到同一文件中。如果有另外一個或多個容器啟動,日志同樣會被追加到同一個文件中。通過Chef安裝logrotate,可防止日志無限制地增長。 ![圖像說明文字](https://box.kancloud.cn/55dcf18b6c79b3cabdddf150ece57376_700x1119.jpeg) 圖4-3 在生產環境中,通常會有一個集中式日志服務器,因此服務器上的日志只是在被收集器取走前做臨時保存。由于所有的容器都將日志寫入宿主機中,所以無須為Docker采用一項全新的日志技術。非運行Docker的環境極可能也會采用相同的日志操作方式,以保持現存監控框架的不變。在這個環境中,很容易將創建或追加的日志文件發送到中央日志服務器(Splunk、Sumologic和Loggly)上以便分析。 這里需要特別注意的是,負載均衡器監控服務器的負荷,并根據需要自動將下一個請求發送給其他可用Web服務。宿主機是通過帶有Docker插件(這里是Datadog)的宿主機上的監控代理來監控的。本示例中的監控是一個全棧監視器。這個代理監控著宿主機的使用情況,如CPU、內存、磁盤IO、JVM監控以及運行的容器數量。這個環境里的應用程序指標通過StatsD發送給中央收集器。這里的指標包括了:網頁點擊量、應用程序查詢速度以及特定功能的延遲指標。 在這個環境中,使用了一個名為Yourkit的JVM優化工具來監控堆的運行情況。這樣,運維團隊或開發人員可以將自己的優化工具連接到宿主機上,從而通過調用棧發現應用程序的深層問題。其缺點之一是,每個容器都需要有單獨的端口,如果宿主機上同時運行著兩個容器,它們的端口也不能一樣。所以需要通過一個快速的SSH或工具來檢查這個端口。類似New Relic和Sysdig(在生態系統中提到過)的這類新技術可以對其進行監控。 由于所有的應用程序依賴都存儲在容器鏡像中,運維團隊只需要管理服務器管理方面的依賴即可。這簡化了Chef配置管理框架以及用于保持環境更新的腳本數量。 這個Web服務環境可以提供零停機時間部署。零停機時間部署通過Hipache以及一個由Redis支撐的實時Web查詢引擎實現,由于Redis是單線程的,在此作為數據庫非常完美。Hipache會將HTTP會話重定向給數據庫列表中最頂部的服務器。新容器上線時,將發送一條更新列表的命令給Redis,然后這個新容器就能接收所有新的點擊。會話狀態保存于后臺數據庫中,因此容器可以短暫存活,并且不會造成客戶端狀態的丟失。 因為Docker鏡像存儲于服務器上且容器啟動速度非常快,這個環境可以非常容易地在需要時回滾舊代碼。由于宿主機上保存著多個容器,很容易使用類似腳本或其他編排工具來啟動舊容器并取代新(錯誤部署的)容器。 RelateIQ已經在生產環境中運行本章所描述的設置一年多了,取得了巨大的成功。他們的團隊將標準的運維工具應用到Docker中,創造出一個功能完整的Web編排層。使得他們無須進行重大的基礎性變更即可嘗試新技術。他們也能將Docker和當前的基礎設施監控及日志方案相結合,使其易于在生產環境中運行。對這個環境有興趣的讀者,可以閱讀有關該環境的[博客文章](https://www.salesforceiq.com/blog/zero-downtime-pushes-say-goodbye-to-the-workout-robot/)和[訪談](http://blog.heavybit.com/blog/2015/3/23/dockermeetup)。 在第5章中,我們將講述RelateIQ如何使用AWS Beanstalk通過Docker為每個分支完整編排一個Web環境。 - - - - - - [\[1\]](part0010.xhtml#ac41) 現已被Salesforce收購并更名為SalesforceIQ。——譯者注
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看