3-Pod

Pod - 运行于 Kubernetes 中的容器


介绍 pod

  • pod 内可以运行一个或多个容器,一个 pod 绝不会跨越多个工作节点。
  • pod 内的容器可以分为主容器和 sidecar 容器。(支持容器)

  • Question: 为什么每个容器内只运行一个进程?
  • Answer: 如果我们在容器内运行多个进程,那么管理这些进程的启动,停止,重启就会变得复杂。同时,由于进程们的输出都写到了 Docker 的输出中,分别管理它们的日志也不容易,未能充分利用 Docker 的特性。

Pod 内容器的共享与隔离

Kubernetes 通过配置 Docker 来让一个 pod 内的所有容器共享 Linux 命名空间。

具体来说:

  • pod 内的所有容器共享 Network, UTS,IPC 命名空间,这样 pod 内的所有容器具有相同的网络环境和主机名,他们之间可以相互进行 IPC 通信。(配置端口时要注意不让他们的端口发生冲突,同时他们可以通过 localhost 地址进行通信。)
  • PID 命名空间默认是不共享的,可以通过配置开启。
  • Mount 命名空间是不共享的,pod 内的容器相互是独立的根目录。如果容器之间想要共享文件的话,可以配置 k8s Volume 资源共享文件目录

Pod 的网络

k8s 集群中所有的 pod 都在同一个网络地址空间中,他们之间没有 NAT 网关。

通过 Manifest 创建 Pod

常用命令

# 输出一个 Pod 的 yaml 配置
`kubectl get pod podName -o=yaml`

# 获取配置的文档
`kubectl explain pod`
`kubectl explain pod.spec.containers`

# 通过 manifest 创建一个 Pod
`kubectl create -f somefile.yaml`

Manifest 说明

apiVersion: v1
kind: Pod
metadata:
  annotations:
    kubernetes.io/limit-ranger: 'LimitRanger plugin set: cpu request for container
      kubiame'
  creationTimestamp: "2020-03-16T13:35:38Z"
  generateName: kubiame-
  labels:
    run: kubiame
  name: kubiame-8wt8x
  namespace: default
  ownerReferences:
  - apiVersion: v1
    blockOwnerDeletion: true
    controller: true
    kind: ReplicationController
    name: kubiame
    uid: bd10842d-6602-11ea-93a6-42010a8c003a
  resourceVersion: "591803"
  selfLink: /api/v1/namespaces/default/pods/kubiame-8wt8x
  uid: 05e120ae-678b-11ea-baaa-42010a8c0091
spec:
  containers:
  - image: bwangel/kubia:v0.1
    imagePullPolicy: IfNotPresent
    name: kubiame
    ports:
    - containerPort: 8080
      protocol: TCP
    resources:
      requests:
        cpu: 100m
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
    volumeMounts:
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: default-token-hbl2l
      readOnly: true
  dnsPolicy: ClusterFirst
  enableServiceLinks: true
  nodeName: gke-demo-default-pool-ade08258-vqx4
  priority: 0
  restartPolicy: Always
  schedulerName: default-scheduler
  securityContext: {}
  serviceAccount: default
  serviceAccountName: default
  terminationGracePeriodSeconds: 30
  tolerations:
  - effect: NoExecute
    key: node.kubernetes.io/not-ready
    operator: Exists
    tolerationSeconds: 300
  - effect: NoExecute
    key: node.kubernetes.io/unreachable
    operator: Exists
    tolerationSeconds: 300
  volumes:
  - name: default-token-hbl2l
    secret:
      defaultMode: 420
      secretName: default-token-hbl2l
status:
  conditions:
  - lastProbeTime: null
    lastTransitionTime: "2020-03-16T13:35:38Z"
    status: "True"
    type: Initialized
  - lastProbeTime: null
    lastTransitionTime: "2020-03-16T13:36:18Z"
    status: "True"
    type: Ready
  - lastProbeTime: null
    lastTransitionTime: "2020-03-16T13:36:18Z"
    status: "True"
    type: ContainersReady
  - lastProbeTime: null
    lastTransitionTime: "2020-03-16T13:35:38Z"
    status: "True"
    type: PodScheduled
  containerStatuses:
  - containerID: docker://59a3d4a8f8778b7fa6424f91246180a82435cda5867915008250004b2171562a
    image: bwangel/kubia:v0.1
    imageID: docker-pullable://bwangel/kubia@sha256:16a200e2b44a2e9b28fe9c40338d3766f376130f806e263193dba02fb6d40c7c
    lastState: {}
    name: kubiame
    ready: true
    restartCount: 0
    state:
      running:
        startedAt: "2020-03-16T13:36:17Z"
  hostIP: 10.140.0.2
  phase: Running
  podIP: 10.0.0.6
  qosClass: Burstable
  startTime: "2020-03-16T13:35:38Z"

