《Kubernetes in action》Pod基础

Kubernetes Pod

介绍Pod

为何需要pod

pod是一组并置的容器, 代表了Kubemetes中的基本构建模块。 在实际应用中我们并不会单独部署容器, 更多的是针对一组pod的容器进行部署和操作。
pod部署
为何多个容器比单个容器中包含多个进程要好
容器被设计为每个容器只运行一个进程(除非进程本身产生子进程)。 如果在单个容器中运行多个不相关的进程, 那么保持所有进程运行、 管理它们的日志等将会是我们的责任。 例如, 我们需要包含一种在进程崩溃时能够自动重启的机制。 同时这些进程都将记录到相同的标准输出中, 而此时我们将很难确定每个进程分别记

了解pod

由于不能将多个进程聚集在一个单独的容器中, 我们需要另 一种更高级的结构来将容器绑定在一起,并将它们作为一个单元进行管理,这就是 pod 背后的根本原理。在包含容器的 pod 下,我们可以同时运行一些密切相关的进程,并为它们提供(几乎) 相同的环境, 此时这些进程就好像全部运行于单个容器中一样, 同时又保待着一定的隔离。 这样一来, 我们便能全面地利用容器所提供的特性, 同时对这些进程来说它们就像运行在一起一样, 实现两全其美。

同一 pod 中容器之间的部分隔离

Kubemetes 通过配置 Docker 来让一个 pod 内的所有容器共享相同的 Linux 命名空间, 而不是每个容器都有自己的一组命名空间。由千一个 pod 中的所有容器都在相同的 network 和 UTS 命名空间下运行(在这里我们讨论的是 Linux 命名空间), 所以它们都共享相同的主机名和网络接口。 同样地, 这些容器也都在相同的 IPC 命名空间下运行, 因此能够通过 IPC 进行通信。 在最新的 Kubernetes 和 Docker 版本中, 它们也能够共享相同的 PID 命名空间, 但是该特征默认是未激活的。

容器如何共享相同的IP和端口空间

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

平坦pod间网络

Kubemetes 集群中的所有 pod 都在同一个共享网络地址空间中(如图 3.2 所示),这意味着每个 pod 都可以通过其他 pod 的 IP 地址来实现相互访问。 换句话说, 这也表示它们之间没有 NAT (网络地址转换) 网关。 当两个 pod 彼此之间发送网络数据包时, 它们都会将对方的实际 IP 地址看作数据包中的源 IP。
pod间网络
pod 之间的通信其实是非常简单的。 不论是将两个 pod 安排在单一的还是不同的工作节点上, 同时不管实际节点间的网络拓扑结构如何, 这些 pod 内的容器都能够像在无 NAT 的平坦网络中一样相互通信, 就像局域网 (LAN) 上的计算机一样。 此时, 每个 pod 都有自己的 IP 地址, 并且可以通过这个专门的网络实现 pod之间互相访问。 这个专门的网络通常是由额外的软件基于真实链路实现的。

通过Pod合理管理容器

将 pod 视为独立的机器, 其中每个机器只托管一个特定的应用。 过去我们习惯于将各种应用程序塞进同一 台主机, 但是 pod 不是这么干的。 由于 pod 比较轻量,我们可以在几乎不导致任何额外开销的前提下拥有尽可能多的 pod。 与将所有内容填充到一个 pod 中不同, 我们应该将应用程序组织到多个 pod 中, 而每个 pod 只包含紧密相关的组件或进程。

将多层应用分散到多个Pod中

如果前端和后端都在同一个容器中, 那么两者将始终在同一 台计算机上运行。如果你有一个双节点 Kubemetes 集群, 而只有一个单独的pod, 那么你将始终只会用一个工作节点, 而不会充分利用第二个节点上的计算资源 (CPU 和内存)。 因此更合理的做法是将pod 拆分到两个工作节点上, 允许 Kubemetes 将前端安排到一个节点, 将后端安排到另 一个节点, 从而提高基础架构的利用率。

基于扩缩容考虑而分割到多个Pod中

通常来说, 前端组件与后端组件具有完全不同的扩缩容需求, 所以我们倾向于分别独立地扩缩它们。更不用说, 像数据库这样的后端服务器, 通常比无状态的前端 web 服务器更难扩展。 因此, 如果你需要单独扩缩容器, 那么这个容器很明确地应该被部署在单独的pod中。

何时在 pod 中使用多个容器

将多个容器添加到单个pod的主要原因是应用可能由 一个主进程和一个或多个辅助进程组成,例如, 中的主容器可以是 个仅仅服务于某个目录中的文件的 服务器,而另 容器(所谓 id 容器) 定期从夕阳 源下载 容并将其存服务器目录中。sidecar 容器的其他例子包括日志轮转器和收集器、数据处理器、通信适配器等。
pod中多个容器
决定何时在 pod 中使用多个容器

我们需要问自己以下题:
它们需要 起运行还是可以在不同的主机上运行?
它们代表的是 体还是相互独立的组
它们必须一起进行扩缩容还是可 分别进行?
pod中单个容器

检查现有 pod YAML/Json 描述文件

kubectl 代码补全

1.安装bash-completion工具
yum install bash-completion -y
 否则报错:
