0. 前置条件
代码库:chintensakai/learn-spring-cloud (gitee.com)
- [k8s集群](kubeadm部署一主二从k8s集群 - 掘金 (juejin.cn))
- [mysql部署到k8s集群中](k8s 集群部署 mysql - 掘金 (juejin.cn))
- [有一个spring cloud 应用](Spring Authorization Server 授权码模式的例子 - 掘金 (juejin.cn)) 上篇文章写的时候还是用的nacos,迁移到k8s之后,就不再用nacos来服务注册和发现了,直接使用k8s原生能力,当为服务创建service之后,服务就已经通过service name注册到etcd中了,各服务之间通过service name就可以调用,同时兼具负载均衡能力。
1. 设计
update--
前端通过ingress暴露域名:chins-blog.me/, 认证中心通过ingress暴露域名,就好比使用第三方登录平台时,第三方平台肯定是暴露的。
点击登录之后,挑战到认证中心认证,输入用户名密码,认证中心响应授权码到chins-blog.me/code-redire… 这个接口是前端项目的后端,有两种方法可以把这接口路由到后端,一种通过网关,我这里使用另一种,复用前端的ingress,直接转发到后端。
后端拿到授权码,请求token,回写到中间页中,就像之前文章描述的那样。
前端拿到token,处理回调事件就好了,可以存入localstorage,再继续其他的业务就行了。其他业务携带token,经过gateway鉴权,路由到对应的后端API。
完事。
前后端分离的应用,通过ingress只暴露前端到集群外部,前端在集群内部通过ingress调用网关,网关通过k8s应用发现机制,根据service name转发流量。
进度: 已完结: ~~域名 -> 前端ingress,后端service调用完成,前端 -> 后端ingress还没做,下周再说。
1.1 安装ingress
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.0/deploy/static/provider/cloud/deploy.yaml
如果你拉不到镜像,还是老办法,修改这个yaml的镜像地址成国内的地址就行
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:v1.1.0
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v1.1.1
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v1.1.1 k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.1.1
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:v1.1.0 k8s.gcr.io/ingress-nginx/controller:v1.1.0
注意,如果你有多个node节点,那么要把ingress-nginx-controller的pod数量改成和节点数量相同
2. 各服务打包
每个服务都有对应的package目录,里面放了helm chart包格式的各种资源文件,分别编辑就行。
同时每个服务根目录有Dockerfile文件,用来docker build镜像,有了镜像你可以推送到镜像仓库,我这里直接推送到节点上,这不是重点。 详见代码库:chintensakai/learn-spring-cloud (gitee.com)
前端不是我的专业,我这里直接npm本地打包,从dist开始打镜像,专业的人可能从基础镜像开始,安装npm,npm run build。。。。。。。。。
FROM nginx
COPY dist /usr/share/nginx/html/
COPY nginx.conf /etc/nginx/nginx.conf
RUN mkdir -p /etc/nginx/logs
RUN tee /etc/nginx/logs/error.log
RUN tee /etc/nginx/logs/access.log
RUN chmod -R 660 /etc/nginx/logs
RUN rm /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
后端同理,可以从基础镜像开始,安装jdk........,我这里直接本地maven package,从target下的jar包开始打镜像。
打就完了。
# 不用这种Dockerfile了,因为没有利用springboot提供的分层镜像复用
#FROM openjdk:8u312-oraclelinux8
#RUN mkdir -p /opt/apps/learn-api
#COPY target/learn-api-0.0.1-SNAPSHOT.jar /opt/apps/learn-api
#ENTRYPOINT ["java", "-jar", "/opt/apps/learn-api/learn-api-0.0.1-SNAPSHOT.jar"]
# 新Dockerfile
FROM 192.168.1.248:5000/openjdk:8u191-jre-alpine as builder
# RUN mkdir -p /opt/apps/learn-api
WORKDIR application
COPY target/learn-api-0.0.1-SNAPSHOT.jar application.jar
RUN java -Djarmode=layertools -jar application.jar extract
# 二阶段
FROM 192.168.1.248:5000/openjdk:8u191-jre-alpine
WORKDIR application
COPY --from=builder application/dependencies/ ./
COPY --from=builder application/spring-boot-loader/ ./
COPY --from=builder application/snapshot-dependencies/ ./
COPY --from=builder application/application/ ./
ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]
3. 写了一个自动化安装工具 golang编写k8s应用部署工具 - 掘金 (juejin.cn)
3. 代码上传到主节点,分别helm package xxxx,再helm install xxx,完事。
说起来很简单,做起来各种坑,周末两天全搞这个了。
遇到的问题
.1 服务通过k8s原生的应用发现机制,feign调用报RBAC问题
解决办法: 给你这个服务新建SA-ROLE-RB,绑到deploy里面,为了方便我这里使用通配符,使这个角色拥有该namespace下的所有权限
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: learn-spring-cloud-k8s
namespace: default
rules:
- apiGroups:
- "*"
resources:
- "*"
verbs:
- "*"
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: learn-spring-cloud-k8s-sa
namespace: default
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: learn-spring-cloud-k8s-rb
namespace: default
subjects:
- kind: ServiceAccount # May be "User", "Group" or "ServiceAccount"
name: learn-spring-cloud-k8s-sa
roleRef:
kind: Role
name: learn-spring-cloud-k8s
apiGroup: rbac.authorization.k8s.io