(三)Kubernetes 之 pod

2021-08-20  本文已影响0人  deve_雨轩

pod 是一组并置的容器,代表了 Kubernetes 中的基本构建模块。在实际应用中我们并不会单独部署容器,更多的是针对一组 pod 的容器进行部署和操作。然而这并不意味着一个 pod 总是要包含多个容器,实际上只包含一个单独容器的 pod 也是非常常见的。值得注意的是,当一个 pod 包含多个容器时,这些容器总是运行于同一个工作节点上,一个 pod 绝不会跨越多个工作节点。

-w688

在包含容器的 pod 下,我们可以同时运行一些密切相关的进程,并为它们提供几乎相同的环境,此时这些进程就好像全部运行于单个容器中一样,同时又保持着一定的隔离。这样一来,我们便能全面地利用容器所提供的特性,同时对这些进程来说它们就像运行在一起一样,实现两全其美 。

容器之间彼此是完全隔离的,但此时我们期望的是隔离容器组,而不是单个容器,并让每个容器组内的容器共享一些资源,而不是完全隔离。Kubernetes 通过配置 Docker 来让一个 pod 内的所有容器共享相同的 Linux 命名空间,而不是每个容器都有自己的一组命名空间。

由于一个 pod 中的所有容器都在相同的 network 和 UTS 命名空间下运行,所以它们都共享相同的主机名和网络接口。同样这些容器也都在相同的 IPC 命名空间下运行,因此能够通过 IPC 进行通信。在最新的 Kubernetes 和 Docker 版本中,它们也能够共享相同的 PID 命名空间,但是该特征默认是未激活的。

当同一个 pod 中的容器使用单独的 PID 命名空间时,在容器中执行 ps aux 就只会看到容器自己的进程。

但是当涉及文件系统时,情况就有所不同。由于大多数容器的文件系统来自容器镜像,因此默认情况下,每个容器的文件系统与其他容器完全隔离。但我们可 以使用 Volume 的 Kubernetes 资源来共享文件目录。

由于一个 pod 中的容器运行于相同的 Network 命名空间中,因此它们共享相同的 IP 地址和端口空间。这意味着在同- pod 中的容器运行的多个进程需要注意不能绑定到相同的端口号,否则会导致端口冲突,但这只涉及同一 pod 中的容器。 由于每个 pod 都有独立的端口空间,对于不同 pod 中的容器来说永远不会遇到端口冲突。此外,一个 pod 中的所有容器也都具有相同的网络接口,因此容器可以通过 localhost 与同一 pod 中的其他容器进行通信。

Kubernetes 集群中的所有 pod 都在同一个共享网络地址空间中,这意味着每个 pod 都可以通过其他 pod 的 IP 地址来实现相互访问。它们之间没有 NAT(网络地址转换)网关。当两个 pod 彼此之间发送网络数据包时,它们都会将对方的实际 IP 地址看作数据包中的源 IP。

-w616

在 Kubernetes 中运行一个简单的 pod

我们可以通过 kubectl run 命令, 该命令可以创建所有资源组件而无需 JSON 或 YAML 文件。

$ kubectl run yx-nginx --image=nginx  --port=80 --generator=run/v1

列出 pod

kubectl get pods

NAME             READY   STATUS    RESTARTS   AGE
yx-nginx-2r4xf   0/1     Pending   0          9m28s

可以看到 pod 处于挂起状态,READY 列显示 0/1 代表 pod 的容器还未就绪。pod 还没有运行的 原因是:该 pod 被分配到的工作节点正在下载容器镜像,完成之后才可以运行。下载完成后,将创建 pod 的容器, 然后 pod 会变为运行状态。

kubectl get pods

NAME             READY   STATUS    RESTARTS   AGE
yx-nginx-2r4xf   1/1     Running   0          9m28s

再次列出 pod,可以发现 pod的状态已经发生改变了。

查看pod详细信息

kubectl describe pod yx-nginx-2r4xf

使用描述文件创建 pod

YAML 格式的 Pod 定义文件的完整内容:

apiVersion: v1  ## 版本号
kind: Pod
metadata: ## 元数据 
  name: string  ## Pod 名称
  namespace: string ## Pod 所属的命名空间 默认值为 default
  labels: ## 自定义标签列表
  - name: string
  annotations: ## 自定义注解列表
    - name: string
