【K8s】Pod 基本使用

216 阅读6分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情

一、简介

一个 PodKubernetes 最基本的构建单元,也是最小、最简单的构建单元。

Pod 也是扩缩容的基本单位,Kubernetes 的扩容和缩容都是直接对 Pod 进行操作的,直接增加 Pod 或是减少 Pod

一个 Pod 包含一个应用容器(有的时候有多个)、存储资源、唯一的网络 IP、以及其它容器运行所必须的资源。

PodKubernetes 集群中主要有两种使用方式:

  • 运行一个单独的容器:这是最常用的方式;在这种情况下,可以认为一个 Pod 封装了一个单独的容器,Kubernetes 是对 pod 进行管理,而不是直接对容器进行管理。

  • 运行耦合度高的多个容器Pod 也可能包含多个容器,这些容器之间关联紧密需要共享资源。将多个容器添加到单个 Pod 的主要原因是应用可能由一个主进程和一个或多个辅助进程组成。在实践中,把一个进程放到一个容器中运行是最好的。

如图:

uid600404-20190606-1559788333441.png

(1)NodePod

Pod 是运行在 Node 上的。一个 NodeKubernetes 上的工作节点,它可能是虚拟出来的节点或者是物理节点,这取决于集群的部署方式。

每个 Node 节点都被 Master 节点所管理,一个 Node 节点可以运行多个 Pod,在集群中,Kubernetes Master 节点通过 Node 节点自动管理 Pods

每个 Nodes 运行至少需要两个组件:

  • Kubelet:负责 MasterNode 之间的通信,用于管理节点上的 Pod
  • Docker:负责从仓库拉取容器镜像,运行应用等。

如图: uid600404-20190606-1559789852083.png

二、操作Pod

Pod 和其他 Kubernetes 资源通过向 Kubernetes REST API 提供 JSONYAML 描述文件来创建

编写YAML有4个重要组成部分:

  • apiVersionYAML描述文件所使用的Kubernetes API版本
  • kindKubernetes对象/资源类型
  • metadataPod元数据(名称、命名空间、标签、注解等)
  • specPod规格/内容(容器列表、存储卷等)
  1. 查看pods有哪些属性 kubectl explain pods

  2. 编写 nginx.yaml文件

此文件定义了一个名为 nginxPod,默认监听在 80 端口

apiVersion: v1
kind: Pod
metadata:
  name: nginx-manual
spec:
  containers:
    - image: registry.cn-hangzhou.aliyuncs.com/chenshi-kubernetes/nginx:1.9.1
      name: nginx
      ports:
        - containerPort: 80
          protocol: TCP
  1. 执行创建 pod kubectl create -f nginx.yaml

  2. Pod 列表查看新创建的 Pod kubectl get pods

Pod 在整个生命周期中存在各种状态,常见的状态如下图:

2020-05-1622:27.png

另外 Pod 的重启策略(RestartPolicy)有 3 种,分别为:

  • Always:默认策略,当容器失效时,kubelet 会自动重启该容器

  • OnFailure:当容器终止运行且退出码不为 0 时,kubelet 会自动重启该容器

  • Never:不论容器运行状态如何,kubelet 都不重启该容器

  1. 查看日志
# pod 上只有一个容器
kubectl logs nginx

# pod 上有多个容器,需要指定参数 -c 容器名 进行查询
kubectl logs nginx -c nginx
  1. 测试pod端口是否可用
# 执行端口转发,将本地 8080 端口转发到 nginx 80端口
kubectl port-forward nginx 8080:80

# 另起一个窗口,访问
curl http://localhost:8080
  1. 删除 Pod kubectl delete pod nginx

使用标签选择器删除pod kubectl delete pod -l creation_method=manual

通过删除整个命名空间的方式来删除pod kubectl delete ns test1-namespace

三、标签label

可以通过标签来组织 Pod 和所有其他 Kubernetes 资源对象。

通过标签划分组,这样就可以对属于某个组的所有 Pod 进行操作,而不需要单独为某个 Pod 执行操作。

  • 标签是可以附加在 Kubernetes 资源对象的任意键值对,通过标签选择器可以选择具有该确切标签的资源。

  • 标签的 key 是唯一的,一个资源可以拥有多个标签。

  • 创建资源时可以将标签附加在资源上,也可以在现有的资源上添加标签或修改标签值。

(1)操作

  1. yaml文件
apiVersion: v1
kind: Pod
metadata:
  name: nginx-manual-v2
  # 标签
  labels:
    creation_method: manual
    rel: beta
spec:
  containers:
    - image: registry.cn-hangzhou.aliyuncs.com/chenshi-kubernetes/nginx:1.9.1
      name: nginx
      ports:
        - containerPort: 80
          protocol: TCP
  1. 创建pod kubectl create -f nginx-manual-with-labels.yaml

  2. 查看 pod 标签 kubectl get pod --show-labels

  3. 查看某个具体的标签 -L kubectl get pod -L creation_method,rel

  4. 修改标签

