k8s-pod
介绍
1、pod 是k8s 中的最小部署单元,一个pod 可以运行多个容器,也可以运行一个容器。
2、pod 相比于容器,通过pod把容器包装到其中,通过k8s管理,可以实现负载均衡、高可用的特性(pod 中容器进程挂掉,应用程序异常主动通知k8s,通过健康检查检测程序异常,集群节点挂掉等都可以重新创建pod或者迁移pod,而容器不具备上述特性。
pod 存在的意义
同一个 Pod 多容器的弊端
如果一个pod 部署多个应用,或者多个容器,那么当需要扩容、重启pod 的时候Pod 中的应用都是同步执行的,这样不灵活,也浪费资源。 通过命令当前终端方式查看Pod 日志多个容器的应用日志混合在一起输出,不方便辨别。
POD 隔离与共享
由于不能将多个进程聚集在一个单独的容器中, 我们需要另 一种更高级的结构来将容器绑定在一起,并将它们作为一个单元进行管理,这就是 pod 背后的根本原理。
在包含容器的 pod 下,我们可以同时运行一些密切相关的进程,并为它们提供(几乎) 相同的环境, 此时这些进程就好像全部运行于单个容器中一样, 同时又保待着
一定的隔离。 这样一来, 我们便能全面地利用容器所提供的特性, 同时对这些进程来说它们就像运行在一起一样, 实现两全其美。
同一 pod 中容器之间的部分隔离
我们已经了解到容器之间彼此是完全隔离的, 但此时我们期望的是隔离容器组, 而不是单个容器, 并让每个容器组内的容器共享一些资源, 而不是全部(换句话说, 没有完全隔离)。 Kubemetes 通过配置 Docker 来让一个 pod 内的所有容器共享相同的 Linux 命名空间, 而不是每个容器都有自己的一组命名空间。
由千一个 pod 中的所有容器都在相同的 network 和 UTS 命名空间下运行(在这里我们讨论的是 Linux 命名空间), 所以它们都共享相同的主机名和网络接口。 同样
地, 这些容器也都在相同的 IPC 命名空间下运行, 因此能够通过 IPC 进行通信。 在最新的 Kubernetes 和 Docker 版本中, 它们也能够共享相同的 PID 命名空间, 但是
该特征默认是未激活的。注意 当同一个 pod 中的容器使用单独的 PID 命名空间时, 在容器中执行 ps aux 就只会看到容器自己的进程。
但当涉及文件系统时, 情况就有所不同。 由于大多数容器的文件系统来自容器镜像, 因此默认情况下, 每个容器的文件系统与其他容器完全隔离。 但我们可以使
用名为 Volume 的 Kubernetes 资源来共享文件目录
容器如何共享相同的IP和端口空间
这里需强调的一 点是, 由于一个 pod 中的容器运行于相同的 Network 命名空间中, 因此它们共享相同的 IP 地址和端口空间。 这意味着在同一 pod 中的容器运行的
多个进程需要注意不能绑定到相同的端口号, 否则会导致端口冲突, 但这只涉及同-pod 中的容器。 由千每个 pod 都有独立的端口空间, 对于不同 pod 中的容器来说
则永远不会遇到端口冲突。 此外, 一个 pod 中的所有容器也都具有相同的 loopback网络接口, 因此容器可以通过 localhost 与同一 pod 中的其他容器进行通信。
共享网络的实现
docker 容器都是独立的命名空间,但是相同的pod 中的容器是同一网络环境。这个是由于在创建pod 的时候会自动生成一个infrastructure Container 的容器,此容器生成pod 中的网络环境,其他pod 加入它构建的网络环境,处于同一个命名空间,同一pod 中的所有容器的IP 都是相同的。
注:还有一个init 初始化容器,需要自定义创建,此容器会在业务容器创建之前创建。
共享存储
通过挂载node 节点相同的数据盘实现共享存储
Pod 的健康保证
通过kubelet 管理
kubelet 是运行在每个node 节点的进程,它负载监控自己节点上的Pod 的情况,并且上报相关信息,出现异常会重启相关容器。
通过 ReplicationController
一个集群节点挂掉了,那么节点上的kubelet和所有pod都会挂掉,此时通过副本控制器可以在其他节点重新创建pod
Pod重启原因查看
通过kubectl describe pod -n namespace 查看 Last state下的退出状态码和 Events 等信息。
Pod 存活探针
三种探测容器的机制
存活探针的附加属性
livenessProbe: httpGet: path: / port: 8080 initialDelaySeconds: 15 #Kubernetes 会在第—次探测前等待15秒
notice:
pod 创建
1、命令方式 kubectl run ...
根据已有pod获取创建它的yaml
kubectl get pod nginx-6f7b4bf5bf-fgnf2 -n kzf -o yaml
yaml 文件结构
一个简单的示例
Tips
1、yaml 中 pod 端口的定义
pod定义中指定端口纯粹是展示性的, 它们对于客户端是以通过端口连接到 pod不会带来任何影响(例如容器中的应用是nginx ,yaml 配置的端口为8090,那么通过本地是无法通过8090 转发到80的,只有另外通过port-forward或service 代理转发)。
但明确定义端口仍是有意义的,在端口定义下,每个使用集群的人都可以快速查看每个 pod 对外露的端口。此外,我们将在本书的后续内容看到,明确定义端口还允许你为每个端口指定 名称,这样来更加方便使用。
2、kubectl explain 使用
在准备yaml时,可以转到http: /kubemetes.io docs/api上的 Kubemetes参考文档查看每个 API 对象支持哪些属性,也可以使用 kubectl explain
kubectl explain pods
Kubectl 打印出对象的解释并列出对象可以包含的属性,接下来就可以深入了解各个属性的更多信息,例如,可以这样查看 spec 属性
$ kubectl explain pod.spec
3、查看pod 的IP
kubectl get po -o wide -n kzf
Pod 删除
Tips:
在删除 pod 的过程中,实际上我 在指示 Kub es 终止该 pod 中的所有容器Kub etes 向进程发送 SI GTE阳信号并等待 定的秒数(默认为 30 ),使其正常关闭 如果它没有及时关闭,则通过 SIGKILL 终止该进程 因此,为了确保你 的进程总是正常关闭,进程需要正确处理 SIGTERM 信号 提示:还可以通过指定多个空格分隔的名称来删除多个 pod (例如 kubectldelete po podl pod2)
按照名称删除Pod
kubectl delete pod kubadf
使用标签选择器删除Pod
kubectl delete pod -1 method=asdfa
通过命名空间删除pod
kubectl delete pod-name -n namspace-name #删除指定命名空间下的pod
kubectl delete ns namespace-name #通过删除整个命名空间来删除 pod
kubectl delete pods --all -n kzf #删除命名空间下所有Pod ,不删除命名空间
kubectl delete all --all -n kzf #删除当前命名空间中的所有资源,可以删Replicationcontrol和pod, 以及所有 service。
Notice: 如果pod 是通过 ReplicationCcontroller创建的,那么只删除pod 还会自动产生新Pod ,此情况需要同时删除这个rc
日志
日志查看
docker logs <container id> #前提是 ssh命令登录到pod正在运行的节点, 并使用docker logs命令查看其日志 kubectl logs pod-name #无需登录容器所在节点,只在master 或其他可以调用k8s api 的客户端即可查看,此命令实际查看的仍然是容器日志 kubectl logs pod-name -c container-name # pod 中存在多个容器时,查看日志要指定要查看日志的容器名称
Notice
Pod端口转发
两种方式
1、kubectl expose 命令创建了 一个service, 以便在外部通过service 访问 pod。 2、kubectl port-forward 命令完成 #一般用于测试,生产环境都是通过service转发端口 kubectl port-forward kubia-manual 8888:8080
标签
一、介绍
Tips: 关于标签有单独一篇博文介绍