1. 程式人生 > >容器部署Spring Cloud項目

容器部署Spring Cloud項目

記得 這一 time 創建app json 節點 通過 rod docke

部署eureka和config

最後我們在rancher上部署eureka和config項目,首先我們需要在本地創建這兩個項目的docker鏡像,然後推送到網易雲鏡像倉庫上。

關於使用Docker部署項目以及Rancher的安裝及使用,可以參考我另外兩篇文章,本文則不再贅述了:

  • Docker化你的SpringBoot項目
  • 安裝 Rancher2.x 並部署工作負載

在eureka項目的根目錄中,創建一個Dockerfile文件,編輯文件內容如下:

FROM hub.c.163.com/library/java:8-alpine

MAINTAINER zeroJun [email protected]

ADD target/*.jar app.jar

EXPOSE 8761

ENTRYPOINT ["java", "-jar", "/app.jar"]

然後push到git倉庫上,接著到服務器上,克隆這個倉庫,並且登錄你的網易雲鏡像倉庫賬戶:

[root@01server ~]# cd /tmp
[root@01server /tmp]# git clone [email protected]:Zero-One/eureka.git
...
[root@01server /tmp]# cd eureka/
[root@01server /tmp/eureka]# docker login -u {登錄賬號} -p {你的網易雲密碼} hub.c.163.com
[root@01server /tmp/eureka]#

註:由於windows下不太方便使用docker,所以我將項目上傳到遠程的git倉庫,然後在一臺CentOS服務器上完成這些操作。

編寫一個簡單的shell腳本來完成build鏡像的工作:

[root@01server /tmp/eureka]# vim build_eureka.sh
#!/bin/bash
mvn clean package -Dmaven.test.skip=true
docker build -t hub.c.163.com/zerojun/eureka .
docker push hub.c.163.com/zerojun/eureka
[root@01server /tmp/eureka]# 

運行腳本:

[root@01server /tmp/eureka]# sh ./build_eureka.sh

腳本執行完成後,到鏡像倉庫上可以看到鏡像已經成功push上來了:

技術分享圖片


完成eureka鏡像的build後,我們使用同樣的套路build config項目的docker鏡像。同樣的,在config項目的根目錄中,創建一個Dockerfile文件,編輯文件內容如下:

FROM hub.c.163.com/library/java:8-alpine

MAINTAINER zeroJun [email protected]

ADD target/*.jar app.jar

EXPOSE 8080

ENTRYPOINT ["java", "-jar", "/app.jar"]

並且修改配置文件中eureka的地址為服務名稱,如下:

eureka:
  client:
    service-url:
      defaultZone: http://eureka:8761/eureka/  # 修改為rancher上的服務名稱

然後push到git倉庫上,接著到服務器上,克隆這個倉庫,由於之前已經登錄過網易雲鏡像倉庫賬戶,所以不用登錄了:

[root@01server /tmp]# git clone [email protected]:Zero-One/config.git
...
[root@01server /tmp]# cd config/
[root@01server /tmp/config]# 

同樣編寫一個簡單的shell腳本來完成build鏡像的工作:

[root@01server /tmp/config]# vim build_config.sh
#!/bin/bash
mvn clean package -Dmaven.test.skip=true
docker build -t hub.c.163.com/zerojun/config .
docker push hub.c.163.com/zerojun/config
[root@01server /tmp/config]# 

運行腳本:

[root@01server /tmp/config]# sh ./build_config.sh

腳本執行完成後,此時鏡像倉庫上就有eureka和config的鏡像了:
技術分享圖片

默認push的鏡像都是私有的訪問權限,我們需要設置為公開的,否則無法被外部訪問:
技術分享圖片

點擊鏡像可以查看到鏡像倉庫詳情,復制鏡像的下載地址:
技術分享圖片

到rancher上部署工作負載:
技術分享圖片

部署完成:
技術分享圖片

使用瀏覽器看看是否能訪問到eureka的信息面板:
技術分享圖片

eureka部署成功後,使用同樣的方式去部署config:
技術分享圖片

不過我這裏部署config失敗,錯誤日誌如下,提示無法啟動內嵌的Tomcat:
技術分享圖片

嘗試多次更改配置後,最後發現原來在pom.xml中,需要增加如下依賴(然而我本地沒這個依賴運行卻是正常的):

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
</dependency>

並且需要修改配置文件如下:

spring:
  application:
    name: config
  cloud:
    config:
      server:
        git:
          uri: https://gitee.com/Zero-One/config-repo
          username: username
          password: password
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: username
    password: password
eureka:
  client:
    service-url:
      defaultZone: http://192.168.190.130/eureka/  # 修改為主機ip
  instance:
    prefer-ip-address: true  # 讓eureka上的地址能夠跳轉到實例的ip地址
management:
  endpoints:
    web:
      exposure:
        include: "*" 

修改之後,需要重新push代碼並build鏡像,接著再到rancher上重新部署,這次就部署成功了:
技術分享圖片

也成功在註冊中心註冊上了:
技術分享圖片

但是我在瀏覽器上嘗試去訪問配置文件的時候無法訪問,錯誤提示無法克隆倉庫:

Cannot clone or checkout repository: https://gitee.com/Zero-One/config-repo

瀏覽器返回的信息如下:
技術分享圖片

經過一番排查後,發現是這個容器內無法ping通外網,所以無法克隆遠程的倉庫。確定問題後,馬上查找不能ping通外網的原因。發現是因為Alpine系統使用了musl libc,與其他Linux發行版使用的glibc實現會有所不同,即musl實現的DNS服務不會使用resolv.conf文件中的search和domain兩個配置。於是進入到容器中手動配置一下DNS解析,如下:

# vi /etc/resolv.conf
nameserver 218.2.135.1
nameserver 202.102.24.35

另一個方法是到rancher上修改容器的網絡設置,這種方式會方便一些,因為容器會經常銷毀、重建,每次都手動去配置DNS比較麻煩。如下:
技術分享圖片

註:使用這種方法會導致無法使用rancher的服務發現功能,也就是不能配置rancher裏的服務名了,只能配置主機的ip地址

問題解決後,這時終於能夠成功訪問到配置文件了:
技術分享圖片


構建eureka高可用服務

在上一小節中,我們完成了eureka和config服務的部署,也解決了一些坑,但是還有個問題,就是目前eureka是單點的。eureka作為整個服務的註冊中心,必然是需要高可用的,所以本小節我們來看看如何構建eureka高可用服務。首先創建application-eureka1.yml和application-eureka2.yml兩個配置文件,如下:
技術分享圖片

application-eureka1.yml內容如下:

eureka:
  client:
    service-url:
      defaultZone: http://eureka2:8762/eureka/
    register-with-eureka: false
  server:
    enable-self-preservation: false
spring:
  application:
    name: eureka
server:
  port: 8761

application-eureka2.yml內容如下:

eureka:
  client:
    service-url:
      defaultZone: http://eureka1:8761/eureka/
    register-with-eureka: false
  server:
    enable-self-preservation: false
spring:
  application:
    name: eureka
server:
  port: 8762

application.yml文件內容如下,默認選擇eureka1:

spring:
  profiles:
    active: eureka1

然後push這些改動到遠程的git倉庫上,然後到服務器上拉取代碼並重新build鏡像:

[root@01server ~]# cd /tmp/eureka/
[root@01server /tmp/eureka]# git pull origin master
...
[root@01server /tmp/eureka]# sh ./build_eureka.sh
[root@01server /tmp/eureka]#

鏡像制作完成並推送到倉庫上後,到rancher上刪除之前的eureka,然後部署eureka1:
技術分享圖片

接著部署eureka2:
技術分享圖片

相對的,config也需要修改一下配置文件,需要增加eureka節點,如下:

eureka:
  client:
    service-url:
      defaultZone: http://192.168.190.130:8761/eureka/,http://192.168.190.130:8762/eureka/
  instance:
    prefer-ip-address: true

修改完之後,也需要重新build,重新部署一下:
技術分享圖片

至於config的高可用這裏就不演示了,因為config也屬於一個服務,只需要部署多個config註冊到eureka上就可以實現高可用了


構建product服務

這一小節我們來部署product服務,首先需要修改配置文件,將mysql、rabbitmq的地址都改為線上容器能夠連接的地址,註意,必須是確認是能夠連接到的地址,否則product服務是啟動不了的。修改bootstrap.yml文件內容如下:

spring:
  cloud:
    config:
      discovery:
        enabled: true
        service-id: CONFIG
      profile: dev
  application:
    name: product
eureka:
  client:
    service-url:
      defaultZone: http://eureka1:8761/eureka/,http://eureka2:8762/eureka/
  instance:
    prefer-ip-address: true

修改遠程git倉庫上的product-dev.yml文件內容如下:

spring:
  application:
    name: product
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: password
    url: jdbc:mysql://192.168.190.129:3306/springcloud_sell?characterEncoding=utf-8&useSSL=false
  jpa:
    show-sql: true
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: username
    password: password

與之前的過程類似,在product項目的根目錄中,創建一個Dockerfile文件,編輯文件內容如下:

FROM hub.c.163.com/library/java:8-alpine

MAINTAINER zeroJun [email protected]

ADD sell_product-server/target/*.jar app.jar

EXPOSE 8080

ENTRYPOINT ["java", "-jar", "/app.jar"]

然後將代碼push到git倉庫上,到服務器上,拉取代碼並編寫shell腳本build 及上傳docker鏡像:

[root@01server ~]# cd /tmp
[root@01server /tmp]# git clone [email protected]:Zero-One/product.git
...
[root@01server /tmp]# cd product/
# 因為order服務需要用到product服務裏的client模塊所以需要安裝一下
[root@01server /tmp/product]# mvn clean package -Dmaven.test.skip=true install  
[root@01server /tmp/product]# vim build_product.sh
#!/bin/bash
mvn clean package -Dmaven.test.skip=true
docker build -t hub.c.163.com/zerojun/product .
docker push hub.c.163.com/zerojun/product
[root@01server /tmp/product]# sh ./build_product.sh
...
[root@01server /tmp/product]# 

鏡像推送完成後,記得需要將訪問權限設置為公開的,如下:
技術分享圖片

鏡像準備好後,到rancher上,部署服務:
技術分享圖片

如果你的product服務,需要通過域名訪問外網服務的話,記得進入容器中手動配置一下DNS解析地址:

# vi /etc/network/resolv.conf
nameserver 218.2.135.1
nameserver 202.102.24.35

或設置容器的網絡:
技術分享圖片

部署成功:
技術分享圖片

通過瀏覽器測試接口成功:
技術分享圖片


構建order服務

構建完product服務後,這一小節我們來部署order服務,首先需要修改配置文件,將mysql、rabbitmq、zipkin的地址都改為線上容器能夠連接的地址,註意,必須是確認是能夠連接到的地址,否則order服務是啟動不了的。修改bootstrap.yml文件內容如下:

spring:
  cloud:
    config:
      discovery:
        enabled: true
        service-id: CONFIG
      profile: dev
  application:
    name: order
eureka:
  client:
    service-url:
      defaultZone: http://eureka1:8761/eureka/,http://eureka2:8762/eureka/
  instance:
    prefer-ip-address: true

修改遠程git倉庫上的product-dev.yml文件內容如下:

spring:
  application:
    name: order
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: password
    url: jdbc:mysql://192.168.190.130:3306/springcloud_sell?characterEncoding=utf-8&useSSL=false
  jpa:
    show-sql: true
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: username
    password: password
  redis:
    port: 6379
    host: 127.0.0.1     
    stream:
      bindings:
        myMessageOutput:
          group: order
          content-type: application/json
  zipkin:
    base-url: http://127.0.0.1:9411/
    sender:
      type: web
  sleuth:
    sampler:
      probability: 1

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 6000
      circuitBreaker:
        enabled: true
        requestVolumeThreshold: 10
        sleepWindowInMilliseconds: 10000
        errorThresholdPercentage: 60

feign:
  client:
    config:
      default:
        connectTimeout: 5000
        readTimeout: 5000
        loggerLevel: basic
  hystrix:
    enabled: true

logging:
  level:
    org.springframework.cloud.openfeign: debug

env:
  dev

在order項目的根目錄中,創建一個Dockerfile文件,編輯文件內容如下:

FROM hub.c.163.com/library/java:8-alpine

MAINTAINER zeroJun [email protected]

ADD sell_order-server/target/*.jar app.jar

EXPOSE 8080

ENTRYPOINT ["java", "-jar", "/app.jar"]

然後將代碼push到git倉庫上,到服務器上,拉取代碼並編寫shell腳本build 及上傳docker鏡像:

[root@01server ~]# cd /tmp/
[root@01server /tmp]# git clone [email protected]:Zero-One/order.git
...
[root@01server /tmp]# cd order/
[root@01server /tmp/order]# vim build_order.sh
#!/bin/bash
mvn clean package -Dmaven.test.skip=true
docker build -t hub.c.163.com/zerojun/order .
docker push hub.c.163.com/zerojun/order
[root@01server /tmp/order]# sh ./build_product.sh
...
[root@01server /tmp/order]# 

鏡像推送完成後,記得需要將訪問權限設置為公開的,如下:
技術分享圖片

鏡像準備好後,到rancher上,部署order服務:
技術分享圖片

部署成功:
技術分享圖片

通過postman測試接口成功:
技術分享圖片


構建api-gateway

構建完order服務後,最後我們來部署api-gateway服務,首先需要修改配置文件,將redis、rabbitmq的地址都改為線上容器能夠連接的地址,註意,必須是確認是能夠連接到的地址,否則api-gateway服務是啟動不了的。修改bootstrap.yml文件內容如下:

spring:
  cloud:
    config:
      discovery:
        enabled: true
        service-id: CONFIG
      profile: dev
  application:
    name: api-gateway
eureka:
  client:
    service-url:
      defaultZone: http://eureka1:8761/eureka/,http://eureka2:8762/eureka/
  instance:
    prefer-ip-address: true

修改遠程git倉庫上的api-gateway-dev.yml文件內容如下:

spring:
  application:
    name: api-gateway
  redis:
    port: 6379
    host: 127.0.0.1
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: username
    password: password
zuul:
  # 全局忽略敏感頭
  sensitive-headers: 
  host:
    connect-timeout-millis: 10000
    socket-timeout-millis: 60000
  routes:
    yourProduct:
      path: /myProduct/**
      serviceId: product
  ignored-patterns:
    - /**/buyer/product/listForOrder

