深入解读核心资源Pod

一、Pod 概念

Pod是Kubernetes中最小的调度单位,是一组容器的集合,Pod中的容器共享网络和存储资源,Pod中的容器可以通过localhost进行通信,Pod中的容器可以通过共享的Volume进行数据共享。

k8s 是通过定义一个 Pod 的资源,然后再 Pod 里面运行容器,容器需要指定一个镜像,这样就可以用来运行具体的服务。

pod架构

Pod 需要调度到k8s集群的工作节点来运行,具体的调度过程是由 kube-scheduler 组件来完成的,kube-scheduler 会根据 Pod 的资源需求和节点的资源容量,选择一个合适的节点来运行 Pod。

1、Pod 如何管理多个容器

Pod 中可以同时运行多个容器。

  • 同一个Pod中的容器会自动分配到同一个工作节点上
  • 同一个Pod中的容器共享资源、网络环境
  • 同一个Pod中的容器可以通过localhost进行通信
  • 同一个Pod中的容器总是被同时调度

只有当你的容器需要紧密配合协作的时候才考虑用这种模式。如果你的容器需要独立扩展,或者你的容器需要被不同的团队管理,那么你应该把它们放到不同的 Pod 中。

一些 Pod 有 init 容器和应用容器,init 容器会先于应用容器启动,init 容器会一直运行直到它们成功完成为止。如果 init 容器失败,Pod 会被重新启动,直到 init 容器成功为止。

2、Pod 网络

Pod 是有 IP 地址的,每个 pod 都被分配唯一的 IP 地址(IP地址靠网络插件calico、flannel、canal、weave等实现),Pod 中的容器共享网络命名空间,包括IP地址和网络端口。

  • Pod 内部的容器可以通过 localhost 相互通信。
  • Pod 中的容器也可以通过网络插件calico 与其他节点上的 Pod 进行通信。

3、Pod 存储

创建 Pod 的时候可以指定挂载的存储卷。

  • Pod 中的所有容器都可以访问这个存储卷,允许容器之间共享数据
  • 这个存储卷的生命周期与 Pod 的生命周期相同
  • Pod 只要挂载持久化数据卷,重启后数据不会丢失
  • Pod 可以挂载多个存储卷

4、Pod 工作方式

在K8S中,所有的资源都可以使用一个 yaml 文件来创建,Pod 也不例外,下面是一个 Pod 的 yaml 文件示例:

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
    app: nginx
spec:
  containers:
  - name: nginx-container
    image: nginx
    ports:
    - containerPort: 80

或者使用 kubectl run 命令来创建 Pod:

kubectl run nginx-pod --image=nginx --restart=Never --port=80

Pod 的 yaml 文件中,有几个重要的字段:

  • apiVersion:指定 Pod 的 API 版本,一般都是 v1
  • kind:指定资源类型,Pod 的类型是 Pod
  • metadata:指定 Pod 的元数据,包括 Pod 的名称、标签等
  • spec:指定 Pod 的规格,包括 Pod 中的容器、存储卷等

Pod 的 yaml 文件中,spec 字段是最重要的,它包含了 Pod 中的容器、存储卷等信息,下面是 spec 字段的详细介绍:

spec:
  containers: # 容器列表
  - name: nginx-container # 容器名称
    image: nginx # 容器镜像
    ports: # 容器端口列表
    - containerPort: 80 # 容器端口
  restartPolicy: Never # Pod 重启策略

Pod 的 yaml 文件中,spec 字段中的 containers 字段是一个容器列表,可以在一个 Pod 中运行多个容器,这些容器会被同时调度到同一个工作节点上。

Pod 的 yaml 文件中,spec 字段中的 restartPolicy 字段是 Pod 的重启策略,它有三个取值:

  • Always:Pod 一旦终止就立即重启,用于部署应用
  • OnFailure:Pod 只有在非零退出码时才重启,用于批处理任务
  • Never:Pod 不重启,用于静态 Web 网站

Pod 的 yaml 文件中,spec 字段中的 nodeName 字段是 Pod 的调度节点,如果指定了 nodeName 字段,那么 Pod 就会被调度到指定的节点上,如果没有指定 nodeName 字段,那么 Pod 就会被调度到一个合适的节点上。

(1)自主式 Pod

自主式 Pod 是指没有被任何控制器管理的 Pod,它的生命周期由用户手动管理,一般用于测试和开发环境。示例如下:

