文章目录

  • 前言
  • 一、将SpringBoot应用打包
  • 二、制作Docker镜像
  • 2.1 将jar包上传到服务器上,创建Dockerfile (必须是这个名字)和jar包放在同一目录下
  • 2.2 编写Dockerfile
  • 2.3 打包镜像
  • 2.4 检查镜像是否成功生成
  • 2.5 运行镜像
  • 2.6 下载镜像
  • 三、编写Charts
  • 3.1 Charts.yaml文件
  • 3.2 values.yaml文件
  • 3.3 templates文件夹
  • 3.3.1 configmap.yaml
  • 3.3.2 service.yaml
  • 3.3.3 deployment.yaml
  • 四、容器化部署
  • 4.1 导入镜像
  • 4.2 推送镜像
  • 4.3 查看镜像列表
  • 4.3 helm部署k8s应用
  • 4.4 查看应用服务状态



前言

在互联网时代,为了实现应用更快的开发迭代,和更好的弹性伸缩,互联网应用不再采用传统的三层架构,而是使用微服务的方式来实现软件系统的松耦合,跨部门开发以及快速交付等等目的。Docker定义容器技术标准使得容器技术的落地变得十分简单,应用可以稳定便携的运行在容器中


在工作过程中,我需要将开发的SpringBoot应用打包成Docker镜像部署到k8s集群中进行管理。本篇文章是我完成任务后的总结归纳,下面内容可供参考

一共有以下几个步骤

  • springboot项目打成jar包(此次不做过多解释)
  • 制作docker镜像
  • 编写charts
  • 容器化部署

一、将SpringBoot应用打包

首先保证springboot项目在本地成功运行,然后maven package打成jar包

二、制作Docker镜像

2.1 将jar包上传到服务器上,创建Dockerfile (必须是这个名字)和jar包放在同一目录下

代码如下(示例):

vim Dockerfile

2.2 编写Dockerfile

代码如下(示例):

# 拉取基础镜像
FROM java:8
 
# 设置作者信息
MAINTAINER xiaopeng "xiaopeng@baidu.com"
 
# 把warning-tool-0.0.1-SNAPSHOT.jar添加到容器里,并重命名为warning-tool.jar
# 因为jar和Dockerfile在同一个目录下,所以只写文件名即可
ADD warning-tool-0.0.1-SNAPSHOT.jar warning-tool.jar
 
# 设置端口号,此处只开放一个端口8089
EXPOSE 8089
 
# 执行命令,此处运行warning-tool.jar 指定配置文件
RUN bash -c 'touch /warning-tool.jar'
ENTRYPOINT ["java","-jar","warning-tool.jar","--spring.config.location=/config/application.properties"]

该处详细解释各个参数。

FROM:指定基础镜像,必需为第一个指令。FROM : tag可选
MAINTAINER:维护者信息
ADD:将本地文件添加到容器的指定目录中,tar类型文件会自动解压(网络压缩资源不会被解压),可以访问网络资源,类似wget
EXPOSE:设置端口号,如果想使得容器与主机的端口有映射关系,必须在容器启动的时候加上 -P参数
RUN:构建镜像时执行的指令

注意:多行命令不要写多个RUN,原因是Dockerfile中每一个指令都会建立一层.

  多少个RUN就构建了多少层镜像,会造成镜像的臃肿、多层,不仅仅增加了构件部署的时间,还容易出错。 RUN书写时的换行符是\

  RUN是构建容器时就运行的命令以及提交运行结果

  CMD是容器启动时执行的命令,在构建时并不运行,构建时指定了这个命令到底是个什么样子

LABEL:功能是为镜像指定标签
ENTRYPOINT:配置容器,使其可执行化。配合CMD可省去命令,只使用参数。
COPY:功能类似ADD,但是是不会自动解压文件,也不能访问网络资源。
VOLUME:用于指定持久化目录

2.3 打包镜像

运行一条命令即可(注意最后有个.号):

docker build -f Dockerfile -t registry.xxx.baidu.com/dev/warningtool:v1.0 .

-f:指定Dockerfile文件 注意:名字要起成这种registry.xxx.baidu.com/dev/…这种,不然上传不到仓库
-t:指定镜像的标签信息

2.4 检查镜像是否成功生成

docker images | grep warningtool

2.5 运行镜像

// -p后面有两个端口,分别是:宿主机端口:容器端口
docker run -p 8083:8083 --name=warningtool registry.xxx.baidu.com/dev/warningtool:v1.0