spec: ##pod 中容器的详细定义
  containers: ## 容器列表
  - name: string ## 容器名称
    image: string ## 容器镜像名称
    ## 镜像拉取策略: 
    ## Always(默认值): 表示每次都尝试重新拉取镜像。
    ## IfNotPresent: 表示 如果本地有该镜像,则使用本地的镜像,本地不存在时拉取镜像。
    ## Never: 表示仅使用本地镜像。
    ## 下面几种情况系统将默认设置 imagePullPolicy=Always。
    ## 1. 不设置 imagePullPolicy,也未指定镜像的 tag
    ## 2. 不设置 imagePullPolicy,镜像 tag 为 latest
    ## 3. 启用名为 AlwaysPullImages 的准入控制器(Admission Controller)
    imagePullPolicy: [Always | Never |IfNotPresent]
    command: [string] ## 容器的启动命令列表,如果不指定,则使用镜像打包时使用的启动命令。
    args: [string]  ## 容器的启动命令参数列表
    workingDir: string ## 容器的工作目录
    volumeMounts: ## 挂载到容器内部的存储卷配置
    - name: string ## 引用 pod 定义的共享存储卷的名称,需使用 volumes[]部分定义的共享存储卷名称
      mountPath: string ## 存储卷在容器内 Mount 的绝对路径,应少于 512 个字符
      readOnly: boolean ## 是否为只读模式,默认为读写模式
    ports: ## 容器需要暴露的端口号列表
    - name: string ## 端口的名称
      containerPort: int ## 容器需要监听的端口号
      hostPort: int ## 容器所在主机需要监听的端口号,默认与 containerPort 相同。设置 hostPort 时,同一台宿主机将无法启动该容器的第 2 份副本
      protocol: string ## 端口协议,支持 TCP 和 UDP, 默认值为 TCP
    env:  ## 容器运行前需设置的环境变量列表
    - name: string ## 环境变量的名称
      value: string ## 环境变量的值
    resources: ## 资源限制和资源请求的设置
      limits: 
        cpu: string ## CPU 限制,单位为 core 数,将用于 docker run --cpu-shares 参数
        memory: string ## 内存限制,单位可以为 MiB、GiB等,将用于 docker run --memory 参数
      requests :
        cpu: string ## CPU 请求,单位为 core 数,容器启动的初始可用数量
        memory: string ## 内存请求,单位可以为 MiB、GiB等,容器启动的初始可用数量
    livenessProbe :
      exec:
        command: [string]
      httpGet:
        path: string
        port: number
        host: string
        scheme: string 
        httpHeaders:
        - name: string
          value: string
      tcpSocket:
        port: number
      initialDelaySeconds: 0
      timeoutSeconds: 0
      periodSeconds: 0
      successThreshold: 0
      failureThreshold: 0
    securityContext:
      privileged: false
  restartPolicy: [Always | Never | OnFailure]
  nodeSelector: object
  imagePullSecrets:
  - name: string
  hostNetwork: false
  volumes: ## 在该 Pod 上定义的共享存储卷列表
  - name: string
    emptyDir: { }
    hostPath:
      path: string
    secret:
      secretName: string
      items:
      - key: string
        path: string
    configMap:
      name: string
      items:
      - key: string
        path: string

pod定义的主要几个部分

pod定义由这么几个部分组成:首先是YAML中使用的 kubernetes API 版本和 YAML 描述的资源类型,其次就是几乎在所有 kubernetes 资源中都可以找到的三大重要部分:

编写一个简单的 YAML 描述文件创建 pod

apiVersion: v1
kind: Pod
metadata:
    name: test-nginx ##pod名称
spec:
    containers: ## pod里运行那些容器
    - image: nginx  ## 镜像名称
      name: test    ## 容器名称
      ports:
      - containerPort: 80 ## 容器运行监听的端口
        protocol: TCP

使用 kubectl explain 查找资源对象的属性
kubectl explain pod
kubectl explain pod.spec

使用 kubectl create 来创建 pod

kubectl create -f test-nginx.yaml

kubectl create -f 命令用于从YAML或JOSN文件创建任何资源,不只是pod。

获取运行中 pod 的完整定义

kubectl get po test-nginx -o yaml
kubectl get po test-nginx -o json

查看应用程序日志

使用 kubectl logs 命令获取 pod 日志

kubectl logs test-nginx

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

kubectl logs test-nginx -c test

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

停止和移除 pod

kc delete pods test-nginx
kc delete pods -l env=debug
kc delete pods --all -n test-namespace 
上一篇 下一篇

猜你喜欢

热点阅读