[root@master tomcat-test]# vim pod-tomcat.yaml
apiVersion: v1
kind: Pod
metadata:
  name: tomcat-test
  namespace: default
  labels:
    app: tomcat
spec:
  containers:
  - name: tomcat-java
    ports:
    - containerPort: 8080
    image: xianchao/tomcat-8.5-jre8:v1
    imagePullPolicy: IfNotPresent

# 导入镜像,且发送文件给node
[root@master tomcat-test]# scp xianchao-tomcat.tar.gz root@10.104.43.118:/root/
# 将镜像导入到本地
[root@master tomcat-test]# docker load -i xianchao-tomcat.tar.gz
[root@node ~]# docker load -i xianchao-tomcat.tar.gz
df64d3292fd6: Loading layer [==================================================>]  4.672MB/4.672MB
0c3170905795: Loading layer [==================================================>]  3.584kB/3.584kB
9bca1faaa73e: Loading layer [==================================================>]  79.44MB/79.44MB
e927085edc33: Loading layer [==================================================>]   2.56kB/2.56kB
e5f8376fd9dc: Loading layer [==================================================>]  27.08MB/27.08MB
e82a3681bb38: Loading layer [==================================================>]  2.048kB/2.048kB
Loaded image: xianchao/tomcat-8.5-jre8:v1

# 查看镜像
[root@master tomcat-test]# docker images 
REPOSITORY                          TAG            IMAGE ID       CREATED         SIZE
xianchao/tomcat-8.5-jre8            v1             4ac473a3dd92   4 years ago     108MB

# 更新资源清单文件
[root@master tomcat-test]# kubectl apply -f pod-tomcat.yaml
pod/tomcat-test created

# 查看 Pod 是否创建成功
[root@master tomcat-test]# kubectl get pods -o wide -l app=tomcat
NAME          READY   STATUS        IP          NODE   
tomcat-test   1/1     Running     10.244.1.13   node   
# 查看 Pod 详情
[root@master tomcat-test]# kubectl describe -f pod-tomcat.yaml

# 注意:
# 自主式Pod是可以删除的,而且一旦被删除是彻底删除。
# 这在生产环境具有非常大风险,因此要应该选择使用控制器管理。
[root@master tomcat-test]# kubectl delete -f pod-tomcat.yaml 
pod "tomcat-test" deleted
[root@master tomcat-test]# kubectl get pods -o wide -l app=tomcat
No resources found in default namespace.

(2)控制器管理的 Pod

常见的管理 Pod 的控制器:Replicaset、Deployment、Job、CronJob、Daemonset、Statefulset。

控制器管理的 Pod 可以确保 Pod 始终维持在指定的副本数运行。通过 Deployment 管理 pod 案例:

# 上传xianchao-nginx.tar.gz 上传到node节点
[root@node ~]# ls
anaconda-ks.cfg  install.sh  original-ks.cfg  xianchao-nginx.tar.gz

# 创建资源清单文件
[root@master ~]# mkdir nginx-test && cd nginx-test
[root@master nginx-test]# vi nginx-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-test
  labels:
    app: nginx-deploy
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: my-nginx
        image: nginx
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80

# 更新资源清单文件
[root@master nginx-test]# kubectl apply -f nginx-deploy.yaml 
deployment.apps/nginx-test created

# 查看deployment
[root@master nginx-test]# kubectl get deploy -l app=nginx-deploy
NAME         READY   UP-TO-DATE   AVAILABLE   AGE
nginx-test   2/2     2            2           87s

# 查看replicaset
[root@master nginx-test]# kubectl get rs -l app=nginx
NAME                    DESIRED   CURRENT   READY   AGE
nginx-test-854985cc6f   2         2         2       2m11s

# 查看pod
[root@master nginx-test]# kubectl get pods -o wide -l app=nginx
NAME                          READY   STATUS    RESTARTS   AGE     IP             NODE     NOMINATED NODE   READINESS GATES
nginx-test-854985cc6f-9qnnj   1/1     Running   0          2m56s   10.244.1.18    node     <none>           <none>
nginx-test-854985cc6f-fw55w   1/1     Running   0          2m56s   10.244.0.250   master   <none>           <none>

# 查看deployment详情
[root@master nginx-test]# kubectl describe deploy nginx-test

