PHP微服务在k8s上落地实战

2019/6/30 posted in  OPS CI/CD

来自公司内部php的k8s落地实战总结分享,php的k8s微服务落地可以参考下面这个博客

k8s和docker关系图

关键点如下:
docker: 虚拟机软件
k8s: 管理docker里的这个虚拟机

k8s和docker都是linux下的软件,操作这个k8s和docker需要使用对应的kubectl和docker命令

docker

虚拟机软件,使用了和系统共用底层资源技术,所以虚拟化额外消耗的资源较低

目的

  1. 限制cpu、内存等资源占用
  2. 隔离和主机的环境,比如在虚拟机中安装卸载软件,不会影响主机安装的软件

要点:

  1. 端口输出(把这个docker虚拟机里的容器的端口输出到主机上)
  2. 把主机上的目录/文件挂载到虚拟机里

容器

名词:一个虚拟机
动词:运行中的虚拟机

Dockerfile: 这个容器的定义文件,比如使用的操作的系统,预先安装的软件等

docker从Dockerfile生成虚拟机,Dockerfile格式参考

FROM centos:7

MAINTAINER suxiaolin <dear.lin@live.com>

# 中国科技大学镜像
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://lug.ustc.edu.cn/wiki/_export/code/mirrors/help/centos?codeblock=3

COPY etc/yum.repos.d/epel.repo /etc/yum.repos.d/epel.repo
COPY etc/yum.repos.d/xxx.repo /etc/yum.repos.d/xxx.repo

# 安装php
RUN yum install -y xxx-php70 xxx-php70-swoole

COPY . /app

WORKDIR /app

ENTRYPOINT ["xxx/php", "console", "serve"]

pod

一组容器

特点

  1. pod里的容器共享ip

deployment管理pod生命周期

  1. cpu使用限制
  2. 内存使用限制
  3. 什么时候算作容器可用(比如web服务某个接口可以访问了算可用)
  4. 容器更新策略
---
apiVersion: v1
kind: Service
metadata:
  name: xxx
spec:
  selector:
    k8s-app: xxx
  ports:
    - protocol: TCP
      name: http
      port: 8080
      targetPort: 8080
  type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "2"
  creationTimestamp: null
  labels:
    k8s-app: xxx
  name: xxx
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      k8s-app: xxx
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        k8s-app: xxx
      name: xxx
    spec:
      containers:
        - name: xxx
          image: "#image#"
          imagePullPolicy: Always
          livenessProbe:
            failureThreshold: 3
            httpGet:
              path: /status.html
              port: 8080
              scheme: HTTP
            initialDelaySeconds: 10
            periodSeconds: 5
            successThreshold: 1
            timeoutSeconds: 1
          resources: {}
          securityContext:
            privileged: false
            procMount: Default
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          env:
            - name: NACOS_HOST
              value: https://nacos.banmahui.cn/
            - name: NACOS_ENV
              value: dev
            - name: NACOS_DATAID
              value: xxx
            - name: NACOS_GROUPID
              value: DEFAULT_GROUP
      dnsPolicy: ClusterFirst
      imagePullSecrets:
        - name: aliyunregistrykey
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30

namespace

一组pod

kubectl

k8s的api的命令行接口

查看节点

kubectl get node

查看pod

kubectl --all-namespaces get pod

rancher

k8s的ui管理界面,可以提高操作效率

  1. 可视化的yaml文件编辑器
  2. 监控集群cpu/内存状态

网关

使用java语言编写的zuul:https://github.com/spring-cloud/spring-cloud-netflix/tree/master/spring-cloud-netflix-zuul

使用zuul有以下考量

  1. java语言编写,便于在网关上添加逻辑
  2. 高性能,底层采用netty库通信,非阻塞io, 性能接近nginx,参考:http://blog.didispace.com/zuul-vs-nginx-performance/

也可以考虑使用nginx+lua的kong网关,但是lua的三方库没有java多

滚动更新

先启动新的pod,新pod达到可用状态后再停止旧的pod

失败容错

如果新的pod起不来,旧的pod不会被删除,旧的pod会继续提供服务

php微服务部署到k8s

方便的给应用动态增减cpu和内存等资源

架构图

k8s项目部署流程

php k8s微服务架构

网关流量入口

日志

背景:k8s集群环境下,容器启动所在的机器会根据k8s的调度发生改变,容器重启时,旧的容器会被完全移除

使用redis进行中专,然后使用中间件把这个redis里面的日志转到阿里云的日志服务里

后期也可以改成kafka或者阿里云的logtail/容器stdout收集等

链路

背景:服务很多的情况下,报错后很难定位问题,可视化的调用链路监控系统,可以提高排错的效率

使用符合opentracing标准的jaeger: https://www.jaegertracing.io/

这个jaeger可以把数据保存进elasticsearch里,可以在kibana里使用elasticsearch提供的搜索语法

配置中心

使用阿里巴巴开源的nacos,参考:https://nacos.io/en-us/

  1. 在项目启动时拉取配置文件
  2. 优雅不停机,定时拉取最新的配置文件(按需)

常用命令

生成k8s的yaml模版

kubectl run nginx --image=nginx --dry-run -o yaml

动态调整k8s的deployment实例数量

kubectl scale deployments/myapp --replicas=3

查看namespace列表

kubectl get namespaces

查看集群负载情况

kubectl top node
kubectl top pod

简写
namespaces -> ns
services -> svc
ReplicaSet -> rs

一些注意的点

  1. rancher的证书有效期默认1年,到期后需要续期(10年),参考:https://mp.weixin.qq.com/s/rvJSXue2a-rN2BdEFElMbA

参考资料

  1. https://jimmysong.io/kubernetes-handbook/concepts/
  2. https://medium.com/jaegertracing/jaeger-elasticsearch-and-kibana-7ecb846137b6
  3. https://instea.sk/2015/04/netflix-zuul-vs-nginx-performance/
  4. https://help.aliyun.com/document_detail/66658.html
  5. https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
  6. https://jimmysong.io/kubernetes-handbook/appendix/docker-best-practice.html
  7. https://medium.com/jaegertracing/jaeger-elasticsearch-and-kibana-7ecb846137b6

持续更新...