k8s集群核心概念pod

k8s集群核心概念pod

1.pod介绍

什么是pod

Pod 是 Kubernetes 应用程序的基本执行单元,即它是 Kubernetes 对象模型中创建或部署的最小和最简单的单元。简单的,我们可以理解为 Pod 是在集群上运行的进程。Pod 封装了应用程序容器或者在某些情况下封装多个容器、存储资源、唯一网络 IP 以及控制容器应该如何运行的选项。其中,Docker 是 Kubernetes Pod 中最常用的容器运行时,但 Pod 也能支持其他的容器运行时。Pod 的两个主要用途如下所示:

  • 运行单个容器的 Pod —— 支持多容器的微服务实例

    • 每个 Pod 一个容器的模型是最常见的使用情况,在这种情况下,可以将 Pod 看作单个容器的包装器,并且 Kubernetes 直接管理 Pod,而不是容器。
  • 运行多个协同工作的容器的 Pod —— 基于多容器微服务模型的分布式应用模型

    • Pod 可能封装由多个紧密耦合且需要共享资源的共处容器组成的应用程序,Pod 将这些容器和存储资源打包为一个可管理的实体。
  • 分布式系统工具包:容器组合的模式 —— 有状态服务水平扩展

    • 即将多个服务同时封装到同一个 Pod 中,对外提供服务,而不再需要用户手动安装其他服务或者工具,真正做到即时即用的便捷效果。
  • 容器设计模式

    • 云原生应用运行的环境都是复杂的分布式环境,在这种情况下,一些有用的设计模式可以起到四两拨千斤的作用。目前 K8s 社区推出的容器设计模式主要分为三大类:单容器管理模式、单节点多容器模式、多节点多容器模式

Pod 中的容器被自动的安排到集群中的同一物理或虚拟机上,并可以一起进行调度。容器可以共享资源和依赖、彼此通信、协调何时以及何种方式终止它们。Pod 提供了两种共享资源:网络 和 存储。

网络:
  • 同一个 Pod 内部通讯:

    • 同一个 Pod 共享同一个网络命名空间,共享同一个 Linux 协议栈。
  • 不同 Pod 之间通讯:

    • Pod1 和 Pod2 在同一台 Node 主机,由 docker0 网桥直接转发请求到 Pod2 上面,- 不经过 Flannel 的转发。
    • Pod1 和 Pod2 不在同一台 Node 主机,Pod 的地址是与 docker0 在同一个网段的,但 docker0 网络与宿主机网卡是两个完全不同的 IP 网段,并且不同的 Node 之间的通讯只能通过宿主机的物理网卡进行。将 Pod 的 IP 地址和所在 Node 的 IP 地址关联起来,通过这个关联让 Pod 可以互相访问。
  • Pod 至 Service 的网络

    • 目前基于性能考虑,全部为 iptables 或 lvs 维护和转发。
  • Pod 到外网

    • Pod 想外网发送请求,查找路由表,转发数据包到宿主机的网卡,宿主机网卡完成路由选择之后,iptables 或 lvs 执行 Masquerade,把源 IP 地址更改为宿主机的网卡的 IP 地址,然后向外网服务器发送请求。
  • 外网访问 Pod

    • 通过 Service 服务来向外部提供 Pod 服务。
存储:

一个 Pod 可以指定一组共享存储卷。Pod 中的所有容器都可以访问共享卷,允许这些容器共享数据。卷还允许 Pod 中的持久数据保留下来,以防其中的容器需要重新启动

pod的使用

我们很少会直接在 kubernetes 中创建单个 Pod。因为 Pod 的生命周期是短暂的,用后即焚的实体。当 Pod 被创建后,都会被 Kubernetes 调度到集群的 Node 上。直到 Pod 的进程终止、被删掉、因为缺少资源而被驱逐、或者 Node 故障之前这个 Pod 都会一直保持在那个 Node 上。

我们需要知道 Pod 本身是不会自愈修复的。如果 Pod 运行的 Node 故障或者是调度器本身故障,这个 Pod 就会被删除。同样的,如果 Pod 所在 Node 因为缺少资源或者 Pod 处于维护状态,那么 Pod 也就会被自动驱逐掉。Kubernetes 使用更高级的称为 Controller 的抽象层,来管理 Pod 实例。虽然可以直接使用 Pod,但是在 Kubernetes 中通常是使用 Controller 来管理 Pod 的。Controller 可以创建和管理多个 Pod,提供副本管理、滚动升级和集群级别的自愈能力。

