PostgreSQL Charm Cross Model Support

Cross model relation support has been added to the PostgreSQL Charm for Juju, best experienced with Juju 2.3 or later. When clients also support this feature, you can split your deployment across multiple models, even across controllers and clouds. Making a charms.reactive client charm support cross model relations should involve nothing more than rebuilding and publishing it; the PostgreSQL interface has also been updated and knows how to use the new ingress and egress address information and its API is unchanged.

The main reasons for splitting your deployments into multiple models this way are to spread out parts of your deployment to other availability zones or clouds, or when different teams are maintaining different parts of a complex deployment (e.g. connecting developer maintained clients to DBA maintained back ends.

Here is a brief walk through connecting clients to a server across continents. This example is using two AWS regions, but this works just as well with other supported clouds (Azure, GCE, OpenStack, etc.), and between cloud providers.

First, I’m going to bootstrap two completely independent Juju controllers. Most sites will use a single HA Juju Controller for production, with multiple controllers only desirable when there are independent regional teams needing to maintain independent infrastructure.

$ juju bootstrap aws/ap-southeast-1 --constraints="mem=2G cores=1" singapore
Creating Juju controller "singapore" on aws/ap-southeast-1
Looking for packaged Juju agent version 2.3.5 for amd64
Launching controller instance(s) on aws/ap-southeast-1...
 - i-0fae2f267c2a3c0aa (arch=amd64 mem=2G cores=1)ap-southeast-1a"
Installing Juju agent on bootstrap instance
Fetching Juju GUI 2.12.1
Waiting for address
Attempting to connect to 52.77.212.143:22
Attempting to connect to 172.31.12.2:22
Connected to 52.77.212.143
Running machine configuration script...
Bootstrap agent now started
Contacting Juju controller at 52.77.212.143 to verify accessibility...
Bootstrap complete, "singapore" controller now available
Controller machines are in the "controller" model
Initial model "default" added

$ juju bootstrap aws/ap-southeast-2 sydney
Creating Juju controller "sydney" on aws/ap-southeast-2
Looking for packaged Juju agent version 2.3.5 for amd64
Launching controller instance(s) on aws/ap-southeast-2...
 - i-097eedbeaec354996 (arch=amd64 mem=4G cores=2)ap-southeast-2a"
Installing Juju agent on bootstrap instance
Fetching Juju GUI 2.12.1
Waiting for address
Attempting to connect to 172.31.0.23:22
Attempting to connect to 13.211.134.68:22
Connected to 13.211.134.68
Running machine configuration script...
Bootstrap agent now started
Contacting Juju controller at 13.211.134.68 to verify accessibility...
Bootstrap complete, "sydney" controller now available
Controller machines are in the "controller" model
Initial model "default" added

Next, I’ll create models in each controller. I’ll deploy a PostgreSQL primary and standby server to Singapore, and some clients to Sydney:

$ juju switch singapore
sydney (controller) -> singapore:admin/default
$ juju add-model server
Uploading credential 'aws/admin/aws' to controller
Added 'server' model on aws/ap-southeast-1 with credential 'aws' for user 'admin'

$ juju deploy cs:postgresql -n 2
Located charm "cs:postgresql-174".
Deploying charm "cs:postgresql-174".

$ juju switch sydney
$ juju add-model client
Uploading credential 'aws/admin/aws' to controller
Added 'client' model on aws/ap-southeast-2 with credential 'aws' for user 'admin'
$ juju deploy cs:~postgresql-charmers/postgresql-client
Located charm "cs:~postgresql-charmers/postgresql-client-5".
Deploying charm "cs:~postgresql-charmers/postgresql-client-5".

Offer up the client Application, and consume the offer on the server. I’ll discuss shortly why it is this way around, and the service not being offered to the client:

$ juju offer client.postgresql-client:db client-db
Application "postgresql-client" endpoints [db] available at "admin/client.client-db"

$ juju status
Model  Controller Cloud/Region       Version SLA
client sydney     aws/ap-southeast-2 2.3.5   unsupported

App               Version Status  Scale Charm             Store      Rev OS Notes
postgresql-client 9.5     blocked 1     postgresql-client jujucharms 5   ubuntu

Unit                 Workload Agent Machine Public address Ports Message
postgresql-client/0* blocked  idle  0       13.210.156.16        Needs db relation

Machine State   DNS           Inst id             Series AZ              Message
0       started 13.210.156.16 i-0849fa7953f3fa1b7 xenial ap-southeast-2a running

Offer     Application       Charm             Rev Connected Endpoint Interface Role
client-db postgresql-client postgresql-client 5   0/0       db       pgsql     requirer
$ juju switch singapore:admin/server
sydney:admin/client -> singapore:admin/server

$ juju consume sydney:admin/client.client-db
Added sydney:admin/client.client-db as client-db

$ juju status
Model Controller Cloud/Region Version SLA
server singapore aws/ap-southeast-1 2.3.5 unsupported

SAAS      Status  Store  URL
client-db blocked sydney admin/client.client-db

App        Version Status Scale Charm      Store      Rev OS Notes
postgresql 9.5.12  active 2     postgresql jujucharms 174 ubuntu

Unit          Workload Agent Machine Public address Ports    Message
postgresql/0* active   idle  0       13.229.205.17  5432/tcp Live master (9.5.12)
postgresql/1  active   idle  1       13.250.20.84   5432/tcp Live secondary (9.5.12)

Machine State   DNS           Inst id             Series AZ              Message
0       started 13.229.205.17 i-0a0ce0ea34e4451da xenial ap-southeast-1a running
1       started 13.250.20.84  i-0c07e2cb0dfd95b69 xenial ap-southeast-1b running

Relation provider      Requirer               Interface   Type Message
postgresql:coordinator postgresql:coordinator coordinator peer 
postgresql:replication postgresql:replication pgpeer      peer

There are several different ways to connect the client and server models together, but for PostgreSQL you should make an offer from the client model, and consume it in the server model. This is because  Juju cross model relations are anonymized to avoid namespace clashes and other edge cases; the units in the client model will not know details about the model they are connected to. These details are irrelevant to most charms, but the PostgreSQL charm uses the remote application name to ensure that, when models are redeployed, that the same database credentials are used and the client units are redeployed with the same access to data that they had before. By consuming the offer made by the client model into the server model (and not the other way around), we can control the client application name seen by the PostgreSQL charm and the normal redeployment and disaster recovery processes work as expected.

Once the offer has been consumed, we end up with a proxy of sorts that works like a standard Juju Application; connecting the client Application to the server is done using the normal add-relation command:

$ juju add-relation postgresql:db client-db:db
$ juju wait
$ juju status
Model   Controller  Cloud/Region        Version  SLA
server  singapore   aws/ap-southeast-1  2.3.5    unsupported

SAAS       Status   Store   URL
client-db  blocked  sydney  admin/client.client-db

App         Version  Status  Scale  Charm       Store       Rev  OS      Notes
postgresql  9.5.12   active      2  postgresql  jujucharms  174  ubuntu  

Unit           Workload  Agent  Machine  Public address  Ports     Message
postgresql/0*  active    idle   0        13.229.205.17   5432/tcp  Live master (9.5.12)
postgresql/1   active    idle   1        13.250.20.84    5432/tcp  Live secondary (9.5.12)

Machine  State    DNS            Inst id              Series  AZ               Message
0        started  13.229.205.17  i-0a0ce0ea34e4451da  xenial  ap-southeast-1a  running
1        started  13.250.20.84   i-0c07e2cb0dfd95b69  xenial  ap-southeast-1b  running

Relation provider       Requirer                Interface    Type     Message
postgresql:coordinator  postgresql:coordinator  coordinator  peer     
postgresql:db           client-db:db            pgsql        regular  
postgresql:replication  postgresql:replication  pgpeer       peer     


$ juju switch sydney:admin/client
singapore:admin/server -> sydney:admin/client
$ juju ssh postgresql-client/0
Welcome to Ubuntu 16.04.4 LTS (GNU/Linux 4.4.0-1054-aws x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  Get cloud support with Ubuntu Advantage Cloud Guest:
    http://www.ubuntu.com/business/services/cloud

0 packages can be updated.
0 updates are security updates.



The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

PostgreSQL Client Charm
=======================

To connect to PostgreSQL:


psql service=db_master
psql service=db_1
psql service=db:0_master
psql service=db:0_1

To run a command as administrator (user "root"), use "sudo ".
See "man sudo_root" for details.

ubuntu@ip-172-31-7-119:~$ psql service=db_master
psql (9.5.12)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

cli=> create table itsalive(x int);
CREATE TABLE
cli=> \q
ubuntu@ip-172-31-7-119:~$ exit
logout
Connection to 13.210.156.16 closed.
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s