2.6 下载镜像

docker save -o warningtool.tar registry.xxx.baidu.com/dev/warningtool

三、编写Charts

k8s 部署服务可以采用两种方式

  1. 自己编写对应的资源控制yaml ,kubectl apply -f XX .yml部署
  2. 使用helm charts的方式部署

Helm 是 Deis 开发的一个用于 Kubernetes 应用的包管理工具,主要用来管理 Charts。

下图是通过helm create test的方式创建charts,以下为目录结构

helm部署mongodb helm部署springboot_helm部署mongodb


文件夹下有三部分: Chart.yaml 、 templates文件夹 、 values.yaml

3.1 Charts.yaml文件

说明:Charts.yml 用于编写版本信息
示例:Charts.yaml

apiVersion: v1
appVersion: "1.0"
description: A Helm chart for Kubernetes
name: warningTool
version: 0.1.0

3.2 values.yaml文件

说明:values.yaml 用于编写整个charts应用的 参数信息 ,比如 image , service-type ,等可变信息。主要定义一些变量,赋值给其他的yaml。
示例:values.yaml。这里是按照nginx的charts作为模板进行修改

# Default values for nginx.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.

warningtool:
# 定义应用的名字
  fullname: warningtool-1-0-0
  fullnameapp: nginx-app
# 定义应用副本数量
  replicaCount: 1

  liveinitialDelaySeconds: 5
  readinitialDelaySeconds: 5

# 定义镜像的仓库地址 tag版本号
image:
  repository: registry.det.baidu.com/xxx/warningtool
  tag:  v1.0
  pullPolicy: IfNotPresent

hostPath:
# 设置是否开启站点模式、如果为true则将宿主机的/data目录通过站点模式映射出来。
  enabled: true
  path: /data
  type: ''

nameOverride: ""
fullnameOverride: ""

# 定义service的类型和端口。
service:
  type: NodePort
  port: 8090


resources:
  # We usually recommend not to specify default resources and to leave this as a conscious
  # choice for the user. This also increases chances charts run on environments with little
  # resources, such as Minikube. If you do want to specify resources, uncomment the following
  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
#  limits:
#    cpu: 2
#    memory: 1Gi
# 启动的最小要求,如不满足则无法启动。
  requests:
    cpu: 1
    memory: 2Gi

# 指定pod分配到指定node节点。
nodeSelector: {}
# 节点亲和性(容忍)是pod的一种属性,它使pod被吸引到一类特定的节点。
tolerations: []

affinity: {}
# 存活探针,判断pod(中的应用容器)是否健康
livenessProbe:
  periodSeconds: 5
  timeoutSeconds: 20
  successThreshold: 1
  failureThreshold: 3
# 就绪探针,pod就绪我们可以理解为这个pod可以接手请求和访问
readinessProbe:
  periodSeconds: 5
  timeoutSeconds: 20
  successThreshold: 3
  failureThreshold: 1

3.3 templates文件夹

templates 目录是实际的 k8s资源控制部署文件 (重点关注)
template文件夹下有warning-cm.yaml、 warning-deployment,.yaml、 warning-service.yaml
configMap用于统一管理配置信息,service用于对外提供服务,deployment用于部署pod及系统升级更新。

3.3.1 configmap.yaml

说明:configMap用于统一管理配置信息, 文件名可以不固定。但示例文件中kind的类型应为ConfigMap(重点关注)
示例:warningtool-cm.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Values.warningtool.fullname  }}
  namespace: {{ .Release.Namespace }}
data:
  application.properties: |
    server.port= 8089
    phones= xxxxxxxx,xxxxxxxx
    logging.level.root=INFO
    logging.file.name=./logs/warningtool.log
    logging.logback.rollingpolicy.max-file-size=50MB

参数详解:
name: 定义service名称 引用values.yaml定义的应用名称 namespace: 定义所在命名空间
application.properties: 类似于这种default.conf 这种 将配置挂载到cm,方便修改。包括端口、日志级别、日志生成路径等等

3.3.2 service.yaml

说明:Service可以看作是一组提供相同服务的Pod对外的访问接口。借助Service,应用可以方便地实现服务发现和负载均衡。
示例:warning-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: {{ .Values.warningtool.fullname  }}

