Kubernetes 的 YAML 文件
YAML 是 Kubernetes 配置文件中使用的标准格式,以及许多其他多种配置 Kubernetes 的方式。YAML 广泛使用,很可能您已经熟悉它。否则,这并’不是一件很大的交易,因为 YAML 是一种非常简单的学习语言。每行 YAML 配置都是详细的,您应了解 YAML 格式作为您的 pod 学习流程的附带结果。
YAML 格式的 pod 配置文件为:
YAML 使用三种基本数据类型:
标量(字符串/数字):atom 数据项,如 pod-1 的字符串,端口号80。
映射(哈希/字典):键/值对可嵌套。apiVersion: v1 是一个映射。key apiVersion 的值为 v1。
序列(数组/列表):有序值集合,无键。列表项以-号指示。密钥容器的值是包括两个容器的列表。
在此示例中,您还会看到嵌套的 YAML 数据结构:
映射映射:规格是地图的关键,您可以在其中定义 pod’规格。在此示例中,您仅定义要在盒中启动的容器的行为。该值是带有容器键的另一个映射。
列表的映射。密钥容器的值为两个项目的列表:每个服务器和客户端容器都是一个映射,它描述了具有几个属性(如名称、图像和端口)的个别容器。
您还应了解有关 YAML 的其他特性:
区分大小写
相同级别中的元素共享相同的左缩进,缩进量无关紧要
不允许使用制表符作为缩进
空行无关紧要
使用 # 注释线路
使用一个单引号来转义任何字符的特殊含义
在深入了解有关 YAML 文件的更多详细信息’之前,请先完成盒创建:
$ kubectl create -f pod-2containers-do-one.yaml pod/pod-1 created $ kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE pod-1 0/2 ContainerCreating 0 18s 10.47.255.237 cent333<none> $ kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE pod-1 2/2 Running 0 18s 10.47.255.237 cent333 <none>
有. 我们创建了第一个 Kubernetes 对象– ,该 pod 称为 pod-1。但容器在哪里?输出内容提供线索:已分配 IP 地址为10.47.255.237 的 pod pod-1 (名称),包含两个容器(就绪/2),已在 Kubernetes 辅助节点 cent333 中启动。盒中的两个容器均已启动(就绪 2/),并且已处于27s 状态,无需重新启动。下面’简要逐行评论 YAML 配置的用途: "
第1行:这是对文本使用编号前的注释行,您可以将任何注释放入 YAML 文件中。(在这本书中,我们使用此第一行为 YAML 文件提供文件名。在从 YAML 文件创建对象时,此命令稍后将用于该文件名。)
第2、3、4行:四个 YAML 映射是 pod 定义的主要组件:
ApiVersion: 有不同版本,例如 v2。这里特别是版本1。
种类请记住,存在不同类型的 Kubernetes 对象,此处我们希望 Kubernetes 创建 pod 对象。稍后,您将在我们的其他对象示例中看到 ReplicationController 或服务的种类。
元数据以识别创建的对象。除了要创建的对象名称之外,另一个重要的元数据是标签。您将在第3章中详细了解这一点。
指标这将提供有关 pod 行为的规格。
线路9-15:此处的 pod 规格仅限于两个容器。系统将下载映像,启动每个具有名称的容器,并分别公开指定端口。
下面’是盒’内运行的内容:
$ kubectl describe pod pod-1 | grep -iC1 container IP: 10.47.255.237 Containers: server: Container ID: docker://9f8032f4fbe2f0d5f161f76b6da6d7560bd3c65e0af5f6e8d3186c6520cb3b7d Image: contrailk8sdayone/contrail-webserver -- client: Container ID: docker://d9d7ffa2083f7baf0becc888797c71ddba78cd951f6724a10c7fec84aefce988 Image: contrailk8sdayone/ubuntu -- Ready True ContainersReady True PodScheduled True -- Normal Pulled 3m2s kubelet, cent333 Successfully pulled image "contrailk8sdayone/contrail-webserver" Normal Created 3m2s kubelet, cent333 Created container Normal Started 3m2s kubelet, cent333 Started container Normal Pulling 3m2s kubelet, cent333 pulling image "contrailk8sdayone/ubuntu" Normal Pulled 3m1s kubelet, cent333 Successfully pulled image "contrailk8sdayone/ubuntu" Normal Created 3m1s kubelet, cent333 Created container Normal Started 3m1s kubelet, cent333 Started container
毫无疑问,pod-1 由 Kubernetes 群集分配并在所有容器之间共享的 IP 地址包含在 YAML 文件、服务器和客户端中声明的两个容器中,如Figure 1中所示:

暂停容器
如果登录到 node cent333,’将看到在盒内运行的 Docker 容器:
$ docker ps | grep -E "ID|pod-1" CONTAINER ID IMAGE COMMAND ... PORTS NAMES d9d7ffa2083f contrailk8sdayone/ubuntu "/sbin/init" ... k8s_client_pod-1_default_f8b42343-d87a-11e9-9a1e-0050569e6cfc_0 9f8032f4fbe2 contrailk8sdayone/contrail-webserver "python app-dayone.py" ... k8s_server_pod-1_default_f8b42343-d87a-11e9-9a1e-0050569e6cfc_0 969ec6d93683 k8s.gcr.io/pause:3.1 "/pause" ... k8s_POD_pod-1_default_f8b42343-d87a-11e9-9a1e-0050569e6cfc_0
第三个带有图像名称 k8s.gcr.io/pause 的容器是 Kubernetes 系统为每个 pod 创建的特殊容器。创建的暂停容器用于管理盒的网络资源,该 pod 由该 pod 的所有容器共享。
Figure 2显示了一个盒箱,其中包括几个用户容器和一个暂停容器。

