--privileged with a host mount
The flags that translate into a pod nobody should apply
docker run -d --privileged -p 8080:80 -v /:/host nginx:latest
Paste a docker run command, line continuations and all, and get a Deployment and a Service. The flags that mean something different in Kubernetes, and the ones with no equivalent, are reported rather than quietly dropped.
Or drop a file anywhere on this panel. Nothing is uploaded: the analysis runs in this tab.
The answer appears here
Paste on the left and press Convert. Nothing leaves this tab.
Nothing else to flag.
No formatting problems, and nothing the rules object to. Worth remembering what that covers: this reads the file you pasted, not the account or cluster it will be applied to.
No finding matches that filter.
Real input you can load into the tool above. Each one shows a different thing going wrong, because that is what the tool is for.
The flags that translate into a pod nobody should apply
docker run -d --privileged -p 8080:80 -v /:/host nginx:latest
An environment value that belongs in a Secret, and the restart policy that has no direct equivalent
docker run -e DB_PASSWORD=hunter2 --restart always myapp:1.2
These are the ones that fail silently. The config is accepted, nothing raises an error, and the consequence arrives later.
It works and it gives the pod the node's filesystem. Anything that escapes the container owns the node.
Instead:Use a PersistentVolumeClaim, or a ConfigMap for configuration. A hostPath is a last resort with a written reason.
Kubernetes restartPolicy has no direct equivalent, because restarting is what a Deployment does by default. The flag has no meaning in a manifest.
Instead:Drop it. A Deployment restarts failed containers already.
hostPort binds the node's port and limits the pod to one replica per node, which is almost never what was meant.
Instead:Use a Service. NodePort or LoadBalancer depending on how it should be reached.
Most of a docker run maps across without comment. These are the parts where a literal translation is accepted by the cluster and behaves differently.
Docker's m is mebibytes. Kubernetes' m is milli, one thousandth. Copied across as written, the manifest asks for half a byte, the API server accepts it without comment, and the container is OOMKilled on its first allocation. The conversion is done here and the finding is critical, because this one is silent at every stage where anyone would look.
-p 8080:80 maps a port on your machine, and a cluster has no equivalent. A Service is a different object with a different job, and a NodePort cannot be 8080 because the range starts at 30000. The honest translation for local work is kubectl port-forward, which is what the finding says instead of quietly emitting a NodePort that will not apply.
Words after the image replace the image's CMD and are still passed to its ENTRYPOINT. In Kubernetes, command replaces ENTRYPOINT and args replaces CMD, so args is the faithful mapping. Nearly every converter for this gets it backwards, and the result is a working image that starts exiting immediately or cannot find a binary that is definitely present.
--restart=no and --rm cannot be expressed by a Deployment, whose pod template is required to use restartPolicy: Always; that workload is a Job. --ulimit has no field anywhere in the pod spec. --memory-swap has nothing to configure because Kubernetes disables swap. Each is named as a gap rather than dropped silently.
docker run starts one container on the machine you typed it on. A Deployment describes a workload that a scheduler places somewhere, replicates, restarts and moves. Most flags have a direct equivalent. The ones that do not are the ones worth reading, because they are where an apparently faithful translation changes behaviour.
This is the root of most of the differences. A bind mount assumes a filesystem that follows the container, and a pod can be scheduled onto any node. A published port assumes a host that clients can reach, and a pod's node is an implementation detail. Both translate literally, and both are usually the wrong answer.
docker kubernetes
-v /data:/data hostPath: needs that exact path
on whichever node it lands on
-v mydata:/data PVC: follows the pod, which is
what the docker volume did
-p 8080:80 Service: a name and an address
inside the cluster. Getting in
from outside is a separate call Four names for two slots. Kubernetes command overrides the image's ENTRYPOINT and args overrides its CMD, and each overrides independently. Docker's trailing words replace CMD only, which is why they belong in args. Putting them in command instead discards the entrypoint the image was built around.
docker run myimage foo bar
ENTRYPOINT stays, CMD becomes [foo bar]
args: ["foo", "bar"] correct
command: ["foo", "bar"] wipes the ENTRYPOINT
docker run --entrypoint /bin/sh myimage -c 'x'
command: ["/bin/sh"]
args: ["-c", "x"] A docker flag is a ceiling and there is nothing else to set. Kubernetes needs a request as well, which is what the scheduler reserves and what decides the QoS class. Requests are set equal to limits here, making the pod Guaranteed: predictable, and the last thing evicted under node pressure. Lowering the request makes it Burstable, able to use spare capacity and evictable before Guaranteed pods.
docker run -m 512m --cpus 0.5
resources:
requests: <- new concept. What the
cpu: 500m scheduler sets aside
memory: 512Mi
limits: <- what docker gave you
cpu: 500m
memory: 512Mi
requests == limits Guaranteed
requests < limits Burstable
nothing set BestEffort, evicted first A HEALTHCHECK baked into a Dockerfile has no effect in Kubernetes. The kubelet does not read it and never has. Without probes, a pod is considered ready the moment its process starts, so traffic arrives before the application can serve it, and a process that hangs without exiting is never restarted.
HEALTHCHECK CMD curl -f http://localhost/ # ignored
readinessProbe: should traffic go here yet
livenessProbe: is it wedged, restart it
startupProbe: hold the other two off until
a slow start finishes
--health-cmd is converted. A HEALTHCHECK inside the
image is not visible from a command line, so it is not. hostNetwork: true is the direct translation, and on its own it breaks DNS. A pod in the host network namespace resolves against the node's resolver, so no in-cluster Service name works. dnsPolicy: ClusterFirstWithHostNet is what fixes it, and leaving it out is the most common mistake with hostNetwork by a distance.
spec:
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet <- not optional
# without the second line, every Service lookup fails
# and the pod otherwise looks completely healthy