# 删除nginx-test-854985cc6f-9qnnj这个Pod
[root@master nginx-test]# kubectl delete pod nginx-test-854985cc6f-9qnnj
pod "nginx-test-854985cc6f-9qnnj" deleted
# 发现重新创建了一个新的pod
[root@master nginx-test]# kubectl get pods -o wide -l app=nginx
NAME                          READY   STATUS    RESTARTS   AGE     IP             NODE     NOMINATED NODE   READINESS GATES
nginx-test-854985cc6f-dfm5b   1/1     Running   0          6s      10.244.1.19    node     <none>           <none>
nginx-test-854985cc6f-fw55w   1/1     Running   0          4m10s   10.244.0.250   master   <none>           <none>

由此可见,通过 deployment 管理的 pod,当 pod 被删除后,会自动创建一个新的 pod,保证 pod 的副本数始终维持在指定副本数量。

二、如何创建一个Pod资源

k8s创建pod流程:
k8s创建pod流程

Pod 是 Kubernetes 中最基本的部署调度单位,可以包含 container,逻辑上表示某种应用的一个实例。如:一个web站点应用由前端、后端、数据库构建而成,这个站点的所有容器可以放在一个 Pod 中,也可以将前端、后端、数据库分别放在不同的 Pod 中,这取决于用户的实际需求。

1、创建 pod 流程

创建 pod 流程

第一步:用户通过 kubectl 命令或者 API Server 发送创建 Pod 的请求。
第二步:apiserver 接收到请求后,将 yaml 文件转换成 json 格式,然后将 json 格式的 Pod 对象存储到 etcd 中。
第三步:apiserver 将 Pod 对象转发给控制器管理器。调度器使用调度算法为 Pod 选择合适的 Node 节点,将node信息给apiserver,apiserver将node信息存储到etcd中。

  • 调度器的调度算法:
    • 1、过滤器:过滤掉不符合要求的节点,如:资源不足、污点、亲和性等。
    • 2、优选器:对符合要求的节点进行打分,选择分数最高的节点。
      第四步:apiserver 通过 watch 机制,调用 kebelet,指定 pod 信息,调用 docker api 在 node 节点上创建 pod。
      第五步:创建完成后反馈给 kubelet,kubelet 又将pod的状态信息反馈给 apiserver,apiserver 将 pod 的状态信息存储到 etcd 中。

2、资源清单yaml文件书写技巧

yaml文件书写技巧:

  • 1、yaml文件中的空格不能随意添加,否则会报错。
  • 2、yaml文件中的缩进必须是两个空格,不能是tab键。
  • 3、yaml文件中的注释必须是#号开头。
  • 4、yaml文件中的字符串必须加上引号,否则会报错。
  • 5、yaml文件中的字符串如果有特殊字符,必须加上单引号或者双引号,否则会报错。
  • 6、yaml文件中的字符串如果有多行,必须使用|或者>,否则会报错。

编写yaml文件遇到字段含义不明确时,可以使用kubectl explain命令查看字段的含义。

(1)kubectl explain 命令

kubelet explain 命令可以查看资源清单文件中的字段的含义。

# kubelet explain 语法
[root@master ~]# kubectl explain -h
List the fields for supported resources.   # 列出支持的资源的字段

 This command describes the fields associated with each supported API resource. Fields are identified via a simple JSONPath identifier:  # 该命令描述与每个支持的API资源相关联的字段。字段通过简单的JSONPath标识符进行标识:

  <type>.<fieldName>[.<fieldName>]
  
 Add the --recursive flag to display all of the fields at once without descriptions. Information about each field is retrieved from the server in OpenAPI format.    # 添加--recursive标志以一次显示所有字段而无需描述。有关每个字段的信息以OpenAPI格式从服务器检索。

Use "kubectl api-resources" for a complete list of supported resources. # 使用“kubectl api-resources”获取支持的资源的完整列表。

Examples:
  # 获取资源及其字段的文档
  kubectl explain pods
  
  # 获取资源的特定字段的文档
  kubectl explain pods.spec.containers

Options:
    --api-version='': 获取特定API版本(API组/版本)的不同解释
    --recursive=false: 打印字段的字段(目前只有1级深)

查看pod的字段,示例如下所示:

[root@master ~]# kubectl explain pods
KIND:     Pod    # 资源类型
VERSION:  v1     # 资源版本

