一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情。
一、简介
一个 Pod 是 Kubernetes 最基本的构建单元,也是最小、最简单的构建单元。
Pod 也是扩缩容的基本单位,Kubernetes 的扩容和缩容都是直接对 Pod 进行操作的,直接增加 Pod 或是减少 Pod。
一个 Pod 包含一个应用容器(有的时候有多个)、存储资源、唯一的网络 IP、以及其它容器运行所必须的资源。
Pod 在 Kubernetes 集群中主要有两种使用方式:
-
运行一个单独的容器:这是最常用的方式;在这种情况下,可以认为一个
Pod封装了一个单独的容器,Kubernetes是对pod进行管理,而不是直接对容器进行管理。 -
运行耦合度高的多个容器:
Pod也可能包含多个容器,这些容器之间关联紧密需要共享资源。将多个容器添加到单个Pod的主要原因是应用可能由一个主进程和一个或多个辅助进程组成。在实践中,把一个进程放到一个容器中运行是最好的。
如图:
(1)Node 与 Pod
Pod 是运行在 Node 上的。一个 Node 是 Kubernetes 上的工作节点,它可能是虚拟出来的节点或者是物理节点,这取决于集群的部署方式。
每个 Node 节点都被 Master 节点所管理,一个 Node 节点可以运行多个 Pod,在集群中,Kubernetes Master 节点通过 Node 节点自动管理 Pods。
每个 Nodes 运行至少需要两个组件:
Kubelet:负责Master和Node之间的通信,用于管理节点上的Pod。Docker:负责从仓库拉取容器镜像,运行应用等。
如图:
二、操作Pod
Pod 和其他 Kubernetes 资源通过向 Kubernetes REST API 提供 JSON 或 YAML 描述文件来创建
编写YAML有4个重要组成部分:
apiVersion:YAML描述文件所使用的Kubernetes API版本kind:Kubernetes对象/资源类型metadata:Pod元数据(名称、命名空间、标签、注解等)spec:Pod规格/内容(容器列表、存储卷等)
-
查看
pods有哪些属性kubectl explain pods -
编写
nginx.yaml文件
此文件定义了一个名为
nginx的Pod,默认监听在 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
-
执行创建
podkubectl create -f nginx.yaml -
在
Pod列表查看新创建的Podkubectl get pods
Pod 在整个生命周期中存在各种状态,常见的状态如下图:
另外 Pod 的重启策略(RestartPolicy)有 3 种,分别为:
-
Always:默认策略,当容器失效时,kubelet会自动重启该容器 -
OnFailure:当容器终止运行且退出码不为 0 时,kubelet会自动重启该容器 -
Never:不论容器运行状态如何,kubelet都不重启该容器
- 查看日志
# pod 上只有一个容器
kubectl logs nginx
# pod 上有多个容器,需要指定参数 -c 容器名 进行查询
kubectl logs nginx -c nginx
- 测试
pod端口是否可用
# 执行端口转发,将本地 8080 端口转发到 nginx 80端口
kubectl port-forward nginx 8080:80
# 另起一个窗口,访问
curl http://localhost:8080
- 删除
Podkubectl 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)操作
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
-
创建
podkubectl create -f nginx-manual-with-labels.yaml -
查看
pod标签kubectl get pod --show-labels -
查看某个具体的标签
-Lkubectl get pod -L creation_method,rel -
修改标签
# 向 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)操作
-
想要筛选出所有手动创建的
Podkubectl get pod -l creation_method=manual -
列出含有
rel标签的所有podkubectl get pod -l rel -
列出不含
rel标签的所有podkubectl get pod -l '!rel' -
其他的使用方式
# 列出含有 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 指定对应的节点标签。
-
查看环境中节点情况
kubectl get nodes -
选择一个几点打上标签
kubectl label node kube-node-1 gpu=true -
查看是否打上标签
kubectl get nodes -l gpu=true -
新建名为
nginx-gpu的pod
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
- 创建
$ kubectl create -f nginx-gpu.yaml
pod/nginx-gpu created
五、命名空间 namespace
由于标签和
Pod是多对多的关系,使用标签可以将众多的Pod进行分组,这些组中的Pod有交叉重复的可能
使用 命名空间 就可以将对象分隔成完全独立且不重叠的组。
Kubernetes 的命名空间为对象名称提供了一个作用域。
对象名称只需要在一个命名空间内保持唯一,不同的命名空间可以包含同名的对象。
(1)操作
-
查看集群中所有的命名空间
kubectl get namespaces -
查看
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
- 创建新的命名空间
apiVersion: v1
kind: Namespace
metadata:
name: test1-namespace
- 执行创建
kubectl create -f test1-namespace.yaml
或者直接使用命令
kubectl create namespace test2-namespace
- 在新的命名空间中创建
Pod
- 在
yaml文件的metadata字段中添加namespace: test1-namespace属性 - 创建
Pod时在命令中使用参数-n指定命名空间
比如创建 pod 时候指定
$ kubectl create -f nginx-manual.yaml -n test1-namespace
pod/nginx-manual created