使用Docker、CoreOS、Mesos部署可擴展的Web應用

本文轉自http://dockerone.com/article/162
【編者的話】本文作者重點介紹了如何使用Docker、CoreOS、Mesos、Vulcand、對象存儲來部署一個可擴展的Web應用,他首先介紹了為什么要選擇這些工具以及與其它工具相比這些工具的優勢。緊接著,他通過實際案例演示了整個部署過程,圖文并茂,推薦閱讀。

介紹

讓我們先來討論一下為什么我決定使用這些軟件來展示如何創建一個可擴展的Web基礎架構。

為什么選擇Docker?

那問題來了,為啥要選擇Linux容器?因為相比于虛擬機,Linux容器擁有更低的計算和存儲開銷。

Docker簡化了人們使用Linux容器的方式,并且提供一些非常實用的特性,比如Dockerfiles、Docker Hub、分層文件系統。在本文中,我將使用使用Amazon S3 API的VIPR搭建私有的Docker Registry以存儲鏡像(如我以前的帖子中描述)。

為什么選擇CoreOS?

所有的組件都會在Docker容器中運行,所以你可能會說,操作系統并沒有那么重要。但是,CoreOS有很多的優勢,具體如下:

  • 以一個單元的形式自動更新整個系統,而不是一個包接著一個包的更新(如果你的基礎設施沒有SPOF,甚至要重啟系統)
  • 包含用于發現服務的etcd,也使用Vulcand(甚至設置中需要mesos)
  • 包含了systemd和fleet,一個可以以一個init系統呈現你整個集群的工具。在這個設置中我不使用fleet,但是在其它方面我有使用它,比如幾秒內啟動elastic search集群。
  • </ul>

    為什么選擇Vulcand?

    我看到有關如何部署容器或虛擬機的很多教程,但我總是驚訝地看到,他們很少涉及基礎設施的負載均衡部分。

    在我看來,負載均衡是一個可擴展的Web應用架構的重要組成部分。如果用戶不能正常訪問你的應用,那還搞什么自動化?

    Vulcand是一個為HTTP API管理和微服務而設計的反向代理工具。Vulcand會監控etcd,并自動檢測到它需要實現新的規則,所以你不需要重新加載任何服務。只需在etcd添加正確的密鑰,然后你的服務/應用程序就可以被使用了。

    為什么選擇Mesos?

    有三種不同的方式來自動化部署Docker容器,具體如下:

    • Fleet:Fleet是一個通過Systemd對CoreOS集群進行控制和管理的工具。如果你想啟動容器或者手動指定映射到主機的端口,那Fleet是一個不錯的選擇(譯者注:Fleet的更多資料可以閱讀本文)。
    • Kubernetes:這可能是最佳的選擇之一,但現在Kuernetes還太年輕。
    • Mesos:Mesos目前已經支持Docker,它已經是一個相對穩定的平臺,并且可以用來部署其它軟件,例如Hadoop。
    • </ul>

      為什么選擇對象存儲?

      我們可以通過上面介紹的軟件來部署可擴展和高可用的應用。但是,數據怎么處理?

      結構化的內容可能會被存儲到分布式數據庫中,例如MongoDB。非結構化的內容一般會存儲在一個本地文件系統、NAS或者對象存儲。

      本地文件系統并不適合現在的場景,因為容器可能會被部署到集群的任何一個節點上。

      理論上NAS共享方案可行,但是特別復雜的。例如,NAS共享需要掛載到所有的主機上,所以你需要為每個容器指定Volume,并在特權模式下運行容器...當容器啟動而NAS共享不可用時,容器內的應用程序需要能夠處理相關問題。

      然而,對象存儲卻可以在任何容器的任何應用中使用,并且是高可用的,因為我們使用了負載均衡器,它不需要任何配置,這也可以加快應用程序的開發周期。為什么了?因為開發者不需要考慮數據的存儲方式、目錄結構管理等。

      我已經開發了一個Web應用程序,它展示了一個應用程序如何不通過數據路徑處理上傳和下載,我會在下面運行這個應用程序。

      1.png


      上圖展示了幾個不同的組件,以及我如何設置3個節點的CoreOS集群。

      我使用Keepalived來確保公共 IP 10.64.231.84是可用的,不管對應在coreos1還是coreos3節點上。

      Vulcand會運行再每個節點上,以均衡用戶和Web應用程序之間的負載,同事也可以平衡應用程序和不同的VIPR節點。

      私有的Docker Registry在coreos1節點上運行,并使用Amazon S3 API在VIPR上存儲鏡像。

      Mesos主節點(Master)和Marathon運行在coreos2節點上。

      Demo

      視頻可以點此鏈接瀏覽。

      為我的Web應用程序創建Docker鏡像

      這里是我用來構建Docker鏡像的Dockerfile:

      FROM golang
      WORKDIR /
      RUN git clone https://djannot:xxxx@github.com/djannot/s3pics.git
      WORKDIR /s3pics
      RUN go build
      EXPOSE 8080

      構建鏡像時我使用了--no-cache參數,以確保最新的源代碼是從GitHub上克隆的。

      core@coreos1 /media/share1/Dockerfiles/s3pics $ docker build --no-cache .
      Sending build context to Docker daemon 2.048 kB
      Sending build context to Docker daemon
      Step 0 : FROM golang
      ---> 1ea210e0e1f6
      Step 1 : WORKDIR /
      ---> Running in f6987b175723
      ---> 022aa96f56d0
      Removing intermediate container f6987b175723
      Step 2 : RUN git clone https://djannot:xxxx@github.com/djannot/s3pics.git
      ---> Running in 54d6a32e90ba
      Cloning into 's3pics'...
      ---> 3369bca87577
      Removing intermediate container 54d6a32e90ba
      Step 3 : WORKDIR /s3pics
      ---> Running in d875bc08eac9
      ---> 73946142ea54
      Removing intermediate container d875bc08eac9
      Step 4 : RUN go build
      ---> Running in e0bd59c1f28b
      ---> baebdd1b633e
      Removing intermediate container e0bd59c1f28b
      Step 5 : EXPOSE 8080
      ---> Running in 16d3fa9be1c5
      ---> 815b7aed2c83
      Removing intermediate container 16d3fa9be1c5
      Successfully built 815b7aed2c83

      最后,我推送鏡像到Docker registry。

      core@coreos1 /media/share1/Dockerfiles/s3pics $ docker push 10.64.231.45:5000/s3pics:2.0
      The push refers to a repository [10.64.231.45:5000/s3pics] (len: 1)
      Sending image list
      Pushing repository 10.64.231.45:5000/s3pics (1 tags)
      Image 511136ea3c5a already pushed, skipping
      Image 16386e29a1f4 already pushed, skipping
      Image 835c4d274060 already pushed, skipping
      Image 22c23ce0a90c already pushed, skipping
      Image 3f1e6432f26e already pushed, skipping
      Image 7982826b1e59 already pushed, skipping
      Image 1dafbd563f5a already pushed, skipping
      Image 7a94d87545e8 already pushed, skipping
      Image e2d60f7b3d07 already pushed, skipping
      Image 4f23222e2f74 already pushed, skipping
      Image 258b590ccdee already pushed, skipping
      Image 986643313a7b already pushed, skipping
      Image 1ea210e0e1f6 already pushed, skipping
      022aa96f56d0: Image successfully pushed
      3369bca87577: Image successfully pushed
      73946142ea54: Image successfully pushed
      baebdd1b633e: Image successfully pushed
      815b7aed2c83: Image successfully pushed
      Pushing tag for rev [815b7aed2c83] on {http://10.64.231.45:5000/v1/repositories/s3pics/tags/2.0}

      我已經指定了一個tag(2.0),以確保集群中的每個節點都會從Docker Registry獲取最新版本。

      部署Mesos應用程序

      現在,讓我們使用Docker鏡像部署一個Mesos應用:

      POST http://<Mesos Marathon IP>:8080/v2/apps

      { "id": "s3pics", "cmd": "cd /s3pics; ./s3pics -AccessKey=denis@ad.forest -SecretKey=xxxx -EndPoint= 當Mesos應用程序啟動后,Mesos Marathon UI就會顯示應用程序的狀態。

      2.png


      幾秒鐘之后,應用部署成功,Docker主機和端口顯示在UI中。

      3.png


      訪問web應用

      使用在Marathon UI顯示的信息,我可以訪問URL為http://coreos1.ad.forest:31000的Web應用程序。

      4.png


      當應用程序運行時頁面左上角會顯示容器名稱,用于上載和下載的圖片的Amazon S3終端(endpoint)會顯示在左下角,并表明ViPR用于存儲數據。

      我們現在可以上傳圖片了。

      5.png


      下面是由Web應用程序發送到瀏覽器的代碼,以讓瀏覽器直接上傳圖片到對象存儲平臺。

      var files =  $("#file")[0].files;
      var reader = new FileReader();
      reader.onload = function(event){
      var content = event.target.result;
      try {
      $.ajax({
        url: 'http://bucket1.denisnamespace.ns.viprds.ad.forest:80/pictures/B6C3OuVCIAEfwjm.jpg',
        data: content,
        cache: false,
        processData: false,
        type: 'PUT',
        beforeSend: function (request)
        {
          request.setRequestHeader('Content-Length','35964');
          request.setRequestHeader('Content-Type','binary/octet-stream');
          request.setRequestHeader('x-amz-date','Sun, 11 Jan 2015 12:53:12 UTC');
          request.setRequestHeader('host','bucket1.denisnamespace.ns.viprds.ad.forest');
          request.setRequestHeader('Authorization','AWS denis@ad.forest:iCnahEUOy8/lanI96tQYA3WKQVE=');
        },
        success: function(data, textStatus, request){
          $('#alert-success').html("Picture uploaded").show().delay(5000).fadeOut();
          },
        error: function(data, textStatus, request){
          $('#alert-danger').html("Upload failed").show().delay(5000).fadeOut();
        }
      });
      }
      catch (e) {
      alert(e);
      }
      }
      reader.readAsArrayBuffer(files[0]);


      圖片直接上傳到對象存儲平臺的事實意味著該Web應用程序中并沒有數據路徑。也就是說無需部署數百個實例應用程序就可以擴展。
      這個Web應用程序,也可用于顯示所有存儲在相應的Amazon S3的圖片。

      6.png


      圖片下方顯示的URL表明圖片可以直接從對象存儲平臺下載,而這又意味著Web應用程序不是從數據路徑直接下載。

      對象存儲是事實上的標準網絡規模應用。

      更新vulcand代理

      現在,讓我們看看如何能夠從外界訪問該Web應用程序。
      我使用Golang開發了一個小工具,同時使用Marathon API和etcd API:

      • 找到那些運行的Mesos應用程序但卻沒有相對應的在etcd中的vulcand規則,然后新建缺失的規則。
      • 找到那些存在與etdc的vulcand規則中的不再運行的Mesos應用,然后刪除。
      • </ul>

        7.png


        Web應用程序現在可以從外界訪問。(http://s3pics.ad.forest).

        8.png


        擴展Mesos應用程序

        其中Mesos之美在于它能夠輕松地擴展當前正在運行的應用程序的實例數目。

        9.png


        幾秒鐘后,20個實例正在運行。

        10.png


        我需要再次運行我的工具來更新vulcand規則。

        11.jpg


        現在,如果我刷新我的網頁瀏覽器,可以看到,在左上角顯示的容器名稱是基于服務的應用程序實例發生變化。

        12.png


        13.png


        使用Marathon UI或API時,它也可以按比例縮小的實例數并再次運行工具來更新vulcand規則。

 本文由用戶 DockerOne 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!