网站首页 > 博客文章 正文
使用云平台:Kubernetes 管理系统
Kubernetes(https://kubernetes.io/),通常简称为 K8s,是一个开源平台,用于管理容器化应用程序。可以把它比作管弦乐团的指挥,但它管理的是一群机器上的容器,而不是乐器。现在,让我们来看看 Kubernetes 如何支持微服务:
使用 Kubernetes 管理微服务的好处包括:
- 可扩展性:Kubernetes 让您可以根据需求轻松地调整单个服务的规模,省去配置整个服务器的麻烦。这使您能够快速适应变化的流量模式,避免资源浪费。
- 高可用性:Kubernetes 能够在容器或机器发生故障时继续运行您的服务。它会自动重启崩溃的容器,并将其重新调度到健康的节点上,确保您的应用程序始终可用。
- 解耦与自主性:Kubernetes 能够独立管理每个微服务,让开发团队自主工作,快速部署更新,而不影响其他服务。
- 资源管理:Kubernetes 允许您为每个服务设定资源限制和配额,确保资源的公平分配,防止资源短缺。这优化了资源的使用效率,并有助于保持系统的稳定性。
- 部署与回滚:轻松简化单个服务的部署和回滚,降低风险,使更新过程更不易干扰。
- 可观察性与监控:您可以监测 Kubernetes 中每个服务的健康状态和性能,从而帮助您快速识别和解决问题。
以下是 Kubernetes 的一些关键特性,这些特性有助于微服务的实现:
- Pods:这些是共享资源和存储的相关容器组。可以将它们视为您服务的迷你环境。
- 部署:您可以定义服务的期望状态,Kubernetes 会确保它们达到这一状态,并自动处理扩展和更新。
- 服务:您可以将微服务提供给其他服务或外部客户端,Kubernetes 会负责负载均衡和服务发现。
- 命名空间:Kubernetes 允许您为不同的团队或环境隔离资源和配置,从而增强安全性和组织性。
Kubernetes 为部署和管理微服务提供了强大的平台,带来了以下优势:
- 提高灵活性和加快开发周期
- 提升可扩展性和高可用性
- 高效利用资源以节省成本
- 简化的操作与管理
Kubernetes 当然不是唯一的微服务平台。其他一些流行的微服务平台包括 Docker Swarm (https://docs.docker.com/engine/swarm/)、HashiCorp Nomad (https://www.nomadproject.io/)、Marathon (https://mesosphere.github.io/marathon/)、Rancher (https://www.rancher.com/)、Cattle (https://github.com/rancher/cattle) 和 Cloud Foundry (https://www.cloudfoundry.org/)。
Kubernetes 是一个强有力的工具,适合用于管理您的容器化环境。虽然 Kubernetes 有一定的学习曲线,但在大规模管理分布式系统时,它所带来的好处是非常显著的。
使用 Kubernetes 平台
正如之前所述,Kubernetes 提供服务发现、配置管理、秘密管理、可靠性、可观察性、高可用性等多种功能。因此,让我们将 Kubernetes 作为我们的云平台,看看如何部署我们的应用。
在本节中,我们将使用 Minikube 作为我们的 Kubernetes 集群,以便在您的计算机上进行本地测试。如果您已经在 Google Cloud、AWS 或 Microsoft Azure 上拥有 Kubernetes 集群,您可以按照相同的步骤进行操作。
如果你在跟着学习,你可以在 13-cloud/k8s 文件夹中找到本节的文件。
安装的前提条件
运行 Minikube 的必要条件如下:
- 1.
- 请访问 https://minikube.sigs.k8s.io/docs/start/ 来安装 Minikube。
- 2.
- 从 https://kubernetes.io/docs/tasks/tools/ 安装 kubectl CLI。如果您已经安装了 Docker Desktop,kubectl 通常会随安装一起提供。
- 3.
- 你可以选择从 https://k9scli.io/ 安装 K9s。这是一个基于文本的用户界面,可以帮助你可视化所有 Kubernetes 组件,而无需输入过多内容。
启动 Minikube 环境
要启动 Minikube,请确保您的系统至少有 4GB 的内存。您可以使用默认配置进行启动。
minikube start
如果你有更多内存,可以使用 --memory 参数。例如,如果你的电脑总内存为 8GB,你可以启动 minikube。
minikube start --memory 4096
还有其他参数,比如 --cpu,您可以用它来指定使用多少个 CPU 核心。要了解更多关于 minikube CLI 的信息,请查看这里的文档:https://minikube.sigs.k8s.io/docs/。
创建 Postgres 部署方案
我们的用户应用需要使用 PostgreSQL 作为数据库,因此我们需要按照接下来的说明来启动它。
配置映射表
我们需要创建用户名和密码。Kubernetes 提供了一种保存和使用它们的方法;在这种情况下,有一个名为 ConfigMap 的组件,声明如下:
apiVersion: v1
kind: ConfigMap
metadata:
name: postgres-config
labels:
app: postgres
data:
POSTGRES_DB: users_db
POSTGRES_USER: admin
POSTGRES_PASSWORD: mysecretpassword
持久卷与持久卷声明
我们需要正确地存储数据。在 Kubernetes 中,PersistentVolume(PV)是实际的存储空间,类似于硬盘,而 PersistentVolumeClaim(PVC)是用户对特定存储量的请求。可以把它看作一个停车场(PV),用户在这里请求停车位(PVC)。PersistentVolume 的声明如下:
kind: PersistentVolume
apiVersion: v1
metadata:
name: postgres-pv-volume
labels:
type: local
app: postgres
spec:
storageClassName: manual
capacity:
storage: 5Gi
accessModes:
- ReadWriteMany
hostPath:
path: "/mnt/data"
持久卷声明如下所示:
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: postgres-pv-claim
labels:
app: postgres
spec:
storageClassName: manual
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
部署过程
在 Kubernetes 中,部署是您对 Pod 的自动驾驶,确保所需数量的实例正常运行,顺利更新,并在必要时进行回滚。PostgreSQL 的部署如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres # Sets Deployment name
spec:
replicas: 1
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres
imagePullPolicy: "IfNotPresent"
ports:
- containerPort: 5432 # Exposes container port
envFrom:
- configMapRef:
name: postgres-config
volumeMounts:
- mountPath: /var/lib/postgresql/data
name: postgredb
resources:
limits:
cpu: "1"
memory: "1Gi"
requests:
cpu: "0.5"
memory: "512Mi"
volumes:
- name: postgredb
persistentVolumeClaim:
claimName: postgres-pv-claim
在继续之前,请务必仔细阅读此声明。
服务内容
Kubernetes 中的服务是访问一组 Pod 的统一入口,隐藏它们的具体细节,并确保高可用性。PostgreSQL 服务如下:
apiVersion: v1
kind: Service
metadata:
name: postgres
labels:
app: postgres
spec:
type: NodePort
ports:
- port: 5432
selector:
app: postgres
安装声明文件
所有这些声明都在一个名为 postgresql.yaml 的文件中。要在您的 Kubernetes 中安装它,您可以执行以下命令:
kubectl apply -f postgresql.yaml
在 Kubernetes 中部署微服务:用户应用、我的复古应用和我的复古网关应用的部署
在本节中,我们将部署所有微服务。回顾一下,我们在 My Retro APP 和 My Retro Gateway 项目中分别使用了 spring-cloud-starter-kubernetes-client-all 和 spring-cloud-starter-kubernetes-fabric8-all 这两个依赖项。通过这些依赖项,我们可以将应用程序无缝集成到 Kubernetes 中,并在 Spring Boot 应用程序中充分利用 Kubernetes 的功能。接下来,我们将讨论其中的一些功能。
集群角色与集群角色绑定
ClusterRole 定义了集群级别的权限,而 ClusterRoleBinding 则将这些权限分配给所有命名空间中的用户或组。可以将其理解为先设置访问规则(ClusterRole),再将这些规则应用到用户(ClusterRoleBinding)上。
我们需要同时声明这两个,因为 Spring Cloud Kubernetes 的依赖项需要访问服务、端点、配置映射、Pod 等,以便在 Spring Boot 端实现无代码的简单集成。ClusterRole 的声明如下:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cluster-read-role
rules:
- apiGroups:
- ""
resources:
- endpoints
- pods
- services
- configmaps
verbs:
- get
- list
- watch
ClusterRoleBinding 的声明如下:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: cluster-read-rolebinding
subjects:
- kind: ServiceAccount
name: default
namespace: default
roleRef:
kind: ClusterRole
name: cluster-read-role
apiGroup: rbac.authorization.k8s.io
通过这些声明,使用 Spring Cloud Kubernetes 依赖的 Spring Boot 应用(我的复古应用和我的复古网关)可以充分利用我们接下来要讨论的集成功能。
用户的部署与服务
让我们来开始用户应用的部署声明:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: users
name: users
spec:
replicas: 1
selector:
matchLabels:
app: users
template:
metadata:
labels:
app: users
spec:
containers:
- name: users
image: felipeg48/users:latest
ports:
- containerPort: 8080
env:
- name: spring.cloud.consul.enabled
value: "false"
- name: spring.datasource.url
value: "jdbc:postgresql://postgres.default.svc.cluster.local:5432/users_db"
- name: spring.datasource.username
valueFrom:
configMapKeyRef:
name: postgres-config
key: POSTGRES_USER
- name: spring.datasource.password
valueFrom:
configMapKeyRef:
name: postgres-config
key: POSTGRES_PASSWORD
resources:
limits:
cpu: "0.5"
memory: "768Mi"
livenessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 6
让我们一起审查这份声明:
- 我们正在使用之前生成的这个镜像。您可以切换到自己的镜像,但这个镜像是公开可用的。
- 我们在 env 部分声明环境变量。由于不打算使用 Consul 进行服务发现和配置,而是选择 Kubernetes 的默认设置,因此我们将 Consul 禁用,将该值设置为 false。
- 该属性保存了 URL(是的,我们正在覆盖它的值),使用标准方式来定位服务。语法为 ..svc.cluster.local。我们可以直接使用 postgres,但我想向您展示 Kubernetes DNS 的用法。
- 我们也在覆盖这些属性。我们通过使用这些键,引用之前定义的 postgres-config 的 ConfigMap。
- livenessProbe: 我们使用这个声明来调用 /actuator/health 端点,以确保我们的应用程序处于健康状态。此外,我们还设置了一些资源限制,以帮助我们减少 Kubernetes 安装的整体资源使用。
接下来,我们来查看用户应用服务的声明:
apiVersion: v1
kind: Service
metadata:
labels:
app: users
name: users-service
spec:
type: NodePort
selector:
app: users
ports:
- name: http
protocol: TCP
port: 80
targetPort: 8080
在这里,我们定义了一个 NodePort,并使用端口 80,该端口会重定向到容器内的 8080。
我的复古部署与服务
接下来,让我们来看看我的复古部署情况:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: myretro
name: myretro
spec:
replicas: 1
selector:
matchLabels:
app: myretro
template:
metadata:
labels:
app: myretro
spec:
containers:
- name: myretro
image: felipeg48/myretro:latest
ports:
- containerPort: 8080
env:
- name: spring.cloud.consul.enabled
value: "false"
resources:
limits:
cpu: "0.5"
memory: "768Mi"
livenessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 6
我们正在使用我的镜像,但你可以更换成你的镜像。此外,我们通过将 spring.cloud.consul.enabled 属性的值设置为 false 来禁用 Consul 配置。
请记住,这个应用程序使用 OpenFeign 连接到用户服务。由于我们使用了 Spring Cloud Kubernetes 依赖,Kubernetes 在后台会处理服务发现和负载均衡,通过类似 users-service.default.svc.cluster.local 的主机来访问服务。
用户服务的声明如下所示:
apiVersion: v1
kind: Service
metadata:
labels:
app: myretro
name: my-retro-app
spec:
type: NodePort
selector:
app: myretro
ports:
- name: http
protocol: TCP
port: 80
targetPort: 8080
我的复古网关配置、部署和服务
接下来,我们来看看 My Retro Gateway 的声明。首先,我们来查看 ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: myretro-gateway
data:
application.yaml: |-
management:
endpoint:
gateway:
enabled: true
endpoints:
web:
exposure:
include: "health,info,gateway,configprops,conditions,env,beans"
spring:
cloud:
gateway:
routes:
- id: users
uri: http://users-service
predicates:
- Path=/users/**
filters:
- name: CircuitBreaker
args:
name: users
fallbackUri: forward:/fallback/users
- id: myretro
uri: http://my-retro-app
predicates:
- Path=/retros/**
filters:
- name: CircuitBreaker
args:
name: retros
fallbackUri: forward:/fallback/retros
让我们一起回顾一下:
- 在 ConfigMap 的数据部分,我们声明了一个新的 application.yaml 文件。是的,我们将覆盖镜像中所有的 application.yaml 文件。在这里,我们定义了一些新的属性,但最重要的属性如下。
- 我们正在重新定义路由,唯一的变化是 uri 键,我们将 lb://(负载均衡器)替换为 http://。在这种情况下,我们使用 http:// 是因为负载均衡是由 Kubernetes 服务提供的,因此不需要添加 lb:// 前缀。此外,我们不再使用 Consul,而是采用 Kubernetes 的默认设置(服务发现和负载均衡)。
接下来是部署声明:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: myretro-gateway
name: myretro-gateway
spec:
replicas: 1
selector:
matchLabels:
app: myretro-gateway
template:
metadata:
labels:
app: myretro-gateway
spec:
containers:
- name: myretro-gateway
image: felipeg48/myretro-gateway:latest
ports:
- containerPort: 8080
env:
- name: spring.config.import
value: "kubernetes:"
- name: spring.cloud.consul.enabled
value: "false"
resources:
limits:
cpu: "0.5"
memory: "768Mi"
livenessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 6
在这里,我们禁用了 Consul(spring.cloud.consul.enabled=false)。我们使用了一个已知的属性 spring.config.import,值为 kubernetes://;只需添加这个,Spring Cloud Kubernetes 的自动配置就会查找与应用程序名称匹配的 ConfigMap,在这种情况下是我们之前声明的 myretro-gateway ConfigMap,并将 application.yaml 文件的新值应用到应用程序中。这真是太酷了!如果你有一个不同名称的 ConfigMap,仍然可以使用,但必须遵循一些命名约定。如果想了解更多,请访问:https://docs.spring.io/spring-cloud-kubernetes/reference/property-source-config/configmap-propertysource.html。
接下来,我们来回顾一下服务内容:
apiVersion: v1
kind: Service
metadata:
labels:
app: myretro-gateway
name: myretro-gateway-service
spec:
type: NodePort
selector:
app: myretro-gateway
ports:
- name: http
protocol: TCP
port: 8080
targetPort: 8080
我们正在使用 8080 端口。
在源代码 13-cloud/k8s 文件夹中,您可以找到一个名为 myretro.yaml 的文件,里面包含我们刚刚审查的所有声明。要应用这个文件,您可以使用以下命令:
kubectl apply -f myretro.yaml
就这样。现在我们可以使用 My Retro Gateway 服务来访问我们的应用程序。您可以通过以下命令检查 pod 是否正常运行以及服务的状态:
kubectl get pods
kubectl get services
访问我的复古网关:如何使用端口转发
接下来,我们将通过 Kubernetes 的端口转发和 myretro-gateway-service 来访问我们的应用。在终端中执行以下命令:
kubectl port-forward svc/myretro-gateway-service 8080:8080
通过这个,你可以选择打开浏览器,或者使用以下命令来访问应用程序:
curl -s http://localhost:8080/users | jq
curl -s http://localhost:8080/retros | jq
curl -s http://localhost:8080/retros/users | j
如果你想查看一些日志,首先需要获取 pod 的名称
kubectl get pods
然后,您可以查看日志记录
kubectl logs <pod-name>
就这样!现在你已经知道如何在 Kubernetes 中部署微服务了。
如果您希望使用 Consul 代替默认的 Kubernetes 服务发现、配置和负载均衡,可以使用 Consul for Kubernetes,这将使微服务的部署变得更加简单。请查看其文档: https://developer.hashicorp.com/consul/docs/k8s。
清理工作
关闭所有内容的最简单方法是执行以下命令,这将删除为 Kubernetes 创建的虚拟机
minikube delete --all --purge
如果你只是想停止它,可以使用
minikube stop
我鼓励你继续探索 Spring Cloud 提供的所有功能,不仅包括 Spring Cloud Consul 和 Spring Cloud Vault,还包括其他项目。
概要
在本章中,我们回顾了 Spring Cloud Consul 用于服务发现和配置,Spring Cloud Vault 用于管理秘密和配置,Spring Cloud Gateway 通过使用断路器模式实现路由、过滤和回退,以及一些 HashiCorp 的产品,如 Consul 和 Vault。
我们还研究了 Docker Compose 和 Kubernetes,了解了如何利用这个云平台实现多个实例、服务发现、高可用性等众多开箱即用的功能;得益于 Spring Cloud Kubernetes,集成变得更加简单。
我需要一本完整的第二本书来描述更多的 Spring Cloud 技术。在我的书《Spring Boot Messaging》(Apress,2017)中,我介绍了 Spring Cloud Stream,而在《Spring Cloud Data Flow》(Apress,2020)中,我则介绍了其他可以丰富您云计算之旅的技术。
- 上一篇: android api 从13 升级到15过程
- 下一篇: C++重载函数和重载运算符
猜你喜欢
- 2025-01-15 kubernetes快速安装部署指南
- 2025-01-15 一文带你看懂vue基础语法、生命周期、指令、监听器、依赖注入
- 2025-01-15 美国工程合同中常见的招投标条款(中英文对照)
- 2025-01-15 JNI接口操作最佳实践(三)
- 2025-01-15 java基础都在这了,小主们拿去吧
- 2025-01-15 写作技巧——这些情况下,必须加连字符
- 2025-01-15 「云原生」k8s中volumeMounts.subPath的巧妙用法
- 2025-01-15 RmlUi:探索C++图形用户界面的璀璨明珠
- 2025-01-15 超级好用的配置文件解析器:minIni
- 2025-01-15 windows常见后门和Linux常见后门
你 发表评论:
欢迎- 366℃用AI Agent治理微服务的复杂性问题|QCon
- 358℃初次使用IntelliJ IDEA新建Maven项目
- 354℃手把手教程「JavaWeb」优雅的SpringMvc+Mybatis整合之路
- 351℃Maven技术方案最全手册(mavena)
- 348℃安利Touch Bar 专属应用,让闲置的Touch Bar活跃起来!
- 346℃InfoQ 2024 年趋势报告:架构篇(infoq+2024+年趋势报告:架构篇分析)
- 344℃IntelliJ IDEA 2018版本和2022版本创建 Maven 项目对比
- 342℃从头搭建 IntelliJ IDEA 环境(intellij idea建包)
- 最近发表
- 标签列表
-
- powershellfor (55)
- messagesource (56)
- aspose.pdf破解版 (56)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- jwt漏洞 (58)
- macos14下载 (58)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- vue回到顶部 (57)
- qcombobox样式表 (68)
- vue数组concat (56)
- tomcatundertow (58)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)