在K8S上部署Web与数据库应用
数据库的搭建,选择Postgresql 11.15版本下载镜像docker pull postgres:11.15-alpine3.15在主机上设置一个PG的数据目录mkdir ~/pg_data运行PG镜像测试docker run --name my_postgres -v /home/roy/data/pg_volume:/var/lib/postgresql/data -e POSTGRES
K8S简化了应用的部署和维护工作,我以一个简单的应用为例子,试验如何在K8S来进行部署。
这个应用很简单,包括了一个Web的Rest接口以及一个PG的数据库。Rest接口返回数据库的查询结果。
PG数据库的搭建
数据库的搭建,选择Postgresql 11.15版本
下载镜像
docker pull postgres:11.15-alpine3.15
在主机上设置一个PG的数据目录
mkdir ~/pg_data
运行PG镜像测试
docker run --name my_postgres -v /home/roy/data/pg_volume:/var/lib/postgresql/data -e POSTGRES_PASSWORD=roy2000 -p 5555:5432 -d postgres:11.15-alpine3.15
之后连接本地的5555端口即可访问
psql -h 127.0.0.1 -p 5555 -U postgres
测试完成后,我们考虑如何在K8S上进行部署。数据库是一个有状态的应用,当数据库的Pod出现问题失败时,K8S会自动调度一个新的Pod,但是我们不能丢失原有的数据,因此需要把数据库的文件存储在PV上。我在本地搭建了一个NFS服务,把PV mount在NFS的文件路径上。
以下是创建PV的pv-volume.yaml文件,运行kubectl apply -f pv-volume.yaml来建立一个PV
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv01
labels:
type: local
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
nfs:
path: /nfsroot/data
server: 192.168.0.105
建立一个deployment的yaml文件,来进行PG的部署Deployment.yaml,在deployment里面,指定了数据库的名称,用户名,密码需要从configmap里面获取。
apiVersion: v1
kind: Service
metadata:
name: myweb-pg
labels:
app: myweb
spec:
ports:
- port: 5555
targetPort: pg
selector:
app: myweb
tier: pg
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pg-pv-claim
labels:
app: myweb
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: myweb-pg
labels:
app: myweb
spec:
selector:
matchLabels:
app: myweb
tier: pg
strategy:
type: Recreate
template:
metadata:
labels:
app: myweb
tier: pg
spec:
containers:
- image: postgres:11.15-alpine3.15
name: pg11
env:
- name: POSTGRES_DB
valueFrom:
configMapKeyRef:
name: postgres-config
key: POSTGRES_DB
- name: POSTGRES_USER
valueFrom:
configMapKeyRef:
name: postgres-config
key: POSTGRES_USER
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: pg-pass
key: password
ports:
- containerPort: 5432
name: pg
volumeMounts:
- name: pg-persistent-storage
mountPath: /var/lib/postgresql/data
volumes:
- name: pg-persistent-storage
persistentVolumeClaim:
claimName: pg-pv-claim
建立一个kustomization.yaml,里面定义了PG的配置信息,运行kubectl apply -k ./来创建
secretGenerator:
- name: pg-pass
literals:
- password=YOUR_PASSWORD
resources:
- pg_deployment.yaml
Deployment创建了之后,运行kubectl get svc来查看创建的service, 然后连接这个service的IP:5555端口测试,例如运行指令psql -h serviceIP -p 5555 -U username -d databasename
Web应用的搭建
搭建一个web应用,提供一个REST接口,查询数据库的内容。
这里我选择了Quarkus这个微服务,可以参考quarkus.io官网,里面有很详细的教程。我的代码可见仓库gzroy/products:
这里有一点需要提到的,在这个代码中,我是选择了Quarkus reactive的方式来构建一个异步的接口,然后用flyway来进行数据库的初始化。因为reactive方式和flyway方式指定的数据库连接方式不同,不能并存,因此需要做一些改动。以下是application.properties的设定,这里只能设定quarkus.datasource.reactive.url,不能同时设定datasource.jdbc.url。并且datasource.jdbc需要设置为false。在reactive.url里面设定的是我们刚才K8S里面建立的PG数据库的service的名称
quarkus.datasource.db-kind=postgresql
quarkus.hibernate-orm.database.generation=drop-and-create
quarkus.http.port=9090
quarkus.datasource.reactive.url=postgresql://myweb-pg.default.svc.cluster.local:5555/products
quarkus.datasource.username=abc
quarkus.datasource.password=12345
quarkus.flyway.migrate-at-start=false
quarkus.datasource.jdbc=false
quarkus.flyway.baseline-on-migrate=true
另外需要新建一个service来在应用开始出发flyway的migrate,如以下代码:
@ApplicationScoped
public class FlywayMigrationService {
@ConfigProperty(name = "quarkus.datasource.reactive.url")
String datasourceUrl;
@ConfigProperty(name = "quarkus.datasource.username")
String datasourceUsername;
@ConfigProperty(name = "quarkus.datasource.password")
String datasourcePassword;
public void runFlywayMigration(@Observes StartupEvent event) {
Flyway flyway = Flyway.configure().dataSource("jdbc:" + datasourceUrl, datasourceUsername, datasourcePassword).load();
flyway.clean();
flyway.migrate();
}
}
编译代码并打包为docker镜像。然后建立一个web_deploymen.yaml:
apiVersion: v1
kind: Service
metadata:
name: myweb-backend
labels:
app: myweb
spec:
ports:
- port: 9090
targetPort: product
selector:
app: myweb
tier: backend
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: myweb-backend
labels:
app: myweb-backend
spec:
selector:
matchLabels:
app: myweb
tier: backend
strategy:
type: Recreate
template:
metadata:
labels:
app: myweb
tier: backend
spec:
containers:
- image: quarkus/products-jvm:latest
name: product
imagePullPolicy: Never
ports:
- containerPort: 9090
name: product
修改一下kustomization.yaml,把这个新的deployment加进去:
secretGenerator:
- name: pg-pass
literals:
- password=XXXXXX
configMapGenerator:
- name: postgres-config
literals:
- POSTGRES_DB=products
- POSTGRES_USER=roy
resources:
- pg_deployment.yaml
- web_deployment.yaml
最后运行kubectl apply -k ./,用kubectl get svc查看新建的web service,然后curl http://serviceIP:9090/products,即可看到返回结果。
更多推荐
所有评论(0)