EggJS 云原生应用硬核实战(Kubernetes+Traefik+Helm+Prometheus+Grafana),提供 Demo
介绍
这是一个关于 Egg.js 应用上云️的示例,笔者所在的大前端团队的已应用于生产。
CI/CD & DevOps & GitOps & HPA 等这里暂不做讨论,因为每一个点篇幅都很长。
我这里的实验条件
- 一个可用的 Kubernetes 集群
- 已在集群中部署 Kube-Prometheus-Stack
- 已在集群中部署 Traefik v2.2 作为 Ingress Controller
- 已安装 Helm V3
示例项目
可直接做实验(文章写的再好,不如提供一个上云示例)
GitHub: k8s-eggjs->点我
GitHub: k8s-eggjs
GitHub: k8s-eggjs
这个示例,简单的提供了两个接口:
/api/posts
curl -X POST http://localhost:7001/api/posts --data '{"title":"post1", "content": "post1 content"}' --header 'Content-Type:application/json; charset=UTF-8'
api/topics
curl -X POST http://localhost:7001/api/topics --data '{"title":"topic1", "content": "topic1 content"}' --header 'Content-Type:application/json; charset=UTF-8'
笔者也把这个项目部署到了
上云实战
(示例已提供,可直接做实验)
Scripts
package.json 这里简单调整为:
"start": "egg-scripts start --workers=1 --title=egg-server-k8s-eggjs-promethues",
最好是单进程启动,应用容器的编排完全交给 kubernetes。
Docker Image 准备
文件位于 docker/Dockerfile.prod
FROM node:15-alpine
RUN ln -sf /usr/share/zoneinfo/Asia/ShangHai /etc/localtime
RUN echo "Asia/Shanghai" > /etc/timezone
COPY package.json /app/dependencies/package.json
COPY yarn.lock /app/dependencies/yarn.lock
RUN cd /app/dependencies \
&& yarn install --frozen-lockfile --registry=https://registry.npm.taobao.org \
&& yarn cache clean \
&& mkdir /app/egg \
&& ln -s /app/dependencies/node_modules /app/egg/node_modules
COPY ./ /app/egg/
WORKDIR /app/egg
EXPOSE 7001
CMD npm run start
构建Image
docker build -f docker/Dockerfile.prod -t k8s-eggjs-promethues:1.0.0 . --no-cache
打个 tag,笔者试验镜像是放在阿里云的(公司有自己的私有仓库)
docker tag k8s-eggjs-promethues:1.0.0 registry.cn-shenzhen.aliyuncs.com/hacker-linner/k8s-eggjs-promethues:1.0.0
推送到阿里云
docker push registry.cn-shenzhen.aliyuncs.com/hacker-linner/k8s-eggjs-promethues:1.0.0
Helm Chart(k8s-helm-charts)
(示例项目已提供,可直接做实验)
生成部署 Chart
mkdir k8s-helm-charts && cd k8s-helm-charts
helm create k8seggjs
我们复制一份 k8seggjs/values.yaml 到外层与 k8seggjs 文件夹同级(k8s-helm-charts/values.yaml)。
k8s-helm-charts/values.yaml做如下修改:
replicaCount: 3 # 部署副本我用3个实例做负载均衡,保证服务可用
image:
repository: registry.cn-shenzhen.aliyuncs.com/hacker-linner/k8s-eggjs-promethues # 镜像变为刚上传
pullPolicy: Always # 镜像拉取策略可直接用默认`IfNotPresent`
# apiPort,metricsPort 默认模板没有,
# 这里我对 template 里面的 ingress.yaml service.yaml deployment.yaml 文件做了相应改动
service:
type: ClusterIP
apiPort: 7001 # 这个 API 服务的端口
metricsPort: 7777 # 这个是 prometheus 所需的 metrics 端口
# Ingress Controller,根据你的环境决定,我这里用的是 traefik
ingress:
enabled: true
annotations:
ingress.kubernetes.io/ssl-redirect: "true"
ingress.kubernetes.io/proxy-body-size: "0"
kubernetes.io/ingress.class: "traefik"
traefik.ingress.kubernetes.io/router.tls: "true"
traefik.ingress.kubernetes.io/router.entrypoints: websecure
hosts:
- host: k8seggjs.hacker-linner.com
paths:
- /
tls:
- secretName: hacker-linner-cert-tls
hosts:
# 做资源限制,防止内存泄漏,交给 K8S 杀掉然后重启,保证服务可用
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi
创建部署 Namespace
kubectl create ns k8seggjs
使用 Helm 部署
helm install k8seggjs ./k8seggjs -f values.yaml -n k8seggjs
# 卸载:helm uninstall k8seggjs -n k8seggjs

