HNHacker News
TopNewBestAskShowJobs

paulfurtado

446 karma · joined October 21, 2013

submissionscomments
paulfurtado··on New Linux vulnerability affecting cgroups: can containers escape?
Slightly pedantic: ec2 doesn't actually support nested virtualization on any instance type I know of, but does have baremetal instance types that support virtualization.

The reason I mention this is because, sadly, baremetal instance types are only ever the largest size of a given family which is cost prohibitive for most users. And even if cost isn't an issue, they take much much longer to start (like 10-20+ minutes) and they actually fail to start far too frequently. It's really a shame that all instance types other than baremetal have virtualization extensions disabled, otherwise we'd be operating far more workloads in firecracker or kata. We operate huge kubernetes clusters so the cost is roughly the same whether it's fewer big instances or more smaller instances, but those startup times and reliability are terrible for autoscaling.

Please, AWS, bring nested virtualization to all nitro instance types!

paulfurtado··on Updating software so Starlink can be powered from car cigarette lighter
The fuses are typically 10A and there are products that go right up to that. You can probably safely use 8A in most cars. So about 100 watts.
paulfurtado··on Use of Google Analytics declared illegal by French data protection authority
Is this really true? As far as I know you can be perfectly compliant with EU law by running in AWS's EU regions.
paulfurtado··on Chain of vulnerabilities led to RCE on Cisco Prime servers
It's not usable for cross-domain AJAX requests, is implicit, and it allows for drive by request attacks that must be mitigated with csrf token headers.

Using token auth headers can avoid the use of csrf tokens and make your backend only require a single type of auth.

paulfurtado··on Container-to-Container Communication
Unix sockets only require as much permission as creating a file in a directory. If a program has write access to a directory, it can create a unix socket. File permission on the socket then dictate which users may connect to it.
paulfurtado··on Kubernetes 1.23 Released
That still significantly raises the barrier to entry until someone writes a generic CSI implementation that translates to the flexvolume API.

And then it's still yet another daemon running on every kubernetes node 24/7.

Regardless, in our case the scripts are full-fledged python applications so inevitably we'll just turn them into grpc servers. We're an advanced kubernetes shop so this isn't a real hurdle, but not everyone is.

My complaint isn't that it is impossible, it's that it makes it much more work compared to the previous API and by selecting GRPC as the protocol instead of HTTP, they are largely disregarding the trivial language interoperability there once was for little gain. GRPC+protonuf is a PITA in non-go languages and build systems.

paulfurtado··on Kubernetes 1.23 Released
Sad to see flexVolume deprecated. CSI is a more powerful interface and I knew this was coming, but the simplicity of the flexVolume exec model for node-local volumes was an amazing feature.

With very little effort, you could use them to create volumes managed by any binary or script: for example, a volume that fetches internal build artifacts or a volume similar to configmaps that pulls from external data sources on pod startup.

The new CSI interface requires operating a GRPC server on a local unix socket. It'd have been great if it were at least HTTP+JSON. GRPC really increases the barrier to entry in all languages that can't use the golang CSI driver libraries and it's hard to see the advantages for a low volume API on localhost.

paulfurtado··on Starship: Cross-shell prompt written in Rust
On linux (and I think even osx), even when stdin, stdout, and stderr are redirected, you can always get at the current session's tty via "/dev/tty" unless the executing program spawns a new session which would be very unlikely in this case. This is why things like sudo can defeat pipes and prompt you.
paulfurtado··on IPv6-only subnets and EC2 instances
At this point you can consider all non-nitro instance types to be legacy: it's been years now since all new instance types have been nitro and pretty much every instance family has a nitro replacement that is both faster and cheaper than its predecessor (except in the odd case where the sizes don't line up nicely). So it's very possible they've just stopped letting legacy instance types get new features as an incentive.

However, nitro instances use their own network hardware which includes the ENA NICS and possibly the switches, where it seems like they may have pushed their virtual network stack into hardware, in which case it makes sense that they'd not bother implementing features separately for non-nitro.

Another random network feature nitro instances get is transparent end-to-end encryption for any traffic flowing between two nitro instances in a VPC. There used to also be Network Load Balancer features that only worked for nitro backends/clients.

paulfurtado··on Managing an external display on Linux shouldn’t be this hard
Windows may actually let you override the EDID info, it's been a while since I used windows but I think it lets you do it in device manager... from the era when displays came with drivers on a cdrom.

