因為 k8s 本身就有擁有注冊中心,和配置中心的功能。如果還是用 Nacos、Eureka、Consul 之類的注冊中心組件,就有點冗余了。當(dāng)然這些組件還是可以繼續(xù)用的。
所以,本教程,教授 Spring Cloud 使用 k8s 的注冊中心。在開發(fā)環(huán)境和生產(chǎn)環(huán)境 的教程!
下面以一個最簡單的 服務(wù)消費者 使用 OpenFeign 調(diào)用 服務(wù)提供者 的案例
源代碼地址(我也不想用gitee,但是github太慢了):
https://gitee.com/thousmile/k8s-demo1
k8s-demo1 的 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>
<packaging>pom</packaging>
<groupId>com.xaaef.k8sdemo</groupId>
<artifactId>k8s-demo1</artifactId>
<version>1.1</version>
<name>k8s-demo1</name>
<description>k8s-demo1</description>
<modules>
<module>k8s-provider</module>
<module>k8s-consumer</module>
</modules>
<properties>
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<maven-compiler.version>3.10.1</maven-compiler.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<hutool.version>5.8.9</hutool.version>
<spring-boot.version>3.0.6</spring-boot.version>
<spring-cloud.version>2022.0.2</spring-cloud.version>
</properties>
<dependencies>
<!-- 生產(chǎn)環(huán)境用 kubernetes 注冊中心 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-fabric8</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-bom</artifactId>
<version>${hutool.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
服務(wù)提供者 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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.xaaef.k8sdemo</groupId>
<artifactId>k8s-demo1</artifactId>
<version>1.1</version>
</parent>
<artifactId>k8s-provider</artifactId>
<name>k8s-provider</name>
<description>
管理服務(wù)
</description>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
服務(wù)提供者 application.yml
server:
port: 18831
spring:
application:
name: k8s-provider
profiles:
active: dev
服務(wù)提供者 application-dev.yml
開發(fā)環(huán)境,禁用 k8s 的注冊中心。就算啟用,也沒啥用,在本地idea中開發(fā)時,根本獲取不到k8s注冊中心的服務(wù)列表
spring:
cloud:
kubernetes:
discovery:
enabled: false
服務(wù)提供者 application-prod.yml
生產(chǎn)環(huán)境 啟動k8s的注冊中心,并且獲取 “ sc ” 這個命名空間下所有的服務(wù)
spring:
cloud:
kubernetes:
discovery:
enabled: true
namespaces:
- "sc"
服務(wù)提供者 java代碼
package com.xaaef.k8sdemo.provider;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.net.InetAddress;
import java.net.UnknownHostException;
@RequestMapping
@RestController
@EnableDiscoveryClient
@SpringBootApplication
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
@GetMapping()
public String index() {
return StrUtil.format("provider ===> : {}", IdUtil.fastSimpleUUID());
}
@GetMapping("hello")
public String hello(@RequestParam("name") String name) throws UnknownHostException {
var hostAddress = InetAddress.getLocalHost().getHostAddress();
return StrUtil.format("provider -> {} : hello {}", hostAddress, name);
}
}
服務(wù)提供者 Dockerfile (一定要根 src 同一個目錄)
FROM eclipse-temurin:17-jre-alpine
MAINTAINER Wang Chen Chen<932560435@qq.com>
ENV VERSION 1.1
# 復(fù)制打包 完成后的jar文件,名字修改成 app.jar
COPY ./target/k8s-provider-1.1.jar app.jar
# 設(shè)置時區(qū)為上海
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN echo 'Asia/Shanghai' >/etc/timezone
# 設(shè)置編碼
ENV LANG C.UTF-8
# JVM參數(shù)
ENV JVM_OPTS="-server -XX:+DisableExplicitGC -XX:+HeapDumpOnOutOfMemoryError"
# 服務(wù)暴露端口PORT
EXPOSE 18831
# 啟動 Spring Boot App 命令
ENTRYPOINT java ${JVM_OPTS} -Dfile.encoding=UTF-8 -Duser.timezone=Asia/Shanghai -Djava.security.egd=file:/dev/./urandom -jar /app.jar
服務(wù)消費者 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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.xaaef.k8sdemo</groupId>
<artifactId>k8s-demo1</artifactId>
<version>1.1</version>
</parent>
<artifactId>k8s-consumer</artifactId>
<name>k8s-consumer</name>
<description>
管理服務(wù)
</description>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
消費者 application.yml
server:
port: 18841
spring:
application:
name: k8s-consumer
profiles:
active: dev
cloud:
openfeign:
client:
config:
default:
connect-timeout: 1000
read-timeout: 1000
logger-level: full
compression:
request:
enabled: true
response:
enabled: true
circuitbreaker:
enabled: true
alphanumeric-ids:
enabled: true
okhttp:
enabled: true
消費者 application-dev.yml
在本地idea 開發(fā)環(huán)境中,無法獲取k8s注冊中心的服務(wù),所以需要自定義的服務(wù)實例信息。
原理請看 SimpleDiscoveryClient 和 SimpleDiscoveryProperties 配置類
spring:
cloud:
kubernetes:
discovery:
enabled: false
discovery:
client:
simple:
instances:
k8s-provider:
- instanceId: k8s-provider-${random.int}
serviceId: k8s-provider
host: localhost
port: 18831
消費者 application-prod.yml
生產(chǎn)環(huán)境 啟動k8s的注冊中心,并且獲取 “ sc ” 這個命名空間下所有的服務(wù)
spring:
cloud:
kubernetes:
discovery:
enabled: true
namespaces:
- "sc"
服務(wù)消費者 java 代碼 ConsumerApplication.java
package com.xaaef.k8sdemo.consumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
服務(wù)消費者 java 代碼 RpcProviderService.java
package com.xaaef.k8sdemo.consumer;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(name = "k8s-provider")
public interface RpcProviderService {
@GetMapping("hello")
String hello(@RequestParam("name") String name);
}
服務(wù)消費者 java 代碼 IndexController.java
package com.xaaef.k8sdemo.consumer;
import lombok.AllArgsConstructor;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RequestMapping
@RestController
@AllArgsConstructor
public class IndexController {
private final RpcProviderService providerService;
private final DiscoveryClient discoveryClient;
// 獲取 注冊中心 中所有的 服務(wù)ID
@GetMapping("services")
public List<String> services() {
return discoveryClient.getServices();
}
// 根據(jù) 服務(wù)ID 獲取服務(wù)實例
@GetMapping("instances")
public List<ServiceInstance> getInstances(@RequestParam String serviceId) {
return discoveryClient.getInstances(serviceId);
}
// 調(diào)用 消費者服務(wù)
@GetMapping("hello")
public String hello() {
return providerService.hello("consumer");
}
}
服務(wù)消費者 Dockerfile (一定要根 src 同一個目錄)
FROM eclipse-temurin:17-jre-alpine
MAINTAINER Wang Chen Chen<932560435@qq.com>
ENV VERSION 1.1
# 復(fù)制打包 完成后的jar文件,名字修改成 app.jar
COPY ./target/k8s-consumer-1.1.jar app.jar
# 設(shè)置時區(qū)為上海
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN echo 'Asia/Shanghai' >/etc/timezone
# 設(shè)置編碼
ENV LANG C.UTF-8
# JVM參數(shù)
ENV JVM_OPTS="-server -XX:+DisableExplicitGC -XX:+HeapDumpOnOutOfMemoryError"
# 服務(wù)暴露端口PORT
EXPOSE 18841
# 啟動 Spring Boot App 命令
ENTRYPOINT java ${JVM_OPTS} -Dfile.encoding=UTF-8 -Duser.timezone=Asia/Shanghai -Djava.security.egd=file:/dev/./urandom -jar /app.jar
test.http 測試
### 消費者 獲取所有服務(wù)名
GET http://localhost:18841/services
### 消費者 根據(jù)服務(wù)名獲取詳情
GET http://localhost:18841/instances?serviceId=k8s-provider
### 消費者 調(diào)用提供者。
GET http://localhost:18841/hello
## 結(jié)果 provider -> 192.168.0.167 : hello consumer
項目打包成 docker 鏡像
服務(wù)提供者 docker 構(gòu)建鏡像
docker build -t k8s-provider:1.1 ./
服務(wù)消費者 docker 構(gòu)建鏡像
docker build -t k8s-consumer:1.1 ./
文章來源:http://www.zghlxwxcb.cn/news/detail-609438.html
到這里有兩個選擇,1.將鏡像推送到 阿里云docker倉庫中,然后在k8s集群中再拉下來、
2.將 鏡像導(dǎo)出成 .tar 文件。然后手動上傳到 k8s 集群的容器中。在這里使用第二種,我的網(wǎng)絡(luò)不太好
## 將 消費者和提供者 保存到 k8s-demo1.tar 文件中。
docker save -o k8s-demo1.tar k8s-consumer:1.1 k8s-provider:1.1
## k8s 的容器如果是 docker 。切記集群有幾個工作節(jié)點,就要導(dǎo)入幾次。
docker load -i k8s-demo1.tar
## k8s 的容器如果是 containerd
ctr -n k8s.io image import k8s-demo1.tar
k8s 服務(wù) yaml
apiVersion: v1
kind: Namespace
metadata:
name: sc
labels:
name: spring-cloud-k8s
---
### 創(chuàng)建一個賬號 然后關(guān)聯(lián)集群管理員的權(quán)限。否則 消費者 無法獲取到 “sc” 命名空間中的 服務(wù)
apiVersion: v1
kind: ServiceAccount
metadata:
name: k8s-demo1
namespace: sc
labels:
app: sc-k8s-demo1
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: k8s-demo1
namespace: sc
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: k8s-demo1
namespace: sc
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: k8s-consumer
namespace: sc
labels:
app: k8s-consumer
spec:
replicas: 3
template:
metadata:
name: k8s-consumer
labels:
app: k8s-consumer
spec:
serviceAccountName: k8s-demo1
containers:
- name: k8s-consumer
image: k8s-consumer:1.1
imagePullPolicy: IfNotPresent
env:
- name: SPRING_PROFILES_ACTIVE
value: prod
restartPolicy: Always
selector:
matchLabels:
app: k8s-consumer
---
apiVersion: v1
kind: Service
metadata:
name: k8s-consumer
namespace: sc
labels:
app: k8s-consumer
spec:
type: ClusterIP
selector:
app: k8s-consumer
ports:
- port: 18841
targetPort: 18841
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: k8s-provider
namespace: sc
labels:
app: k8s-provider
spec:
replicas: 3
template:
metadata:
name: k8s-provider
labels:
app: k8s-provider
spec:
serviceAccountName: k8s-demo1
containers:
- name: k8s-provider
image: k8s-provider:1.1
imagePullPolicy: IfNotPresent
env:
- name: SPRING_PROFILES_ACTIVE
value: prod
restartPolicy: Always
selector:
matchLabels:
app: k8s-provider
---
apiVersion: v1
kind: Service
metadata:
name: k8s-provider
namespace: sc
labels:
app: k8s-provider
spec:
type: ClusterIP
selector:
app: k8s-provider
ports:
- port: 18831
targetPort: 18831
---
################## ingress myapp ##################
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: k8s-demo1
namespace: sc
labels:
app: k8s-demo1
spec:
ingressClassName: nginx
rules:
- host: consumer.example.com
http:
paths:
- path: "/"
pathType: Prefix
backend:
service:
name: k8s-consumer
port:
number: 18841
- host: provider.example.com
http:
paths:
- path: "/"
pathType: Prefix
backend:
service:
name: k8s-provider
port:
number: 18831
啟動 消費者 和 提供者 服務(wù)
kubectl apply -f k8s-demo1.yaml
1.編輯 C:\Windows\System32\drivers\etc\hosts
### 192.168.2.33 即是k8s集群中 ingress 的 ip
192.168.2.33 provider.example.com
192.168.2.33 consumer.example.com
test.http 測試
### 消費者 獲取所有服務(wù)名
GET http://consumer.example.com/services
### 消費者 根據(jù)服務(wù)名獲取詳情
GET http://consumer.example.com/instances?serviceId=k8s-provider
### 消費者 調(diào)用提供者。
GET http://consumer.example.com/hello
## 結(jié)果 provider -> 10.233.76.8 : hello consumer
2.使用 kt-connect 的VPN能力,直接訪問k8s集群內(nèi)部的 service
官方文檔 https://alibaba.github.io/kt-connect/#/文章來源地址http://www.zghlxwxcb.cn/news/detail-609438.html
ktctl connect
test.http 測試
### 消費者 獲取所有服務(wù)名
GET http://k8s-consumer.sc.svc:18841/services
### 消費者 根據(jù)服務(wù)名獲取詳情
GET http://k8s-consumer.sc.svc:18841/instances?serviceId=k8s-provider
### 消費者 調(diào)用提供者。
GET http://k8s-consumer.sc.svc:18841/hello
## 結(jié)果 provider -> 10.233.76.8 : hello consumer
至此,開發(fā)環(huán)境使用配置的服務(wù)列表。生產(chǎn)環(huán)境k8s的注冊中心。不需要修改任何代碼。只需要切換spring.profiles.active 的環(huán)境接口。如果有人知道更方便的方式,可以留言給我!
spring boot 、mybatis-plus、mysql 的 schema 多租戶 項目 請大家去點個贊
https://github.com/thousmile/molly-multi-tenant
到了這里,關(guān)于Spring Cloud 使用 k8s 作為注冊中心 開發(fā)環(huán)境 和 生產(chǎn)環(huán)境的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!