summaryrefslogtreecommitdiff
path: root/libpod/oci.go
diff options
context:
space:
mode:
authorAdrian Reber <areber@redhat.com>2018-09-18 09:56:19 +0000
committerAdrian Reber <adrian@lisas.de>2018-10-03 21:41:39 +0200
commitf7c8fd8a3d6f289a3abee1e2f676bfb956f7195c (patch)
treeb81521dee82594d4cc816814712557e0d8fc94b4 /libpod/oci.go
parent3750b35ae2a22e7f7bc0070c5c2dadf1ef437074 (diff)
downloadpodman-f7c8fd8a3d6f289a3abee1e2f676bfb956f7195c.tar.gz
podman-f7c8fd8a3d6f289a3abee1e2f676bfb956f7195c.tar.bz2
podman-f7c8fd8a3d6f289a3abee1e2f676bfb956f7195c.zip
Add support to checkpoint/restore containers
runc uses CRIU to support checkpoint and restore of containers. This brings an initial checkpoint/restore implementation to podman. None of the additional runc flags are yet supported and container migration optimization (pre-copy/post-copy) is also left for the future. The current status is that it is possible to checkpoint and restore a container. I am testing on RHEL-7.x and as the combination of RHEL-7 and CRIU has seccomp troubles I have to create the container without seccomp. With the following steps I am able to checkpoint and restore a container: # podman run --security-opt="seccomp=unconfined" -d registry.fedoraproject.org/f27/httpd # curl -I 10.22.0.78:8080 HTTP/1.1 403 Forbidden # <-- this is actually a good answer # podman container checkpoint <container> # curl -I 10.22.0.78:8080 curl: (7) Failed connect to 10.22.0.78:8080; No route to host # podman container restore <container> # curl -I 10.22.0.78:8080 HTTP/1.1 403 Forbidden I am using CRIU, runc and conmon from git. All required changes for checkpoint/restore support in podman have been merged in the corresponding projects. To have the same IP address in the restored container as before checkpointing, CNI is told which IP address to use. If the saved network configuration cannot be found during restore, the container is restored with a new IP address. For CRIU to restore established TCP connections the IP address of the network namespace used for restore needs to be the same. For TCP connections in the listening state the IP address can change. During restore only one network interface with one IP address is handled correctly. Support to restore containers with more advanced network configuration will be implemented later. v2: * comment typo * print debug messages during cleanup of restore files * use createContainer() instead of createOCIContainer() * introduce helper CheckpointPath() * do not try to restore a container that is paused * use existing helper functions for cleanup * restructure code flow for better readability * do not try to restore if checkpoint/inventory.img is missing * git add checkpoint.go restore.go v3: * move checkpoint/restore under 'podman container' v4: * incorporated changes from latest reviews Signed-off-by: Adrian Reber <areber@redhat.com>
Diffstat (limited to 'libpod/oci.go')
-rw-r--r--libpod/oci.go18
1 files changed, 17 insertions, 1 deletions
diff --git a/libpod/oci.go b/libpod/oci.go
index e5db06540..cf2b76ab0 100644
--- a/libpod/oci.go
+++ b/libpod/oci.go
@@ -227,7 +227,7 @@ func bindPorts(ports []ocicni.PortMapping) ([]*os.File, error) {
return files, nil
}
-func (r *OCIRuntime) createOCIContainer(ctr *Container, cgroupParent string) (err error) {
+func (r *OCIRuntime) createOCIContainer(ctr *Container, cgroupParent string, restoreContainer bool) (err error) {
var stderrBuf bytes.Buffer
runtimeDir, err := GetRootlessRuntimeDir()
@@ -289,6 +289,10 @@ func (r *OCIRuntime) createOCIContainer(ctr *Container, cgroupParent string) (er
args = append(args, "--syslog")
}
+ if restoreContainer {
+ args = append(args, "--restore", ctr.CheckpointPath())
+ }
+
logrus.WithFields(logrus.Fields{
"args": args,
}).Debugf("running conmon: %s", r.conmonPath)
@@ -766,3 +770,15 @@ func (r *OCIRuntime) execStopContainer(ctr *Container, timeout uint) error {
return nil
}
+
+// checkpointContainer checkpoints the given container
+func (r *OCIRuntime) checkpointContainer(ctr *Container) error {
+ // imagePath is used by CRIU to store the actual checkpoint files
+ imagePath := ctr.CheckpointPath()
+ // workPath will be used to store dump.log and stats-dump
+ workPath := ctr.bundlePath()
+ logrus.Debugf("Writing checkpoint to %s", imagePath)
+ logrus.Debugf("Writing checkpoint logs to %s", workPath)
+ return utils.ExecCmdWithStdStreams(os.Stdin, os.Stdout, os.Stderr, nil, r.path, "checkpoint",
+ "--image-path", imagePath, "--work-path", workPath, ctr.ID())
+}