DESCRIPTION:     # 描述
    Pod是可以在主机上运行的容器集合。此资源由客户端创建并安排到主机上。

FIELDS:          # 字段
   apiVersion	<string>    # api版本
     APIVersion定义此对象的版本化模式。服务器应将已识别的模式转换为最新的内部值,并且可以拒绝未识别的值。

   kind	<string>          # 字符串类型的值,代表要创建的资源类型
     Kind是表示此对象表示的REST资源的字符串值.服务器可以从客户端提交请求的端点推断此值。不能更新。在CamelCase中。

   metadata	<Object>      # metadata是对象,定义元数据属性信息
     标准对象的元数据

   spec	<Object>          # 制定了定义pod的规格,里面包含容器的信息
     Pod的期望行为的规范。 

   status	<Object>        # 状态,不可修改,定义pod时不需要填写
     最近观察到的Pod的状态。这些数据可能不是最新的。状态字段,由系统填充,只读。

查看pod.metadata的字段,示例如下所示:

[root@master ~]# kubectl explain pods.metadata
KIND:     Pod        # 资源类型
VERSION:  v1         # 资源版本
RESOURCE: metadata <Object>   # 资源为 metadata 对象<object>
DESCRIPTION:
     标准对象的元数据
     ObjectMeta是所有持久化资源必须具有的元数据,其中包括用户必须创建的所有对象。
FIELDS:              # 字段
   annotations	<map[string]string>     # annotations是注解,map类型表示对应值是键值对
     注释是存储在资源中的非结构化键值映射,可以由外部工具设置以存储和检索任意元数据。它们不可查询,并且在修改对象时应该保留。

   creationTimestamp	<string>
     创建时间戳是表示创建此对象时的服务器时间的时间戳。不能保证在单独操作中以发生之前的顺序设置它。客户端可能不会设置此值。它以RFC3339形式表示,并且处于UTC中。可以设置为任何时间,但一旦设置,就不能更改。只读。

   deletionGracePeriodSeconds	<integer>
      此对象在从系统中删除之前允许优雅终止的秒数。仅在设置deletionTimestamp时设置。可能只缩短。只读。

   deletionTimestamp	<string>  # 删除时间戳
     删除时间戳是表示删除此对象时的服务器时间的时间戳。如果未设置,则此对象尚未删除。只读。

   finalizers	<[]string>   # finalizers是终结器,[]string表示对应值是字符串数组
     终结器是在删除对象时运行的一组非同步任务。在删除对象时,系统会阻止对该对象的修改,直到所有终结器都已完成。终结器可能会以任何顺序运行。系统不会保证它们将在删除操作完成之前运行,或者将在删除操作完成之后运行。终结器可能会在删除操作完成之前或之后失败。终结器是在删除操作完成之前运行的,因此它们可以在删除操作完成之前阻止对象的删除。失败的终结器可能会在下一次删除操作中重新运行。终结器通常用于将群集外部的资源与Kubernetes对象关联起来,以便在删除对象时清理这些资源。

   generateName	<string>
     生成名称是服务器使用的可选前缀,仅在未提供名称字段时生成唯一名称。如果使用此字段,则返回给客户端的名称将与传递的名称不同。此值还将与唯一后缀组合。提供的值具有与名称字段相同的验证规则,并且可能会被所需的后缀的长度截断,以使该值在服务器上唯一。  

   generation	<integer>
     表示所需状态的特定生成的序列号。由系统填充,只读。

   labels	<map[string]string>
     标签是一组键值对,用于组织和分类对象. 可以与复制控制器和服务的选择器匹配。

   managedFields	<[]Object>
     管理字段将工作流ID和版本映射到由该工作流管理的字段集。这主要用于内部事务处理,用户通常不需要设置或了解此字段。工作流可以是用户的名称,控制器的名称,或者特定应用程序路径的名称,例如“ci-cd”。字段集始终在工作流修改对象时使用的版本中。

   name	<string>
     名称必须在命名空间内唯一。在创建资源时是必需的,尽管某些资源可能允许客户端自动请求生成适当的名称。名称主要用于创建幂等性和配置定义。不能更新。

   namespace	<string>
     命名空间定义了每个名称必须唯一的空间。空命名空间等同于“默认”命名空间,但“默认”是规范表示。并非所有对象都必须限定于命名空间 - 这些对象的此字段的值将为空。

   ownerReferences	<[]Object>
     依赖的对象列表。如果列表中的所有对象都已删除,则将对此对象进行垃圾回收。如果此对象由控制器管理,则列表中的条目将指向此控制器,其中控制器字段设置为true。不能有多个管理控制器。

   resourceVersion	<string>
     资源版本,用于乐观锁,客户端不需要修改,只读

   selfLink	<string>
     selfLink是一个遗留的只读字段,不再由系统填充。

   uid	<string>
     UID是此对象的时间和空间唯一值。通常由服务器在成功创建资源时生成,并且不允许在PUT操作上更改。客户端可以使用此值确定是否已替换服务器上的对象。不能更新。更多信息请参见类型元数据。

