diff --git a/cluster/plan.go b/cluster/plan.go index f1dd08fd..347ee2c7 100644 --- a/cluster/plan.go +++ b/cluster/plan.go @@ -525,7 +525,6 @@ func (c *Cluster) BuildKubeletProcess(host *hosts.Host, prefixPath string, servi "/var/lib/calico:/var/lib/calico:z", "/etc/resolv.conf:/etc/resolv.conf", "/sys:/sys:rprivate", - host.DockerInfo.DockerRootDir + ":" + host.DockerInfo.DockerRootDir + ":rw,rslave,z", fmt.Sprintf("%s:%s:shared,z", path.Join(prefixPath, "/var/lib/kubelet"), path.Join(prefixPath, "/var/lib/kubelet")), "/var/lib/rancher:/var/lib/rancher:shared,z", "/var/run:/var/run:rw,rprivate", @@ -537,6 +536,12 @@ func (c *Cluster) BuildKubeletProcess(host *hosts.Host, prefixPath string, servi "/usr:/host/usr:ro", "/etc:/host/etc:ro", } + BindDockerRootDir := fmt.Sprintf("%s:%s:rw,rslave,z", host.DockerInfo.DockerRootDir, host.DockerInfo.DockerRootDir) + if hosts.IsEnterpriseLinuxHost(host) && hosts.IsDockerSELinuxEnabled(host) && !hosts.IsEnterpriseLinuxDocker(host) { + // Avoid relabing on Enterprise Linux with Docker SELinux and upstream Docker + BindDockerRootDir = strings.TrimSuffix(BindDockerRootDir, ",z") + } + Binds = append(Binds, BindDockerRootDir) // Special case to simplify using flex volumes if path.Join(prefixPath, "/var/lib/kubelet") != "/var/lib/kubelet" { Binds = append(Binds, "/var/lib/kubelet/volumeplugins:/var/lib/kubelet/volumeplugins:shared,z") @@ -659,8 +664,15 @@ func (c *Cluster) BuildKubeProxyProcess(host *hosts.Host, prefixPath string, ser Binds := []string{ fmt.Sprintf("%s:/etc/kubernetes:z", path.Join(prefixPath, "/etc/kubernetes")), "/run:/run", - "/lib/modules:/lib/modules:z,ro", } + + BindModules := "/lib/modules:/lib/modules:z,ro" + if hosts.IsEnterpriseLinuxHost(host) && hosts.IsDockerSELinuxEnabled(host) && !hosts.IsEnterpriseLinuxDocker(host) { + // Avoid relabing on Enterprise Linux with Docker SELinux and upstream Docker + BindModules = "/lib/modules:/lib/modules:ro" + } + Binds = append(Binds, BindModules) + if host.DockerInfo.OSType == "windows" { // compatible with Windows Binds = []string{ // put the execution binaries to the host diff --git a/hosts/hosts.go b/hosts/hosts.go index 8ce70c8b..753e0bdd 100644 --- a/hosts/hosts.go +++ b/hosts/hosts.go @@ -395,3 +395,32 @@ func GetInternalAddressForHosts(hostList []*Host) []string { } return hostAddresses } + +func IsDockerSELinuxEnabled(host *Host) bool { + for _, securityOpt := range host.DockerInfo.SecurityOptions { + if securityOpt == "selinux" { + logrus.Debugf("Host [%s] has SELinux enabled in Docker", host.Address) + return true + } + } + return false +} + +func IsEnterpriseLinuxHost(host *Host) bool { + operatingSystem := strings.ToLower(host.DockerInfo.OperatingSystem) + if strings.Contains(operatingSystem, "centos") || strings.Contains(operatingSystem, "red hat") { + logrus.Debugf("Host [%s] with OperatingSystem [%s] is Enterprise Linux", host.Address, operatingSystem) + return true + } + return false +} + +func IsEnterpriseLinuxDocker(host *Host) bool { + dockerInitBinary := host.DockerInfo.InitBinary + // Init binary for Enterprise Linux Docker (not upstream) is /usr/libexec/docker/docker-init-current + // Init binary for upstream Docker is docker-init + if strings.EqualFold(dockerInitBinary, "/usr/libexec/docker/docker-init-current") { + return true + } + return false +} diff --git a/services/services.go b/services/services.go index ed294d01..2451dafa 100644 --- a/services/services.go +++ b/services/services.go @@ -123,25 +123,21 @@ func GetProcessConfig(process v3.Process, host *hosts.Host) (*container.Config, hostCfg.RestartPolicy = container.RestartPolicy{Name: process.RestartPolicy} } // The MCS label only needs to be applied when container is not running privileged, and running privileged negates need for applying the label - if !process.Privileged { - for _, securityOpt := range host.DockerInfo.SecurityOptions { - // If Docker is configured with selinux-enabled:true, we need to specify MCS label to allow files from service-sidekick to be shared between containers - if securityOpt == "selinux" { - logrus.Debugf("Found selinux in DockerInfo.SecurityOptions on host [%s]", host.Address) - // Check for containers having the sidekick container - for _, volumeFrom := range hostCfg.VolumesFrom { - if volumeFrom == SidekickContainerName { - logrus.Debugf("Found [%s] in VolumesFrom on host [%s], applying MCSLabel [%s]", SidekickContainerName, host.Address, MCSLabel) - hostCfg.SecurityOpt = []string{MCSLabel} - } - } - // Check for sidekick container itself - if value, ok := imageCfg.Labels[ContainerNameLabel]; ok { - if value == SidekickContainerName { - logrus.Debugf("Found [%s=%s] in Labels on host [%s], applying MCSLabel [%s]", ContainerNameLabel, SidekickContainerName, host.Address, MCSLabel) - hostCfg.SecurityOpt = []string{MCSLabel} - } - } + // If Docker is configured with selinux-enabled:true, we need to specify MCS label to allow files from service-sidekick to be shared between containers + if !process.Privileged && hosts.IsDockerSELinuxEnabled(host) { + logrus.Debugf("Found selinux in DockerInfo.SecurityOptions on host [%s]", host.Address) + // Check for containers having the sidekick container + for _, volumeFrom := range hostCfg.VolumesFrom { + if volumeFrom == SidekickContainerName { + logrus.Debugf("Found [%s] in VolumesFrom on host [%s], applying MCSLabel [%s]", SidekickContainerName, host.Address, MCSLabel) + hostCfg.SecurityOpt = []string{MCSLabel} + } + } + // Check for sidekick container itself + if value, ok := imageCfg.Labels[ContainerNameLabel]; ok { + if value == SidekickContainerName { + logrus.Debugf("Found [%s=%s] in Labels on host [%s], applying MCSLabel [%s]", ContainerNameLabel, SidekickContainerName, host.Address, MCSLabel) + hostCfg.SecurityOpt = []string{MCSLabel} } } }