k8s部署微服务

Posted 爱上口袋的天空

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了k8s部署微服务相关的知识,希望对你有一定的参考价值。

1、环境准备

提前搭建好的k8s集群准备:

    192.168.56.30(master节点)

    192.168.56.31(node节点)

harbor远程仓库准备:

     192.168.56.14

2、微服务的应该程序准备

kgf-eureka : 注册中心

kgf-gateway: 网关

kgf-openfeign-client: 使用feign调用远程程序的客户端

springboot-test-demo: 被客户端调用的springboot服务,这个我们使用tomcat部署

在本地启动后的效果:

调用的效果:

OK,下面开始使用k8s部署上面的应用程序。

注意:在其他的应用服务向kgf-eureka注册中心注册的时候需要进行下面的yamlpeizhi 

eureka:
  instance:
    prefer-ip-address: true  #以IP注册进eureka,不以ID注册
  client:
    service-url:
      defaultZone: http://kgf-eureka-0.kgf-eureka.kgf-dev.svc.cluster.local:7001/eureka,http://kgf-eureka-1.kgf-eureka.kgf-dev.svc.cluster.local:7001/eureka,http://kgf-eureka-2.kgf-eureka.kgf-dev.svc.cluster.local:7001/eureka

http://kgf-eureka-0.kgf-eureka.kgf-dev.svc.cluster.local:7001/eureka

kgf-eureka-0:StatefulSet的3个Pod是有序的,从零开始,第一个Pod名称是kgfeureka-0 

kgf-eureka: 表示的是svc名称

kgf-dev: 表示的是名称空间

svc.cluster.local:是svc内部通信,固定的写法

3、准备基础镜像

3.1、首先创建一个指定的namespace,kgf-namespace.yaml

apiVersion: v1
kind: Namespace
metadata:
  name: kgf-dev

3.2、创建configMap,kgf-configmap.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: application-dev-yaml
  namespace: kgf-dev
data:
  application.yaml: |
    spring:
      profiles:
        active: dev 

3.3、创建jdk基础镜像的Dockerfile

#基于centos基础镜像
FROM centos:latest

#作者信息
MAINTAINER kgf

#将jdk的安装包拷贝到容器中,会自动解压为jdk1.8.0_191
ADD jdk-8u191-linux-x64.tar.gz /usr/local/java

#设置环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_191
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV PATH $PATH:$JAVA_HOME/bin

#最后打印出jdk版本
CMD java -version

3.4、基于jdk1.8.0_191创建tomcat基础镜像的Dockerfile

#基于jdk1.8.0_191基础镜像
FROM jdk1.8.0_191:v1

#作者信息
MAINTAINER kgf

#将tomcat的安装包拷贝到容器中
ADD apache-tomcat-8.5.37.tar.gz /usr/local/

#配置tomcat环境变量
ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.37
ENV CATALINA_BASE /usr/local/apache-tomcat-8.5.37
ENV PATH $PATH:$CATALINA_HOME/lib:$CATALINA_HOME/bin

#公开端口
EXPOSE 8080
#设置启动命令
#CMD /usr/local/apache-tomcat-8.5.37/bin/startup.sh && tail -F /usr/local/apache-tomcat-8.5.37/logs/catalina.out

4、配置注册中心的Dockerfile以及yaml脚本

4.1、创建kgf-eureka的Dockerfile脚本

#基于jdk1.8.0_191镜像
FROM jdk1.8.0_191:v1

MAINTAINER kgf

#将jar拷贝到容器中去
ADD kgf-eureka.jar /opt

#赋予执行权限
RUN chmod +x /opt/kgf-eureka.jar

#Java JVM 启动参数变量,这里需要在这里加一个时区参数。
ENV JAVA_OPTS="-Duser.timezone=Asia/Shanghai"

#暴露端口
EXPOSE 7001

#Spring 容器启动参数变量,方便后续操作时能通过此变量配置 Spring 参数
ENV APP_OPTS=""

