从银行到电商K8s云原生应用架构落地实践容器化部署微服务管理弹性伸缩运维监控常见问题解决方案
说实话,我第一次接触到Kubernetes的时候,是在一家传统银行做数字化转型的项目里。那时候,我们公司的系统还跑在物理机上,每次新上线一个功能,都得提前两周申请服务器资源,配置环境、调参数、跑测试……整个过程繁琐得让人怀疑人生。后来转行到电商公司,节奏快得多,一天不上线几个版本都不好意思说自己是做研发的。也就是在这个过程中,我才真正理解了什么叫”云原生”。
今天,我想跟你聊聊这条从银行到电商的架构演进之路,说说我们在K8s落地过程中踩过的坑、交过的学费,以及那些值得分享的最佳实践。
银行系统的阵痛:当传统架构遇上数字化浪潮
我还在银行工作的那几年,记得最清楚的就是”上线日”。每个月的1号、15号,全公司的人都不敢正眼休息。为什么?因为那时候银行的系统太复杂了,核心账务、支付渠道、风控引擎、客户管理……每个系统都运行在不同的服务器上,互相之间通过复杂的接口调用。
有一次,春节期间交易量激增,我们的支付渠道系统扛不住了。那时候的处理方式是什么?紧急扩容服务器。听起来很简单对吧?但实际上,整个过程花了将近6个小时:申请资源、安装系统、部署应用、配置参数、测试验证。等系统恢复,春节假期都快结束了。
更头疼的是,银行对稳定性的要求极高,任何变更都需要经过严格的审批流程。一个小小的配置调整,可能要经过五级审批。结果是,业务部门的需求迟迟得不到响应,研发团队抱怨不断,两边都在内耗。
我们当时就意识到,再不改变,迟早被时代淘汰。
第一次接触K8s:从懵圈到真香
转到电商公司后,我第一次听说Kubernetes。同事说,这东西能帮我们解决很多痛点:弹性伸缩、快速部署、服务治理……我半信半疑,直到领导决定让我们尝试把一个新项目部署到K8s上。
那段时间,我白天看文档,晚上敲命令,经常搞到凌晨。记得第一次创建Deployment的时候,我写了整整两页YAML,然后kubectl apply -f,等了半天……没动静。去查日志,才发现是镜像地址写错了。
错误示例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service
spec:
replicas: 3
selector:
matchLabels:
app: order-service
template:
metadata:
labels:
app: order-service
spec:
containers:
- name: order-service
image: myregistry/order-service:latest # 注意:这里用了latest标签,不建议在生产环境使用
ports:
- containerPort: 8080
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
后来我才明白,”latest”标签是个坑。在生产环境,一定要用具体的版本号,比如order-service:v1.2.3。否则,当你回滚版本的时候,会发现根本找不到原来的镜像。
容器化改造:把应用”装进盒子”
银行系统的容器化改造,是从非核心系统开始的。我们选择了一个营销活动系统作为试点。这个系统的技术栈是Spring Boot,数据库是MySQL,缓存用的是Redis。看起来挺简单,但真正容器化的时候,问题还是不少。
Dockerfile示例:
# 使用多阶段构建,减小镜像体积
FROM maven:3.8.6-eclipse-temurin-17-alpine AS builder
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn clean package -DskipTests
# 生产阶段
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
COPY --from=builder /app/target/*.jar app.jar
# 设置时区
ENV TZ=Asia/Shanghai
RUN apk add --no-cache tzdata && \
cp /usr/share/zoneinfo/$TZ /etc/localtime && \
echo $TZ > /etc/timezone
# 非root用户运行,提高安全性
RUN addgroup -g 1001 -S spring && \
adduser -u 1001 -S spring -G spring
USER spring
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
多阶段构建是个好东西,能把构建工具和运行环境分开,最终的镜像体积能减少70%以上。我们之前一个Spring Boot应用的镜像有1.2GB,优化后只有350MB。
镜像优化前后对比:
# 优化前
$ docker images order-service
REPOSITORY TAG SIZE
order-service v1.0.0 1.2GB
# 优化后
$ docker images order-service
REPOSITORY TAG SIZE
order-service v1.0.0 350MB
镜像小了,拉取速度快了,部署效率自然就提高了。
微服务拆分:从单体到分布式
容器化只是第一步,真正的挑战在于微服务拆分。电商系统比银行系统复杂得多,订单、商品、用户、支付、库存……每个模块都有独立的业务逻辑。
我们采用了一套”逐步拆分”的策略:
- 识别边界:通过DDD(领域驱动设计)的方法,找出各个限界上下文
- 服务划分:按照业务领域划分服务,每个服务独立部署
- 接口定义:制定API规范,使用Swagger进行文档管理
- 灰度发布:先让新服务与旧系统共存,逐步切流
服务拆分后的目录结构:
ecommerce-platform/
├── order-service/ # 订单服务
│ ├── Dockerfile
│ ├── src/
│ └── k8s/
│ ├── deployment.yaml
│ ├── service.yaml
│ └── hpa.yaml
├── product-service/ # 商品服务
├── user-service/ # 用户服务
├── payment-service/ # 支付服务
├── inventory-service/ # 库存服务
└── gateway/ # API网关
每个服务都有自己独立的k8s目录,里面存放对应的YAML文件。这样做的目的是让每个服务的部署配置独立管理,避免混乱。
Kubernetes部署:从入门到精通
有了容器化的应用,接下来就是部署到K8s上。刚开始,我们用的是裸K8s集群,后来引入了Service Mesh(Istio)来管理服务间的通信。
Deployment配置文件示例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service
namespace: ecommerce
labels:
app: order-service
version: v1.2.3
team: order-team
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0 # 确保滚动更新期间服务不中断
selector:
matchLabels:
app: order-service
template:
metadata:
labels:
app: order-service
version: v1.2.3
spec:
# 使用专用节点池,提高资源隔离性
nodeSelector:
kubernetes.io/os: linux
node-type: high-memory
# 容忍污点
tolerations:
- key: "dedicated"
operator: "Equal"
value: "ecommerce"
effect: "NoSchedule"
# 亲和性配置
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- order-service
topologyKey: kubernetes.io/hostname
containers:
- name: order-service
image: registry.example.com/order-service:v1.2.3
ports:
- containerPort: 8080
protocol: TCP
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "1Gi"
cpu: "1000m"
env:
- name: SPRING_PROFILES_ACTIVE
value: "production"
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: order-config
key: db.host
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: order-secrets
key: db.password
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
# 启动命令
command: ["/bin/sh", "-c"]
args:
- |
echo "Starting order service..."
java -Xms256m -Xmx512m \
-XX:+UseG1GC \
-XX:MaxGCPauseMillis=200 \
-jar /app/app.jar \
--spring.profiles.active=${SPRING_PROFILES_ACTIVE}
这个配置里用到了很多K8s的最佳实践:
- 资源限制:设置了requests和limits,避免单个Pod占用过多资源
- 探针配置:livenessProbe和readinessProbe分开配置,确保服务健康
- 亲和性与反亲和性:通过podAntiAffinity确保同一个服务的Pod分散在不同节点上
- 环境配置:使用ConfigMap和Secret管理配置,避免硬编码
弹性伸缩:应对流量洪峰
电商系统最怕的就是大促。我记得有一次双11,我们的流量峰值是平时的50倍。如果靠传统方式扩容,根本来不及。K8s的HPA(Horizontal Pod Autoscaler)帮我们解决了这个问题。
HPA配置示例:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: order-service-hpa
namespace: ecommerce
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: order-service
minReplicas: 3
maxReplicas: 50
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 70
- type: Pods
pods:
metric:
name: "http_requests_per_second"
target:
type: AverageValue
averageValue: "1000"
behavior:
scaleUp:
stabilizationWindowSeconds: 60
policies:
- type: Pods
value: 5
periodSeconds: 60
- type: Percent
value: 20
periodSeconds: 60
selectPolicy: Max
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Pods
value: 2
periodSeconds: 60
这个配置有几个关键点:
- 多指标监控:同时监控CPU、内存和HTTP请求数
- 缩放策略:up的时候快速扩容,down的时候慢速缩容,避免频繁震荡
- stabilizationWindowSeconds:防止短暂流量波动导致不必要的伸缩
双11那天,我们的order-service从3个副本扩到了45个,整个过程只用了8分钟。换作以前,这根本不敢想。
VPA(Vertical Pod Autoscaler)补充:
除了水平伸缩,我们还会用到VPA来自动调整Pod的资源请求。
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: order-service-vpa
namespace: ecommerce
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: order-service
updatePolicy:
updateMode: "Auto" # Auto: 自动重启Pod应用新配置; Initial: 仅建议在创建时
resourcePolicy:
containerPolicies:
- containerName: order-service
minAllowed:
cpu: 100m
memory: 128Mi
maxAllowed:
cpu: "2"
memory: 2Gi
controlledResources: ["cpu", "memory"]
VPA会自动分析Pod的历史资源使用情况,给出推荐的资源配置。我们在生产环境用的是”Initial”模式,只在Pod创建时生效,避免运行时变更带来的风险。
运维监控:让系统”透明化”
没有监控的系统就像盲飞。我们搭建了一套完整的监控体系,包括指标监控、日志收集和链路追踪。
Prometheus配置示例:
# prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'kubernetes-pods'
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__meta_kubernetes_namespace]
regex: ecommerce
action: keep
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
action: keep
regex: true
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
action: replace
target_label: __metrics_path__
regex: (.+)
- source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
action: replace
regex: ([^:]+)(?::\d+)?;(\d+)
replacement: $1:$2
target_label: __address__
- action: replace
source_labels:
- __meta_kubernetes_namespace
- __meta_kubernetes_pod_name
regex: (.+);(.+)
target_label: kubernetes_pod
replacement: ${1}/${2}
Grafana仪表板配置示例:
{
"annotations": {
"list": []
},
"editable": true,
"graphs": [],
"panels": [
{
"title": "Order Service - CPU Usage",
"type": "graph",
"datasource": "Prometheus",
"targets": [
{
"expr": "rate(container_cpu_usage_seconds_total{namespace=\"ecommerce\", pod=~\"order-service.*\"}[5m])",
"legendFormat": "{{pod}}"
}
],
"yaxes": [
{
"label": "CPU Usage",
"format": "percentunit"
}
]
},
{
"title": "Order Service - Memory Usage",
"type": "graph",
"datasource": "Prometheus",
"targets": [
{
"expr": "container_memory_working_set_bytes{namespace=\"ecommerce\", pod=~\"order-service.*\"}",
"legendFormat": "{{pod}}"
}
],
"yaxes": [
{
"label": "Memory (Bytes)",
"format": "bytes"
}
]
},
{
"title": "Order Service - HTTP Request Rate",
"type": "graph",
"datasource": "Prometheus",
"targets": [
{
"expr": "sum(rate(http_requests_total{namespace=\"ecommerce\", service=\"order-service\"}[5m])) by (status)",
"legendFormat": "Status {{status}}"
}
]
},
{
"title": "Order Service - Latency P99",
"type": "graph",
"datasource": "Prometheus",
"targets": [
{
"expr": "histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket{namespace=\"ecommerce\", service=\"order-service\"}[5m])) by (le))",
"legendFormat": "P99 Latency"
}
],
"yaxes": [
{
"label": "Seconds",
"format": "s"
}
]
}
],
"schemaVersion": 30,
"version": 1
}
ELK日志收集配置:
# filebeat.yml
filebeat.inputs:
- type: container
paths:
- /var/log/containers/*.ecommerce.*.log
processors:
- add_kubernetes_metadata:
in_cluster: true
output.elasticsearch:
hosts: ["elasticsearch:9200"]
index: "ecommerce-logs-%{+yyyy.MM.dd}"
logging.level: info
Fluentd配置(用于日志转发):
<source>
@type tail
path /var/log/containers/*.log
pos_file /tmp/fluentd-k8s.pos
tag kubernetes.*
read_from_head true
<parse>
@type json
time_key time
time_format %Y-%m-%dT%H:%M:%S.%NZ
</parse>
</source>
<match kubernetes.**>
@type elasticsearch
host elasticsearch-service
port 9200
logstash_format true
logstash_prefix kubernetes
logstash_dateformat %Y-%m-%d
include_tag_key true
type_name access_log
tag_key @log_name
flush_interval 5s
</match>
常见问题及解决方案
在落地K8s的过程中,我们遇到了各种各样的问题。下面整理一些典型的案例和解决方案。
问题一:Pod启动失败,状态为CrashLoopBackOff
现象:Pod创建后不断重启,日志里看不到明确的错误信息。
排查步骤:
# 1. 查看Pod状态
kubectl get pods -n ecommerce
# 2. 查看Pod事件
kubectl describe pod <pod-name> -n ecommerce
# 3. 查看日志
kubectl logs <pod-name> -n ecommerce --previous
# 4. 进入Pod调试
kubectl exec -it <pod-name> -n ecommerce -- /bin/sh
常见原因及解决方案:
镜像问题:镜像不存在或启动命令错误 “`bash
检查镜像是否存在
docker pull myregistry/order-service:v1.2.3
# 检查镜像内的启动命令 docker run –rm myregistry/order-service:v1.2.3 cat /proc/1/cmdline
2. **配置问题**:环境变量或挂载卷配置错误
```yaml
# 检查ConfigMap和Secret是否存在
kubectl get configmap order-config -n ecommerce
kubectl get secret order-secrets -n ecommerce
# 查看配置详情
kubectl describe configmap order-config -n ecommerce
资源不足:节点资源不够,Pod无法调度 “`bash
查看节点资源情况
kubectl describe node
# 查看Pending Pod的原因 kubectl get events -n ecommerce –field-selector reason=FailedScheduling
### 问题二:服务间调用超时
**现象**:电商大促期间,服务间调用频繁超时,导致请求失败。
**排查步骤**:
```bash
# 1. 查看服务间的调用链路(Jaeger)
# 访问 Jaeger UI,查询 trace_id
# 2. 查看服务延迟
kubectl top pods -n ecommerce
# 3. 查看网络连接
kubectl exec <pod-name> -n ecommerce -- netstat -ant | grep ESTABLISHED
解决方案:
调整超时配置: “`yaml
Istio VirtualService配置超时
apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: order-service-vs namespace: ecommerce spec: hosts:
- order-service http:
- match:
prefix: /api/orders route:- uri:
host: order-service port:- destination:
timeout: 5s retries: attempts: 3 perTryTimeout: 2snumber: 8080
”`
优化服务调用:
- 使用连接池,避免频繁建立连接
- 异步调用代替同步调用
- 添加缓存,减少数据库查询
排查网络问题: “`bash
测试服务间连通性
kubectl exec
-n ecommerce – curl -v http://order-service:8080/health
# 检查DNS解析
kubectl exec
# 检查网络策略 kubectl get networkpolicy -n ecommerce
### 问题三:存储持久化问题
**现象**:Pod重启后数据丢失,或者多Pod共享存储出现问题。
**解决方案**:
1. **使用PersistentVolume(PV)和PersistentVolumeClaim(PVC)**:
```yaml
# PV配置
apiVersion: v1
kind: PersistentVolume
metadata:
name: order-data-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs-storage
nfs:
path: /data/orders
server: nfs-server.example.com
# PVC配置
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: order-data-pvc
namespace: ecommerce
spec:
accessModes:
- ReadWriteMany
storageClassName: nfs-storage
resources:
requests:
storage: 5Gi
- StatefulSet用于有状态服务:
“`yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
namespace: ecommerce
spec:
serviceName: mysql
replicas: 3
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
ports:
- containerPort: 3306
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
volumeClaimTemplates:
- metadata: name: mysql-data spec: accessModes: [“ReadWriteOnce”] resources: requests: storage: 10Gi
问题四:Ingress配置问题
现象:外部无法访问服务,或者SSL证书配置不正确。
解决方案:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ecommerce-ingress
namespace: ecommerce
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
ingressClassName: nginx
tls:
- hosts:
- api.example.com
secretName: api-example-tls
rules:
- host: api.example.com
http:
paths:
- path: /api/orders
pathType: Prefix
backend:
service:
name: order-service
port:
number: 8080
- path: /api/products
pathType: Prefix
backend:
service:
name: product-service
port:
number: 8080
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: api-example-tls
namespace: ecommerce
spec:
secretName: api-example-tls
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
commonName: api.example.com
dnsNames:
- api.example.com
acme:
config:
- http01:
ingressClass: nginx
domain: api.example.com
问题五:集群升级导致服务中断
现象:升级K8s版本后,部分Pod无法启动,或者配置不兼容。
预防方案:
使用多集群管理:
# 使用Cluster API管理多集群 kubectl cluster-info kubectl config get-contexts灰度升级策略: “`yaml
分批次升级节点
第一步:升级节点池A(非关键服务)
kubectl cordon node-pool-a-node-1 kubectl drain node-pool-a-node-1 –ignore-daemonsets –delete-emptydir-data
升级node-1…
kubectl uncordon node-pool-a-node-1
# 第二步:观察业务指标 # 第三步:升级节点池B(关键服务)
3. **回滚方案**:
```bash
# 保存当前集群状态
kubectl get all -n ecommerce -o yaml > backup-ecommerce.yaml
# 回滚到上一个版本
kubectl rollout undo deployment/order-service -n ecommerce
kubectl rollout undo deployment/order-service -n ecommerce --to-revision=2
GitOps:让部署更可靠
随着服务数量的增加,手动管理K8s配置变得越来越困难。我们引入了GitOps理念,使用Argo CD来管理应用的部署。
Argo CD Application配置示例:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: order-service
namespace: argocd
spec:
project: default
source:
repoURL: https://git.example.com/ecommerce/order-service.git
targetRevision: main
path: k8s/overlays/production
destination:
server: https://kubernetes.default.svc
namespace: ecommerce
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- PruneLast=true
这样,所有的配置变更都通过Git进行版本控制,任何变更都有迹可查。Argo CD会自动同步集群状态与Git仓库的配置,确保环境的一致性。
CI/CD流水线:自动化是关键
我们使用的CI/CD工具链是:GitLab CI + Jenkins + Harbor + Argo CD。
GitLab CI配置示例:
stages:
- build
- test
- scan
- deploy
variables:
DOCKER_REGISTRY: registry.example.com
IMAGE_NAME: ecommerce/order-service
KUBE_CONFIG: $KUBE_CONFIG_PROD
build:
stage: build
image: docker:24.0
services:
- docker:24.0-dind
script:
- docker login -u $DOCKER_USER -p $DOCKER_PASS $DOCKER_REGISTRY
- docker build -t $DOCKER_REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHA .
- docker push $DOCKER_REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHA
- docker tag $DOCKER_REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHA $DOCKER_REGISTRY/$IMAGE_NAME:$CI_COMMIT_REF_NAME
- docker push $DOCKER_REGISTRY/$IMAGE_NAME:$CI_COMMIT_REF_NAME
only:
- main
- tags
test:
stage: test
image: $DOCKER_REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHA
script:
- ./mvnw test
only:
- main
scan:
stage: scan
image: aquasec/trivy:latest
script:
- trivy image --severity HIGH,CRITICAL $DOCKER_REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHA
only:
- main
deploy:
stage: deploy
image: bitnami/kubectl:latest
script:
- kubectl set image deployment/order-service order-service=$DOCKER_REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHA -n ecommerce
only:
- main
when: manual
安全加固:不容忽视的环节
云原生环境的安全问题越来越多,我们采取了以下措施:
网络隔离: “`yaml apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: order-service-network-policy namespace: ecommerce spec: podSelector: matchLabels:
app: order-servicepolicyTypes:
- Ingress
- Egress ingress:
- from:
matchLabels:- podSelector:
ports:app: gateway
egress:- port: 8080 - to:
matchLabels:- podSelector:
ports:app: mysql- port: 3306 - to:
matchLabels:- podSelector:
ports:app: redis- port: 6379
”`
Pod安全策略: “`yaml apiVersion: pod-security.kubernetes.io/v1 kind: Pod metadata: name: order-service namespace: ecommerce annotations: seccomp.security.alpha.kubernetes.io/pod: runtime/default apparmor.security.beta.kubernetes.io/hruntime/default spec: containers:
- name: order-service image: registry.example.com/order-service:v1.2.3 securityContext: runAsNonRoot: true allowPrivilegeEscalation: false readOnlyRootFilesystem: true capabilities: drop: - ALL
”`
Secret管理:使用外部Secret管理器(如HashiCorp Vault)来管理敏感信息。
成本优化:让每一分钱都花在刀刃上
云原生架构虽然灵活,但成本也不低。我们通过以下方式优化成本:
使用Spot实例:对于非关键服务,使用Spot实例可以节省60-90%的成本。
apiVersion: apps/v1 kind: Deployment metadata: name: non-critical-service namespace: ecommerce spec: replicas: 2 selector: matchLabels: app: non-critical-service template: metadata: labels: app: non-critical-service spec: nodeSelector: node-type: spot tolerations: - key: node.kubernetes.io/not-ready operator: Exists effect: NoExecute tolerationSeconds: 60 - key: node.kubernetes.io/unreachable operator: Exists effect: NoExecute tolerationSeconds: 60资源配额管理:
apiVersion: v1 kind: ResourceQuota metadata: name: ecommerce-quota namespace: ecommerce spec: hard: requests.cpu: "20" requests.memory: 40Gi limits.cpu: "40" limits.memory: 80Gi pods: "100"自动缩容: “`yaml apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: non-critical-service-hpa namespace: ecommerce spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: non-critical-service minReplicas: 1 maxReplicas: 10 metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 30
behavior:
scaleDown:
stabilizationWindowSeconds: 600
policies:
- type: Pods value: 1 periodSeconds: 120
”`
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 30
behavior:
scaleDown:
stabilizationWindowSeconds: 600
policies:
总结:从银行到电商,架构演进的启示
回头看,从银行到电商的架构演进,其实是一个不断学习和适应的过程。银行系统的稳定优先理念,让我们养成了严谨的习惯;电商系统的快速迭代文化,让我们学会了灵活应变。
K8s云原生架构不是一蹴而就的,它需要:
- 循序渐进:从非核心系统开始,逐步扩展到核心业务
- 重视监控:没有监控就没有话语权
- 自动化优先:能自动化的就不要手动
- 安全左移:在开发阶段就考虑安全问题
- 成本意识:云原生不等于无成本
我们踩过的坑、流过的泪,都化作了今天的经验。希望这些分享能帮到正在或者准备走这条路的朋友。如果你有什么具体问题,欢迎随时交流,我们一起学习进步。
