javascript
Spring Cloud开发实践 - 04 - Docker部署
Docker的安裝和命令可以參考?https://www.cnblogs.com/milton/p/9866963.html .?
資源規劃
這一步要區分傳統資源和Docker資源, 為后面的細節定好基礎. 因為Docker的特性, 適合于占CPU和MEM資源, 但是對HDD資源要求不高的應用. 不適合用于對數據有持久化要求以及安全性要求較高的應用, 例如MySQL和日志系統.
在開發和測試環境, 你可以隨手啟動一個MySQL來配合開發, 但是在生產環境目前還是不太現實的, 需要整套運維工具跟進對Docker的配合后才能實現足夠的安全性.?
生產環境涉及的資源如下:
- 堡壘機, VPN, 網關, 用于生產環境的底層訪問控制, >= 1
- 存檔備份, 低性能大容量帶冗余的存儲, >=1
- CI工具, Jenkins, 用于在生產環境進行自動部署, =1
- RMDB 數據庫, MySQL等, >=2
- NoSQL 數據庫, MongoDB, Redis 等, >=2
- 緩存服務, Ehcache, Redis等, >=1
- 文件服務, FastDF等, >=1
- 配置和服務注冊服務, Zookeeper, EurekaServer等, >=3
- 日志服務, Kafka等, >=1
- 搜索服務, Elasticsearch等, >=1
- JVM節點, 這是用于運行jar項目的節點, =N
- WEB服務, Nginx等, >=2
其中與業務開發關系最大, 適合用Docker進行部署的就是JVM節點部分, 還有緩存服務, WEB服務, 日志服務, 配置和注冊服務, 也是適合通過Docker管理的. 這邊假定僅僅使用Docker配置JVM節點.
網絡劃分
三類網絡的私有地址范圍
10.0.0.0? ? ? ?- 10.255.255.255
172.16.0.0? ?- 172.31.255.255
192.168.0.0 - 192.168.255.255
與環境現有子網綜合考慮. 需要達到的目標是
- 每個容器有獨立的 IP,運維就可以像連接虛機一樣通過ssh連接容器
- 需要跨宿主機之間的容器通信
- 訪問控制, 安全性和隔離性
- 性能損失盡量小
如果是在IDC自建機房的規劃, 網絡的實現方案可以參考這一篇?http://www.cnblogs.com/sammyliu/p/5926343.html?,
方案一:?基于bridge
將默認的docker bridge網橋替換為 linuxbridge, 把 linuxbridge 網段的 ip 加入到容器里, 實現容器與傳統環境應用的互通.
首先在宿主機上添加一個linux bridge, 把宿主機網卡(可以是物理機的, 也可以是虛擬機的), 把這個網卡加入bridge里面, bridge配上網卡原本的管理IP.?
然后創建一個新的docker bridge網絡, 指定bridge子網, 并將該網絡的網橋綁定到上一步創建的網橋上.
容器啟動時候指定網絡為第二步中創建的bridge網絡, 同時為容器指定一個該網絡子網內的IP. 容器啟動后網絡IP默認即可與外界互通.
這是最容易實現的方式, 如果要實現Docker在網絡內跨宿主機遷移, 需要宿主機位于同一VLAN, 并且為了避免IP沖突, 要實現整個VLAN的IP的統一管理.
方案二: 基于Calico, 這個還沒有仔細研究, 不介紹了.
安全組配置
如果是在公共云服務例如阿里云上, 并且docker數量也比較小的情況下, 就直接用宿主機端口映射就好了. 可以創建子網, 可以配置阿里云的安全組進行訪問控制.?根據 對不同目標(外網, 安全組)的訪問許可, 設置不同的安全組. 安全組的設置原則是, 1) 全局禁止安全組之間互訪, 2) 設置資源組 + 此資源的授權組. 例如
全局組: 全部虛機
可訪問全局組的: 堡壘機, VPN
外網: 默認
可訪問外網的: 如公共接口模塊, CI工具, 可分為一組
DB組: 只允許從特定組訪問的, 分為一組
可訪問DB組的: 如公共接口模塊, 備份計劃模塊等, 可分為一組
COMMON組:
可訪問COMMON組的: 下游邊界業務模塊等
部署Spring Cloud Jar
編寫Dockerfile. 因為java:8默認不帶vi, nano, ifconfig這些命令, 建議基于java:8制作一個自己的image, 把nano和net-tools裝上, 這樣方便運維查看容器環境信息.
FROM java:8 ADD target/scot-eureka.jar scot-eureka.jar ENTRYPOINT ["java", "-jar", "/scot-eureka.jar"]一個更完整的Dockerfile例子
FROM openjdk:8-jre-alpine VOLUME ./mysql:/var/lib/mysql ADD /build/libs/application.jar app.jar ENTRYPOINT exec java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jaror
FROM openjdk:8-jre RUN echo "Europe/Berlin" > /etc/timezone && dpkg-reconfigure -f noninteractive tzdata RUN mkdir /data WORKDIR /data ADD myapp.jar /data/myapp.jarENV springprofiles="" \MAXRAMIFNOLIMIT=4096ENTRYPOINT MAXRAM=$(expr `cat /sys/fs/cgroup/memory/memory.limit_in_bytes` / 1024 / 1024) && \MAXRAM=$(($MAXRAM>$MAXRAMIFNOLIMIT?$MAXRAMIFNOLIMIT:$MAXRAM))m && \echo "MaxRam: $MAXRAM" && \java -XX:MaxRAM=$MAXRAM -Djava.security.egd=file:/dev/./urandom -jar -Dspring.profiles.active="$springprofiles" myapp.jar#when "-XX:+UseCGroupMemoryLimitForHeap" isn't experimental anymore, you can use the following #ENTRYPOINT java -XX:+UseCGroupMemoryLimitForHeap -Djava.security.egd=file:/dev/./urandom -jar -Dspring.profiles.active="$springprofiles" myapp.jar EXPOSE 8080?
制作Docker Image
docker build -t scot-eureka .啟動Docker container
docker run -d --name eureka -p 8762:8761 scot-eureka# or
docker run -m 1024MB -d --name container-name -p 9100:9100 -e JAVA_OPTS="-Xmx512M -Xms512M -XX:MaxRAM=1024M"?imagename:tag
其中8761是jar本身打開的端口, 8762是從外部(容器IP或者本機IP)去訪問的端口, 可以通過 docker ps 或者 docker port [docker-name | container-id] 查看映射關系
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2ea7392a8b51 scot-eureka "java -jar /scot-eur…" 25 minutes ago Up 25 minutes 0.0.0.0:8762->8761/tcp eureka這時候就可以通過容器或本機的 IP:8762 端口去訪問eureka.jar啟動的服務了.
在實際環境中, 需要事先配置好IP信息, package時寫入jar, 給docker創建自定義的network, 在run的時候--net 指定network, --ip指定IP. 或者使用zookeeper提供的配置服務, 在啟動時實時獲取IP配置.
?
對JVM內存參數的要求
在docker容器中可以查看默認的heap size, 這個和docker run -m 指定的內存大小是無關的, 只和宿主機內存容量有關, 一般為這個容量的1/4 (參考? https://blog.csanchez.org/2017/05/31/running-a-jvm-in-a-container-without-getting-killed/?)
$ java -XshowSettings:vm -version VM settings:Max. Heap Size (Estimated): 1.67GErgonomics Machine Class: serverUsing VM: Java HotSpot(TM) 64-Bit Server VMjava version "1.8.0_152" Java(TM) SE Runtime Environment (build 1.8.0_152-b16) Java HotSpot(TM) 64-Bit Server VM (build 25.152-b16, mixed mode)在容器中
$ docker run -m 100MB openjdk:8u121 java -XshowSettings:vm -version VM settings:Max. Heap Size (Estimated): 444.50MErgonomics Machine Class: serverUsing VM: OpenJDK 64-Bit Server VM在Java8之前,?Max memory = [-Xmx] + [-XX:MaxPermSize] + number_of_threads * [-Xss]? ?在Java8之后用Metaspace代替了PermGen, 而Metaspace僅受主機實際內存限制.?僅僅使用-Xmx限制內存大小是不夠的, 需要用-XX:MaxRAM限制實際使用的內存大小, 才能避免被Docker Daemon關閉. 在8u131+之后, 可以用?UseCGroupMemoryLimitForHeap 參數進行檢測
$ docker run -m 2G -ti --rm openjdk:8-jdk java -XshowSettings:vm -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=1 -version Max. Heap Size (Estimated): 1.74GIt turns out that Java VisualVM doesn't know anything about OffHeap, and, as a result, it can be very tricky to investigate your Java application's memory consumption using this tool. Also, it's crucial to understand the JVM options you use. As for me, it was the discovery that specifying -Xmx=512m tells the JVM to allocate a 512mb heap. It’s not telling the JVM to limit its entire memory usage to 512mb. There are code caches and all sorts of other off heap data.
For specifying total memory, you should use the -XX:MaxRAM parameter. Be aware that with MaxRam=512m your heap will be approximately 250mb. Be careful and pay attention to your app JVM options.
總結
以上是生活随笔為你收集整理的Spring Cloud开发实践 - 04 - Docker部署的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: openstack之虚拟机管理命令
- 下一篇: Algs4-2.1.37部分有序