Monday 28 September 2015

Tricky: docker, oraclelinux, ubuntu and ulimit -Hn

Virtualization is said to bee good for training and development, but  it should be kept out from productive environments. Some people, to whom I belong, meanwhile changed their minds and are convinced, that e.g. docker containers running ubuntu or oraclelinux, breed85/oracle12c or alike will play an increasing role in data virtualization. See also oaktable-world-agenda-2015/ To get experience and clarify certain questions we have created a Docker Project on github. This story here came up with the number of open files in a system (ulimit -Hn), crucial for productive systems. The issue discussion serves best to  understand the impact and the trickyness of the question. For whom it may concern, it is published here.

It is embarrassing to confess, that I did not remember basic lessons on Linux, otherwise I would have seen the solution long before. Nevertheless the discussion has brought up some surprising details, which should not be withhold.
click on the pictures to enlarge
Consider this statement of Oracle's docker team, certainly not to blame merited colleagues, but to show the trickyness of that point.





It is not true, that the inability to increase ulimit -Hn is founded in Docker itself. And it is not true, that oraclelinux comes along with ulimit -Hn 1048576.

Consider this screenshot:



We have Ubuntu as host OS on a laptop and it has only ulimit -Hn 4096. Then we have a docker image of Ubuntu and it has ulimit -Hn 4096, too. Then we have a docker image of oraclelinux and it has ulimit -Hn 4096, too. We learn, that it is not an intrinsic property of oraclelinux to have ulimit -Hn 1048567.

Now consider the next screenshot from the same laptop, where I meanwhile updated the limits.conf.


Keep in mind, that docker is owned by root. If you want to grant a resource to root, you are bound to write it explicitly into the limits.conf - file of the host OS. Here root is granted 104586 open file descriptors. And you see, that both docker images - ubuntu and oraclelinux - of course have the same ulimit -Hn as the host OS.  Understand the concept of file system layers in Docker, e.g. Architecture of Docker If you log into the docker container as oracle (su - oracle) , you will find, that ulimit -Hn for oracle is 65536, which is configured in the limits.conf of the host. And please convince yourself, that the limits.conf of the docker container itself is empty. Of course you may configure that "local" one in a different way, thus the local configuration overrides the host configuration. Decreasing of limits will always be successful, but increasing beyond the host's limits.conf  will end in an error ("cannot  modify limit: Operation not permitted"). And that is exactly what oracle-rdbms-server-12cR1-preinstall does. Unfortunately it assumes that the host configuration is big enough to allow 65536 open file descriptors for the user oracle. boot2docker  - a lightweight Linux distribution for Windows and Mac OS X - shows, at least on Windows, ulimit -Hn unlimited, so there is no problem, but with usual ( free ) Linux distributions  there is a conflict, which can be resolved as demonstrated.

So the inability to increase ulimit -Hn is not founded in Docker itself, but rather in the configuration of the OS on the host where Docker s running. The configuration of /etc/security/limits.conf is straightforward, but to check the new configuration is not, because it takes effect only at login time, i.e. the user has to log out. There is a little trick on Ubuntu to do it easily - see apply changes to limits.conf immediately - namely add a line to /etc/pam.d/common-session* and simulate a login by sudo -i -u <user>.

And there is another benefit of this discussion for our project: either change the limits.conf before you execute oracle-rdbms-server-12cR1-preinstall or do the preinstall manually as demonstrated in my last post about that and continue your database installation in a docker container.


1 comment:

Marcel Körtgen said...

When rolling your own infrastructure setting ulimits appropriately on the docker hosts is no big deal.
The typical use case however will be using on premise hosts from a saas cloud provider. In this case you have no control over the hosts, you typically don't even know the host by name or ip