Bug #91395 Mysql 8.0 does not run in Centos docker container without SYS_NICE capability
Submitted: 24 Jun 2018 23:17 Modified: 26 Jul 2018 6:10
Reporter: Mike Bayer Email Updates:
Status: No Feedback Impact on me:
None 
Category:MySQL Server Severity:S1 (Critical)
Version:8.0 OS:CentOS (CentOS Linux release 7.3.1611 )
Assigned to: Terje Røsten CPU Architecture:x86

[24 Jun 2018 23:17] Mike Bayer
Description:
A docker image build from centos cannot run /usr/sbin/mysqld without the SYS_NICE capability being added; gets "operation not permitted" otherwise.  this is a critical issue since it prevents "docker build" from being able to run mysqld in order to initialize the data directory or similar, since "docker build" does not accept the "--cap-add" option.

How to repeat:
1. create dockerfile:

[root@dell tmp]# cat > dockerfile << EOF
> FROM centos
> 
> RUN curl -OL https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm
> 
> RUN \
>      rpm -i mysql80-community-release-el7-1.noarch.rpm && \
>      yum-config-manager --enable mysql80-community && \
>      yum install -y mysql-community-server
> EOF

2. build image:

[root@dell tmp]# docker build -f dockerfile .
Sending build context to Docker daemon 2.048 kB
Step 1/3 : FROM centos
 ---> 49f7960eb7e4
Step 2/3 : RUN curl -OL https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm
 ---> Using cache
 ---> 24a5674a9557
Step 3/3 : RUN rpm -i mysql80-community-release-el7-1.noarch.rpm &&      yum-config-manager --enable mysql80-community &&      yum install -y mysql-community-server
 ---> Running in a85f95ba432c

# ... output truncated ... #

---> 8c82a8c18c5f
Removing intermediate container a85f95ba432c
Successfully built 8c82a8c18c5f

3. demonstrate we can do a simple mysqld --help with the SYS_NICE capability

[root@dell tmp]# docker run --cap-add SYS_NICE 8c82a8c18c5f /usr/sbin/mysqld --help
2018-06-24T23:15:33.128006Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.11) starting as process 1
/usr/sbin/mysqld  Ver 8.0.11 for Linux on x86_64 (MySQL Community Server - GPL)
Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Starts the MySQL database server.

Usage: /usr/sbin/mysqld [OPTIONS]

For more help options (several pages), use mysqld --verbose --help.

4. demonstrate that without SYS_NICE, we get "operation not permitted"

[root@dell tmp]# docker run  8c82a8c18c5f /usr/sbin/mysqld --help
standard_init_linux.go:178: exec user process caused "operation not permitted"

Suggested fix:
a simple run of mysqld should not require calling upon setpriority(), or it should gracefully degrade when this system call is not permitted.   per https://dev.mysql.com/doc/refman/8.0/en/innodb-parameters.html the setpriority call is skipped when it's "not available" which this situation corresponds towards.
[25 Jun 2018 2:35] Tsubasa Tanaka
I saw a same problem but this is described restriction.,,

https://dev.mysql.com/doc/refman/8.0/en/resource-groups.html#resource-group-restrictions

From Japan MySQL User Group
[25 Jun 2018 14:29] Mike Bayer
yup, that's the problem, it's packaged like this

[root@219222dd3c4d /]# getcap /usr/sbin/mysqld
/usr/sbin/mysqld = cap_sys_nice+ep

dockerfile as follows resolves:

FROM centos

RUN curl -OL https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm

RUN  rpm -i mysql80-community-release-el7-1.noarch.rpm && yum-config-manager --enable mysql80-community && yum install -y mysql-community-server

RUN setcap -r /usr/sbin/mysqld

I know how it goes w/ Oracle bug reports but IMHHHHHO the RPM should script conditionally setting this based on a check against the environment if the capability is even possible (just call nice and see if it fails).
[26 Jun 2018 6:10] Terje Røsten
Hi!

Thanks for report!

This is a side effect WL#9467: Resource Groups:
 https://dev.mysql.com/worklog/task/?id=9467

In some restricted contexts (e.g under SELinux & docker) this caused
issues even the feature was not used.

I still don't understand why your images fails completely, you get the
"operation not permitted" warning, is this fatal in your case?

I also don't understand why you want to run initialize during *build* of the
image, can you please explain your use case and a way to produce this issue?
[26 Jun 2018 8:02] Terje Røsten
If you want to build a CentOS based image, the most easy path will be to use
files from:

 https://github.com/mysql/mysql-docker/tree/mysql-server/8.0

and just change the FROM line in Dockerfile.

If this fails in build or run step can you please provide logs.
[26 Jun 2018 11:02] Terje Røsten
Yeah, %post script for standard server rpm does: 

%{_sbindir}/setcap cap_sys_nice+ep %{_sbindir}/mysqld

for Resources Group feature to work out of the box.

However, the rpm used for MySQL docker image: 

 http://repo.mysql.com/yum/mysql-8.0-community/docker/x86_64/mysql-community-server-minimal...

don't call setcap in %post script. 

In some cases there might be need for the standard rpm and then adding 
RUN "setcap -r  /usr/sbin/mysqld" seems like a good solution, however you mean
we can add check of nice before running setcap? Something like this:

if nice > /dev/null 2>&1; then
  %{_sbindir}/setcap cap_sys_nice+ep %{_sbindir}/mysqld
else
  :
fi

(we need to return true from %post script , if not install of rpm will fail
with scriptlet error.)

There still might be problems as context during install of rpm and of execution of mysqld might be different. 

In a way, it feels more naturally that the special environment (here: docker) takes care of
this problem than having logic in %post in rpm to deal with this, agree?
[27 Jul 2018 1:00] Bugs System
No feedback was provided for this bug for over a month, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".