Page MenuHomePhabricator

WikiKube: Investigate how to abstract misc Mariadb clusters host/ip information so that no deployment of apps is needed when a master is failed over
Closed, ResolvedPublic

Description

In T340780, linkrecommendation issued errors for a period of time due to being unable to contact the MariaDB master database its data is in. This happened due to T337812 and the egress rules needed to be updated to follow the move. We should investigate if we can find a way to abstract away from the applications, and the helm charts, those failovers/moves.

There's a couple of paths that we can take. Some that come to mind are in broad strokes:

Drop egress rules altogether and allow all applications to reach out to any resources they want.

Having egress rules that make sure that services don't get to connect to anything they haven't been explicitly configured for has been a requirement (in part set by the then Services team, and in part set by SRE). The logic behind the requirement was Principle_of_least_privilege. The practical gains are both to mitigate RCE attacks that compromise a service as well as avoiding non easily discoverable communication patterns between various applications and services. In essence, we are talking about patterns that are not clearly set in a single easily searchable repo. The anti-pattern that this move tries to avoid is having services talk to each other through either non sanctioned pathways (e.g. via the edge cache CDN instead of via the service proxy) or via a configuration that is set solely in the deployment repo of the application (which doesn't scale if you have tens of services/applications)

In other environments, the same problem is solved by having the recipient of a communication explicitly whitelist it on their end. Unfortunately, this approach isn't/wasn't so each to achieve in our environment due to the sheer size of historical code. It also has the drawback of adding the onus of updates to the receiving side, which might not be necessarily aware that the initiating side's need might not even exist anymore(e.g. it has migrated away from needing that dependency, it has been undeployed, removed the powered functionality etc), leading eventually to a violation of the Principle_of_least_privilege.

For the above reasons, it's probably prudent that we don't forego entirely our egress limitations.

Allow a predefined set of dst ports, representing MariaDB clusters to be reached by all apps in a kubernetes clusters. (chosen solution)

In this setup, we 'd allow all outgoing traffic for a set predefined dst ports (e.g. 3306-3320). Those ports would be agreed up with Data-Persistence, we would add rules to allow access towards those ports for applications that define in their values.yaml files the MariaDB sections they want access to.

This is essentially just a trimmed down version of the above. It substantially trims down the attack surface by allowing only a few TCP ports, selectable by the application. The port range is derived from MariaDB Puppet manifests, so the source of truth is in the hands of Data-Persistence, allowing to add sections as they please with the proper mappings. Developers/Deployers only need to define the sections they want, without caring about the actual TCP ports.

Depending on the original range of those ports, it might also be sustainable long term, meaning we won't be needing to update that port range often. The MariaDB hosts have anyway password authentication and presumably a compromised service wouldn't have access to the passwords.

Note that this is the path we followed for MW-on-K8s. See https://gerrit.wikimedia.org/r/plugins/gitiles/operations/deployment-charts/+/refs/heads/master/charts/mediawiki/templates/_mw_helpers.tpl#28

Make overall the WikiKube environment (if not the other k8s environments as well) aware of the moves of MariaDB masters.

What we are talking here about is essentially a more automated and stricter version of the above. Applications set a tunable (that we have to invent and implement), that lists the clusters they want access to, e.g. mariadb_cluster_access: ["m1", "x1", "s1", "etc"], and using some puppetdb/netbox automation we collect all IP addresses and allow, possibly per application, access. The difference from the above one is that we don't end up needing a "contract" of sorts (the port list) that all sides need to honor, but rather always the entirety of the information required (the IPs+ports of all destinations needed by the application). The big drawback here is that we need deployments for rules to be updated. If we go with per applications rules, multiple deployments, if we go with a global rule, at least 1 deployment.

This idea would need some work to sketch out more clearly and implement and I am not entirely sold on the value we 'd derive to be honest.

Ossify MariaDB master/follower endpoints

This is essentially what we 've done with all LVS services. Their IPs are kinda set in stone, probably never to change after their initial deployment, moving the updates to the DNS layer (and even then just for switching DCs or maintenance). Given that we already got dbproxy hosts for the Misc clusters, abstracting away the MariaDB hosts themselves, could we just put those behind LVS, giving them statically assigned, never to change virtual service IPs? The pros would be consistency with everything else and knowing that this that works. Cons are that we might need some LVS updates if we even want to add more ports.

Event Timeline

akosiaris renamed this task from Investigate how to abstract misc Mariadb clusters host/ip information so that no manual action is needed when a master is failed over to WikiKube: Investigate how to abstract misc Mariadb clusters host/ip information so that no deployment of apps is needed when a master is failed over.Jun 30 2023, 1:18 PM

The easy way out is ofc to follow the MW-on-K8s way, i.e. put in applications something like what is used in https://gerrit.wikimedia.org/r/plugins/gitiles/operations/deployment-charts/+/refs/heads/master/charts/mediawiki/templates/_mw_helpers.tpl#28

At least that would mean some consistency and would allow us to take some time to think the problem more thoroughly without risking another similar incident to T340780

Some of the ideas above can be implemented using ideas from T331894, e.g. the GlobalNetworkSets could be used to implement the 3rd idea on the side of wikikube.

For what is worth, in this case, the issue was changing a dbproxy that needed refresh. This is an operation we normally only do every 3 years, as we normally we do not change the pair of proxies (we have two, one active and one stand by)

Adding another datapoint: T340950

Toolhub uses m5-master.eqiad.wmnet, but it needs network policies in k8s to allow to contact what its CNAME points to (the dbproxies IPs).

Toolhub uses m5-master.eqiad.wmnet, but it needs network policies in k8s to allow to contact what its CNAME points to (the dbproxies IPs).

At the risk of stating an obvious thing, the same is true for linkrecommendation as well (CNAME is used to actually access the database, but network policies need to be in sync for stuff to work).

We 've discussed this in the ServiceOps meeting today. We touched on a number of subjects. TL;DR is, we would be very interested in re-visiting the Ossify MariaDB master/follower endpoints approach to see what has changed from the past that would make this approach more or less feasible (revisiting assumptions/decisions, so to say). However, we also need to mitigate the issue, and thus we are gonna go with Allow a predefined set of dst ports, representing MariaDB clusters to be reached by all apps in a kubernetes clusters. for the short term. That way we 'll at least have some consistency with MW-on-K8s while still keeping things functional.

@Marostegui Can you provide us with the list of ports that would need to be opened?

In the mw-on-k8s charts we have:
3306 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320
But the comment says

open ports 3306 and 3311 through 3320

And the commit says

any port between 3306 and 3320

What's the canonical answer?

You'd need to open: 3321, 3322, 3323, 3325 too as those are the ones serving the replicas for m1, m2, m3 and m5 (there is no m4)

So, the full list would be:

3306 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3325, right? Is this something we can have an expectation of remaining reasonably stable?

So, dbproxies have nothing listening on 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 behind them.
The dbproxy* have:
Master:3306
Slave: 332[1235]

There is nothing else behind and I don't see that changing anytime soon at all (as that would imply rebuilding all our misc infra).

3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 are used in production (mediawiki) for our multi-instance replicas. But nothing connecting to them goes through a dbproxy.

Cool, that completes the picture I was trying to form, thanks!

Change 935746 had a related patch set uploaded (by Alexandros Kosiaris; author: Alexandros Kosiaris):

[operations/deployment-charts@master] modules: Add a new networkpolicy for base modules

https://gerrit.wikimedia.org/r/935746

Change 940323 had a related patch set uploaded (by Alexandros Kosiaris; author: Alexandros Kosiaris):

[operations/puppet@production] deployment: Support making k8s deploys db section aware

https://gerrit.wikimedia.org/r/940323

Change 940323 merged by Alexandros Kosiaris:

[operations/puppet@production] deployment: Support making k8s deploys db section aware

https://gerrit.wikimedia.org/r/940323

Hi all, is there any update on this please? linkrecommendation service had a second incident today caused by the same problem. I've updated the network policies again, but it'd be great to implement one of the solutions described in this task soon-ish to prevent future outages.

Hi all, is there any update on this please? linkrecommendation service had a second incident today caused by the same problem. I've updated the network policies again, but it'd be great to implement one of the solutions described in this task soon-ish to prevent future outages.

Hi, yes there is. The change linked in the task and dependent changes are almost ready to merge, I have to forward port some changes that made it to the previous version and get a final round of review. Then roll it out to all services and remove all the manually curated network polices and call it done.

That sounds promising! Thank you very much for the update @akosiaris.

Change 935746 merged by jenkins-bot:

[operations/deployment-charts@master] modules: Add a new networkpolicy for base modules

https://gerrit.wikimedia.org/r/935746

akosiaris changed the task status from Open to In Progress.Aug 29 2023, 2:47 PM
akosiaris claimed this task.
akosiaris triaged this task as Medium priority.

Change 953286 had a related patch set uploaded (by Alexandros Kosiaris; author: Alexandros Kosiaris):

[operations/deployment-charts@master] MariaDB egress: Brown paper bag fix

https://gerrit.wikimedia.org/r/953286

Change 953286 merged by jenkins-bot:

[operations/deployment-charts@master] MariaDB egress: Brown paper bag fix

https://gerrit.wikimedia.org/r/953286

Change 953308 had a related patch set uploaded (by Alexandros Kosiaris; author: Alexandros Kosiaris):

[operations/deployment-charts@master] mariadb egress: Second round of brown paper bag fixes

https://gerrit.wikimedia.org/r/953308

Change 953308 merged by jenkins-bot:

[operations/deployment-charts@master] mariadb egress: Second round of brown paper bag fixes

https://gerrit.wikimedia.org/r/953308

Update:

Patch was merged and deployed for cxserver. Things went ok after a couple of roadbump and corresponding brown paper bag fixes. I 'll be deploying the changes to ipoid, toolhub and linkrecommendation in the next few days and remove the hardcoded references to dbproxies from those deployments.

Change 953551 had a related patch set uploaded (by Alexandros Kosiaris; author: Alexandros Kosiaris):

[operations/deployment-charts@master] linkrecommendation: TODO

https://gerrit.wikimedia.org/r/953551

Change 953551 had a related patch set uploaded (by Alexandros Kosiaris; author: Alexandros Kosiaris):

[operations/deployment-charts@master] linkrecommendation: Update vendor modules for T340843

https://gerrit.wikimedia.org/r/953551

Change 953554 had a related patch set uploaded (by Alexandros Kosiaris; author: Alexandros Kosiaris):

[operations/deployment-charts@master] linkrecommendation: Remove all hardcoded dbproxy networkpolicies

https://gerrit.wikimedia.org/r/953554

Change 953551 merged by jenkins-bot:

[operations/deployment-charts@master] linkrecommendation: Update vendor modules for T340843

https://gerrit.wikimedia.org/r/953551

Change 953554 merged by jenkins-bot:

[operations/deployment-charts@master] linkrecommendation: Remove all hardcoded dbproxy networkpolicies

https://gerrit.wikimedia.org/r/953554

Change 953629 had a related patch set uploaded (by Alexandros Kosiaris; author: Alexandros Kosiaris):

[operations/deployment-charts@master] linkrecommendation: Use mesh.deployment 1.2 sextant module

https://gerrit.wikimedia.org/r/953629

Change 953629 merged by jenkins-bot:

[operations/deployment-charts@master] linkrecommendation: Use mesh.deployment 1.2 sextant module

https://gerrit.wikimedia.org/r/953629

Change 954262 had a related patch set uploaded (by Alexandros Kosiaris; author: Alexandros Kosiaris):

[operations/deployment-charts@master] toolhub: Update to utilize MariaDB egress functionality

https://gerrit.wikimedia.org/r/954262

Change 954263 had a related patch set uploaded (by Alexandros Kosiaris; author: Alexandros Kosiaris):

[operations/deployment-charts@master] toolhub: Remove hardcoded dbproxies, enable MariaDB egress

https://gerrit.wikimedia.org/r/954263

Change 954265 had a related patch set uploaded (by Alexandros Kosiaris; author: Alexandros Kosiaris):

[operations/deployment-charts@master] ipoid: Update to utilize MariaDB egress functionality

https://gerrit.wikimedia.org/r/954265

Change 954266 had a related patch set uploaded (by Alexandros Kosiaris; author: Alexandros Kosiaris):

[operations/deployment-charts@master] ipoid: Remove hardcoded dbproxy stanzas

https://gerrit.wikimedia.org/r/954266

Change 954262 merged by jenkins-bot:

[operations/deployment-charts@master] toolhub: Update to utilize MariaDB egress functionality

https://gerrit.wikimedia.org/r/954262

Change 954263 merged by jenkins-bot:

[operations/deployment-charts@master] toolhub: Remove hardcoded dbproxies, enable MariaDB egress

https://gerrit.wikimedia.org/r/954263

Change 954265 merged by jenkins-bot:

[operations/deployment-charts@master] ipoid: Update to utilize MariaDB egress functionality

https://gerrit.wikimedia.org/r/954265

Change 954266 merged by jenkins-bot:

[operations/deployment-charts@master] ipoid: Remove hardcoded dbproxy stanzas

https://gerrit.wikimedia.org/r/954266

ipoid and toolhub done today. Resolving this. We 've chosen a path forward, implemented it and migrated the services that utilized hardcoded dbproxies networking rules to the new thing.

Change 955422 had a related patch set uploaded (by JMeybohm; author: JMeybohm):

[operations/deployment-charts@master] CI: Pull mariadb_sections into general fixtures

https://gerrit.wikimedia.org/r/955422

Change 955422 merged by jenkins-bot:

[operations/deployment-charts@master] CI: Pull mariadb_sections into general fixtures

https://gerrit.wikimedia.org/r/955422