Kubernetes 部署 SpringCloud应用实践

一、本文示例

简单实现一个注册中心两个互相调用服务的SpringCloud应用,制作镜像并在k8s环境部署

本地环境:

minikube v1.6.2

java 8

SpringCloud 2.3.2-RELEASE

为保证minikube中可直接使用本地构建的镜像,需要行进行如下设置,使本地docker命令连接到minikube环境中

执行命令:

1
eval $(minikube docker-env)

此时docker 命令已经连接到minikube环境中了,可以使用docker images查看已经不是本地的镜像列表了(别担心该命令只改变了当前会话下的docker命令,关闭或重新开户会话就正常了)

然后按正常逻辑构建镜像即可

1
docker build -t xxx .

最后在写部署文件的Deployment.yaml中将imagePullPolicy设置为IfNotPresent或Never(不去远程拉取,使用本地)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: service-customer
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: service-customer
    spec:
      containers:
      - name: service-customer
        image: service-customer
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080

二、创建项目

eureka项目:注册中心

service-provider: 服务提供方

service-customer:服务调用方

下面挑重点说一下,完事代码文末有github地址

1)eureka注册中心

pom.xml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
....
		
			org.springframework.boot
			spring-boot-starter-actuator
		
		
			org.springframework.boot
			spring-boot-starter-web
		
		
			org.springframework.cloud
			spring-cloud-starter-netflix-eureka-server
		
....

主要是引入eureka-server依赖

application.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
spring:
  application:
    name: eureka
server:
  port: 8080
eureka:
  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

Dockerfile:

1
2
3
FROM openjdk:8-alpine
COPY target/eureka.jar .
CMD java -jar eureka.jar

k8s部署及创建service k8s.yaml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: eureka
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: eureka
    spec:
      containers:
      - name: eureka
        image: eureka
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: eureka
spec:
  type: NodePort
  selector:
    app: eureka
  ports:
  - protocol: TCP
    port: 8080
    targetPort: 8080

2) service-provider服务提供方

pom.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
....
		
			org.springframework.boot
			spring-boot-starter-actuator
		
		
			org.springframework.boot
			spring-boot-starter-web
		
		
			org.springframework.boot
			spring-boot-starter-actuator
		
		
			org.springframework.cloud
			spring-cloud-starter-netflix-eureka-client
		
....

引入eureka client依赖

application.yaml:

1
2
3
4
5
6
7
8
9
10
11
12
13
spring:
  application:
    name: service-provider
eureka:
  instance:
    instance-id: service-provider
    hostname: service-provider
  client:
    service-url:
      # eureka地址使用 k8s的service地址
      defaultZone: http://eureka:8080/eureka/
server:
  port: 8080

Dockerfile:

1
2
3
FROM openjdk:8-alpine
COPY target/service-provider.jar .
CMD java -jar service-provider.jar

k8s部署及创建service k8s.yaml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: service-provider
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: service-provider
    spec:
      containers:
      - name: service-provider
        image: service-provider
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: service-provider
spec:
  selector:
    app: service-provider
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 8080

提供接口服务 HelloController.java:

1
2
3
4
5
6
7
8
9
@RestController
@RequestMapping("/")
public class HelloController {

    @RequestMapping("/hello")
    public String hello(){
        return "hello world";
    }
}

3) service-customer服务调用方

pom.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
....
		
			org.springframework.boot
			spring-boot-starter-actuator
		
		
			org.springframework.boot
			spring-boot-starter-web
		
		
			org.springframework.boot
			spring-boot-starter-actuator
		
		
			org.springframework.cloud
			spring-cloud-starter-netflix-eureka-client
		
....

引入eureka client依赖

application.yaml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
spring:
  application:
    name: service-customer
eureka:
  client:
    service-url:
      # eureka地址使用 k8s的service地址
      defaultZone: http://eureka:8080/eureka/
  instance:
    instance-id: service-customer
    hostname: service-customer
server:
  port: 8080
feign:
  hystrix:
    enabled: true

Dockerfile:

1
2
3
FROM openjdk:8-alpine
COPY target/service-customer.jar .
CMD java -jar service-customer.jar