#运行jar
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS  -jar /opt/kgf-eureka.jar  $APP_OPTS" ]

4.2、创建kgf-eureka的yaml脚本

     kgf-eureka注册中心,这里选择用 StatefulSet (有状态集)方式来部署,这样能保证它 Eureka Pod 名是有序的,如果部署为 Deployment,那么得部署三个 Deployment 对象,比较繁琐。并且 StatefulSet 支持 Service Headless 方式创建 Service 来对内部服务访问,如果是 CluserIP 方式创建 Service 会分一个虚拟 IP 给该 Service,那么服务通过 Service 访问 Pod 每次都需要经过 Kube-proxy 代理流量,这样会增加与注册中心的通信造成一定性能损耗。Headless 方式部署的 Service 不会分配虚拟 IP,而是用轮询的访问,每次都直接与 Pod 的 IP 进行通信。

---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: k8s-eureka
  namespace: kgf-dev #命名空间 接下来的部署都会使用这个命名空间
spec:
  rules:
    - host: kgf.eureka.com #外部访问的域名
      http:
        paths:
        - path: /
          backend:
            serviceName: kgf-eureka #服务对应的service名称
            servicePort: 7001 #对应service的端口
---
apiVersion: v1
kind: Service
metadata:
  name: kgf-eureka # Service 的名称,对应着Ingress中的serviceName: kgf-eureka
  namespace: kgf-dev
spec:
  clusterIP: None # 这就是将这个service 设置为无头服务,因为通过网址的形式进行注册 , 所以需要使用到Headless Service无头服务,Headless 方式部署的 Service 不会分配虚拟 IP,而是用轮询的访问,每次都直接与 Pod 的 IP 进行通信
  ports:
    - name: kgf-eureka # 指定端口的名称
      port: 7001
  selector:
    project: kgf-dev
    app: kgf-eureka # 轮询对应 Deployment 中 kgf-dev 命名空间的 selector 指定的app
---
apiVersion: apps/v1
kind: StatefulSet #这里选择用 StatefulSet (有状态集)方式来部署,这样能保证它 Eureka Pod 名是有序的,如果部署为 Deployment,那么得部署三个 Deployment 对象,比较繁琐。并且 StatefulSet 支持 Service Headless 方式创建 Service 来对内部服务访问
metadata:
  name: kgf-eureka
  namespace: kgf-dev
spec:
  serviceName: kgf-eureka
  replicas: 3
  selector:
    matchLabels:
      project: kgf-dev
      app: kgf-eureka
  template:
    metadata:
      labels:
        project: kgf-dev
        app: kgf-eureka
    spec:
      terminationGracePeriodSeconds: 10    #当删除Pod时,等待时间
      containers:
        - name: kgf-eureka
          image: hub.harbor.com/library/kgf-eureka:v1
          ports:
            - protocol: TCP
              containerPort: 7001
          env:
            - name: APP_NAME  #APP_NAME: 和服务名称一致,将服务名称传入容器环境中。
              value: "kgf-eureka"
            - name: POD_NAME #POD_NAME:Pod名称,将 Pod 名称传入容器环境中。
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: APP_OPTS #APP_OPTS: Dockerfile 中定义的变量,用于设置 Spring 启动参数,这里主要设置此值与 APP_NAME 和 POD_NAME 两值配合使用
              value: "
                     --eureka.instance.hostname=${POD_NAME}.${APP_NAME}
                     --registerWithEureka=true
                     --fetchRegistry=true
                     --eureka.instance.preferIpAddress=true
                     --eureka.client.serviceUrl.defaultZone=http://kgf-eureka-0.${APP_NAME}:7001/eureka/,http://kgf-eureka-1.${APP_NAME}:7001/eureka/,http://kgf-eureka-2.${APP_NAME}:7001/eureka/
                     "
          resources: #对 Pod 使用计算资源的限制
            limits:
              cpu: 1
              memory: 1024Mi
            requests:
              cpu: 0.5
              memory: 125Mi
          readinessProbe:              #就绪探针,Pod 启动时只有就绪探针探测成功后才对外提供访问,用它可用避免 Pod 启动而内部程序没有启动的情况下就允许外部流量流入这种情况。
            tcpSocket:
              port: 7001
            initialDelaySeconds: 20    #延迟加载时间
            periodSeconds: 5           #重试时间间隔
            timeoutSeconds: 10         #超时时间设置
            failureThreshold: 5        #探测失败的重试次数
          livenessProbe:               #存活探针,定期检测 Docker 内部程序是否存活
            tcpSocket:
              port: 7001
            initialDelaySeconds: 60    #延迟加载时间
            periodSeconds: 5           #重试时间间隔
            timeoutSeconds: 5          #超时时间设置
            failureThreshold: 3        #探测失败的重试次数

