Docker+Maven+Jenkins在Devops中完整應用

  很早以前,當咱們須要一個部署環境的時候,咱們可能指的是一臺PowerEdge R710 2U服務器,走一系列冗長的申請流程,而後上架到機房、調試網絡、安裝系統、調試環境、最終部署應用,就這樣過去了幾個月。
  
  接着出現了虛擬化技術,咱們在一臺內部服務器使用Citrix XenApp劃分出幾臺虛擬機,搭建了內部需求管理系統、SVN、測試環境等等,當須要新的機器時,咱們只須要再次複製出一臺虛擬機便可,如今只須要幾個小時咱們就能整理好一個環境。
  
  到了2013年,docker出現了。當我須要搭建一個Jenkins環境時,我只須要執行兩個命令 :
  
  docker pull jenkins/jenkins
  
  docker run jenkins/jenkins
  
  就能夠開始使用Jenkins了,只花了我幾分鐘時間。
  
  docker到底是什麼,咱們應該如何在軟件生產過程當中使用呢?
  
  docker基本概念
  
  咱們不打算深刻的介紹docker的基礎原理,只打算從最基本的應用的場景來講明咱們必須理解的部分。
  
  一個完整的Docker有如下幾個部分組成:
  
  Docker Client【客戶端】
  
  Docker Client是Docker架構中用戶與Docker Daemon創建通訊的客戶端。
  
  Docker Daemon【守護進程】
  
  Daemon是Docker的守護進程,Docker Client經過命令行與Docker Damon通訊,完成Docker相關操做。
  
  Docker Image【鏡像】
  
  包含了用戶定義的應用和其相關的依賴,能夠理解成是一張「系統盤」。
  
  Docker Container【容器】
  
  鏡像實例化以後就是容器,容器生成以後任何變化與鏡像無關,能夠理解成是「系統盤」安裝的「系統」。
  
  docker使用場景
  
  咱們假設的場景流程是這樣:
  
  如今咱們有一個應用,託管在Git倉庫上。管理層要求可以完整支持自動化的devops流程,因此咱們須要可以使用CI服務器從Git倉庫上拉取代碼,編譯打包以後生成鏡像,上傳至公司的私有倉庫。最後可以使用CI服務器部署至應用服務器並啓動。
  
  進階場景:
  
  最後一步改成使用容器編排軟件,拉取鏡像而且部署。而且支持灰度發佈,自動擴容(模擬場景)。
  
  預設的環境
  
  應用:SpringBoot + Maven
  
  應用服務器環境:CentOS
  
  Git倉庫:Github
  
  CI服務器:Jenkins
  
  私有倉庫:阿里雲容器鏡像服務
  
  容器編排軟件:Kubernetes
  
  實施過程
  
  在實施過程當中,咱們能夠不用太關心具體SpringBoot的代碼,只是用於說明Dockerfile如何構建。因此咱們忽略編寫應用,上傳Github的過程,假設目前已經有已經上傳好的應用,Jenkins也啓動完畢,咱們從這裏講起。
  
  pom.xml編寫
  
  pom.xml中最重要的部分就是根據Dockerfile生成鏡像的插件,下面給出關鍵部分的節點
  
  <properties>
  
  <java.version>1.8</java.version>
  
  <spring-cloud.version>Greenwich.SR2</spring-cloud.version>
  
  <docker.image.prefix>software5000<www.tdcqpt.cn /docker.image.prefix>
  
  <docker.repository>registry.cn-hangzhou.aliyuncs.com</docker.repository>
  
  </properties>
  
  <build>
  
  <plugins>
  
  <plugin>
  
  <groupId>com.spotify</groupId>
  
  <artifactId>dockerfile-maven-plugin</artifactId>
  
  <version>1.4.10</version>
  
  <executions>
  
  <execution>
  
  <id>default</id>
  
  <goals>
  
  <goal>build</goal>
  
  <goal>push</goal>
  
  </goals>
  
  </execution>
  
  </executions>
  
  <configuration>
  
  <repository>${docker.repository}/${docker.image.prefix}/${project.artifactId}</repository>
  
  <tag>${project.version}</tag>
  
  <buildArgs>
  
  <JAR_FILE>target/$www.dongfangyuld.com {project.build.finalName}.jar</JAR_FILE>
  
  </buildArgs>
  
  </configuration>
  
  </plugin>
  
  </plugins>
  
  </build>
  
  鏡像的打包其實是由com.spotify.dockerfile-maven-plugin執行,重點在configuration標籤下的幾個子標籤,稍後會好好解釋。
  
  Dockerfile
  
  Dockerfile是最基礎的docker 鏡像描述文件,能夠直接訪問官方說明。
  
  FROM openjdk:8u181-jdk-alpine
  
  ARG workdir=www.jmaguojiyL.com  /app
  
  VOLUME ${workdir}
  
  WORKDIR ${workdir}
  
  ARG JAR_FILE
  
  COPY ${JAR_FILE} app.jar
  
  EXPOSE 8081
  
  ENTRYPOINT [www.zbzxyL12.com "java","-Djava.security.egd=file:www.yfykLe2019.com /dev/./urandom","-jar","app.jar"]
  
  咱們就上面的進行一下說明
  
  FROM:是指從什麼基本鏡像繼承增長自定義配置。這是大部分Dockerfile的第一行代碼,由於Docker的推薦最佳實踐中就是強調複用,複用社區或者他人已經提供的基礎鏡像。咱們使用的是openjdk 8的基礎鏡像
  
  ARG:是指Dockerfile中的參數變量,這裏就能夠看到上面pom.xml中有一個buildArgs標籤,實際上就是用來在初始化Dockerfile時提供的參數。
  
  VOLUME:是指Docker容器運行時的掛載點,用於方便容器和宿主機器之間磁盤訪問,相似共享文件夾。
  
  WORKDIR:指定了Docker容器運行時的基礎根目錄。默認命令會從指定的目錄開始執行。
  
  COPY/ADD:這個是構建鏡像時的核心命令了,會將當前宿主機器中的文件拷貝到鏡像當中,好比本例中就是將打包好的jar複製到鏡像中。區別是ADD會自動解壓(好比war就能夠解壓出來了),COPY不會。
  
  EXPOSE:這個比較好理解,就是容器運行時,能夠對外映射的端口。(當同一個容器在同一個宿主機器運行時,能夠指定多個外部訪問端口)
  
  CMD/ENTRYPOINT:這一樣也是核心命令,做用就是在啓動時自動執行的命令。可是差別以下:
  
  CMD命令設置容器啓動後默認執行的命令及其參數,但CMD設置的命令可以被docker run命令後面的命令行參數替換
  
  ENTRYPOINT配置容器啓動時的執行命令(不會被忽略,必定會被執行,即便運行 docker run時指定了其餘命令)
  
  鏡像倉庫
  
  鏡像倉庫使用了阿里雲的容器鏡像服務
  
  咱們在pom.xml中的屬性中有兩個變量:docker.repository 和 docker.image.prefix,若是你使用的是阿里雲,那基本docker.repository固定就是registry.cn-hangzhou.aliyuncs.com,docker.image.prefix就是你建立的命名空間了。
  
  接下來是要建立鏡像倉庫。我一開始理解的鏡像倉庫有錯,我覺得全部的鏡像都是放在某一個鏡像倉庫下,實際上鏡像倉庫是指某一個鏡像多個版本的倉庫。因此針對咱們的每一個項目都要建立一個鏡像倉庫。
  
  Jenkins推送倉庫和拉取部署
  
  最終串聯的場景是這樣,當版本已經測試完畢,測試斷定能夠執行正式發佈動做,點擊Jenkins中release任務的build按鈕。而服務器則定時凌晨2點定時刪除本地鏡像而且拉取最新的鏡像而且啓動容器。
  
  鏡像版本控制,也就是docker的tag。咱們在dockerfile:build的時候,給鏡像打的版本是什麼,若是不標記默認就是latest。這樣推到倉庫以後再拉取整個過程只要不標記版本號便可。
  
  根據咱們以前的pom文件,Jenkins中這樣配置就會推送至阿里雲的鏡像倉庫。
  
  服務器定時任務執行的shell腳本,就是中止容器、刪除容器、刪除鏡像。
  
  # 中止容器
  
  docker stop eureka-server
  
  # 刪除容器
  
  docker rm eureka-server
  
  # 刪除鏡像
  
  docker rmi eureka-server
  
  # 拉取鏡像
  
  docker pull registry.cn-www.yfylhl.com hangzhou.aliyuncs.com/software5000/eureka-server
  
  # 運行鏡像
  
  docker run -d --name=eureka-server -p 9001:8081 registry.www.haojiangyule.com cn-hangzhou.aliyuncs.com/software5000/eureka-server
  
  總結
  
  這篇文章主要是將docker,maven,jenkins整合,模擬實際工做的場景將全部流程串聯在一塊兒,而且使用裏阿里雲的倉庫。可是在真正發佈的時候,還須要考慮CI/CD,灰度發佈等狀況。咱們並無在這裏徹底解決掉。由於每一個項目的環境和架構都不相同,因此仍是要根據實際具體的狀況來推動Devops。如今也正在研究Kubernetes的使用,如今可以確認的有一點。Kubernetes至關於接管了整個環境,因此咱們的服務器都是須要安裝Kubernetes的客戶端,全部的應用也都變成容器化的運行方式。因此當環境切換到docker以後,再切換至Kubernetes會更簡單,後續的維護也更加輕鬆。
  
  另外,若是本文仍是看得不是很明白能夠先了解一下docker的基本命令和使用方法,本身建個虛擬機體驗一下就能明白不少事情。java

相關文章
相關標籤/搜索