只需五步,將Spring Boot服務(wù)遷移到Kubernetes
當(dāng)許多Java開發(fā)人員使用Spring框架來快速創(chuàng)建Web服務(wù),但是其在生產(chǎn)環(huán)境中運行可能是個比較大的挑戰(zhàn),因為有很多運行方式和云提供商。當(dāng)然您可以使用像AWS Elastic Beanstalk這樣的服務(wù)來保持其運行,實現(xiàn)自動縮放、零停機(jī)部署、無需部署新版本的基礎(chǔ)設(shè)施經(jīng)驗等等。但是,這些服務(wù)對于預(yù)算較低的人來說會花費很多錢,同時失去對服務(wù)基礎(chǔ)設(shè)施的控制。
如果預(yù)算有限,想以低成本獲得彈性Beanstalk的所有好處,可以使用Kubernetes,并且它是開源的!
1. 生成Docker鏡像
Kubernetes是一個容器編排平臺,它可以自動化地部署、擴(kuò)展和管理容器化應(yīng)用程序。Kubernetes的工作原理是這樣的:您可以從應(yīng)用程序創(chuàng)建Docker鏡像,并“告訴”Kubernetes啟動您創(chuàng)建的一個或多個鏡像實例。然后,Kubernetes會自動將這些實例分配給可用的節(jié)點,并確保它們始終處于運行狀態(tài)。如果有節(jié)點失敗或需要擴(kuò)展應(yīng)用程序,則Kubernetes會自動重新分配實例,以確保應(yīng)用程序始終處于可用狀態(tài)。因此,我們的第一步是從Spring Boot服務(wù)創(chuàng)建一個鏡像。
以下一個Dockerfile示例:
FROM openjdk:8-jdk-alpine
VOLUME /tmp
MAINTAINER Samuel Birocchi <samuel.birocchi@gobots.com.br>
ADD target/*.jar app.jar
COPY newrelic newrelic
ENV JAVA_OPTS=""
ENV SPRING_PROFILE="default"
ENV MONGO_PASSWORD=""
ENTRYPOINT exec java $JAVA_OPTS \
-javaagent:newrelic/newrelic.jar \
-Djava.security.egd=file:/dev/./urandom \
-Dspring.profiles.active=$SPRING_PROFILE \
-Dmongo.password=$MONGO_PASSWORD \
-jar app.jar
有了這個和docker build插件,我們可以運行g(shù)radle clean buildDocker(或使用maven docker插件)來構(gòu)建docker鏡像。請注意,它將創(chuàng)建一個帶有g(shù)radle.properties或build.gradle上配置的版本標(biāo)簽的映像。
2. 創(chuàng)建部署和Pods
現(xiàn)在要將創(chuàng)建好的鏡像放在Kubernetes上,我們需要將其上傳到注冊表中。我們可以上傳到公共docker注冊表,但是該映像將對每個人都可用!由于我們的服務(wù)是私有的,因此我們需要上傳到私有注冊表。幸運的是,Gcloud為您的帳戶提供了私有注冊表。
這樣一來,就可以最終將服務(wù)放在Kubernetes集群上了!由于正在使用Gcloud,因此使用GKE創(chuàng)建集群非常容易,請按照本教程進(jìn)行操作。創(chuàng)建集群后,配置命令行連接它后,需要為應(yīng)用程序創(chuàng)建部署(或復(fù)制控制器)以實現(xiàn)可擴(kuò)展性。使用以下配置作為初始配置:
apiVersion: apps/v1beta1 # for versions before 1.8.0 use apps/v1beta1
kind: Deployment
metadata:
name: spring-boot-deployment
spec:
selector:
matchLabels:
app: spring-boot-app
replicas: 3 # tells deployment to run 3 pods matching the template
template: # create pods using pod definition in this template
metadata:
labels:
app: spring-boot-app
spec:
containers:
- name: spring-boot-app
image: #your image name here
ports:
- containerPort: 8080
name: server
- containerPort: 8081
name: management
考慮到在最后一步中配置了Kubernetes命令行界面(kubectl),因此我們可以使用kubectl apply -f Deployment.yml為Kubernetes集群創(chuàng)建一個新的部署,并使用此配置。過一段時間后,您可以使用kubectl get deployment spring-boot-deployment檢查部署的狀態(tài),并使用kubectl get pods spring-boot-app檢查pod的狀態(tài)。如果要檢查pod的日志,則可以使用kubectl log命令。
3. 使用服務(wù)公開我們的Pods
現(xiàn)在,我們的Pod正在運行,需要創(chuàng)建一個服務(wù)來將Pod公開。使用下配置創(chuàng)建服務(wù):
apiVersion: v1
kind: Service
metadata:
name: spring-boot-service
spec:
ports:
- port: 8080
targetPort: 8080
name: http
- port: 8081
targetPort: 8081
name: management
selector:
app: spring-boot-app
type: NodePort
正如所看到的,服務(wù)配置非常簡單。但是,此配置未公開。我們可以將服務(wù)類型設(shè)置為LoadBalancer,因為gcloud會自動為我們的服務(wù)創(chuàng)建真正的負(fù)載均衡器和外部IP。實際上嘗試使用此配置我們無法正確設(shè)置TLS和HTTPS,我們希望服務(wù)僅通過HTTPS協(xié)議訪問。但是該怎么做呢?
4. 使用Ingress進(jìn)行路由
可以找到Kubernetes Ingress來使用。它是一個較新的功能,但非常有效。它幾乎像一個類型為LoadBalancer的服務(wù),但您可以設(shè)置自定義路由規(guī)則。下面是Ingress配置:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: spring-boot-ingress
annotations:
kubernetes.io/ingress.allow-http: "false"
spec:
tls:
- secretName: your-tls-secret
backend:
serviceName: spring-boot-service
servicePort: 8080
正如所看到的,我們將入口設(shè)置為僅允許使用kubernetes.io/ingress.allow-http:"false"進(jìn)行HTTPS連接。但是,您會發(fā)現(xiàn)此文件中有TLS配置。我們需要首先創(chuàng)建一個Secret,其中包含用于Ingress訪問的ssl證書數(shù)據(jù)。使用下文配置即可完成此操作。
5. Secrets
apiVersion: v1
data:
tls.crt: #base64 hash of your cert
tls.key: #base64 hash of your key
kind: Secret
metadata:
name: your-tls-secret
namespace: default
type: Opaque
應(yīng)用所有配置后,我們可以使用 kubectl get ingress spring-boot-ingress 命令檢查應(yīng)用程序的外部 IP。通過 HTTPS 訪問,我們的 Spring Boot 應(yīng)用程序就運行在 Kubernetes 集群上了!
重要!Kubernetes服務(wù)對默認(rèn)pod端口和端點“/”執(zhí)行健康檢查。如果您沒有映射該端點或者它受到保護(hù),則需要加入livenessProbe和readinessProbe配置。
建議在部署到生產(chǎn)之前使用minikube測試這些設(shè)置,以便您熟悉Kubernetes環(huán)境。
要部署新版本,請使用kubectl set image deployment/spring-boot-deployment spring-boot-app=your-new-image或僅使用kubectl edit deployment spring-boot-deployment編輯配置。使用第二個命令,您可以同時更新圖像和Pod的數(shù)量。如果您只想擴(kuò)展應(yīng)用程序,請運行kubectl scale deployment spring-boot-deployment --replicas=10或創(chuàng)建自動縮放配置。
更新部署會導(dǎo)致Kubernetes滾動更新,無需停機(jī),因為它會處理所有內(nèi)容,您只需坐下來放松即可。將基礎(chǔ)架構(gòu)更改為GKE后,可以減少關(guān)注應(yīng)用程序的健康狀況,更多地關(guān)注開發(fā)。Kubernetes非常易于與CI工具(如Jenkins、GitLab CI、BitBucket Pipelines等)一起使用。