SpringCloud--19微服务的部署(将服务部署在K8S集群上面)

1.把它们放到kubernetes集群运行我们要考虑什么问题?

  • 哪些服务适合单独成为一个pod?哪些服务适合在一个pod中?
  • 在一个pod里面的服务如何彼此访问?他们的服务如何对外提供服务?
  • 单独的pod如何对外提供服务?
  • 哪个服务作为整个服务的入口,入口服务如何对外提供服务?

2. 搞定配置

配置的模板已经为大家准备好了,但是还需要大家做一下处理才能使用哦,参考下面脚本:

$ cd ~/kubernetes-starter/service-config/
$ ls
api-gateway.yaml     message-service.yaml
course-service.yaml  user-service.yaml
#替换变量 - (hub.mooc.com:8080是我的环境的镜像仓库地址,大家修改为各自的仓库)
$ sed -i 's/{{HUB}}/hub.haojing.com:8080/g' *

3. 部署服务

部署前准备:

  • 要过一遍我们现有的代码配置,看看是否有需要修改的,修改后需要新生成镜像
  • 要启动好微服务依赖的服务,像zookeeper,mysql,registry等

 目前镜像是这样的:

 

目前的话,一个pod分一个服务先将基础组件的mysql服务起来,在node1的节点上

首先部署eureka服务,

eureka服务的yml文件:

server:
  port: 8000

eureka:
  instance:
#    hostname: ${host.name}
    hostname: localhost
    prefer-ip-address: true
    instance-id: ${spring.cloud.client.ipAddress}:${server.port}
  client:
    registerWithEureka: false
    fetchRegistry: false
    serviceUrl:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
#      defaultZone: http://localhost:8000/eureka/

 k8s上的部署yaml文件:

 这个文件会起一个servcies和一个deployment,他的服务端口是8000,他的容器端口是8000,对外提供访问的端口nodeport是8000

apiVersion: v1
kind: Service
metadata:
  labels:
    app: eureka-service
  name: eureka-service
spec:
  ports:
  - port: 8000
    protocol: TCP
    targetPort: 8000
    nodePort: 8000
  selector:
    app: eureka-service
  type: NodePort
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: eureka-service-deployment
spec:
  replicas: 1
  template: 
    metadata:
      labels:
        app: eureka-service
    spec:
      containers:
      - name: eureka-service
        image: hub.haojing.com/haojing/eureka-app:1.0
        ports:
        - containerPort: 8000
      imagePullSecrets:
      - name: regsecret

 

kubectl apply -f eureka-service.yaml

 在启动的时候有端口的限制,我们改一下api-server:

 

  修改配置后我们重新启动api-server服务

systemctl daemon-reload
service kube-apiserver restart

 

  

 

 访问:

刚刚开始部署的时候他无法拉取镜像,在工作节点上手动拉取了镜像才能部署成功,工作节点的docker 必须要登陆,因为要拉的是私库的镜像,按照道理来说master节点是不需要拉取镜像的,所以他可以不用登陆吧,

 网关服务的yml文件,service port是服务端口,服务端口是80,容器端口是8080,对外的nodeport特使80,然后还定义了一个

 deployment

apiVersion: v1
kind: Service
metadata:
  labels:
    app: api-gateway
  name: api-gateway
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 8080
    nodePort: 80
  selector:
    app: api-gateway
  type: NodePort
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: api-gateway-deployment
spec:
  replicas: 1
  template: 
    metadata:
      labels:
        app: api-gateway
    spec:
      containers:
      - name: api-gateway
        image: hub.haojing.com/haojing/api-app:1.0
        ports:
        - containerPort: 8080

  项目的yml文件:

spring:
  application:
    name: api-gateway
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
#    url: jdbc:mysql://${mysql.address}:3306/sys-user?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8
    url: jdbc:mysql://192.168.237.129:3306/sys-user?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8
    username: root
    password: 133309
eureka:
  client:
    serviceUrl:
      defaultZone: http://eureka-service:8000/eureka/
#      defaultZone: http://${eureka.host}:8000/eureka/
#      defaultZone: http://localhost:8000/eureka/
  instance:
    prefer-ip-address: true
    instance-id: ${spring.cloud.client.ipAddress}:${server.port}
