介绍

这是一个关于 Egg.js 应用上云️的示例,笔者所在的大前端团队的已应用于生产。

CI/CD & DevOps & GitOps & HPA 等这里暂不做讨论,因为每一个点篇幅都很长。

我这里的实验条件

示例项目

可直接做实验(文章写的再好,不如提供一个上云示例)

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。

Egg 关于 K8S 部署的相关 issues

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的更多相关文章

  1. 云原生之旅 - 5)Kubernetes时代的包管理工具 Helm

    前言 上一篇文章 [基础设施即代码 使用 Terraform 创建 Kubernetes] 教会了你如何在Cloud上面建Kubernetes资源,那么本篇来讲一下如何在Kubernetes上面部署应 ...

  2. 第一届云原生应用大赛火热报名中! helm install “一键安装”应用触手可及!

    云原生应用,是指符合“云原生”理念的应用开发与交付模式,这是当前在云时代最受欢迎的应用开发最佳实践. 在现今的云原生生态当中,已经有很多成熟的开源软件被制作成了 Helm Charts,使得用户可以非 ...

  3. 如何将云原生工作负载映射到 Kubernetes 中的控制器

    作者:Janakiram MSV 译者:殷龙飞 原文地址:https://thenewstack.io/how-to-map-cloud-native-workloads-to-kubernetes- ...

  4. 云原生应用 Kubernetes 监控与弹性实践

    前言 云原生应用的设计理念已经被越来越多的开发者接受与认可,而Kubernetes做为云原生的标准接口实现,已经成为了整个stack的中心,云服务的能力可以通过Cloud Provider.CRD C ...

  5. 云原生之旅 - 6)不能错过的一款 Kubernetes 应用编排管理神器 Kustomize

    前言 相信经过前一篇文章的学习,大家已经对Helm有所了解,本篇文章介绍另一款工具 Kustomize,为什么Helm如此流行,还会出现 Kustomize?而且 Kustomize 自 kubect ...

  6. 云原生生态周报 Vol.9| K8s v1.15 版本发布

    本周作者 | 衷源.心贵 业界要闻 1.Kubernetes Release v1.15 版本发布,新版本的两个主题是持续性改进和可扩展性.(https://github.com/kubernetes ...

  7. 云原生生态周报 Vol. 8 | Gartner 发布云原生趋势

    业界要闻 Gartner 发布云原生基础设施未来的八大趋势:权威分析机构 Gartner 在对 2020 年技术趋势的展望当中指出:“预计2020年所有领先的容器管理软件均内置服务融合技术,到2022 ...

  8. 如何优雅地使用云原生 Prometheus 监控集群

    作者陈凯烨,腾讯云前端开发工程师.负责 TKE 集群,弹性集群和云原生监控等模块控制台开发. 概述 Prometheus 是一套开源的系统监控报警框架.2016 年,Prometheus 正式加入 C ...

  9. Dapr | 云原生的抽象与实现

    引言 Dapr 是微软主导的云原生开源项目,2019年10月首次发布,到今年2月正式发布 V1.0 版本.在不到一年半的时间内,github star 数达到了 1.2 万,超过同期的 kuberne ...

随机推荐

  1. 4G DTU模块和串口设备连接的方式

    首先说下解决思路: 由于考虑到串口开发很麻烦,所以后来买了一个4g模块的dtu. 所以最后的解决方案是,plc串口设备与dtu相连,由于dtu是透传模式,使用java与4g模块进行通信就完事了. 虽然 ...

  2. python实现有趣的数学逻辑程序

    1.无重复数字的三位数 题目:有1.2.3.4个数字, 能组成多少个互不相同且无重复数字的三位数? 都是多少? for i in range(1,5): for j in range(1,5): fo ...

  3. Django之实现分页显示内容

    关注公众号"轻松学编程"了解更多.- ​ 分页 1.作用 数据加载优化 2.前端引入bootstrap样式: {# 引入bootstrap样式的cdn资源 #} <link ...

  4. 【jmeter】实现接口关联的两种方式:正则表达式提取器和json提取器

    关联通俗来讲就是把上一次请求的返回内容中的部分截取出来保存为参数,用来传递给下一个请求使用. 示例: 1.用户密码进行登录,登录后生成authentication 2.需要将登录接口响应结果中auth ...

  5. Raft算法原理剖析

    一.复制状态机(replicated state machine) Raft协议可以使得一个集群的服务器组成复制状态机,在详细了解Raft算法之前,我们先来了解一下什么是复制状态机.一个分布式的复制状 ...

  6. Elasticsearch原理解析与性能调优

    基本概念 定义 一个分布式的实时文档存储,每个字段 可以被索引与搜索 一个分布式实时分析搜索引擎 能胜任上百个服务节点的扩展,并支持 PB 级别的结构化或者非结构化数据 用途 全文检索 结构化搜索 分 ...

  7. 【Kubernetes学习笔记】-使用Minikube快速部署K8S单机学习环境

    介绍 https://minikube.sigs.k8s.io/docs/ Minikube 用于快速在本地搭建 Kubernetes 单节点集群环境,它对硬件资源没有太高的要求,方便开发人员学习试用 ...

  8. JAVA基础之接口与内部类

    接口与内部类 目录 接口与内部类 1. Lambda表达式 1. 关于懒计算 2. Predicate接口 3. 关于方法引用 4. 关于构造器引用 5. 关于变量的作用域 2. 内部类 1. 局部内 ...

  9. 第一章epoll

    IO多路复用之epoll总结 1.基本知识 epoll是在2.6内核中提出的,是之前的select和poll的增强版本.相对于select和poll来说,epoll更加灵活,没有描述符限制.epoll ...

  10. Centos7下Jewel版本radosgw服务启动

    前言 本篇介绍了centos7下jewel版本的radosgw配置,这里的配置是指将服务能够正常起来,不涉及到S3的配置,以及其他的更多的配置,radosgw后面的gw就是gateway的意思,也就是 ...