{"id":113738,"date":"2024-10-11T13:58:29","date_gmt":"2024-10-11T04:58:29","guid":{"rendered":"https:\/\/avinton.com\/?p=113738"},"modified":"2024-10-17T17:11:51","modified_gmt":"2024-10-17T08:11:51","slug":"postgresql-operator-on-kubernetes","status":"publish","type":"post","link":"https:\/\/avinton.com\/en\/blog\/2024\/10\/postgresql-operator-on-kubernetes\/","title":{"rendered":"PostgreSQL Operator on Kubernetes"},"content":{"rendered":"<div class=\"wpb-content-wrapper\"><p>[vc_row][vc_column][vc_custom_heading text=&#8221;Running PostgreSQL on Kubernetes&#8221; use_theme_fonts=&#8221;yes&#8221; el_class=&#8221;header2&#8243;][\/vc_column][\/vc_row][vc_row][vc_column width=&#8221;1\/2&#8243;][vc_row_inner][vc_column_inner][vc_column_text]<img decoding=\"async\" class=\"size-thumbnail wp-image-113918 aligncenter\" src=\"https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/postgre-sql-162x167.png\" alt=\"posgresql\" width=\"162\" height=\"167\" srcset=\"https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/postgre-sql-162x167.png 162w, https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/postgre-sql.png 174w\" sizes=\"(max-width: 162px) 100vw, 162px\" \/>[\/vc_column_text][\/vc_column_inner][\/vc_row_inner][\/vc_column][vc_column width=&#8221;1\/2&#8243;][vc_row_inner][vc_column_inner][vc_column_text]<img decoding=\"async\" class=\"size-thumbnail wp-image-113969 aligncenter\" src=\"https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/kubernetes-1-172x167.png\" alt=\"kubernetes\" width=\"172\" height=\"167\" srcset=\"https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/kubernetes-1-172x167.png 172w, https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/kubernetes-1-300x292.png 300w, https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/kubernetes-1.png 926w\" sizes=\"(max-width: 172px) 100vw, 172px\" \/>[\/vc_column_text][\/vc_column_inner][\/vc_row_inner][\/vc_column][\/vc_row][vc_row][vc_column][vc_column_text]Recently, there are more use cases to run <em data-sourcepos=\"9:43-9:54\">PostgreSQL<\/em> on <em data-sourcepos=\"9:59-9:70\">Kubernetes<\/em>. One of the main reason of this is to leverage <em data-sourcepos=\"9:119-9:130\">Kubernetes<\/em>&#8216;s scalability and self-healing to run <em data-sourcepos=\"9:170-9:181\">PostgreSQL<\/em>. <a href=\"https:\/\/www.timescale.com\/state-of-postgres\/2023\" target=\"_blank\" rel=\"nofollow noreferrer noopener\" data-sourcepos=\"9:185-9:267\">The survey by Timescale in 2023<\/a> shows that there are some amounts of users who deploy <em data-sourcepos=\"9:323-9:334\">PostgreSQL<\/em> on <em data-sourcepos=\"9:339-9:350\">Kubernetes<\/em>. People still uses <em data-sourcepos=\"9:371-9:382\">Helm chart<\/em> to deploy <em data-sourcepos=\"9:394-9:405\">PostgreSQL<\/em> on <em data-sourcepos=\"9:410-9:421\">Kubernetes<\/em> (like us), but more recently they are shifting to use <em data-sourcepos=\"9:477-9:486\">Operator<\/em>.<\/p>\n<p>Reference: <a href=\"https:\/\/www.timescale.com\/state-of-postgres\/2023\" target=\"_blank\" rel=\"nofollow noreferrer noopener\" data-sourcepos=\"11:12-11:94\">The survey by Timescale in 2023<\/a><\/p>\n<p><img decoding=\"async\" class=\"aligncenter wp-image-113924 size-full\" src=\"https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/2023-timescale-k8s-postgre.jpg\" alt=\"2023-timescale-k8s-postgre\" width=\"586\" height=\"415\" srcset=\"https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/2023-timescale-k8s-postgre.jpg 586w, https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/2023-timescale-k8s-postgre-1-300x212.jpg 300w, https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/2023-timescale-k8s-postgre-1-236x167.jpg 236w\" sizes=\"(max-width: 586px) 100vw, 586px\" \/><\/p>\n<p>In this article, we explore various <em data-sourcepos=\"14:37-14:57\">PostgreSQL Operator<\/em> on <em data-sourcepos=\"14:62-14:73\">Kubernetes<\/em>.[\/vc_column_text][vc_custom_heading text=&#8221;PostgreSQL Operator&#8221; use_theme_fonts=&#8221;yes&#8221; el_class=&#8221;header2&#8243;][vc_column_text]<\/p>\n<p dir=\"auto\" data-sourcepos=\"18:1-18:89\">We&#8217;ve investigated these 6 operators which are popular on <em data-sourcepos=\"18:59-18:66\">GitHub<\/em> or <em data-sourcepos=\"18:71-18:78\">GitLab<\/em> as OSS.<\/p>\n<ul dir=\"auto\" data-sourcepos=\"19:1-24:0\">\n<li data-sourcepos=\"19:1-19:83\"><a href=\"https:\/\/github.com\/CrunchyData\/postgres-operator\" target=\"_blank\" rel=\"nofollow noreferrer noopener\" data-sourcepos=\"19:3-19:83\">CrunchyData\/postgres-operator<\/a><\/li>\n<li data-sourcepos=\"20:1-20:68\"><a href=\"https:\/\/github.com\/cloudnative-pg\/cloudnative-pg\" target=\"_blank\" rel=\"nofollow noreferrer noopener\" data-sourcepos=\"20:3-20:68\">cloudnative-pg<\/a><\/li>\n<li data-sourcepos=\"21:1-21:75\"><a href=\"https:\/\/github.com\/zalando\/postgres-operator\" target=\"_blank\" rel=\"nofollow noreferrer noopener\" data-sourcepos=\"21:3-21:75\">zalando\/postgres-operator<\/a><\/li>\n<li data-sourcepos=\"22:1-22:55\"><a href=\"https:\/\/github.com\/reactive-tech\/kubegres\" target=\"_blank\" rel=\"nofollow noreferrer noopener\" data-sourcepos=\"22:3-22:55\">kubegres<\/a><\/li>\n<li data-sourcepos=\"23:1-24:0\"><a href=\"https:\/\/github.com\/ongres\/stackgres\" target=\"_blank\" rel=\"nofollow noreferrer noopener\" data-sourcepos=\"23:3-23:49\">stackers<\/a><\/li>\n<\/ul>\n<p dir=\"auto\" data-sourcepos=\"25:1-25:47\">We tested each operator by following aspects:<\/p>\n<ul dir=\"auto\" data-sourcepos=\"26:1-32:0\">\n<li data-sourcepos=\"26:1-26:30\">High Availability: Failover<\/li>\n<li data-sourcepos=\"27:1-27:15\">Documentation<\/li>\n<li data-sourcepos=\"28:1-28:16\">Customization<\/li>\n<li data-sourcepos=\"29:1-29:9\">Backup<\/li>\n<li data-sourcepos=\"30:1-30:13\">Monitoring<\/li>\n<li data-sourcepos=\"31:1-32:0\">Other features (UI or additional features)<\/li>\n<\/ul>\n<p>[\/vc_column_text][vc_custom_heading text=&#8221;Patroni&#8221; use_theme_fonts=&#8221;yes&#8221; el_class=&#8221;header2&#8243; link=&#8221;url:https%3A%2F%2Fgithub.com%2Fpatroni%2Fpatroni|title:Patroni|target:_blank&#8221;][vc_column_text]<\/p>\n<p dir=\"auto\" data-sourcepos=\"35:1-35:165\">Before going into each operator, let&#8217;s discuss <em data-sourcepos=\"35:48-35:56\">Patroni<\/em> because three of the operators (<em data-sourcepos=\"35:90-35:98\">Zalando<\/em>, <em data-sourcepos=\"35:101-35:113\">CrunchyData<\/em>, <em data-sourcepos=\"35:116-35:126\">Stackgres<\/em>) use it for their HA implementation.<\/p>\n<p dir=\"auto\" data-sourcepos=\"37:1-37:240\"><em data-sourcepos=\"37:1-37:9\">Patroni<\/em> supports PostgreSQL cluster HA by managing the leader key stored on the <em data-sourcepos=\"37:83-37:88\">etcd<\/em> (or <em data-sourcepos=\"37:94-37:104\">Zookeeper<\/em> etc). It helps the PostgreSQL cluster for automatic failover\/startup\/shutdown\/configuration, etc. Zalando developed this originally.<\/p>\n<p dir=\"auto\" data-sourcepos=\"39:1-39:219\"><em data-sourcepos=\"39:1-39:9\">Patroni<\/em> is not originally designed for Kubernetes, but it has good synergy with Kubernetes. With Kubernetes, it does not require a dedicated etcd cluster; it simply uses Kubernetes API to manage the cluster state.<\/p>\n<p dir=\"auto\" data-sourcepos=\"41:1-41:106\">While testing, we found it works well for managing the cluster state, and it handles failover smoothly.<\/p>\n<p dir=\"auto\" data-sourcepos=\"43:1-43:189\"><a href=\"https:\/\/access.crunchydata.com\/documentation\/postgres-operator\/latest\/architecture\/high-availability\" target=\"_blank\" rel=\"nofollow noreferrer noopener\" data-sourcepos=\"43:1-43:129\">CrunchyData documentation<\/a> has some explanation about how it works on <em data-sourcepos=\"43:174-43:185\">Kubernetes<\/em>:<\/p>\n<blockquote dir=\"auto\" data-sourcepos=\"44:1-44:579\">\n<p data-sourcepos=\"44:3-44:579\">Each HA PostgreSQL cluster maintains its availability by using Patroni to manage failover when the primary becomes compromised. Patroni stores the primary\u2019s ID in annotations on a Kubernetes Endpoints object which acts as a lease. The primary must periodically renew the lease to signal that it\u2019s healthy. If the primary misses its deadline, replicas compare their WAL positions to see who has the most up-to-date data. Instances with the latest data try to overwrite the ID on the lease. The first to succeed becomes the new primary, and all others follow the new primary.<\/p>\n<\/blockquote>\n<p dir=\"auto\" data-sourcepos=\"46:1-46:33\">Some resources about <em data-sourcepos=\"46:22-46:30\">Patroni<\/em>:<\/p>\n<ul dir=\"auto\" data-sourcepos=\"47:1-51:0\">\n<li data-sourcepos=\"47:1-47:151\">Youtube: <a href=\"https:\/\/www.youtube.com\/watch?v=CftcVhFMGSY\" target=\"_blank\" rel=\"nofollow noreferrer noopener\" data-sourcepos=\"47:12-47:151\">Elephants on Automatic: HA Clustered PostgreSQL with Helm [I] &#8211; Josh Berkus &amp; Oleksii Kliukin<\/a><\/li>\n<li data-sourcepos=\"48:1-48:162\">Slideshare: <a href=\"https:\/\/www.slideshare.net\/slideshow\/high-availability-postgresql-with-zalando-patroni\/57820504\" target=\"_blank\" rel=\"nofollow noreferrer noopener\" data-sourcepos=\"48:15-48:162\">High Availability PostgreSQL with Zalando Patroni<\/a><\/li>\n<li data-sourcepos=\"49:1-51:0\">Youtube: <a href=\"https:\/\/www.youtube.com\/watch?v=iruaCgeG7qs\" target=\"_blank\" rel=\"nofollow noreferrer noopener\" data-sourcepos=\"49:12-49:136\">Day 1, Full Automatic Database: PostgreSQL HA with Kubernetes; KubeCon EU 2016<\/a><\/li>\n<\/ul>\n<p>[\/vc_column_text][vc_custom_heading text=&#8221;CrunchyData Postgres-operator&#8221; use_theme_fonts=&#8221;yes&#8221; el_class=&#8221;header2&#8243; link=&#8221;url:https%3A%2F%2Fwww.crunchydata.com%2Fproducts%2Fcrunchy-postgresql-for-kubernetes|title:CrunchyData%20Postgres-operator|target:_blank&#8221;][vc_column_text]<\/p>\n<h3 dir=\"auto\" data-sourcepos=\"56:1-56:6\"><img decoding=\"async\" class=\"aligncenter wp-image-113927 size-thumbnail\" src=\"https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/cruchydata-postgres-operator-172x167.png\" alt=\"Patroni\" width=\"172\" height=\"167\" srcset=\"https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/cruchydata-postgres-operator-172x167.png 172w, https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/cruchydata-postgres-operator-300x292.png 300w, https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/cruchydata-postgres-operator.png 372w\" sizes=\"(max-width: 172px) 100vw, 172px\" \/>HA<\/h3>\n<p dir=\"auto\" data-sourcepos=\"57:1-57:39\"><em data-sourcepos=\"57:1-57:9\">Patroni<\/em>. Failover process is smooth.<\/p>\n<h3 dir=\"auto\" data-sourcepos=\"58:1-58:17\">Documentation<\/h3>\n<p dir=\"auto\" data-sourcepos=\"59:1-59:77\">Simple and easy to follow. Many examples so you can start using it quickly.<\/p>\n<h3 dir=\"auto\" data-sourcepos=\"60:1-60:17\">Customization<\/h3>\n<p dir=\"auto\" data-sourcepos=\"61:1-61:55\">Good. Everything can be defined in a single manifest.<\/p>\n<h3 dir=\"auto\" data-sourcepos=\"62:1-62:10\">Backup<\/h3>\n<p dir=\"auto\" data-sourcepos=\"63:1-63:330\"><a href=\"https:\/\/pgbackrest.org\/\" target=\"_blank\" rel=\"nofollow noreferrer noopener\" data-sourcepos=\"63:1-63:39\"><em data-sourcepos=\"63:2-63:13\">pgBackRest<\/em><\/a> is used for logical\/WAL backup for database. It works fine with a PVC based approach but <strong data-sourcepos=\"63:130-63:163\">not with S3-compatible storage<\/strong> like <em data-sourcepos=\"63:170-63:178\">Ceph S3<\/em>. It requires configuring <em data-sourcepos=\"63:205-63:216\">pgBackRest<\/em> parameters, but we had some issues due to the inability to set environment variables or lack of debug logging.<\/p>\n<h3 dir=\"auto\" data-sourcepos=\"64:1-64:14\">Monitoring<\/h3>\n<p dir=\"auto\" data-sourcepos=\"65:1-65:262\"><em data-sourcepos=\"65:1-65:27\">Prometheus format metrics<\/em> is supported. But it does not automatically create <em data-sourcepos=\"65:80-65:88\">Service<\/em> or <em data-sourcepos=\"65:93-65:104\">PodMonitor<\/em> resource. It&#8217;s hard to use with the existing <em data-sourcepos=\"65:151-65:162\">Prometheus<\/em> and <em data-sourcepos=\"65:168-65:176\">Grafana<\/em> (Discussed in <a href=\"https:\/\/github.com\/CrunchyData\/postgres-operator\/issues\/1968\" target=\"_blank\" rel=\"nofollow noreferrer noopener\" data-sourcepos=\"65:192-65:259\">here<\/a>)<\/p>\n<h3 dir=\"auto\" data-sourcepos=\"67:1-67:10\">Pooler<\/h3>\n<p dir=\"auto\" data-sourcepos=\"68:1-68:153\"><em data-sourcepos=\"68:1-68:11\">PgBouncer<\/em> is supported. There are some issues with the login user to use for <em data-sourcepos=\"68:80-68:90\">PgBouncer<\/em>, but there are fewer documentations about how to workaround.<\/p>\n<h3 dir=\"auto\" data-sourcepos=\"70:1-70:18\">Other features<\/h3>\n<p dir=\"auto\" data-sourcepos=\"71:2-71:97\"><em data-sourcepos=\"71:2-71:10\">pgAdmin<\/em> : You can deploy <em data-sourcepos=\"71:29-71:37\">pgAdmin<\/em> Web UI, but it does not automatically create a <em data-sourcepos=\"71:86-71:94\">Service<\/em>.<\/p>\n<h3 dir=\"auto\" data-sourcepos=\"73:1-73:12\">Concerns<\/h3>\n<h4 dir=\"auto\" data-sourcepos=\"74:1-74:13\">License<\/h4>\n<p dir=\"auto\" data-sourcepos=\"75:1-75:290\"><em data-sourcepos=\"75:1-75:13\">CrunchyData<\/em> has <a href=\"https:\/\/www.crunchydata.com\/developers\/terms-of-use\" target=\"_blank\" rel=\"nofollow noreferrer noopener\" data-sourcepos=\"75:19-75:103\">statements about its licensing<\/a>. The operator itself is open source under <em data-sourcepos=\"75:147-75:166\">Apache License 2.0<\/em>, but container images have a different license. This is not clear, but we understand this limits using it for production.<\/p>\n<h4 dir=\"auto\" data-sourcepos=\"77:1-77:35\">Setting environment variables<\/h4>\n<p dir=\"auto\" data-sourcepos=\"78:1-78:319\">It does not allow setting environment variables in the resource definition but need to set on the <em data-sourcepos=\"78:99-78:112\">StatefullSet<\/em> manually (discussed in GitHub <a href=\"https:\/\/github.com\/CrunchyData\/postgres-operator\/issues\/3054\" target=\"_blank\" rel=\"nofollow noreferrer noopener\" data-sourcepos=\"78:144-78:212\">issue<\/a>). This makes it difficult to overwrite S3 configs to work the backup process with S3 compatible storage.<\/p>\n<h4 dir=\"auto\" data-sourcepos=\"80:1-80:35\">TLS connection for <em data-sourcepos=\"80:25-80:35\">PgBouncer<\/em><\/h4>\n<p dir=\"auto\" data-sourcepos=\"81:1-81:243\">TLS connection is required to access <em data-sourcepos=\"81:38-81:48\">PgBouncer<\/em>. This is a little complex to disable, and it is not very clear in the doc about which certificate or key to use (GitHub <a href=\"https:\/\/github.com\/CrunchyData\/postgres-operator\/issues\/253\" target=\"_blank\" rel=\"nofollow noreferrer noopener\" data-sourcepos=\"81:170-81:242\">issue link<\/a>)<\/p>\n<p>[\/vc_column_text][vc_custom_heading text=&#8221;CloudNative PG&#8221; use_theme_fonts=&#8221;yes&#8221; el_class=&#8221;header2&#8243; link=&#8221;url:https%3A%2F%2Fcloudnative-pg.io%2F|title:CloudNative%20PG|target:_blank&#8221;][vc_column_text]<\/p>\n<h3 dir=\"auto\" data-sourcepos=\"87:1-87:7\"><img decoding=\"async\" class=\"size-full wp-image-113930 aligncenter\" src=\"https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/cloudnative-pg.png\" alt=\"CloudNativePG\" width=\"267\" height=\"150\" \/><\/h3>\n<h3 dir=\"auto\" data-sourcepos=\"87:1-87:7\">HA<\/h3>\n<p dir=\"auto\" data-sourcepos=\"88:1-88:294\">It doesn&#8217;t use <em data-sourcepos=\"88:16-88:24\">Patroni<\/em> but its own HA implementation. It uses PostgreSQL&#8217;s native physical replication technology (<a href=\"https:\/\/cloudnative-pg.io\/documentation\/1.20\/architecture\/#synchronizing-the-state\" target=\"_blank\" rel=\"nofollow noreferrer noopener\" data-sourcepos=\"88:118-88:223\">more info in the doc<\/a>). It also uses the Kubernetes API server to manage the cluster state.<\/p>\n<p dir=\"auto\" data-sourcepos=\"90:1-90:359\">Failover goes slowly by default. Based on the application requirements, you need to <a href=\"https:\/\/cloudnative-pg.io\/documentation\/1.20\/failover\/\" target=\"_blank\" rel=\"nofollow noreferrer noopener\" data-sourcepos=\"90:85-90:170\">adjust <code data-sourcepos=\"90:94-90:112\">.spec.failoverDelay<\/code><\/a> . This depends on the data protection policy or service availability policy balance. See some <a href=\"https:\/\/github.com\/cloudnative-pg\/cloudnative-pg\/discussions\/2835\" target=\"_blank\" rel=\"nofollow noreferrer noopener\" data-sourcepos=\"90:266-90:345\">discussions<\/a> in GitHub.<\/p>\n<h3 dir=\"auto\" data-sourcepos=\"91:1-91:17\">Documentation<\/h3>\n<p dir=\"auto\" data-sourcepos=\"92:1-92:6\">Good.<\/p>\n<h3 dir=\"auto\" data-sourcepos=\"94:1-94:17\">Customization<\/h3>\n<p dir=\"auto\" data-sourcepos=\"95:1-95:114\">Easy customization by using <a href=\"https:\/\/github.com\/cloudnative-pg\/charts\" target=\"_blank\" rel=\"nofollow noreferrer noopener\" data-sourcepos=\"95:29-95:82\">Helm chart<\/a> for both operator and cluster.<\/p>\n<h3 dir=\"auto\" data-sourcepos=\"97:1-97:10\">Backup<\/h3>\n<p dir=\"auto\" data-sourcepos=\"98:1-98:115\">S3 is supported for WAL and Data backup. This works smoothly with S3-compatible storage like <em data-sourcepos=\"98:94-98:102\">Ceph S3<\/em> or <em data-sourcepos=\"98:107-98:113\">MinIO<\/em>.<\/p>\n<h3 dir=\"auto\" data-sourcepos=\"100:1-100:14\">Monitoring<\/h3>\n<p dir=\"auto\" data-sourcepos=\"101:1-101:35\">Supported, it&#8217;s easy to configure.<\/p>\n<h3 dir=\"auto\" data-sourcepos=\"103:1-103:10\">Pooler<\/h3>\n<p dir=\"auto\" data-sourcepos=\"104:1-104:27\"><em data-sourcepos=\"104:1-104:11\">PgBouncer<\/em> is supported.<\/p>\n<h3 dir=\"auto\" data-sourcepos=\"106:1-106:18\">Other features<\/h3>\n<h4 dir=\"auto\" data-sourcepos=\"107:1-107:30\">Does not use StatefulSet<\/h4>\n<p dir=\"auto\" data-sourcepos=\"108:1-108:282\">It does not use <em data-sourcepos=\"108:17-108:29\">StatefulSet<\/em> but uses a <em data-sourcepos=\"108:42-108:46\">Pod<\/em> to deploy <em data-sourcepos=\"108:58-108:69\">PostgreSQL<\/em> cluster. This feature makes this operator unique from others. <a href=\"https:\/\/cloudnative-pg.io\/documentation\/1.20\/controller\/\" target=\"_blank\" rel=\"nofollow noreferrer noopener\" data-sourcepos=\"108:133-108:196\">Here<\/a> are some explanations about the reasons behind using <em data-sourcepos=\"108:251-108:255\">Pod<\/em> instead of <em data-sourcepos=\"108:268-108:280\">StatefulSet<\/em>.<\/p>\n<h4 dir=\"auto\" data-sourcepos=\"110:1-110:25\">kubectl cnpg plugin<\/h4>\n<p dir=\"auto\" data-sourcepos=\"111:1-111:182\"><a href=\"https:\/\/cloudnative-pg.io\/documentation\/current\/kubectl-plugin\/\" target=\"_blank\" rel=\"nofollow noreferrer noopener\" data-sourcepos=\"111:1-111:81\"><code data-sourcepos=\"111:3-111:14\">kubectl cnpg<\/code><\/a> plugin is very useful. It is full of utilities from spinning up a new cluster to running benchmark.<\/p>\n<h3 dir=\"auto\" data-sourcepos=\"113:1-113:12\">Concerns<\/h3>\n<h4 dir=\"auto\" data-sourcepos=\"114:1-114:27\">Own HA implementation<\/h4>\n<p dir=\"auto\" data-sourcepos=\"115:1-115:155\">It does not rely on <em data-sourcepos=\"115:21-115:29\">Patroni<\/em> but uses its own architecture for HA. You need to read the documentation carefully to understand how it works for failover.<\/p>\n<h4 dir=\"auto\" data-sourcepos=\"117:1-117:24\">Complex parameters<\/h4>\n<p dir=\"auto\" data-sourcepos=\"118:1-118:200\">It is complex in configuring many parameters. For example, the default <code data-sourcepos=\"118:73-118:93\">.spec.switchoverDelay<\/code> makes the failover slower and requires proper design and planning based on the application requirements.<\/p>\n<p>[\/vc_column_text][vc_custom_heading text=&#8221;Zalando Postgres Operator&#8221; use_theme_fonts=&#8221;yes&#8221; el_class=&#8221;header2&#8243; link=&#8221;url:https%3A%2F%2Fgithub.com%2Fzalando%2Fpostgres-operator%3Ftab%3Dreadme-ov-file|title:Zalando%20Postgres%20Operator|target:_blank&#8221;][vc_column_text]<img decoding=\"async\" class=\"size-medium wp-image-113933 aligncenter\" src=\"https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/zelando-postgres-operator-300x169.png\" alt=\"Zalando\" width=\"300\" height=\"169\" srcset=\"https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/zelando-postgres-operator-300x169.png 300w, https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/zelando-postgres-operator-297x167.png 297w, https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/zelando-postgres-operator.png 500w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/p>\n<p><img decoding=\"async\" class=\"size-medium wp-image-113984 aligncenter\" src=\"https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/zalando-postgres-operator-300x272.png\" alt=\"Zalando Postgres Operator\" width=\"300\" height=\"272\" srcset=\"https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/zalando-postgres-operator-300x272.png 300w, https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/zalando-postgres-operator-184x167.png 184w, https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/zalando-postgres-operator.png 540w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/p>\n<h3 dir=\"auto\" data-sourcepos=\"127:1-127:6\">HA<\/h3>\n<p dir=\"auto\" data-sourcepos=\"128:2-128:105\"><a href=\"https:\/\/github.com\/zalando\/spilo\" target=\"_blank\" rel=\"nofollow noreferrer noopener\" data-sourcepos=\"128:2-128:42\">Spilo<\/a> which bundles <em data-sourcepos=\"128:58-128:69\">PostgreSQL<\/em> and <em data-sourcepos=\"128:75-128:83\">Patroni<\/em> together is used.<\/p>\n<h3 dir=\"auto\" data-sourcepos=\"129:1-129:18\">Documentation<\/h3>\n<p dir=\"auto\" data-sourcepos=\"130:1-130:56\">Insufficient and hard to find what you are looking for.<\/p>\n<h3 dir=\"auto\" data-sourcepos=\"132:1-132:17\">Customization<\/h3>\n<p dir=\"auto\" data-sourcepos=\"133:1-133:55\">Complex due to a lack of clarity in the documentation.<\/p>\n<h3 dir=\"auto\" data-sourcepos=\"135:1-135:10\">Backup<\/h3>\n<p dir=\"auto\" data-sourcepos=\"136:1-136:167\">S3 is supported. To use S3 compatible storage like Ceph S3, some hack is required to add some env vars. Unfortunately, this is not very clear from the documentation.<\/p>\n<h3 dir=\"auto\" data-sourcepos=\"138:1-138:14\">Monitoring<\/h3>\n<p dir=\"auto\" data-sourcepos=\"139:1-139:46\">No. Need to add a sidecar container manually.<\/p>\n<h3 dir=\"auto\" data-sourcepos=\"141:1-141:10\">Pooler<\/h3>\n<p dir=\"auto\" data-sourcepos=\"142:1-142:27\"><em data-sourcepos=\"142:1-142:11\">PgBouncer<\/em> is supported.<\/p>\n<h3 dir=\"auto\" data-sourcepos=\"144:1-144:20\">Other features:<\/h3>\n<p dir=\"auto\" data-sourcepos=\"145:1-145:215\"><a href=\"https:\/\/github.com\/zalando\/postgres-operator\/blob\/master\/docs\/operator-ui.md\" target=\"_blank\" rel=\"nofollow noreferrer noopener\" data-sourcepos=\"145:1-145:86\">Web UI<\/a> is useful when deploying without a YAML file. You can check the logs etc. But it comes without authentication or authorization.<\/p>\n<p dir=\"auto\" data-sourcepos=\"145:1-145:215\"><img decoding=\"async\" class=\"aligncenter wp-image-113944 size-large\" src=\"https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/zalando-pgop-ui-1024x450.png\" alt=\"zalando-pgop-ui\" width=\"1024\" height=\"450\" srcset=\"https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/zalando-pgop-ui-1024x450.png 1024w, https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/zalando-pgop-ui-300x132.png 300w, https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/zalando-pgop-ui-355x156.png 355w, https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/zalando-pgop-ui-1536x674.png 1536w, https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/zalando-pgop-ui.png 1913w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/p>\n<h3 dir=\"auto\" data-sourcepos=\"149:1-149:13\">Concerns<\/h3>\n<h4 dir=\"auto\" data-sourcepos=\"150:1-150:26\">Operator performance<\/h4>\n<p dir=\"auto\" data-sourcepos=\"151:1-151:436\">The operator&#8217;s performance is a concern. Some child resources are not cleaned up when deleting parent resources (Looks like it has been fixed recently. <a href=\"https:\/\/github.com\/zalando\/postgres-operator\/issues\/2719\" target=\"_blank\" rel=\"nofollow noreferrer noopener\" data-sourcepos=\"151:153-151:224\">GitHub issue<\/a> and <a href=\"https:\/\/github.com\/zalando\/postgres-operator\/pull\/2713\" target=\"_blank\" rel=\"nofollow noreferrer noopener\" data-sourcepos=\"151:230-151:289\">PR<\/a>). Sometimes, terminating Pod took a long time. The insufficient documentation and lack of enough logging make the debugging a little difficult.<\/p>\n<p>[\/vc_column_text][vc_custom_heading text=&#8221;kubegres&#8221; use_theme_fonts=&#8221;yes&#8221; el_class=&#8221;header2&#8243; link=&#8221;url:https%3A%2F%2Fwww.kubegres.io%2F|title:kubegres|target:_blank&#8221;][vc_column_text]<img decoding=\"async\" class=\"size-full wp-image-113938 aligncenter\" src=\"https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/kubegres.png\" alt=\"Kubegres\" width=\"82\" height=\"80\" \/><\/p>\n<h3 dir=\"auto\" data-sourcepos=\"157:1-157:6\">HA<\/h3>\n<p dir=\"auto\" data-sourcepos=\"158:1-158:232\">Standard Postgres <a href=\"https:\/\/wiki.postgresql.org\/wiki\/Streaming_Replication\" target=\"_blank\" rel=\"nofollow noreferrer noopener\" data-sourcepos=\"158:19-158:97\">streaming replication<\/a>. It is built with the native Postgres library only. No custom or 3rd party library. The operator manages failover but it works slowly.<\/p>\n<h3 dir=\"auto\" data-sourcepos=\"160:1-160:17\">Documentation<\/h3>\n<p dir=\"auto\" data-sourcepos=\"161:1-161:17\">Good and simple.<\/p>\n<h3 dir=\"auto\" data-sourcepos=\"162:1-162:17\">Customization<\/h3>\n<p dir=\"auto\" data-sourcepos=\"163:1-163:224\">Not many customizations are available. It&#8217;s <a href=\"https:\/\/www.kubegres.io\/doc\/properties-explained.html\" target=\"_blank\" rel=\"nofollow noreferrer noopener\" data-sourcepos=\"163:45-163:119\">allowed parameters<\/a> are limited. It uses the official docker image of PostgreSQL, so easy to customize the container image.<\/p>\n<h3 dir=\"auto\" data-sourcepos=\"165:1-165:10\">Backup<\/h3>\n<p dir=\"auto\" data-sourcepos=\"166:1-166:37\">Supported on the PVC. No S3 support.<\/p>\n<h3 dir=\"auto\" data-sourcepos=\"167:1-167:14\">Monitoring<\/h3>\n<p dir=\"auto\" data-sourcepos=\"168:2-168:22\">No built-in support.<\/p>\n<h3 dir=\"auto\" data-sourcepos=\"169:1-169:10\">Pooler<\/h3>\n<p dir=\"auto\" data-sourcepos=\"170:2-170:22\">No built-in support.<\/p>\n<h3 dir=\"auto\" data-sourcepos=\"172:1-172:18\">Other features<\/h3>\n<p dir=\"auto\" data-sourcepos=\"173:1-173:14\">Noting much.<\/p>\n<h3 dir=\"auto\" data-sourcepos=\"175:1-175:13\">Concerns<\/h3>\n<h4 dir=\"auto\" data-sourcepos=\"176:1-176:35\">No side-car container support<\/h4>\n<p dir=\"auto\" data-sourcepos=\"177:1-177:184\">No side-car supported. This makes it cumbersome to implement <em data-sourcepos=\"177:62-177:82\">Prometheus Exporter<\/em> or other customizations. Many manual works are required to set up monitoring or connection poolers.<\/p>\n<h4 dir=\"auto\" data-sourcepos=\"179:1-179:42\">Development community is not active<\/h4>\n<p dir=\"auto\" data-sourcepos=\"180:1-180:84\">The development is not as active as others. (The last commit was a few months ago.)<\/p>\n<p>[\/vc_column_text][vc_custom_heading text=&#8221;Stackgres&#8221; use_theme_fonts=&#8221;yes&#8221; el_class=&#8221;header2&#8243; link=&#8221;url:https%3A%2F%2Fstackgres.io%2F|title:Stackgres|target:_blank&#8221;][vc_column_text]<img decoding=\"async\" class=\"size-full wp-image-113941 aligncenter\" src=\"https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/stackgres.png\" alt=\"StackGres \" width=\"192\" height=\"192\" srcset=\"https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/stackgres.png 192w, https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/stackgres-167x167.png 167w, https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/stackgres-768x768.png 768w, https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/stackgres-570x570.png 570w\" sizes=\"(max-width: 192px) 100vw, 192px\" \/><\/p>\n<h3 dir=\"auto\" data-sourcepos=\"186:1-186:6\">HA<\/h3>\n<p dir=\"auto\" data-sourcepos=\"187:1-187:40\"><em data-sourcepos=\"187:1-187:9\">Patroni<\/em>. The failover works smoothly.<\/p>\n<h3 dir=\"auto\" data-sourcepos=\"188:1-188:17\">Documentation<\/h3>\n<p dir=\"auto\" data-sourcepos=\"189:1-189:25\">Good and easy to follow.<\/p>\n<h3 dir=\"auto\" data-sourcepos=\"191:1-191:17\">Customization<\/h3>\n<p dir=\"auto\" data-sourcepos=\"192:1-192:253\">Very flexible and allows much customization but is more complex than others as there are more features and more resources. (<code data-sourcepos=\"192:126-192:142\">SGInstanceProfile<\/code>, <code data-sourcepos=\"192:147-192:162\">SGPostgresConfig<\/code>, <code data-sourcepos=\"192:167-192:181\">SGPoolingConfig<\/code>, <code data-sourcepos=\"192:186-192:200\">SGOBjectStorage<\/code>, <code data-sourcepos=\"192:205-192:221\">SGDistributedLogs<\/code>, <code data-sourcepos=\"192:226-192:233\">SGScript<\/code>, <code data-sourcepos=\"192:238-192:246\">SGCluster<\/code>, etc)<\/p>\n<p dir=\"auto\" data-sourcepos=\"194:1-194:103\">For example. Creating a user or database should be written in the <code data-sourcepos=\"194:68-194:71\">.sql<\/code> file on <code data-sourcepos=\"194:84-194:91\">SGScript<\/code> resource.<\/p>\n<h3 dir=\"auto\" data-sourcepos=\"196:1-196:10\">Backup<\/h3>\n<p dir=\"auto\" data-sourcepos=\"197:1-197:57\">S3 supported. Works fine with S3-compatible storage too.<\/p>\n<h3 dir=\"auto\" data-sourcepos=\"199:1-199:14\">Monitoring<\/h3>\n<p dir=\"auto\" data-sourcepos=\"200:1-200:109\">Supported. Automatically integrate with existing <em data-sourcepos=\"200:50-200:61\">Prometheus<\/em> and <em data-sourcepos=\"200:67-200:75\">Grafana<\/em>. This is very easy to configure.<\/p>\n<h3 dir=\"auto\" data-sourcepos=\"202:1-202:10\">Pooler<\/h3>\n<p dir=\"auto\" data-sourcepos=\"203:1-203:164\"><em data-sourcepos=\"203:1-203:11\">PgBouncer<\/em> is implemented as a side-car container in each pod. This is different from other operators that deploy <em data-sourcepos=\"203:116-203:126\">PgBouncer<\/em> outside of each <em data-sourcepos=\"203:144-203:155\">PostgreSQL<\/em> <em data-sourcepos=\"203:157-203:162\">Pods<\/em>.<\/p>\n<h3 dir=\"auto\" data-sourcepos=\"205:1-205:19\">Other features<\/h3>\n<h4 dir=\"auto\" data-sourcepos=\"206:1-206:19\">Support Citus<\/h4>\n<p dir=\"auto\" data-sourcepos=\"207:1-207:116\">It supports <a href=\"https:\/\/stackgres.io\/doc\/1.5\/administration\/sharded-cluster-creation\/\" target=\"_blank\" rel=\"nofollow noreferrer noopener\" data-sourcepos=\"207:13-207:100\">sharded cluster<\/a> using <em data-sourcepos=\"207:108-207:114\">Citus<\/em>.<\/p>\n<h4 dir=\"auto\" data-sourcepos=\"209:1-209:17\">Fancy Web UI<\/h4>\n<p dir=\"auto\" data-sourcepos=\"210:1-210:129\">Fancy Web UI with OIDC login support. This friendly UI helps the developer team to manage <em data-sourcepos=\"210:91-210:102\">PostgreSQL<\/em> instances by themselves.<\/p>\n<p dir=\"auto\" data-sourcepos=\"210:1-210:129\"><img decoding=\"async\" class=\"aligncenter wp-image-113935 size-large\" src=\"https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/web-ui-for-stackgres-postgresql-1024x442.png\" alt=\"web-ui-for-stackgres-postgresql\" width=\"1024\" height=\"442\" srcset=\"https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/web-ui-for-stackgres-postgresql-1024x442.png 1024w, https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/web-ui-for-stackgres-postgresql-300x129.png 300w, https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/web-ui-for-stackgres-postgresql-355x153.png 355w, https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/web-ui-for-stackgres-postgresql-1536x663.png 1536w, https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/web-ui-for-stackgres-postgresql.png 1914w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/p>\n<h3 dir=\"auto\" data-sourcepos=\"214:1-214:14\">Concerns<\/h3>\n<h4 dir=\"auto\" data-sourcepos=\"215:1-215:13\">License<\/h4>\n<p dir=\"auto\" data-sourcepos=\"216:1-216:65\">The license is AGPLv3. (This is fine but different from others.)<\/p>\n<h4 dir=\"auto\" data-sourcepos=\"218:1-218:16\">Complexity<\/h4>\n<p dir=\"auto\" data-sourcepos=\"219:1-219:58\">Complex architecture due to many components and features.<\/p>\n<p>[\/vc_column_text][vc_custom_heading text=&#8221;Conclusion&#8221; use_theme_fonts=&#8221;yes&#8221; el_class=&#8221;header2&#8243;][vc_column_text]<\/p>\n<p dir=\"auto\" data-sourcepos=\"222:1-222:311\">In our conclusion, <em data-sourcepos=\"222:20-222:35\">CloudNative PG<\/em> can be the first option as it covers most of our use cases and is easy to use and configure. Also, there is a lot of community support, comes with good documentation and the development is very active. There is less management overhead because of the <code data-sourcepos=\"222:289-222:300\">kubectl cnpg<\/code> plugin.<\/p>\n<p dir=\"auto\" data-sourcepos=\"224:1-224:154\">The second option will be <em data-sourcepos=\"224:27-224:37\">Stackgres<\/em> if you want to use <em data-sourcepos=\"224:58-224:66\">Patroni<\/em>, although it is complex. It is more robust and mature compared with other operators.<\/p>\n<p dir=\"auto\" data-sourcepos=\"226:1-226:232\">I personally like the concept of <em data-sourcepos=\"226:34-226:43\">kubegres<\/em> for its minimalism and simplicity. Many operators try to implement as many features as possible, but it&#8217;s unique that they try to keep it very simple and focus on a few critical things.<\/p>\n<p dir=\"auto\" data-sourcepos=\"228:1-228:320\">Management cost compared with <em data-sourcepos=\"228:31-228:36\">Helm<\/em> chart will be less or the same for us. Using <em data-sourcepos=\"228:83-228:92\">Operator<\/em> will add another abstraction layer and component you need to manage. It costs some work and time to understand how it works. However, if you are going to deploy and destroy many <em data-sourcepos=\"228:272-228:283\">PostgreSQL<\/em> clusters, <em data-sourcepos=\"228:295-228:304\">Operator<\/em> is very useful.<\/p>\n<p>[\/vc_column_text][\/vc_column][\/vc_row]<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"<p>[vc_row][vc_column][vc_custom_heading text=&#8221;Running PostgreSQL on Kubernetes&#8221; use_theme_fonts=&#8221;yes&#8221; el_class=&#8221;header2&#8243;][\/vc_column][\/vc_row][vc_row][vc_column width=&#8221;1\/2&#8243;][vc_row_inner][vc_column_inner][vc_column_text][\/vc_column_text][\/vc_column_inner][\/vc_row_inner][\/vc_column][vc_column width=&#8221;1\/2&#8243;][vc_row_inner][vc_column_inner][vc_column_text][\/vc_column_text][\/vc_column_inner][\/vc_row_inner][\/vc_column][\/vc_row][vc_row][vc_column][vc_column_text]Recently, there are more use cases to run PostgreSQL on Kubernetes. One of the main reason of this is to leverage Kubernetes&#8216;s scalability and self-healing to run PostgreSQL. The survey by Timescale in 2023 shows that there are some amounts of users who deploy PostgreSQL on Kubernetes.<br \/><a href=\"https:\/\/avinton.com\/en\/blog\/2024\/10\/postgresql-operator-on-kubernetes\/\" class=\"more\">Read more<\/a><\/p>\n","protected":false},"author":39,"featured_media":113954,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1830,2006],"tags":[1832,2099,2100,2101],"class_list":["post-113738","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category--en","category-technical-en","tag-kubernetes-en","tag--en","tag-postgresql-en"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v25.8 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>PostgreSQL Operator on Kubernetes<\/title>\n<meta name=\"description\" content=\"we explore various PostgreSQL Operator on Kubernetes\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/avinton.com\/en\/blog\/2024\/10\/postgresql-operator-on-kubernetes\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"PostgreSQL Operator on Kubernetes\" \/>\n<meta property=\"og:description\" content=\"we explore various PostgreSQL Operator on Kubernetes\" \/>\n<meta property=\"og:url\" content=\"https:\/\/avinton.com\/en\/blog\/2024\/10\/postgresql-operator-on-kubernetes\/\" \/>\n<meta property=\"og:site_name\" content=\"Avinton Japan\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/Avintons\/\" \/>\n<meta property=\"article:published_time\" content=\"2024-10-11T04:58:29+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-10-17T08:11:51+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/deploying-postgresql-operator-in-Kubernetes.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1338\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Avinton rk\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@AvintonJapan\" \/>\n<meta name=\"twitter:site\" content=\"@AvintonJapan\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Avinton rk\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"30 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/avinton.com\/en\/blog\/2024\/10\/postgresql-operator-on-kubernetes\/\",\"url\":\"https:\/\/avinton.com\/en\/blog\/2024\/10\/postgresql-operator-on-kubernetes\/\",\"name\":\"PostgreSQL Operator on Kubernetes\",\"isPartOf\":{\"@id\":\"https:\/\/avinton.com\/en\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/avinton.com\/en\/blog\/2024\/10\/postgresql-operator-on-kubernetes\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/avinton.com\/en\/blog\/2024\/10\/postgresql-operator-on-kubernetes\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/deploying-postgresql-operator-in-Kubernetes.jpg\",\"datePublished\":\"2024-10-11T04:58:29+00:00\",\"dateModified\":\"2024-10-17T08:11:51+00:00\",\"author\":{\"@id\":\"https:\/\/avinton.com\/en\/#\/schema\/person\/546f19a79ed5ae06273f4f7e975d617f\"},\"description\":\"we explore various PostgreSQL Operator on Kubernetes\",\"breadcrumb\":{\"@id\":\"https:\/\/avinton.com\/en\/blog\/2024\/10\/postgresql-operator-on-kubernetes\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/avinton.com\/en\/blog\/2024\/10\/postgresql-operator-on-kubernetes\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/avinton.com\/en\/blog\/2024\/10\/postgresql-operator-on-kubernetes\/#primaryimage\",\"url\":\"https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/deploying-postgresql-operator-in-Kubernetes.jpg\",\"contentUrl\":\"https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/deploying-postgresql-operator-in-Kubernetes.jpg\",\"width\":1338,\"height\":630,\"caption\":\"deploying-postgresql-operator-in-Kubernetes\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/avinton.com\/en\/blog\/2024\/10\/postgresql-operator-on-kubernetes\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/avinton.com\/en\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"PostgreSQL Operator on Kubernetes\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/avinton.com\/en\/#website\",\"url\":\"https:\/\/avinton.com\/en\/\",\"name\":\"Avinton Japan\",\"description\":\"Tailored Solutions and Consulting in AI and Big Data\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/avinton.com\/en\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/avinton.com\/en\/#\/schema\/person\/546f19a79ed5ae06273f4f7e975d617f\",\"name\":\"Avinton rk\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/avinton.com\/en\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/4d9ec2f187849e422156bfa0a775d8dfabb6ddfc31f47087d889f9f0ec2697e5?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/4d9ec2f187849e422156bfa0a775d8dfabb6ddfc31f47087d889f9f0ec2697e5?s=96&d=mm&r=g\",\"caption\":\"Avinton rk\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"PostgreSQL Operator on Kubernetes","description":"we explore various PostgreSQL Operator on Kubernetes","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/avinton.com\/en\/blog\/2024\/10\/postgresql-operator-on-kubernetes\/","og_locale":"en_US","og_type":"article","og_title":"PostgreSQL Operator on Kubernetes","og_description":"we explore various PostgreSQL Operator on Kubernetes","og_url":"https:\/\/avinton.com\/en\/blog\/2024\/10\/postgresql-operator-on-kubernetes\/","og_site_name":"Avinton Japan","article_publisher":"https:\/\/www.facebook.com\/Avintons\/","article_published_time":"2024-10-11T04:58:29+00:00","article_modified_time":"2024-10-17T08:11:51+00:00","og_image":[{"width":1338,"height":630,"url":"https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/deploying-postgresql-operator-in-Kubernetes.jpg","type":"image\/jpeg"}],"author":"Avinton rk","twitter_card":"summary_large_image","twitter_creator":"@AvintonJapan","twitter_site":"@AvintonJapan","twitter_misc":{"Written by":"Avinton rk","Est. reading time":"30 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/avinton.com\/en\/blog\/2024\/10\/postgresql-operator-on-kubernetes\/","url":"https:\/\/avinton.com\/en\/blog\/2024\/10\/postgresql-operator-on-kubernetes\/","name":"PostgreSQL Operator on Kubernetes","isPartOf":{"@id":"https:\/\/avinton.com\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/avinton.com\/en\/blog\/2024\/10\/postgresql-operator-on-kubernetes\/#primaryimage"},"image":{"@id":"https:\/\/avinton.com\/en\/blog\/2024\/10\/postgresql-operator-on-kubernetes\/#primaryimage"},"thumbnailUrl":"https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/deploying-postgresql-operator-in-Kubernetes.jpg","datePublished":"2024-10-11T04:58:29+00:00","dateModified":"2024-10-17T08:11:51+00:00","author":{"@id":"https:\/\/avinton.com\/en\/#\/schema\/person\/546f19a79ed5ae06273f4f7e975d617f"},"description":"we explore various PostgreSQL Operator on Kubernetes","breadcrumb":{"@id":"https:\/\/avinton.com\/en\/blog\/2024\/10\/postgresql-operator-on-kubernetes\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/avinton.com\/en\/blog\/2024\/10\/postgresql-operator-on-kubernetes\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/avinton.com\/en\/blog\/2024\/10\/postgresql-operator-on-kubernetes\/#primaryimage","url":"https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/deploying-postgresql-operator-in-Kubernetes.jpg","contentUrl":"https:\/\/avinton.com\/wp-content\/uploads\/2024\/10\/deploying-postgresql-operator-in-Kubernetes.jpg","width":1338,"height":630,"caption":"deploying-postgresql-operator-in-Kubernetes"},{"@type":"BreadcrumbList","@id":"https:\/\/avinton.com\/en\/blog\/2024\/10\/postgresql-operator-on-kubernetes\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/avinton.com\/en\/"},{"@type":"ListItem","position":2,"name":"PostgreSQL Operator on Kubernetes"}]},{"@type":"WebSite","@id":"https:\/\/avinton.com\/en\/#website","url":"https:\/\/avinton.com\/en\/","name":"Avinton Japan","description":"Tailored Solutions and Consulting in AI and Big Data","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/avinton.com\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/avinton.com\/en\/#\/schema\/person\/546f19a79ed5ae06273f4f7e975d617f","name":"Avinton rk","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/avinton.com\/en\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/4d9ec2f187849e422156bfa0a775d8dfabb6ddfc31f47087d889f9f0ec2697e5?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/4d9ec2f187849e422156bfa0a775d8dfabb6ddfc31f47087d889f9f0ec2697e5?s=96&d=mm&r=g","caption":"Avinton rk"}}]}},"_links":{"self":[{"href":"https:\/\/avinton.com\/en\/wp-json\/wp\/v2\/posts\/113738","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/avinton.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/avinton.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/avinton.com\/en\/wp-json\/wp\/v2\/users\/39"}],"replies":[{"embeddable":true,"href":"https:\/\/avinton.com\/en\/wp-json\/wp\/v2\/comments?post=113738"}],"version-history":[{"count":20,"href":"https:\/\/avinton.com\/en\/wp-json\/wp\/v2\/posts\/113738\/revisions"}],"predecessor-version":[{"id":114032,"href":"https:\/\/avinton.com\/en\/wp-json\/wp\/v2\/posts\/113738\/revisions\/114032"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/avinton.com\/en\/wp-json\/wp\/v2\/media\/113954"}],"wp:attachment":[{"href":"https:\/\/avinton.com\/en\/wp-json\/wp\/v2\/media?parent=113738"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/avinton.com\/en\/wp-json\/wp\/v2\/categories?post=113738"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/avinton.com\/en\/wp-json\/wp\/v2\/tags?post=113738"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}