3、通过资源清单文件创建pod

# 导入镜像
[root@node ~]# ls
anaconda-ks.cfg  install.sh  original-ks.cfg  xianchao-nginx.tar.gz  xianchao-tomcat.tar.gz
[root@node ~]# ctr -n k8s.io images import xianchao-tomcat.tar.gz 
unpacking docker.io/xianchao/tomcat-8.5-jre8:v1 (sha256:14dae4798a335e2925e4ee07b3ccd519a67faab2a9155adeb76a4556478dd8d7)...done

# 查看镜像
[root@node ~]# ctr -n k8s.io images list | grep tomcat
docker.io/xianchao/tomcat-8.5-jre8:v1                                                                                      application/vnd.docker.distribution.manifest.v2+json      sha256:14dae4798a335e2925e4ee07b3ccd519a67faab2a9155adeb76a4556478dd8d7 106.1 MiB linux/amd64                                                                                             io.cri-containerd.image=managed

# 创建pod资源清单文件
[root@master tomcat-test]# vi pod-tomcat.yaml
apiVersion: v1
kind: Pod
metadata:
  name: tomcat-test
  namespace: default
  labels:
    app: tomcat-pod-first
spec:
  containers:
  - name: tomcat-first
    image: xianchao/tomcat-8.5-jre8:v1
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 8080

# 更新资源清单文件
[root@master tomcat-test]# kubectl apply -f pod-tomcat.yaml

# 查看pod是否创建成功
[root@master tomcat-test]# kubectl get pods -o wide -l app=tomcat-pod-first
NAME          READY   STATUS    RESTARTS   AGE   IP            NODE   NOMINATED NODE   READINESS GATES
tomcat-test   1/1     Running   0          5s    10.244.1.25   node   <none>           <none>

# 查看pod日志
[root@master tomcat-test]# kubectl logs tomcat-test
06-Jul-2023 04:22:44.695 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version:        Apache Tomcat/8.5.34
06-Jul-2023 04:22:44.699 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server built:          Sep 4 2018 22:28:22 UTC
06-Jul-2023 04:22:44.699 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server number:         8.5.34.0
06-Jul-2023 04:22:44.699 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Name:               Linux
...略
06-Jul-2023 04:22:45.833 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["ajp-nio-8009"]
06-Jul-2023 04:22:45.837 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 886 ms

# 进入刚刚创建的Pod
[root@master tomcat-test]# kubectl exec -ti tomcat-test /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
bash-4.4# ls
BUILDING.txt     LICENSE          README.md        RUNNING.txt      conf             lib              native-jni-lib   webapps
CONTRIBUTING.md  NOTICE           RELEASE-NOTES    bin              include          logs             temp             work

# 架设pod有多个容器时,可以指定容器名称
[root@master tomcat-test]# kubectl exec -it tomcat-test -c tomcat-first /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
bash-4.4# cat /etc/resolv.conf 
search default.svc.cluster.local svc.cluster.local cluster.local openstacklocal
nameserver 10.96.0.10
options ndots:5

4、通过命令行创建pod

kubectl run 命令可以直接创建pod,但是不推荐使用,因为它创建的pod没有资源限制,也没有标签,不利于管理。

(1)kubectl run语法

[root@master tomcat-test]# kubectl run -h
Create and run a particular image in a pod.

