> IncludeOS is a minimal unikernel operating system for C++ services running in the cloud and on real hardware.
> more minimal
Which carries other benefits: boot time, memory overhead, etc. You could probably treat IncludeOS VMs like containers.
If you're using runtime languages on the backed (node, python) then you're already failing the environment. An efficient compiled language can perform the same functions much more efficiently.
Not necessarily. If you make a living running a typical CRUD software-as-a-service offering, your code may really just be glue mapping HTTP requests to database requests. There, your choice of language doesn't count for much; your code isn't doing heavy lifting, the DBMS is.
It's quite possible your hardware requirements could be lower by writing in Python and tuning your database, rather than spending the same time writing non-performance-critical code in C++.
Frameworks like Tornado, for Python, are able to quite efficiently handle highly concurrent workloads, despite using a single-threaded, interpreted, language.
For computationally intensive code, then sure, a language like Python will need far more hardware horsepower to get the job done than C++ would.
This post is about an optimized environment for C++ services though - not node or python services.
Unlike some other methods for reducing carbon emissions, which require subsidies to be competitive, massively reducing server infrastructure footprint often improves the absolute economics through radical reductions in OpEx/CapEx for data intensive businesses.
That said, if your goal is reducing expenditures, reducing your carbon footprint is a great cherry on top.
1- Yes, optimizing for lowering this consumption by an app-developer can definitely be an ill-advised endeavor economically (you're saving 0.1-10% of your cost.. by adding a huge investment of time, possibly larger than the application development itself)
2- Optimizing across all deployments, can definitely move the needle, in a very significant way, against the effort required, since you're automatically deployed on 1000-1M places.
It's the same reason library developers (especially system/langugage/heavily-used-libraries) have a very good reason economically (and therefore ecologically as well) to optimize. Competition here is a huge benefit to everyone, including the environment.
If you want to see what real computing energy looks like, look at Bitcoin.
Technical speaking, a clean slate solution always offer better quality for the targeted usage scenario.
The problem however, is how much users would be willing to pay for the difference in quality.
Being able to share the kernel safely means potentially better utilization. (The progression is dedicated machines -> hypervisor-based VMs -> multiple customers sharing the Linux kernel. gVisor exists for that last step, but I don't see anyone willing to sell me the ability to run my random container next to their mission-critical security-sensitive app, whereas people are perfectly happy to share CPUs with me if there is a hypervisor in the middle. But we're certainly moving in that direction.)
It is also intriguing to imagine a world that moves the other direction; just have a giant computer with thousands of power-efficient CPUs in it and no virtualization. When a request comes in to your app, your CPU is just powered on, your app boots in a millisecond, handles the request, and shuts down. I am not sure even the big cloud providers have solved the time-of-day utilization problems; being able to turn most of the computers off at night has some potential to save money. (I would turn my workstation off at night if it booted in 1 millisecond in the morning, for example. I can also imagine some power savings for mobile devices if they could go hard off for 59 seconds out of every minute.)
There's no reason to believe Spectre and Meltdown were a one time thing, especially since the response has been to apply ad-hoc fixes just good enough to break the proofs-of-concept. On the contrary, they demonstrate that such vulnerabilities are possible and we should expect to see them again.
Even barring CPU bugs, the kernel is one giant attack surface, all written in C, all running with full ring 0 privileges. Find ONE hole to pwn.
Do AWS spot prices fall at night? That would be one way of increasing utilization - assuming, of course, that there’s sufficient demand at any viable price. There most only be so many jobs people are willing to run unobserved overnight in order to save money.
Or perhaps AWS (and others) are actually powering systems up and down to meet demand? That makes a lot more sense, I suppose.
I don't know whether things have improved since then.
> A longer list of features and limitations can be found on our documentation site.
But unfortunately it looks like the linked page doesn't actually talk about limitations :) Unless you consider a warning about hlt-ing yourself in the foot a list of limitations I guess.
- You can't just port anything to IncludeOS. Since you have direct hardware control and you can schedule work directly to numbered CPUs you can take advantage of things, but if you don't do that then you are just living in a limited C++ environment.
- The network stack hasn't been built with multiprocessing in mind, and some parts need to be rebuilt because of that
- There are codepaths that could lead to C++ exceptions, such as being out of memory, which trounces performance.
- There is a paging and memory allocation system in the OS which doesn't have to be there (for example paging can be "burned in" to the image for the most part, while only leaving room for adding pages for stacks. Memory can be handled by donating everything to the C standard library) - the goal being to keep the attack surface lower.
- Debugging is hard - you will have to connect to GDB while pausing somewhere in the OS.
This is really just me thinking out loud. Add salt.
Also a big collection of info on unikernels: https://github.com/cetic/unikernels
The bigger risk is DDoS attacks but that’s risk when writing sloppy code in any language, runtime and hosting environment.
Am I missing something obvious?
Two ways to address those concerns:
- Your app runs on bare metal and security is implemented on the network layer. For example, something external to app handles authentication and you have something in front of the bare metal box examining and approving requests (like other apps).
- Your app runs in a VM and the hypervisor handles security.
The local user-based security model has been insufficient on the server end of things ever since publicly widely accessible cluters of HTTP servers with load balancers became the norm. Of course you want to protect the local server but we're much more interested in authenticating and applying security beyond the boundaries of any individual OS. There is LDAP and numerous standards but they require implementation beyond the OS - your own or reliance on a third party like Google or Microsoft. If you have to reimplement this with microservices then who cares about the local OS?
A microservice that is only spoken to via HTTP GET or POST requests could get away with removing a lot of things in a traditional OS, such as shells, TTYs, console support, all drivers unrelated to CPU features or networking (no SCSI, floppy, etc.), all drivers unrelated to sending/receiving data through a NIC (no xtables support, no NAT/routing, no weird TCP options no one uses, no weird protocols no one users, no conntrack), no dnotify/inotify support, and maybe even go so far as to remove code behind syscalls that the app doesn't actually use. No TTY support means no one's logging in, so who cares about users at this point?
A non-microservice app, like CGI scripts invoked via Apache, is probably a poor choice for unikernel, but a front-end caching webserver may not be.
The alternative for people using this approach is running in a kernel module, or a kernel-bypass setup with root permissions. Grown-up stuff. Eliminating most of the kernel, and using C++ not C is a very substantial improvement over status quo.
This is a really weird hill to die on; I see you've made the same comment several times in this thread. C and C++ fit hand in glove, and lots of folks use them in conjunction. I don't think anybody here has the misconception that C/C++ is a single language, unless perhaps they don't know either.
Equating the two is extremely common, even by people who are certainly equipped to know better. When you feel a need to tar C++ as if it were C, you signal the weakness of your argument before you have even expressed it.
Please turn down your flamethrower, that style of conversation is not welcome here.
It is fine when talking about ABI or object-code generation.
The failure modes of Rust code are very different from C's, but calling C libraries, as is usually a practical necessity in production, exposes you to all of them.
Switching to modern C++ nets 90% of the benefit (plus other benefits Rust lacks, and may always lack) for 10% of the cost and 0% of the hump.
So, is it C/Rust and C/C++, or Rust and C++?
The "/" symbol is an infinitely extensible shorthand for a union.
What you are describing is an embedded system, which is done, very commonly. This thing is effectively running like an embedded system within a larger system.
The first commits to IncludeOS were 2014, when Rust was in a high state of flux; before the 1.0 release. So I'm certainly not surprised given the historical context of the two projects.
Rust has some cool features, but believe it or not, C++ is still a popular language and people continue to develop projects that are older than Rust. So even if you're of the opinion that C++ is entirely deprecated by Rust, we're not going to stop the entire world and rewrite every C++ project in Rust.
But good news! You can run your Rust apps in a Rust-based unikernel OS . Since these OSs are meant to run in containers, the ecosystem is big enough for both and we don't need such shedpainting conversations.
Memory and thread safety properties can be achieved in C++ by operating at a higher level than C with mature, well-debugged, well-optimized libraries. No pointers means no pointer errors.
Integer overflows are equally possible in Rust and C++. Both offer debug build modes that can watch for those.
Use after free can be perfectly well expressed with C++ references, or invalidated iterators to standard library containers.
> Integer overflows are equally possible in Rust and C++.
In C++, unsigned integer overflows can often be leveraged into out-of-bounds access; in safe Rust, they cannot.
Eh, not to the extent that Rust does. It’s still reasonably easy to get use-after-frees by using a value that has been moved or destroyed.
> Integer overflows are equally possible in Rust and C++. Both offer debug build modes that can watch for those.
In Rust the behavior is defined regardless of signedness.
I have the same discussion with people who insist unsigned types in C++ or C are safer than signed types because of the UB boogeyman. They only demonstrate their own limited understanding.
Anyone else have a unikernel recommendation besides IncludeOS + rpi 4?
> Node.js-style callback-based programming - everything happens in one efficient thread with no I/O blocking or unnecessary guest-side context switching.
Unless I'm missing something.
Then asserts that the retail price for the paper edition is the point ebooks should undercut by, oh, 25%.
This ignores the fact that publishers are not retailers, they're manufacturers; the retail sector takes 50-70% of the price the customer pays for a book, and this includes Amazon's kindle store. In actual fact, the physical cost of goods for a paper book is less than 10% of the price the customer pays. Another 10% is editorial/typesetting costs which are exactly the same for the ebook, maybe 10% goes to the author, and 50-70% to Jeff Bezos and co.
Great technology, top tier team. Although I believe their distance to Silicone Valley and relatively cheap capital causes their difficulty.
I'm thinking as an alternative to CoreOS or COS. These OSs will likely have a relatively high overhead in comparison to IncludeOS should such an OS exists.
Advantage over embedded being you don't need jtag hardware.
I'm taking this and your other remarks as sarcasm. But still, here we go again.
> When will there be a decent Rust unikernel as a drop in replacement for the standard lib/async-std/tokio/whatever ?
You seem to be knowledgeable and interested in such a project. Perhaps you care to create or contribute to such a unikernel project to test against the IncludeOS project?
If not then sit back and keep on waiting.
I'm involved with nanos/ops.
- is the Nano unikernel open source ? A quick (maybe too quick) google search tells me no.
- can you customize the component you want a la MirageOS, eg is it possible in the future to add a fail2ban to your app with a single command line ? same for filesystem and so on.
- is performance on par at least with other linux systems ?
- does it support rust ? not metal barebone rust, but rust with at least the std lib ?
It also runs rust very well.
To your Rust question it seems like the standard library is supported https://github.com/nanovms/ops-examples/blob/master/rust/02-...
When someone write it? Why not you even?
As a user, I don't care whether the tool is in Go, C++, Rust, or whatever else. If Docker was written in C (or Rust, or whatever else), it would have zero effect on my usage of Docker.
SQLite is written in ANSI C. What's your point?
This is my point.
This isn't even an argument here. How is he/she wrong?
It's true that the majority of C/C++ programs are riddled with memory corruption vulnerabilities. Just look at the countless CVE's of WebKit, Linux, Chrome, V8, VMWare and the list forever goes on.
There is a case for Rust to reduce or possibly eliminate these age old vulnerabilities which C/C++ find it hard to do.
You are free to change my mind. :)
Here's your hard slap in your face.
Not really. I said 'reduce or possibly eliminate'. I already entertained the fact that even Rust has bugs. But I can't see how one example of a documented Rust vulnerability which even requires a tricky exploit chain in practice, would change my mind given the tens of thousands of memory corruption CVEs in C/C++ software. The effectiveness of Rust's claims to 'reduce' these cases of memory corruption vulnerabilities have been proven over the years.
Rust is no doubt already being tested with confidence in production by many companies for years, making it possible to compliment or replace C/C++ based programs. You too are more than welcome to change my mind. :)
Just wanted to let you know that your comment feels very misleading because you present the large number of bugs in say web browsers and contrast it with no Rust bugs in web browsers because nobody uses a Rust browser(I know Firefox has some parts in Rust but those parts are new so you can't compare it with years old code that had time to accumulate bugs and people to find them)
Applies to any memory safe programming language, not only Rust.
It won't be that easy.
Or the ones given by Google and Microsoft at Linux Kernel Security Summit 2018 and 2019.
But in OpenBSD even plan9port compiled software is done with Retguard:
>nm $HOME/Docs/c/p9p/9.aecho | grep retpo
00003150 t __llvm_retpoline_r11
It makes using acid(1) in OpenBSD a bit more difficult, but I almost always omit that.
Yes, it is great that OpenBSD values security over performance, but as the talk shows, not every security feature is as secure in practice as OpenBSD sells it.
Neither of them are magical.
All of them don't suffer from memory corruption, UB and use-after-free like C does.
When we security minded people talk about secure languages, we have a panoply to chose from, Swift, D, OCaml, Java, .NET, ATS, Ada, Go, Nim, Zig, Crystal and many more, yet you always think that we speak only about Rust.
This tribal way of thinking makes no sense at all. I qualify as a C and C++ developer and I'm very excited with Rust. The only baby there is is the software project we are working on.
Meanwhile I, and others have been replacing C and C++ written applications by safer stacks long before Rust was born.
And on mobile OSes, the alternative languagea that are being pushed are not Rust.
Yet the replies are always as if we are only talking about Rust as alternative.
anthk:~>syspatch -l | wc -l
We are counting memory corruption and UB bugs here.
70% of microsoft errors would be gone in future if they start using what you demean as "toy" language.
Yes, it isn't Rust and uses automatic memory management, however as proven by their deployments in production, it is quite usable.
So I stick to ./configure ; make ; make install
All this is well-documented and -understood. The overhead is in no way imaginary.
Unikernels don’t need to do context switches, by virtue of not having processes.
As for context swicthing etc I need some unixy bases. Instead of reinventing everything, I've found in practice that the linux kernel running my programs on baremetal (no virtualization) keeps the overhead to an acceptable minimum.