zoukankan      html  css  js  c++  java
  • bindMountContainerRootfs(

    func (k *kataAgent) createContainer(sandbox *Sandbox, c *Container) (p *Process, err error) {
            span, _ := k.trace("createContainer")
            defer span.Finish()
    
            var ctrStorages []*grpc.Storage
            var ctrDevices []*grpc.Device
            var rootfs *grpc.Storage
    
            // This is the guest absolute root path for that container.
            rootPathParent := filepath.Join(kataGuestSharedDir(), c.id)
            rootPath := filepath.Join(rootPathParent, c.rootfsSuffix)
    
            // In case the container creation fails, the following defer statement
            // takes care of rolling back actions previously performed.
            defer func() {
                    if err != nil {
                            k.Logger().WithError(err).Error("createContainer failed")
                            k.rollbackFailingContainerCreation(c)
                    }
            }()
    
            if rootfs, err = k.buildContainerRootfs(sandbox, c, rootPathParent); err != nil {
                    return nil, err
            } else if rootfs != nil {
                    // Add rootfs to the list of container storage.
                    // We only need to do this for block based rootfs, as we
                    // want the agent to mount it into the right location
                    // (kataGuestSharedDir/ctrID/
                    ctrStorages = append(ctrStorages, rootfs)
            }
    
            ociSpec := c.GetPatchedOCISpec()
            if ociSpec == nil {
                    return nil, errorMissingOCISpec
            }
    
            // Handle container mounts
            newMounts, ignoredMounts, err := c.mountSharedDirMounts(getMountPath(sandbox.id), kataGuestSharedDir())
            if err != nil {
                    return nil, err
            }
    
            k.handleShm(ociSpec.Mounts, sandbox)
    
            epheStorages := k.handleEphemeralStorage(ociSpec.Mounts)
            ctrStorages = append(ctrStorages, epheStorages...)
    
            localStorages := k.handleLocalStorage(ociSpec.Mounts, sandbox.id, c.rootfsSuffix)
            ctrStorages = append(ctrStorages, localStorages...)
    ls /var/lib/docker/volumes/data1/
    _data
    root@p:/home/pcl# ls /var/lib/docker/volumes/data1/_data/
    find  /var/lib/docker/overlay2/0302ff6f07ca65ebbf82884a33e0dcec795e0de1d5af7006d5473402028099eb/  -name data1
    /var/lib/docker/overlay2/0302ff6f07ca65ebbf82884a33e0dcec795e0de1d5af7006d5473402028099eb/merged/data1
    /var/lib/docker/overlay2/0302ff6f07ca65ebbf82884a33e0dcec795e0de1d5af7006d5473402028099eb/diff/data
    func (k *kataAgent) buildContainerRootfs(sandbox *Sandbox, c *Container, rootPathParent string) (*grpc.Storage, error) {
            if c.state.Fstype != "" && c.state.BlockDeviceID != "" {
                    // The rootfs storage volume represents the container rootfs
                    // mount point inside the guest.
                    // It can be a block based device (when using block based container
                    // overlay on the host) mount or a 9pfs one (for all other overlay
                    // implementations).
                    rootfs := &grpc.Storage{}
    
                    // This is a block based device rootfs.
                    device := sandbox.devManager.GetDeviceByID(c.state.BlockDeviceID)
                    if device == nil {
                            k.Logger().WithField("device", c.state.BlockDeviceID).Error("failed to find device by id")
                            return nil, fmt.Errorf("failed to find device by id %q", c.state.BlockDeviceID)
                    }
    
                    blockDrive, ok := device.GetDeviceInfo().(*config.BlockDrive)
                    if !ok || blockDrive == nil {
                            k.Logger().Error("malformed block drive")
                            return nil, fmt.Errorf("malformed block drive")
                    }
                    switch {
                    case sandbox.config.HypervisorConfig.BlockDeviceDriver == config.VirtioMmio:
                            rootfs.Driver = kataMmioBlkDevType
                            rootfs.Source = blockDrive.VirtPath
                    case sandbox.config.HypervisorConfig.BlockDeviceDriver == config.VirtioBlockCCW:
                            rootfs.Driver = kataBlkCCWDevType
                            rootfs.Source = blockDrive.DevNo
                    case sandbox.config.HypervisorConfig.BlockDeviceDriver == config.VirtioBlock:
                            rootfs.Driver = kataBlkDevType
                            if blockDrive.PCIAddr == "" {
                                    rootfs.Source = blockDrive.VirtPath
                            } else {
                                    rootfs.Source = blockDrive.PCIAddr
                            }
    
                    case sandbox.config.HypervisorConfig.BlockDeviceDriver == config.VirtioSCSI:
    
                            rootfs.Driver = kataSCSIDevType
                            rootfs.Source = blockDrive.SCSIAddr
                    default:
                            return nil, fmt.Errorf("Unknown block device driver: %s", sandbox.config.HypervisorConfig.BlockDeviceDriver)
                    }
    
                    rootfs.MountPoint = rootPathParent
                    rootfs.Fstype = c.state.Fstype
    
                    if c.state.Fstype == "xfs" {
                            rootfs.Options = []string{"nouuid"}
                    }
    
                    // Ensure container mount destination exists
                    // TODO: remove dependency on shared fs path. shared fs is just one kind of storage sources.
                    // we should not always use shared fs path for all kinds of storage. Stead, all storage
                    // should be bind mounted to a tmpfs path for containers to use.
                    if err := os.MkdirAll(filepath.Join(getMountPath(c.sandbox.id), c.id, c.rootfsSuffix), DirMode); err != nil {
                            return nil, err
                    }
                    return rootfs, nil
            }
            // This is not a block based device rootfs.
            // We are going to bind mount it into the 9pfs
            // shared drive between the host and the guest.
            // With 9pfs we don't need to ask the agent to
            // mount the rootfs as the shared directory
            // (kataGuestSharedDir) is already mounted in the
            // guest. We only need to mount the rootfs from
            // the host and it will show up in the guest.
            if err := bindMountContainerRootfs(k.ctx, getMountPath(sandbox.id), c.id, c.rootFs.Target, false); err != nil {
                    return nil, err
            }
    
            return nil, nil
    }
    // bindMountContainerRootfs bind mounts a container rootfs into a 9pfs shared
    // directory between the guest and the host.
    func bindMountContainerRootfs(ctx context.Context, shareDir, cid, cRootFs string, readonly bool) error {
            span, _ := trace(ctx, "bindMountContainerRootfs")
            defer span.Finish()
    
            rootfsDest := filepath.Join(shareDir, cid, rootfsDir)
    
            return bindMount(ctx, cRootFs, rootfsDest, readonly, "private")
    }
    // bindMount bind mounts a source in to a destination. This will
    // do some bookkeeping:
    // * evaluate all symlinks
    // * ensure the source exists
    // * recursively create the destination
    // pgtypes stands for propagation types, which are shared, private, slave, and ubind.
    func bindMount(ctx context.Context, source, destination string, readonly bool, pgtypes string) error {
            span, _ := trace(ctx, "bindMount")
            defer span.Finish()
    
            if source == "" {
                    return fmt.Errorf("source must be specified")
            }
            if destination == "" {
                    return fmt.Errorf("destination must be specified")
            }
    
            absSource, err := filepath.EvalSymlinks(source)
            if err != nil {
                    return fmt.Errorf("Could not resolve symlink for source %v", source)
            }
    
            if err := ensureDestinationExists(absSource, destination); err != nil {
                    return fmt.Errorf("Could not create destination mount point %v: %v", destination, err)
            }
    
            if err := syscall.Mount(absSource, destination, "bind", syscall.MS_BIND, ""); err != nil {
                    return fmt.Errorf("Could not bind mount %v to %v: %v", absSource, destination, err)
            }
    
            if pgtype, exist := propagationTypes[pgtypes]; exist {
                    if err := syscall.Mount("none", destination, "", pgtype, ""); err != nil {
                            return fmt.Errorf("Could not make mount point %v %s: %v", destination, pgtypes, err)
                    }
            } else {
                    return fmt.Errorf("Wrong propagation type %s", pgtypes)
            }
    
            // For readonly bind mounts, we need to remount with the readonly flag.
            // This is needed as only very recent versions of libmount/util-linux support "bind,ro"
            if readonly {
                    return syscall.Mount(absSource, destination, "bind", uintptr(syscall.MS_BIND|syscall.MS_REMOUNT|syscall.MS_RDONLY), "")
            }
    
            return nil
    }
    func (k *kataAgent) handleLocalStorage(mounts []specs.Mount, sandboxID string, rootfsSuffix string) []*grpc.Storage {
            var localStorages []*grpc.Storage
            for idx, mnt := range mounts {
                    if mnt.Type == KataLocalDevType {
                            // Set the mount source path to a the desired directory point in the VM.
                            // In this case it is located in the sandbox directory.
                            // We rely on the fact that the first container in the VM has the same ID as the sandbox ID.
                            // In Kubernetes, this is usually the pause container and we depend on it existing for
                            // local directories to work.
                            mounts[idx].Source = filepath.Join(kataGuestSharedDir(), sandboxID, rootfsSuffix, KataLocalDevType, filepath.Base(mnt.Source))
    
                            // Create a storage struct so that the kata agent is able to create the
                            // directory inside the VM.
                            localStorage := &grpc.Storage{
                                    Driver:     KataLocalDevType,
                                    Source:     KataLocalDevType,
                                    Fstype:     KataLocalDevType,
                                    MountPoint: mounts[idx].Source,
                                    Options:    localDirOptions,
                            }
                            localStorages = append(localStorages, localStorage)
                    }
            }
            return localStorages
    }

    docker run -it --runtime=kata-runtime -v data1:/data1 --rm debian /bin/bash
    root@0e13f5a22fca:/#

        "Mounts": [
                {
                    "Type": "volume",
                    "Name": "data1",
                    "Source": "/var/lib/docker/volumes/data1/_data",
                    "Destination": "/data1",
                    "Driver": "local",
                    "Mode": "z",
                    "RW": true,
                    "Propagation": ""
                }
            ],
    docker  inspect 0e13f5a22fca
    [
        {
            "Id": "0e13f5a22fcafdca480f16ef9bae2e6e5da5d14f8d50b712a51ba1e51a68233e",
            "Created": "2020-12-04T00:57:07.930022529Z",
            "Path": "/bin/bash",
            "Args": [],
            "State": {
                "Status": "running",
                "Running": true,
                "Paused": false,
                "Restarting": false,
                "OOMKilled": false,
                "Dead": false,
                "Pid": 3105787,
                "ExitCode": 0,
                "Error": "",
                "StartedAt": "2020-12-04T00:57:10.936012588Z",
                "FinishedAt": "0001-01-01T00:00:00Z"
            },
            "Image": "sha256:2aa621c7db398cbad23b51b63348fedf0a779542d52f71acd4f24072cb872170",
            "ResolvConfPath": "/var/lib/docker/containers/0e13f5a22fcafdca480f16ef9bae2e6e5da5d14f8d50b712a51ba1e51a68233e/resolv.conf",
            "HostnamePath": "/var/lib/docker/containers/0e13f5a22fcafdca480f16ef9bae2e6e5da5d14f8d50b712a51ba1e51a68233e/hostname",
            "HostsPath": "/var/lib/docker/containers/0e13f5a22fcafdca480f16ef9bae2e6e5da5d14f8d50b712a51ba1e51a68233e/hosts",
            "LogPath": "/var/lib/docker/containers/0e13f5a22fcafdca480f16ef9bae2e6e5da5d14f8d50b712a51ba1e51a68233e/0e13f5a22fcafdca480f16ef9bae2e6e5da5d14f8d50b712a51ba1e51a68233e-json.log",
            "Name": "/distracted_haibt",
            "RestartCount": 0,
            "Driver": "overlay2",
            "Platform": "linux",
            "MountLabel": "",
            "ProcessLabel": "",
            "AppArmorProfile": "docker-default",
            "ExecIDs": null,
            "HostConfig": {
                "Binds": [
                    "data1:/data1"
                ],
                "ContainerIDFile": "",
                "LogConfig": {
                    "Type": "json-file",
                    "Config": {
                        "max-size": "100m"
                    }
                },
                "NetworkMode": "default",
                "PortBindings": {},
                "RestartPolicy": {
                    "Name": "no",
                    "MaximumRetryCount": 0
                },
                "AutoRemove": true,
                "VolumeDriver": "",
                "VolumesFrom": null,
                "CapAdd": null,
                "CapDrop": null,
                "Dns": [],
                "DnsOptions": [],
                "DnsSearch": [],
                "ExtraHosts": null,
                "GroupAdd": null,
                "IpcMode": "shareable",
                "Cgroup": "",
                "Links": null,
                "OomScoreAdj": 0,
                "PidMode": "",
                "Privileged": false,
                "PublishAllPorts": false,
                "ReadonlyRootfs": false,
                "SecurityOpt": null,
                "UTSMode": "",
                "UsernsMode": "",
                "ShmSize": 67108864,
                "Runtime": "kata-runtime",
                "ConsoleSize": [
                    0,
                    0
                ],
                "Isolation": "",
                "CpuShares": 0,
                "Memory": 0,
                "NanoCpus": 0,
                "CgroupParent": "",
                "BlkioWeight": 0,
                "BlkioWeightDevice": [],
                "BlkioDeviceReadBps": null,
                "BlkioDeviceWriteBps": null,
                "BlkioDeviceReadIOps": null,
                "BlkioDeviceWriteIOps": null,
                "CpuPeriod": 0,
                "CpuQuota": 0,
                "CpuRealtimePeriod": 0,
                "CpuRealtimeRuntime": 0,
                "CpusetCpus": "",
                "CpusetMems": "",
                "Devices": [],
                "DeviceCgroupRules": null,
                "DiskQuota": 0,
                "KernelMemory": 0,
                "MemoryReservation": 0,
                "MemorySwap": 0,
                "MemorySwappiness": null,
                "OomKillDisable": false,
                "PidsLimit": 0,
                "Ulimits": null,
                "CpuCount": 0,
                "CpuPercent": 0,
                "IOMaximumIOps": 0,
                "IOMaximumBandwidth": 0,
                "MaskedPaths": [
                    "/proc/asound",
                    "/proc/acpi",
                    "/proc/kcore",
                    "/proc/keys",
                    "/proc/latency_stats",
                    "/proc/timer_list",
                    "/proc/timer_stats",
                    "/proc/sched_debug",
                    "/proc/scsi",
                    "/sys/firmware"
                ],
                "ReadonlyPaths": [
                    "/proc/bus",
                    "/proc/fs",
                    "/proc/irq",
                    "/proc/sys",
                    "/proc/sysrq-trigger"
                ]
            },
            "GraphDriver": {
                "Data": {
                    "LowerDir": "/var/lib/docker/overlay2/e17f8f08ca2d3e8dd4dc29d9167fca9856beeb25cac37104bd43573d628c849d-init/diff:/var/lib/docker/overlay2/53cfc5f6a35592815e1df5bcdb226c096e7bdbd59fb0c58253d82c055c2b8435/diff",
                    "MergedDir": "/var/lib/docker/overlay2/e17f8f08ca2d3e8dd4dc29d9167fca9856beeb25cac37104bd43573d628c849d/merged",
                    "UpperDir": "/var/lib/docker/overlay2/e17f8f08ca2d3e8dd4dc29d9167fca9856beeb25cac37104bd43573d628c849d/diff",
                    "WorkDir": "/var/lib/docker/overlay2/e17f8f08ca2d3e8dd4dc29d9167fca9856beeb25cac37104bd43573d628c849d/work"
                },
                "Name": "overlay2"
            },
            "Mounts": [
                {
                    "Type": "volume",
                    "Name": "data1",
                    "Source": "/var/lib/docker/volumes/data1/_data",
                    "Destination": "/data1",
                    "Driver": "local",
                    "Mode": "z",
                    "RW": true,
                    "Propagation": ""
                }
            ],
            "Config": {
                "Hostname": "0e13f5a22fca",
                "Domainname": "",
                "User": "",
                "AttachStdin": true,
                "AttachStdout": true,
                "AttachStderr": true,
                "Tty": true,
                "OpenStdin": true,
                "StdinOnce": true,
                "Env": [
                    "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
                ],
                "Cmd": [
                    "/bin/bash"
                ],
                "Image": "debian",
                "Volumes": null,
                "WorkingDir": "",
                "Entrypoint": null,
                "OnBuild": null,
                "Labels": {}
            },
            "NetworkSettings": {
                "Bridge": "",
                "SandboxID": "b7dab902309c0390682b0f572832ecb996f8cb1fe3fb942ebe4a1a2cd8301fe6",
                "HairpinMode": false,
                "LinkLocalIPv6Address": "",
                "LinkLocalIPv6PrefixLen": 0,
                "Ports": {},
                "SandboxKey": "/var/run/docker/netns/b7dab902309c",
                "SecondaryIPAddresses": null,
                "SecondaryIPv6Addresses": null,
                "EndpointID": "e15b8cdb018fac7f63bf18cbafd3904cfbdf7c5102d3542ad5d0f6c7f51cbe27",
                "Gateway": "172.17.0.1",
                "GlobalIPv6Address": "",
                "GlobalIPv6PrefixLen": 0,
                "IPAddress": "172.17.0.3",
                "IPPrefixLen": 16,
                "IPv6Gateway": "",
                "MacAddress": "02:42:ac:11:00:03",
                "Networks": {
                    "bridge": {
                        "IPAMConfig": null,
                        "Links": null,
                        "Aliases": null,
                        "NetworkID": "46f664be20d1ea20abc7661d495d3f7f5283588f940faa72b9c0ab5d077b076a",
                        "EndpointID": "e15b8cdb018fac7f63bf18cbafd3904cfbdf7c5102d3542ad5d0f6c7f51cbe27",
                        "Gateway": "172.17.0.1",
                        "IPAddress": "172.17.0.3",
                        "IPPrefixLen": 16,
                        "IPv6Gateway": "",
                        "GlobalIPv6Address": "",
                        "GlobalIPv6PrefixLen": 0,
                        "MacAddress": "02:42:ac:11:00:03",
                        "DriverOpts": null
                    }
                }
            }
        }
    ]
    docker run -it --runtime=kata-runtime  -v data1:/data1 --rm  debian /bin/bash
    root@0e13f5a22fca:/# ls data1/
    root@0e13f5a22fca:/# 
    time="2020-12-04T01:01:45.94077978Z" level=debug msg="new request" debug_console=true name=kata-agent pid=56 req="container_id:"0e13f5a22fcafdca480f16ef9bae2e6e5da5d14f8d50b712a51ba1e51a68233e" exec_id:"0e13f5a22fcafdca480f16ef9bae2e6e5da5d14f8d50b712a51ba1e51a68233e" len:32768 " request=/grpc.AgentService/ReadStdout sandbox=0e13f5a22fcafdca480f16ef9bae2e6e5da5d14f8d50b712a51ba1e51a68233e source=agent
    
    ls: cannot access 'data': No such file or directory
    root@ubuntu:/# ls data
    ls: cannot access 'data': No such file or directory
    root@ubuntu:/# 

    kata虚拟机看不到

    root@ubuntu:/# ls data
    ls: cannot access 'data': No such file or directory
    root@ubuntu:/# ls
    bin   dev  home  lost+found  mnt  proc  run   srv  tmp  var
    boot  etc  lib   media       opt  root  sbin  sys  usr  vmi.sh
    root@ubuntu:/# 
  • 相关阅读:
    26 转义符 re模块 方法 random模块 collection模块的Counter方法
    25 正则表达式
    24 from 模块 import 名字
    24 from 模块 import 名字
    24 from 模块 import 名字
    23 析构方法 items系列 hash方法 eq方法
    21 isinstance issubclass 反射 _str_ _new_ _len_ _call_
    20 属性, 类方法, 静态方法. python2与python3的区别.
    python(1)
    python之字符串格式化
  • 原文地址:https://www.cnblogs.com/dream397/p/14083972.html
Copyright © 2011-2022 走看看