5、kgf-gateway网关的Dockerfile和yaml脚本编写

5.1、Dockerfile脚本编写

#基于我们刚刚创建的jdk镜像
FROM jdk1.8.0_191:v1

#作者信息
MAINTAINER kgf

#将应用包拷贝进入容器
ADD kgf-gateway.jar /opt

#赋予容器内应用程序执行的权限
RUN chmod +x /opt/kgf-gateway.jar

#运行jar
CMD java -jar /opt/kgf-gateway.jar

5.2、yaml脚本编写

apiVersion: apps/v1
kind: Deployment
metadata:
  name: kgf-gateway
  namespace: kgf-dev
  labels:
    app: kgf-gateway
spec:
  replicas: 1
  selector:
    matchLabels: { app: kgf-gateway }
  strategy: 
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
    type: RollingUpdate  
  template:
    metadata:
      labels: { app: kgf-gateway }
    spec:
      containers:
        - name: kgf-gateway
          env:
            - name: kgf-gateway
              valueFrom:
                fieldRef: { fieldPath: metadata.name }
          image: hub.harbor.com/library/kgf-gateway:v1
          imagePullPolicy: IfNotPresent
          resources: 
            limits:
              cpu: 1
              memory: 512Mi
            requests:
              cpu: 0.4
              memory: 256Mi
          volumeMounts:
            - name: application-dev-yaml
              mountPath: /config
            - name: kgf-gateway-log
              mountPath: /log/kgf/kgf-gateway  
      volumes:
        - name: kgf-gateway-log
          hostPath:
            path: /logs/kgf/kgf-gateway
            type: DirectoryOrCreate
        - name: application-dev-yaml
          configMap:
            name: application-dev-yaml
            items: 
              - key: application.yaml
                path: application.yaml              

5.3、创建对应的svc脚本,kgf-gateway-service.yaml

#service版本
apiVersion: v1
#这个表示资源类型我们创建的是Service
kind: Service
metadata: #这个里面定义的是Service中我们创建的对象信息
  #对象名称
  name: kgf-gateway
  #元数据名称空间
  namespace: kgf-dev
  labels:
    app: kgf-gateway
spec: #下面定义service的详细信息
  #类型为NodePort
  type: NodePort
  selector: #通过标签选择器去查询对应版本的pod,最后组成一个service
    app: kgf-gateway
  ports: #指定容器需要用到的端口列表
    #指定端口名称 
    - name: http
      #服务对外的端口
      port: 8888
      protocol: TCP
      #容器的端口
      targetPort: 8888

6、创建kgf-openfeign-client的Dockerfile和yaml脚本

6.1、创建Dockerfile

#基于我们刚刚创建的jdk镜像
FROM jdk1.8.0_191:v1

#作者信息
MAINTAINER kgf

#将应用包拷贝进入容器
ADD kgf-openfeign-client.jar /opt

#赋予容器内应用程序执行的权限
RUN chmod +x /opt/kgf-openfeign-client.jar