# 通过spec.selector字段确定这个Service将要使用哪些Label。
# 在本例,这个名warning-service的Service,将会管理所有具有标签app: warningtool的Pod。  
spec:
  type: {{ .Values.service.type }}
  selector:
    app: warningtool
    version: warningtool-1.0.0
  ports:
    - port: 8089
      nodePort: {{ .Values.service.port }}
      targetPort: 8089
      protocol: TCP
      name: http

参数详解:
type: service类型 nodePort

有四种选项   1. ClusterIP 虚拟ip 集群内部访问 
              2.NodePort 将Service通过指定的Node上的端口暴露给外部
              3.LoadBalancer 在 NodePort 的基础上,借助 cloud provider 创建一个外部的负载均衡器 此模式只能在云服务器
              4.ExternalName 将服务通过 DNS CNAME 记录方式转发到指定的域名(通过 spec.externlName 设定)

selector: 需要和deployment的selector matchLabels保持一致,才能绑定到一起。(重点关注

参数

含义

port

kubernetes中的服务之间访问的端口

nodePort

外部机器可访问的端口。比如一个Web应用需要被其他用户访问,那么需要配置type=NodePort

targetPort

容器的端口(最根本的端口入口),与制作容器时暴露的端口一致(DockerFile中EXPOSE),例如docker.io官方的nginx暴露的是80端口。

3.3.3 deployment.yaml

说明:deployment用于部署pod及系统升级更新。
示例:warning-deployment.yaml

apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: {{ .Values.warningtool.fullname  }}
  namespace: {{ .Release.Namespace }}
  # deployment的标签 标签的键值对 app:warningtool
  labels:
    app: warningtool
    version: warningtool-1.0.0
spec:
  replicas: {{ .Values.warningtool.replicaCount }}
  # 与service里的selector的标签对应上才可以对外提供服务
  selector:
  # 和下面的labels一致,否则会直接报错:选择的和模板标签不匹配
    matchLabels:
      app: warningtool
      version: warningtool-1.0.0
  template:
    metadata:
    # 为即将新建的pod附加label
      labels:
        app: warningtool
        version: warningtool-1.0.0
    spec:
      containers:
        - name: {{ .Values.warningtool.fullname  }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          resources:
{{ toYaml .Values.resources | indent 12 }}
          ports:
            - name: http
              containerPort: 8089
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /healthcheck
              port: 8089
            initialDelaySeconds: {{ .Values.warningtool.liveinitialDelaySeconds }}
            periodSeconds: {{ .Values.livenessProbe.periodSeconds }}
            timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }}
            successThreshold: {{ .Values.livenessProbe.successThreshold }}
            failureThreshold: {{ .Values.livenessProbe.failureThreshold }}
          readinessProbe:
            httpGet:
              path: /healthcheck
              port: 8089
            initialDelaySeconds: {{ .Values.warningtool.readinitialDelaySeconds }}
            periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
            timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }}
            successThreshold: {{ .Values.readinessProbe.successThreshold }}
            failureThreshold: {{ .Values.readinessProbe.failureThreshold }}
          # 映射到容器的位置
          volumeMounts:
      {{- if .Values.hostPath.enabled }}
          - mountPath: /data
            name: data
      {{- end }}
          - name: config
            mountPath: /config/application.properties
            subPath: application.properties
          - name: log
            mountPath: /logs
      volumes:
      - name: config
        configMap:
          name: {{ .Values.warningtool.fullname  }}
      {{- if .Values.hostPath.enabled }}
      - name: data
        hostPath:
          path: {{ .Values.hostPath.path }}
          type: {{ .Values.hostPath.type }}
      - name: log
        hostPath:
          # 宿主机的目录
          path: /data/logs
          type: DirectoryOrCreate
      {{- end }}
{{- if .Values.nodeSelector }}
      # 指定pod分配到指定node节点,属于强制性的。如果我们的目标节点没有可用的资源,我们的pod就会一直处于Pending状态
      nodeSelector:
{{ toYaml .Values.nodeSelector | indent 8 }}
{{- end }}

参数详解都写在注释上了。需要注意的点

四、容器化部署

4.1 导入镜像

docker load -i  warningtool.tar

4.2 推送镜像

docker push registry.xxx.baidu.com/dev/warningtool:v1.0

4.3 查看镜像列表

docker images | grep warning

4.3 helm部署k8s应用

helm install warningtool -f values.yaml .

4.4 查看应用服务状态

kubectl get po | grep warning

以上就是从零开始进行docker镜像的制作和打包,制作Charts。使用helm方式部署到k8s集群。