部署数据库Portgres到Kubernetes

之前我们已成功安装了kubernetes,现在可以部署我们的应用服务。我们在安装ingres前先部署Portgres数据库,数据库被要求不能被外网访问并且大多数应用服务都会依赖数据库。这里需要注意的一点是数据库的数据不能丢失,所有我们需要使用持久化卷(persistent volumes)。

创建Namespace

编写00-namespace.yaml

1
2
3
4
5
6
apiVersion: v1
kind: Namespace
metadata:
name: db
labels:
name: db

运行命令创建 kubectl create -f 00-namespace.yaml

创建PV/PVC

编写01-postgres-pv.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
apiVersion: v1
kind: PersistentVolume
metadata:
name: db-postgres-pv
namespace: db
spec:
capacity:
storage: 5Gi
# volumeMode field requires BlockVolume Alpha feature gate to be enabled.
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
storageClassName: local-storage
local:
path: /data
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- node01

kubernetes支持多种PV,由于我本机没有额外的存储服务(nfs service/cefs …),所以我选择使用local方式,也就是storageClassName: local-storage。这种方式需要指定节点和挂载目录,并需要提前将目录准备好。如上例子中被指定到node01接点的/data目录。

运行命令创建 kubectl create -f 01-postgres-pv.yaml

创建后可使用kubectl get pv -n db查看

1
2
3
# kubectl get pv -n db
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
db-postgres-pv 5Gi RWO Delete Bound local-storage 1d

编写02-postgres-pvc.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: db-postgres-pvc-postgres-0
namespace: db
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 5Gi
storageClassName: local-storage

注意:pvc的命名是有一定规则的,否则就无法将PV与PVC关系起来,关联成功后PV的CLAIM值是对应的namespace/PVC名称。

运行命令创建 kubectl create -f 02-postgres-pvc.yaml

创建后可使用kubectl get pvc -n db查看

1
2
3
4
5
6
7
# kubectl get pv -n db
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
db-postgres-pv 5Gi RWO Delete Bound db/db-postgres-pvc-postgres-0 local-storage 1d

# kubectl get pvc -n db
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
db-postgres-pvc-postgres-0 Bound db-postgres-pv 5Gi RWO local-storage 1d

创建Portgres服务

编写03-postgres-statefulset.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
apiVersion: v1
kind: Service
metadata:
name: postgres
namespace: db
labels:
svc: postgres
spec:
ports:
- port: 5432
targetPort: 5432
protocol: TCP
name: postgres
selector:
svc: postgres
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres
namespace: db
spec:
selector:
matchLabels:
svc: postgres # has to match .spec.template.metadata.labels
serviceName: "postgres"
replicas: 1 # by default is 1
template:
metadata:
labels:
svc: postgres # has to match .spec.selector.matchLabels
spec:
terminationGracePeriodSeconds: 10
containers:
- name: postgres
image: postgres:10.3-alpine
env:
- name: POSTGRES_USER
value: "postgres"
- name: POSTGRES_PASSWORD
value: "password"
- name: PGDATA
value: "/var/lib/postgresql/data"
ports:
- containerPort: 5432
name: postgres
protocol: TCP
volumeMounts:
- name: db-postgres-pvc
mountPath: /var/lib/postgresql/data
volumeClaimTemplates:
- metadata:
name: db-postgres-pvc
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "local-storage"
resources:
requests:
storage: 5Gi

创建了集群内部访问的Service, 使用StatefulSet创建带状态的服务类型,服务使用了本地PV,Portgres服务只会在node01节点运行。参数replicas: 1指定副本数,这里设置1就好,如果想达到多副本,使用数据库本身的集群方式搭建。

运行命令创建 kubectl create -f 03-postgres-statefulset.yaml

OK, 我们登陆UI界面查看服务运行状况。

访问Portgres

Portgres的Service类型只能在集群内部访问,访问方式:postgres.db:5432 (service.namespace:port)。如果想外部访问你可以修改service类型或使用Ingress实现,但这里我们不想外部能访问到数据库。

不过这里可以使用proxy临时访问到集群内部服务:kubectl port-forward postgres-0 -n db 5434:5432