#运行jar
CMD java -jar /opt/kgf-openfeign-client.jar

6.2、创建Deployment类型的yaml脚本,kgf-openfeign-client-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: kgf-openfeign-client
  namespace: kgf-dev
  labels:
    app: kgf-openfeign-client
spec:
  replicas: 1
  selector:
    matchLabels: { app: kgf-openfeign-client }
  strategy: 
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
    type: RollingUpdate  
  template:
    metadata:
      labels: { app: kgf-openfeign-client }
    spec:
      containers:
        - name: kgf-openfeign-client
          env:
            - name: kgf-openfeign-client
              valueFrom:
                fieldRef: { fieldPath: metadata.name }
          image: hub.harbor.com/library/kgf-openfeign-client:v1
          imagePullPolicy: IfNotPresent
          resources: 
            limits:
              cpu: 1
              memory: 512Mi
            requests:
              cpu: 0.4
              memory: 256Mi
          volumeMounts:
            - name: application-dev-yaml
              mountPath: /config
            - name: kgf-openfeign-client-log
              mountPath: /log/kgf/kgf-openfeign-client 
      volumes:
        - name: kgf-openfeign-client-log
          hostPath:
            path: /logs/kgf/kgf-openfeign-client
            type: DirectoryOrCreate             
        - name: application-dev-yaml
          configMap:
            name: application-dev-yaml
            items: 
              - key: application.yaml
                path: application.yaml

6.3、创建svc脚本,kgf-openfeign-client-service.yaml

#service版本
apiVersion: v1
#这个表示资源类型我们创建的是Service
kind: Service
metadata: #这个里面定义的是Service中我们创建的对象信息
  #对象名称
  name: kgf-openfeign-client
  #元数据名称空间
  namespace: kgf-dev
  labels:
    app: kgf-openfeign-client
spec: #下面定义service的详细信息
  #类型为NodePort
  type: NodePort
  selector: #通过标签选择器去查询对应版本的pod,最后组成一个service
    app: kgf-openfeign-client
  ports: #指定容器需要用到的端口列表
    #指定端口名称 
    - name: http
      #服务对外的端口
      port: 9090
      protocol: TCP
      #容器的端口
      targetPort: 9090

7、创建springboot-test-demo的Dockerfile以及yaml脚本

7.1、创建Dockerfile脚本

#基于我们刚刚创建的jdk镜像
FROM mytomcat:v1

#作者信息
MAINTAINER kgf

#将应用包拷贝到容器内部
COPY springboot-test.war  /usr/local/apache-tomcat-8.5.37/webapps/


#设置启动命令
CMD /usr/local/apache-tomcat-8.5.37/bin/startup.sh && tail -F /usr/local/apache-tomcat-8.5.37/logs/catalina.out

7.2、创建Deployment脚本,springboot-test-demo-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: springboot-test
  namespace: kgf-dev
  labels:
    app: springboot-test
spec:
  replicas: 1
  selector:
    matchLabels: { app: springboot-test }
  strategy: 
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
    type: RollingUpdate  
  template:
    metadata:
      labels: { app: springboot-test }
    spec:
      containers:
        - name: springboot-test
          env:
            - name: springboot-test
              valueFrom:
                fieldRef: { fieldPath: metadata.name }
          image: hub.harbor.com/library/springboot-test:v1
          imagePullPolicy: IfNotPresent
          resources: 
            limits:
              cpu: 1
              memory: 512Mi
            requests:
              cpu: 0.4
              memory: 256Mi
          volumeMounts:
            - name: application-dev-yaml
              mountPath: /config
            - name: springboot-test-log
              mountPath: /log/kgf/springboot-test
      volumes:
        - name: springboot-test-log
          hostPath:
            path: /logs/kgf/springboot-test
            type: DirectoryOrCreate           
        - name: application-dev-yaml
          configMap:
            name: application-dev-yaml
            items: 
              - key: application.yaml
                path: application.yaml 