上面是通过 kubectl get pod -o=yaml 获取的完整的配置文件,一个 Pod 的YAML配置文件主要包括这么几部分:

名称 说明
apiVersion k8s API 的版本
kind 定义的资源的类型
metadata部分 Pod 的名称,命名空间,标签以及其他信息
spec部分 Pod 内容的实际说明,例如 Pod 的容器,卷等
status部分 Pod 的状态信息 (创建 Pod 时,无需指定 status 部分)

创建一个 Pod

下面是创建 Pod 所需的 Manifest 文件, kubia-manual.yaml,使用命令 kubectl create -f kubia-manual.yaml 就可以创建一个 Pod 了。

apiVersion: v1
kind: Pod
metadata:
  name: kubia-manual
spec:
  containers:
    - image: bwangel/kubia:v0.1
      name: kubiame
      ports:
      - containerPort: 8080
        protocol: TCP

需要注意的是, ports 部分是信息式的,即使 Manifest 中未声明 ports,只要应用监听了0.0.0.0:8080,其他 Pod 仍然能够访问这个 Pod 的 8080 端口。采用这样的声明可以让其他用户方便地了解到这个 Pod 暴露了哪些端口。

端口转发 & 查看日志

可以通过端口转发来访问 pod

kubectl port-forward kubia-manual <本地端口>:<Pod 暴露的端口>
# 查看日志
kubectl logs -f <Pod 名称> -c <容器的名称>

使用标签组织 Pod

标签是可以附加到资源的任意键值对,用以选择具有该确切标签的资源(这是通过标签选择器完成的)。

查看 Pod 的标签

# 查看所有标签
ø> kubectl get pod --show-labels
NAME              READY   STATUS    RESTARTS   AGE     LABELS
kubia-manual      1/1     Running   0          6d      <none>
kubia-manual-v2   1/1     Running   0          59s     creation_method=manual,env=prod
kubiame-fvh8x     1/1     Running   0          5d22h   run=kubiame
kubiame-hcjkf     1/1     Running   0          5d22h   run=kubiame
kubiame-qvw7w     1/1     Running   0          5d22h   run=kubiame
# 查看指定标签
ø> kubectl get pod -L creation_method,env
NAME              READY   STATUS    RESTARTS   AGE     CREATION_METHOD   ENV
kubia-manual      1/1     Running   0          6d
kubia-manual-v2   1/1     Running   0          63s     manual            prod
kubiame-fvh8x     1/1     Running   0          5d22h
kubiame-hcjkf     1/1     Running   0          5d22h
kubiame-qvw7w     1/1     Running   0          5d22h

修改 Pod 的标签

# 为 Pod 新增标签
ø> kubectl label pod kubia-manual creation_method=manual
pod/kubia-manual labeled
# 修改 Pod 的已有标签
ø> kubectl label pod kubia-manual-v2 env=debug --overwrite
pod/kubia-manual-v2 labeled
ø> kubectl get pod -L creation_method,env
NAME              READY   STATUS    RESTARTS   AGE     CREATION_METHOD   ENV
kubia-manual      1/1     Running   0          6d      manual
kubia-manual-v2   1/1     Running   0          2m52s   manual            debug

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

标签选择器可以根据资源的以下条件来选择资源:

# 包含(或者不包含)使用特定建的标签
ø> kubectl get pod -l creation_method
NAME              READY   STATUS    RESTARTS   AGE
kubia-manual      1/1     Running   0          6d
kubia-manual-v2   1/1     Running   0          17m
ø> kubectl get pod -l '!creation_method'
NAME            READY   STATUS    RESTARTS   AGE
kubiame-fvh8x   1/1     Running   0          5d22h
kubiame-hcjkf   1/1     Running   0          5d22h
kubiame-qvw7w   1/1     Running   0          5d22h

# 包含具有特定建和值的标签
ø> kubectl get pod -l creation_method=manual
NAME              READY   STATUS    RESTARTS   AGE
kubia-manual      1/1     Running   0          6d
kubia-manual-v2   1/1     Running   0          18m
ø> kubectl get pod -l 'env in (debug,prod)'
NAME              READY   STATUS    RESTARTS   AGE
kubia-manual-v2   1/1     Running   0          20m

# 键的值值不是我们指定的值
ø> kubectl get pod -l 'creation_method!=manual'
NAME            READY   STATUS    RESTARTS   AGE
kubiame-fvh8x   1/1     Running   0          5d22h
kubiame-hcjkf   1/1     Running   0          5d22h
kubiame-qvw7w   1/1     Running   0          5d22h
ø> kubectl get pod -l 'env notin (debug,prod)' --show-labels
NAME            READY   STATUS    RESTARTS   AGE     LABELS
kubia-manual    1/1     Running   0          6d1h    creation_method=manual
kubiame-fvh8x   1/1     Running   0          5d22h   run=kubiame
kubiame-hcjkf   1/1     Running   0          5d22h   run=kubiame
kubiame-qvw7w   1/1     Running   0          5d22h   run=kubiame
  • 当条件有多个时,他们是and的关系