There are also EDID cloner/emulator hardware solutions that you plug in inline on the display cable.

paulfurtado··on Ask HN: What is the best privacy-focused video doorbell?
Problem with Gira is I've never actually figured out how to purchase it as a consumer. The products look amazing, but it seems impossible to buy in the US.
paulfurtado··on How Microsoft reduced Windows 11 update size by 40%
FWIW, RPM based distros can use delta RPMs
paulfurtado··on PostgreSQL 14 on Kubernetes
This is a controller we wrote in order to make local storage actually usable. Internally we have a "kube cluster operator" that handles the cluster-level ops like this, gracefully draining nodes, etc.
paulfurtado··on PostgreSQL 14 on Kubernetes
Cool thing about finalizers is that there's no straightforward way to delete them from the CLI, you need to explicitly patch the object to delete the finalizer so that goes a long way towards preventing instant mass deletion, they really do help a lot here.

The additional protection we have is via admission controllers which hook all API calls to prevent mistakes, of course, you have to foresee those mistakes and come up with a validation that prevents it. But even something as simple as "only 5 pods are allowed to be terminating at once" can help.

I absolutely agree about people claiming kubernetes is easy. It is easy to throw some helm chart at the kube API and suddenly have an app running with all it's databses configured. It is hard to keep them all running.

The pattern of operators seeks to solve this. Instead of a helm chart creating a MySQL statefulset, it creates a MySQLCluster that gets managed by a well-written operator following the best practices and correctly implementing all the hooks. The ecosystem is starting to converge on this finally and the beauty is that the sum of the industry's operational knowledge can be coded into these operators and we'll finally arrive at nearly fully self managing databases with backups and all.

The industry isn't there quite yet though, and so at least for stateful workloads you need significant operational experience. For background: I am the Tech Lead of our team that runs the kubernetes clusters and we provide all of the primitives our users need and control access. Each database type then has dedicated teams operating them and codifying operations into operators. There is a lot of work being done. But prior to kubernetes, all of these teams separately were coding against the EC2 API with no standardization, no unified view, ad-hoc failure detection, ad-hoc auditing, etc. Kubernetes is a very substantial improvement over that, but 90% of companies never reach a scale where this is necessary. But once extremely solid open source operators exist we may truly hit the dream of just applying some self managing operator manifest to an EKS or GKE cluster and getting an actually production grade database setup.

Version control is an interesting topic because it's hard to express transitive dependencies in that code. For example, the MySQL operator creating a StatefulSet and the Statefulset creating pods. It doesn't make sense to commit those lower level resources to git, they're not fully independent. However, for top level things, our build system produces artifacts from git and the deploy system creates them in the cluster. With this setup, only admins could directly apply them, which really helps with keeping things in sync with git.

paulfurtado··on PostgreSQL 14 on Kubernetes
No database should lack an unsynchronized replica in general. A kubernetes admin could accidentally drain the host, but we run in AWS and AWS can kill nodes a lot faster than we can haha. We have enough servers in AWS that at least 5 fail per day. If some database is not replicated, someone is getting paged for it. We run MySQL with semi-sync replication for example: if a primary has two replicas, one replica must ack a write before the primary commits it, so you can lose the primary at any time and not lose data. That said, kubernetes has prevention mechanisms for this.

PodDisruptionBudgets allow you to specify the minimum number of replicas. The drain command calls evict instead of delete and evict honors these restrictions. This is helpful for node draining, but not necessarily helpful if someone accidentally deletes a StatefulSet. However, nothing in kubernetes deletes PVC objects automatically, so if you delete the pod, the volume remains bound to the PVC until you delete it.

preStop hooks are used in all the database pods to ensure that if the current pod is the primary, leadership is correctly changed to a replica before proceeding with the delete. We combine this with extremely long termination grace periods and alerting if termination is taking too long so that an ops team can look into the issue.

preStop hooks are great, but they also are somewhat of a time bomb if not careful, so some of our database operators make use of finalizers instead. With finalizers, nothing happens when a pod enters the terminating state until an operator marks the pod's finalizer as completed. This flow is really nice because you end up with behavior where the kubernetes cluster admins or built in controllers effectively are really gently requesting that a pod terminate, and it's up to the operator of that pod to decide exactly how and when that occurs.