7.3、创建svc脚本,springboot-test-demo-service.yaml

#service版本
apiVersion: v1
#这个表示资源类型我们创建的是Service
kind: Service
metadata: #这个里面定义的是Service中我们创建的对象信息
  #对象名称
  name: springboot-test
  #元数据名称空间
  namespace: kgf-dev
  labels:
    app: springboot-test
spec: #下面定义service的详细信息
  #类型为NodePort
  type: NodePort
  selector: #通过标签选择器去查询对应版本的pod,最后组成一个service
    app: springboot-test
  ports: #指定容器需要用到的端口列表
    #指定端口名称 
    - name: http
      #服务对外的端口
      port: 8080
      protocol: TCP
      #容器的端口
      targetPort: 8080

8、开始执行上面准备的脚本

8.1、创建namespace

      kubectl apply -f kgf-namespace.yaml
      

8.2、创建configMap环境变量

   命令:kubectl apply -f kgf-configmap.yaml
   

8.3、创建jdk基础镜像

命令:docker build -t jdk1.8.0_191:v1 .


8.4、创建tomcat基础镜像

      命令:docker build -t mytomcat:v1 .
      

8.5、  创建kgf-eureka注册中心的镜像以及执行yaml脚本

   1)创建kgf-eureka的镜像
         命令:docker build -t hub.harbor.com/library/kgf-eureka:v1 .
        
        将生成的镜像推送到harbor: docker push hub.harbor.com/library/kgf-eureka:v1 

   2)执行eureka-yaml脚本

       命令:kubectl apply -f eureka.yaml

       
       查看创建的svc和Ingress
       
       查看pods
       
       在本地hosts配置:

       192.168.56.31 kgf.eureka.com

       浏览器效果:
       

8.6、创建kgf-gateway的镜像以及执行yaml脚本

    1)创建基础镜像

         命令:docker build -t hub.harbor.com/library/kgf-gateway:v1 .
        
         推送到harbor: docker push hub.harbor.com/library/kgf-gateway:v1

    2) 执行kgf-gateway-deployment.yaml脚本

         命令:kubectl apply -f kgf-gateway-deployment.yaml
        

    3)执行kgf-gateway-service.yaml脚本
        命令:kubectl apply -f kgf-gateway-service.yaml
        
     4)查看注册中心
         

8.7、创建kgf-openfeign-client镜像以及执行yaml脚本

      1)创建kgf-openfeign-client镜像

            命令:docker build -t hub.harbor.com/library/kgf-openfeign-client:v1 .
            
            推送到harbor: docker push hub.harbor.com/library/kgf-openfeign-client:v1

      2)执行kgf-openfeign-client-deployment.yaml脚本

            命令:kubectl apply -f kgf-openfeign-client-deployment.yaml
            

      3)执行kgf-openfeign-client-service.yaml脚本

            命令:kubectl apply -f kgf-openfeign-client-service.yaml
            

      4)查看注册中心

           

8.8、  创建springboot-test-demo的镜像并且执行yaml脚本

        1)执行Dockerfile脚本

            命令:docker build -t hub.harbor.com/library/springboot-test:v1 .
            

        2) 执行yaml脚本

       3)查看注册中心

          

9、调用接口看效果

 接口:http://192.168.56.30:32447/gateway/kgf-openfeign-client/test/queryMenus

 或者http://192.168.56.31:32447/gateway/kgf-openfeign-client/test/queryMenus

32447端口代表gateway的svc映射的8888端口:

效果:

以上是关于k8s部署微服务的主要内容,如果未能解决你的问题,请参考以下文章

十三,部署微服务到K8S

微服务从代码到k8s部署应有尽有系列(十一日志收集)

如何在k8s上部署mongodb微服务

k8s+SpringCloud全栈技术:在k8s平台部署亿级高并发的SpringCloud项目

高可用集群篇-- K8S部署微服务

k8s部署基础服务