一、本文示例
简单实现一个注册中心两个互相调用服务的SpringCloud应用,制作镜像并在k8s环境部署
本地环境:
minikube v1.6.2
java 8
SpringCloud 2.3.2-RELEASE
为保证minikube中可直接使用本地构建的镜像,需要行进行如下设置,使本地docker命令连接到minikube环境中
执行命令:
eval $(minikube docker-env)
此时docker 命令已经连接到minikube环境中了,可以使用docker images查看已经不是本地的镜像列表了(别担心该命令只改变了当前会话下的docker命令,关闭或重新开户会话就正常了)
然后按正常逻辑构建镜像即可
docker build -t xxx .
1
1
docker build -t xxx .
1
最后在写部署文件的Deployment.yaml中将imagePullPolicy设置为IfNotPresent或Never(不去远程拉取,使用本地)
apiVersion: extensions/v1beta1kind: Deploymentmetadata: name: service-customerspec: replicas: 1 template: metadata: labels: app: service-customer spec: containers: - name: service-customer image: service-customer imagePullPolicy: IfNotPresent ports: - containerPort: 8080
1234567891011121314151617
1234567891011121314151617
apiVersion: extensions/v1beta1kind: Deploymentmetadata: name: service-customerspec: replicas: 1 template: metadata: labels: app: service-customer spec: containers: - name: service-customer image: service-customer imagePullPolicy: IfNotPresent ports: - containerPort: 8080
1234567891011121314151617
二、创建项目
eureka项目:注册中心
service-provider: 服务提供方
service-customer:服务调用方
下面挑重点说一下,完事代码文末有github地址
1)eureka注册中心
pom.xml:
.... <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency>....
1234567891011121314
1234567891011121314
.... <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency>....
1234567891011121314
主要是引入eureka-server依赖
application.yaml
spring: application: name: eurekaserver: port: 8080eureka: client: register-with-eureka: true fetch-registry: false service-url: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ instance: hostname: localhost instance-id: eureka-8080
1234567891011121314
1234567891011121314
spring: application: name: eurekaserver: port: 8080eureka: client: register-with-eureka: true fetch-registry: false service-url: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ instance: hostname: localhost instance-id: eureka-8080
1234567891011121314
Dockerfile:
FROM openjdk:8-alpineCOPY target/eureka.jar .CMD java -jar eureka.jar
123
123
FROM openjdk:8-alpineCOPY target/eureka.jar .CMD java -jar eureka.jar
123
k8s部署及创建service k8s.yaml:
apiVersion: extensions/v1beta1kind: Deploymentmetadata: name: eurekaspec: replicas: 1 template: metadata: labels: app: eureka spec: containers: - name: eureka image: eureka imagePullPolicy: IfNotPresent ports: - containerPort: 8080---apiVersion: v1kind: Servicemetadata: name: eurekaspec: type: NodePort selector: app: eureka ports: - protocol: TCP port: 8080 targetPort: 8080
123456789101112131415161718192021222324252627282930
123456789101112131415161718192021222324252627282930
apiVersion: extensions/v1beta1kind: Deploymentmetadata: name: eurekaspec: replicas: 1 template: metadata: labels: app: eureka spec: containers: - name: eureka image: eureka imagePullPolicy: IfNotPresent ports: - containerPort: 8080---apiVersion: v1kind: Servicemetadata: name: eurekaspec: type: NodePort selector: app: eureka ports: - protocol: TCP port: 8080 targetPort: 8080
123456789101112131415161718192021222324252627282930
2) service-provider服务提供方
pom.xml
.... <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>....
123456789101112131415161718
123456789101112131415161718
.... <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>....
123456789101112131415161718
引入eureka client依赖
application.yaml:
spring: application: name: service-providereureka: instance: instance-id: service-provider hostname: service-provider client: service-url: # eureka地址使用 k8s的service地址 defaultZone: http://eureka:8080/eureka/server: port: 8080
12345678910111213
12345678910111213
spring: application: name: service-providereureka: instance: instance-id: service-provider hostname: service-provider client: service-url: # eureka地址使用 k8s的service地址 defaultZone: http://eureka:8080/eureka/server: port: 8080
12345678910111213
Dockerfile:
FROM openjdk:8-alpineCOPY target/service-provider.jar .CMD java -jar service-provider.jar
123
123
FROM openjdk:8-alpineCOPY target/service-provider.jar .CMD java -jar service-provider.jar
123
k8s部署及创建service k8s.yaml:
apiVersion: extensions/v1beta1kind: Deploymentmetadata: name: service-providerspec: replicas: 1 template: metadata: labels: app: service-provider spec: containers: - name: service-provider image: service-provider imagePullPolicy: IfNotPresent ports: - containerPort: 8080---apiVersion: v1kind: Servicemetadata: name: service-providerspec: selector: app: service-provider ports: - protocol: TCP port: 8080 targetPort: 8080
1234567891011121314151617181920212223242526272829
1234567891011121314151617181920212223242526272829
apiVersion: extensions/v1beta1kind: Deploymentmetadata: name: service-providerspec: replicas: 1 template: metadata: labels: app: service-provider spec: containers: - name: service-provider image: service-provider imagePullPolicy: IfNotPresent ports: - containerPort: 8080---apiVersion: v1kind: Servicemetadata: name: service-providerspec: selector: app: service-provider ports: - protocol: TCP port: 8080 targetPort: 8080
1234567891011121314151617181920212223242526272829
提供接口服务 HelloController.java:
@RestController@RequestMapping("/")public class HelloController { @RequestMapping("/hello") public String hello(){ return "hello world"; }}
123456789
123456789
@RestController@RequestMapping("/")public class HelloController { @RequestMapping("/hello") public String hello(){ return "hello world"; }}
123456789
3) service-customer服务调用方
pom.xml
.... <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>....
123456789101112131415161718
123456789101112131415161718
.... <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>....
123456789101112131415161718
引入eureka client依赖
application.yaml:
spring: application: name: service-customereureka: client: service-url: # eureka地址使用 k8s的service地址 defaultZone: http://eureka:8080/eureka/ instance: instance-id: service-customer hostname: service-customerserver: port: 8080feign: hystrix: enabled: true
12345678910111213141516
12345678910111213141516
spring: application: name: service-customereureka: client: service-url: # eureka地址使用 k8s的service地址 defaultZone: http://eureka:8080/eureka/ instance: instance-id: service-customer hostname: service-customerserver: port: 8080feign: hystrix: enabled: true
12345678910111213141516
Dockerfile:
FROM openjdk:8-alpineCOPY target/service-customer.jar .CMD java -jar service-customer.jar
123
123
FROM openjdk:8-alpineCOPY target/service-customer.jar .CMD java -jar service-customer.jar
123
k8s部署及创建service k8s.yaml:
apiVersion: extensions/v1beta1kind: Deploymentmetadata: name: service-customerspec: replicas: 1 template: metadata: labels: app: service-customer spec: containers: - name: service-customer image: service-customer imagePullPolicy: IfNotPresent ports: - containerPort: 8080---apiVersion: v1kind: Servicemetadata: name: service-customerspec: selector: app: service-customer type: NodePort ports: - protocol: TCP port: 8080 targetPort: 8080
123456789101112131415161718192021222324252627282930
123456789101112131415161718192021222324252627282930
apiVersion: extensions/v1beta1kind: Deploymentmetadata: name: service-customerspec: replicas: 1 template: metadata: labels: app: service-customer spec: containers: - name: service-customer image: service-customer imagePullPolicy: IfNotPresent ports: - containerPort: 8080---apiVersion: v1kind: Servicemetadata: name: service-customerspec: selector: app: service-customer type: NodePort ports: - protocol: TCP port: 8080 targetPort: 8080
123456789101112131415161718192021222324252627282930
测试接口IndexController.java:
@RestController@RequestMapping("/")public class IndexController { @Resource private HelloService helloService; @RequestMapping("/index") public String index(){ return helloService.hello(); }}
123456789101112
123456789101112
@RestController@RequestMapping("/")public class IndexController { @Resource private HelloService helloService; @RequestMapping("/index") public String index(){ return helloService.hello(); }}
123456789101112
HelloService.java:
/** * 通过feignClient调用服务提供者 */@FeignClient(name = "service-provider", fallback = HelloServiceFallback.class)public interface HelloService { @RequestMapping("/hello") String hello();}
12345678
12345678
/** * 通过feignClient调用服务提供者 */@FeignClient(name = "service-provider", fallback = HelloServiceFallback.class)public interface HelloService { @RequestMapping("/hello") String hello();}
12345678
HelloServiceFallback.java:
@Servicepublic class HelloServiceFallback implements HelloService{ @Override public String hello() { return "fallback...."; }}
1234567
1234567
@Servicepublic class HelloServiceFallback implements HelloService{ @Override public String hello() { return "fallback...."; }}
1234567
三、构建部署
首先保证当前终端已经使用的是minikube的docker(可以docker images
看一下,镜像列表不是本地环境的就对了)
首先构建部署eureka(进入eureka项目目录):
# 构建docker build -t eureka .# 查看镜像docker images# 部署k8skubectl apply -f k8s.yaml# 查看deploymentkubectl get deploymentNAME READY UP-TO-DATE AVAILABLE AGEeureka 1/1 1 1 29s# 查看Servicekubectl get svcNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEeureka NodePort 10.101.11.23 <none> 8080:30512/TCP 65s# 查看podkubectl get podNAME READY STATUS RESTARTS AGEeureka-8b48665d7-v9wmf 1/1 Running 0 82s
123456789101112131415161718
123456789101112131415161718
# 构建docker build -t eureka .# 查看镜像docker images# 部署k8skubectl apply -f k8s.yaml# 查看deploymentkubectl get deploymentNAME READY UP-TO-DATE AVAILABLE AGEeureka 1/1 1 1 29s# 查看Servicekubectl get svcNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEeureka NodePort 10.101.11.23 <none> 8080:30512/TCP 65s# 查看podkubectl get podNAME READY STATUS RESTARTS AGEeureka-8b48665d7-v9wmf 1/1 Running 0 82s
123456789101112131415161718
可以看到service映射到nodeport的 30512 可以使用命令查看minikube的ip:
12 | minikube ip192.168.64.2 |
在浏览器访问 http://192.168.64.2:30512 就可以打开eureka注册中心了
部署service-provider服务提供方(进入service-provider项目目录):
# 构建docker build -t service-provider .# 查看镜像docker images# 部署k8skubectl apply -f k8s.yaml# 查看deploymentkubectl get deploymentNAME READY UP-TO-DATE AVAILABLE AGEeureka 1/1 1 1 4m18sservice-provider 1/1 1 1 7s# 查看Servicekubectl get svcNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEeureka NodePort 10.101.11.23 <none> 8080:30512/TCP 4m39sservice-provider ClusterIP 10.103.25.172 <none> 8080/TCP 28s# 查看podkubectl get pod NAME READY STATUS RESTARTS AGEeureka-8b48665d7-v9wmf 1/1 Running 0 4m51sservice-provider-57d69f46c-lltgw 1/1 Running 0 40s
123456789101112131415161718192021
123456789101112131415161718192021
# 构建docker build -t service-provider .# 查看镜像docker images# 部署k8skubectl apply -f k8s.yaml# 查看deploymentkubectl get deploymentNAME READY UP-TO-DATE AVAILABLE AGEeureka 1/1 1 1 4m18sservice-provider 1/1 1 1 7s# 查看Servicekubectl get svcNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEeureka NodePort 10.101.11.23 <none> 8080:30512/TCP 4m39sservice-provider ClusterIP 10.103.25.172 <none> 8080/TCP 28s# 查看podkubectl get pod NAME READY STATUS RESTARTS AGEeureka-8b48665d7-v9wmf 1/1 Running 0 4m51sservice-provider-57d69f46c-lltgw 1/1 Running 0 40s
123456789101112131415161718192021
部署service-customer服务调用方(进入service-customer项目目录):
pod都Running之后,测试一下接口调用 跟上边eureka一样,customer映射到node的prot为 32357
# 构建docker build -t service-customer .# 查看镜像docker images# 部署k8skubectl apply -f k8s.yaml# 查看deploymentkubectl get deploymentNAME READY UP-TO-DATE AVAILABLE AGEeureka 1/1 1 1 10mservice-customer 1/1 1 1 8sservice-provider 1/1 1 1 6m18s# 查看Servicekubectl get svcNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEeureka NodePort 10.101.11.23 <none> 8080:30512/TCP 10mservice-customer NodePort 10.104.108.133 <none> 8080:32357/TCP 23sservice-provider ClusterIP 10.103.25.172 <none> 8080/TCP 6m33s# 查看podkubectl get podNAME READY STATUS RESTARTS AGEeureka-8b48665d7-v9wmf 1/1 Running 0 11mservice-customer-898557664-m854c 1/1 Running 0 46sservice-provider-57d69f46c-lltgw 1/1 Running 0 6m56s
123456789101112131415161718192021222324
123456789101112131415161718192021222324
# 构建docker build -t service-customer .# 查看镜像docker images# 部署k8skubectl apply -f k8s.yaml# 查看deploymentkubectl get deploymentNAME READY UP-TO-DATE AVAILABLE AGEeureka 1/1 1 1 10mservice-customer 1/1 1 1 8sservice-provider 1/1 1 1 6m18s# 查看Servicekubectl get svcNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEeureka NodePort 10.101.11.23 <none> 8080:30512/TCP 10mservice-customer NodePort 10.104.108.133 <none> 8080:32357/TCP 23sservice-provider ClusterIP 10.103.25.172 <none> 8080/TCP 6m33s# 查看podkubectl get podNAME READY STATUS RESTARTS AGEeureka-8b48665d7-v9wmf 1/1 Running 0 11mservice-customer-898557664-m854c 1/1 Running 0 46sservice-provider-57d69f46c-lltgw 1/1 Running 0 6m56s
123456789101112131415161718192021222324
使用浏览器访问 http://192.168.64.2:32357/index 返回:
hello world
1
1
hello world
1
删除服务提供者的pod:
kubectl delete pod service-provider-57d69f46c-lltgw
1
1
kubectl delete pod service-provider-57d69f46c-lltgw
1
再次请求: http://192.168.64.2:32357/index 返回:
fallback....
1
1
fallback....
1
过一会新的pod启动成功后再访问就恢复正常了