javascript
Spring Cloud开发实践 - 04 - Docker部署
Docker的安裝和命令可以參考?https://www.cnblogs.com/milton/p/9866963.html .?
資源規(guī)劃
這一步要區(qū)分傳統(tǒng)資源和Docker資源, 為后面的細(xì)節(jié)定好基礎(chǔ). 因為Docker的特性, 適合于占CPU和MEM資源, 但是對HDD資源要求不高的應(yīng)用. 不適合用于對數(shù)據(jù)有持久化要求以及安全性要求較高的應(yīng)用, 例如MySQL和日志系統(tǒng).
在開發(fā)和測試環(huán)境, 你可以隨手啟動一個MySQL來配合開發(fā), 但是在生產(chǎn)環(huán)境目前還是不太現(xiàn)實的, 需要整套運維工具跟進(jìn)對Docker的配合后才能實現(xiàn)足夠的安全性.?
生產(chǎn)環(huán)境涉及的資源如下:
- 堡壘機, VPN, 網(wǎng)關(guān), 用于生產(chǎn)環(huán)境的底層訪問控制, >= 1
- 存檔備份, 低性能大容量帶冗余的存儲, >=1
- CI工具, Jenkins, 用于在生產(chǎn)環(huán)境進(jìn)行自動部署, =1
- RMDB 數(shù)據(jù)庫, MySQL等, >=2
- NoSQL 數(shù)據(jù)庫, MongoDB, Redis 等, >=2
- 緩存服務(wù), Ehcache, Redis等, >=1
- 文件服務(wù), FastDF等, >=1
- 配置和服務(wù)注冊服務(wù), Zookeeper, EurekaServer等, >=3
- 日志服務(wù), Kafka等, >=1
- 搜索服務(wù), Elasticsearch等, >=1
- JVM節(jié)點, 這是用于運行jar項目的節(jié)點, =N
- WEB服務(wù), Nginx等, >=2
其中與業(yè)務(wù)開發(fā)關(guān)系最大, 適合用Docker進(jìn)行部署的就是JVM節(jié)點部分, 還有緩存服務(wù), WEB服務(wù), 日志服務(wù), 配置和注冊服務(wù), 也是適合通過Docker管理的. 這邊假定僅僅使用Docker配置JVM節(jié)點.
網(wǎng)絡(luò)劃分
三類網(wǎng)絡(luò)的私有地址范圍
10.0.0.0? ? ? ?- 10.255.255.255
172.16.0.0? ?- 172.31.255.255
192.168.0.0 - 192.168.255.255
與環(huán)境現(xiàn)有子網(wǎng)綜合考慮. 需要達(dá)到的目標(biāo)是
- 每個容器有獨立的 IP,運維就可以像連接虛機一樣通過ssh連接容器
- 需要跨宿主機之間的容器通信
- 訪問控制, 安全性和隔離性
- 性能損失盡量小
如果是在IDC自建機房的規(guī)劃, 網(wǎng)絡(luò)的實現(xiàn)方案可以參考這一篇?http://www.cnblogs.com/sammyliu/p/5926343.html?,
方案一:?基于bridge
將默認(rèn)的docker bridge網(wǎng)橋替換為 linuxbridge, 把 linuxbridge 網(wǎng)段的 ip 加入到容器里, 實現(xiàn)容器與傳統(tǒng)環(huán)境應(yīng)用的互通.
首先在宿主機上添加一個linux bridge, 把宿主機網(wǎng)卡(可以是物理機的, 也可以是虛擬機的), 把這個網(wǎng)卡加入bridge里面, bridge配上網(wǎng)卡原本的管理IP.?
然后創(chuàng)建一個新的docker bridge網(wǎng)絡(luò), 指定bridge子網(wǎng), 并將該網(wǎng)絡(luò)的網(wǎng)橋綁定到上一步創(chuàng)建的網(wǎng)橋上.
容器啟動時候指定網(wǎng)絡(luò)為第二步中創(chuàng)建的bridge網(wǎng)絡(luò), 同時為容器指定一個該網(wǎng)絡(luò)子網(wǎng)內(nèi)的IP. 容器啟動后網(wǎng)絡(luò)IP默認(rèn)即可與外界互通.
這是最容易實現(xiàn)的方式, 如果要實現(xiàn)Docker在網(wǎng)絡(luò)內(nèi)跨宿主機遷移, 需要宿主機位于同一VLAN, 并且為了避免IP沖突, 要實現(xiàn)整個VLAN的IP的統(tǒng)一管理.
方案二: 基于Calico, 這個還沒有仔細(xì)研究, 不介紹了.
安全組配置
如果是在公共云服務(wù)例如阿里云上, 并且docker數(shù)量也比較小的情況下, 就直接用宿主機端口映射就好了. 可以創(chuàng)建子網(wǎng), 可以配置阿里云的安全組進(jìn)行訪問控制.?根據(jù) 對不同目標(biāo)(外網(wǎng), 安全組)的訪問許可, 設(shè)置不同的安全組. 安全組的設(shè)置原則是, 1) 全局禁止安全組之間互訪, 2) 設(shè)置資源組 + 此資源的授權(quán)組. 例如
全局組: 全部虛機
可訪問全局組的: 堡壘機, VPN
外網(wǎng): 默認(rèn)
可訪問外網(wǎng)的: 如公共接口模塊, CI工具, 可分為一組
DB組: 只允許從特定組訪問的, 分為一組
可訪問DB組的: 如公共接口模塊, 備份計劃模塊等, 可分為一組
COMMON組:
可訪問COMMON組的: 下游邊界業(yè)務(wù)模塊等
部署Spring Cloud Jar
編寫Dockerfile. 因為java:8默認(rèn)不帶vi, nano, ifconfig這些命令, 建議基于java:8制作一個自己的image, 把nano和net-tools裝上, 這樣方便運維查看容器環(huán)境信息.
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] 查看映射關(guān)系
$ 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啟動的服務(wù)了.
在實際環(huán)境中, 需要事先配置好IP信息, package時寫入jar, 給docker創(chuàng)建自定義的network, 在run的時候--net 指定network, --ip指定IP. 或者使用zookeeper提供的配置服務(wù), 在啟動時實時獲取IP配置.
?
對JVM內(nèi)存參數(shù)的要求
在docker容器中可以查看默認(rèn)的heap size, 這個和docker run -m 指定的內(nèi)存大小是無關(guān)的, 只和宿主機內(nèi)存容量有關(guān), 一般為這個容量的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僅受主機實際內(nèi)存限制.?僅僅使用-Xmx限制內(nèi)存大小是不夠的, 需要用-XX:MaxRAM限制實際使用的內(nèi)存大小, 才能避免被Docker Daemon關(guān)閉. 在8u131+之后, 可以用?UseCGroupMemoryLimitForHeap 參數(shù)進(jìn)行檢測
$ 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.
總結(jié)
以上是生活随笔為你收集整理的Spring Cloud开发实践 - 04 - Docker部署的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: openstack之虚拟机管理命令
- 下一篇: Springsecurity之Authe