Examples:
  # Start a nginx pod:通过镜像创建pod
  kubectl run nginx --image=nginx
  
  # Start a hazelcast pod and let the container expose port 5701:通过镜像创建pod,并指定容器暴露端口5701
  kubectl run hazelcast --image=hazelcast/hazelcast --port=5701
  
  # Start a hazelcast pod and set environment variables "DNS_DOMAIN=cluster" and "POD_NAMESPACE=default" in the container:通过镜像创建pod,并指定容器环境变量
  kubectl run hazelcast --image=hazelcast/hazelcast --env="DNS_DOMAIN=cluster" --env="POD_NAMESPACE=default"
  
  # Start a hazelcast pod and set labels "app=hazelcast" and "env=prod" in the container:通过镜像创建pod,并指定容器标签
  kubectl run hazelcast --image=hazelcast/hazelcast --labels="app=hazelcast,env=prod"
  
  # Dry run; print the corresponding API objects without creating them:通过镜像创建pod,但是不创建pod,只打印pod的配置信息
  kubectl run nginx --image=nginx --dry-run=client
  
  # Start a nginx pod, but overload the spec with a partial set of values parsed from JSON:通过镜像创建pod,并指定pod的配置信息
  kubectl run nginx --image=nginx --overrides='{ "apiVersion": "v1", "spec": { ... } }'
  
  # Start a busybox pod and keep it in the foreground, don't restart it if it exits:通过镜像创建pod,并指定pod的配置信息,但是不重启pod
  kubectl run -i -t busybox --image=busybox --restart=Never
  
  # Start the nginx pod using the default command, but use custom arguments (arg1 .. argN) for that command:通过镜像创建pod,并指定容器的启动参数
  kubectl run nginx --image=nginx -- <arg1> <arg2> ... <argN>
  
  # Start the nginx pod using a different command and custom arguments:通过镜像创建pod,并指定容器的启动命令和启动参数
  kubectl run nginx --image=nginx --command -- <cmd> <arg1> ... <argN>

Options:
    --allow-missing-template-keys=true: 如果为true,则忽略模板中缺少字段或映射键时的任何错误。仅适用于golang和jsonpath输出格式。
    --annotations=[]: 会应用到pod上的注解
    --attach=false: 如果为true,则等待Pod开始运行,然后附加到Pod,就像调用“kubectl attach ...”一样。默认为false。
    --cascade=true: 仅在-i/--stdin设置时默认为false,否则默认为true。如果--restart=Never,则返回容器进程的退出代码。
    --command=false: 如果为true并且存在额外的参数,则将它们用作容器中的“command”字段,而不是默认的“args”字段。
    --dry-run='none': 必须为none、server或client,如果为client,则只打印pod的配置信息,不创建pod。仅在--dry-run=server时有效,如果为true,则不会将pod持久化到etcd中。
    --env=[]: 为容器设置环境变量
    --expose=false: 如果为true,则创建一个与pod关联的ClusterIP服务。需要--port参数。
    --field-manager='kubectl-run': 用于跟踪字段所有权的管理器的名称。
    --image='': 指定容器镜像
    --image-pull-policy='': 指定镜像拉取策略,如果不指定,则由服务器决定
    -l, --labels='': 为pod指定标签,如果pod已经存在,则会覆盖之前的标签
    --leave-stdin-open=false: 如果pod以交互模式或stdin启动,则在第一次附加完成后保留stdin打开。默认情况下,stdin将在第一次附加完成后关闭。
    -o, --output='': 指定输出格式. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file). 
    --override-type='merge': merge和strategic都是合并,但是strategic可以指定字段的合并策略
    --overrides='': 通过json格式的字符串指定pod的配置信息
    --pod-running-timeout=1m0s: 等待pod运行的时间(like 5s, 2m, or 3h, higher than zero)
    --port='': 指定容器暴露的端口
    --privileged=false: 如果为true,则以特权模式运行容器。
    -q, --quiet=false: 如果为true,则不会打印提示信息
    --restart='Always': pod重启策略(Always, OnFailure, Never)
    --rm=false: 如果为true,则在pod退出后删除pod。仅在附加到容器时有效,例如使用“--attach”或“-i / --stdin”。
    --save-config=false: 保存pod的配置信息到pod的注解中,方便后续使用kubectl apply 命令更新pod的配置信息
    --show-managed-fields=false: 如果为true,则在打印JSON或YAML格式的对象时保留managedFields。
    -i, --stdin=false: 保持容器的stdin打开,即使没有附加到容器上
    --template='': 模板字符串或模板文件的路径,用于-o = go-template,-o = go-template-file。
    -t, --tty=false: 为pod中的容器分配一个TTY