ServiceMonitor(k8s-prometheus)
RBAC 设置
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleList
items:
- apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: prometheus-k8s-k8seggjs
namespace: k8seggjs
rules:
- apiGroups:
- ""
resources:
- services
- endpoints
- pods
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBindingList
items:
- apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: prometheus-k8s-k8seggjs
namespace: k8seggjs
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: prometheus-k8s-k8seggjs
subjects:
- kind: ServiceAccount
name: prometheus-k8s
namespace: monitoring
指标 Service 设置
apiVersion: v1
kind: Service
metadata:
namespace: k8seggjs
name: k8seggjs-metrics
labels:
k8s-app: k8seggjs-metrics
annotations:
prometheus.io/scrape: 'true'
prometheus.io/scheme: http
prometheus.io/path: /metrics
prometheus.io/port: "7777"
spec:
selector:
app.kubernetes.io/name: k8seggjs
ports:
- name: k8seggjs-metrics
port: 7777
targetPort: 7777
protocol: TCP
ServiceMonitor 设置
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: k8seggjs
namespace: monitoring
spec:
endpoints:
- bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
interval: 5s
port: k8seggjs-metrics
jobLabel: k8s-app
namespaceSelector:
matchNames:
- k8seggjs
selector:
matchLabels:
k8s-app: k8seggjs-metrics
应用
kubectl apply -f ServiceMonitor.yaml



egg-exporter & egg-prometheus
egg-exporter,Egg.js 的 Prometheus 指标收集插件,附带 Grafana 看板。
egg-prometheus,Prometheus plugin for Egg.js。
示例项目的指标收集就是用的这个。
Grafana (k8s-grafana)
dashboard-metrics.json,完整的面板 json。来自于egg-exporter。笔者这里做了 metrics 前缀的调整。
config.exporter = {
scrapePort: 7777,
scrapePath: '/metrics',
prefix: 'k8seggjs_',
defaultLabels: { stage: process.env.NODE_ENV },
};
我们导入 json 文件进行 Grafana 面板创建

修改面板 Variables

$stage
- Query:
k8seggjs_nodejs_version_info{worker="app"} - Regex:
/.*stage="([^"]*).*/

$appname
- Query:
k8seggjs_nodejs_version_info{worker="app"} - Regex:
/.*app="([^"]*).*/

$node
- Query:
k8seggjs_nodejs_version_info{worker="app"} - Regex:
/.*instance="([^"]*).*/

最终效果

Refs
互相交流学习
我的微信:

