准备工作
一个 Kubernetes 集群
理解 Docker 的基础知识
你可以在任何公共云提供商(例如:AWS ,Azure ,Google 云 或是 DigitalOcean 等)上配置 Kubernetes 集群。
要在 Kubernetes 上部署 PostgreSQL,我们需要执行以下步骤:
Postgres Docker 镜像
用于存储 Postgres 配置的 ConfigMap
持久化卷 Persistent Volume
PostgreSQL 的 k8s Deployment
PostgreSQL 的 k8s Service
PostgreSQL Docker 镜像
我们使用官方仓库中的 PostgreSQL 11.7 Docker 镜像。 该映像将提供提供 PostgreSQL 自定义配置/环境变量的功能,例如:用户名,密码,数据库名称和路径等。
配置 PostgreSQL 的 ConfigMap
我们将使用 ConfigMap 来存储 PostgreSQL 相关信息。 在这里,我们在配置映射中使用数据库,用户和密码,部署模板中的 PostgreSQL pod 将使用该数据库,用户和密码。
postgres-configmap.yaml:
1
2
3
4
5
6
7
8
9
10
11
apiVersion : v1
kind : ConfigMap
metadata :
name : postgres-config
labels :
app : postgres
namespace : dev
data :
POSTGRES_DB : postgresdb
POSTGRES_USER : postgresadmin
POSTGRES_PASSWORD : admin12345
Copy Copy 创建 Postgres ConfigMap 资源
1
$ kubectl create -f postgres-configmap.yaml configmap "postgres-config" created
Copy Copy 持久化卷 Persistent Storage Volume
众所周知 Docker 容器本质上是临时的。 容器实例终止后,由容器或容器中生成的所有数据都将丢失。
为了保存数据,我们将在 Kubernetes 中使用 Persistent Volume 和 Persistent Volume Claim 资源将数据存储在持久存储中。
在这里,我们使用本地目录/路径作为永久存储资源(/mnt/data)
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
kind : PersistentVolume
apiVersion : v1
metadata :
name : postgres-pv-volume
labels :
type : local
app : postgres
spec :
storageClassName : manual
capacity :
storage : 5Gi
accessModes :
- ReadWriteMany
hostPath :
path : '/data/localpvc'
---
kind : PersistentVolumeClaim
apiVersion : v1
metadata :
name : postgres-pv-claim
labels :
app : postgres
spec :
storageClassName : manual
accessModes :
- ReadWriteMany
resources :
requests :
storage : 5Gi
Copy Copy 如果你在使用 DigitalOcean ,那么你可能不需要 Persistent Volume,因为你的 k8s 中默认会有一个名为 do-block-storage 的 SC。
所以我们只需一个 PVC:
1
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: postgres-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 5Gi storageClassName : do-block-storage
Copy Copy PostgreSQL Deployment
用于 Deployment 的 PostgreSQL 容器使用 PostgreSQL 11.7 。 它使用 PostgreSQL 我们先前创建的 configmap 中的配置,例如:用户名,密码和数据库名称。 它还会挂载从持久卷创建的卷,并声明使 PostgreSQL 容器的数据持久化。
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
apiVersion : apps/v1
kind : Deployment
metadata :
name : postgres-deployment
spec :
strategy :
type : Recreate
selector :
matchLabels :
app : postgres
replicas : 1
template :
metadata :
labels :
app : postgres
spec :
containers :
- name : postgres
image : postgres:11.7
imagePullPolicy : 'IfNotPresent'
ports :
- containerPort : 5432
envFrom :
- configMapRef :
name : postgres-config
volumeMounts :
- mountPath : /var/lib/postgresql/data
name : postgredb
volumes :
- name : postgredb
persistentVolumeClaim :
claimName : postgres-pv-claim
Copy Copy PostgreSQL 版本选择
对于 Postgres 的版本选择,一般使用最新的大版本下面一号版本的最新 minor 版本。比如,目前本有:12.2、11.7、10.12 和 9.6.17。其中 9.6 的话还有一年就会停止维护,版本 10 将在 2022 年停止维护,以此类推。所以选择目前最高版本 12 下面一号版本 11 或者 10 将是我们的首选。参考
创建 Postgres deployment:
1
$ kubectl create -f postgres-deployment.yaml deployment "postgres" created
Copy Copy PostgreSQL Service
要访问部署或容器,我们需要暴露 PostgreSQL Deployment。 Kubernetes 提供了不同类型的服务,例如 ClusterIP,NodePort 和 LoadBalancer。
使用 ClusterIP,我们可以在 Kubernetes 中访问 PostgreSQL 服务。 NodePort 可以在 Kubernetes 节点上公开服务端点。 为了从外部访问 PostgreSQL,我们则需要使用一个 Load Balancer 服务类型,该服务类型可以在外部公开。
postgres-service.yaml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion : v1
kind : Service
metadata :
name : postgres-service
labels :
app : postgres
spec :
type : NodePort
ports :
- port : 5432
targetPort : 5432
protocol : TCP
selector :
app : postgres
Copy Copy 创建 Postgres Service:
1
$ kubectl create -f postgres-service.yaml service "postgres" created
Copy Copy 查看运行结果
1
$ kubectl get svc postgres NAME TYPE CLUSTER-IP EXTERNAL-IP PORT( S) AGE postgres-service NodePort 10.245.62.239 <none> 5432:32312/TCP 6h10m
Copy Copy 大功告成!
问题
如果遇到 Volume 挂在报错,先去看看 postgres 的日志。
如果遇到以下问题:
initdb: directory “/var/lib/postgresql/data” exists but is not empty If you want to create a new database system, either remove or empty the directory “/var/lib/postgresql/data” or run initdb with an argument other than “/var/lib/postgresql/data”.
说明你的 volume 里已经有其他文件了,这时候只要在挂在的文件夹中创建一个子文件夹就可以:
在 postgres-configmap.yaml 中添加:
1
- name: PGDATA value : /var/lib/postgresql/data/pgdata
Copy Copy PostgreSQL 就会使用 pgdata 这个子文件夹。