1 什么是 Pod
摘取官网: kubernetes.io/zh-cn/docs/…
1.1 简介
Pod 是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元。Pod(就像在鲸鱼荚或者豌豆荚中)是一组(一个或多个)容器; 这些容器共享存储、网络、以及怎样运行这些容器的声明。 Pod 中的内容总是并置(colocated)的并且一同调度,在共享的上下文中运行。简言之如果用 Docker 的术语来描述,Pod 类似于共享名字空间并共享文件系统卷的一组容器。
定义: Pod 就是用来管理一组(一个|多个)容器的集合 特点: 共享网络 共享存储 共享上下文环境
1.2 Pod 怎样管理多个容器?
一般将多个紧密协作
的容器放入到一个Pod中,当一个Pod包含多个容器时,这些容器总是运行于同一个工作节点上,一个pod绝不会跨多个工作节点。
Pod 中的容器被自动安排到集群中的同一物理机或虚拟机上,并可以一起进行调度。 容器之间可以共享资源和依赖、彼此通信、协调何时以及何种方式终止自身。例如,你可能有一个容器,为共享卷中的文件提供 Web 服务器支持,以及一个单独的 "边车 (sidercar)" 容器负责从远端更新这些文件。Pod多容器的使用常见场景
- 日志收集,通过log agent来上报日志信息
- sidecar模式,接管限流、降级等基础功能
- 功能辅助,本地调用等场景
pod内多个容器之间共享的部分:
- 网络命名空间: IP地址、端口范围、路由表....,同一Pod下容器不能绑定相同端口
- UTS命名空间: 主机名,同一Pod下容器拥有相同hostname
- IPC命名空间:UNIX域socket
由于共享端口空间,在同一pod的容器中运行的进程不能绑定到相同的端口号,而其他pod中的进程有自己的网络接口和端口空间,从而消除了不同pod之间的端口冲突。
pod内多个容器之间不共享的部分:
- 容器的文件系统(Mount Namespace)与其他容器完全隔离,但我们可以使用名为volume的Kubernetes资源来共享文件目录
- 容器的进程空间(PID Namespace)默认与其他容器完全隔离,不过可以设置POD的shareProcessNamespace这个值为true来进行共享
从图上我们可以看出 - Pod内的两个容器不能绑定同一端口
- 两容器共享同一网络空间
- 容器之间可以通过回环地址通信127.0.0.1
1.3 为什么"多容器的pod"要强于"单容器多进程"
- 容器只能管理PID=1的进程,这个进程是容器内(通过与PID Namespace隔离)所有进程的父进程
- 如果单容器运行多个进程,那么保持所有进程运行,管理它们的日志,就落到集群的肩上,比如需要包含一个进程崩溃时能自动重启的机制,因为容器只在根进程死亡时才会重启容器,而不在乎它创建哪些子进程
- 同时这些进程都将记录到相同的标准输出中,而因此我们将很难确定每个进程分别记录了什么
1.4 如何使用 Pod?
通常不需要直接创建 Pod,甚至单实例 Pod。 相反,一般会使用诸如 Deployment 或 Job 这类工作负载资源来创建 Pod。 如果 Pod 需要跟踪状态,可以考虑 StatefulSet 资源,将在之后学习这些资源。
Kubernetes 集群中的 Pod 主要有两种用法:
- 运行单个容器的 Pod。"每个 Pod 一个容器" 模型是最常见的 Kubernetes 用例; 在这种情况下,可以将 Pod 看作单个容器的包装器,并且 Kubernetes 直接管理 Pod,而不是容器。
- 运行多个协同工作的容器 的 Pod。 Pod 可能封装由多个紧密耦合且需要共享资源的共处容器组成的应用程序。 这些位于同一位置的容器可能形成单个内聚的服务单元 —— 一个容器将文件从共享卷提供给公众, 而另一个单独的 “边车”(sidecar)容器则刷新或更新这些文件。 Pod 将这些容器和存储资源打包为一个可管理的实体。
说明:
- 将多个并置、同管的容器组织到一个 Pod 中是一种相对高级的使用场景。 只有在一些场景中,容器之间紧密关联时你才应该使用这种模式。
- 每个 Pod 都旨在运行给定应用程序的单个实例。如果希望横向扩展应用程序 (例如,运行多个实例以提供更多的资源),则应该使用多个 Pod,每个实例使用一个 Pod。 在 Kubernetes 中,这通常被称为副本(Replication)。 通常使用一种工作负载资源及其控制器来创建和管理一组 Pod 副本。
2 Pod 基本操作
2.1 查看 pod
# 查看默认命名空间的 pod
$ kubectl get pods|pod|po
# 查看所有命名空间的 pod
$ kubectl get pods|pod -A
$ kubectl get pods|pod|po -n 命名空间名称
# 查看默认命名空间下 pod 的详细信息
$ kubectl get pods -o wide
# 查看所有命名空间下 pod 的详细信息
$ kubectl get pods -o wide -A
# 实时监控 pod 的状态
$ kubectl get pod -w
2.2 创建 pod
pod : kubectl run nginx(pod名称) --image=nginx:1.19
container: docker run --name nginx nginx:1.19
官网参考地址: kubernetes.io/zh-cn/docs/…
# nginx-pod.yml
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.19
ports:
- containerPort: 80
# 使用 kubectl apply/create -f 创建 pod
$ kubectl create -f nginx-pod.yml
$ kubectl apply -f nginx-pod.yml
注意: create 仅仅是不存在时创建,如果已经存在则报错!apply 不存在创建,存在更新配置。推荐使用 apply!
2.3 删除 pod
$ kubectl delete pod pod名称
$ kubectl delete -f pod.yml
2.4 进入 pod 中容器
# 注意: 这种方式进入容器默认只会进入 pod 中第一个容器
$ kubectl exec -it nginx(pod名称) --(固定写死) bash(执行命令)
# 注意: 进入指定 pod 中指定容器
$ kubectl exec -it pod名称 -c 容器名称 --(固定写死) bash(执行命令)
2.5 查看 pod 日志
# 注意: 查看 pod 中第一个容器日志
$ kubectl logs -f(可选,实时) nginx(pod 名称)
# 注意: 查看 pod 中指定容器的日志
$ kubect logs -f pod名称 -c 容器名称
2.6 查看 pod 描述信息
$ kubectl describe pod nginx(pod名称)
3 Pod 运行多个容器
3.1 创建 pod
# myapp-pod.yml
apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
containers:
- name: nginx
image: nginx:1.19
ports:
- containerPort: 80
imagePullPolicy: IfNotPresent
- name: redis
image: redis:5.0.10
ports:
- containerPort: 6379
imagePullPolicy: IfNotPresent
$ kubectl apply -f myapp-pod.yml
3.2 查看指定容器日志
# 查看日志 (默认只查看第一个容器日志,这里是展示 nginx 日志)
$ kubectl logs -f myapp
# 查看 pod 中指定容器的日志
$ kubectl logs -f myapp -c nginx(容器名称)
$ kubectl logs -f myapp -c redis(容器名称)
3.3 进入容器
# 进入 pod 的容器 (默认进入第一个容器内部,这里会进入 nginx 容器内部)
$ kubectl exec -it myapp -- sh
# 进入 pod 中指定容器内部
$ kubectl exec -it myapp -c nginx -- sh
$ kubectl exec -it myapp -c redis -- sh
4 Pod 的 Labels(标签)
对于微服务架构,部署的微服务数量可以超过20个,这些组件可以是副本和多个不同发布版本,如果没有有效组织这些组件的机制,将会导致产生巨大混乱,因此Kubernetes 对象可附加标签属性。
标签(Labels)
是附加到 Kubernetes 对象(比如 Pod)上的键值对。 标签旨在用于指定对用户有意义且相关的对象的标识属性。标签可以在创建时附加到对象,随后可以随时添加和修改。每个对象都可以定义一组键(key)/值(value)标签,但是每个键(key)对于给定对象必须是唯一的。
标签作用: 用来给 k8s 中对象起别名, 有了别名可以方便过滤和筛选
4.1 语法
标签由键值对组成
,其有效标签值:
- 必须为 63 个字符或更少(可以为空)
- 除非标签值为空,必须以字母数字字符(
[a-z0-9A-Z]
)开头和结尾 - 包含破折号(
-
)、下划线(_
)、点(.
)和字母或数字
4.2 示例
apiVersion: v1
kind: Pod
metadata:
name: myapp
labels:
name: myapp #创建时添加
spec:
containers:
- name: nginx
image: nginx:1.21
imagePullPolicy: IfNotPresent
- name: redis
image: redis:5.0.10
imagePullPolicy: IfNotPresent
restartPolicy: Always
4.3 标签基本操作
# 查看标签
$ kubectl get pods --show-labels
# kubectl label pod pod名称 标签键值对
$ kubectl label pod myapp env=prod
# 覆盖标签 --overwrite
$ kubectl label --overwrite pod myapp env=test
# 删除标签 -号代表删除标签
$ kubectl label pod myapp env-
# 根据标签筛选 env=test/env > =