美文网首页
(三)Kubernetes 之 pod

(三)Kubernetes 之 pod

作者: deve_雨轩 | 来源:发表于2021-08-20 09:27 被阅读0次

    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
    
    • --image=nginx 指定运行的镜像
    • --port=80 告诉kubernetes应用正在监听80端口
    • --generator 一般来说不会使用它,这里使用是为了让kubernetes创建一个 ReplicationController而不是Deployment

    列出 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 资源中都可以找到的三大重要部分:

    • metadata:包括名称,命名空间,标签和关于该容器的其他信息。
    • spec:包含 pod 内容的实际说明,例如 pod 的容器,卷和其他数据。
    • status:包含运行中的 pod 的当前信息,例如 pod 所处的条件,每个容器的描述和状态,以及内部IP和其他基本信息。

    编写一个简单的 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

    • 按名称删除 pod
    kc delete pods test-nginx
    
    • 使用标签选择器删除 pod
    kc delete pods -l env=debug
    
    • 删除指定命名空间下的所有 pod
    kc delete pods --all -n test-namespace 
    

    相关文章

      网友评论

          本文标题:(三)Kubernetes 之 pod

          本文链接:https://www.haomeiwen.com/subject/tkiobltx.html