需要注意的是,重启 Pod 中的容器跟重启 Pod 不是一回事。Pod 只提供容器的运行环境并保持容器的运行状态,重启容器不会造成 Pod 重启。

Kubernetes 使用了一个更高级的称为 控制器 的抽象,由它处理相对可丢弃的 Pod 实例的管理工作。因此,虽然可以直接使用 Pod,但在 Kubernetes 中,更为常见的是使用控制器管理 Pod。

  • Deployment
  • StatefulSet
  • DaemonSet

2.pod的生命周期

了解 Init 容器

我们知道 Pod 可以包含多个容器,应用运行在这些容器里面,同时 Pod 也可以有一个或多个先于应用容器启动的 Init 容器。Init 容器与普通的容器非常像,但是有两点不同之处。与普通容器的不同之处在于,Init 容器支持应用容器的全部字段和特性,包括资源限制、数据卷和安全设置,但是不支持 Readiness Probe,因为它们必须在 Pod 就绪之前运行完成。

  • 其一就是,Init 容器总是运行到完成为止。
  • 其二就是,每个 Init 容器都必须在下一个 Init 容器启动之前成功完成才会继续运行。

如果 Pod 内设置的 Init 容器运行失败了,那么 Kubernetes 就会不断地重启该 Pod,直到 Init 容器成功为止。然而,如果 Pod 对应的重启策略 restartPolicy 的值为 Never,它不会重新启动。如果为一个 Pod 指定了多个 Init 容器,这些容器会按顺序逐个运行。每个 Init 容器必须运行成功,下一个才能够运行。当所有的 Init 容器运行完成时,Kubernetes 才会为 Pod 初始化应用容器并像平常一样运行。

因为 Init 容器具有与应用容器分离的单独镜像,其启动相关代码具有如下优势:

  • Init 容器可以包含一些安装过程中应用容器中不存在的实用工具或个性化代码。例如,没有必要仅为了在安装过程中使用类似 sed、 awk、 python 或 dig 这样的工具而去 FROM 一个镜像来生成一个新的镜像。
  • Init 容器可以安全地运行这些工具,避免这些工具导致应用镜像的安全性降低。应用镜像的创建者和部署者可以各自独立工作,而没有必要联合构建一个单独的应用镜像。
  • Init 容器能以不同于 Pod 内应用容器的文件系统视图运行。因此,Init 容器可具有访问 Secrets 的权限,而应用容器不能够访问。
  • 由于 Init 容器必须在应用容器启动之前运行完成,因此 Init 容器提供了一种机制来阻塞或延迟应用容器的启动,直到满足了一组先决条件。一旦前置条件满足,Pod 内的所有的应用容器会并行启动。

使用 Init 容器

下面的例子定义了一个具有 2 个 Init 容器的简单 Pod。第一个等待 myservice 启动,第二个等待 mydb 启动。一旦这两个 Init 容器都启动完成,Pod 将启动 spec 区域中的应用容器。下面的准备的 yaml 文件展示了 mydb 和 myservice 两个 Pod 对应的 Service 服务。

  • pod
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
spec:
  containers:
    - name: myapp-container
      image: busybox:1.28
      command: ['sh', '-c', 'echo The app is running! && sleep 3600']
  initContainers:
    - name: init-myservice
      image: busybox:1.28
      command:
        - "sh"
        - "-c"
        - "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"
    - name: init-mydb
      image: busybox:1.28
      command:
        - "sh"
        - "-c"
        - "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]
  • Service
apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376
---
apiVersion: v1
kind: Service
metadata:
  name: mydb
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9377

要启动这个 Pod,可以执行如下命令,这可以看到对应的启动过程,但是我们会发现其状态一直停留在 init 的阶段没有就绪。通过日志我们发现,是因为 init 容器没有检测到 myservice 和 mydb 的 service 启动导致的。

# 启动Pod
$ kubectl apply -f myapp.yaml
pod/myapp-pod created

# 检查Pod状态
$ kubectl get -f myapp.yaml
NAME        READY     STATUS     RESTARTS   AGE
myapp-pod   0/1       Init:0/2   0          6m

# 如需更详细的信息
$ kubectl describe -f myapp.yaml

# 如需查看Pod内Init容器的日志
$ kubectl logs myapp-pod -c init-myservice
$ kubectl logs myapp-pod -c init-mydb

创建 mydb 和 myservice 的 service 之后,这样将能看到这些 Init 容器 执行完毕,随后 my-app 的 Pod 转移进入 Running 状态且 myapp-pod 被创建了。需要注意的是,如果 Pod 重启,所有 Init 容器必须重新执行。

