PostgreSQL bản thân đám mây - Hướng dẫn PGO CrunchyData: Tạo, kết nối và xóa cụm Postgres

Khởi đầu

Trước khi bắt đầu, đảm bảo bạn đã thực hiện các bước sau:

  1. Chép kho lưu trữ Postgres Operator và clone về máy địa phương.
  2. Cài đặt PGO vào không gian tên postgres-operator. Nếu bạn đang ở thư mục postgres-operator-examples, chạy lệnh kubectl apply -k kustomize/install.
  3. 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.imagespec.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 PostgresClusterdataVolumeClaimSpec. 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 KeycloakPostgresCluster 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.

Thẻ: PostgreSQL CrunchyData PGO Kubernetes Kustomize pgBackRest

Đăng vào ngày 17 tháng 7 lúc 22:51