Skip to content

Commit b73d6ed

Browse files
committed
Cloud NAT article
1 parent 08bc9f0 commit b73d6ed

9 files changed

+139
-0
lines changed

CLOUDNAT.md

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
## Preface
2+
3+
In the [previous article](README.md) we told you about how to connect to MongoDB Atlas with Go and to interact with the database cluster. MongoDB Atlas is a cloud platform, therefore queries run through the public internet and must be very well secured. Let us go through some options we have in matters of safety and security while creating a distributed cloud infrastructure. We are going to concentrate on one particular setup, and that is a connection between a Google Kubernetes cluster and a MongoDB Atlas.
4+
5+
## Possible solutions
6+
7+
MongoDB Atlas offers three methods of securing the network:
8+
9+
![Options to secure network](images/access_options.png "Options")
10+
11+
1. `IP Access List` where you can manage static ip addresses of hosts that are allowed to connect to your database clusters. This is a very easy way to achieve the goal, especially if you want to connect a single VM (virtual machine) that has a static public IP. A good thing about this way is that you can use this setup with all tiers MongoDB Atlas offers, even with the smallest and free of charge `M0 Sandbox`.<br>
12+
However, if you have a kubernetes cluster with several nodes, this option is almost useless. First of all, nodes of the cluster must have public ip addresses - a setup that is normally not favoured for security reasons. Secondly, the public ip of a node in the cluster is most likely to be changed at some point, and therefore MongoDB Atlas might start to refuse connections from this node.<br>
13+
Why this option is _almost_ useless for kubernetes clusters, we'll explain below.
14+
2. `Peering` is very good in case you have a cluster to connect. Also pretty easy to set up. There is a [comprehensive guide](https://docs.atlas.mongodb.com/security-vpc-peering/) on how to do it. However, you must have at least `M10` cluster which is not always what you want to use. For example, we like to use several smaller MongoDB Atlas clusters, sometimes using them fleetingly and at a lower price. So, that option does not entirely meet our requirements as well.
15+
3. `Private Endpoint` is quite the same as `Peering`, but built for AWS and works for it very well.
16+
17+
So, our challenge was to whitelist a Google Kubernetes Engine (GKE) cluster in MongoDB Atlas for `M2`, `M5` or even with a free of charge `M0` tier. MongoDB Atlas does not support such possibility out-of-the-box. We need to tinker around the GKE cluster.
18+
19+
## Big Picture
20+
21+
Our goal is to set up our GKE cluster so that it gets an IP address which is public and static. We use Cloud NAT for that:
22+
23+
![Big Picture](images/cloud-nat.png "Cloud NAT")
24+
25+
Accordingly to this picture we are going to do following steps:
26+
27+
1. create a GKE cluster with private nodes
28+
2. create a router and connect it with the clusters network
29+
3. preserve a static ip address and assign it to the router
30+
4. whitelist this ip address in Mongo DB Atlas in `IP Access List`
31+
32+
## Create a GKE cluster with private nodes
33+
34+
In any case it is a good idea to keep IP addresses of your nodes private. For the security reasons we suggest to have this setup as a best practice. However, we will make the Kubernetes API endpoint public now for the purpose of simplicity.
35+
36+
First, we authorize `gcloud` to access the Cloud Platform:
37+
38+
```sh
39+
> gcloud config set project my-project
40+
Updated property [core/project].
41+
42+
> gcloud auth activate-service-account \
43+
44+
--key-file cluster-admin-key.json
45+
Activated service account credentials for: [[email protected]]
46+
```
47+
48+
_Hint: you must have a service account with the roles `Kubernetes Engine Cluster Admin` and `Compute Network Admin` as well as a key file to create a cluster. In our example we named the service account `cluster-admin` and the key `cluster-admin-key.json`_
49+
50+
Let us boot the cluster up:
51+
52+
```sh
53+
gcloud container clusters create my-cluster \
54+
--enable-private-nodes \
55+
--enable-ip-alias \
56+
--master-ipv4-cidr 172.16.0.0/28 \
57+
--no-enable-master-authorized-networks \
58+
--no-enable-basic-auth \
59+
--no-issue-client-certificate \
60+
--zone europe-west1-b
61+
```
62+
63+
...and explain what the parameters are good for as long as the cluster is being configured:
64+
65+
`--enable-private-nodes`: like it says the nodes will receive private IP addresses and will not be accessible from outside the cluster.<br>
66+
`--enable-ip-alias`: it creates a VPC-native cluster which means setting up subnetworks that has two secondary IP ranges: one for pods and one for services.<br>
67+
`--master-ipv4-cidr 172.16.0.0/28` specifies an internal address range for the Kubernetes management endpoints. You must declare this range, if you start a private cluster.<br>
68+
`--no-enable-master-authorized-networks` allow to access the Kubernetes API endpoint from everywhere.<br>
69+
`--no-enable-basic-auth` disables basic authentication for the cluster.<br>
70+
`--no-issue-client-certificate` disables issuing a client certificate.<br>
71+
`--zone europe-west1-b` defines in which cloud zone is to create the cluster. Be careful in choosing the zone. It should be the same one as MongoDB Atlas is running on, unless you have good reasons to start the cluster somewhere else. Using the same zone makes the response time of the Mongo queries shorter and the costs lower.
72+
73+
We hope you see a similar picture now:
74+
75+
```sh
76+
NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS
77+
my-cluster europe-west1-b 1.15.12-gke.20 35.234.XX.YY n1-standard-1 1.15.12-gke.20 3 RUNNING
78+
```
79+
80+
## Setting up the router with the static IP
81+
82+
Now we would like to encourage you to go to the [Google Console](https://console.cloud.google.com) and to continue with Cloud NAT:
83+
84+
![Go to Cloud NAT](images/goto-cloud-nat.png "Cloud NAT on Google Console")
85+
86+
...and click on the button `Create NAT gateway`.
87+
88+
![Create Gateway](images/create-gateway.png "Create NAT gateway")
89+
90+
91+
You have to fill following fields out:
92+
93+
`Gateway name` like it says this is the name of your gateway.<br>
94+
`VPC Network` may stay as _default_ so far.<br>
95+
`Region` should be the same where your cluster runs (_europe-west1_ in our case)<br>
96+
`Cloud Router` is not created yet, but we can create it right here by clicking on _Create new router_<br>
97+
98+
In the new form you just need to give a proper name for a router and click on `Create`:
99+
100+
![Create Router](images/create-router.png "Create the router")
101+
102+
Now you are back to the previous form and your router is already set up.<br>
103+
104+
The last step you have to do is to create a static ip address for our router. Change the selection of the field `NAT IP addresses` to `manual`, let the other fields like they are.
105+
106+
![Select NAT IP](images/select-nat-ip.png "Select NAT IP")
107+
108+
Again, in a new form you just have to input an alias for the static ip address you are going to reserve:
109+
110+
![Reserve static IP](images/reserve-static-ip.png "Reserve static IP")
111+
112+
After several seconds your Cloud NAT gateway is ready to serve you!
113+
114+
## Whitelist the IP address on MongoDB Atlas
115+
116+
If you click on the newly created gateway, you will see its configuration in details.
117+
118+
![Gateway details](images/nat-details.png "Gateway details")
119+
120+
`my-nat-ip` has the IP 34.78.85.15 in our case. This is the one that can be whitelisted under `IP Access List` on MongoDB Atlas.<br>
121+
122+
On the [MongoDB Atlas Console](https://cloud.mongodb.com) go under _Network Access -> IP Access list_ again, click on `Add IP Address` there and put this IP and a comment.<br>
123+
124+
Now your GKE cluster is securely connected to the MongoDB Atlas and you can use database clusters of any setup you want!
125+
126+
## Things to be considered
127+
128+
You can remove the GKE cluster easily by the following command:
129+
130+
```sh
131+
gcloud container clusters delete my-cluster --zone europe-west1-b
132+
```
133+
134+
However, this command does not release the static IP address you reserved earlier. And this is a resource you are paying to Google for. Be careful to remove everything:
135+
- the Cloud NAT
136+
- the router
137+
- the static IP address under _VPC Network -> External IP Addresses_ as the last step
138+
139+
Actually you have to use an infrastructure as code software for this, but there is enough input for today.

images/access_options.png

74.7 KB
Loading

images/cloud-nat.png

163 KB
Loading

images/create-gateway.png

136 KB
Loading

images/create-router.png

81 KB
Loading

images/goto-cloud-nat.png

87 KB
Loading

images/nat-details.png

73.1 KB
Loading

images/reserve-static-ip.png

39.8 KB
Loading

images/select-nat-ip.png

120 KB
Loading

0 commit comments

Comments
 (0)