(2)kubectl run创建pod

[root@master tomcat-test]# kubectl run tomcat-test --image=xianchao/tomcat-8.5-jre8:v1 --port=8080 --image-pull-policy=IfNotPresent
pod/tomcat-test created
[root@master tomcat-test]# kubectl get pod
NAME          READY   STATUS    RESTARTS   AGE
tomcat-test   1/1     Running   0          15s
# 删除pod
[root@master tomcat-test]# kubectl delete pod tomcat-test
pod "tomcat-test" deleted

三、命名空间

1、命名空间简介

Kubernetes 支持多个虚拟集群,底层依赖于同一个物理集群,这些虚拟集群被称为命名空间。

命名空间 namespace 是 k8s 集群级别的资源,可以用来为同一个集群中的多个用户、多个项目或多个团队分配集群资源。例如,可以为开发、测试和生产环境分别创建不同的命名空间,这样可以更好地隔离不同环境的资源。

2、命名空间应用场景

命名空间适用于存在很多跨多个团队或项目的用户的场景。命名空间可以帮助不同的项目或团队将集群中的资源划分为多个虚拟集群,从而实现资源的隔离。(对只有几个到十几个用户的集群来说,不需要创建或考虑命名空间)。

(1)查看名称空间及其资源对象

k8s 集群默认提供三个命名空间,分别是 default、kube-system、kube-public

  • kube-system:k8s 系统默认创建的命名空间,包含了 k8s 集群的核心组件,例如 kube-dns、kube-proxy、kube-apiserver 等。
  • kube-public:这个命名空间是自动创建的,包含了集群信息的 ConfigMap 对象,一般不需要手动创建。
  • default:这个命名空间是用户创建资源时没有指定命名空间的默认命名空间。
# 查看命名空间
[root@master ~]# kubectl get namespace
NAME              STATUS   AGE
default           Active   36d
istio-system      Active   35d
kube-flannel      Active   36d
kube-node-lease   Active   36d
kube-public       Active   36d
kube-system       Active   36d
kubevirt          Active   36d
springcloud       Active   19d

# 查看命名空间中的资源对象
[root@master ~]# kubectl get all -n default
Warning: kubevirt.io/v1 VirtualMachineInstancePresets is now deprecated and will be removed in v2.
NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   36d

# 查看命名空间详情
[root@master ~]# kubectl describe namespace default
Name:         default
Labels:       kubernetes.io/metadata.name=default
Annotations:  <none>
Status:       Active
No resource quota.
No LimitRange resource.

(2)创建命名空间

namespace 资源属性较少,通常只需要指定名称即可创建,例如:

[root@master ~]# kubectl create namespace qa
namespace/qa created
[root@master ~]# kubectl get namespace

# 查看命名空间
[root@master ~]# kubectl get namespace | grep qa
qa                Active   38s

注意:namespace 资源的名称只能由字母、数字、下划线、连接线等字符组成,且长度不能超过 63 个字符。

(3)删除命名空间

删除 namespace 资源会级联删除该命名空间中的所有资源对象,例如:

[root@master ~]# kubectl delete namespace qa
namespace "qa" deleted

3、命名空间的使用

# 创建命名空间
[root@master ~]# kubectl create namespace test
namespace/test created

# 切换命名空间
[root@master ~]# kubectl config set-context --current --namespace=test
Context "kubernetes-admin@kubernetes" modified.
# 切换命名空间后,可以使用 kubectl get pod 查看当前命名空间中的 pod

# 查看当前命名空间
[root@master ~]# kubectl config view --minify | grep namespace
    namespace: test

# 查看哪些资源属于命名空间级别的
[root@master ~]# kubectl api-resources --namespaced=true
NAME                                SHORTNAMES                                APIVERSION                          NAMESPACED   KIND
bindings                                                                      v1                                  true         Binding
configmaps                          cm                                        v1                                  true         ConfigMap
endpoints                           ep                                        v1                                  true         Endpoints
events                              ev                                        v1                                  true         Event
...略
csistoragecapacities                                                          storage.k8s.io/v1                   true         CSIStorageC
telemetries                         telemetry                                 telemetry.istio.io/v1alpha1         true         Telemetry

4、namespace资源限额

namespace 是命名空间,里面有很多资源,可以对命名空间资源进行限制,防止该命名空间部署的资源超过限制。

(1)编辑命名空间资源限额