-bash: _get_comp_words_by_ref: command not found
2.执行bash_completion
source /usr/share/bash-completion/bash_completion
3.加载kubectl completion
echo "source <(kubectl completion bash)" >> ~/.bashrc # 在您的 bash shell 中永久的添加自动补全
source ~/.bashrc
4.您还可以为 kubectl 使用一个速记别名,该别名也可以与 completion 一起使用:
alias k=kubectl
apiVersion: v1 //Kubernetes API版本
kind: Pod // 资源类型
metadata: // Pod元数据(名称, 标签和注解等)
  annotations:
    kubernetes.io/created-by: ...
  ereatonTmestamp: 2016-03-l8Tl2:3750Z
  generateName: kubia-
  labels:
    run: kub
  name: kubia-zxzij
  namespace: default
  resourceVersion: "294"
  selfLink: /api/v1/anamespaces/default/pods/kubia-zxzij
  uid: 3a564dc0-ed06-ll5-ba3b-42010af00004
spec: // pod规格/内容(pod的容器列表, volume)
  cotaiers:
    - image: luksa/kub
      imagePullPolicy: IfNotPresent
      name: kubia
      ports:
      - containerPort: 8080
        protocol: TCP
      resources:
        requests:
          cpu: 100m
          terminationMessagePath: /dev/termination-log
          volumeMounts:
          - mountPath: /var/run/secrets/k8s.io/service
            name: default-token-kvcqa
            readOnly: true
      dnsPolicy: ClusterFirst
      nodeName: gke-kubia-e8fe08b9-node-txje
      restartPolicy: Always
      serviceAccount: default
      terminationGracePeriodSeconds: 30
      volumes:
      - name: default-token-kvcqa
        secret:
          secretName: default-token-kvcqa
  status: // pod及其内部容器的详细状态
    conditions:
      - lastProbeTime: null
        lastTransitionTime: null
        status: "True"
        type: Ready
    containerStatuses:
    - containerID: docker://f0232
      image: luksa/kubia
      imageID: docker://4cafdaf
      lastState: {}
      name: kubia
      ready: true
      restartCount: 0
      state:
        running:
          starteAt: 2016-03-18T12:46:05Z
    hostIP: 10.132.0.4
    phase: Running
    podIP: 10.0.2.3
    startTime: 2016-03-18T12:44:05Z

kubectl 创建及查看pod(yaml)

  • 创建:
    • 快速创建deployments: kubectl create deployment kubia-manual --image=luksa/kubia -o yaml>kubia-manual.yaml
    • 通过yaml文件: kubectl create -f kubia-manual.yaml
    • 创建并更新: kubeclt apply -f kubia-manual.yaml
  • 查看
    • kubectl get po kubia-manual -o yaml
    • kubectl get po kubia-manual -o json
    • 使用 kubectl logs 命令获取 pod 日志 kubectl logs kubia-manual
    • 获取多容器 pod 的日志时指定容器名称 kubectl logs kubia-manual -c kubia

向pod发送请求

在实际操作中看到该状态

  • 将本地网络端口转发到 pod 中的端口
    • 将机器的本地端口 8888转发到我们的kubia-manual pod的端口8080:
      kubect1 port-forward kubia-manual 8888:8080
  • 通过端口转发连接到 podcurl localhost:8888
    curl port

通过标签选择器列出pod子集

介绍标签

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

创建pod时指定标签

apiVersion: vl 
kind: Pod 
metadata:
  name: kubia-manual-v2 
  labels: 
    creation method: manual 
    env: prod 
spec: 
  containers:
  - image: luksa/kubia
    name: kubia
    ports:
    - containerPort: 8080
      protocol: TCP

查看标签: kubectl get pod --show-labels
特定标签: kubectl get pod -L create_method, env

修改现有pod的标签

添加: kubectl label pod kubia-manual creation_method=manual
修改: kubectl label pod kubia-manual env=debug --overwrite

通过标签的选择pod

  • creation_rnethod!=rnanual 选择带有creation_rnethod标签, 并且值不等于manual的pod
  • env in (prod, devel)选择带有env标签且值为prod或devel的pod
  • env notin (prod, devel)选择带有env标签, 但其值不是prod或devel的pod
    select pod by labels
    使用标签选择器将Pod调度到特定节点: kubia-gpu.yaml
apiVersion: vl 
kind: Pod 
metadata:
  name: kubia-gpu 
spec: 
  nodeSelector.
    gpU: "true"
  containers: 
  - image: luksa/kubia
    name: kubia

注解

概念: 注解也是键值对,所以它们本质上与标签非常相似。但与标签不同,注解并不是为了保存标识信息而 存在的,它们不能像标签 一 样用千对对象进行分组。注解 可以容纳更多的信息,并且主要用于工具使用。Kubemetes也会将一些注解自动添加到对象,但 其他的注解则需要由用户手动添加。
好处: 大量使用注解可以为每个pod或其他API对象添加说明,以便每个使用该集群的入都可以快速查找有关每个
单独对象的信息。

添加和修改注解:kubect1 annotate pod kubia-manual mycompany.com/someannotation="foo bar"

命名空间

创建命名空间: kubectl creat ns custom-namespace
删除整个命名空间来删除 pod: kubectl delete ns custom-namespace
删除当前命名空间中的所有pod: kubectl delete pod --all

查看Kubernetes资源信息:kubectl explain

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值