{"id":2128,"date":"2020-08-26T08:38:08","date_gmt":"2020-08-26T05:38:08","guid":{"rendered":"https:\/\/upcloud.com\/global\/us\/resources\/tutorials\/install-cockroachdb-secure-database-cluster\/"},"modified":"2020-08-26T08:38:08","modified_gmt":"2020-08-26T05:38:08","slug":"install-cockroachdb-secure-database-cluster","status":"publish","type":"tutorial","link":"https:\/\/upcloud.com\/global\/resources\/tutorials\/install-cockroachdb-secure-database-cluster\/","title":{"rendered":"How to install CockroachDB secure database cluster"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">CockroachDB is a distributed database designed for the cloud. It is built to be resilient, horizontally scalable and it is PostgreSQL wire-protocol compatible to a high degree. Together with UpCloud MaxIOPS storage, it can create high-performant and fault-tolerant, low-cost backend for applications. You can find more information about CockroachDB at <a href=\"https:\/\/www.cockroachlabs.com\/docs\/stable\/\" target=\"_blank\" rel=\"noopener\">their documentation<\/a>.<\/p>\n\n\n\n<div class=\"wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/signup.upcloud.com\/\">Test hosting on UpCloud!<\/a><\/div>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\">In this tutorial, we will install and set up a secure CockroachDB cluster on UpCloud. The cluster will be placed inside an SDN and client applications can connect to the database through an SQL client.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><b>Prerequisites:<\/b><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Register for UpCloud account<\/li>\n\n\n\n<li>SSH client such OpenSSH or Putty installed on your local computer<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><b>Overview of the tutorial steps:<\/b><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Creating a database node template<br>\u2013 Deploying the Ubuntu server<br>\u2013 Creating the CockroachDB user, setting up SSH<br>\u2013 Installing CockroachDB<\/li>\n\n\n\n<li>Setting up the CockroachDB server<br>\u2013 Creating the ballast file<br>\u2013 Keeping the servers synchronized<br>\u2013 Securing the connections to a node<\/li>\n\n\n\n<li>Setting up an SDN private network<br>\u2013 Create the SDN private network<br>\u2013 Connecting DB server to the private network<\/li>\n\n\n\n<li>Finalising the server template and creating custom image<br>\u2013 Creating a template systemd file<br>\u2013 Creating a custom image by cloning the storage<br>\u2013 Creating Node2 and Node3 from the custom image<\/li>\n\n\n\n<li>Initialising the CockroachDB cluster<br>\u2013 Setting up node-certificates for the nodes<br>\u2013 Create a local root client Certificate on Node1<br>\u2013 Starting up the nodes<br>\u2013 Initializing the cluster: The database is live!<\/li>\n\n\n\n<li>Connecting and testing the database<br>\u2013 Adding a test user and test database<br>\u2013 Logging in to the admin web-UI<br>\u2013 Testing the DB with DBeaver<\/li>\n\n\n\n<li>Continuing further<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">1. Creating a database node template<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The minimum number of nodes in a Cockroach database cluster is three, which gives CockroachDB the ability to tolerate the failure of one of the nodes. With five nodes we would be able to handle the simultaneous failure of two nodes, and so on. It is possible to scale the Cockroach DB cluster simply by adding servers to the cluster.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We will create three servers that act as nodes for the database. The servers will be identical, as Cockroach Labs, the developers of the Cockroach DB recommend that the nodes (or in our case, UpCloud servers that run Cockroach DB) are uniform for consistent SQL performance. We will create one server as a template and then use UpCloud server cloning functionality to create a cluster of three identical servers.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><b>The minimum requirements<\/b> for CockroachDB are 2 or more vCPUs and at least 2 GB of RAM. However, for actual production use it is recommended to have:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>2 or more vCPUs<\/li>\n\n\n\n<li>RAM of 2 GB per vCPU, which means for 2 vCPUs you should configure 4 GB of RAM<\/li>\n\n\n\n<li>Storage based on your workload, which will likely be over 200 GB. Cockroach Labs recommends a 300 \u2013 2 TiB storage for best performance results<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">It\u2019s good to note that for resiliency Cockroach Labs recommends using many smaller nodes instead of a few larger ones. With many smaller nodes, the data is more spread making recovery from a node failure faster.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For this installation tutorial, I\u2019m using the 5$\/month Simple plan Ubuntu server with 1 vCPU, 1 GB of RAM and 25GB of storage. Despite being well below the minimum requirements, it\u2019ll work perfectly for the purposes of this tutorial. The server plan can always be upgraded later.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Deploying Ubuntu server<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Creation of an Ubuntu server we will work with is straight-forward using the UpCloud control panel. If you haven\u2019t used UpCloud before, there\u2019s a <a href=\"https:\/\/upcloud.com\/global\/docs\/guides\/quick-start-guide\/\" target=\"_blank\" rel=\"noreferrer noopener\">quick start guide<\/a> that will get you up to speed in no time.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To deploy an Ubuntu server:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Login to the <a href=\"https:\/\/hub.upcloud.com\/\" target=\"_blank\" rel=\"noopener\">UpCloud Control Panel<\/a><\/li>\n\n\n\n<li>Go to the Servers tab<\/li>\n\n\n\n<li>Click Deploy Server<\/li>\n\n\n\n<li>Choose the location of your liking for the server, UK-LON1 in this tutorial<\/li>\n\n\n\n<li>Choose a plan for your server, the $5\/mo Simple plan will work fine to start with<\/li>\n\n\n\n<li>Choose the amount of storage, the $5\/mo Simple plan includes 25 GB, add a secondary storage device you want to have more at this point<\/li>\n\n\n\n<li>Choose Ubuntu Server as the operating system, 20.04 is the latest at the time of writing<\/li>\n\n\n\n<li>Give a hostname and a description to your server, i.e. cockroachnode1<\/li>\n\n\n\n<li>Click Deploy!<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">The server will now be created and you will get a password you can use to login to the server with root user. The next step is to set up a user that will run the CockroachDB.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Creating the user for CockroachDB and setting up SSH<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Instead of using the <em>root<\/em> user, we\u2019ll create a cockroach DB user <em>cradmin<\/em> and configure the database by using this user. We will also do some basic setup by disabling password login to the server and only allowing login using SSH keys. The following steps will create the user and setup SSH for Ubuntu, but you can read more about this setup for other OSes from these tutorials:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/upcloud.com\/global\/resources\/tutorials\/manage-linux-user-account-security\/\" target=\"_blank\" rel=\"noreferrer noopener\">Manage Linux User Account Security<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/upcloud.com\/global\/docs\/guides\/use-ssh-keys-authentication\/\" target=\"_blank\" rel=\"noreferrer noopener\">Use SSH-keys Authentication<\/a><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Log in to your server using Putty or some other SSH client via the public IP address of your server. We\u2019ll start by updating the server with the following command:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">apt update &amp;&amp; apt upgrade<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Afterwards, reboot your server and login again.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">reboot<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then follow on by creating the <em>cradmin<\/em> user using the next command:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">adduser cradmin<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">In Ubuntu, this command will prompt for a password and other user details. Fill in a password and you can leave the other values as blank.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Then we\u2019ll add the <em>cradmin<\/em> user to the SUDO group using the command below:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">adduser cradmin sudo<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">To ensure that you can connect to the server using the <em>cradmin <\/em>user, open another session with your SSH client and login with the <em>cradmin<\/em> user. After logging in successfully, we\u2019ll continue the setup in the <em>cradmin<\/em> session.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">ssh cradmin@&lt;node_1_public_IP&gt;<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The first thing we will do is disable password login and enable SSH key login. To do this, we\u2019ll create a <em>.ssh <\/em>directory in the home directory of the <em>cradmin<\/em> user. Type in the following commands:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">mkdir -p \/home\/cradmin\/.ssh\nchmod 700 \/home\/cradmin\/.ssh<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The <em>mkdir<\/em> command creates the hidden <em>.ssh<\/em> folder and <em>chmod<\/em> command will restrict the permissions to the <em>.ssh<\/em> directory to just the <em>cradmin<\/em> user.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Next, you need to generate an SSH key pair, save the private key to your computer and copy-paste the public key to the server.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Do the following on your own computer:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open Puttygen<\/li>\n\n\n\n<li>Click Generate and follow instructions in Puttygen. If you want, you can set a passphrase for the SSH key pair.<\/li>\n\n\n\n<li>Save both the private key and the public key to a folder where you\u2019ll find them later<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">We are now ready to add the public key to the server. On the <em>cradmin<\/em> SSH session, go to the <em>.ssh<\/em> folder with the command:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">cd \/home\/cradmin\/.ssh<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then create a file named <em>authorized_keys<\/em> with the command below.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">nano authorized_keys<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The command creates a new file called <em>authorized_keys<\/em> and opens it in the nano text editor. Copy the public key from Puttygen or from the file where you saved it earlier and right-click on the SSH window. This should copy the public key into the editor. Save the file with <em>ctrl+o<\/em> (click enter to confirm the filename), then close nano with <em>ctrl+x<\/em>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Lastly, ensure appropriate permissions for the keys by using the following command.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">chmod 600 \/home\/cradmin\/.ssh\/authorized_keys<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You should then try to login to the server with <em>cradmin<\/em> using the new SSH keys before continuing. If you\u2019re using Putty, you\u2019ll use the keys to login by going to the <em>Connection settings<\/em> and on the <em>Data<\/em> tab. Set the auto-login username to <em>cradmin,<\/em>&nbsp;then expanding the SSH and on the <em>Auth<\/em> tab select the private key file with the browse button.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">On the Sessions tab, you can save these settings to make login more convenient later on. Click Open and you should now login with the key-pair you just created.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you cannot log in or you are prompted for a password (and not the passphrase if you set one up), check that<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>You have copied the entire public key to the <em>authorized_keys<\/em> file<\/li>\n\n\n\n<li>Check that the public key is the first and only line on the <em>authorized_keys<\/em> file (delete any empty rows from the file)<\/li>\n\n\n\n<li>Check that you chose the correct <em>.ppk<\/em> file in Putty.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">After logging in successfully, we\u2019ll update the settings of the server to only allow SSH key-based login and we will also disable root login. In the <em>cradmin <\/em>session, open the <em>sshd_config<\/em> file with the next command:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo nano \/etc\/ssh\/sshd_config<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Change the row \u201c<em>PermitRootLogin yes<\/em>\u201d to \u201c<em>PermitRootLogin no<\/em>\u201c.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Remove the comment (#-character) from the row \u201c<em>PubkeyAuthentication yes<\/em>\u201c.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">And finally, change the row \u201c<em>PasswordAuthentication yes<\/em>\u201d to \u201c<em>PasswordAuthentication no<\/em>\u201c.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>Ctrl+o<\/em>, then enter to save your changes, <em>ctrl+x<\/em> to close the editor.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To activate these changes, we need to restart the SSH service with the following command:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo systemctl restart ssh<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Logout from the server and login again with your private key to ensure that everything works as intended.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Setting up CockroachDB server<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Next, we\u2019ll install the CockroachDB files and create the CA certificate that will later be used to create node certificates for each node.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Installing CockroachDB<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">While logged in as the <em>cradmin <\/em>user, download the CockroachDB archive for Linux and extract the binary from the archive:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">wget -qO-&nbsp;https:\/\/binaries.cockroachdb.com\/cockroach-v20.1.3.linux-amd64.tgz&nbsp;| tar xvz<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">To make it easy to use the binary, we\u2019ll copy it to a folder that is included in the PATH variable:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo cp -i cockroach-v20.1.3.linux-amd64\/cockroach \/usr\/local\/bin\/<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Check that the binary works by running the next command:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">cockroach version<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You should receive a listing showing the version of <em>cockroach<\/em>, which should be 20.3.1 at the time of writing this tutorial.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Build Tag:    v20.1.3\nBuild Time:   2020\/06\/23 08:44:08\nDistribution: CCL\nPlatform:     linux amd64 (x86_64-unknown-linux-gnu)\nGo Version:   go1.13.9\nC Compiler:   gcc 6.3.0\nBuild SHA-1:  7fd454f880f386cdd0eda6b21b12f6532c14f0db\nBuild Type:   release<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Next, we\u2019ll create a ballast file and prepare the server template for securing the CockroachDB nodes by creating a CA certificate.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Creating a ballast file<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">If the cockroach node runs out of disk space, it will shut down. The ballast file can be used to reserve some disk space. Then, if the disk space runs out, the ballast file can be deleted and the node restarted. To create a ballast-file of 1GB you use the following command:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">cockroach debug ballast ballast.txt --size=1GB<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Keeping the servers synchronized<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The servers on the cluster must be synchronized for CockroachDB to preserve data consistency. By default, when a node detects that its clock is out of sync with at least half of the other nodes by 80% of the maximum allowed offset, the node will shut down. The default maximum offset is 500 ms, which means that if the difference in server clock is more than 400 ms compared to half of the other servers running Cockroach nodes, the node on the server will shut itself down.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To keep the servers in sync we need to install an NTP package and point them all to the same source to sync their clocks. Cockroach Labs recommends using Google\u2019s NTP service because it handles \u201csmearing\u201d of the leap second and thus saves some configuration on the client-side later on. We will follow this recommendation.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">First, we need to disable <em>timesyncd<\/em> daemon which is active by default, then install NTP. You can check if it\u2019s active by running the command:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">timedatectl<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If the daemon is active, you\u2019ll see \u201c<em>NTP service: active<\/em>\u201d in the output:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To disable it, run the command:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo timedatectl set-ntp no<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">When you run the command <em>timedatectl<\/em> the NTP service should now be inactive:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">               Local time: Fri 2020-08-21 10:50:04 UTC\n           Universal time: Fri 2020-08-21 10:50:04 UTC\n                 RTC time: Fri 2020-08-21 10:50:05    \n                Time zone: Etc\/UTC (UTC, +0000)       \nSystem clock synchronized: yes                        \n              NTP service: inactive                   \n          RTC in local TZ: no<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">We\u2019re now ready to install the NTP package. Run the command:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo apt-get install ntp<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">We\u2019ll then change the sync source to Google\u2019s NTP service. Stop the NTP daemon with the command:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo systemctl stop ntp<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then sync the server\u2019s clock with Google\u2019s NTP service:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo ntpd -b&nbsp;time.google.com<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">We must also update the conf file, so we\u2019ll open the <em>\/etc\/ntp.conf<\/em> with nano:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo nano \/etc\/ntp.conf<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then comment out all the lines starting with the word server or pool. They will likely be the following:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">--\n#pool 0.ubuntu.pool.ntp.org iburst\n#pool 1.ubuntu.pool.ntp.org iburst\n#pool 2.ubuntu.pool.ntp.org iburst\n#pool 3.ubuntu.pool.ntp.org iburst\n# Use Ubuntu's ntp server as a fallback\n#pool ntp.ubuntu.com\n--<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">After commenting out the rows, add the following lines to the file:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">server&nbsp;time1.google.com&nbsp;iburst\nserver&nbsp;time2.google.com&nbsp;iburst\nserver&nbsp;time3.google.com&nbsp;iburst\nserver&nbsp;time4.google.com&nbsp;iburst<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then <em>ctrl+o<\/em> and enter to save your changes, <em>ctrl+x<\/em> to close nano.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Restart the NTP daemon and verify that the server used is a google NTP-server:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo systemctl start ntp<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo ntpq -p<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The active NTP server is marked with an asterisk as the first character on the line. In the picture below it is&nbsp;<em>time4.google.com<\/em>:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">     remote           refid      st t when poll reach   delay   offset  jitter\n==============================================================================\n 0.ubuntu.pool.n .POOL.          16 p    -   64    0    0.000    0.000   0.000\n 1.ubuntu.pool.n .POOL.          16 p    -   64    0    0.000    0.000   0.000\n 2.ubuntu.pool.n .POOL.          16 p    -   64    0    0.000    0.000   0.000\n 3.ubuntu.pool.n .POOL.          16 p    -   64    0    0.000    0.000   0.000\n ntp.ubuntu.com  .POOL.          16 p    -   64    0    0.000    0.000   0.000\n*time3.google.co .GOOG.           1 u   26   64    1    7.219   -0.811   2.357\n+static.141.138. 194.100.2.194    2 u   25   64    1   37.003   -0.257   2.334\n+ivanova.ganneff 192.53.103.108   2 u   26   64    1   36.914   -2.491   2.418\n+support.russian 194.58.202.148   2 u   28   64    1   36.944   -0.784   1.920\n#time03.nevondo. 17.253.38.125    2 u   23   64    1   34.350   -3.292   1.937\n...\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Securing the connections to a node<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">CockroachDB uses certificates to secure communication between nodes. CockroachDB can create the required certificates by itself or alternatively, OpenSSL can be used to create them. For this tutorial, we are using the CockroachDB\u2019s built-in cert command.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Start by creating two directories, <em>certs<\/em> and <em>my-safe-directory.<\/em> The <em>certs <\/em>directory will contain all the certificates including the CA certificate and <em>my-safe-directory<\/em> will contain the CA key.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">mkdir certs<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">mkdir my-safe-directory<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Once these directories are created, we can create our CA key with the following command:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">cockroach cert create-ca --certs-dir=certs --ca-key=my-safe-directory\/ca.key<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If the command succeeded, you should see a <em>ca.crt<\/em> in the <em>certs <\/em>directory and <em>ca.key<\/em> file in the <em>my-safe-directory<\/em>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For now, we\u2019re happy with the configuration that we have. We still need to add the systemd configuration file for the database, but before we can do that we need to set up the SDN private network. Shut down the server by using the following command:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo shutdown -h now<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">3. Setting up an SDN private network<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">All the servers we\u2019ll use in the cluster will connect to an SDN private network on UpCloud and they will communicate with one another using the network interface on the SDN.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Create the SDN<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">It is very easy to create a private network and costs just $5 each per month:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Login to the <a href=\"https:\/\/hub.upcloud.com\/\" target=\"_blank\" rel=\"noopener\">UpCloud Control Panel<\/a><\/li>\n\n\n\n<li>Go to the Network tab.<\/li>\n\n\n\n<li>Choose the Private Networks tab.<\/li>\n\n\n\n<li>Click the \u201cCreate SDN network\u201d button<\/li>\n\n\n\n<li>Choose the same location that you used when creating the server<\/li>\n\n\n\n<li>Set the IP address space to your liking, e.g. 10.0.1.0\/24<\/li>\n\n\n\n<li>Make sure that <em>Enable DHCP<\/em> is checked.<\/li>\n\n\n\n<li>Click the Create SDN network button.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Connecting the DB server to the private network<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Again, it is very simple to connect a server to the SDN private network. Go to Servers, choose the server you created, make sure it\u2019s shut down and then choose the Network tab for the server.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Click the \u201cAttach SDN private network\u2026\u201d button, choose the network you just created, then assign an IP manually to the server. In this example, we\u2019ll assign the IP 10.0.1.2 to the server that will be cockroachnode1. Nodes 2 and 3 will receive the IPs of 10.0.1.3 and 10.0.1.4 respectively.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/cockroachdb-attach-sdn-private-network.png\" alt=\"Attaching CockroachDB node to an SDN private network\" class=\"wp-image-16376\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">To finalise, we need to configure the network interface on the server itself, so start up the server and login with the <em>cradmin<\/em> user.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Then open the network configuration file with the following command:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo nano \/etc\/network\/interfaces<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If you\u2019ve created the server with the default settings, you need to add a fourth ethernet interface to the file. Add the following lines to the end of the file:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">auto eth3\niface eth3 inet dhcp<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Once done, use <em>ctrl+o<\/em> and enter to save your changes, <em>ctrl+x<\/em> to close the file.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Then restart networking with the command:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo systemctl restart networking<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You can check that you can see the interface you added with the command:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">ip addr<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You should see something like this:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">5: eth3: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; mtu 1500 qdisc fq_codel state UP group default qlen 1000\n    link\/ether 6e:d7:1b:bf:c8:e5 brd ff:ff:ff:ff:ff:ff\n    inet 10.0.1.2\/24 brd 10.0.1.255 scope global dynamic eth3\n       valid_lft 3598sec preferred_lft 3598sec\n    inet6 fe80::6cd7:1bff:febf:c8e5\/64 scope link \n       valid_lft forever preferred_lft forever<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now that we\u2019ve created the network interface, we can create a template for the systemd config file for the server.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4. Finalising the server template and creating custom image<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">To finalize our server template we\u2019ll create a template for the systemd configuration file that will be used to start and stop the database and to start it automatically when the server restarts.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Creating a template systemd file<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Create the file by running the following command:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo nano \/etc\/systemd\/system\/securecockroachdb.service<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then add the following text to the file. You can notice that we have a few IP addresses in the config file, namely the IP addresses to the nodes 1, 2 and 3. You must change these to the ones you will be using in your SDN you created earlier.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Note that whenever you are adding a node, later on, you must update the <em>\u2013advertise-addr -parameter<\/em> to the node\u2019s own IP address, but everything else can be as is.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">[Unit]\nDescription=Cockroach Database cluster node\nRequires=network.target\n[Service]\nType=notify\n\nWorkingDirectory=\/home\/cradmin\nExecStart=\/usr\/local\/bin\/cockroach start --certs-dir=certs --advertise-addr=10.0.1.2 --join=10.0.1.2,10.0.1.3,10.0.1.4 --cache=.25 --max-sql-memory=.25\nTimeoutStopSec=60\nRestart=always\nRestartSec=10\nStandardOutput=syslog\nStandardError=syslog\nSyslogIdentifier=cockroach\n\nUser=cradmin\n\n[Install]\nWantedBy=default.target<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then press <em>ctrl+o<\/em> and enter to save the file, <em>ctrl+x<\/em> to close nano editor.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We do not want to start or enable the service just now, but to create the custom image instead. Next, logout from the server and shut it down from the UpCloud Control Panel or by using the command below:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo shutdown -h now<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Creating a custom image<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">There\u2019s more than one way to clone a server, and you can find information about them in a <a href=\"https:\/\/upcloud.com\/global\/docs\/guides\/server-cloning\/\" target=\"_blank\" rel=\"noreferrer noopener\">tutorial on server cloning<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For this tutorial, we\u2019ll create a custom image of the storage of our CockroachDB server. This is the way to do it:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In the <a href=\"https:\/\/hub.upcloud.com\/\" target=\"_blank\" rel=\"noopener\">UpCloud Control Panel<\/a>, after shutting down the server, go to the <em>Storage<\/em> tab<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">On the <em>Devices<\/em> tab, you can see all the storage devices of your servers. There should be one for the server you created. You should see two buttons for each storage device.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Click the button on the left to <em>create a custom image<\/em>.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/cockroachdb-create-custom-image.png\" alt=\"Creating a custom CockroachDB image\" class=\"wp-image-16439\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Give your template a name, e.g. <em>cockroachdb-node<\/em>, then click the <em>Create<\/em> button.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/cockroachdb-create-custom-image-2.png\" alt=\"Creat custom CockroachDB image\" class=\"wp-image-16439\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">After a few seconds, the template is ready and you should see it under the <em>Custom Images<\/em> tab.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/cockroachdb-custom-image.png\" alt=\"CockroachDB custom image\" class=\"wp-image-16439\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">You can now use the Deploy button to create new nodes to the cluster. This way you only need to choose the server plan, give a hostname, and the server is deployed with all the earlier setup steps already done. Your SSH keys should work similarly as with node 1.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We can now start deploying nodes 2 and 3 and can finalise node 1.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Creating Node2 and Node3<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Deploy two new nodes using your custom <em>cockroach-node<\/em> image. Once the deployments have finished, shut down both node 2 and node 3.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Attach both new nodes to the same SDN private network by going to the <em>Network<\/em> tab in the server settings.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Next, go to the server\u2019s Network tab and attach the private SDN you created for the servers. Assign the IP address manually for both new nodes as you did for the first one.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">cockroachdb-node-2 10.0.1.3\ncockroachdb-node-3 10.0.1.4<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Afterwards, restart all server and login to make sure everything is working.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/cockroachdb-start-cluster.png\" alt=\"Starting all nodes in CockroachDB cluster\" class=\"wp-image-16439\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Next, we need to update the hostname on <strong>all nodes<\/strong> for the server with the command:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo nano \/etc\/hostname<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Change the name to indicate which node is which, for example:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">cockroachdb-node-&lt;node_number&gt;<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then press <em>ctrl+o<\/em> and enter to save, <em>ctrl+x<\/em> to close the editor.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Afterwards, reboot all nodes to enable the hostname changes. You can do this at your <a href=\"https:\/\/hub.upcloud.com\/\" target=\"_blank\" rel=\"noopener\">UpCloud Control Panel<\/a> or by using the following command:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo reboot<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You should now have three identical database nodes running and ready. Continue in the next section to get the cluster initialised.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">5. Initialising the CockroachDB cluster<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Setting up node-certificates for the nodes<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Now that each server has its own IP we can create the node certificates for the nodes. We do this by using the CA key we created in the earlier step.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Log in to the <strong>node 1<\/strong> server and run the following command to create the node certificate:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">cockroach cert create-node 10.0.1.2 cockroachnode1 localhost 127.0.0.1 --certs-dir=certs --ca-key=my-safe-directory\/ca.key<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This node certificate makes the node reachable via the SDN private IP, the hostname, \u201clocalhost\u201d and the local IP 127.0.0.1. If you want the node to be reachable via the public IP, add it to the list after the local IP.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you made a mistake typing in the IPs, you can run the command with the additional argument <em>\u2013overwrite<\/em>. This will overwrite the certs if the file already exists.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now do the same for <strong>nodes 2 and 3<\/strong>, by using their IPs.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># node 2\ncockroach cert create-node 10.0.1.3 cockroachnode1 localhost 127.0.0.1 --certs-dir=certs --ca-key=my-safe-directory\/ca.key\n# node 3\ncockroach cert create-node 10.0.1.4 cockroachnode1 localhost 127.0.0.1 --certs-dir=certs --ca-key=my-safe-directory\/ca.key<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Afterwards, on <strong>nodes 2 and 3<\/strong>, delete the <em>ca.key<\/em> file with the commands:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">rm ~\/my-safe-directory\/ca.key<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Create a local root client Certificate on Node1<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">On <strong>node 1<\/strong>, we\u2019ll create a root client certificate. This certificate is used later to log in to the database to create users, databases etc. Root login can be used on any of the servers that contain this certificate, but for now, we\u2019ll just have it on the node 1 server. Run the command:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">cockroach cert create-client root --certs-dir=certs --ca-key=my-safe-directory\/ca.key<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Starting up the nodes<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">It is now time to enable and start the systemd service script we created earlier. On <strong>nodes 2 and 3<\/strong> we need to update the node IP in the service file.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Open the file with the following command:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo nano \/etc\/systemd\/system\/securecockroachdb.service<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">And then update the parameter <em>\u2013advertise-addr<\/em> to the IP address you\u2019ve selected to the node. For example, on <strong>node 2<\/strong>, we\u2019ll change the <em>ExecStart<\/em> to show the following:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">...\nExecStart=\/usr\/local\/bin\/cockroach start --certs-dir=certs --advertise-addr=10.0.1.3 --join=10.0.1.2,10.0.1.3,10.0.1.4 --cache=.25 --max-sql-memory=.25\n...<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">On <strong>all nodes<\/strong>, run the following command to enable the systemd script. This will start the database whenever the server reboots.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo systemctl enable securecockroachdb.service<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then run the following command to start the database:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo systemctl start securecockroachdb.service<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">As a result, the node becomes active but is not yet connected to the other nodes. We are now ready to initialize the cluster.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Initializing the cluster: The database is live!<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Now that the nodes are started, we\u2019re ready to initialize the cluster. On <strong>node 1<\/strong>, run the command:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">cockroach init --certs-dir=certs --host=&lt;node_1_sdn_ip&gt;<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For this example, the command is:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">cockroach init --certs-dir=certs --host=10.0.1.2<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">Cluster successfully initialized<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If all went correctly, you get the message like the example output above.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">6. Connecting and testing the database<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Creating a database and a user<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Login to <strong>node 1<\/strong> with the <em>cradmin<\/em> user. We will log in to the database cluster using the root certificate we created in the earlier step. To do this, run the command:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">cockroach sql --certs-dir=certs --host=localhost<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You can connect to the cluster through any of the nodes, however, for the root user you need to copy the certificate over to your other servers certs-directory.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now that we\u2019re logged in to the database cluster, we will create a database and a user that we can use to test the database. This user can also be used to login to the admin web-UI in the next step. In the SQL client, run the following commands to create a test database named <em>testdb<\/em> and a test user named <em>tester<\/em>:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">create database testdb;<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">set database=testdb;<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">create user tester with password '&lt;write a password here&gt;';<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then we\u2019ll grant the <em>tester<\/em> user all privileges to the database we created, create a table and then add value to the table:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">grant all on database testdb to tester;<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">create table test(column1 string);<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">insert into test(column1)values('test!');<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">q;<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">We\u2019re now ready to test how the database works with a database client and we can log in to the admin web UI.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Logging in to the admin web UI<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">After creating the user tester and granting all privileges to it, we can use it to log in to the web UI. To do that you take the public IP of any of your server nodes and in your browser navigate to:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">https:\/\/&lt;node_1_public_ip&gt;:8080<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Your browser will warn about the site certificate as it is self-signed by Cockroach, but you can continue to the login page and then login by using the user tester you created earlier.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/cockroachdb-web-ui-login.png\" alt=\"Logging into the CockroachDB web UI\" class=\"wp-image-16440\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The web UI shows the status of the nodes and other useful information to administer the database cluster. If you get a 404 error, you\u2019ve forgotten to update the node IP on the systemd service file.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/cockroachdb-web-ui-overview.png\" alt=\"CockroachDB web UI overview\" class=\"wp-image-16441\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">To try how everything works, you can shut down one of the nodes and see the status changes in the web-UI. You can then restart the node to see if it resumes normal operation.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Testing the DB with DBeaver<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">For a more hands-on test, we will use the DBeaver SQL client. Head over to their <a href=\"https:\/\/dbeaver.io\/download\/\" target=\"_blank\" rel=\"noopener\">download page<\/a> and get the community edition version appropriate to your OS.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">After the installation, open the DBeaver and click on the new connection button. Select CockroachDB as the target and click the <em>Next<\/em> button.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/cockroachdb-dbeaver-new-database.png\" alt=\"DBeaver new database connection to CockroachDB\" class=\"wp-image-16448\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Then in the new connection settings, set the host to any of the public addresses of your cockroach nodes, leave the port as the default (26257).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Write the database name <em>testdb<\/em>, the username <em>tester<\/em> and the password you chose. You can test the credentials by clicking the <em>Test Connection<\/em> button.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Once all set, click Finish.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/cockroachdb-dbeaver-connect-to-database.png\" alt=\"Connecting DBeaver to CockroachDB\" class=\"wp-image-16447\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Then on the database navigator, expand the <em>testdb<\/em> connection and you should be able to find the table you created.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/cockroachdb-dbeaver-test-table.png\" alt=\"Finding the CockroachDB test table on DBeaver\" class=\"wp-image-16449\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">You can try creating a table, adding some rows and then logging in through some other node to see that your changes are replicated between all the instances.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">7. Continuing further<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Congratulations! If you\u2019ve made it this far, you should now have a fully functional CockroachDB cluster up and running.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">However, there is one, big glaring problem with the current setup: we usually don\u2019t want our database nodes to be available through the public internet. So the next step would be to remove the public IPs from the cockroach node servers and then set up a way to connect to them through VPN. One good choice for this is to use <a href=\"https:\/\/upcloud.com\/global\/resources\/tutorials\/get-started-wireguard-vpn\/\" target=\"_blank\" rel=\"noreferrer noopener\">Wireguard VPN<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can also further improve the setup by adding a load balancer server that is used to connect to the servers. CockroachDB can create HAProxy configuration files automatically, so the primary steps to do this are:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Deploy a new UpCloud server and connect it to the SDN private network<\/li>\n\n\n\n<li>Then <a href=\"https:\/\/upcloud.com\/global\/resources\/tutorials\/haproxy-load-balancer-ubuntu\/\" target=\"_blank\" rel=\"noreferrer noopener\">install the HAproxy load balancer<\/a><\/li>\n\n\n\n<li>On cockroach node 1, run the following command to create the haproxy config file:<br><tt>cockroach gen haproxy --certs-dir=certs --host=&lt;any node address&gt;<\/tt><\/li>\n\n\n\n<li>Copy the resulting <em>haproxy.cfg<\/em> config file over to the Load balancer server from cockroach node 1<\/li>\n\n\n\n<li>On the load balancer server, start the load balancer with the command:<br><tt>haproxy -f &lt;path to the config file&gt;\/haproxy.cfg<\/tt><\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Once that\u2019s all done, you should be able to connect to your cockroach cluster through the load balancer IP address.<\/p>\n","protected":false},"author":46,"featured_media":16454,"comment_status":"open","ping_status":"closed","template":"","community-category":[226,223],"class_list":["post-2128","tutorial","type-tutorial","status-publish","has-post-thumbnail","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/tutorial\/2128","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/tutorial"}],"about":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/types\/tutorial"}],"author":[{"embeddable":true,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/users\/46"}],"replies":[{"embeddable":true,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/comments?post=2128"}],"version-history":[{"count":0,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/tutorial\/2128\/revisions"}],"wp:attachment":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/media?parent=2128"}],"wp:term":[{"taxonomy":"community-category","embeddable":true,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/community-category?post=2128"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}