k8s部署及创建service k8s.yaml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: service-customer
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: service-customer
    spec:
      containers:
      - name: service-customer
        image: service-customer
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: service-customer
spec:
  selector:
    app: service-customer
  type: NodePort
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 8080

测试接口IndexController.java:

1
2
3
4
5
6
7
8
9
10
11
12
@RestController
@RequestMapping("/")
public class IndexController {

    @Resource
    private HelloService helloService;

    @RequestMapping("/index")
    public String index(){
        return helloService.hello();
    }
}

HelloService.java:

1
2
3
4
5
6
7
8
/**
 * 通过feignClient调用服务提供者
 */
@FeignClient(name = "service-provider", fallback = HelloServiceFallback.class)
public interface HelloService {
    @RequestMapping("/hello")
    String hello();
}

HelloServiceFallback.java:

1
2
3
4
5
6
7
@Service
public class HelloServiceFallback implements HelloService{
    @Override
    public String hello() {
        return "fallback....";
    }
}

三、构建部署

首先保证当前终端已经使用的是minikube的docker(可以docker images看一下,镜像列表不是本地环境的就对了)

首先构建部署eureka(进入eureka项目目录):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 构建
docker build -t eureka .
# 查看镜像
docker images
# 部署k8s
kubectl apply -f k8s.yaml
# 查看deployment
kubectl get deployment
NAME     READY   UP-TO-DATE   AVAILABLE   AGE
eureka   1/1     1            1           29s
# 查看Service
kubectl get svc
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
eureka       NodePort    10.101.11.23           8080:30512/TCP   65s
# 查看pod
kubectl get pod
NAME                               READY   STATUS    RESTARTS   AGE
eureka-8b48665d7-v9wmf             1/1     Running   0          82s

可以看到service映射到nodeport的 30512 可以使用命令查看minikube的ip:

1
2
minikube ip
192.168.64.2

在浏览器访问 http://192.168.64.2:30512 就可以打开eureka注册中心了

部署service-provider服务提供方(进入service-provider项目目录):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 构建
docker build -t service-provider .
# 查看镜像
docker images
# 部署k8s
kubectl apply -f k8s.yaml
# 查看deployment
kubectl get deployment
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
eureka             1/1     1            1           4m18s
service-provider   1/1     1            1           7s
# 查看Service
kubectl get svc
NAME               TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
eureka             NodePort    10.101.11.23            8080:30512/TCP   4m39s
service-provider   ClusterIP   10.103.25.172           8080/TCP         28s
# 查看pod
kubectl get pod 
NAME                               READY   STATUS    RESTARTS   AGE
eureka-8b48665d7-v9wmf             1/1     Running   0          4m51s
service-provider-57d69f46c-lltgw   1/1     Running   0          40s

部署service-customer服务调用方(进入service-customer项目目录):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 构建
docker build -t service-customer .
# 查看镜像
docker images
# 部署k8s
kubectl apply -f k8s.yaml
# 查看deployment
kubectl get deployment
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
eureka             1/1     1            1           10m
service-customer   1/1     1            1           8s
service-provider   1/1     1            1           6m18s
# 查看Service
kubectl get svc
NAME               TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
eureka             NodePort    10.101.11.23             8080:30512/TCP   10m
service-customer   NodePort    10.104.108.133           8080:32357/TCP   23s
service-provider   ClusterIP   10.103.25.172            8080/TCP         6m33s
# 查看pod
kubectl get pod
NAME                               READY   STATUS    RESTARTS   AGE
eureka-8b48665d7-v9wmf             1/1     Running   0          11m
service-customer-898557664-m854c   1/1     Running   0          46s
service-provider-57d69f46c-lltgw   1/1     Running   0          6m56s

pod都Running之后,测试一下接口调用 跟上边eureka一样,customer映射到node的prot为 32357

使用浏览器访问 http://192.168.64.2:32357/index 返回:

1
hello world

删除服务提供者的pod:

1
kubectl delete pod service-provider-57d69f46c-lltgw

再次请求: http://192.168.64.2:32357/index 返回:

1
fallback....

过一会新的pod启动成功后再访问就恢复正常了

你可能感兴趣的:(运维,springcloud)