server:
  port: 8080

#zuul:
##  prefix: /cloud-action
#  ignored-services: "*"
#  routes:
#    user-service: /user-service/**
#    ls-prevention-check: /prevention-check/**


zuul:
  host:
    connect-timeout-millis: 15000
    socket-timeout-millis: 60000
  routes:
    user-service:
      path: /user-service/**
      serviceId: user-service
#      url: http://user-service:8002
      sensitiveHeaders:
      customSensitiveHeaders: true
  add-proxy-headers: true
  retryable: true
#    blog-service:
#      path: /blogapi/**
#      serviceId: blog-service
#      sensitiveHeaders:

ribbon:
  ConnectTimeout: 250 # 连接超时时间(ms)
  ReadTimeout: 2000 # 通信超时时间(ms)
  OkToRetryOnAllOperations: true # 是否对所有操作重试
  MaxAutoRetriesNextServer: 2 # 同一服务不同实例的重试次数
  MaxAutoRetries: 1 # 同一实例的重试次数
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 6000 # 熔断超时时长:6000ms


 出现同样的错误,无法自动拉取私库的镜像,是不是master 上的docker 没有登陆的原因。把master也登陆上去吧

 

 还是不行。

直接查看docker的日志:

journalctl -u docker -f  

拉取镜像失败

然后百度了一下发现自己踩坑了,k8s拉取私有仓库需要额外的配置

对于公司内部的项目, 我们不可能使用公有开放的镜像仓库, 一般情况可能会花钱买 docker私仓服务, 或者说自己在服务器上搭建自己的私仓, 但不管怎样, 我们如何让k8s能够拉取私有仓库的镜像

1. 登录docker镜像仓库,这个在任意的node节点上登陆就行了。如果报443端口的错误就要配置daemon.json文件了

docker login hub.haojing.com

 之后输入密码就可以了, 这个时候我们可以在配置文件中查看登录情况

cat ~/.docker/config.json

  

  这个时候我们虽然可以通过docker pull命令拉取镜像, 但无法通过k8s创建pod方式拉取

  2. 生成密钥secret

kubectl create secret docker-registry regsecret --docker-server=hub.haojing.com --docker-username=admin --docker-password=xxxx --docker-email=wanglove@qq.com

 其中:
regsecret: 指定密钥的键名称, 可自行定义
--docker-server: 指定docker仓库地址
--docker-username: 指定docker仓库账号
--docker-password: 指定docker仓库密码
--docker-email: 指定邮件地址(选填)

 可以看到密钥生成了

可以看到当前除了默认的密钥, 还有我们刚才生成的. 另外要注意的是, 该密钥只能在对应namespace使用, 也就是这里的default, 如果需要用到其他namespace, 比如说test, 就需要在生成的时候指定参数 -n test

yml文件加入密钥参数

其中imagePullSecrets是声明拉取镜像时需要指定密钥, regsecret 必须和上面生成密钥的键名一致, 另外检查一下pod和密钥是否在同一个namespace, 之后k8s便可以拉取镜像

第二种方法(我用的是这种方法)

将登陆后生成的~/.docker/config.json配置文件进行编码:

base64 -w 0 ~/.docker/config.json

创建Secret:

### vim secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: regsecret
  namespace: default
data:
  .dockerconfigjson: ewoJImF1dGhzIjogewoJCSJodWIuaGFvamluZy5jb20iOiB7CgkJCSJhdXRoIjogIllXUnRhVzQ2TVRNek16QTUiCgkJfQoJfSwKCSJIdHRwSGVhZGVycyI6IHsKCQkiVXNlci1BZ2VudCI6ICJEb2NrZXItQ2xpZW50LzE5LjAzLjIgKGxpbnV4KSIKCX0KfQ==
type: kubernetes.io/dockerconfigjson
kubectl create -f secret.yaml

  

  ok,在创建部署的文件里面给他加上密钥配置就好了

 

 然后部署:

ok,没有问题

下面继续部署user服务

部署的yml文件:注意这个user服务属于内部服务,不需要指定nodeport供外部访问

apiVersion: v1
kind: Service
metadata:
  labels:
    app: user-service
  name: user-service
  namespace: default
spec:
  ports:
  - name: user-service-port
    port: 8082
    protocol: TCP
    targetPort: 8082
  selector:
    app: user-service
  sessionAffinity: None
  type: ClusterIP
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: user-service-deployment
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: user-service
    spec:
      containers:
      - name: user-service
        image: hub.haojing.com/haojing/user-app:1.0
        ports:
        - containerPort: 8082
      imagePullSecrets:
      - name: regsecret

 项目的yml文件:

eureka:
  client:
    serviceUrl:
#      defaultZone: http://${eureka.host}:8000/eureka/
      defaultZone: http://eureka-service:8000/eureka/
#      defaultZone: http://localhost:8000/eureka/
  instance:
    prefer-ip-address: true
    instance-id: ${spring.cloud.client.ipAddress}:${server.port}
spring:
  application:
    name: user-service
  cloud:
    loadbalancer:
      retry:
        enabled: true

  datasource:
    driver-class-name: com.mysql.jdbc.Driver
#    url: jdbc:mysql://${mysql.address}:3306/sys-user?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8
    url: jdbc:mysql://192.168.237.129:3306/sys-user?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8
    username: root
    password: 133309
mybatis:
  mapper-locations: classpath:mapper/*
  type-aliases-package: com.wx.userservice.domain.*
mapper:
  mappers: com.wx.userservice.utils.IBaseDao
  identity: MYSQL
server:
  port: 8002

ribbon:
  ConnectTimeout: 250 # 连接超时时间(ms)
  ReadTimeout: 2000 # 通信超时时间(ms)
  OkToRetryOnAllOperations: true # 是否对所有操作重试
  MaxAutoRetriesNextServer: 2 # 同一服务不同实例的重试次数
  MaxAutoRetries: 1 # 同一实例的重试次数
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 6000 # 熔断超时时长:6000ms

 ok,部署

 

每个服务都能跑起来,但是调用服务之间的调用就会出错,他会去拿eureka上默认分配的名字去调用,而不是我们事先定好的application的名字

这是什么原因呢?因为如果请求经过zuul网关转发到后台的服务提供者的话,

如果服务提供者和zuul网关在同一台机器上,大家都是localhost的域名,那就没问题,能发现服务;

如果服务提供者和zuul网关不在同一台机器上,会报一个没找到服务的异常,原因是根据localhost和端口没有找到相应的服务。

此时,一种解决方法是让服务提供者上报自己的 ip地址,并显示在Eureka的注册列表中。

 

然后重新部署;

可以看到拿的使IP了,swagger也能访问了

进入到pod中

kubectl exec -it api-gateway-deployment-86dbbcbc5c-dpnwr  -n default /bin/bash

看看网关的路由功能是否能用

 

好的,能调到user服务的接口,继续部署uaa服务

部署yml文件:

apiVersion: v1
kind: Service
metadata:
  labels:
    app: uaa-service
  name: uaa-service
spec:
  ports:
  - port: 8081
    protocol: TCP
    targetPort: 8081
  selector:
    app: uaa-service
  type: ClusterIP
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: uaa-service-deployment
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: uaa-service
    spec:
      containers:
      - name: uaa-service
        image: hub.haojing.com/haojing/uaa-app:1.0
        ports:
        - containerPort: 8081
      imagePullSecrets:
      - name: regsecret

项目的yml:

spring:
  application:
    name: uaa-service
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
#    url: jdbc:mysql://${mysql.address}:3306/sys-user?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8
    url: jdbc:mysql://192.168.237.129:3306/sys-user?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8
    username: root
    password: 133309
mybatis:
  mapper-locations: classpath:mapper/*
  type-aliases-package: com.wx.uaaservice.domain.*
mapper:
  mappers: com.wx.uaaservice.utils.IBaseDao
  identity: MYSQL
server:
  port: 8001

eureka:
  client:
    serviceUrl:
#      defaultZone: http://${eureka.host}:8000/eureka/
      defaultZone: http://eureka-service:8000/eureka/
#      defaultZone: http://localhost:8000/eureka/
  instance:
    prefer-ip-address: true
    instance-id: ${spring.cloud.client.ipAddress}:${server.port}

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 5000

 

 

 

 

 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时空恋旅人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值