0%

Kubernetes In Action 书中一些命令摘抄

第三章 pod

使用 kubectl explain 来发现可能的 API 对象字段

在准备 manifest 时,可以转到 http: /kubemetes.io docs/api 上的 Kubemetes 参考文档查看每个 API 对象支持哪些属性,也可以使用命令 kubectl explain

1
2
3
4
5
如当从头创建一个 pod manifest 时,可以从请求 kubectl 来解释 pod开始:
$ kubectl explain pods

Kubectl 打印出对象的解释并列出对象可以包含的属性,接下来就可以深入了解各个属性的更多信息 例如,可以这样查看 spec 属性:
$ kubectl explain pod.spec

获取多容器 pod 的日志时指定容器名称

如果我们的 pod 包含多个容器,在运行 kubectl logs 命令时则必须通过包含-c <容器名称>选项来显式指定容器名称。

1
$ kubectl logs kubia-manual -c kubia 

将本地网络端口转发到 pod 中的端口

如果想要在不通过 service 的情况下与某个特定的 pod 进行通信 出于调试或其他原因), Kubemetes 将允许我们配置端口转发到该 pod。

1
2
3
4
例如以下命令会将机器的本地端口 8888 转发到我们的 kubia-manual pod 的端口 8080 : 
$ kubectl port-forward kubia-manual 8888:8080
Forwarding from 127.0.0.1:8888 -> 8080
Forwarding from [: :l] :8888 -> 8080

pod 标签

你只对某些标签感兴趣,可以使用-L选项指定它们并将它们分别显示在自己的列中,而不是列出所有标签 接下来我们再次列出所有pod。

1
2
3
4
5
6
$ kubectl get po --show-labels 

$ kubectl get po -L creation_method,env
NAME READY STATUS RESTARTS AGE CREATION_METHOD ENV
kubia-manual 1/1 Running 0 16m <none> <none>
kubia-manual-v2 1/1 Running 0 2m manual prod

创建标签

1
$ kubectl label po kubia-manual creation_method=manual 

修改标签

1
$ kubectl label po kubia-manual-v2 env=debug --overwrite

注意 在更改现有标签 ,需要使用 –overwrite 选项

删除命名空间中的(几乎)所有资源

1
$ kubectl delete all --all 

命令中的第一个all指定正在删除所有资源类型,而–all选项指定将删除所有资源实例
注意 kubectl delete all –all 命令也会删除名为 kubernetes Service ,但它应该会在几分钟后自动重新创建

第四章 控制器

获取前容器日志

kubectl logs 命令将显示当前容器的日志,当你想知道为什么前一个容器终止时,你想看到的是前一个容器的日志,而不是当前容可以通过添加–previous 选项来完成:

1
kubectl logs liveness --previous

kubectl describe说明

1
2
3
4
5
Last State:     Terminated
Reason: Error
Exit Code: 137
Started: Wed, 22 May 2019 16:14:45 +0800
Finished: Wed, 22 May 2019 16:16:33 +0800

退出代码为137这有特殊的含义,表示该进程由外部信号终止 数字 137 是两个数字的总和:128+x ,其中x是终止进程的信号编号。在这个例子中, x等于9,这是SIGKILL的信号编号,意味着这个进程被强行终止。

注意 退出代码 137 表示进程被外部信号终止,退出代码为 128+9 (SIGKILL)同样,退出代码143对应于128+15 (SIGTERM)。

注意 当容器被强行终止时会创建一个全新的容器,而不是重启原来的容器

存活探针说明

yaml

1
2
3
4
livenessProbe:
httpGet:
path: /
port: 8080

kubectl describe 输出如下

1
Liveness:       http-get http://:8080/ delay=0s timeout=1s period=10s #success=1 #failure=3