# 创建mydb和myservice
$ kubectl create -f services.yaml
service "myservice" created
service "mydb" created

# 查看Pod状态
$ kubectl get -f myapp.yaml
NAME        READY     STATUS    RESTARTS   AGE
myapp-pod   1/1       Running   0          9m

状态和策略

  • Pod 的重启策略

Pod 重启策略 RestartPolicy 应用于 Pod 内的所有容器,并且仅在 Pod 所处的 Node 上由 kubelet 进行判断和重启操作。当某个容器异常退出或者健康检查失败时,kubelet 将根据 RestartPolicy 的设置来进行相应的操作。Pod 的重启策略包括 Always、OnFailure 和 Never 三种,默认值为 Always。

kubelet 重启失效容器的时间间隔以 sync-frequency 乘以 2n 来计算,例如 1、2、4 等,最长延时 5min,并且在成功重启后的 10min 后重置该时间

重启策略描述
Always当容器失效时,由kubelet自动重启改容器
OnFailure当容器终止运行且退代码不为0时,由kubelet自动重启改容器
Never不论容器运行状态如何,kubelet都不会重启改容器
  • Pod 的各种状态

Pod 的 status 定义在 PodStatus 对象中,其中有一个 phase 字段。Pod 的运行阶段(phase)中其生命周期中的简单宏观概述。该阶段并不是对容器或 Pod 的综合汇总,也不是为了做为综合状态机。下面是 phase 可能的值:

状态值描述
PendingAPI Server已经创建改pod,但还有一个或者多个容器的镜像没有创建成功,如下载镜像等状态
RunningPod内容器均已创建,且至少有一个容器出于运行状态,正在启动或者正在重启
Succeededpod内所有容器均已成功执行退出,且不会重启
Failedpod内所有容器均=退出,但至少有一个容器退出为失败状态
Unknow由于某种原因无法获取改pod的状态,可能由于网络通信不通导致

容器探针的类型

探针是由 kubelet 对容器执行的定期诊断,主要是为了保证我们在使用容器探针来帮助我们检测和保证 Pod 中的服务正常运行。要执行诊断,kubelet 调用由容器实现的 Handler,有三种类型的处理程序:

  • ExecAction

    • 在容器内执行指定命令。如果命令退出时返回码为 0 则认为诊断成功。
  • TCPSocketAction

    • 对指定端口上的容器的 IP 地址进行 TCP 检查。如果端口打开,则诊断被认为是成功的。
  • HTTPGetAction

    • 对指定的端口和路径上的容器的 IP 地址执行 HTTP Get 请求。如果响应的状态码大于等于 200 且小于 400,则诊断被认为是成功的。

Kubelet 可以选择是否执行在容器上运行的三种探针执行和做出反应:

  • livenessProbe

    • 指示容器是否正在运行。如果存活探测失败,则 kubelet 会杀死容器,并且容器将受到其 重启策略 的影响。如果容器不提供存活探针,则默认状态为 Success。
  • readinessProbe

    • 指示容器是否准备好服务请求。如果就绪探测失败,端点控制器将从与 Pod 匹配的所有 Service 的端点中删除该 Pod 的 IP 地址。初始延迟之前的就绪状态默认为 Failure。如果容器不提供就绪探针,则默认状态为 Success。
  • startupProbe

    • 指示容器中的应用是否已经启动。如果提供了启动探测(startup probe),则禁用所有其他探测,直到它成功为止。如果启动探测失败,kubelet 将杀死容器,容器服从其重启策略进行重启。如果容器没有提供启动探测,则默认状态为成功Success。

检测探针 -就绪检测(readinessProbe-httpget)

apiVersion: v1
kind: Pod
metadata:
  name: readiness-httpget-pod
  namespace: default
spec:
  containers:
    - name: readiness-httpget-container
      image: escape/nginx-test:v1
      imagePullPolicy: IfNotPresent
      readinessProbe:
        httpGet:
          port: 80
          path: /index1.html
        initialDelaySeconds: 1
        periodSeconds: 3

检测探针 - 存活检测

  • livenessProbe-exec
apiVersion: v1
kind: Pod
metadata:
  name: liveness-exec-pod
  namespace: default
spec:
  containers:
    - name: liveness-exec-container
      image: busybox
      imagePullPolicy: IfNotPresent
      command:
        - "/bin/sh"
        - "-c"
        - "touch /tmp/live ; sleep 60; rm -rf /tmp/live; sleep 3600 "
      livenessProbe:
        exec:
          command: ["test", "-e", "/tmp/live"]
        initialDelaySeconds: 1
        periodSeconds: 3
  • livenessProbe-httpget