For non-local volumes, like EBS PVCs, once the PVC is deleted an operator will snapshot the volume during a finalizer before allowing the volume to be fully deleted so that we can recover data if this ever accidentally occurs. This was the first protection we ever implemented when initially adopting kubernetes back when we had no idea what we were doing so that we could always recover data in the event of admin mistakes. We can't do this for local volumes, however, any team making use of local volumes truly needs to stay on top of replication when running in the cloud, whether on kubernetes or not or else you absolutely will lose data. AWS local nvme volumes have limited write cycles just like the ones in on-prem servers. So ideally all databses are configured to not accept writes that cannot be replicated. And even with EBS, at scale we end up with something like 20 unrecoverable volume failures per year

paulfurtado··on PostgreSQL 14 on Kubernetes
We do actually automate this away by deleting PVCs when they are tied to PVs on nodes with our drain taint on them and their pod is in the pending state. We also delete pods owned my StatefulSets that have missing PVCs. These two control loops really grease the wheels. It's definitely frustrating that statefulset pvc management isn't fully declarative, but hopefully this improves.
paulfurtado··on PostgreSQL 14 on Kubernetes
Say you have 100 database clusters and you want to schedule them on dedicated servers.

A kubernetes node can advertise those local block devices as persistent volumes. Your StatefulSet can request that class of local storage and the kubernetes scheduler will then find a volume for the pods on a node that the pod can fit on.

You then get all the features of kubernetes operators plus the performance of dedicated nodes and local storage. When a local storage node disappears, your pod gets a new volume on a new node and can replicate from its peers, or start from a backup.

Kubernetes then offers metrics, certificate management, secret storage and management, load balancing, healthchecks, debugging tools, rich firewalling, RBAC, and a huge ecosystem of plugins. It gives you a unified API for all your workloads. Requesting a database then is as simple as a single API call to kubernetes with a spec for your database (ex: creating a MysqlCluster object).

The company I work for runs MySQL, ZooKeeper, memcached, hbase, hadoop, kafka, elasticsearch, and more in kubernetes with great success. Scale here in one prod region is ~10,000 pods on a clusters of ~600 nodes. There are about 900 separate MySQL clusters consisting of 3 replicas each, 150 separate zk clusters of 5 replicas each, etc.

paulfurtado··on Partitioning GitHub’s relational databases to handle scale
Vitess can be thought of as a very smart MySQL proxy with additional MySQL management features built in.

Centralized vtgates proxy to vttablet services which run on the same host as MySQL, the tablet then queries the local MySQL server. On top of this, a lot of magic can be built

paulfurtado··on Erase your darlings: immutable infrastructure for mutable systems
You can be fairly good about it, but there's always state with the potential to be left behind or become inconsistent: transitive dependencies of packages sticking around, packages with pre/post scripts, services writing out data files to unexpected locations on disk you forget to cleanup, a failure somewhere between a resource and a "notify" firing causing your service to not restart after a config file update and the next run not rerunning the notify, etc.
paulfurtado··on Transmission torrent client ported to C++
Transmission also does have transmission-cli
paulfurtado··on Nftables 1.0.0 Released
Kubernetes implements load balancing via iptables probability rules. It creates "magic" static IPs on all kube nodes for ClusterIP services and makes iptables randomly select backend pods, making for a highly efficient zero-userspace load balancer. That gets less efficient with more rules due to the linearity of iptables. It also has an alternative implementation using ipvs, which is theoretically more efficient but has faced a number of issues over the years.

Kubernetes also has network security policy features for firewalling, that piece is implemented by plugins which do whatever they want though.

At this time, kubernetes requires you to be using iptables instead of nftables for all of this, so it will be interesting to see it running on iptables-free servers in the future.

paulfurtado··on Nftables 1.0.0 Released
cillium reimplements kube-proxy's functionality. There may still be a couple of features missing, but it can definitely take over service routing more efficiently. I haven't checked in a bit but I'm pretty sure it covers NodePort too
paulfurtado··on It looks like a product but is secretly a subscription
As someone who hates making frequent grocery trips and drinks milk too intermittently to ever finish a normal bottle before it goes bad, I highly recommend buying UHT (Ultra High Temperature) pasteurized milk which does actually often have 3+ week shelf life. In the US, typically the organic brands are all UHT since they often come from farther away and need longer shelf life, but some of the cheap brands like Hood also do it.
paulfurtado··on Life of a Container (2020)
If running as a privileged user, you can run the process in just a PID namespace with no other container features enabled using the unshare command.

