一、简介
本篇我们将会把商城的服务部署到k8s中,同时变化的还有以下两个地方:
1.不再使用Consul做服务的注册和发现,转而使用Traefik来实现。
2.不再使用Ocelot作为业务网关,同样使用Traefik来实现。
正如上面所讲,Traefik将会被用来做服务发现和网关,当然,相比与以上两个工具,Traefik还有自己的不足,比如Consul的健康检查、Ocelot的限流、熔断机制,不过这些我们后面可以通过其它方式来实现。
整体思路很简单哈,就是编写Dockerfile文件,将各个服务打包成镜像上传到DockerHub,然后再我们的k8s集群中部署,并使用Traefik路由。
二、打包镜像
Dockerfile文件都一样的,所以我这里只列出IdentityServer4服务的Dockerfile:
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base WORKDIR /app EXPOSE 80 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.Entity RUN dotnet restore RUN dotnet build -c Release -o /app WORKDIR /src/MI.Service.Account.Model RUN dotnet restore RUN dotnet build -c Release -o /app 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: 2 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: 80
apiVersion: v1 kind: Service metadata: name: mi-service-identity namespace: mi spec: selector: k8s-app: mi-service-identity ports: - name: http port: 80 targetPort: 80
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 1/1 Running 0 23h mi-service-identity-7dfbf85d-z4hz9 1/1 Running 0 23h [root@localhost ~]# kubectl get deployment -n mi NAME READY UP-TO-DATE AVAILABLE AGE mi-service-identity 2/2 2 2 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> 80/TCP 7s [root@localhost k8s-mi]# kubectl get ing -n mi NAME HOSTS ADDRESS PORTS AGE mi-service mi.service.identity 80 33m
这个时候我们已经可以再集群内部访问了:
[root@localhost service-yaml]# curl http://10.109.13.2/api/Health ok
然后配置下Host文件,通过浏览器访问
这个服务是用来获取token令牌的,所以呢我们需要postman测试下能不能获取到Token:
成功!