k8s是一个容器应用的基础运行环境,那么对于初学者来说,如何在k8s上部署自己的应用呢?本文介绍几种最简单的,适合初学者了解部署过程的几种方法:

  • 通过kubectl apply直接部署
  • 通过helm部署
    kubectl apply适合部署单个Pod,如果Pod较多,部署结构比较复杂,就需要使用编排来实现。Helm是当下最适合做K8s应用部署的编排工具,通过Helm可以声明一组Pod,由一个Helm包部署一整个应用程序。

本文不介绍Helm的安装了,大家可以自行搜索。

通过Helm部署应用

创建Helm包

~ helm create jflyfox
Creating jflyfox

helm 包中的目录结构如下:
jflyfox/
├── .helmignore   # Contains patterns to ignore when packaging Helm charts.
├── Chart.yaml    # Information about your chart
├── values.yaml   # The default values for your templates
├── charts/       # Charts that this chart depends on
└── templates/    # The template files
    └── tests/    # The test files

直接删除templates中的所有文件(一般是没用的测试文件或者demo),直接创建自己的template即可。

声明DB

~ touch templates/db.yaml
apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  ports:
  - port: 3306
  selector:
    app: mysql
  clusterIP: None
---
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: mysql
spec:
  selector:
    matchLabels:
      app: mysql
  replicas: 1
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - image: mysql:5.6
        name: mysql
        imagePullPolicy: Always
        env:
          # Use secret in real usage
        - name: MYSQL_ROOT_PASSWORD
          value: password
        resources:
          limits:
            cpu: "1"
            memory: 512Mi
          requests:
            cpu: "1"
            memory: 512Mi
        ports:
        - containerPort: 3306
          name: mysql

如上所示,该template用来创建一个mysql,并通过service代理。

声明tomcat

再创建一个tomcat,如下:

web的部署包含以下镜像:

  1. jflyfox-db: 这个镜像里只包含数据库脚本
  2. jflyfox-web: 这个镜像里只包含war文件
  3. busy-box: 用来执行shell命令
  4. mysql : 用来执行sql初始化
  5. tomcat: 用来运行war包程序

web部署还包含两个共享的volume,即app-volume和db-volume,这两个volume都是用空目录声明的,只是为了实现tomcat容器和mysql容器能够读取到jflyfox-db和jflyfox-web中的数据库文件和war文件。

web的部署过程:

  1. 执行initContainer容器:

    1. sql-copy: 拷贝sql文件到共享目录
    2. web-init : 拷贝war包到共享目录
    3. init-mysql: 等待mysql服务启动(由db.yaml启动的pod)
    4. sql-init : 执行初始化sql
  2. 启动tomcat容器
~ touch templates/web.yaml
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: web
  replicas: 1
  template:
    metadata:
      labels:
        app: web
    spec:
      initContainers:
      - image: registry.bingosoft.net/cmp/jfyfox-db:1.0
        name: sql-copy
        resources:
          limits:
            cpu: "0.5"
            memory: 256Mi
          requests:
            cpu: "0.5"
            memory: 256Mi
        command: ['cp','/install/mysql.sql','/data']
        volumeMounts:
        - mountPath: /data
          name: db-volume
      - image: registry.bingosoft.net/cmp/jflyfox-web:2.0
        name: web-init
        resources:
          limits:
            cpu: "0.5"
            memory: 256Mi
          requests:
            cpu: "0.5"
            memory: 256Mi
        command: ['cp','/install/jflyfox.war','/app']
        volumeMounts:
        - mountPath: /app
          name: app-volume
      - name: init-mysql
        image: busybox:1.31
        resources:
          limits:
            cpu: "0.5"
            memory: 256Mi
          requests:
            cpu: "0.5"
            memory: 256Mi
        command: ['sh', '-c', 'until nslookup mysql; do echo waiting for mysql; sleep 2; done;']
      - image: mysql:5.6
        name: sql-init
        resources:
          limits:
            cpu: "0.5"
            memory: 256Mi
          requests:
            cpu: "0.5"
            memory: 256Mi
        command: ['sh','-c','mysql -u root -h mysql -ppassword  < /data/mysql.sql']
        volumeMounts:
        - mountPath: /data
          name: db-volume
      containers:
      - image: registry.bingosoft.net/library/tomcat:8-jdk8
        name: tomcat
        imagePullPolicy: Always
        resources:
          limits:
            cpu: "1"
            memory: 512Mi
          requests:
            cpu: "1"
            memory: 512Mi
        volumeMounts:
        - mountPath: /usr/local/tomcat/webapps
          name: app-volume
        ports:
        - containerPort: 8080
      volumes:
      - name: app-volume
        emptyDir: {}
      - name: db-volume
        emptyDir: {}

Helm 打包

yaml编写完成后,需要打包为helm包:

~ helm package jflyfox
jflyfox-0.1.0.tgz

Helm部署

~ helm install jflyfox-0.1.0.tgz jflyfox
WARNING: Kubernetes configuration file is group-readable. This is insecure. Location: /Users/jason/.kube/config
WARNING: Kubernetes configuration file is world-readable. This is insecure. Location: /Users/jason/.kube/config
NAME: jflyfox-0.1.0.tgz
LAST DEPLOYED: Thu Jun 17 14:26:39 2021
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None

各位可以参考这个最简单的web应用的部署思路,准备sql包和war包,开始k8s的的第一个容器部署吧!

常见问题

  1. 数据库为什么不做持久化?

    这里只是一个入门demo,主要解释如何实现一个最简单的web应用的部署,不是生产级别的应用部署方案,不引入太复杂的内容。

  2. tomcat和war包为什么不放在一起?

    一般war包是经常变化的,tomcat是一直不变的,做成两个容器镜像的好处是应用镜像足够小,不需要冗余文件。并且通过镜像管理war包,可以很好的建立版本管理。

  3. 部署helm的时候出现错误:missing key "meta.helm.sh/release-name": must be set to

    一般是由于当前namespace下有冲突的资源,例如service,deployment,或者pod,清理掉再试,或者创建一个全新的命名空间用来部署。


行愚
13 声望2 粉丝