使用Kubernetes,Spring Boot和Flyway实现零停机部署源码项目


这是个Github示例项目,展示如何使用Kubernetes,Kotlin+Spring Boot和Flyway实现零停机时间部署.
主程序:


@SpringBootApplication
class ZeroDowntimeApplication {

    @Bean
    fun displayInfo(context: Context) = CommandLineRunner {
        println("START: ${context.hostname} (running v${context.version})")
    }

    @Bean
    fun context() = Context()
}

fun main(args: Array<String>) {
    runApplication<ZeroDowntimeApplication>(*args)
}

@Controller
class PersonController(private val repository: PersonRepository, private val context: Context) {

    @GetMapping(
"/")
    fun getAll(model: Model): String {
        println(
"GET : ${context.hostname} (running v${context.version})")
        model[
"person"] = Person()
        model[
"persons"] = repository.findAll()
        model[
"title"] = "Person ${context.hostname} (v${context.version})"
        return
"/persons"
    }

    @PostMapping(
"/")
    fun create(@Valid person: Person, result: BindingResult): String {
        println(
"POST: ${context.hostname} (running v${context.version})")
        repository.save(person)
        return
"redirect:/"
    }
}

interface PersonRepository : JpaRepository<Person, Long>

模型类:


@Entity
class Person(@Id @GeneratedValue(strategy = IDENTITY) var id: Long = -1,
             val name: String = "") {

    @OneToOne(mappedBy =
"person", cascade = [CascadeType.ALL])
    @JoinColumn(name =
"id")
    val address: Address = Address()

    init {
        address.person = this
    }
}

@Entity
class Address(@Id @GeneratedValue(strategy = IDENTITY) var id: Long? = null,
              var addressLine1: String =
"",
              var addressLine2: String? = null,
              var city: String =
"",
              var zipCode: String =
"") {
    @OneToOne
    @JoinColumn(name =
"person_id")
    lateinit var person: Person
}

application.yml:

spring:
  jpa:
    hibernate.ddl-auto: validate
    open-in-view: false
  datasource:
    url: jdbc:h2:tcp://localhost:1521/~/zerodowntime
    username: sa
    driver-class-name: org.h2.Driver
info:
  app:
    version: @project.version@

Kubernetes部署application.yml:

apiVersion: v1
kind: Namespace
metadata:
  name: zerodowntime
---
apiVersion: v1
kind: Service
metadata:
  namespace: zerodowntime
  name: app-service
spec:
  selector:
    role: app
  ports:
  - port: 8080
    nodePort: 30002
  type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: application
  namespace: zerodowntime
spec:
  replicas: 3
  minReadySeconds: 10
  selector:
    matchLabels:
      role: app
  strategy:
    rollingUpdate:
      maxSurge: 0
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      labels:
        role: app
    spec:
      containers:
      - name: spring-boot-app
        image: zerodowntime:1.0
        imagePullPolicy: Never
        readinessProbe:
          periodSeconds: 2
          httpGet:
            path: /actuator/health
            port: 8080
        env:
        - name: spring.datasource.url
          value: jdbc:h2:tcp://db-service:1521/~/zerodowntime
        ports:
        - containerPort: 8080

点击标题见源码