Kubernetes
基本概念
Pod
是什么: Kubernetes 中最小的、最简单的部署和管理单元。
类比: 一台“逻辑主机”或一个“虚拟机实例”。
关键点:
- 一个 Pod 可以包含一个或多个紧密相关的容器(例如,一个应用容器和一个日志收集 sidecar 容器)。
- 这些容器共享网络命名空间(拥有相同的 IP 地址和端口空间)、存储卷和其他资源。
- Pod 是短暂的,会被频繁地创建和销毁
Deployment
是什么: 用于部署和管理 Pod 副本集的声明式定义。
解决的问题: 如何确保指定数量的、完全相同的 Pod 副本始终在运行?如何无缝更新应用(滚动更新)?如何在更新出问题时快速回滚?
关键点:
- 你定义一个“期望状态”(例如,需要运行 3 个 Nginx Pod),Deployment 控制器会确保实际状态始终匹配这个期望状态。
- 它是实现无状态应用部署的首选控制器。
Service
是什么: 一个稳定的网络端点,用于访问一组 Pod。
解决的问题: Pod 是短暂的,IP 地址会变。客户端如何稳定地找到并访问这些动态变化的 Pod?
关键点:
- Service 提供一个固定的 虚拟 IP (ClusterIP) 和 DNS 名称。
- 通过 标签选择器 (Label Selector) 来匹配一组 Pod,并将流量负载均衡到这些 Pod 上。
- 常见的类型:
- ClusterIP: 默认类型,仅在集群内部可访问。
- NodePort: 在每个节点上开放一个静态端口,从而可以从集群外部访问。
- LoadBalancer: 使用云提供商的负载均衡器,向外部公开服务
Volume (存储卷)
是什么: 允许 Pod 中的容器持久化存储数据。
解决的问题: 容器内部的文件系统是临时的,容器重启后数据会丢失。如何持久化保存数据(如数据库文件、日志)?
关键点:
- 存储卷的生命周期独立于 Pod。即使 Pod 被销毁,存储卷中的数据依然存在。
- 支持多种后端存储类型:本地存储、云存储(如 AWS EBS、GCE PD)、NFS、分布式存储(如 Ceph)等。
Namespace (命名空间)
是什么: 在物理集群内部创建的虚拟集群,用于实现资源隔离和分组。
解决的问题: 在有多个团队或项目的大型集群中,如何避免资源(如 Pod、Service 名称)冲突?如何实现资源配额管理?
关键点:
- 默认有 default, kube-system (系统组件), kube-public 等命名空间。
- 可以为每个命名空间设置资源配额,限制其能使用的 CPU、内存等资源总量。
ConfigMap & Secret
- ConfigMap: 用于将非机密的配置数据(如配置文件、环境变量、命令行参数)与容器镜像解耦。让你可以不重写镜像就能改变应用配置。
- Secret: 与 ConfigMap 类似,但专门用于存储敏感信息,如密码、OAuth 令牌、SSH 密钥。数据会以 Base64 编码(非加密,需额外措施保障安全)存储。
使用K8S部署Spring Boot应用
前置条件,docker和kubernetes已安装配置
参考:macOS上优雅运行Docker容器
准备一个Spring Boot应用
SpringK8sDemoApplication- @SpringBootApplication
- @RestController
- public class SpringK8sDemoApplication {
- private static Date firstTime;
- private static SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- public static void main(String[] args) {
- SpringApplication.run(SpringK8sDemoApplication.class, args);
- }
- @GetMapping("/")
- public String hello() {
- if (firstTime == null) {
- firstTime = new Date();
- }
- // 容器里看日志是否有负载均衡
- System.out.println("request in " + formatter.format(new Date()));
- return "Hello from Spring Boot on Kubernetes! first time: " + formatter.format(firstTime);
- }
- @GetMapping("/health")
- public String health() {
- return "OK";
- }
- }
复制代码 pom.xml- <?xml version="1.0" encoding="UTF-8"?>
- <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.springframework.boot</groupId>
- spring-boot-starter-parent</artifactId>
- <version>3.5.7</version>
- <relativePath />
- </parent>
- <groupId>com.example</groupId>
- spring-k8s-demo</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <name>spring-k8s-demo</name>
- <description>Demo project for Spring Boot</description>
- <properties>
- <java.version>21</java.version>
- </properties>
- <dependencies>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- spring-boot-starter</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- spring-boot-starter-web</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- spring-boot-starter-test</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
- <build>
- <plugins>
- <plugin>
- <groupId>org.springframework.boot</groupId>
- spring-boot-maven-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
- </project>
复制代码 构建 Docker 镜像
Dockerfile- FROM eclipse-temurin:21-jre-alpine AS runtime
- # 创建应用目录
- WORKDIR /app
- # 复制jar文件
- COPY target/spring-k8s-demo-0.0.1-SNAPSHOT.jar app.jar
- # 暴露端口
- EXPOSE 8080
- # 启动应用
- ENTRYPOINT ["java", "-jar", "app.jar"]
复制代码 build.sh- # 切换指定JDK版本(可选)
- export JAVA_HOME=`/usr/libexec/java_home -v 21`
- # 可替换mvn
- mvnd clean package -DskipTests
- # 构建镜像
- docker build -t spring-k8s-demo:latest .
复制代码 编写 k8s Deployment 文件
k8s-deployment.yaml- apiVersion: apps/v1
- kind: Deployment
- metadata:
- name: spring-app
- spec:
- replicas: 2 # 运行 2 个 Pod 副本
- selector:
- matchLabels:
- app: spring-app
- template:
- metadata:
- labels:
- app: spring-app
- spec:
- containers:
- - name: spring-app
- image: spring-k8s-demo:latest
- ports:
- - containerPort: 8080 # 容器内暴露的端口
- livenessProbe: # 存活探针
- httpGet:
- path: /health
- port: 8080
- initialDelaySeconds: 300
- periodSeconds: 10
- readinessProbe: # 就绪探针
- httpGet:
- path: /health
- port: 8080
- initialDelaySeconds: 300
- periodSeconds: 10
- resources: # 分配资源
- requests:
- memory: "256Mi"
- cpu: "250m"
- limits:
- memory: "512Mi"
- cpu: "500m"
复制代码 k8s-services.yaml- # service.yaml
- apiVersion: v1
- kind: Service
- metadata:
- name: sprint-service
- labels:
- app: sprint-service
- spec:
- type: NodePort
- selector:
- app: spring-app
- ports:
- - protocol: TCP
- port: 80
- targetPort: 8080
- nodePort: 30080
复制代码 配置文件解释:
- Deployment:
- replicas: 2:确保任何时候都有 2 个 Pod 在运行。
- selector & labels:Deployment 通过 app: spring-app 这个标签来管理它创建的 Pod。
- image:指定从哪个镜像运行容器。
- resources:为容器设置 CPU 和内存的资源请求与限制,这是生产环境的最佳实践。
- Service:
- type: NodePort: 在每个节点上开放一个静态端口,从而可以从集群外部访问
- selector: app: spring-app:Service 通过这个标签找到要代理的 Pod。
- ports:将 Service 的 80 端口流量转发到 Pod 的 8080 端口。
部署到集群
应用配置- kubectl apply -f k8s-deployment.yaml
- kubectl apply -f k8s-services.yaml
复制代码 测试
Pod 状态变为 Running
- curl http://192.168.64.3:30080/
复制代码
根据时间,可以看到每次轮询到不同pod,也就是不同容器
注意:因为我使用是colima所以需要使用colima list命令查出来IP是192.168.64.3
k8s 常用命令
- # 查看所有节点
- kubectl get nodes
- # 查看节点详情
- kubectl describe node <node-name>
- # 查看Pod
- kubectl get pods
- # 查看Pod详情
- kubectl describe pod <pod-name>
- # 查看Pod日志
- kubectl logs <pod-name> -n <namespace>
- # 查看单个 Pod 的日志
- kubectl logs <pod-name>
- # 查看部署
- kubectl get deployments
- # 查看部署详情
- kubectl describe deployment <deployment-name>
- # 查看由 Deployment 创建的所有 Pod 的日志
- kubectl logs -l app=spring-app
- # 转发端口(用于本地测试)
- kubectl port-forward svc/sprint-service 8080:80
- # 水平扩缩容(将副本数从 2 增加到 3)
- kubectl scale deployment spring-app --replicas=3
- # 查看部署历史
- kubectl rollout history deployment/<deployment-name>
- # 滚动更新(例如,更新到新版本的镜像)
- kubectl set image deployment/spring-app java-app=spring-k8s-demo:2.0.0
- # 回滚到上一个版本
- kubectl rollout undo deployment/<deployment-name>
- # 删除部署
- kubectl delete -f k8s-deployment.yaml
- kubectl delete -f k8s-services.yaml
复制代码 引用
https://github.com/WilsonPan/java-developer
例子: https://github.com/WilsonPan/java-developer/tree/main/samples/spring-demo
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |