<?xml version="1.0" encoding="UTF-8" ?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" version="2.0"><channel><title>Jeff McCormick | CrunchyData Blog</title>
<atom:link href="https://www.crunchydata.com/blog/author/jeff-mccormick/rss.xml" rel="self" type="application/rss+xml" />
<link>https://www.crunchydata.com/blog/author/jeff-mccormick</link>
<image><url>https://www.crunchydata.com/build/_assets/default.png-W4XGD4DB.webp</url>
<title>Jeff McCormick | CrunchyData Blog</title>
<link>https://www.crunchydata.com/blog/author/jeff-mccormick</link>
<width>256</width>
<height>256</height></image>
<description>PostgreSQL experts from Crunchy Data share advice, performance tips, and guides on successfully running PostgreSQL and Kubernetes solutions</description>
<language>en-us</language>
<pubDate>Tue, 11 Jun 2019 05:00:00 EDT</pubDate>
<dc:date>2019-06-11T09:00:00.000Z</dc:date>
<dc:language>en-us</dc:language>
<sy:updatePeriod>hourly</sy:updatePeriod>
<sy:updateFrequency>1</sy:updateFrequency>
<item><title><![CDATA[ What's New in Crunchy PostgreSQL Operator 4.0 ]]></title>
<link>https://www.crunchydata.com/blog/crunchy-postgres-kubernetes-operator-4.0</link>
<description><![CDATA[ Crunchy Data announces general availability of PostgreSQL Operator for Kubernetes 4, latest major release of PostgreSQL-as-a-Service Kubernetes platform. ]]></description>
<content:encoded><![CDATA[ <p>Crunchy Data is pleased to release <a href=https://access.crunchydata.com/documentation/pgo/4.0.0/>PostgreSQL Operator 4.0</a>.<p><a href=https://github.com/CrunchyData/postgres-operator>Crunchy PostgreSQL Operator</a> extends Kubernetes to give you the power to easily create, configure and manage PostgreSQL clusters at scale. When combined with the <a href=https://github.com/CrunchyData/crunchy-containers>Crunchy PostgreSQL Container Suite</a>, the Crunchy PostgreSQL Operator provides an open source software solution for PostgreSQL scaling, high-availability, disaster recovery, monitoring, and more. All of this capability comes with the repeatability and automation that comes from Operators on Kubernetes.<p>Crunchy PostgreSQL Operator is open source and developed in close collaboration with users to support enterprise deployments of cloud agnostic PostgreSQL-as-a-Service capability. This release comes after extensive feedback from our customers and the community to ensure the scalability and security that sysadmins, DBAs, and developers have come to rely on.<p>Key features added to the Crunchy PostgreSQL Operator 4.0. include:<h2 id=namespace-deployment-options><a href=#namespace-deployment-options>Namespace Deployment Options</a></h2><p>Support for deploying the Crunchy PostgreSQL Operator with additional namespace patterns, including the ability to deploy the operator its own namespace but manage PostgreSQL clusters in multiple namespace. The new namespace management features lets users create multi-tenant PostgreSQL environments that add further isolation and security to their deployments. The various deployment patterns are included within the <a href=https://access.crunchydata.com/documentation/postgres-operator/4.0.0/gettingstarted/design/namespace/>Design documentation</a>.<h2 id=further-enhancements-to-pgbackrest-integration><a href=#further-enhancements-to-pgbackrest-integration>Further Enhancements to pgBackRest Integration</a></h2><p>Crunchy PostgreSQL Operator 4.0. continues the integration of <a href=https://access.crunchydata.com/documentation/backrest/2.14/>pgBackRest</a>, building on features incorporated within <a href=/blog/crunchy-postgresql-operator-3.5-new-features>version 3.5</a>. For example, this latest release adds the ability to perform pgBackRest backups to Amazon S3. This allows users to create an automated, geographically distributed, and hybrid cloud disaster recovery strategy: : in addition to the benefits of backing up to a distributed object store, users can move their PostgreSQL data easily between data centers.<h2 id=integrated-postgresql-benchmarking><a href=#integrated-postgresql-benchmarking>Integrated PostgreSQL Benchmarking</a></h2><p>Crunchy PostgreSQL Operator 4.0. adds the ability to run <a href=https://access.crunchydata.com/documentation/postgresql11/11.3/pgbench.html>pgBench</a>, a simple program for running standard and customizable benchmark tests on PostgreSQL, from the Operator command-line interface. The <a href=https://access.crunchydata.com/documentation/postgres-operator/4.0.0/operatorcli/pgo-overview/>operator CLI overview documentation</a> provides guidance as to how to use this capability. This provides and simple and easy means for users to compare and investigate performance and scalability under different deployment scenarios.<h2 id=ansible-playbook-based-installation><a href=#ansible-playbook-based-installation>Ansible Playbook Based Installation</a></h2><p>Crunchy PostgreSQL Operator 4.0 provides <a href=https://access.crunchydata.com/documentation/postgres-operator/4.0.0/installation/install-with-ansible/>Ansible playbooks to automate operator installation</a>. The Crunchy PostgreSQL Operator Ansible Installers allow users to install PostgreSQL Operator on Kubernetes and OpenShift from a Linux, Mac or Windows (Ubuntu subsystem) host. In connection with the automated installation, the Ansible playbooks can generate TLS certificates required by the PostgreSQL Operator and configure PostgreSQL Operator settings from a single inventory file.<h2 id=operator-lifecycle-management-olm><a href=#operator-lifecycle-management-olm>Operator Lifecycle Management (OLM)</a></h2><p>Crunchy PostgreSQL Operator 4.0. supports <a href=https://github.com/operator-framework/operator-lifecycle-manager><dfn>Operator Lifecycle Management</dfn></a> (<abbr>OLM</abbr>). The OLM project is a component of the Operator Framework, an open source toolkit to manage Operators, in an effective, automated, and scalable way. OLM concepts were included into Crunchy PostgreSQL Operator to assist in the deployment on Kubernetes using OLM integration.<h2 id=documentation-improvements><a href=#documentation-improvements>Documentation Improvements</a></h2><p>The latest release includes enhanced <a href=https://access.crunchydata.com/documentation/postgres-operator/4.0.0/>user documentation</a>, providing additional information regarding architecture, installation and configuration options. Please take a look and let us know what you think.<h2 id=how-to-get-started><a href=#how-to-get-started>How to Get Started</a></h2><p>Please give the new release of the operator a try and let us know what you think about these new features.<p>If you are new to the Crunchy PostgreSQL Operator and interested in installing the Crunchy PostgreSQL Operator in your environment, please start here: <a href=https://access.crunchydata.com/documentation/postgres-operator/4.0.0/installation/install-with-ansible/>Installation via Ansible</a>. Instructions for <a href=https://access.crunchydata.com/documentation/postgres-operator/4.0.0/installation/operator-install/>Installation via Bash</a> are also available.<p>Interested in a feature you dont see in this release? Please let us know. The project is open source and welcomes <a href=https://access.crunchydata.com/documentation/postgres-operator/4.0.0/contributing/>issues and pull requests</a>.<p>We plan to provide a series of posts over the coming weeks to provide additional information about these new features and how they can support enterprise PostgreSQL-as-a-Service requirements. ]]></content:encoded>
<category><![CDATA[ Kubernetes ]]></category>
<author><![CDATA[ Jeff.McCormick@crunchydata.com (Jeff McCormick) ]]></author>
<dc:creator><![CDATA[ Jeff McCormick ]]></dc:creator>
<guid isPermalink="false">https://blog.crunchydata.com/blog/crunchy-postgres-kubernetes-operator-4.0</guid>
<pubDate>Tue, 11 Jun 2019 05:00:00 EDT</pubDate>
<dc:date>2019-06-11T09:00:00.000Z</dc:date>
<atom:updated>2019-06-11T09:00:00.000Z</atom:updated></item>
<item><title><![CDATA[ What's New in Crunchy PostgreSQL Operator 3.5 ]]></title>
<link>https://www.crunchydata.com/blog/crunchy-postgresql-operator-3.5-new-features</link>
<description><![CDATA[ The latest release of the Crunchy PostgreSQL Operator brings significant improvements to the high-availability and disaster recovery features needed to run PostgreSQL in large-scale, production enterprise environments. ]]></description>
<content:encoded><![CDATA[ <p><a href=https://www.crunchydata.com>Crunchy Data</a> is happy to announce the release of the open source <a href=https://github.com/CrunchyData/postgres-operator>PostgreSQL Operator</a> 3.5 for Kubernetes project, which you can find here: <a href=https://github.com/CrunchyData/postgres-operator/>https://github.com/CrunchyData/postgres-operator/</a><p>This latest release provides further feature enhancements designed to support users intending to deploy large-scale <a href=https://www.postgresql.org>PostgreSQL</a> clusters on <a href=https://kubernetes.io/>Kubernetes</a>, with enterprise high-availability and disaster recovery requirements.<p>When combined with the Crunchy <a href=https://github.com/CrunchyData/crunchy-containers>PostgreSQL Container Suite</a>, the PostgreSQL Operator provides an open source, Kubernetes-native PostgreSQL-as-a-Service capability.<p>Read on to see what is new in PostgreSQL Operator 3.5.<h2 id=pgbackrest-architecture-enhancements><a href=#pgbackrest-architecture-enhancements>pgBackRest Architecture Enhancements</a></h2><p>In order to reduce disk consumption resulting from backups of large PostgreSQL clusters, the PostgreSQL Operator 3.5 improves on the existing <a href=https://pgbackrest.org/>pgBackRest</a> to provide users with a pgBackRest shared repository. This shared pgBackRest repository is used by the primary and each of the replicas of a given <a href=https://www.postgresql.org>PostgreSQL</a> cluster deployed by the Operator. This pgBackRest repository runs within its own Kubernetes <a href=https://kubernetes.io/docs/concepts/workloads/controllers/deployment/>Deployment</a> and is dedicated to serving this given single PostgreSQL cluster.<h2 id=pgbackrest-point-in-time-recovery><a href=#pgbackrest-point-in-time-recovery>pgBackRest Point-In-Time-Recovery</a></h2><p>The PostgreSQL Operator 3.5 provides <a href=https://access.crunchydata.com/documentation/postgresql11/11.1/continuous-archiving.html>point-in-time-recovery</a> from this newly introduced pgBackRest shared repository by implementing the pgBackRest <a href=https://access.crunchydata.com/documentation/backrest/2.08/command/#TableOfContents295>restore</a> command.<p>Users can create a pgBackRest backup using the following pgo CLI command:<pre><code class=language-shell>pgo backup mycluster --backup-type=pgbackrest
</code></pre><p>Users can view pgBackRest backups using the following command:<pre><code class=language-shell>pgo show backup mycluster --backup-type=pgbackrest
</code></pre><p>Users can perform a point-in-time restore of a given cluster with pgBackRest using the following command:<pre><code class=language-shell>pgo restore mycluster --backup-opts="--type=time" --pitr-target="2019-01-14 00:02:14.921404+00"
</code></pre><p><strong>Note</strong>: When you restore a cluster, you are putting your PostgreSQL database into a different state (or timeline) and therefore you should exercise caution before doing so!<h2 id=fast-failover><a href=#fast-failover>Fast Failover</a></h2><p>A key component of <a href=https://access.crunchydata.com/documentation/postgresql11/11.1/high-availability.html>high-availability</a> is ensuring that you are able to quickly <a href=https://access.crunchydata.com/documentation/postgresql11/11.1/warm-standby-failover.html>fail over</a> from a primary to a replica database in order to limit your downtime. This new release of the PostgreSQL Operator ensures that failovers are fast: a replica can now be promoted to a primary in only a matter of milliseconds!<h2 id=archive-storage-configuration><a href=#archive-storage-configuration>Archive Storage Configuration</a></h2><p>For PostgreSQL Operator users that require and have enabled archiving, but have elected not to use pgBackRest, this release provides a means to specify storage volume sizes specifically for their archive volumes. In this new release, users can now specify configuration setting for your WAL archives in the pgo.yaml configuration file using the <code>XlogStorageConfig</code> setting.<h2 id=auto-failover-toggle><a href=#auto-failover-toggle>Auto-failover Toggle</a></h2><p>Users can now turn off and back on the auto-failover feature for a given cluster. This is helpful for when you need to do maintenance for a PostgreSQL cluster (or perhaps you just want to avoid auto-failover from kicking in).<p>This is performed using the command line:<pre><code class=language-shell>pgo update mycluster --label=autofail=false
</code></pre><h2 id=preferred-failover-node-label><a href=#preferred-failover-node-label>Preferred Failover Node Label</a></h2><p>In PostgreSQL Operator 3.5, we have added a Kubernetes <a href=https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/>label</a> selector setting within the pgo.yaml configuration file. If set, this selector will be used to determine a list of preferred Kubernetes <a href=https://kubernetes.io/docs/concepts/architecture/nodes/>nodes</a> on which a target would be selected as part of a failover, whether manual or automated. This feature supports a more precise failover target selection and will be expanded in future versions.<h2 id=pgo-scheduler><a href=#pgo-scheduler>pgo-scheduler</a></h2><p>In PostgreSQL Operator 3.5, we wrote a dedicated and highly integrated cron scheduler which now runs within the Operator pod. This scheduler is tightly integrated into the Operator and offers users a means to schedule <a href=https://access.crunchydata.com/documentation/postgresql11/11.1/app-pgbasebackup.html>pg_basebackup</a>, <a href=https://pgbackrest.org/>pgBackRest</a>, and policy scheduled jobs (or in other words, jobs where you want to run your own SQL). Users interact with the scheduler using the following commands:<pre><code class=language-shell>pgo create schedule
pgo delete schedule
pgo show schedule
</code></pre><h2 id=documentation><a href=#documentation>Documentation</a></h2><p>Lastly the entire <a href=https://access.crunchydata.com/documentation/postgres-operator/latest>Operator documentation</a> was redesigned and rewritten to better describe the current features of the Operator.<h2 id=final-thoughts><a href=#final-thoughts>Final Thoughts</a></h2><p>Crunchy Data views the PostgreSQL Operator as an enabling component for enterprises interested in deploying Kubernetes native PostgreSQL-as-a-Service. In this 3.5 release, we have targeted specific new functionality that will better enable enterprises to deploy increasingly sophisticated containerized PostgreSQL infrastructure in a highly integrated Kubernetes environment.<p>While this release represents a major milestone, the rapid innovation demonstrated by the Kubernetes community and the potential for the Operator pattern provides an opportunity for continued improvements in a variety of directions. You can also find more information about running <a href=https://www.crunchydata.com/products/crunchy-postgresql-for-kubernetes>PostgreSQL on Kubernetes</a> on our <a href=https://www.crunchydata.com>website</a>.<p>Please stay tuned, and we welcome any feedback or questions as you get started. ]]></content:encoded>
<category><![CDATA[ Kubernetes ]]></category>
<author><![CDATA[ Jeff.McCormick@crunchydata.com (Jeff McCormick) ]]></author>
<dc:creator><![CDATA[ Jeff McCormick ]]></dc:creator>
<guid isPermalink="false">https://blog.crunchydata.com/blog/crunchy-postgresql-operator-3.5-new-features</guid>
<pubDate>Thu, 24 Jan 2019 04:00:00 EST</pubDate>
<dc:date>2019-01-24T09:00:00.000Z</dc:date>
<atom:updated>2019-01-24T09:00:00.000Z</atom:updated></item>
<item><title><![CDATA[ PostgreSQL Operator for Kubernetes ]]></title>
<link>https://www.crunchydata.com/blog/postgres-operator-for-kubernetes</link>
<description><![CDATA[ PostgreSQL Operator for Kubernetes from Crunchy Data ]]></description>
<content:encoded><![CDATA[ <p>Crunchy Data is pleased to announce an initial implementation of a PostgreSQL Operator for Kubernetes to build on our work with PostgreSQL Containers. This initial implementation provides a user with the ability to perform certain PostgreSQL functions including creating PostgreSQL clusters, performing database backup and restores and viewing persistent volume claims.<h2 id=operators><a href=#operators>Operators</a></h2><p>Last November the team at CoreOS introduced the concept of an “application-specific controller” for Kubernetes called <a href=https://coreos.com/blog/introducing-operators.html>software Operators</a>. In their announcement, CoreOS suggested Operators as a means to more efficiently manage database infrastructure.<p>Crunchy Data has previously released a <a href=https://www.crunchydata.com/products/crunchy-postgresql-for-kubernetes>suite of containers for deploying, administering and monitoring PostgreSQL</a> and leveraging the Operator concept to further advance the deployment and management of PostgreSQL functions within Kubernetes was a natural extension of our work to date.<p>To that end, Crunchy Data is pleased to announce an initial implementation of a PostgreSQL Operator.<h2 id=initial-scope><a href=#initial-scope>Initial Scope</a></h2><p>For the initial release of a PostgreSQL operator our team has focused on a few basic operations that a user would interact with on a daily basis including:<ul><li>View existing databases and clusters<li>Create a single master or master-replica PostgreSQL configuration<li>Delete a single master or entire PostgreSQL deployment<li>Perform a database backup and list prior backups<li>Perform a database restore<li>Provide visibility into a Persistent Volume Claim</ul><h2 id=design-features><a href=#design-features>Design Features</a></h2><p>The Operator concept makes use of <dfn>Third Party Resources</dfn> (<abbr>TPR</abbr>) to create a set of domain specific objects that pertain to a specific application. This Operator creates PostgreSQL specific objects, including: pgdatabase, pgcluster, and pgbackup. A few additional notes on the design:<ul><li>The PostgreSQL Operator runs in a Deployment on the Kubernetes cluster and watches for TPR events<li>The user interface of the PostgreSQL Operator is a command line utility called <code>pgo</code><li>The PostgreSQL Operator allows for a variety of Persistent Volume technologies to be used such as HostPath, NFS, and block storage.<li>The PostgreSQL Operator allows for different deployment strategies to be defined. A Deployment Strategy in the case is the set of objects that the Operator will create for a new database or PostgreSQL cluster including Pods, Services, Deployments, etc. This is a key feature in that different customers will want to customize exactly how their PostgreSQL databases are deployed.</ul><p>The following diagram shows the <code>pgo</code> client communicating to the Postgres Operator running within the Kubernetes Cluster and causing the Operator to create or act upon PostgreSQL containers.<p><img alt=postgres-operator-blog-diagram.png loading=lazy src=https://cdn2.hubspot.net/hubfs/2283855/postgres-operator-blog-diagram.png><h2 id=source-code><a href=#source-code>Source Code</a></h2><p>The PostgreSQL Operator is primarily written in golang and available on <a href=https://github.com/CrunchyData/postgres-operator>GitHub</a>. Instructions on building the code is found under the heading Build-Setup Documentation.<p>A binary release is provided along with the requisite Docker images on <a href=https://github.com/CrunchyData/postgres-operator>Docker Hub</a>.<h2 id=getting-started><a href=#getting-started>Getting Started</a></h2><p>In order to get started, a user can build a single master PostgreSQL database using the <code>pgo</code> command line utility as follows:<pre><code class=language-shell>pgo create database mydatabase
</code></pre><p>This command creates a database TPR upon which the Operator will act. This command will cause the PostgreSQL Operator to use the default database deployment strategy and create a Pod running the PostgreSQL database along with a Service mapped to the database pod.<p>A user can then view the database using the following command:<pre><code class=language-shell>$ pgo show database mydatabase**

database : mydatabase**

├── pod : mydatabase (Running)**

└── service : mydatabase (10.108.0.81)
</code></pre><p>Once the database is created, a user can perform a database backup using the following command:<pre><code class=language-shell>pgo create backup mydatabase
</code></pre><p>This command will create Kubernetes Job that executes a full database backup on the previously created PostgreSQL database named mydatabase.<p>The following command allows a user to view the backup:<pre><code class=language-shell>$ pgo show backup mydatabase

pgbackup mydatabase was found PVC_NAME is crunchy-pvc

backup job pods for database mydatabase...

└── backup-mydatabase-63fw1

└── mydatabase

database pod mydatabase is found

├── mydatabase-backups/2017-03-27-13-54-33

├── mydatabase-backups/2017-03-27-13-56-49

└── mydatabase-backups/2017-03-27-14-02-38
</code></pre><p>Once the backup has been created, it is possible to create a database off of that backup using the following command:<pre><code class=language-shell>$ pgo create database myrestoredb
--backup-path=mydatabase/2017-03-27-14-02-38 --backup-pvc=mydatabase-pvc
</code></pre><h2 id=deploying-a-postgresql-cluster><a href=#deploying-a-postgresql-cluster>Deploying a PostgreSQL Cluster</a></h2><p>Lastly, lets create a more complex PostgreSQL cluster:<pre><code class=language-shell>pgo create cluster mycluster
</code></pre><p>This command creates a master database deployment, replica database deployment, a service for the master, and a service for the replicas.<pre><code class=language-bash>$ pgo show cluster mycluster**

cluster : mycluster

├── deployment : mycluster

├── deployment : mycluster-replica

├── replicaset : mycluster-2460202476

├── replicaset : mycluster-replica-306362430

├── pod : mycluster-2460202476-ndndb (Running)

├── pod : mycluster-replica-306362430-blzvd (Running)

├── pod : mycluster-replica-306362430-s32g7 (Running)

├── service : mycluster (10.107.139.100)

└── service : mycluster-replica (10.100.198.149)
</code></pre><p>Finally, it is possible to delete of all of the databases created using the following command:<pre><code class=language-shell>pgo delete database mydatabase

pgo delete cluster mycluster
</code></pre><h2 id=conclusion><a href=#conclusion>Conclusion</a></h2><p>The Third Party Resource API and golang client projects are both emerging frameworks that let allow application providers like Crunchy Data to build a rich native orchestration layer for Kubernetes In our case, our orchestration is focused on the PostgreSQL database but the pattern and frameworks could certainly be applied to other applications.<p>In particular, the Operator concept provides an exciting new platform Crunchy Data looks forward to build on and further advances our objective of saving users time in deploying and managing container based PostgreSQL databases infrastructure. This blog provides an discussion of an initial set of PostgreSQL Operator functions. Crunchy Data plans to continue our development to offer more extensive and advanced PostgreSQL automation in future versions of the PostgreSQL Operator, so please stay tuned!<h2 id=other-resources><a href=#other-resources>Other Resources</a></h2><p><a href=https://www.crunchydata.com/blog/deploying-postgresql-clusters-kubernetes-statefulsets>Deploying PostgreSQL Clusters Using StatefulSets</a><p><a href=https://www.crunchydata.com/blog/creating-a-postgresql-cluster-using-helm-for-kubernetes>Creating a PostgreSQL Cluster Using Helm</a> ]]></content:encoded>
<category><![CDATA[ Kubernetes ]]></category>
<author><![CDATA[ Jeff.McCormick@crunchydata.com (Jeff McCormick) ]]></author>
<dc:creator><![CDATA[ Jeff McCormick ]]></dc:creator>
<guid isPermalink="false">https://blog.crunchydata.com/blog/postgres-operator-for-kubernetes</guid>
<pubDate>Tue, 28 Mar 2017 05:00:00 EDT</pubDate>
<dc:date>2017-03-28T09:00:00.000Z</dc:date>
<atom:updated>2017-03-28T09:00:00.000Z</atom:updated></item>
<item><title><![CDATA[ Deploying PostgreSQL Clusters using Kubernetes StatefulSets ]]></title>
<link>https://www.crunchydata.com/blog/deploying-postgresql-clusters-kubernetes-statefulsets</link>
<description><![CDATA[ Simple steps to build a PostgreSQL cluster using the new StatefulSet feature available in Kubernetes 1.5. ]]></description>
<content:encoded><![CDATA[ <p>This blog provides guidance on how to build a PostgreSQL cluster using the new Kubernetes feature - <a href=https://kubernetes.io/docs/concepts/abstractions/controllers/statefulsets/>StatefulSet</a>. Using this StatefulSet capability provides a very simple, Kubernetes native, mechanism to make clustering decisions when deploying a PostgreSQL cluster.<p>The <a href=https://www.crunchydata.com/products/crunchy-postgresql-for-kubernetes>Crunchy PostgreSQL Container Suite</a> is a set of containers that can be used to deploy, monitor, and administer the open source PostgreSQL database. More details can be found in the crunchy-containers GitHUB repository <a href=https://github.com/CrunchyData/crunchy-containers>here</a> In a prior <a href=https://www.crunchydata.com/blog/creating-a-postgresql-cluster-using-helm-for-kubernetes>blog</a>, Crunchy Data described how to deploy a similar cluster using <a href=https://github.com/kubernetes/helm>Helm</a>.<p>(This blog cross-posted at the kubernetes.io blog <a href=https://blog.kubernetes.io/2017/02/postgresql-clusters-kubernetes-statefulsets.html>here</a>)<h2 id=statefulsets-example><a href=#statefulsets-example>StatefulSets Example</a></h2><h3 id=step-1---create-kube-environment><a href=#step-1---create-kube-environment>Step 1 - Create Kube Environment</a></h3><p>StatefulSets is a new feature and, as a result, running this example will require an environment based on Kubernetes 1.5.<p>The example in this blog deploys on Centos7 using <code>kubeadm</code>. Some instructions on what <a href=https://kubernetes.io/docs/reference/setup-tools/kubeadm/>kubeadm</a> provides and how to deploy a Kubernetes cluster is located <a href=https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/>here</a>.<h3 id=step-2---install-nfs><a href=#step-2---install-nfs>Step 2 - Install NFS</a></h3><p>The example in this blog uses NFS for the Persistent Volumes, but any shared file system would also work (ex: ceph, gluster). Reference documentation for Volumes can be found <a href=https://kubernetes.io/docs/concepts/storage/volumes/>here</a>.<p>The example script assumes the NFS server is running locally and the hostname resolves to a known IP address.<p>In summary, the steps used to get NFS working on a Centos 7 host are as follows:<pre><code class=language-bash>sudo setsebool -P virt_use_nfs 1
sudo yum -y install nfs-utils libnfsidmap
sudo systemctl enable rpcbind nfs-server
sudo systemctl start rpcbind nfs-server rpc-statd nfs-idmapd
sudo mkdir /nfsfileshare
sudo chmod 777 /nfsfileshare/
sudo vi /etc/exports
sudo exportfs -r
</code></pre><p>The /etc/exports file should contain a line similar to this one except with the applicable IP address specified:<pre><code class=language-bash>/nfsfileshare 192.168.122.9(rw,sync)
</code></pre><p>After these steps NFS should be running in the test environment.<h3 id=step-3---clone-the-crunchy-container-repo><a href=#step-3---clone-the-crunchy-container-repo>Step 3 - Clone the Crunchy Container Repo</a></h3><p>The example used in this blog is found at in the Crunchy Containers GitHUB repo <a href=https://github.com/CrunchyData/crunchy-containers.git>here</a>. Clone the Crunchy Containers repository to the applicable test Kubernertes host and go to the example:<pre><code class=language-bash>cd $HOME
git clone https://github.com/CrunchyData/crunchy-containers.git
cd crunchy-containers/examples/kube/statefulset
</code></pre><p>Next, pull down the crunchy-postgres container image:<pre><code class=language-docker>docker pull crunchydata/crunchy-postgres:centos7-9.5-1.2.6
</code></pre><h3 id=step-4---run-the-example><a href=#step-4---run-the-example>Step 4 - Run the Example</a></h3><p>To begin, it is necessary to set a few of the environment variables used in the example:<pre><code class=language-bash>export BUILDBASE=$HOME/crunchy-containers
export CCP_IMAGE_TAG=centos7-9.5-1.2.6
</code></pre><p>BUILDBASE is where you cloned the repository and CCP_IMAGE_TAG is the container image version we want to use.<p>Next, run the example:<pre><code class=language-bash>./run.sh
</code></pre><p>That script will create several Kubernetes objects including:<ul><li>Persistent Volumes (pv1, pv2, pv3)<li>Persistent Volume Claim (pgset-pvc)<li>Service Account (pgset-sa)<li>Services (pgset, pgset-master, pgset-replica)<li>StatefulSet (pgset)<li>Pods (pgset-0, pgset-1)</ul><p>At this point, two pods will be running in the environment:<pre><code class=language-bash>$ kubectl get pod

NAME      READY   STATUS    RESTARTS   AGE
pgset-0   1/1     Running   0          2m
pgset-1   1/1     Running   1          2m
</code></pre><p>Immediately after the pods are created, the deployment will be as depicted below:<p><img alt="StatefulSets Blog Diagram 1.png"loading=lazy src=https://cdn2.hubspot.net/hubfs/2283855/StatefulSets%20Blog%20Diagram%201.png><h3 id=step-5---what-just-happened><a href=#step-5---what-just-happened>Step 5 - What Just Happened?</a></h3><p>This example will deploy a StatefulSet, which in turn creates two pods.<p>The containers in those two pods run the database. For a replicating cluster, we need one of the containers to assume the master role and the other containers to assume the replica role.<p>So, how do the containers determine who will be the master, and who will be the replica?<p>This is where the new StateSet mechanics come into play. The StateSet mechanics assign a unique ordinal value to each pod in the set.<p>The StatefulSets provided unique ordinal value always start with 0. During the initialization of the container, each container examines its assigned ordinal value. An ordinal value of 0 causes the container to assume the master role within the database cluster. For all other ordinal values, the container assumes a replica role. This is a very simple form of discovery made possible by the StatefulSet mechanics.<p>Replicas are configured to connect to the master database via a Service dedicated to the master database. In order to support this replication, the example creates a separate Service for each of the master role and the replica role. Once the replica has connected, the replica will begin replicating state from the master.<p>During the container initialization, a master container will use a <a href=https://kubernetes.io/docs/concepts/security/service-accounts/>Service Account</a> (pgset-sa) to change it’s container label value to match the master Service selector. Changing the label is important to enable traffic destined to the master database to reach the correct container within the Stateful Set. All other pods in the set assume the replica Service label by default.<h3 id=step-6---deployment-diagram><a href=#step-6---deployment-diagram>Step 6 - Deployment Diagram</a></h3><p>The example results in a deployment depicted below:<p><img alt="StatefulSets Blog Diagram 2.png"loading=lazy src=https://cdn2.hubspot.net/hubfs/2283855/StatefulSets%20Blog%20Diagram%202.png>In this deployment, there is a Service for the master and a separate Service for the replica. The replica is connected to the master and replication of state has started.<p>The crunchy-postgres container supports other forms of cluster deployment, the style of deployment is dictated by setting the PG_MODE environment variable for the container. In the case of a StatefulSet deployment, that value is set to:<pre><code class=language-pgsql>PG_MODE=set
</code></pre><p>This environment variable is a hint to the container initialization logic as to the style of deployment intended.<h3 id=step-7---testing-the-example><a href=#step-7---testing-the-example>Step 7 - Testing the Example</a></h3><p>The tests below assume that the psql client has been installed on the test system. If if not, the psql client has been previously installed, it can be installed as follows:<pre><code class=language-bash>sudo yum -y install postgresql
</code></pre><p>In addition, the tests below assume that the tested environment DNS resolves to the Kube DNS and that the tested environment DNS search path is specified to match the applicable Kube namespace and domain. The master service is named pgset-master and the replica service is named pgset-replica.<p>Test the master as follows (the password is <code>password</code>):<pre><code class=language-bash>psql -h pgset-master -U postgres postgres -c 'table pg_stat_replication'
</code></pre><p>If things are working, the command above will return output indicating that a single replica is connecting to the master.<p>Next, test the replica as follows:<pre><code class=language-bash>psql -h pgset-replica -U postgres postgres -c 'create table foo (id int)'
</code></pre><p>The command above should fail as the replica is <code>read-only</code> within the cluster.<p>Next, scale up the set as follows:<pre><code class=language-bash>kubectl scale statefulset pgset --replicas=3
</code></pre><p>The command above should successfully create a new replica pod called <code>pgset-2</code> as depicted below:<p><img alt="StatefulSets Blog Diagram 3.png"loading=lazy src=https://cdn2.hubspot.net/hubfs/2283855/StatefulSets%20Blog%20Diagram%203.png><h3 id=step-8---persistence-explained><a href=#step-8---persistence-explained>Step 8 - Persistence Explained</a></h3><p>Take a look at the persisted data files on the resulting NFS mount path:<pre><code class=language-bash>ls -l /nfsfileshare/
</code></pre><pre><code class=language-bash>total 12
drwx------ 20 26 26 4096 Jan 17 16:35 pgset-0
drwx------ 20 26 26 4096 Jan 17 16:35 pgset-1
drwx------ 20 26 26 4096 Jan 17 16:48 pgset-2
</code></pre><p>Each container in the StatefulSet binds to the single NFS Persistent Volume Claim (pgset-pvc) created in the example script.<p>Since NFS and the PVC can be shared, each pod can write to this NFS path.<p>The container is designed to create a subdirectory on that path using the pod host name for uniqueness.<h2 id=conclusion><a href=#conclusion>Conclusion</a></h2><p>StatefulSets is an exciting feature added to Kubernetes for container builders that are implementing clustering. The ordinal values assigned to the set provide a very simple mechanism to make clustering decisions when deploying a PostgreSQL cluster.<p>To learn more contact Crunchy Data at <a href=mailto:info@crunchydata.com>info@crunchydata.com</a> ]]></content:encoded>
<category><![CDATA[ Kubernetes ]]></category>
<author><![CDATA[ Jeff.McCormick@crunchydata.com (Jeff McCormick) ]]></author>
<dc:creator><![CDATA[ Jeff McCormick ]]></dc:creator>
<guid isPermalink="false">https://blog.crunchydata.com/blog/deploying-postgresql-clusters-kubernetes-statefulsets</guid>
<pubDate>Sun, 26 Feb 2017 04:00:00 EST</pubDate>
<dc:date>2017-02-26T09:00:00.000Z</dc:date>
<atom:updated>2017-02-26T09:00:00.000Z</atom:updated></item>
<item><title><![CDATA[ Easy PostgreSQL Cluster Recipe Using Docker 1.12 and Swarm ]]></title>
<link>https://www.crunchydata.com/blog/easy-postgresql-cluster-recipe-using-docker-1.12</link>
<description><![CDATA[ An overview of how to set up and run PostgreSQL in docker containers using docker 1.12. ]]></description>
<content:encoded><![CDATA[ <h2 id=update><a href=#update>UPDATE</a></h2><p>PLEASE READ THE UPDATED VERSION: <a href=https://www.crunchydata.com/blog/an-easy-recipe-for-creating-a-postgresql-cluster-with-docker-swarm>AN EASY RECIPE FOR CREATING A POSTGRESQL CLUSTER WITH DOCKER SWARM</a><p>The below content has been deprecated in favor of <a href=https://www.crunchydata.com/blog/an-easy-recipe-for-creating-a-postgresql-cluster-with-docker-swarm>An Easy Recipe for Creating a PostgreSQL Cluster with Docker Swarm</a>.<h2 id=deprecated-recipe><a href=#deprecated-recipe>Deprecated Recipe</a></h2><p>In this blog I’ll show you how to deploy a PostgreSQL cluster using the latest Docker 1.12 technology. Updates to Docker in their 1.12 release greatly simplify deploying a PostgreSQL cluster. IP addresses and hostnames used in this blog are just examples and not mandated.<h3 id=recipe-step-1---environment><a href=#recipe-step-1---environment>Recipe Step 1 - Environment</a></h3><p>To start with, provision a Docker cluster. For this example, I have deployed a development cluster that looks like this:<p><img alt=docker-cluster-v2.png loading=lazy src=https://cdn2.hubspot.net/hubfs/2283855/docker-cluster-v2.png><p>Each host has Docker 1.12 installed and enabled.<h3 id=recipe-step-2---swarm-setup><a href=#recipe-step-2---swarm-setup>Recipe Step 2 - Swarm Setup</a></h3><p>Docker 1.12 now includes the Swarm clustering technology directly within the Docker Engine. On your Docker 1.12 cluster, you will need to configure Swarm as documented here:<p><a href=https://docs.docker.com/engine/swarm/swarm-tutorial/create-swarm>https://docs.docker.com/engine/swarm/swarm-tutorial/create-swarm</a><p>This setup will include initializing Swarm on the Manager designated node using:<pre><code class=language-shell>docker swarm init --advertise-addr 192.168.10.1
</code></pre><p>Then on the other Docker worker nodes you would enter this command for them to join the Swarm:<pre><code class=language-shell>docker swarm join --token SWMTKN-1-65cn5wa1qv76l8l45uvlsbprogyhlprjpn27p1qxjwqmncn37o-015egopg4jhtbmlu04faon82u 192.168.10.1:2377
</code></pre><h3 id=recipe-step-3---docker-network-setup><a href=#recipe-step-3---docker-network-setup>Recipe Step 3 - Docker Network Setup</a></h3><p>Docker 1.12 also includes the ability to define an overlay network to be shared by a set of containers, again this feature is directly built into the Docker Engine. For this PostgreSQL cluster example, we create an overlay network (on the manager node), named <code>crunchynet</code>, as follows:<pre><code class=language-shell>docker network create --driver overlay crunchynet
</code></pre><p>This overlay network will provide us a means to perform service discovery between the PostgreSQL replica containers and the PostgreSQL master container. In PostgreSQL streaming replication (clustering), the replica containers need to be able to locate a master database by either IP address or a hostname that will resolve via DNS. The Docker overlay network provides this lookup capability for us if the PostgreSQL containers are all connected to the same overlay network. Within the overlay network, Docker will allow us to resolve the PostgreSQL host using the Docker service name.<h3 id=recipe-step-4---container-placement><a href=#recipe-step-4---container-placement>Recipe Step 4 - Container Placement</a></h3><p>For a highly available PostgreSQL cluster configuration you would want the master database to run on a different host than where the replica databases will be run. Also, you might have a particular host you want the master container to be running on since it will be providing a write capability. Remember, in a PostgreSQL cluster, replica databases are read-only, whereas the master is read-write. So, you might want the master container to be placed on a host with a very fast local disk performance capability.<p>To allow for container placement, we will add a metadata label to our Swarm nodes as follows:<pre><code class=language-shell>docker node inspect worker1 | grep IDdocker node update --label-add type=master 18yrb7m650umx738rtevojpqy
</code></pre><p>In the above example, the <code>worker1</code> node with ID <code>18yrb7m650umx738rtevojpqy</code> has a user defined label of “<code>master</code>” added to it. The master service specifies “<code>master”</code> as a constraint when created, this tells Swarm to place the service on that specific node. The replica specifies a constraint of “<code>node.labels.type != master</code>” to have the replica always placed on a node that is not hosting the master service.<h3 id=recipe-step-5---postgresql-cluster-startup><a href=#recipe-step-5---postgresql-cluster-startup>Recipe Step 5 - PostgreSQL Cluster Startup</a></h3><p>Finally, we have all the wiring and configuration in place to start running our PostgreSQL cluster. Docker 1.12 provides the service abstraction around the underlying deployed containers. This is a powerful abstraction in that it provides a higher-level form of identifying and deploying your application containers across a set of Docker Swarm hosts.<p>Our PostgreSQL cluster will be comprised of a PostgreSQL master service and a PostgreSQL replica service. Services are created by running the following commands on the Swarm manager node:<pre><code class=language-shell>docker service create \
  --mount type=volume,src=$MASTER_SERVICE_NAME-volume,dst=/pgdata,volume-driver=local \
  --name $MASTER_SERVICE_NAME \
  --network crunchynet \
  --constraint 'node.labels.type == master' \
  --env PGHOST=/tmp \
  --env PG_USER=testuser \
  --env PG_MODE=master \
  --env PG_MASTER_USER=master \
  --env PG_ROOT_PASSWORD=password \
  --env PG_PASSWORD=password \
  --env PG_DATABASE=userdb \
  --env PG_MASTER_PORT=5432 \
  --env PG_MASTER_PASSWORD=password \
  crunchydata/crunchy-postgres:centos7-9.5-1.2.5
</code></pre><p>Then create the replica service as follows:<pre><code class=language-shell>docker service create
  --mount type=volume,src=$VOLUME_NAME,dst=/pgdata,volume-driver=local \
  --name $SERVICE_NAME \
  --network crunchynet \
  --constraint 'node.labels.type != master' \
  --env PGHOST=/tmp \
  --env PG_USER=testuser \
  --env PG_MODE=slave \
  --env PG_MASTER_USER=master \
  --env PG_ROOT_PASSWORD=password \
  --env PG_PASSWORD=password \
  --env PG_DATABASE=userdb \
  --env PG_MASTER_PORT=5432 \
  --env PG_MASTER_PASSWORD=password \
  --env PG_MASTER_HOST=$MASTER_SERVICE_NAME \
  crunchydata/crunchy-postgres:centos7-9.5-1.2.5
</code></pre><p>After running these commands, you will end up with a deployment of containers as depicted in this diagram:<p><img alt=docker112-pg-cluster-v2.png loading=lazy src=https://cdn2.hubspot.net/hubfs/2283855/docker112-pg-cluster-v2.png><p>Note the following lines from the examples above when creating the Docker services:<pre><code class=language-shell>--constraint 'node.labels.type == master'
</code></pre><p>This line supplies a constraint to the Swarm manager when choosing what Swarm node to run the container, in this case, we want the master database container to always run on a host with the master label type, in our case this is the worker1 host.<pre><code class=language-shell>--network crunchynet
</code></pre><p>This line specifies the network we want the container to use, in our case the network is called crunchynet.<pre><code class=language-shell>--mount type=volume,src=$VOLUME_NAME,dst=/pgdata,volume-driver=local
</code></pre><p>This line specifies a dynamically created Docker volume be created using the local driver and which will be mounted to the /pgdata directory within the PostgreSQL container. The /pgdata volume is where PostgreSQL will store it’s data files.<pre><code class=language-shell>--env PG_MASTER_HOST=$MASTER_SERVICE_NAME
</code></pre><p>This line specifies the master PostgreSQL database host and in this case is the Docker service name used for the master database service. This name is resolved by means of the overlay network we created, crunchynet.<h3 id=recipe-step-6---testing-the-cluster><a href=#recipe-step-6---testing-the-cluster>Recipe Step 6 - Testing the Cluster</a></h3><p>Docker 1.12 provides the service abstraction around the underlying deployed containers. You can view the deployed services as follows:<pre><code class=language-shell>docker service ps master
</code></pre><pre><code class=language-shell>docker service ps replica
</code></pre><p>Given the PostgreSQL replica service is named <code>replica</code>, you can scale up the number of replica containers by running this command:<pre><code class=language-shell>docker service scale replica=2
</code></pre><pre><code class=language-shell>docker service ls
</code></pre><p>You can verify you have two replicas within PostgreSQL by viewing the <code>pg_stat_replication</code> table, the password is <code>password</code>, when logged into the <code>kubernetes-node-1</code> host:<pre><code class=language-shell>docker exec -it $(docker ps -q) psql -U postgres -c 'table pg_stat_replication' postgres
</code></pre><p>You should see a row for each replica along with its replication status.<h3 id=example-code><a href=#example-code>Example Code</a></h3><p>The example described above is provided in the Crunchy Containers Suite github in the following location:<p><a href=https://github.com/CrunchyData/crunchy-containers/tree/master/examples/docker/swarm-service>https://github.com/CrunchyData/crunchy-containers/tree/master/examples/docker/swarm-service</a><h3 id=conclusion><a href=#conclusion>Conclusion</a></h3><p>The update to Docker with the 1.12 release contains an impressive set of new features that greatly simplify enterprises in deploying PostgreSQL to their container environments. I look forward to other enterprise container features being added to the Docker engine including a distributed storage implementation.<p>Jeff McCormick, the author, works for Crunchy Data, a leading provider of enterprise open source PostgreSQL technology, support and training. ]]></content:encoded>
<category><![CDATA[ Postgres Tutorials ]]></category>
<author><![CDATA[ Jeff.McCormick@crunchydata.com (Jeff McCormick) ]]></author>
<dc:creator><![CDATA[ Jeff McCormick ]]></dc:creator>
<guid isPermalink="false">https://blog.crunchydata.com/blog/easy-postgresql-cluster-recipe-using-docker-1.12</guid>
<pubDate>Thu, 22 Dec 2016 04:00:00 EST</pubDate>
<dc:date>2016-12-22T09:00:00.000Z</dc:date>
<atom:updated>2016-12-22T09:00:00.000Z</atom:updated></item></channel></rss>