SpringCloud微服务容器云之路
Springboot应用配合Actuator开启:监控检查
,优雅停机
,监控metrics
等endpoints
根据Dockerfile
定义制作Docker镜像并上传Harbor
私有Docker Registry
渲染K8S部署模板文件并完成应用部署,同时应该考虑快速回滚等保障机制
Tips: 步骤2 - 可使用Maven Plugin dockerfile-maven 集成到Maven流程中,命令如: mvn dockerfile:build
, mvn dockerfile:push
, 详见官方文档
1、Springboot配置示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 spring: application: name: spring-produce profiles: active: ${ENVIRONMENT:pro} server: port: 10080 management: endpoints: web: base-path: /actuator/ exposure: include: health,shutdown,prometheus endpoint: shutdown: enabled: true metrics: tags: application: ${spring.application.name} eureka: instance: preferIpAddress: true client: serviceUrl: defaultZone: http://eureka-0.eureka.micro-public.svc.cluster.local:8761/eureka,http://eureka-1.eureka.micro-public.svc.cluster.local:8761/eureka,http://eureka-2.eureka.micro-public.svc.cluster.local:8761/eureka logging: file: max-size: 200MB max-history: 7 path: /opt/logs name: /opt/logs/${HOSTNAME}.${spring.application.name}.log
注意:actuator开启prometheus需要添加依赖
1 2 3 4 5 <dependency > <groupId > io.micrometer</groupId > <artifactId > micrometer-registry-prometheus</artifactId > <version > ${micrometer.version}</version > </dependency >
2、Dockerfile
在项目根目录下创建Dockerfile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 FROM adoptopenjdk:8 u252-b09-jdk-hotspotMAINTAINER Boer Zhang <[email protected] >WORKDIR /opt COPY target/produce-1.0.1.jar . RUN echo "Asia/Chongqing" > /etc/timezone EXPOSE 10080 CMD [ "sh" , "-c" , "java ${JVM_OPTS} -jar produce-1.0.1.jar ${APP_OPTS} " ]
3、K8S容器云部署文件模板
在项目根目录下创建manifests
目录,在目录下创建文件k8s.yaml
服务名称 - 全局替换<change-me>
为您的服务名称
服务端口 - 全局替换10080
为您的服务端口
服务资源 - 注意resources
字段服务所申请的资源
服务域名 - 根据实际情况,选择是否需要对外暴露Ingress
服务版本 - 根据项目pom文件version
字段,同时修改Dockerfile中jar包版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 apiVersion: apps/v1 kind: Deployment metadata: name: <change-me>-deployment annotations: kubernetes.io/change-cause: <CHANGE_CAUSE> spec: selector: matchLabels: app: <change-me> replicas: 1 template: metadata: labels: app: <change-me> spec: initContainers: - image: registry.boer.xyz/public/skywalking-agent:8.1.0 name: skywalking-agent imagePullPolicy: IfNotPresent command: ['sh' ] args: ['-c' ,'cp -r /usr/skywalking/agent/* /skywalking/agent' ] volumeMounts: - mountPath: /skywalking/agent name: skywalking-agent containers: - name: <change-me> image: <IMAGE>:<IMAGE_TAG> imagePullPolicy: IfNotPresent volumeMounts: - mountPath: /usr/skywalking/agent name: skywalking-agent - mountPath: /opt/logs name: app-logs ports: - containerPort: 10080 resources: requests: memory: "512Mi" cpu: "200m" limits: memory: "1Gi" cpu: "600m" env: - name: ENVIRONMENT value: "pro" - name: APP_OPTS value: "--spring.kafka.consumer.group-id=consumer.group" - name: JVM_OPTS value: "-Xms512m -Xmx512m -javaagent:/usr/skywalking/agent/skywalking-agent.jar" livenessProbe: httpGet: path: /actuator/health port: 10080 initialDelaySeconds: 60 periodSeconds: 10 timeoutSeconds: 5 readinessProbe: httpGet: path: /actuator/health port: 10080 initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 5 lifecycle: preStop: exec: command: - "curl" - "-XPOST" - "http://127.0.0.1:10080/actuator/shutdown" imagePullSecrets: - name: regcred volumes: - name: skywalking-agent emptyDir: {} - name: app-logs hostPath: path: /opt/app-logs/<change-me> type: DirectoryOrCreate --- apiVersion: v1 kind: Service metadata: name: <change-me>-service annotations: prometheus.io/path: /actuator/prometheus prometheus.io/port: "10080" prometheus.io/scrape: "true" labels: app: <change-me> spec: type: ClusterIP ports: - port: 10080 targetPort: 10080 selector: app: <change-me> --- apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: <change-me>-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: / nginx.ingress.kubernetes.io/load-balance: "ip_hash" nginx.ingress.kubernetes.io/upstream-hash-by: "$request_uri" spec: rules: - host: <change-me>.boer.xyz http: paths: - path: / backend: serviceName: <change-me>-service servicePort: 10080
4、K8S发布
此过程已通过Jenkins Pipeline自动化CICD方式实现
Git clone/pull代码 :git clone git://gitea.boer.xyz/spring-produce.git
Junit单元测试 :mvn test
# 普通程序员都没有单元测试?
Maven编译打包 :mvn clean package -Dmaven.test.skip=true
Docker打包镜像 :docker build -t ${image}:${imageTag} .
Harbor镜像推送 :docker push ${image}:${imageTag}
Sed渲染模板 :1 2 3 sed -i "s|<CHANGE_CAUSE>|${changeCause} |g" manifests/k8s.yaml sed -i "s|<IMAGE>|${image} |g" manifests/k8s.yaml sed -i "s|<IMAGE_TAG>|${imageTag} |g" manifests/k8s.yaml
Kubectl部署应用 :kubectl --kubeconfig $kubeconfig apply -f manifests/k8s.yaml -n ${NAMESPACE}
Rollout快速回滚 :kubectl --kubeconfig ${kubeconfig} rollout undo deployment consume-deployment -n ${NAMESPACE}