helpers_linux.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. // +build linux
  2. /*
  3. Copyright 2015 The Kubernetes Authors.
  4. Licensed under the Apache License, Version 2.0 (the "License");
  5. you may not use this file except in compliance with the License.
  6. You may obtain a copy of the License at
  7. http://www.apache.org/licenses/LICENSE-2.0
  8. Unless required by applicable law or agreed to in writing, software
  9. distributed under the License is distributed on an "AS IS" BASIS,
  10. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. See the License for the specific language governing permissions and
  12. limitations under the License.
  13. */
  14. package dockershim
  15. import (
  16. "bytes"
  17. "crypto/md5"
  18. "encoding/json"
  19. "fmt"
  20. "io/ioutil"
  21. "path/filepath"
  22. "strings"
  23. "github.com/blang/semver"
  24. dockertypes "github.com/docker/docker/api/types"
  25. dockercontainer "github.com/docker/docker/api/types/container"
  26. "k8s.io/api/core/v1"
  27. runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
  28. )
  29. func DefaultMemorySwap() int64 {
  30. return 0
  31. }
  32. func (ds *dockerService) getSecurityOpts(seccompProfile string, separator rune) ([]string, error) {
  33. // Apply seccomp options.
  34. seccompSecurityOpts, err := getSeccompSecurityOpts(seccompProfile, separator)
  35. if err != nil {
  36. return nil, fmt.Errorf("failed to generate seccomp security options for container: %v", err)
  37. }
  38. return seccompSecurityOpts, nil
  39. }
  40. func getSeccompDockerOpts(seccompProfile string) ([]dockerOpt, error) {
  41. if seccompProfile == "" || seccompProfile == "unconfined" {
  42. // return early the default
  43. return defaultSeccompOpt, nil
  44. }
  45. if seccompProfile == v1.SeccompProfileRuntimeDefault || seccompProfile == v1.DeprecatedSeccompProfileDockerDefault {
  46. // return nil so docker will load the default seccomp profile
  47. return nil, nil
  48. }
  49. if !strings.HasPrefix(seccompProfile, "localhost/") {
  50. return nil, fmt.Errorf("unknown seccomp profile option: %s", seccompProfile)
  51. }
  52. // get the full path of seccomp profile when prefixed with 'localhost/'.
  53. fname := strings.TrimPrefix(seccompProfile, "localhost/")
  54. if !filepath.IsAbs(fname) {
  55. return nil, fmt.Errorf("seccomp profile path must be absolute, but got relative path %q", fname)
  56. }
  57. file, err := ioutil.ReadFile(filepath.FromSlash(fname))
  58. if err != nil {
  59. return nil, fmt.Errorf("cannot load seccomp profile %q: %v", fname, err)
  60. }
  61. b := bytes.NewBuffer(nil)
  62. if err := json.Compact(b, file); err != nil {
  63. return nil, err
  64. }
  65. // Rather than the full profile, just put the filename & md5sum in the event log.
  66. msg := fmt.Sprintf("%s(md5:%x)", fname, md5.Sum(file))
  67. return []dockerOpt{{"seccomp", b.String(), msg}}, nil
  68. }
  69. // getSeccompSecurityOpts gets container seccomp options from container seccomp profile.
  70. // It is an experimental feature and may be promoted to official runtime api in the future.
  71. func getSeccompSecurityOpts(seccompProfile string, separator rune) ([]string, error) {
  72. seccompOpts, err := getSeccompDockerOpts(seccompProfile)
  73. if err != nil {
  74. return nil, err
  75. }
  76. return fmtDockerOpts(seccompOpts, separator), nil
  77. }
  78. func (ds *dockerService) updateCreateConfig(
  79. createConfig *dockertypes.ContainerCreateConfig,
  80. config *runtimeapi.ContainerConfig,
  81. sandboxConfig *runtimeapi.PodSandboxConfig,
  82. podSandboxID string, securityOptSep rune, apiVersion *semver.Version) error {
  83. // Apply Linux-specific options if applicable.
  84. if lc := config.GetLinux(); lc != nil {
  85. // TODO: Check if the units are correct.
  86. // TODO: Can we assume the defaults are sane?
  87. rOpts := lc.GetResources()
  88. if rOpts != nil {
  89. createConfig.HostConfig.Resources = dockercontainer.Resources{
  90. // Memory and MemorySwap are set to the same value, this prevents containers from using any swap.
  91. Memory: rOpts.MemoryLimitInBytes,
  92. MemorySwap: rOpts.MemoryLimitInBytes,
  93. CPUShares: rOpts.CpuShares,
  94. CPUQuota: rOpts.CpuQuota,
  95. CPUPeriod: rOpts.CpuPeriod,
  96. }
  97. createConfig.HostConfig.OomScoreAdj = int(rOpts.OomScoreAdj)
  98. }
  99. // Note: ShmSize is handled in kube_docker_client.go
  100. // Apply security context.
  101. if err := applyContainerSecurityContext(lc, podSandboxID, createConfig.Config, createConfig.HostConfig, securityOptSep); err != nil {
  102. return fmt.Errorf("failed to apply container security context for container %q: %v", config.Metadata.Name, err)
  103. }
  104. }
  105. // Apply cgroupsParent derived from the sandbox config.
  106. if lc := sandboxConfig.GetLinux(); lc != nil {
  107. // Apply Cgroup options.
  108. cgroupParent, err := ds.GenerateExpectedCgroupParent(lc.CgroupParent)
  109. if err != nil {
  110. return fmt.Errorf("failed to generate cgroup parent in expected syntax for container %q: %v", config.Metadata.Name, err)
  111. }
  112. createConfig.HostConfig.CgroupParent = cgroupParent
  113. }
  114. return nil
  115. }
  116. func (ds *dockerService) determinePodIPBySandboxID(uid string) []string {
  117. return nil
  118. }
  119. func getNetworkNamespace(c *dockertypes.ContainerJSON) (string, error) {
  120. if c.State.Pid == 0 {
  121. // Docker reports pid 0 for an exited container.
  122. return "", fmt.Errorf("cannot find network namespace for the terminated container %q", c.ID)
  123. }
  124. return fmt.Sprintf(dockerNetNSFmt, c.State.Pid), nil
  125. }
  126. // applyExperimentalCreateConfig applys experimental configures from sandbox annotations.
  127. func applyExperimentalCreateConfig(createConfig *dockertypes.ContainerCreateConfig, annotations map[string]string) {
  128. }