Systemd can also handle it by killing the processes by cgroup i believe, and for non services you could take advantage of that with systemd-run.

paulfurtado··on Warp: Fast, Rust-based terminal (waiting list)
It's been a while, but gnome-terminal on earlier gnome 3 releases used to segfault very frequently for me. It's the thing that finally made me seek out other terminal emulators
paulfurtado··on How Netflix uses eBPF flow logs at scale for network insight
Doing it with eBPF gives you a hook for each retransmit, this makes it possible to know the exact connection, process, and network interface that hit the retransmit and allows you measure things like "100s of hosts are hitting 1000s of retransmits to 10.0.0.56:443", which 10.0.0.56's netstat metrics may not clearly indicate. It gets more interesting if you break things down by VM hosts, racks, rows, data centers, etc.

If you go deeper with the eBPF tracing, you can also determine which code path the retransmit occurred on, which may or many not be interesting.

paulfurtado··on Improving Firefox stability on Linux
That said, the ABS tree and the AUR in arch, combined with the general avoidance of patches, do make arch one of the easiest places to play with bleeding edge software. With the toolchain in place, so many packages are just a one line version number change to get any particular version building. Whereas building packages from source on ubuntu/fedora/etc can be an uphill battle depending how entrenched the distro's patches and inter version dependencies are. (Though most of the time, building things via make and sticking them in some directory is acceptable, arch really does make building packages easier than other distros)
paulfurtado··on Improving Firefox stability on Linux
Package versions don't remain in the repo for long so if you don't update the package index you'll find that many packages are not installable. There isn't really a snapshot of compatible versions at a given point in time as far as I know, though this might work for a couple of weeks.
paulfurtado··on Improving Firefox stability on Linux
> More often, sure. But for software delivery from the production side, the common viewpoint seems to be that deploying more often leads to less pain in total, because you're making smaller increments so the individual failures are smaller as well. > > As such, aside from integration issues like Xorg and the drivers, I would expect Arch to have fewer major breakages than (e.g.) using LTS releases of some distro and upgrading every second year.

This is mostly true for production infra (at least for your own software in production infra) but I'm not sure this logic flies for personal machines and software you don't directly interact with. I have used arch for at least 7 years and I have had upgrades render my system unbootable (or nearly unbootable, like Xorg/GDM/Gnome failing to start). These issues were mostly not due to my configuration needing to change, they were due to breakages between different packages that would end up being fixed in some later minor version.

As an end-user upgrading distros every 2 years, I really doubt I'd hit many major breakages each time as all of those pieces of software will have been in the wild for a bit and major bugs will have likely been fixed. I think the system-level issues that are resolved by frequent deploys are stuff like "systemd deprecated setting X in service unit files, so I need to update my config" or "library xyz changed some API so I need to update my app", etc. With linux distros that have coordinated releases like fedora/ubuntu/debian/etc my software's interaction with the distro may break, but for the most part the major inter-package relationships within the distro get some amount of coordinated testing which doesn't happen with rolling release distros.

Put another way: deploying more often is great for quickly discovering problems introduced in software that you write. Deploying every single dependency in a linux distro more often is going to cause you to hit every bug destined to be fixed in some minor version of the software in pieces of code that you are very far away from and lack the context to quickly debug. So you will hit a much higher sum total of bugs that would have otherwise ended up getting fixed whether you personally hit them or not. However, if you are developing a linux distribution itself, then yes your CI infra should be constantly upgrading dependencies.

I'm not convinced that an arch-paced rolling release at a distro level will ever reach a point where inter-package dependencies do not cause totally unexpected bugs given just how many inter-library dependencies there are. The entire OSS ecosystem would need to write a ton more tests for this to be a reality, and distros would need to run that full suite of tests any time and dependency is upgraded. And even then, there's still so much possibility for breakages given that shared libraries don't do a fantastic job of versioning and the upstream vendors can't possibly ensure their software works against versions of a library they never ran it against. There's a linus torvalds post about this: https://lwn.net/ml/linux-kernel/CAHk-=whs8QZf3YnifdLv57+FhBi...

Despite all of this, Arch is actually amazingly stable, and the entire community is probably better off due to the existence of arch and arch users. We might be the best integration test there is for OSS software.

paulfurtado··on Improving Firefox stability on Linux
Yeah, definitely usually fine to avoid kernel upgrades, so that is a saving grace. The issue is just that pacman -Syu is going to be full of surprises
← PreviousPage 2 of 7Next →