Pod 内通信
在 Kubernetes 主设备中,’从主设备登录到一个容器:
#login to pod-1's container client $ kubectl exec -it pod-1 -c client bash root@pod-1:/# #login to pod-1's container server $ kubectl exec -it pod-1 -c server bash root@pod-1:/app-dayone#
如果您曾使用 Docker 玩,您将立即意识到这相当整洁。请记住,容器在一个节点上启动,因此如果您使用 Docker,则必须先登录到正确的远程节点,然后使用类似的 Docker exec 命令登录每个容器。Kubernetes 隐藏这些详细信息。它允许您从一个节点–到主设备,执行所有操作。
现在,检查容器中运行的进程:
服务器容器
root@pod-1:/app-dayone# ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.0 55912 17356 ? Ss 12:18 0:00 python app-dayo root 7 0.5 0.0 138504 17752 ? Sl 12:18 0:05 /usr/bin/python root 10 0.0 0.0 18232 1888 pts/0 Ss 12:34 0:00 bash root 19 0.0 0.0 34412 1444 pts/0 R+ 12:35 0:00 ps aux root@pod-1:/app-dayone# ss -ant State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 *:80 *:* LISTEN 0 128 *:22 *:* LISTEN 0 128 :::22 :::* root@pod-1:/app-dayone# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 116: eth0@if117: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:f8:e6:63:7e:d8 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 10.47.255.237/12 scope global eth0 valid_lft forever preferred_lft forever
客户端容器
$ kubectl exec -it pod-1 -c client bash root@pod-1:/# ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.0 32716 2088 ? Ss 12:18 0:00 /sbin/init root 41 0.0 0.0 23648 888 ? Ss 12:18 0:00 cron root 47 0.0 0.0 61364 3064 ? Ss 12:18 0:00 /usr/sbin/sshd syslog 111 0.0 0.0 116568 1172 ? Ssl 12:18 0:00 rsyslogd root 217 0.2 0.0 18168 1916 pts/0 Ss 12:45 0:00 bash root 231 0.0 0.0 15560 1144 pts/0 R+ 12:45 0:00 ps aux root@pod-1:/# ss -ant State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 *:80 *:* LISTEN 0 128 *:22 *:* LISTEN 0 128 :::22 :::* root@pod-1:/# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 116: eth0@if117: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:f8:e6:63:7e:d8 brd ff:ff:ff:ff:ff:ff inet 10.47.255.237/12 scope global eth0 valid_lft forever preferred_lft forever
此 ps 命令输出显示,每个容器都在运行自己的进程。但是,ss 和 ip 命令输出指示两个容器共享相同的网络环境,因此两者都可以看到彼此公开的端口。因此,盒中容器之间的通信只需使用 localhost 即可发生。让’我们通过使用卷曲命令启动 TCP 连接来测试这种情况。
假设从客户端容器,您希望从服务器容器获取网页。您只需使用 localhost IP 地址启动曲线:
root@pod-1:/# curl localhost <html> <style> h1 {color:green} h2 {color:red} </style> <div align="center"> <head> <title>Contrail Pod</title> </head> <body> <h1>Hello</h1><br><h2>This page is served by a <b>Contrail</b> pod</h2><br><h3>IP address = 10.47.255.237<br>Hostname = pod-1</h3> <img src="/static/giphy.gif"> </body> </div> </html>
您可以看到连接已建立,网页已成功下载。
现在,’让我们来监控 TCP 连接状态:已成功建立连接:
root@pod-1:/# ss -ant State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 *:80 *:* LISTEN 0 128 *:22 *:* TIME-WAIT 0 0 127.0.0.1:80 127.0.0.1:34176 #<--- LISTEN 0 128 :::22 :::*
完全相同的连接可从服务器容器中看到:
$ kubectl exec -it pod-1 -c server bash root@pod-1:/app-dayone# ss -ant State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 *:80 *:* LISTEN 0 128 *:22 *:* TIME-WAIT 0 0 127.0.0.1:80 127.0.0.1:34176 #<--- LISTEN 0 128 :::22 :::*
Kubectl 工具
到目前为止’,您已看到由 kubectl 命令创建的对象。与 Docker 世界中的 docker 命令一样,此命令是 Kubernetes world 中的一个接口,用于与群集进行交谈,或者更准确地说是通过 Kubernetes API 的 Kubernetes 主设备。这’是一种多用途工具,可提供满足您需要处理 Kubernetes 的所有任务的选项。
作为一个快速示例,假设您已为 kubectl 启用了自动完成功能,则可以登录到 master 和 kubectl,然后键入两个 tab 键,以列出您当前环境中支持的所有选项:
root@test1:~# kubectl<TAB><TAB> alpha attach completion create exec logs proxy set wait annotate auth config delete explain options replace taint api-resources autoscale convert describe patch rollout top api-versions certificate drain get plugin run uncordon apply cluster-info cp edit label port-forward scale version expose cordon
要设置 kubectl 命令的自动完成,请遵循完成选项的说明:
kubectl 完成-h
请放心,您’会在本书其余部分看到并了解其中的部分选项。