docker+kubernetes+springcloud微服務叢集部署,spring-cloud-kubernetes,使用k8s部署spring cloud并實作服務注冊、負載均衡、網關等功能
-
官方位址: https://github.com/spring-cloud/spring-cloud-kubernetes
-
參考:https://blog.csdn.net/boling_cavalry/article/details/91346780
https://blog.csdn.net/u013360850/article/details/100635405
- 本機環境
位址 | 服務 |
---|---|
192.168.0.11 | k8s-master |
192.168.0.22 | k8s-node1 , docker registry |
192.168.0.33 | k8s-node2 |
代碼見https://github.com/heliu0/springcloud-k8s.git
-
生産者 producer
-
1, 建立spring cloud項目。并編寫ProducerApplication.java,ProducerController.java,Dockerfile,application.yaml, pom.xml,producer-service.yaml。
-
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">
<parent>
<artifactId>springcloud-k8s-parent</artifactId>
<groupId>com.yayiyo.k8s</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>springcloud-k8s-producer</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>${spring-cloud-openfegin.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<version>${spring-boot.version}</version>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${spring-boot.version}</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes</artifactId>
<version>${spring-cloud.k8s}</version>
</dependency>
</dependencies>
</project>
-
ProducerApplication.java
package com.yayiyo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class ProducerApplication {
public static void main(String[] args) {
SpringApplication.run(ProducerApplication.class, args);
}
}
-
RpcController.java
package com.yayiyo.controllers;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.net.InetAddress;
import java.net.UnknownHostException;
@Controller
public class RpcController {
@GetMapping("/ping")
@ResponseBody
public String ping() {
try {
return InetAddress.getLocalHost().getHostName();
} catch (UnknownHostException e) {
return "Pong";
}
}
}
-
application.yaml
spring:
application:
name: producer-service
cloud:
kubernetes:
config:
sources:
- name: ${spring.application.name}
namespace: default
reload:
enabled: true
mode: event
discovery:
all-namespaces: true
server:
port: 8082
management:
endpoint:
restart:
enabled: true
endpoints:
web:
exposure:
include: restart
-
2. idea上配置docker服務,執行Dockerfile,打包鏡像并把鏡像推到docker伺服器上。
-
Dockerfile
-
FROM openjdk:8-jdk-alpine
LABEL version="1.0" maintainer="[email protected]"
VOLUME /tmp
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
ARG JAR_FILE
ADD target/springcloud-k8s-producer-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java", "-jar","/app.jar"]
EXPOSE 8082
-
idea的docker配置
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIyVGduV2YfNWawNCM38FdsYkRGZkRG9lcvx2bjxiNx8VZ6l2cs0TP31UMsdkYshmMMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL4YjM5MTN0ETMzEDMxAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
-
3. 把鏡像推到docker倉庫裡面
#檢視本地倉庫裡面是否有該鏡像
docker images
# 推到遠端鏡像倉庫
docker push 鏡像名
-
4.在k8s-master伺服器上 編寫 producer-service.yaml并執行
kubectl apply -f producer-service.yaml
apiVersion: v1
kind: Service
metadata:
name: producer-service
labels:
app.kubernetes.io/name: producer-service
spec:
type: ClusterIP
ports:
- port: 8082
targetPort: 8082
nodePort: 8082
protocol: TCP
name: http
selector:
app.kubernetes.io/name: producer-service
---
apiVersion: apps/v1producer-service
kind: Deployment
metadata:
name: producer-service
labels:
app.kubernetes.io/name: producer-service
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: producer-service
template:
metadata:
labels:
app.kubernetes.io/name: producer-service
app.kubernetes.io/instance: sad-markhor
spec:
containers:
- name: producer-service
# 鏡像名需要與倉庫中的鏡像名一緻
image: "192.168.0.22:5000/spring-cloud-k8s-producer:1.0"
imagePullPolicy: Always
ports:
- name: http
containerPort: 8082
protocol: TCP
可以看到有 producer-service 的pod正常運作。
-
消費者 customer
-
1, 建立spring cloud項目。并編寫CustomerApplication.java,CustomerController.java,ProducerClient.java,ProducerClientFallback Dockerfile,application.yaml, pom.xml,customer-service.yaml。
-
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">
<parent>
<artifactId>springcloud-k8s-parent</artifactId>
<groupId>com.yayiyo.k8s</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>springcloud-k8s-customer</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>${spring-cloud-openfegin.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
<version>${spring-cloud-openfegin.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<version>${spring-boot.version}</version>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${spring-boot.version}</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes</artifactId>
<version>${spring-cloud.k8s}</version>
</dependency>
</dependencies>
</project>
-
CustomerApplication.java
package com.yayiyo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class CustomerApplication {
public static void main(String[] args) {
SpringApplication.run(CustomerApplication.class, args);
}
}
-
RpcController.java
package com.yayiyo.controllers;
import com.yayiyo.client.ProducerClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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.RestController;
import java.util.List;
@RestController
@Slf4j
public class CoustomerController {
@Autowired
private DiscoveryClient discoveryClient;
@Autowired
private ProducerClient producerClient;
@GetMapping("/service")
public Object getClient() {
return discoveryClient.getServices();
}
@GetMapping("/instance")
public List<ServiceInstance> getInstance(String instanceId) {
return discoveryClient.getInstances(instanceId);
}
@GetMapping("/ping")
public String ping() {
return producerClient.ping();
}
}
-
ProducerClient.java
package com.yayiyo.client;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@FeignClient(name = "http://producer-service:8082", url = "http://producer-service:8082", fallback = ProducerClientFallback.class)
public interface ProducerClient {
@RequestMapping(value = "/ping", method = RequestMethod.GET)
String ping();
}
@Component
class ProducerClientFallback implements ProducerClient{
@Override
public String ping() {
return "Error";
}
}
-
application.yaml
spring:
application:
name: customer-service
cloud:
kubernetes:
config:
sources:
- name: ${spring.application.name}
namespace: default
reload:
enabled: true
mode: event
discovery:
all-namespaces: true
server:
port: 8081
management:
endpoint:
restart:
enabled: true
endpoints:
web:
exposure:
include: restart
-
2. idea上配置docker服務,執行Dockerfile,打包鏡像并把鏡像推到docker伺服器上。
-
Dockerfile
-
FROM openjdk:8-jdk-alpine
LABEL version="1.0" maintainer="[email protected]"
VOLUME /tmp
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
ARG JAR_FILE
ADD target/springcloud-k8s-customer-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java", "-jar","/app.jar"]
EXPOSE 808
-
idea的docker配置
-
3. 把鏡像推到docker倉庫裡面
#檢視本地倉庫裡面是否有該鏡像
docker images
# 推到遠端鏡像倉庫
docker push 鏡像名
-
4.在k8s-master伺服器上 編寫 customer-service.yaml并執行
kubectl apply -f customer-service.yaml
apiVersion: v1
kind: Service
metadata:
name: customer-service
labels:
app.kubernetes.io/name: customer-service
spec:
# 可以直接使用NodePort方式放開端口,這裡使用ClusterIP+nginx的方式,其好處是使用負載均衡以及nginx代理。
# 注意:如果使用NodePort方式,則不用編寫ingress-nginx-controller以及tcp-services-configmap
type: ClusterIP
ports:
- port: 8081
targetPort: 8081
nodePort: 8081
protocol: TCP
name: http
selector:
app.kubernetes.io/name: customer-service
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: customer-service
labels:
app.kubernetes.io/name: customer-service
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: customer-service
template:
metadata:
labels:
app.kubernetes.io/name: customer-service
app.kubernetes.io/instance: sad-markhor
spec:
containers:
- name: customer-service
image: "192.168.0.22:5000/spring-cloud-k8s-customer:1.0"
imagePullPolicy: Always
ports:
- name: http
containerPort: 8081
protocol: TCP
---
# Source: ingress-nginx/templates/controller-service.yaml
apiVersion: v1
kind: Service
metadata:
labels:
helm.sh/chart: ingress-nginx-2.13.0
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 0.35.0
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: controller
name: ingress-nginx-controller
namespace: ingress-nginx
spec:
type: LoadBalancer
externalTrafficPolicy: Cluster
ports:
# 該名稱需要與消費者service中的name保持一緻
- name: customer-service
port: 8081
protocol: TCP
targetPort: 8081
nodePort: 8081
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/component: controller
---
apiVersion: v1
kind: ConfigMap
metadata:
# 該檔案需要在ingress-nginx-controller中引用。
name: tcp-services-configmap
namespace: ingress-nginx
data:
"8081": "default/customer-service:8081"
正常可以在浏覽器中看到:
-
注意問題:
- 在ide編輯時一定要用LF格式
docker+kubernetes+springcloud微服務叢集部署,spring-cloud-kubernetes,使用k8s部署spring cloud并實作服務注冊、負載均衡、網關等功能docker+kubernetes+springcloud微服務叢集部署,spring-cloud-kubernetes,使用k8s部署spring cloud并實作服務注冊、負載均衡、網關等功能 - 執行dockerfile後記得在伺服器上push鏡像。
- customer中的producerCLient.java中FeignClient 的url要寫ip:port,隻寫服務名是找不到該服務的。
@FeignClient(name = "http://producer-service:8082", url = "http://producer-service:8082", fallback = ProducerClientFallback.class)
- 如果想在本機測試,可以在host裡面設定producer-service
127.0.0.1 producer-service