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的部署包含以下镜像:
- jflyfox-db: 这个镜像里只包含数据库脚本
- jflyfox-web: 这个镜像里只包含war文件
- busy-box: 用来执行shell命令
- mysql : 用来执行sql初始化
- tomcat: 用来运行war包程序
web部署还包含两个共享的volume,即app-volume和db-volume,这两个volume都是用空目录声明的,只是为了实现tomcat容器和mysql容器能够读取到jflyfox-db和jflyfox-web中的数据库文件和war文件。
web的部署过程:
执行initContainer容器:
- sql-copy: 拷贝sql文件到共享目录
- web-init : 拷贝war包到共享目录
- init-mysql: 等待mysql服务启动(由db.yaml启动的pod)
- sql-init : 执行初始化sql
- 启动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的的第一个容器部署吧!
常见问题
数据库为什么不做持久化?
这里只是一个入门demo,主要解释如何实现一个最简单的web应用的部署,不是生产级别的应用部署方案,不引入太复杂的内容。
tomcat和war包为什么不放在一起?
一般war包是经常变化的,tomcat是一直不变的,做成两个容器镜像的好处是应用镜像足够小,不需要冗余文件。并且通过镜像管理war包,可以很好的建立版本管理。
部署helm的时候出现错误:
missing key "meta.helm.sh/release-name": must be set to
一般是由于当前namespace下有冲突的资源,例如service,deployment,或者pod,清理掉再试,或者创建一个全新的命名空间用来部署。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。