ø> kubectl get pod -l 'creation_method=manual,env=debug' --show-labels
NAME              READY   STATUS    RESTARTS   AGE   LABELS
kubia-manual-v2   1/1     Running   0          25m   creation_method=manual,env=debug

使用标签和选择器来约束 Pod 调度

# 为节点添加标签
ø> kubectl label node gke-demo-default-pool-ade08258-g3rl gpu=true
node/gke-demo-default-pool-ade08258-g3rl labeled
apiVersion: v1
kind: Pod
metadata:
  name: kubia-gpu
spec:
  nodeSelector:
    gpu: "true"
  containers:
    - image: bwangel/kubia:v0.1
      name: kubiame
      ports:
      - containerPort: 8080
        protocol: TCP

通过 spec.NodeSelector 可以约束这个 Pod 只在 gpu=true 的节点上调度。

每个节点都有一个默认标签: kubernetes.io/hostname={节点的主机名},可以通过这个标签来让某个 Pod 只在一个节点上调度。

但是如果这个节点挂了的话,这个 Pod 则不会调度。

注解 Pod

# 添加注解
ø> kubectl annotate pod kubia-gpu bwangel.me/someannotation="foo bar"
pod/kubia-gpu annotated

# 查看注解
ø> kubectl describe pod kubia-gpu
Name:         kubia-gpu
Annotations:  bwangel.me/someannotation: foo bar
              kubernetes.io/limit-ranger: LimitRanger plugin set: cpu request for container kubiame

使用命名空间对资源进行分组

命名空间介绍

k8s 命名空间和 Linux 的命名空间不同,它只是简单地为对象名称提供了一个作用域,可以让我们在不同的命名空间中使用相同的名称,k8s 命名空间并不会隔离网络。

节点资源是全局的且未被约束于单一命名空间的资源,其他的大多数资源都和命名空间有关。

k8s 中所有的内容都是一个 API 对象,都可以通过向 K8S API 服务器提供 YAML manifest,来实现创建,读取,更新和删除操作。

查看命名空间及资源

# 获取所有命名空间

ø> kubectl get ns
NAME                   STATUS   AGE
default                Active   11d
kube-node-lease        Active   11d
kube-public            Active   11d
kube-system            Active   11d
kubernetes-dashboard   Active   9d

# 列出只属于某个 NS 的 Pod
ø> kubectl get pod -n kubernetes-dashboard
NAME                                          READY   STATUS    RESTARTS   AGE
kubernetes-dashboard-6f89577b77-fhbfb         1/1     Running   0          6d8h
kubernetes-metrics-scraper-79c9985bc6-bx59z   1/1     Running   0          6d8h

创建命名空间

可以通过以下 yaml 文件创建命名空间,也可以通过 k create namespace {namespace} 命令来创建命名空间。

命名空间的名字可以包括 字母,数字,横杠(-),但是不能包括点(.)。

apiVersion: v1
kind: Namespace
metadata:
  name: bwangel

为资源指定命名空间

可以在 Pod 的创建文件中设置 metadata.namespace 字段,为资源指定命名空间,也可以通过 k create -f pod.yaml -n {namespace} 命令指定资源的命名空间。

metadata:
  name: kubia-manual
  namespace: bwangel

切换命名空间

# 切换当前 kubectl 的默认命名空间到 bwangel
kubectl config set-context $(kubectl config current-context) --namespace bwangel

# 创建 kcd 命名,快速地切换命名空间
(( $+commands[kubectl] )) && alias kcd='kubectl config set-context $(kubectl config current-context) --namespace'

# 查看当前命名空间
ø> kubectl config view| grep namespace:
    namespace: default

停止和移除 Pod

k8s 在终止容器时,首先会向进程发送 SIGTERM 信号,并等待30秒。如果没有关闭的话,则继续发送 SIGKILL 信号。

如果应用程序想要正常结束的话,需要处理 SIGTERM 信号。

# 通过标签删除容器
ø> kubectl delete pod -l creation_method=manual
pod "kubia-manual" deleted
pod "kubia-manual-v2" deleted

# 删除所有资源(注:删除的是当前命名空间下的)
ø> kubectl delete all --all
pod "kubia-gpu" deleted
pod "kubiame-fvh8x" deleted
pod "kubiame-hcjkf" deleted
pod "kubiame-qvw7w" deleted
replicationcontroller "kubiame" deleted
service "kubernetes" deleted
service "kubia-http" deleted

# 删除命名空间
ø> kubectl delete ns bwangel
namespace "bwangel" deleted
2020年03月19日 / 00:03