容器改变了我们对虚拟化的看法。您可能还记得(或者您可能仍然生活在)虚拟机是完整堆栈的时代,从虚拟化的 BIOS、操作系统和内核,到每个虚拟化的网络接口控制器(NIC)。您登录虚拟盒子,就像登录您自己的工作站一样。这是一个非常直接和简单的类比。
然后容器出现了,从 LXC 开始,最终形成了开放容器倡议组织 (OCI),事情变得复杂起来。
幂等性
在容器的世界里,“虚拟机”只是大部分是虚拟的。所有不需要虚拟化的东西都从宿主机借用。此外,容器本身通常被设计为短暂的和幂等的,因此它不存储持久性数据,并且它的状态由宿主机上的配置文件定义。
如果您习惯了旧的虚拟机方式,那么您自然会期望登录虚拟机以便与之交互。但是容器是短暂的,因此容器中您所做的任何事情都会被遗忘,这是设计使然,以防容器需要重启或重新生成。
控制您的容器基础设施的命令(例如 oc、crictl、lxc 和 docker)提供了一个接口来运行重要的命令,以重启服务、查看日志、确认重要文件的存在和权限模式等等。您应该使用容器基础设施提供的工具与您的应用程序交互,或者编辑配置文件并重新启动。这就是容器的设计目的。
例如,开源论坛软件 Discourse 官方以容器镜像的形式分发。Discourse 软件是无状态的,因此它的安装是自包含在 /var/discourse 中的。只要您备份了 /var/discourse,您始终可以通过重新启动容器来恢复论坛。容器不保存持久性数据,其配置文件是 /var/discourse/containers/app.yml。
如果您登录容器并编辑它包含的任何文件,如果容器必须重新启动,所有更改都将丢失。
您从头开始构建的 LXC 容器更加灵活,配置文件(在您定义的位置)在您启动容器时传递给容器。
像 Jenkins 这样的构建系统通常有一个默认的配置文件,例如 jenkins.yaml,为仅用于构建和运行源代码测试的基础容器镜像提供指令。构建完成后,容器就会消失。
既然您知道您不需要 SSH 来与容器交互,那么这里概述了可用的工具(以及关于尽管有所有使其变得多余的花哨工具,但仍然使用 SSH 的一些注意事项)。
OpenShift Web 控制台
OpenShift 4 为容器的创建和维护提供了一个开源工具链,包括一个交互式 Web 控制台。
当您登录到您的 Web 控制台时,导航到您的项目概览,然后单击 应用程序 选项卡以查看 Pod 列表。选择一个(正在运行的)Pod 以打开应用程序的 详细信息 面板。

opensource.com
单击 详细信息 面板顶部的 终端 选项卡,以在您的容器中打开一个交互式 Shell。

opensource.com
如果您更喜欢基于浏览器的 Kubernetes 管理体验,您可以通过 learn.openshift.com 上提供的交互式课程了解更多信息。
OpenShift oc
如果您更喜欢命令行界面体验,您可以使用 oc 命令从终端与容器交互。
首先,获取正在运行的 Pod 列表(或参考 Web 控制台以获取活动 Pod 列表)。要获取该列表,请输入
$ oc get pods
您可以查看资源(Pod、构建或容器)的日志。默认情况下,oc logs 返回您指定的 Pod 中第一个容器的日志。要选择单个容器,请添加 --container 选项
$ oc logs --follow=true example-1-e1337 --container app
您还可以使用以下命令查看 Pod 中所有容器的日志
$ oc logs --follow=true example-1-e1337 --all-containers
执行命令
您可以使用以下命令远程执行命令
$ oc exec example-1-e1337 --container app hostname
example.local
这类似于以非交互方式运行 SSH:您可以运行您想运行的命令,而无需交互式 Shell 接管您的环境。
远程 Shell
您可以附加到正在运行的容器。这仍然不会在容器中打开 Shell,但它会直接运行命令。例如
$ oc attach example-1-e1337 --container app
如果您需要在容器中获得真正的交互式 Shell,只要容器包含 Shell,您就可以使用 oc rsh 命令打开远程 Shell。默认情况下,oc rsh 启动 /bin/sh
$ oc rsh example-1-e1337 --container app
Kubernetes
如果您直接使用 Kubernetes,您可以使用 kubectl exec 命令在您的 Pod 中运行 Bash Shell。
首先,确认您的 Pod 正在运行
$ kubectl get pods
只要列出了包含您的应用程序的 Pod,您就可以使用 exec 命令在容器中启动 Shell。使用名称 example-pod 作为 Pod 名称,输入
$ kubectl exec --stdin=false --tty=false
example-pod -- /bin/bash
root@example.local:/# ls
bin core etc lib root srv
boot dev home lib64 sbin tmp var
Docker
docker 命令类似于 kubectl。在 dockerd 守护进程运行的情况下,获取正在运行的容器的名称(如果您不在相应的组中,您可能必须使用 sudo 来提升权限)
$ docker ps
CONTAINER ID IMAGE COMMAND NAME
678ac5cca78e centos "/bin/bash" example-centos
使用容器名称,您可以在容器中运行命令
$ docker exec example/centos cat /etc/os-release
CentOS Linux release 7.6
NAME="CentOS Linux"
VERSION="7"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
[...]
或者您可以启动 Bash Shell 进行交互式会话
$ docker exec -it example-centos /bin/bash
容器和设备
在处理云时,要记住的重要一点是,容器本质上是运行时,而不是虚拟机。虽然它们与 Linux 系统有很多共同之处(因为它们就是 Linux 系统!),但它们很少直接转换为您可能在 Linux 工作站上开发的命令和工作流程。然而,像设备一样,容器有一个界面来帮助您开发、维护和监控它们,因此请熟悉前端命令和服务,直到您可以像与虚拟(或裸机)机器交互一样轻松地与它们交互。很快,您就会想知道为什么一切不是都开发成短暂的。
6 条评论