apiVersion: v1
kind: Pod
metadata:
  name: liveness-httpget-pod
  namespace: default
spec:
  containers:
    - name: liveness-httpget-container
      image: escape/nginx-test:v1
      imagePullPolicy: IfNotPresent
      ports:
        - name: http
          containerPort: 80
      livenessProbe:
        httpGet:
          port: http
          path: /index.html
        initialDelaySeconds: 1
        periodSeconds: 3
        timeoutSeconds: 10
  • livenessProbe-tcp
apiVersion: v1
kind: Pod
metadata:
  name: probe-tcp
  namespace: default
spec:
  containers:
    - name: nginx
      image: escape/nginx-test:v1
      livenessProbe:
        initialDelaySeconds: 5
        timeoutSeconds: 1
        tcpSocket:
          port: 80

3.查看pod

查看default命名空间中的Pod

kubectl get pod
或
kubectl get pods
或
kubectl get pods --namespace default
或
kubectl get pod --namespace default

查看其他命名空间中的Pod

kubectl get pod -n kube-system  # kube-system 命名空间名称

4.创建pod

由于网络原因,建议提前准备好容器镜像。本次使用nginx:latest容器镜像

1.编写用于创建Pod资源清单文件

root@k8s1:/home# cat 02-create-pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod1
  #namespace: default
spec:
  containers:
  - name: ngninx-pod
    image: nginx:latest
    ports:
    - name: nginxport
      containerPort: 88
    resources:
        limits:
          cpu: '1'
          memory: 1Gi
        requests:
          cpu: 200m
          memory: 512Mi

2.应用用于创建Pod资源清单文件

命令

kubectl apply -f 02-create-pod.yaml

输出结果

pod/pod1 created

3.验证Pod是否被创建

查看已创建pod

root@k8s1:/home# kubectl get pod
NAME                                 READY   STATUS      RESTARTS   AGE
pod1                                 1/1     Running     0          6m

通过指定默认命名空间查看已创建pod

root@k8s1:/home# kubectl get pods -n default
NAME                                 READY   STATUS      RESTARTS   AGE
pod1                                 1/1     Running     0          7m47s

查看pod更加详细信息

root@k8s1:/home# kubectl get pods -o wide
NAME                                 READY   STATUS      RESTARTS   AGE     IP              NODE   NOMINATED NODE   READINESS GATES
pod1                                 1/1     Running     0          8m59s   10.233.88.56    k8s3   <none>           <none>

5.访问pod

root@k8s1:/home# curl http://10.233.88.56
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

6.删除pod

kubectl命令行删除

root@k8s1:/home# kubectl delete pods pod1
pod "pod1" deleted

通过kubectl使用Pod资源清单文件删除

root@k8s1:/home# kubectl delete -f 02-create-pod.yaml
pod "pod1" deleted
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Kubernetes(简称K8s)是一个开源的容器编排平台,可以帮助实现容器化应用的自动化部署、扩展和管理。Kubernetes通过以下几个核心概念来实现集群管理: 1. PodPodKubernetes中最小的调度和管理单位,它是一个或多个容器的组合。Pod可以共享网络和存储资源,并且在同一个Pod中的容器可以通过localhost相互通信。 2. Node:Node是Kubernetes集群中的一个工作节点,它可以是物理机器或虚拟机。每个Node可以运行多个Pod,并且负责Pod的调度和运行。 3. Deployment:Deployment是用来定义应用的副本数和更新策略的对象。通过Deployment,可以实现应用的自动扩缩容和滚动更新。 4. Service:Service是一组Pod的抽象,可以提供稳定的网络访问地址。Service可以通过标签选择器来选择一组Pod,并将它们暴露给其他应用或用户。 5. Namespace:Namespace是用来隔离和组织集群资源的虚拟环境。通过Namespace,可以将不同的应用和团队隔离开来,避免资源冲突。 6. ConfigMap和Secret:ConfigMap用于存储应用的配置信息,Secret用于存储敏感的密钥和证书。通过ConfigMap和Secret,可以将配置信息和密钥与应用解耦,提高安全性和可维护性。 通过这些核心概念Kubernetes可以实现自动化部署、自动扩缩容、自动恢复等功能,从而简化了集群管理的复杂度。同时,Kubernetes还提供了丰富的API和命令行工具,可以方便地管理和监控集群的状态和健康状况。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值