原文网址:https://www.bbsmax.com/A/Ae5RRDeN5Q/
一、简介
本篇我们将会把商城的服务部署到k8s中,同时变化的还有以下两个地方:
1.不再使用Consul做服务的注册和发现,转而使用k8s-dns来实现。
2.不再使用Ocelot作为业务网关,使用Traefik来实现。
正如上面所讲,服务发现和网关均使用k8s的相关工具,当然,相比与以上两个工具,Traefik还有自己的不足,比如Consul的健康检查、Ocelot的限流、熔断机制,不过这些我们后面可以通过其它方式来实现。
整体思路很简单哈,就是编写Dockerfile文件,将各个服务打包成镜像上传到DockerHub,然后再我们的k8s集群中部署,并使用Traefik路由。
二、打包镜像
Dockerfile文件都一样的,所以我这里只列出IdentityServer4服务的Dockerfile:
- FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
- WORKDIR /app
- EXPOSE
- FROM microsoft/dotnet:2.1-sdk AS build
- WORKDIR /src
- Copy . .
- RUN dotnet restore
- RUN dotnet build -c Release -o /app
- FROM build as publish
- RUN dotnet publish -c Releease -o /app
- FROM base AS final
- WORKDIR /app
- COPY --from=publish /app .
- ENTRYPOINT ["dotnet", "MI.Service.Identity.dll"]
通过以下命令进行打包:
- docker build -t 镜像名 .
这里需要注意的是镜像名要用自己DockerHub的用户名作为前缀,比如 用户名/mi.service.identity ,只有这样才能再后面上传镜像。
然后通过以下命令登录Docker,上传镜像:
- docker login --username xxx
- docker push 用户名/mi.service.identity
这里需要注意的是如果我们的项目是包含类库的,比如下面这种:
那我们的Dockerfile文件写法要改成下面这样,并且要把它放在和解决方案.sln同级的文件夹内,因为类库也需要进行编译:
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 80
FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /src
Copy . .
WORKDIR /src/MI.Service.Account
RUN dotnet restore
RUN dotnet build -c Release -o /app
FROM build as publish
RUN dotnet publish -c Releease -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "MI.Service.Account.dll"]
三、部署到k8s
我们的需要编写deployment、Service和ingress的yaml文件,分别如下
- kind: Deployment
- apiVersion: apps/v1
- metadata:
- labels:
- k8s-app: mi-service
- name: mi-service-identity
- namespace: mi
- spec:
- replicas:
- selector:
- matchLabels:
- k8s-app: mi-service-identity
- template:
- metadata:
- labels:
- k8s-app: mi-service-identity
- spec:
- containers:
- - name: mi-service-identity
- image: 用户名/mi.service.identity
- ports:
- - containerPort:
- apiVersion: v1
- kind: Service
- metadata:
- name: mi-service-identity
- namespace: mi
- spec:
- selector:
- k8s-app: mi-service-identity
- ports:
- - name: http
- port:
- targetPort:
- apiVersion: extensions/v1beta1
- kind: Ingress
- metadata:
- name: mi-service
- namespace: mi
- spec:
- rules:
- - host: mi.service.identity
- http:
- paths:
- - path: /
- backend:
- serviceName: mi-service-identity
- servicePort: http
通过以下命令部署(拉取镜像需要点时间):
- kubectl apply -f mi_identity.yaml
- kubectl apply -f mi_identity_service.yaml
- kubectl apply -f mi-service-ingress.yaml
完成后查看svc、pod、ingress的状态:
- [root@localhost ~]# kubectl get pods -n mi
- NAME READY STATUS RESTARTS AGE
- mi-service-identity-7dfbf85d-x7w82 / Running 23h
- mi-service-identity-7dfbf85d-z4hz9 / Running 23h
- [root@localhost ~]# kubectl get deployment -n mi
- NAME READY UP-TO-DATE AVAILABLE AGE
- mi-service-identity / 23h
- [root@localhost service-yaml]# kubectl get svc -n mi
- NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
- mi-service-identity ClusterIP 10.109.13.2 <none> /TCP 7s
- [root@localhost k8s-mi]# kubectl get ing -n mi
- NAME HOSTS ADDRESS PORTS AGE
- mi-service mi.service.identity 33m
这个时候我们已经可以再集群内部访问了:
- [root@localhost service-yaml]# curl http://10.109.13.2/api/Health
- ok
然后配置下Host文件,通过浏览器访问
这个服务是用来获取token令牌的,所以呢我们需要postman测试下能不能获取到Token:
成功!
然后我们需要把另外的服务也部署到k8s,同时更新Ingress的配置,如下:
- apiVersion: extensions/v1beta1
- kind: Ingress
- metadata:
- name: mi-service
- namespace: mi
- spec:
- rules:
- - host: mi.service.identity
- http:
- paths:
- - path: /
- backend:
- serviceName: mi-service-identity
- servicePort: http
- - host: mi.service.account
- http:
- paths:
- - path: /
- backend:
- serviceName: mi-service-account
- servicePort: http
- - host: mi.service.monitor
- http:
- paths:
- - path: /
- backend:
- serviceName: mi-service-monitor
- servicePort: http
- - host: mi.service.picture
- http:
- paths:
- - path: /
- backend:
- serviceName: mi-service-picture
- servicePort: http
- - host: mi.service.shopcar
- http:
- paths:
- - path: /
- backend:
- serviceName: mi-service-shopcar
- servicePort: http
这个时候其实我们已经可以正常使用了,我们将Web项目里的服务地址修改下,不再通过调用Ocelot进行转发,而是使用k8s中Service的标识,修改appsettings:
- {
- "Logging": {
- "IncludeScopes": false,
- "LogLevel": {
- "Default": "Warning"
- }
- },"ServiceAddress": {
- "Service.Identity": "http://mi.service.identity",
- "Service.Account": "http://mi.service.account","Service.Picture": "http://mi.service.picture",
- "Service.Monitor": "http://mi.service.monitor",
- "Service.ShopCar": "http://mi.service.shopcar"
- }
- }
然后运行项目查看:
但是我们现在还存在一个问题。虽然Pod的IP可以被Service发现,但是Service的IP被谁发现呢,现在Traefik中配置host和其IP是我们手动配置,当然Service的IP一般是固定不变的,但是如果变了,我们希望能被自动发现和映射,这一步将通过k8s dns来实现。
三、使用k8s-dns做服务发现
k8s中的service分配的虚拟IP是固定的,而pod异常后新生成的pod ip会发生变化,可以通过service做代理关联到后端的pod。
kube-dns可以解决Service的发现问题,k8s将Service的名称当做域名注册到kube-dns中,通过Service的名称就可以访问其提供的服务。
标签:Core,http,Service,service,mi,商城,Net,k8s,identity From: https://www.cnblogs.com/bruce1992/p/17033639.html