在微服務時代,服務數量及規模越來越大,服務的部署及運維的模式如果仍然採用傳統方式就會大大增加運維成本。所以微服務時代的運維方式一定是Devops模式,通過構建自動化運維釋出平臺來打通產品、開發、測試及運維流程,從而整體上提升研發效能,而這也是目前大部分公司正在做的事情。
隨著以Docker為代表的容器化技術的普及,目前Devops實踐大多會採用容器(如Docker、K8s)這樣的方式來作為微服務應用部署執行的載體,並通過容器的彈性擴充套件來實現快速擴容和縮容,從而更快地響應業務、更好地利用資源。
目前Devops最流行的部署方案是基於K8s的叢集方案,但是它本身也是基於Docker容器技術的,所以在接觸K8s技術之前,先通過本文了解下Docker及基於Docker的容器化部署。
Docker的基本概念Docker是一個開源的應用容器引擎,也是目前最流程的應用部署方式,通過它可以把應用及其依賴打包到一個可移植的映象中,然後利用Docker提供的部署機制將其釋出至任意安裝了Docker容器的系統環境中。從使用角度主要需要理解一下幾個要點如圖所示:
如上圖所示,理解Docker的使用方式需要掌握以下幾個概念:
Image(映象):它是一個可執行檔案,包含應用程式碼、依賴庫、執行環境(如JRE等)以及環境變數及配置等資訊,通過映象可以啟動一個應用,映象的構建過程通過Dockefile檔案描述。Container(容器):使用Image啟動的一個程序例項,它與映象之間為一對多的關係,一個映象可以啟動多個容器例項。Service(服務):一組提供對外服務的Container,這些Container使用同一個Image映象,它與映象為一對一、與容器為一對多的關係,Service由docker-compose檔案定義。Stack(應用):一組Service,相互協作對外提供服務,可以看作是一個完整的應用,在一些複雜的場景中會拆分為多個Stack,由docker-compose構建。Docker部署一個Spring Boot服務為了更進一步加深對上述概念的理解,這裡以一個Spring Boot應用為例演示如何通過Docker部署一個Spring Boot服務。這裡可以通過IDE建立一個簡單的Spring Boot應用並寫一個測試介面,如下圖所示:
以上為通過IDEA建立的一個最為簡單的Spring Boot應用程式,執行後啟動服務可以通過埠訪問測試介面,接下來使用Docker部署該服務,步驟如下:
建立Dockerfile檔案構建Docker映象
按照前面Docker的介紹,如果要讓Spring Boot程式執行在Docker容器上,首先需要構建Docker映象,而構建的過程則需要通過Dockerfile檔案來描述。例如在專案src/main/docker目錄建立Dockerfile檔案,程式碼如下:
FROM java:8VOLUME /tmpRUN mkdir /appADD springboot-1.0-SNAPSHOT.jar /app/springboot.jarADD runboot.sh /app/RUN bash -c 'touch /app/springboot.jar'WORKDIR /appRUN chmod a+x runboot.shEXPOSE 9090CMD /app/runboot.sh
上述Dockerfile檔案定義了執行的基礎資訊為JDK1.8、容器執行的目錄為/app、並添加了所需的Jar包等資訊,最後定義了要執行的命令為“/app/runboot.sh”指令碼。runboot.sh指令碼程式碼如下:
sleep 10java -Djava.security.egd=file:/dev/./urandom -jar /app/springboot.jar
這裡打包Spring Boot應用Docker映象的Dockerfile檔案就定義好了,為了能在Maven專案中執行Docker映象構建命令,還需要在專案pom.xml檔案新增Maven Build外掛資訊,程式碼如下:
mvn clean package docker:build
執行成功可以看到本地Docker倉庫中映象資訊,命令如下:
這表示Spring Boot程式的Docker映象已打好,需要說明的是以上命令執行是需要你的系統已經安裝Docker容器執行環境。
建立docker-compose.yml檔案
有了Docker映象,如何將映象作為容器啟動以及該映象中啟動那些服務、它的資源限制及網路使用什麼方式,這些都是docker-compose檔案定義的,其程式碼如下:
version: '3.2'services: springboot: image: springboot:1.0-SNAPSHOT hostname: springboot environment: - SPRING_PROFILES_ACTIVE=${SPRING_PROFILES_ACTIVE:-debug} ports: - "9999:9090" networks: - mynetnetworks: mynet: external: true
在上述docker compose檔案中定義了一個springboot服務,然後針對該服務描述了其所使用的Docker映象、環境變數引數、容器埠對映及網路等資訊。需要說明的是services下面還可以定義服務,stack(應用)與service(服務)的關係在docker-compose中是一對多的關係,只是這裡暫時沒有需要定義其他服務。
啟動Docker容器實現應用容器部署
通過上述準備,此時就可以通過docker-compose啟動Spring Boot應用的Docker映象,目錄切換到src/main/docker目錄,執行如下命令:
$ docker-compose up -dCreating docker_springboot_1 ... done
此時應用就已經通過Docker容器部署了,可以通過如下命令進行檢視:
$ docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES4117e4a8963e springboot:1.0-SNAPSHOT "/bin/sh -c /app/run…" 5 seconds ago Up 3 seconds 9090/tcp, 0.0.0.0:9999->9999/tcp docker_springboot_1
到這裡就大功告成了,訪問9999埠就能夠訪問到Docker容器中的Spring Boot服務了。
寫在最後:歡迎大家關注我新開通的公眾號【風平浪靜如碼】,海量Java相關文章,學習資料都會在裡面更新,整理的資料也會放在裡面。
海量面試、架構資料分享