[root@master tomcat-test]# vi namespace-quota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
  name: mem-cpu-quota
  namespace: test
spec:
  hard:
    requests.cpu: "2"
    requests.memory: 2Gi
    limits.cpu: "4"
    limits.memory: 4Gi

test命名空间中创建的 ResourceQuota 对象将添加如下限制:

  • 该命名空间中所有 pod 的 CPU 请求总量不得超过 2 核,CPU 限制总量不得超过 4 核。
  • 该命名空间中所有 pod 的内存请求总量不得超过 2Gi,内存限制总量不得超过 4Gi。

(2)创建pod时设置资源限额

设置过资源限额的命名空间,创建 pod 时,如果 pod 的资源请求或限制超过了命名空间的资源限额,则 pod 无法创建成功,例如:

[root@master tomcat-test]# vi pod-tomcat.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-test
  namespace: test
  labels:
    app: tomcat-pod-test
spec:
  containers:
  - name: tomcat-test
    ports:
    - containerPort: 8080
    image: xianchao/tomcat-8.5-jre8:v1
    imagePullPolicy: IfNotPresent
    resources:
      requests:
        memory: "100Mi"
        cpu: "1"
      limits:
        memory: "1Gi"
        cpu: "2"

(3)启动资源限制和pod

# 创建资源限额
[root@master tomcat-test]# kubectl apply -f namespace-quota.yaml
resourcequota/mem-cpu-quota created

# 创建pod
[root@master tomcat-test]# kubectl apply -f pod-tomcat.yaml
pod/tomcat-test created

# 查看pod状态
[root@master tomcat-test]# kubectl get pod -n test
NAME       READY   STATUS    RESTARTS   AGE
pod-test   1/1     Running   0          10s

四、标签

标签(label)其实是一对 key/value,被关联在对象上,比如 pod、service、node 等。

标签的作用:

  • 用于标识对象,方便用户管理和查找。
  • 用于选择器,可以根据标签选择对象。
  • 用于对象的生命周期管理,可以根据标签选择对象进行删除。

在 k8s 中,标签是最常用的资源属性,几乎所有的资源对象都可以使用标签。

1、给pod资源打标签

# 对已经存在的pod打标签
[root@master tomcat-test]# kubectl label pods pod-test release=v1
pod/pod-test labeled

# 查看pod标签
[root@master tomcat-test]# kubectl get pods pod-test --show-labels
NAME       READY   STATUS    RESTARTS   AGE   LABELS
pod-test   1/1     Running   0          23m   app=tomcat-pod-test,release=v1   《————标签打成功

2、查看资源标签

# 查看默认命名空间下的所有pod标签
[root@master tomcat-test]# kubectl get pods --show-labels
NAME       READY   STATUS    RESTARTS   AGE   LABELS
pod-test   1/1     Running   0          28m   app=tomcat-pod-test,release=v1

# 查看默认命名空间下指定pod具有的所有标签
[root@master tomcat-test]# kubectl get pods pod-test --show-labels
NAME       READY   STATUS    RESTARTS   AGE   LABELS
pod-test   1/1     Running   0          29m   app=tomcat-pod-test,release=v1

# 列出默认命名空间下标签key是release的pod,不显示标签
[root@master tomcat-test]# kubectl get pods -l release
NAME       READY   STATUS    RESTARTS   AGE
pod-test   1/1     Running   0          30m

# 列出默认命名空间下标签key是release的所有pod,并打印对应的标签值
[root@master tomcat-test]# kubectl get pods -L release
NAME       READY   STATUS    RESTARTS   AGE   RELEASE
pod-test   1/1     Running   0          32m   v1

# 查看所有名称空间下的所有pod标签
[root@master tomcat-test]# kubectl get pods --all-namespaces --show-labels
kube-system    coredns-c676cc86f-ljjbj                1/1     Running   32 (5h24m ago)   33d   k8s-app=kube-dns,pod-template-hash=c676cc86f
kube-system    coredns-c676cc86f-wprfg                1/1     Running   32 (5h24m ago)   33d   k8s-app=kube-dns,pod-template-hash=c676cc86f
kube-system    etcd-master                            1/1     Running   35 (5h24m ago)   36d   component=etcd,tier=control-plane
...略
posted @ 2023-07-04 22:29  休耕  阅读(108)  评论(0编辑  收藏  举报