如 delay(延迟)、timeout(超时)、period(周期)等 。delay=Os 部分显示在容器启动后立即开始探测,timeout 仅设置为1秒,因此容器必须在1秒内进行响应,不然这次探测记作失败。每 10 秒探测一次容器( period=lOs ),并在探测连续三次失败( # failure=3)后重启容器。

1
2
3
4
5
livenessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 15 # Kubernetes 会在第一次探测前等待15秒

第五章 服务

在运行的容器中远程执行命令

1
$ kubectl exec kubia-7nogl -- curl -s http: //10 .111. 249 .153

为什么是双横杠?
双横杠(–)代表着 kubectl 命令项的结束,在两个横杠之后的内容是指在 pod 内部需要执行的命令。如果需要执行的命令并没有以横杠开始的参数,横杠也不是必需的,如下情况,如果这里不使用横杠号,–选项会被解析成kubectl exec 选项,会导致结果异常和歧义错误。

1
2
3
4
5
6
$ kubectl exec kubia-7nogl curl -s http://10.lll.249.153 
The connection to the server 10.11 .249.153 was refused - did you
specify the right host or port?

服务除拒绝连接外什么都不做,这是因为 kubectl 并不能连接到位于10.111.249.153的API服务器( -s 选项用来告诉 kubectl 需要连接一个
不同的 API 服务器而不是默认的)

配置服务上的会话亲和性

如果希望特定客户端产生的所有请求每次都指向同一个pod,可以设置服务的sessionAffinity 属性为 ClientIP(而不是None, None是默值),如下:

1
2
3
4
5
apiVersion: vl 
kind: Service
spec:
sessionAffinity: ClientIP
...

Kubernetes 仅仅支持两种形式的会话亲和性服务:None 和 ClientIP,不支持基于 cookie 的会话亲和性的选项。了解 kubernetes服务不是在 HTTP层面上工作,服务处理TCP和UDP包。而cookie是HTTP协议中的一部分。

同一个服务暴露多个端口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: vl 
kind: Service
metadata:
name: kubia
spec:
ports:
- name: http
port: 80
targetPort: 8080 # pod的8080映射成80端口
- name: https
port: 443
targetPort: 8443
selector:
app: kubia # 标签选择器适用于整个服务

无法 ping 通服务 IP 的原因

pod里面可以执行curl访问服务,但是却ping不通。这是因为服务的集群是一个虚拟IP,并且只有在与服务端口结合时才有意义。

使用 JSONPath 获取所有节点的 IP

可以在节点的 JSON 或YAML描述符中找到IP。

1
$ kubectl get nodes -o jsonpath='{.items[*].status.addresses[?(@.type=="ExternaIP")].address}'

通过指定 kubectl 的 JSONPath ,使得其只输出需要的信息。你可能已经
熟悉 XPath,并且知道如何使用XML,JSONPath 基本上是 JSON 的XPath。上例中的 JSONPath 指示 kubectl 执行以下操作:

  • 浏览 item 属性中的所有元素
  • 对于每个元素 ,输入 status 属性
  • 过滤 address 属性的元素,仅包含那些具有将 type 属性设置为External IP 的元素
  • 最后 ,打印过滤元素的 address 属性

防止不必要的网络跳数

当外部客户端通过节点端口连接到服务时(这也包括先通过负载均衡器时的情况),随机选择 pod 并不一定在接收连接的同一节点上运行。可能需要额外的网络跳转才能到达 pod ,但这种行为并不符合期望。

可以通过将服务配置为仅将外部通信重定 向到接收连接的节点上运行的 pod来阻止额外跳数。这是通过在服务的 spec 部分中设置 externalTrafficPolicy宇段来完成的。

1
2
3
spec: 
externalTrafficPolicy: Local
...

注意 这种配置客户端 IP 是不记录的

第八章 API交互

关闭基于角色的访问控制( RBAC)

目前最简单的方式就是运行下面的命令查询 API 服务器,从而绕过 RBAC 方式

1
2
3
$ kubectl create clusterrolebinding permissive-binding \ 
--clusterrole=cluster admin \
--group=system:serviceaccounts

这个命令赋予了所有服务账户(也可以说所有的 pod )的集群管理员权限,允许它们执行任何需要的操作,很明显这是一个危险的操作,永远都不应该在生产的集群中执行,对于测试来说是没有问题的。