# 向 nginx-manual 这个 pod 添加一个标签
$ kubectl label pod nginx-manual creation_method=manual
pod/nginx-manual labeled

# 将 nginx-manual-v2 这个 pod 上 rel=beat 修改为 rel=stable
# 需要添加 --overwrite 选项
$ kubectl label pod nginx-manual-v2 rel=stable --overwrite
pod/nginx-manual-v2 labeled

四、标签选择器

标签通常与标签选择器结合在一起使用,标签选择器可以选择标记有特定标签的 Pod 子集,并对这些 Pod 执行操作。

标签选择器对于标签的使用一般有如下 3 种方式:

  • 包含或是不包含使用特定键的标签
  • 包含具有特定键和值的标签
  • 包含有特定键,值可以为任意值的标签

(1)操作

  1. 想要筛选出所有手动创建的 Pod kubectl get pod -l creation_method=manual

  2. 列出含有 rel 标签的所有pod kubectl get pod -l rel

  3. 列出不含 rel 标签的所有 pod kubectl get pod -l '!rel'

  4. 其他的使用方式

# 列出含有 creation_method 标签,但是其值不能为 manual 的 Pod
$ kubectl get pod -l 'creation_method!=manual'
# 列出含有 rel 标签,且其值为 beta 或是 stable 的 Pod
$ kubectl get pod -l 'rel in (beta,stable)'
# 列出含有 rel 标签,且其值不为 beta 和 stable 的 Pod
$ kubectl get pod -l 'rel notin (beta,stable)'
# 列出含有标签 creation_method=manual 和 rel=stable 的 Pod
$ kubectl get pod -l creation_method=manual,rel=stable

(2)约束 pod 调度

Pod 通常都是随机调度到工作节点上。

如果想要将 Pod 调度到 GPU 的工作节点上,可以对相应的节点打上标签,然后在编写 yaml 文件时使用 nodeSelector 指定对应的节点标签。

  1. 查看环境中节点情况 kubectl get nodes

  2. 选择一个几点打上标签 kubectl label node kube-node-1 gpu=true

  3. 查看是否打上标签 kubectl get nodes -l gpu=true

  4. 新建名为 nginx-gpupod

apiVersion: v1
kind: Pod
metadata:
  name: nginx-gpu
spec:
  # 标签选择器
  nodeSelector:
    gpu: "true"
  containers:
    - image: registry.cn-hangzhou.aliyuncs.com/chenshi-kubernetes/nginx:1.9.1
      name: nginx
      ports:
        - containerPort: 80
          protocol: TCP
  1. 创建
$ kubectl create -f nginx-gpu.yaml
pod/nginx-gpu created

五、命名空间 namespace

由于标签和 Pod 是多对多的关系,使用标签可以将众多的 Pod 进行分组,这些组中的 Pod 有交叉重复的可能

使用 命名空间 就可以将对象分隔成完全独立且不重叠的组。

Kubernetes 的命名空间为对象名称提供了一个作用域。

对象名称只需要在一个命名空间内保持唯一,不同的命名空间可以包含同名的对象。

(1)操作

  1. 查看集群中所有的命名空间 kubectl get namespaces

  2. 查看 kube-system 命名空间下的 Pod

这里的pod都是和 Kubernetes 系统相关的。

$kubectl get pod -n kube-system                       
NAME                                    READY   STATUS    RESTARTS   AGE
coredns-5c98db65d4-zssrt                1/1     Running   0          64m
etcd-kube-master                        1/1     Running   7          272d
kube-apiserver-kube-master              1/1     Running   7          272d
kube-controller-manager-kube-master     1/1     Running   7          64m
kube-proxy-2ddnw                        1/1     Running   0          64m
kube-proxy-fjnhx                        1/1     Running   0          64m
kube-proxy-wldhn                        1/1     Running   0          64m
kube-scheduler-kube-master              1/1     Running   7          272d
kubernetes-dashboard-5ff478f859-d5b2g   1/1     Running   0          64m
  1. 创建新的命名空间
apiVersion: v1
kind: Namespace
metadata:
  name: test1-namespace
  1. 执行创建 kubectl create -f test1-namespace.yaml

或者直接使用命令 kubectl create namespace test2-namespace

  1. 在新的命名空间中创建 Pod
  • yaml 文件的 metadata 字段中添加 namespace: test1-namespace 属性
  • 创建 Pod 时在命令中使用参数 -n 指定命名空间

比如创建 pod 时候指定

$ kubectl create -f nginx-manual.yaml -n test1-namespace
pod/nginx-manual created