github.com/sealerio/sealer@v0.11.1-0.20240507115618-f4f89c5853ae/pkg/infra/container/client/docker/container.go (about) 1 // Copyright © 2021 Alibaba Group Holding Ltd. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package docker 16 17 import ( 18 "github.com/docker/docker/api/types" 19 "github.com/docker/docker/api/types/container" 20 "github.com/docker/docker/api/types/mount" 21 "github.com/docker/docker/api/types/network" 22 "github.com/sirupsen/logrus" 23 24 "github.com/sealerio/sealer/pkg/infra/container/client" 25 ) 26 27 const ( 28 CgroupNoneDriver = "none" 29 ) 30 31 func (p *Provider) getUserNsMode() (container.UsernsMode, error) { 32 sysInfo, err := p.DockerClient.Info(p.Ctx) 33 if err != nil { 34 return "", err 35 } 36 37 var usernsMode container.UsernsMode 38 for _, opt := range sysInfo.SecurityOptions { 39 if opt == "name=userns" { 40 usernsMode = "host" 41 } 42 } 43 return usernsMode, err 44 } 45 46 func (p *Provider) setContainerMount(opts *client.CreateOptsForContainer) []mount.Mount { 47 mounts := DefaultMounts() 48 if opts.Mount != nil { 49 mounts = append(mounts, opts.Mount...) 50 } 51 return mounts 52 } 53 54 func (p *Provider) RunContainer(opts *client.CreateOptsForContainer) (string, error) { 55 //docker run --hostname master1 --name master1 56 //--privileged 57 //--security-opt seccomp=unconfined --security-opt apparmor=unconfined 58 //--tmpfs /tmp --tmpfs /run 59 //--volume /var --volume /lib/modules:/lib/modules:ro 60 //--device /dev/fuse 61 //--detach --tty --restart=on-failure:1 --init=false sealer-io/sealer-base-image:latest 62 networkID, err := p.PrepareNetworkResource(opts.NetworkName) 63 if err != nil { 64 return "", err 65 } 66 67 _, err = p.PullImage(opts.ImageName) 68 if err != nil { 69 return "", err 70 } 71 72 mod, _ := p.getUserNsMode() 73 mounts := p.setContainerMount(opts) 74 falseOpts := false 75 resp, err := p.DockerClient.ContainerCreate(p.Ctx, &container.Config{ 76 Image: opts.ImageName, 77 Tty: true, 78 Labels: opts.ContainerLabel, 79 Hostname: opts.ContainerHostName, 80 AttachStdin: false, 81 AttachStdout: false, 82 AttachStderr: false, 83 }, 84 &container.HostConfig{ 85 UsernsMode: mod, 86 SecurityOpt: []string{ 87 "seccomp=unconfined", "apparmor=unconfined", 88 }, 89 RestartPolicy: container.RestartPolicy{ 90 Name: "on-failure", 91 MaximumRetryCount: 1, 92 }, 93 Init: &falseOpts, 94 CgroupnsMode: "host", 95 Privileged: true, 96 Mounts: mounts, 97 }, &network.NetworkingConfig{ 98 EndpointsConfig: map[string]*network.EndpointSettings{ 99 opts.NetworkName: { 100 NetworkID: networkID, 101 }, 102 }, 103 }, nil, opts.ContainerName) 104 105 if err != nil { 106 return "", err 107 } 108 109 err = p.DockerClient.ContainerStart(p.Ctx, resp.ID, types.ContainerStartOptions{}) 110 if err != nil { 111 return "", err 112 } 113 logrus.Infof("create container %s successfully", opts.ContainerName) 114 return resp.ID, nil 115 } 116 117 func (p *Provider) GetContainerInfo(containerID string, networkName string) (*client.Container, error) { 118 resp, err := p.DockerClient.ContainerInspect(p.Ctx, containerID) 119 if err != nil { 120 return nil, err 121 } 122 return &client.Container{ 123 ContainerName: resp.Name, 124 ContainerIP: resp.NetworkSettings.Networks[networkName].IPAddress, 125 ContainerHostName: resp.Config.Hostname, 126 ContainerLabel: resp.Config.Labels, 127 Status: resp.State.Status, 128 }, nil 129 } 130 131 func (p *Provider) GetContainerIDByIP(containerIP string, networkName string) (string, error) { 132 resp, err := p.DockerClient.ContainerList(p.Ctx, types.ContainerListOptions{}) 133 if err != nil { 134 return "", err 135 } 136 137 for _, item := range resp { 138 if net, ok := item.NetworkSettings.Networks[networkName]; ok { 139 if containerIP == net.IPAddress { 140 return item.ID, nil 141 } 142 } 143 } 144 return "", err 145 } 146 147 func (p *Provider) RmContainer(containerID string) error { 148 err := p.DockerClient.ContainerRemove(p.Ctx, containerID, types.ContainerRemoveOptions{ 149 RemoveVolumes: true, 150 Force: true, 151 }) 152 153 if err != nil { 154 return err 155 } 156 157 logrus.Infof("delete container %s successfully", containerID) 158 return nil 159 } 160 161 func (p *Provider) GetServerInfo() (*client.DockerInfo, error) { 162 sysInfo, err := p.DockerClient.Info(p.Ctx) 163 if err != nil { 164 return nil, err 165 } 166 167 var dInfo client.DockerInfo 168 169 // When CgroupDriver == "none", the MemoryLimit/PidsLimit/CPUShares 170 // values are meaningless and need to be considered false. 171 // https://github.com/moby/moby/issues/42151 172 dInfo.CgroupVersion = sysInfo.CgroupVersion 173 dInfo.StorageDriver = sysInfo.Driver 174 dInfo.SecurityOptions = sysInfo.SecurityOptions 175 dInfo.CgroupDriver = sysInfo.CgroupDriver 176 if sysInfo.CgroupDriver == CgroupNoneDriver { 177 return &dInfo, nil 178 } 179 dInfo.MemoryLimit = sysInfo.MemoryLimit 180 dInfo.PidsLimit = sysInfo.PidsLimit 181 dInfo.CPUShares = sysInfo.CPUShares 182 dInfo.CPUNumber = sysInfo.NCPU 183 return &dInfo, nil 184 }