一般开发人员,比如 Java 开发人员来说,如何使用和利用 Kubernetes 呢?其实就是如何开发云原生(cloud native)应用。

我觉得最理想的方式是透明、无侵入,也就是说你原来如何开发,现在还是老样子。总的指导思想还是 12 法则应用理论”( Twelve-Factor App) https://12factor.net/zh_cn/

  1. Liveness 健康检查 k8s 的心跳检测,如果返回失败,平台会尝试反复重启 pod。对于一个需要稳定运行的服务,肯定要配置这个了。 要注意的是服务器有没有挂掉和服务是否正常(Readiness probes)是两个问题,需要仔细设计。开始可以简单在运行代码开始时运行这个接口,逻辑也只是直接返回 200 正常,更完美的应该是检查服务是否还在正常运行、各个依赖项是否都能访问,这个就要具体问题具体分析了。另一个方面,如果服务运行出错,也不要静默或自己反复尝试,直接退出是简单有效的办法,因为这样除了能让 k8s 帮助重启 pod,而且不用分析日志就能获知服务状态和对服务进行有效监控。需要注意的是要监控重启次数,如果次数太多肯定不对。这个不容易察觉,因为 k8s 会在失败后帮助重启,导致系统看上去似乎都运行正常。健康检查支持多种方法

  2. CI/CD 开发者只有不用考虑太多编译、打包和发布,不断试错且每次尝试代价很小,才能在这个新环境中快速上手而不怕失败。

  3. 开发环境
    • 一般都是在环境中直接开发调试,不用做成镜像,带热部署(修改代码后不用重启 server)功能。
    • 开发环境中能直接访问 kubernetes 上面的服务 port-forward
    • outside-cluster 使用 kubeconfig 访问 k8s,in-cluster 则直接访问,代码中需要区分
  4. 使用参数和环境变量,不要使用配置文件。开发环境中从配置文件读取,部署后使用 mount 读取。

  5. 保持无状态,保持简单。
    • 应用能被 kill 掉而反复重启,反复重启对功能无影响。
    • 能水平扩展:能其多个实例而正常运行,实现中避免同步锁,太复杂。
    • 能快速运行起来,能快速的关掉干净的退出。保存轻量级。Java 在这里似乎就有些笨重了。
    • 应用切分合理,容易测试。
  6. 错误的处理
    • 能适应各种无法预料的问题,但是不要掩盖错误(这会让分布式的调试更加复杂)
    • 日志直接吐到标准输出 stdout,这样后端能接到日志系统。