Migrating to CockroachDB
openmymind.net
openmymind.net
Eh, I'm not sure how I feel about this. Obviously you should secure your network as best you can, but how confident are you really that a bad actor will never find a foothold anywhere in your network? I think I would advocate for your services to all communicate securely (TLS et al), even internally, and if your database supports mutual client/server auth like it sounds like Cockroach does then you should use that as well. Particularly if you're depending on at-rest encryption handled transparently by the DBMS to protect your users' data - that won't do you much good if someone can just sniff/MITM network traffic and wait until a bunch of your data has been queried.
You mention that query response data can be sniffed by an attacker in case networks are compromised. The much worse scenario is that the passwords themselves can be intercepted, giving attackers full access.
Also some environments like Kubernetes might already have network encryption (provided by a service mesh) and don't need another layer.
Certificates serve both encryption and authentication, but encryption can be done with self-signed certs automatically generated by the nodes upon joining the cluster and authentication can be handled in the joining process by using a token or some other bootstrap value that's easier to manage.
This comment is not any more true as of CockroachDB 20.1 (Upcoming in Q2 2020).
This version will enable you to set up your own transport-level security with clients using password authentication to crdb.
The cert business is not just about encryption, it's also about authentication over an untrusted network.
The problem I have is that I'm not sure what method you want to use to inject certificates. The current systems seem to be "something will figure it out for you at runtime, and your application will be none the wiser". (This is things like Istio and Linkerd.) I am not sure I'm convinced this adds much security. Anyone that can talk to the apiserver that injects certificates can probably convince the system to give you a certificate for your rogue container. And, I'm not sure that applications have enough visibility into the networking layer to really add any trust. I'd like for each incoming request to have some provenance information attached with dimensions like "this container was built from trusted source code and each commit that it contains was code reviewed", "this container was launched from a manifest written and applied by a trusted engineer from a trusted machine", and of course "this request was authorized by a human user whose data is being accessed". Right now, I feel like you have to hand-wave to get the first two. Sure, maybe Istio thinks the container is legit, perhaps because it asked a container notary (very early stages of support), and so now it can open a TLS connection to anything in the cluster. And, adding a request-scoped JWT is easy enough to provide the "here is the human user that made the request". I just don't think you can hide this from the application with a service mesh; every application needs to be aware of what's going on so it can say no to suspicious requests. And for that, I don't think we're really there yet. We had this at Google and it worked well, but I haven't found anything that works well in the outside world yet.
With that in mind, I totally understand why people trust the "well, it's all behind a firewall" model. It's not very good, but it is easy. I hope that in the next year or two we can get to where I want to be, but I'm also not sure that anyone cares. "Good is the enemy of great" and a private network seems to fit people's mental model pretty well. The only thing that automatic mTLS gets you right now is protection against "SSL added and removed here ;-)", and it's only the NSA that's really doing that. If you aren't a target of the NSA, your data is being exfiltrated by employees with access, or by simple application level bugs (XSRF, SQL injection).
This is all very rambly and I'm not sure where I'm going with this... but I wish that someone made application-level transport security work and it was trivial to set up.
This is pretty infrastructure-heavy but I think my ideal solution would be to have a trusted orchestrator service on every machine which has its own certificate and accepts human-signed build artifacts to be run in a new container on that machine. It could verify the signature of each uploaded artifact and send CSRs for them to a hardened signing server, which returns the certs to be mounted (or sent over a standard initialization API) into the new containers.
Your options for compromising this are:
1. Get a malicious build artifact signed and submit it to a machine for execution. This shouldn't be possible without compromising an actual developer's credentials to sign the artifact.
2. Send your own custom CSR to the signing server to get a signed certificate. This shouldn't be possible without compromising the certificate from one of the orchestrator services to sign the CSR.
I think this should work as long as you can guarantee that services can't break out of their containers and as long as there's some hardware root of trust ensuring that your orchestrator service is genuine and the only thing that can read its CSR-signing certificate.
Now the issue is that they are a real PITA to implement in some of those networks, where you have to use tons of private registries and repositories, and to get everything working with certificates. Because those companies are not used to issue certs, often times it take them months to do so, as they have a very rigorous process, so everyone wonders why this tiny app never goes to "production" and why we are blocked by such restrictions.
Now I'm not even accounting for the fact that you sometimes actually need to go online to install some of those stuff. Recent example was node-sass, dependancy from a composer package, which you would expect to just install from the composer registry ; but no, it has a setup script that goes to nodejs.org or something, which of course you cannot fake because it will have to check certs as well. So again, something designed for the web that'll never work seemlessly elsewhere. (There are workaround of course but I'd love to spend my time elsewhere).
To give you an idea, the cloud I'm working on right now is pretty much entirely offline, for both egress and ingress. There is a nexus mirror-proxy to dockerhub and that's it, even this is in the LAN. So really, having to configure cockroachdb certs (or anything else for that matter, like etcd...) is useless, time consuming, frustrating, and counterproductive.
Is cockroachdb the right DB for this use case, though? A more traditional Postgres/MySQL or evening sqlite (depending on needs) is often plenty good for a small internal app without requiring this extra security
> the cloud I’m working on right now is pretty much entirely offline
I fee like “cloud” has lost all meaning it may have once had
It's not, but the app I described is just an example. Some use cases involve bigger dataset and resilience.
It's not cockroachdb specifically but any of those "web" tools that, used internally in a closed environment, become a PITA to manage. Language tooling, repositories, dbs... Etcd for example is used as an internal storage for tenants (for example to store DNS information) and the team that manages it cannot upgrade right now because they have to figure out first how to implement ssl.
> I fee like “cloud” has lost all meaning it may have once had
Well, how would you call an on-prem install of OpenStack ? It's their internal cloud. Cloud has not much to do with the web or with the fact that it is publicly exposed, it's a tool to manage infrastructure. And to be perfectly honest, "cloud" isn't a proper term to begin with. Years ago when the word came out one of my professor said they basically renamed "grid" to "cluster" then "cloud". They used to administer hundreds+ of machines and multiples of that of jobs using pssh. They didn't wait for kube, and they didn't need ssl between each and every API and services.
Now don't get me wrong, the public cloud provides a great service and tooling coming out now should be web ready and web safe. Just, please, pretty please, give us a --insecure and --offline even if it means having it all over my ansible code, so we can get the job done without having to spend my days working around those tools.
> And to be perfectly honest, "cloud" isn't a proper term to begin with.
Completely agree, it’s just a marketing buzzword.
Have you taken a look at [0]? (All caveats around running an insecure cluster apply)
[0]: https://www.cockroachlabs.com/docs/stable/deploy-cockroachdb...
There is no cryptographic security benefit of publicly vs privately signed certificates. After all publicly signed certificates are just privately signed certificates whose CA has been added to your CA store. So just add your own CA to whatever program is needed (do not add your own CA to the whole system). The annoyance is keeping those certificates and CAs up to date. Tools like Hashicorp Vault can automatically generate certificates for you if you want to automate this part.
In that scenario, it's very easy to end up in a situation where CRDB communications are encrypted twice, with separate certificate management systems. Not just the client->db connections, but also the node->node ones. Especially with things like Istio becoming more popular.
Secure everything, and assume that everything is compromised. Anything less is downright negligent.
This is why i've been so happy reading about wireguard in the kernel recently. This makes it possible to have a very secure, low hassle default that is completely independent of applications.
It certainly is if the thing you're securing is the flush handle itself.
Like all security questions, understanding exactly what you need/want to secure and the threat models surrounding it is extremely important.
The problem with locking every object in your home isn't that its an inherently bad thing, its that it introduces too much overhead to be worth the hassle. Now, if there were some touch ID enabled force-field that unlocked things only for you, within milliseconds and was highly reliable to work, that might change the dynamics a lot.
And that is what happens with crytographic security. There is very little overhead that modern systems impose on securing your systems so there is no reason for you to not enable them (setup may be hard, I acknowledge its a problem but its a one time cost to pay).
Taking the analogy further; if you had to repeat the authentication flow for every digital object it would still introduce a lot of hassle. So digital cryptography gets around this by instead requiring short lived tokens so the cost of enabling cryptography is amortized across all your digital assets. In our analogy; it would be that every object in our home is locked, but we use faceID to get a short lived key that is cached for e.g. 10 minutes. All locked objects check for the existence of that short lived key.
If they would have proper backups in free, more people would start using it, and then discover that they’ll need some of the premium features (data locality, Role-Based Access Control or follower reads).
Also, why is there no public pricing page? How will I know that pricing won’t change every year? Or be arbitrary based on how much they can squeeze us? (less likely with public, listed prices)
Why would a company with low marginal cost (software) limit their growth like this?
Also WAL-E has been replaced by WAL-G (written in Go):
I think this should be true to any distributed database: you can't really beat an optimized single-machine software with a networked app, no matter how hard you try.
My experience with CockroachDB showed that increasing the cluster size from 3 to 6 and more provided more benefit than I've expected. 1 -> 3 seems to be a meaningless metric for such setup with a replication factor of 3.
Same thing with CockroachDB Postgresql "wire protocol support". The fact that it only supports "serializable" isolation level when Postgresql utilizes Read Committed OTB should be a screaming red flag to just about anyone that you are in for some challenges on the performance front. Some well-worn modeling techniques are simply infeasible under typical workloads at that isolation level, for one.
Starting with bog-standard RDBMS you have to be deliberate to get great performance. Adding in extra, fancy scaling properties means even more considerations to take into account to maintain consistency while achieving gains.
There was an inconsistency issue when deleting a ton of (self referencing foreign key) rows in rapid succession. The results of a "select count(*) from table" returned different results than a "select count(id) from table". After some delay the results came back in sync again.
As I was trying to shoehorn an existing PostgreSQL database into CRDB, I had to find solutions for SELECT .. FOR UPDATE, finding alternatives for triggers, issues with the query builder I use (knex.js). In the end it was too much, not even considering lack of backups and the risk of a VC funded company going belly up. I do hope they gain a solid foothold and these NewSQL databases gain more traction.
As for your performance analysis, do share your results and methodology. We published an in-depth, reproducible comparison with YugaByte here [1] in addition to publishing our TPCC-100k numbers[2]. If you're seeing performance that doesn't line up with the above, let us know.
[0]: https://www.cockroachlabs.com/blog/consistency-model/
[1]: https://www.cockroachlabs.com/blog/unpacking-competitive-ben...
I still find CRDB's replication interesting, since all data is replicated 3-way on every commit, and data also auto-rebalances as needed. With some exceptions, as long as you are connected to any node, you should have access to all data.
Just fronting it with haproxy to read/write to a single node at a time (setting others to "backup") has worked well for us, since we're not doing a huge number of queries.
Thank you for writing this up and putting your experiences out there, clear as day. It's very valuable.
Cluster scalability has always been a thing with Oracle, SQL Server, Sybase, Informix, DB2.
Or the CERN infrastructure to deal with non-stop handling from accelerator data and storage for posterior data analysis.
Sometimes this industry feels like a continuous reboot.
Postgres still has a couple of tricks to learn from big boys databases.
I doubt CERN is dumping all of their experiment data into a single SQL database.
Nowadays no idea.
I don't think Ecto works as-is, you'd have to check.
For simple apps, it might be a drop-in replacement, or require very few tweaks. In addition to the issues mentioned in the OP, the cockroachdb documentation has a detailed list of differences (1).
(1) https://www.cockroachlabs.com/docs/stable/detailed-sql-suppo...
The whole point of cdb is to enable things like Google scale. But all I ever see on it are random devs spinning up three nodes and being so proud.
Which is too bad because I'd love to see someone pushing its limits, and betting mission critical services on it that nothing else could handle.
One downsides I didn't like though is no incremental backups unless enterprise. There's PG dump but not sure if it'd work on a bunch of threads and stuff. If using MySQL there's the MyDumper project that looked interesting.
Then there's no full text search is a downside, but I know it seems people recommend running a separate search solution anyways so that can be a little slow to get started. Easier if you could just run it in one system in the beginning, and who knows maybe search isn't a bottleneck anyways depending on the implementation of the database or you want to be able to still full text search while debugging maybe.
Then no geospatial can be a downside for some types of businesses or use cases, say a place lookup, factoring it into a game matching algo, etc. I've been really interested in MongoDB lately though, but was playing with a few newer SQL based databases for what to use on my own project. Then I know some companies actually run multiple databases too, some stuff might be noSQL while other workloads are SQL databases too, but I know some rather just one a single database so only one source of truth. Then I know PostgreSQL has the idea of foreign data wrappers [0], so I guess then you could treat a MongoDB collection as a table. So maybe you had a users collection, you could join on it I think using this but never played with it. However this seems mostly Postgre itself, other Postgre compatible databases don't implement this as far as I can tell.
However I believe even MongoDB with it sharding can't handle GEO unless you separate that data in a unsharded collection, which is then placed on any replica set in the cluster. So maybe you could split geo results up by city level in different collections but then if you wanted to find near by things that could go into other cities based on the radius, you'd have to write your own logic. Unsure how larger sites like say Yelp handles GEO lookups.
Only big downside I see with MongoDB though is no joins, so say you had a social networking site and wanted to hide posts by users suspended from the results, you'd have to write your own logic to do so. I think it'd be so cool if you could like symlink a value from one document to another. I think OrientDB has something like that though. I was asking a friend who uses Mongo for advice, apparently in that case you'd just update every single post when you suspend that user - not sure if that's really efficient or not but I doubt a single user would have millions of posts... So probably less than 10K posts at the most maybe. However I guess with social feeds themselves, seems it recommend to fan out on write instead of fanning out on read, so in a way you can sometimes precompute things to help the database. All about making decisions and tradeoffs I guess.
You won't get that popular. And if you do, replacing database layer would be a party with cases of champagne.
They must at least have read replicas given the traffic for the site.
I feel like you need more hardware than that for a hello world kubernetes tutorial...
Bit outdated but probably still holds true.
It's pretty amazing what SQL Server can do...just wish it wasn't so expensive
I find it difficult to setup PostgreSQL without having a single point of failure and introducing downtime for things such as upgrades.
We aren't doing life changing stuff, true, but a downtime in our system can result in employees (often at the bottom of the economic ladder) not being able to get to work. That gnaws at me. I guess the better alternative is to go for a hosted approach, but that isn't without its own complications and challenges.
Amazon does this with RDS, and so can you.
This really isn't very tough to achieve with replicas. And for upgrades you just add a new replica with the latest version and promote it to master and replace the remaining nodes one at a time.
Having a master with a read replica and then making the read replica the master in case the master goes down seems to be a very well known methodology. You can use a virtual ip with both servers behind it (keepalived) or a 0 ttl DNS solution (consul). Is you case more complex than that? With master to master replication I feel there are couple of gotchas and you need to design your data in a way to avoid conflict as much as you can. A solution like bdr seems to be an off-the-shelf one that is proven.
I haven't really upgraded postgres in a rapid fashion, usually just keep with whatever version comes with the OS package manager forever.. or whatever docker image I start it with. I guess the same approach for HA can be used to upgrade one at a time, am assuming postgres doesn't break backwards compatibility very often.
You can either automate the failover or have a system to SMS you when it happens. I like to do it manually personally since I have seen the automated failover fail more times than the manual procedure.
I have probably managed over 30 postgres instances in my services that have grown up to 1/2 PB of data and I've never had a single issue with it... postgres, redis, rabbitmq, consul are technologies that you RTFM, set it up, and it just works!
I wouldn't trust a technology that isn't established and widely adopted which is how I see cockroachdb a the moment.
We still use Postgresql, and I agree, it's setup and forget. But those aren't HA (and don't need to be).
Compared to all that, CRDB is just a binary on each server pointing to each other. Operational simplicity matters and that's where CRDB is a great alternative.
None of that is automatic and every step introduces problems compounded by the amount of tools used to handle each step. Because of this, the setup is intensive and usually custom to every environment. This is hard to test and be confident in and the source of much downtime or data loss.
Meanwhile CRDB handles all of this seamlessly. As long as you have a quorum of healthy nodes, your database is alive and working. Point a load balancer at all of the nodes and you will always have a database to contact with no other overhead. Postgres could get there, but it isn't anywhere there today.
>You can either automate the failover or have a system to SMS you when it happens.
I don't want to be writing code to make things do automatic failover. I'm not a database engineer. I want a database where its standard setup does this stuff for me.
(I would find it really interesting if there was a tightly-integrated "distribution" of Postgresql plus related services that had a setup process as straight-forward as CockroachDB and had automatic read-replicas and failover.)
Anyway, just call it CrDB, it’s an accepted alias. And everyone needs to stop complaining about the name each and every single time.
It's a nod at resiliency, clever IMO.
If you need to list the names of the databases you know, especially if you are not an expert in the domain, and you have heard of it, it will probably be on your list just because it has a memorable name (regardless of its merits).
Problem solved!