Khởi đầu
Trước khi bắt đầu, đảm bảo bạn đã thực hiện các bước sau:
- Chép kho lưu trữ
Postgres Operatorvà clone về máy địa phương. - Cài đặt
PGOvào không gian tênpostgres-operator. Nếu bạn đang ở thư mụcpostgres-operator-examples, chạy lệnhkubectl apply -k kustomize/install. - Tham khảo hướng dẫn chi tiết tại: PostgreSQL bản thân đám mây - PGO CrunchyData: 5 phút cài đặt nhanh.
Tutorial này sử dụng ví dụ từ thư mục kustomize/postgres.
Khi tham chiếu đến các đối tượng lồng nhau trong tệp YAML, chúng ta sẽ sử dụng định dạng . tương tự như kubectl explain. Ví dụ, nếu chúng ta muốn truy cập phần sâu nhất của tệp YAML sau:
spec:
hippos:
appetite: huge
Chúng ta sẽ nói là spec.hippos.appetite.
kubectl explain là công cụ hữu ích. Bạn có thể dùng kubectl explain postgrescluster để khám phá định nghĩa tài nguyên tùy chỉnh postgrescluster.postgres-operator.crunchydata.com. Bạn cũng có thể xem tài liệu tham khảo CRD.
Tạo cụm Postgres
Tạo cụm Postgres rất đơn giản. Sử dụng ví dụ trong thư mục kustomize/postgres, bạn chỉ cần chạy:
kubectl apply -k kustomize/postgres
PGO sẽ tạo một cụm Postgres tên là hippo trong không gian tên postgres-operator. Bạn có thể theo dõi trạng thái cụm bằng lệnh:
kubectl -n postgres-operator describe postgresclusters.postgres-operator.crunchydata.com hippo
Dùng lệnh sau để theo dõi trạng thái Pod Postgres:
--selector=postgres-operator.crunchydata.com/cluster=hippo,postgres-operator.crunchydata.com/instance
Điều gì vừa xảy ra?
PGO đã tạo cụm Postgres dựa trên các tài nguyên Kustomize trong thư mục kustomize/postgres. Để hiểu rõ hơn, hãy xem tệp kustomize/postgres/postgres.yaml:
apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PostgresCluster
metadata:
name: hippo
spec:
image: registry.developers.crunchydata.com/crunchydata/crunchy-postgres:centos8-13.5-0
postgresVersion: 13
instances:
- name: instance1
dataVolumeClaimSpec:
accessModes:
- "ReadWriteOnce"
resources:
requests:
storage: 1Gi
backups:
pgbackrest:
image: registry.developers.crunchydata.com/crunchydata/crunchy-pgbackrest:centos8-2.36-0
repos:
- name: repo1
volume:
volumeClaimSpec:
accessModes:
- "ReadWriteOnce"
resources:
requests:
storage: 1Gi
Khi chạy lệnh kubectl apply, bạn đã tạo tài nguyên tùy chỉnh PostgresCluster trong Kubernetes. PGO phát hiện tài nguyên mới và bắt đầu tạo tất cả đối tượng cần thiết để chạy Postgres trong Kubernetes!
Điều gì còn nữa? PGO lấy tên cụm từ metadata.name và xác định hình ảnh container sử dụng từ spec.image và spec.backups.pgbackrest.image. Giá trị spec.postgresVersion rất quan trọng vì nó giúp PGO theo dõi phiên bản chính của Postgres bạn đang sử dụng.
PGO biết số lượng instance Postgres cần tạo qua phần spec.instances. Mặc dù tên là tùy chọn, nhưng chúng ta đặt là instance1. Chúng ta có thể tạo nhiều bản sao và instance khi khởi tạo cụm, nhưng sẽ nói thêm về việc mở rộng cụm HA Postgres sau.
Một phần quan trọng trong tài nguyên tùy chỉnh PostgresCluster là dataVolumeClaimSpec. Phần này mô tả lưu trữ sẽ được sử dụng bởi instance Postgres của bạn, được xây dựng dựa trên PersistentVolumeClaim. Nếu bạn không cung cấp spec.instances.dataVolumeClaimSpec.storageClassName, Kubernetes sẽ dùng lớp lưu trữ mặc định.
Kết nối đến cụm Postgres
Tạo cụm Postgres là một việc, kết nối là việc khác. Hãy xem PGO làm thế nào để kết nối tới cụm Postgres!
Phía sau: Services, Secrets và TLS
PGO tạo ra một loạt service Kubernetes để cung cấp endpoint ổn định để kết nối tới cơ sở dữ liệu Postgres của bạn. Các endpoint này giúp ứng dụng của bạn dễ dàng duy trì kết nối với dữ liệu. Để kiểm tra các service có sẵn, bạn có thể chạy lệnh:
kubectl -n postgres-operator get svc --selector=postgres-operator.crunchydata.com/cluster=hippo
Kết quả sẽ trông giống như:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hippo-ha ClusterIP 10.103.73.92 <none> 5432/TCP 3h14m
hippo-ha-config ClusterIP None <none> <none> 3h14m
hippo-pods ClusterIP None <none> <none> 3h14m
hippo-primary ClusterIP None <none> 5432/TCP 3h14m
hippo-replicas ClusterIP 10.98.110.215 <none> 5432/TCP 3h14m
Bạn không cần quan tâm đến hầu hết các service này vì chúng hỗ trợ quản lý tổng thể trạng thái sức khỏe của cụm Postgres. Service quan trọng để kết nối là hippo-primary. Nhờ PGO, bạn thậm chí không cần lo lắng điều này vì thông tin được lưu trữ trong Secret!
Khi khởi tạo cụm Postgres, PGO sẽ tạo tài khoản người dùng và cơ sở dữ liệu mà ứng dụng có thể truy cập. Thông tin này được lưu trữ trong Secret có tên theo dạng <clusterName>-pguser-<userName>. Đối với cụm hippo, Secret này mang tên hippo-pguser-hippo. Secret này chứa thông tin cần thiết để kết nối ứng dụng tới cơ sở dữ liệu Postgres:
user: Tên tài khoản người dùng.password: Mật khẩu tài khoản người dùng.dbname: Tên cơ sở dữ liệu mà người dùng có quyền truy cập.host: Tên máy chủ cơ sở dữ liệu. Tham chiếu tới service của instance Postgres chính.port: Cổng mà cơ sở dữ liệu đang lắng nghe.uri: URI kết nối PostgreSQL chứa toàn bộ thông tin đăng nhập.jdbc-uri: URI JDBC kết nối PostgreSQL chứa toàn bộ thông tin đăng nhập qua driver JDBC.
Tất cả kết nối đều đi qua TLS. PGO cung cấp chứng chỉ CA riêng để cho phép bạn kết nối an toàn ứng dụng tới cụm Postgres. Điều này cho phép bạn sử dụng chế độ SSL "verify-full" của Postgres, giúp bảo vệ chống lại việc nghe lén và tấn công MITM. Bạn cũng có thể chọn sử dụng CA của riêng mình, phần này sẽ được thảo luận trong phần "Cụm tùy chỉnh" sau.
Thay đổi kiểu Service
Mặc định, PGO triển khai service với kiểu ClusterIP. Tùy thuộc vào cách bạn muốn mở rộng cơ sở dữ liệu, bạn có thể cần thay đổi service để sử dụng kiểu service khác.
Bạn có thể thay đổi các service do PGO quản lý thông qua các thuộc tính sau:
spec.service- Quản lý service để kết nối tới máy chủ Postgres chính.spec.proxy.pgBouncer.service- Quản lý service để kết nối tới pool kết nối PgBouncer.
Ví dụ, để thiết lập service cho node chính Postgres sử dụng kiểu NodePort, bạn có thể thêm đoạn sau vào tệp:
spec:
service:
type: NodePort
Với cụm hippo của chúng ta, bạn sẽ chạy:
kubectl -n postgres-operator get svc --selector=postgres-operator.crunchydata.com/cluster=hippo
Kết quả sẽ tương tự:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hippo-ha NodePort 10.96.17.210 <none> 5432:32751/TCP 2m37s
hippo-ha-config ClusterIP None <none> <none> 2m37s
hippo-pods ClusterIP None <none> <none> 2m37s
hippo-primary ClusterIP None <none> 5432/TCP 2m37s
hippo-replicas ClusterIP 10.96.151.53 <none> 5432/TCP 2m37s
(Lưu ý rằng nếu bạn mở rộng service ra ngoài và phụ thuộc vào xác thực TLS, bạn sẽ cần sử dụng tính năng TLS tùy chỉnh của PGO).
Kết nối ứng dụng
Trong tutorial này, chúng ta sẽ kết nối Keycloak, một ứng dụng quản lý danh tính mã nguồn mở. Keycloak có thể triển khai trên Kubernetes và được hỗ trợ bởi cơ sở dữ liệu Postgres. Mặc dù chúng tôi cung cấp ví dụ triển khai Keycloak và PostgresCluster trong kho lưu trữ Postgres Operator, đoạn mã dưới đây sẽ sử dụng cụm hippo mà chúng ta đã chạy để triển khai nó:
kubectl apply --filename=- <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: keycloak
namespace: postgres-operator
labels:
app.kubernetes.io/name: keycloak
spec:
selector:
matchLabels:
app.kubernetes.io/name: keycloak
template:
metadata:
labels:
app.kubernetes.io/name: keycloak
spec:
containers:
- image: quay.io/keycloak/keycloak:latest
name: keycloak
env:
- name: DB_VENDOR
value: "postgres"
- name: DB_ADDR
valueFrom: { secretKeyRef: { name: hippo-pguser-hippo, key: host } }
- name: DB_PORT
valueFrom: { secretKeyRef: { name: hippo-pguser-hippo, key: port } }
- name: DB_DATABASE
valueFrom: { secretKeyRef: { name: hippo-pguser-hippo, key: dbname } }
- name: DB_USER
valueFrom: { secretKeyRef: { name: hippo-pguser-hippo, key: user } }
- name: DB_PASSWORD
valueFrom: { secretKeyRef: { name: hippo-pguser-hippo, key: password } }
- name: KEYCLOAK_USER
value: "admin"
- name: KEYCLOAK_PASSWORD
value: "admin"
- name: PROXY_ADDRESS_FORWARDING
value: "true"
ports:
- name: http
containerPort: 8080
- name: https
containerPort: 8443
readinessProbe:
httpGet:
path: /auth/realms/master
port: 8080
restartPolicy: Always
EOF
</code>
Lưu ý phần sau trong đoạn mã:
- name: DB_ADDR
valueFrom: { secretKeyRef: { name: hippo-pguser-hippo, key: host } }
- name: DB_PORT
valueFrom: { secretKeyRef: { name: hippo-pguser-hippo, key: port } }
- name: DB_DATABASE
valueFrom: { secretKeyRef: { name: hippo-pguser-hippo, key: dbname } }
- name: DB_USER
valueFrom: { secretKeyRef: { name: hippo-pguser-hippo, key: user } }
- name: DB_PASSWORD
valueFrom: { secretKeyRef: { name: hippo-pguser-hippo, key: password } }
Đoạn mã trên cho thấy tất cả các giá trị này được trích xuất từ Secret hippo-pguser-hippo. Điều này có nghĩa là bạn không cần biết bất kỳ thông tin kết nối nào, cũng không cần truyền chúng một cách không an toàn — chúng sẵn sàng cho ứng dụng sử dụng!
Với phương pháp này, bạn có thể kết nối trực tiếp ứng dụng của mình với pipeline GitOps để kết nối tới Postgres mà không cần biết trước PGO sẽ triển khai Postgres như thế nào: Tất cả thông tin cần thiết cho ứng dụng của bạn sẽ được truyền đến Secret!
Xóa cụm Postgres
Đôi khi bạn cần xóa cụm của mình. Nếu bạn đã làm theo ví dụ chính thức, bạn có thể xóa cụm Postgres bằng cách chạy lệnh sau:
kubectl delete -k kustomize/postgres
PGO sẽ xóa tất cả đối tượng liên quan đến cụm của bạn.
Việc giữ lại dữ liệu phụ thuộc vào chính sách lưu trữ PVC của bạn. Để biết thêm thông tin về cách Kubernetes quản lý việc giữ lại dữ liệu, xem tài liệu về thu hồi khối lượng lưu trữ của Kubernetes.