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:v12)执行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:v12) 执行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:v12)执行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部署微服务的主要内容,如果未能解决你的问题,请参考以下文章