ribbon:
  ReadTimeout: 30000
  SocketTimeout: 30000
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 62000

在api-gateway項目的根目錄中,創建一個Dockerfile文件,編輯文件內容如下:

FROM hub.c.163.com/library/java:8-alpine

MAINTAINER zeroJun [email protected]

ADD target/*.jar app.jar

EXPOSE 8080

ENTRYPOINT ["java", "-jar", "/app.jar"]
[root@01server ~]# cd /tmp/
[root@01server /tmp]# git clone [email protected]:Zero-One/api-gateway.git
...
[root@01server /tmp]# cd api-gateway/
[root@01server /tmp/api-gateway]# vim build_aip-gateway.sh
#!/bin/bash
mvn clean package -Dmaven.test.skip=true
docker build -t hub.c.163.com/zerojun/api-gateway .
docker push hub.c.163.com/zerojun/api-gateway
[root@01server /tmp/api-gateway]# sh ./build_aip-gateway.sh
...
[root@01server /tmp/api-gateway]# 

鏡像推送完成後,記得需要將訪問權限設置為公開的,如下:
技術分享圖片

鏡像準備好後,到rancher上,部署api-gateway服務:
技術分享圖片

部署成功:
技術分享圖片

測試接口成功:
技術分享圖片

到此為止,我們就通過Docker和Rancher完成了整個微服務項目的部署。

容器部署Spring Cloud項目