I have a docker container that runs a GUI application, I can successfully run it, using this command
sudo docker run --net=host --env="DISPLAY" --volume="$HOME/.Xauthority:/root/.Xauthority:rw" -it test
I have already tried to create this deployment file:
{
"kind": "Deployment",
"apiVersion": "extensions/v1beta1",
"metadata": {
"name": "test",
"namespace": "default",
"selfLink": "/apis/extensions/v1beta1/namespaces/default/deployments/gazebo",
"uid": "249a12a9-83b8-11e9-8ec2-32ccf6441134",
"resourceVersion": "6165060",
"generation": 1,
"creationTimestamp": "2019-05-31T15:24:12Z",
"labels": {
"k8s-app": "test"
},
"annotations": {
"deployment.kubernetes.io/revision": "1"
}
},
"spec": {
"replicas": 1,
"selector": {
"matchLabels": {
"k8s-app": "test"
}
},
"template": {
"metadata": {
"name": "test",
"creationTimestamp": null,
"labels": {
"k8s-app": "test"
}
},
"spec": {
"volumes": [
{
"name": "test",
"hostPath": {
"path": "$HOME/.Xauthority:/root/.Xauthority:rw",
"type": ""
}
}
],
"containers": [
{
"name": "test",
"image": "test:1.0.12",
"env": [
{
"name": "DISPLAY",
"value": ":0"
}
],
"resources": {},
"terminationMessagePath": "/dev/termination-log",
"terminationMessagePolicy": "File",
"imagePullPolicy": "IfNotPresent",
"securityContext": {
"privileged": false,
"procMount": "Default"
},
"stdin": true
}
],
"restartPolicy": "Always",
"terminationGracePeriodSeconds": 30,
"dnsPolicy": "ClusterFirst",
"nodeSelector": {
"component": "test"
},
"hostNetwork": true,
"securityContext": {},
"schedulerName": "default-scheduler"
}
},
"strategy": {
"type": "RollingUpdate",
"rollingUpdate": {
"maxUnavailable": "25%",
"maxSurge": "25%"
}
},
"revisionHistoryLimit": 10,
"progressDeadlineSeconds": 600
},
"status": {
"observedGeneration": 1,
"replicas": 1,
"updatedReplicas": 1,
"unavailableReplicas": 1,
"conditions": [
{
"type": "Progressing",
"status": "True",
"lastUpdateTime": "2019-05-31T15:24:14Z",
"lastTransitionTime": "2019-05-31T15:24:12Z",
"reason": "NewReplicaSetAvailable",
"message": "ReplicaSet \"test-dbfdb6467\" has successfully progressed."
},
{
"type": "Available",
"status": "False",
"lastUpdateTime": "2019-05-31T15:40:21Z",
"lastTransitionTime": "2019-05-31T15:40:21Z",
"reason": "MinimumReplicasUnavailable",
"message": "Deployment does not have minimum availability."
}
]
}
}
I have tried to inspect the resulting containers and I have obtained these results:
For the one deployed with kubernetes the result is
[
{
"Id": "114e1d307b8260eaa02bfcf214031cf34ae522cf55258731a8a6dca535527995",
"Created": "2019-05-31T15:24:13.320599267Z",
"Path": "/home/startup.sh",
"Args": [],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 10908,
"ExitCode": 0,
"Error": "",
"StartedAt": "2019-05-31T15:24:13.627542552Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:2b02610511b1d09925b5b0b2471efea087819942c36c0c0bf490d6a28709f54e",
"ResolvConfPath": "/home/docker/containers/8537a1c6038f5d6b4186d0b56a6b839207477825d0ad99d8610d36f66967495e/resolv.conf",
"HostnamePath": "/home/docker/containers/8537a1c6038f5d6b4186d0b56a6b839207477825d0ad99d8610d36f66967495e/hostname",
"HostsPath": "/var/lib/kubelet/pods/249ff7a4-83b8-11e9-8ec2-32ccf6441134/etc-hosts",
"LogPath": "/home/docker/containers/114e1d307b8260eaa02bfcf214031cf34ae522cf55258731a8a6dca535527995/114e1d307b8260eaa02bfcf214031cf34ae522cf55258731a8a6dca535527995-json.log",
"Name": "/k8s_gazebo_gazebo-dbfdb6467-fd448_default_249ff7a4-83b8-11e9-8ec2-32ccf6441134_0",
"RestartCount": 0,
"Driver": "aufs",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "docker-default",
"ExecIDs": null,
"HostConfig": {
"Binds": [
"/var/lib/kubelet/pods/249ff7a4-83b8-11e9-8ec2-32ccf6441134/volumes/kubernetes.io~secret/default-token-4ncqs:/var/run/secrets/kubernetes.io/serviceaccount:ro",
"/var/lib/kubelet/pods/249ff7a4-83b8-11e9-8ec2-32ccf6441134/etc-hosts:/etc/hosts",
"/var/lib/kubelet/pods/249ff7a4-83b8-11e9-8ec2-32ccf6441134/containers/gazebo/f4a9bfa2:/dev/termination-log"
],
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "container:8537a1c6038f5d6b4186d0b56a6b839207477825d0ad99d8610d36f66967495e",
"PortBindings": null,
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"Dns": null,
"DnsOptions": null,
"DnsSearch": null,
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "container:8537a1c6038f5d6b4186d0b56a6b839207477825d0ad99d8610d36f66967495e",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 1000,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": [
"seccomp=unconfined"
],
"UTSMode": "host",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"ConsoleSize": [
0,
0
],
"Isolation": "",
"CpuShares": 2,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "/kubepods/besteffort/pod249ff7a4-83b8-11e9-8ec2-32ccf6441134",
"BlkioWeight": 0,
"BlkioWeightDevice": null,
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 100000,
"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/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware"
],
"ReadonlyPaths": [
"/proc/asound",
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": null,
"Name": "aufs"
},
"Mounts": [
{
"Type": "bind",
"Source": "/var/lib/kubelet/pods/249ff7a4-83b8-11e9-8ec2-32ccf6441134/volumes/kubernetes.io~secret/default-token-4ncqs",
"Destination": "/var/run/secrets/kubernetes.io/serviceaccount",
"Mode": "ro",
"RW": false,
"Propagation": "rprivate"
},
{
"Type": "bind",
"Source": "/var/lib/kubelet/pods/249ff7a4-83b8-11e9-8ec2-32ccf6441134/etc-hosts",
"Destination": "/etc/hosts",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
},
{
"Type": "bind",
"Source": "/var/lib/kubelet/pods/249ff7a4-83b8-11e9-8ec2-32ccf6441134/containers/gazebo/f4a9bfa2",
"Destination": "/dev/termination-log",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
"Config": {
"Hostname": "davidePC",
"Domainname": "",
"User": "0",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": true,
"StdinOnce": false,
"Env": [
"DISPLAY=:0",
"KUBERNETES_PORT_443_TCP_PROTO=tcp",
"KUBERNETES_PORT_443_TCP_PORT=443",
"KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1",
"KUBERNETES_SERVICE_HOST=10.96.0.1",
"KUBERNETES_SERVICE_PORT=443",
"KUBERNETES_SERVICE_PORT_HTTPS=443",
"KUBERNETES_PORT=tcp://10.96.0.1:443",
"KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443",
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"LANG=C.UTF-8",
"LC_ALL=C.UTF-8",
"ROS_DISTRO=kinetic",
"ROS_MASTER_URI=http://localhost:11311",
"ROS_PACKAGE_PATH=/opt/ros/kinetic/share",
"DEBIAN_FRONTEND=noninteractive",
"TURTLEBOT_3D_SENSOR=no3d",
"TURTLEBOT_TOP_PLATE_DEVICE=rplidar",
"JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-amd64/"
],
"Cmd": [],
"Healthcheck": {
"Test": [
"NONE"
]
},
"ArgsEscaped": true,
"Image": "sha256:2b02610511b1d09925b5b0b2471efea087819942c36c0c0bf490d6a28709f54e",
"Volumes": null,
"WorkingDir": "/home",
"Entrypoint": [
"/home/startup.sh"
],
"OnBuild": null,
"Labels": {
"annotation.io.kubernetes.container.hash": "86f118b",
"annotation.io.kubernetes.container.restartCount": "0",
"annotation.io.kubernetes.container.terminationMessagePath": "/dev/termination-log",
"annotation.io.kubernetes.container.terminationMessagePolicy": "File",
"annotation.io.kubernetes.pod.terminationGracePeriod": "30",
"io.kubernetes.container.logpath": "/var/log/pods/default_gazebo-dbfdb6467-fd448_249ff7a4-83b8-11e9-8ec2-32ccf6441134/gazebo/0.log",
"io.kubernetes.container.name": "gazebo",
"io.kubernetes.docker.type": "container",
"io.kubernetes.pod.name": "gazebo-dbfdb6467-fd448",
"io.kubernetes.pod.namespace": "default",
"io.kubernetes.pod.uid": "249ff7a4-83b8-11e9-8ec2-32ccf6441134",
"io.kubernetes.sandbox.id": "8537a1c6038f5d6b4186d0b56a6b839207477825d0ad99d8610d36f66967495e"
}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {},
"SandboxKey": "",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "",
"Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "",
"IPPrefixLen": 0,
"IPv6Gateway": "",
"MacAddress": "",
"Networks": {}
}
}
]
Instead for the one run from CLI, the result is:
[
{
"Id": "ed428815132ac62020e36b1d50421ec7402c3b433907575a4858617d56322366",
"Created": "2019-05-31T15:13:51.991700539Z",
"Path": "/home/startup.sh",
"Args": [],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 8377,
"ExitCode": 0,
"Error": "",
"StartedAt": "2019-05-31T15:13:52.469581933Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:2b02610511b1d09925b5b0b2471efea087819942c36c0c0bf490d6a28709f54e",
"ResolvConfPath": "/home/docker/containers/ed428815132ac62020e36b1d50421ec7402c3b433907575a4858617d56322366/resolv.conf",
"HostnamePath": "/home/docker/containers/ed428815132ac62020e36b1d50421ec7402c3b433907575a4858617d56322366/hostname",
"HostsPath": "/home/docker/containers/ed428815132ac62020e36b1d50421ec7402c3b433907575a4858617d56322366/hosts",
"LogPath": "/home/docker/containers/ed428815132ac62020e36b1d50421ec7402c3b433907575a4858617d56322366/ed428815132ac62020e36b1d50421ec7402c3b433907575a4858617d56322366-json.log",
"Name": "/youthful_benz",
"RestartCount": 0,
"Driver": "aufs",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "docker-default",
"ExecIDs": null,
"HostConfig": {
"Binds": [
"/home/davide/.Xauthority:/root/.Xauthority:rw"
],
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "host",
"PortBindings": {},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"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": "runc",
"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": null,
"Name": "aufs"
},
"Mounts": [
{
"Type": "bind",
"Source": "/home/davide/.Xauthority",
"Destination": "/root/.Xauthority",
"Mode": "rw",
"RW": true,
"Propagation": "rprivate"
}
],
"Config": {
"Hostname": "davidePC",
"Domainname": "",
"User": "",
"AttachStdin": true,
"AttachStdout": true,
"AttachStderr": true,
"Tty": true,
"OpenStdin": true,
"StdinOnce": true,
"Env": [
"DISPLAY=:0",
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"LANG=C.UTF-8",
"LC_ALL=C.UTF-8",
"ROS_DISTRO=kinetic",
"ROS_MASTER_URI=http://localhost:11311",
"ROS_PACKAGE_PATH=/opt/ros/kinetic/share",
"DEBIAN_FRONTEND=noninteractive",
"TURTLEBOT_3D_SENSOR=no3d",
"TURTLEBOT_TOP_PLATE_DEVICE=rplidar",
"JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-amd64/"
],
"Cmd": [],
"ArgsEscaped": true,
"Image": "cpswarm/gazebo-em-ex:1.0.12",
"Volumes": null,
"WorkingDir": "/home",
"Entrypoint": [
"/home/startup.sh"
],
"OnBuild": null,
"Labels": {}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "70d4cff7200ece8610fdcc04ffed7b2248caea6e61658c4622368a25d0864660",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {},
"SandboxKey": "/var/run/docker/netns/default",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "",
"Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "",
"IPPrefixLen": 0,
"IPv6Gateway": "",
"MacAddress": "",
"Networks": {
"host": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "81ea4770bb3b91fca3383336b35ebd9c6a00c7728180873b99fb663fcbb3ef4f",
"EndpointID": "1aa92639019060c8a229a06b86a79b0e6607437ab6a9c5de45f83d797b8e5b9f",
"Gateway": "",
"IPAddress": "",
"IPPrefixLen": 0,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "",
"DriverOpts": null
}
}
}
}
]
The result that I obtain is that running from CLI, I can see the GUI of the application running in the docker container. Instead with the container deployed with Kubernetes I see the application running but I cannot see the GUI.
Is there something that I can change in the deployment file to make the deployed container working?
To run GUI application on headless server, you need Xvfb to create a virtual frame buffer as a X-server, and let application connect to the X-server by env DISPLAY
.
Example yaml use xvfb docker image:
...
spec:
containers:
- name: test
image: test:1.0.12
env:
- name: DISPLAY
value: "localhost:1.0"
- name: xvfb
image: comiq/xvfb:latest
env:
- name: DISPLAY
value: 1
- name: SCREEN
value: 0
ports:
- name: xserver
containerPort: 6001