如何让容器在Kubernetes上运行?

我现在尝试在Kubernetes集群上使用shell (/bin/bash)运行一个简单的容器。

我认为有一种方法可以通过使用pseudo-tty和detach选项(docker run命令上的-td选项)来保持容器在Docker容器上运行。

例如,

$ sudo docker run -td ubuntu:latest

Kubernetes中有这样的选项吗?

我尝试过使用kubectl run-container命令运行容器,比如:

kubectl run-container test_container ubuntu:latest --replicas=1

但是容器会退出几秒钟(就像使用上面没有提到的选项的docker run命令启动一样)。ReplicationController会重复启动。

有没有一种方法可以让容器像docker run命令中的-td选项一样在Kubernetes上运行?

392469 次浏览

容器在主进程退出时退出。做这样的事情:

docker run -itd debian

坦率地说,保持容器打开是一种只能用于快速测试和示例的hack。如果你只是想要一个容器来测试几分钟,我会这样做:

docker run -d debian sleep 300

它的优点是,如果你忘记它,容器将自动退出。或者,你可以在while循环中放入这样的东西以保持它永远运行,或者只是运行诸如top这样的应用程序。所有这些在Kubernetes中都很容易做到。

真正的问题是你为什么要这么做?您的容器应该提供一个服务,该服务的进程将使容器在后台运行。

我能够在Kubernetes中使用命令sleep infinity来工作,这将保持容器打开。当它不起作用时,请参阅这个答案以获得替代方案。

你可以在Dockerfile中使用这个CMD:

CMD exec /bin/bash -c "trap : TERM INT; sleep infinity & wait"

这将使您的容器保持活动状态,直到它被告知停止。使用trap和wait将使你的容器立即对停止请求作出反应。没有陷阱/等待停止需要几秒钟。

对于基于busybox的图像(用于基于alpine的图像),sleep不知道无穷大参数。这个变通方法给你相同的立即响应docker stop,就像上面的例子:

CMD exec /bin/sh -c "trap : TERM INT; sleep 9999999999d & wait"

容器意味着运行到完成。您需要为容器提供一个永远不会完成的任务。像这样的东西应该工作:

apiVersion: v1
kind: Pod
metadata:
name: ubuntu
spec:
containers:
- name: ubuntu
image: ubuntu:latest
# Just spin & wait forever
command: [ "/bin/bash", "-c", "--" ]
args: [ "while true; do sleep 30; done;" ]
  1. 在Dockerfile中使用以下命令:

    CMD ["sh", "-c", "tail -f /dev/null"]
    
  2. Build your docker image.

  3. Push it to your cluster or similar, just to make sure the image it's available.
  4. kubectl run debug-container -it --image=<your-image>
    

在我的例子中,带有initContainer的pod初始化失败。运行docker ps -a,然后运行docker logs exited-container-id-here,得到一条日志消息,其中kubectl logs podname没有显示。谜团解开了:-)

最简单的命令,因为它可以为k8s pod manifest永远运行容器:

apiVersion: v1
kind: Pod
metadata:
name: ubuntu
spec:
containers:
- name: ubuntu
image: ubuntu:latest
# Just sleep forever
command: [ "sleep" ]
args: [ "infinity" ]

为了保持POD运行,它应该执行某些任务,否则Kubernetes会发现它没有必要,因此它会停止。保持POD运行的方法有很多。

当我需要一个POD连续运行而不做任何有用的操作时,我也遇到过类似的问题。以下是对我有效的两种方法:

  1. 运行容器时运行sleep命令。
  2. 在容器内运行一个无限循环。
虽然第一个选项比第二个更容易,可能满足要求,但它不是最好的选择。因为,在sleep命令中分配的秒数是有限制的。 但是在容器内运行无限循环的容器永远不会退出

但是,我将描述这两种方式(考虑到您正在运行busybox容器):

1. 睡眠命令

apiVersion: v1
kind: Pod
metadata:
name: busybox
labels:
app: busybox
spec:
containers:
- name: busybox
image: busybox
ports:
- containerPort: 80
command: ["/bin/sh", "-ec", "sleep 1000"]

2. 无限循环

apiVersion: v1
kind: Pod
metadata:
name: busybox
labels:
app: busybox
spec:
containers:
- name: busybox
image: busybox
ports:
- containerPort: 80
command: ["/bin/sh", "-ec", "while :; do echo '.'; sleep 5 ; done"]

运行pod命令:

kubectl apply -f <pod-yaml-file-name>.yaml

希望能有所帮助!

在Dockerfile中使用这个命令来保持容器在K8s集群中运行:

  • CMD tail -f /dev/null

我对这个问题的一些看法。假设kubectl正在工作,那么与您在问题中提到的docker命令等效的最接近的命令将是这样的。

$ kubectl run ubuntu --image=ubuntu --restart=Never --command sleep infinity

上面的命令将在default命名空间中创建一个单独的Pod,并且它将执行带有infinity参数的sleep命令——这样你将有一个在前台运行的进程,使容器保持活跃。

之后,您可以通过运行kubectl exec命令与Pod交互。

$ kubectl exec ubuntu -it -- bash

这种技术对于创建Pod资源和特别调试非常有用。

有许多不同的方法来实现这一点,但最优雅的的方法之一是:

kubectl run -i --tty --image ubuntu:latest ubuntu-test --restart=Never --rm /bin/sh

我做了一个hack,把它放在后台:

[root@localhost ~]# kubectl run hello -it --image ubuntu -- bash &
[2] 128461

在pod hello上执行

[root@localhost ~]# kubectl exec -it hello -- whoami
root
[root@localhost ~]# kubectl exec -it hello -- hostname
hello

获得外壳

[root@localhost ~]# kubectl exec -it hello -- bash
root@hello:/# ls
bin  boot  dev  etc  home  lib  lib32  lib64  libx32  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

在模板中添加->在spec中添加->在集装箱中;在港口中;后集装箱港线

    command: ["/bin/sh", "-ec", "while :; do echo '.'; sleep 6 ; done"]

这个命令可能会有帮助

CMD exec /bin/bash -c "trap : TERM INT; sleep i infinity & wait"