k8s-pod

摘要:
介绍1、pod是k8s中的最小部署单元,一个pod可以运行多个容器,也可以运行一个容器。此外,一个pod中的所有容器也都具有相同的loopback网络接口,因此容器可以通过localhost与同一pod中的其他容器进行通信。

介绍

1、pod 是k8s 中的最小部署单元,一个pod 可以运行多个容器,也可以运行一个容器。

2、pod 相比于容器,通过pod把容器包装到其中,通过k8s管理,可以实现负载均衡、高可用的特性(pod 中容器进程挂掉,应用程序异常主动通知k8s,通过健康检查检测程序异常,集群节点挂掉等都可以重新创建pod或者迁移pod,而容器不具备上述特性。

pod 存在的意义

Pod为亲密性应用而存在。
亲密性应用场景:
•两个应用之间发生文件交互
•两个应用需要通过127.0.0.1或者socket通信
•两个应用需要发生频繁的调用

同一个 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 的情况,并且上报相关信息,出现异常会重启相关容器。

1、容器的主进程崩溃, Kubelet 将重启容器
2、容器内的应用程序挂掉,kubelet 就会重启应用程序
3、通过健康检查(存活探针)检查应用,如果异常则重新启动容器

通过ReplicationController

一个集群节点挂掉了,那么节点上的kubelet和所有pod都会挂掉,此时通过副本控制器可以在其他节点重新创建pod

Pod重启原因查看

通过kubectl describe pod -n namespace查看 Last state下的退出状态码和Events等信息。

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

Pod 存活探针

Kubemetes 可以通过存活探针 (liveness probe) 检查容器是否还在运行。 可以为 pod 中的每个容器单独指定存活探针。 如果探测失败, Kubemetes 将定期执行探针并重新启动容器。

三种探测容器的机制

1、HTTPGET探针对容器的 IP 地址(你指定的端口和路径)执行 HTTP GET 请求,根据状态码决定是否重启容器。
2、TCP套接字探针尝试与容器指定端口建立TCP连接。如果连接成功建立,则探测成功。否则,容器重新启动。
3、Exec探针在容器内执行任意命令,并检查命令的退出状态码。如果状态码是 0, 则探测成功。所有其他状态码都被认为失败。

存活探针的附加属性

除了明确指定的存活探针选项,还可以看到其他属性,例如delay(延迟)、超时timeout(超时)、period(周期)等。delay=0s部分显示在容器启动后立即开始探测。超时timeout仅设置为1秒,因此容器必须在1秒内进行响应, 不然这次探测记作失败。每10秒探测一次容器(period=lOs), 并在探测连续三次失败(# failure=3)后重启容器。定义探针时可以自定义这些附加参数。
配置示例(设置初始延迟,将initialDelaySeconds属性添加到存活探针的配置中)
k8s-pod第1张k8s-pod第2张
livenessProbe: 
  httpGet: 
    path: /port: 8080initialDelaySeconds: 15          #Kubernetes 会在第—次探测前等待15秒
View Code

notice:

1、务必记得设置一个初始延迟来说明应用程序的启动时间
如果没有设置初始延迟,探针将在启动时立即开始探测容器, 这通常会导致探测失败, 因为应用程序还没准备好开始接收请求)
2、保持探针轻量
存活探针不应消耗太多的计算资源, 并且运行不应该花太长时间 。 默认情况下,探测器执行的频率相对较高, 必须在一秒之内执行完毕。 一个过重的探针会大大减慢你的容器运行
3、无须在探针中实现重试循环
探针的失败阙值是可配置的, 并且通常在容器被终止之前探针必须失败多次。 但即使你将失败阙值设置为1 , Kubemetes为了确认一次探测的失败,会尝试若干次 。 因此探针中自己实现重试循环是浪费精力

pod 创建

1、命令方式kubectl run ...

2、通过向 kubenetes REST API 提供 JSON 或YAML 描述文件来创建,kubectl create -f pod.yaml

根据已有pod获取创建它的yaml

kubectl get pod nginx-6f7b4bf5bf-fgnf2 -n kzf -o yaml

yaml 文件结构

pod定义由这么几个部分组成,首先是 YAML中使用的 K8s API 版本(apiVersion)和YAML 描述的资源类型(kind),其次是几乎在所有k8s资源中都可找到的三大重要部分
•metadata  包括名称、命名空间、标签和关于该容器的其他信息
•spec    包含 pod内容的实际说明,例如pod的容器、卷和其他数据
•status    包含运行中的pod的当前信息,例如pod所处的条件每个容器的描述和状态,以及内部IP和其他基本信息。status 部分包含只读的运行时数据,该数据展示了给定时刻的资源状态。而在创
建新的pod 时,永远不需要提供 status 部分。

一个简单的示例

k8s-pod第3张

Tips

1、yaml 中 pod 端口的定义

k8s-pod第4张k8s-pod第5张
pod定义中指定端口纯粹是展示性的, 它们对于客户端是以通过端口连接到 pod不会带来任何影响(例如容器中的应用是nginx ,yaml 配置的端口为8090,那么通过本地是无法通过8090 转发到80的,只有另外通过port-forward或service 代理转发)。
但明确定义端口仍是有意义的,在端口定义下,每个使用集群的人都可以快速查看每个 pod 对外露的端口。此外,我们将在本书的后续内容看到,明确定义端口还允许你为每个端口指定 名称,这样来更加方便使用。
View Code

2、kubectl explain 使用

k8s-pod第6张k8s-pod第7张
在准备yaml时,可以转到http: /kubemetes.io docs/api上的 Kubemetes参考文档查看每个 API 对象支持哪些属性,也可以使用 kubectl explain
kubectl explain pods
Kubectl 打印出对象的解释并列出对象可以包含的属性,接下来就可以深入了解各个属性的更多信息,例如,可以这样查看 spec 属性
$ kubectl explain pod.spec
View Code

3、查看pod 的IP

k8s-pod第8张k8s-pod第9张
kubectl get po -o wide -n kzf
View Code

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。
注意使用 all 关键字删除所有内容并不是真的完全删除所有内容。 一些资源比如 Secret会被保留下来, 并且需要被明确指定删除。

Notice: 如果pod 是通过ReplicationCcontroller创建的,那么只删除pod 还会自动产生新Pod ,此情况需要同时删除这个rc

日志

容器化的应用程序通常会将日志记录到标准输出和标准错误流, 而不是将其写入文件, 这就允许用户可以通过简单、 标准的方式查看不同应用程序的日志。

日志查看

k8s-pod第10张k8s-pod第11张
docker  logs  <container id>#前提是 ssh命令登录到pod正在运行的节点, 并使用docker logs命令查看其日志
kubectl logs pod-name          #无需登录容器所在节点,只在master 或其他可以调用k8s api 的客户端即可查看,此命令实际查看的仍然是容器日志
kubectl logs pod-name  -c container-name  # pod 中存在多个容器时,查看日志要指定要查看日志的容器名称
View Code

Notice

1、每天或者每次日志文件达到10MB大小时, 容器日志都会自动轮替。kubectl logs命令仅显示最后一次轮替后的日志条目。
2、当一个pod被删除时,它的日志也会被删除。 如果希望在pod删除之后仍然可以获取其日志, 我们需要设置中心化的、 集群范围的日志系统, 将所有日志存储到中心存储中。
3、默认查看的是当前Pod 的日志,如果pod 重启了,那么想要查看上一个pod 日志,可以通过命令 kubectl logs mypod --previous 查看

Pod端口转发

两种方式

k8s-pod第12张k8s-pod第13张
1、kubectl expose 命令创建了 一个service, 以便在外部通过service 访问 pod。

2、kubectl port-forward 命令完成                       #一般用于测试,生产环境都是通过service转发端口
   kubectl  port-forward  kubia-manual  8888:8080
View Code

标签

一、介绍

标签是一种简单却功能强大的Kubemetes特性, 不仅可以组织pod, 也可以组织所有其他的Kubemetes资源。 详细来讲, 标签是可以附加到资源的任意键值对,
用以选择具有该确切标签的资源(这是通过标答选择器完成的 )。 只要标签的key在资源内是唯一的,一个资源便可以拥有多个标签。 通常在我们创建资源时就会将标
签附加到资源上, 但之后我们也可以再添加其他标签, 或者修改现有标签的值, 而无须重新创建资源。

Tips: 关于标签有单独一篇博文介绍

免责声明:文章转载自《k8s-pod》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Android 简单UDP发送接收ios开发过程中描述文件(provisioning profile)过期导致ios无法正常安装的处理办法下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

K8S上的ELK和应用日志上报实战

来源:DevOps ID:Idevops168 本次实战的基础结构如下图所示: 一共有两个Pod:ELK和web应用; ELK的Pod会暴露两个服务,一个暴露logstash的5044端口,给filebeat用,另一个暴露kibana的5601端口,给搜索日志的用户访问的时候用; web应用暴露一个服务,给用户通过浏览器访问; 实战步骤简介 部署ELK的...

翻译:如何在Ubuntu16.04上安装Mosquitto这个MQTT消息服务器并对其进行安全配置

原文地址: https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-the-mosquitto-mqtt-messaging-broker-on-ubuntu-16-04 简介 MQTT是一个在机器和机器之间传递消息的协议,为实现物联网设备间轻量级的发布/订阅通信...

用宝塔搭建自己的网站

1.购买服务器 服务器就是电脑,理论上个人电脑也可以,但由于服务器上要部署网站,为了保证网站随时可以访问,就要求服务器不能关机。个人电脑由于没有专门的降温设备,长时间运行CPU扛不住,所以最好还是购买专门的服务器。对于个人以及很多小微企业,也不可能真的去向华为、浪潮等服务器提供商购买物理服务器,因为购买回来还得自建机房,这种情况下我们可以买云服务器,说白了...

OC项目加入swift第三方库遇到的坑

https://www.jianshu.com/p/96d868dcd69c 2017.07.07 16:23* 字数 295 阅读 5218评论 2喜欢 4 首先,在OC项目的Podfile文件中添加如下 use_frameworks! pod 'PromiseKit', '~> 4.2.2' #任意一个swift库 然后pod install 接...

Kubernetes进阶实战读书笔记:StatefulSet控制器(资源升级)

一、滚动更新 1、将myapp控制器下的pod资源镜像升级为:"ikubernetes/myapp:v6" [root@master ~]# kubectl set image sts myapp myapp=ikubernetes/myapp:v6 statefulset.apps/myapp image updated 2、实时监控更新操作过程 [ro...

谷歌火狐浏览器限制的端口

最近新项目,开了新端口进行测试,端口号是6666,却发现火狐和谷歌浏览器均不能访问。 火狐提示如下: 此地址使用了一个通常用于网络浏览以外目的的端口。出于安全原因,Firefox 取消了该请求。 谷歌提示如下: 无法显示此网页 ERR_UNSAFE_PORT 然后就开始怀疑是否是端口的问题,结果换成了8090,谷歌浏览器能正常访问了,想了下可能是谷歌浏览...