EggJS 云原生应用硬核实战(Kubernetes+Traefik+Helm+Prometheus+Grafana),提供 Demo的更多相关文章
- 云原生之旅 - 5)Kubernetes时代的包管理工具 Helm
前言 上一篇文章 [基础设施即代码 使用 Terraform 创建 Kubernetes] 教会了你如何在Cloud上面建Kubernetes资源,那么本篇来讲一下如何在Kubernetes上面部署应 ...
- 第一届云原生应用大赛火热报名中! helm install “一键安装”应用触手可及!
云原生应用,是指符合“云原生”理念的应用开发与交付模式,这是当前在云时代最受欢迎的应用开发最佳实践. 在现今的云原生生态当中,已经有很多成熟的开源软件被制作成了 Helm Charts,使得用户可以非 ...
- 如何将云原生工作负载映射到 Kubernetes 中的控制器
作者:Janakiram MSV 译者:殷龙飞 原文地址:https://thenewstack.io/how-to-map-cloud-native-workloads-to-kubernetes- ...
- 云原生应用 Kubernetes 监控与弹性实践
前言 云原生应用的设计理念已经被越来越多的开发者接受与认可,而Kubernetes做为云原生的标准接口实现,已经成为了整个stack的中心,云服务的能力可以通过Cloud Provider.CRD C ...
- 云原生之旅 - 6)不能错过的一款 Kubernetes 应用编排管理神器 Kustomize
前言 相信经过前一篇文章的学习,大家已经对Helm有所了解,本篇文章介绍另一款工具 Kustomize,为什么Helm如此流行,还会出现 Kustomize?而且 Kustomize 自 kubect ...
- 云原生生态周报 Vol.9| K8s v1.15 版本发布
本周作者 | 衷源.心贵 业界要闻 1.Kubernetes Release v1.15 版本发布,新版本的两个主题是持续性改进和可扩展性.(https://github.com/kubernetes ...
- 云原生生态周报 Vol. 8 | Gartner 发布云原生趋势
业界要闻 Gartner 发布云原生基础设施未来的八大趋势:权威分析机构 Gartner 在对 2020 年技术趋势的展望当中指出:“预计2020年所有领先的容器管理软件均内置服务融合技术,到2022 ...
- 如何优雅地使用云原生 Prometheus 监控集群
作者陈凯烨,腾讯云前端开发工程师.负责 TKE 集群,弹性集群和云原生监控等模块控制台开发. 概述 Prometheus 是一套开源的系统监控报警框架.2016 年,Prometheus 正式加入 C ...
- Dapr | 云原生的抽象与实现
引言 Dapr 是微软主导的云原生开源项目,2019年10月首次发布,到今年2月正式发布 V1.0 版本.在不到一年半的时间内,github star 数达到了 1.2 万,超过同期的 kuberne ...
随机推荐
- python中的 异常处理(try...expect)
错误处理 关注公众号"轻松学编程"了解更多. 在程序运行的过程中,如果发生了错误,可以事先约定一个错误代码,这样就可以知道是否有错,以及出错的原因,在操作系统的调用中,返回错误码的 ...
- 重载符operator() -- effective c++ 3rd P71的的隐式类型转换及相关的研究
class的"operator 返回类型 ()" 的重载 就是对(class)的重载,这个重载符不用参数,参数就是自身,并且与函数传递的参数括号等价 如 func(c), 并且多个 ...
- P1526 [NOI2003]智破连环阵
目录 题意描述 算法分析 闲话 初步分析 具体思路 剪枝一 剪枝二 剪枝三 总结一下 代码实现 预处理 剪枝一 剪枝二 剪枝三 二分图匹配 代码综合 结语 又是被楼教主虐的体无完肤的一天 题意描述 在 ...
- PHP修改css文件中的背景图片并下载到本地
扒网站当中一般css中的图片扒不下来,这个脚本就是用来下载这些图片到本地的 流程 1.获取css文件路径 2.打开文件逐行读取判断是否包含需要的图片 2.1 包含则 -进行截取直接获取到相对路径 2. ...
- 使用 .NET 5 体验大数据和机器学习
翻译:精致码农-王亮 原文:http://dwz.win/XnM .NET 5 旨在提供统一的运行时和框架,使其在各平台都有统一的运行时行为和开发体验.微软发布了与 .NET 协作的大数据(.NET ...
- MFC的大致讲解
现在使用MFC框架的人越来越少了,现在大家都在用QT框架来写,对应初学者就我感觉来说,MFC真的是一个很好的框架,现在在工业方面使用的几乎都是MFC,所以以后就业想要往工业方面找C++工作,可以好好看 ...
- http 结构初始化
简要而说:accept 到连接后 根据fd 构建一个connection 由于是 http : 重新封装为http-connection:同时设置fd的读回调: 回调函数根据是否是https/htt ...
- python之路《七》文件的处理
其实我觉得python的方便之处就是简便特别是对数据的处理上 当我们要处理一些数据的时候免不了的就是要处理许多的文件那么下面就让我们来看一下文件的处理 1.打开文件 python的文件打开方式较为简单 ...
- showengineinnodbstatus的解读
如何查看innodb的相关信息 ---------------------- BUFFER POOL AND MEMORY ---------------------- Total memory al ...
- Spring源码之事务(一)— TransactionAutoConfiguration自动配置
总结: 在ConfigurationClassParser#parse()中会对deferredImportSelectorHandler进行处理(在处理@ComponentScan 自己所写@Com ...