k8s (二) pod: 运行于 Kubernetes 中的容器
pod 是一组并置的容器,代表了 Kubernetes 中的基本构建模块。在实际应用中我们并不会单独部署容器,更多的是针对一组 pod 的容器进行部署和操作。然而这并不意味着一个 pod 总是要包含多个容器:实际上只包含一个单独容器的 pod 也是非常常见的。值得注意的是,当一个 pod 包含多个容器时,这些容器总是运行于同一个工作节点上,一个 pod 绝不会跨越多个工作节点:
使用 pod 而不是直接使用容器的优点:同一 pod 中容器之间的部分隔离
一、使用 YAML 或 JSON 描述文件创建 pod
可以使用下面命令,查看上一篇文章通过命令创建的 pod 的 YAML 描述文件:kubectl get pods hello-minikube-6895494d6d-wsfmx -o yaml
1.1. 创建 pod 的 YAML 描述文件
kubia-manual.yaml:
apiVersion: v1 # Kubernetes API 版本
kind: Pod # Kubernetes 对象/资源类型
metadata:
name: kubia-manual # pod 的名称
spec:
containers:
- image: luksa/kubia
name: kubia # 容器的名称
ports:
- containerPort: 8080 # 应用监听的端口
protocol: TCP
1.2. 创建 pod
kubectl create -f kubia-manual.yaml
kubectl create -f 命令用于从 YAML 或 JSON 文件创建任何资源(不只是 pod)
查看 pod 的完整描述文件:kubectl get pod kubia-manual -o yaml
1.3. 查看应用程序日志
kubectl logs kubia-manual
kubectl logs kubia-manual -c kubia # 如果 pod 包含多个容器,可以显示指定容器名称
1.4. 向 pod 发送请求
可以使用上一篇文章中的 kubectl expose 创建一个 service,也可以通过端口转发:kubectl port-forward kubia-manual 8888:8080
可以在本地使用端口 8888 访问程序
遇到的报错:unable to do port forwarding: socat not found
yum install -y socat
二、标签
通过标签来组织 pod 和所有其他 Kubernetes 对象(一个资源可以拥有多个标签),可以通过一次操作对属于某个组的所有 pod 进行操作,而不必单独为每个 pod 执行操作。
2.1. 创建 pod 时指定标签
kubia-manual-with-labels.yaml:
apiVersion: v1 kind: Pod metadata: name: kubia-manual-v2 labels: creation_method: manual # 标签 1 env: prod # 标签 2 spec: containers: - image: luksa/kubia name: kubia ports: - containerPort: 8080 protocol: TCP
创建 pod:
kubectl create -f kubia-manual-with-labels.yaml
查看 pod 的标签:kubectl get pods --show-labels
2.2. 修改现有 pod 的标签
添加:
kubectl label pod kubia-manual creation_method=manual
修改(需要使用 —overwrite 选项):kubectl label pod kubia-manual-v2 env=debug --overwrite
2.3. 标签选择器
kubectl get pods -l creation_method=manual # 包含 creation_method=manual kubectl get pods -l env # 包含 env 标签 kubectl get pods -l '!env' # 不包含 env 标签 kubectl get pods -l creation_method!=manual # 不包含 creation_method=manual kubectl get pods -l creation_method=manual,env=debug # 包含 creation_method=manual,env=debug
三、命名空间
在使用多个命名空间的前提下,我们可以将包含大量组件的复杂系统拆分为更小的不同组,这些不同组也可以用于在多租户环境中分配资源,将资源分配为生产、开发和 QA 环境,或者以其他任何你需要的方式分配资源。资源名称只需在命名空间内保持唯一即可,因此两个不同的命名空间可以包含同名的资源。大多数类型的资源都与命名空间相关,但也有一些例外,例如,全局且未被约束于单一命名空间的节点资源。
查看集群中所有命名空间列表:kubectl get namespaces # namespaces 可以缩写为 ns
可以看到有个名为 default 的命名空间,我们之前的操作都是在这个命名空间,之前使用 kubectl get 时未明确指定命名空间,因此 kubectl 总是默认为 default 命名空间,只显示该命名空间下的对象。指定命令空间:kubectl get pods --namespace kube-system # --namespace 可以使用 -n 代替
命名空间使我们能够将不属于一组的资源分到不重叠的组中。如果有多个用户或用户组正在使用同一个 Kubernetes 集群,并且它们都各自管理自己独特的资源集合,那么它们就应该分别使用各自的命名空间。这样一来,它们就不用特别担心无意中修改或删除其他用户的资源,也无须关心名称冲突。3.1. 创建命名空间
方法一:
custom-namespace.yaml:apiVersion: v1 kind: Namespace metadata: name: custom-namespace
kubectl create -f custom-namespace.yaml
方法二:kubectl create namespace custom-namespace
命名空间名字中不能包含点号3.2. 管理其他命名空间中的对象
如果想要在上面创建的命名空间中创建资源,可以在 metadata 字段中添加 namespace: custom-namespace 属性,也可以创建资源时指定命名空间:
kubectl create -f kubia-manual.yaml -n custom-namespace
此时我们有两个重名的 pod(kubia-manual),一个在 default 命名空间,一个在 custom-namespace 命名空间
需要注意的是:尽管命名空间将对象分隔到不同的组,只允许你对属于特定命名空间的对象进行操作,但实际上命名空间之间并不提供对正在运行的对象的任何隔离。例如,你可能会认为当不同的用户在不同的命名空间中部署 pod 时,这些 pod 应该彼此隔离,并且无法通信,但事实并非如此。命名空间之间是否提供网络隔离取决于 Kubernetes 所使用的网络解决方案。当该解决方案不提供命名空间间的网络隔离时,如果命名空间 foo 的某个 pod 知道命名空间 bar 中 pod 的 IP 地址,那它就可以将流量(例如 HTTP 请求)发送到另一个 pod。四、停止和移除 pod
kubectl delete pod kubia-manual-v2 # 按照名字删除 kubectl delete pod -l creation_method=manual # 按照标签删除 kubectl delete ns custom-namespace # 通过删除整个命名空间来删除 kubectl delete pod --all # 删除命名空间中的所有 pod,但保留命名空间: all 代表所有实例 kubectl delete all --all # 删除命名空间中的(几乎)所有资源:第一个 all 代表所有资源类型,第二个 all 代表所有实例