首先搭建k8s集群颁湖。見(jiàn) Centos安裝k8s
使用springcloud 創(chuàng)建兩個(gè)項(xiàng)目,我這里創(chuàng)建了一個(gè)talk一個(gè)project脖捻。想利用talk項(xiàng)目在k8s中,使用feign調(diào)用peoject項(xiàng)目兆衅。下面是具體實(shí)現(xiàn)
上代碼
- SpringCloud kubernetes maven 依賴
<?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.shujunjun.project</groupId>
<artifactId>shujunjun</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>talk</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</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-openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.zaxxer/HikariCP -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>5.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-client-all</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-fabric8-all</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-bootstrap -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<!-- 負(fù)載均衡 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-fabric8-loadbalancer</artifactId>
</dependency>
<!-- 負(fù)載均衡 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-client-loadbalancer</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-spring-boot3-starter -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.5</version>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
</build>
</project>
- 配置文件 bootstrap.yml
spring:
cloud:
kubernetes:
discovery:
# 讓所有命名空間服務(wù)都可以發(fā)現(xiàn)服務(wù)
all-namespaces: true
# 發(fā)現(xiàn)未標(biāo)記為“就緒”的服務(wù)端地址
include-not-ready-addresses: true
# ExternalName類型服務(wù)的列表 DiscoveryClient::getInstances 返回該列表 ServiceInstance::getMetadata
include-external-name-services: true
enabled: true
config:
name: talk-config
namespace: default
# 配置是否讀取配置文件
enabled: true
# 啟用屬性源監(jiān)控和配置重新加載
reload:
enabled: true
# 允許監(jiān)視配置映射中的更改
monitoring-config-maps: true
# 觸發(fā)重新加載時(shí)使用的策略
strategy: refresh
# 指定如何偵聽(tīng)屬性源的更改
mode: event
loadbalancer:
# 通過(guò)服務(wù)名啟用負(fù)載均衡
mode: pod
application:
name: talk
main:
# 允許在Spring的ApplicationContext中覆蓋已有的Bean定義
allow-bean-definition-overriding: true
這里我設(shè)置了允許讓k8s去覆蓋定義的bean地沮,同時(shí)設(shè)置了所有命名空間都可以發(fā)現(xiàn)服務(wù)。其次羡亩,利用talk-config 的configmap去設(shè)置服務(wù)的一些配置信息摩疑。這里測(cè)試使用,目前只設(shè)置了端口號(hào)
[root@k8s-master shujunjun]# cat talk-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: talk-config
data:
application.yml: |
server:
port: 8888
- 簡(jiǎn)單的feign調(diào)用接口
package com.shujunjun.project.feign;
import com.shujunjun.project.entity.dto.ProjectDTO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.List;
@FeignClient(name = "project", url = "${shujunjun.project.url:}")
public interface IProjectFeign {
@GetMapping(value = "project")
List<ProjectDTO> list();
}
- controller實(shí)現(xiàn)
package com.shujunjun.project.controller;
import com.shujunjun.project.entity.dto.ProjectDTO;
import com.shujunjun.project.feign.IProjectFeign;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
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
@RequiredArgsConstructor
public class ProjectController {
final IProjectFeign projectFeign;
@Resource
private DiscoveryClient discoveryClient;
@GetMapping(value = "services")
public List<String> getServices() {
return discoveryClient.getServices();
}
@GetMapping(value = "project")
public List<ProjectDTO> project() {
return projectFeign.list();
}
}
- project項(xiàng)目就是一個(gè)簡(jiǎn)單的接口
package com.shujunjun.project.controller;
import com.shujunjun.project.entity.Project;
import com.shujunjun.project.service.IProjectService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequiredArgsConstructor
public class ProjectController {
final IProjectService projectService;
@GetMapping(value = "project")
public List<Project> project() {
return projectService.list();
}
}
- 使用docker build 鏡像到k8s服務(wù)器
[root@k8s-slave1 talk]# ls
Dockerfile talk.jar
[root@k8s-slave1 talk]# cat Dockerfile
FROM openjdk:17-jdk-alpine
EXPOSE 8080
ADD talk.jar app.jar
ENTRYPOINT ["java","-jar","-Duser.timezone=GMT+08","app.jar"]
- 構(gòu)建talk項(xiàng)目鏡像(project項(xiàng)目同理)
[root@k8s-slave1 talk]# docker build -t talk:latest .
[+] Building 20.6s (7/7) FINISHED docker:default
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 92B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/openjdk:17-jdk-alpine 15.9s
=> [internal] load build context 1.4s
=> => transferring context: 93.37MB 1.4s
=> CACHED [1/2] FROM docker.io/library/openjdk:17-jdk-alpine@sha256:4b6abae565492dbe9e7a894137c966a7485154238902f2f25e9dbd9784383d81 0.0s
=> [2/2] ADD talk.jar app.jar 2.7s
=> exporting to image 0.4s
=> => exporting layers 0.4s
=> => writing image sha256:87f5c2f9ea674ad2570b43006bce21966fc63c87193fc482180c4e1257ff51ba 0.0s
=> => naming to docker.io/library/talk:latest 0.0s
- 查看鏡像
[root@k8s-slave1 talk]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
talk latest 87f5c2f9ea67 46 minutes ago 419MB
project latest 8733fdc4c777 3 days ago 419MB
192.168.121.128:8082/oaim-web latest b883ef6510d2 3 weeks ago 156MB
istio/proxyv2 1.16.7 d90c7490ed6d 8 months ago 261MB
istio/pilot 1.16.7 e73936e7d5be 8 months ago 202MB
redis latest 7614ae9453d1 2 years ago 113MB
mysql latest 3218b38490ce 2 years ago 516MB
calico/node v3.19.1 c4d75af7e098 2 years ago 168MB
calico/pod2daemon-flexvol v3.19.1 5660150975fb 2 years ago 21.7MB
calico/cni v3.19.1 5749e8b276f9 2 years ago 146MB
calico/kube-controllers v3.19.1 5d3d5ddc8605 2 years ago 60.6MB
kubernetesui/dashboard v2.0.0 8b32422733b3 3 years ago 222MB
registry.aliyuncs.com/google_containers/kube-proxy v1.18.0 43940c34f24f 3 years ago 117MB
registry.aliyuncs.com/google_containers/pause 3.2 80d28bedfe5d 4 years ago 683kB
registry.aliyuncs.com/google_containers/coredns 1.6.7 67da37a9a360 4 years ago 43.8MB
registry.cn-hangzhou.aliyuncs.com/kubeapps/k8s-gcr-kubernetes-dashboard-amd64 v1.8.3 0c60bcf89900 6 years ago 102MB
bingozhou/mysql5.7 latest 8dbbe042b8f7 6 years ago 407MB
如上述顯示所示畏铆,talk和project項(xiàng)目已經(jīng)打包至k8s從節(jié)點(diǎn)雷袋。你也可以通過(guò)Nexus統(tǒng)一管理鏡像
- 在k8s環(huán)境中創(chuàng)建具體服務(wù)
創(chuàng)建服務(wù)之前,給默認(rèn)用戶賦權(quán)限辞居,否則項(xiàng)目啟動(dòng)會(huì)報(bào)錯(cuò)
[project] [els.V1Service-1] i.k.c.informer.cache.ReflectorRunnable : class io.kubernetes.client.openapi.models.V1Service#Reflector loop failed unexpectedly
io.kubernetes.client.openapi.ApiException: class V1Status {
apiVersion: v1
code: 403
details: class V1StatusDetails {
causes: null
group: null
kind: services
name: null
retryAfterSeconds: null
uid: null
}
kind: Status
message: services is forbidden: User "system:serviceaccount:default:default" cannot list resource "services" in API group "" at the cluster scope
metadata: class V1ListMeta {
_continue: null
remainingItemCount: null
resourceVersion: null
selfLink: null
}
reason: Forbidden
status: Failure
}
因此需要給默認(rèn)用戶足夠權(quán)限楷怒。我這里為了方便賦的權(quán)限比較大蛋勺,具體可以根據(jù)自己的情況設(shè)置
如下:auth.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cluster-service-endpoints-reader
rules:
- apiGroups: [""]
resources: ["pods", "services", "endpoints", "secrets", "configmaps"]
verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: cluster-service-endpoints-reader-binding
subjects:
- kind: ServiceAccount
name: default
namespace: default
roleRef:
kind: ClusterRole
name: cluster-service-endpoints-reader
apiGroup: rbac.authorization.k8s.io
- 創(chuàng)建talk.yaml和對(duì)應(yīng)需要的configmap配置
[root@k8s-master shujunjun]# ls
project-config.yaml project.yaml talk-config.yaml talk.yaml
[root@k8s-master shujunjun]# cat talk-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: talk-config
data:
application.yml: |
server:
port: 8888
[root@k8s-master shujunjun]# cat talk.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: talk
spec:
replicas: 1
selector:
matchLabels:
app: talk
template:
metadata:
labels:
app: talk
spec:
# serviceAccountName: shujunjun
containers:
- name: talk
image: talk:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8888
---
apiVersion: v1
kind: Service
metadata:
name: talk
spec:
type: LoadBalancer
ports:
- port: 8888
targetPort: 8888
nodePort: 8888
selector:
app: talk
project類似處理,這里不再贅述
- 部署應(yīng)用
[root@k8s-master shujunjun]# kubectl apply -f talk.yaml
deployment.apps/talk created
service/talk created
-
測(cè)試效果
通過(guò)kubernetes使用feign調(diào)用成功
也可以查看k8s中其他服務(wù)信息