pod的介绍、命令行创建pod

前言

环境:centos7.9 docker-ce-20.10.9 kubernetes-version v1.22.6

介绍pod

在kubernetes的世界中,k8s并不直接处理容器,而是使用多个容器共存的理念,这组容器就叫做pod。
pod是k8s中可以创建和管理的最小单元,是资源对象模型中由用户创建或部署的最小资源对象模型,其他的资源对象都是用来支撑pod对象功能的,比如,pod控制器就是用来管理pod对象的,service或者imgress资源对象是用来暴露pod引用对象的,persistentvolume资源
是用来为pod提供存储等等,简而言之,k8s不会直接处理容器,而是pod,pod才是k8s中可以创建和管理的最小单元,也是基本单元。

pod的特点

1、每个pod就像一个独立的逻辑机器,k8s会为每个pod分配一个集群内部唯一的IP地址,所以每个pod都拥有自己的IP地址、主机名、进程等;
2、一个pod可以包含1个或多个容器,1个容器一般被设计成只运行1个进程,1个pod只可能运行在单个节点上,即不可能1个pod跨节点运行,pod的生命周期是短暂,也就是pod可能随时被消亡(如节点异常,pod异常等情况);
2、每一个pod都有一个特殊的被称为"根容器"的pause容器,也称info容器,pause容器对应的镜像属于k8s平台的一部分,除了pause容器,每个pod还包含一个或多个跑业务相关组件的容器;
3、一个pod中的容器共享network命名空间;
4、一个pod里的多个容器共享pod IP,这就意味着1个pod里面的多个容器的进程所占用的端口不能相同,否则在这个pod里面就会产生端口冲突;既然每个pod都有自己的IP和端口空间,那么对不同的两个pod来说就不可能存在端口冲突;
5、应该将应用程序组织到多个pod中,而每个pod只包含紧密相关的组件或进程;
6、pod是k8s中扩容、缩容的基本单位,也就是说k8s中扩容缩容是针对pod而言而非容器。
pod实现共享网络实现机制:首先pod会创建pause容器,把其他业务容器加入pause容器,
从而让所以业务容器都在同一个命名空间中,这样可是实现网络共享。
pod共享存储实现机制: 引入数据卷volume,使用数据卷进行持久化存储。

pod背后的根本原理

一个容器一般被设计运行一个进程,除非进程本身产生子进程,,由于不能将多个进程聚集在同一个单独的容器中,所以需要一种更高级的结构将容器绑定在一起,并将它们作为一个单元进行管理,这就是pod的背后原理。

命令行创建pod、查看pod

#注意:kubectl run 在旧版本中创建的是deployment,但在本书的版本中创建的是pod
[root@master ~]# kubectl run nginx --image=nginx:1.7.9 --labels="app=nginx"	#创建一个pod,并设置标签为app=httpd		
pod/nginx created
[root@master ~]# kubectl  get pods -n default 									#查看pod,已经是运行状态
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          43s
[root@master ~]# kubectl  get pod nginx -n default -o wide
NAME    READY   STATUS    RESTARTS   AGE   IP            NODE    NOMINATED NODE   READINESS GATES
nginx   1/1     Running   0          75s   10.244.1.28   node1   <none>           <none>
[root@master ~]# 

kubectl describe 命令查看pod的详细信息

[root@master ~]# kubectl describe pod nginx			#使用kubectl describe命令来查看我们刚才创建的pod的详细信息
Name:         nginx									#pod的名称为nginx
Namespace:    default								#pod的所属命名空间
Priority:     0										#这个参数是优先级,暂时不用管
Node:         node1/192.168.118.132					#pod所在节点
Start Time:   Mon, 14 Feb 2022 22:40:55 +0800		#pod启动时间
Labels:       app=nginx								#标签
Annotations:  <none>
Status:       Running								#状态
IP:           10.244.1.28							#pod的IP,前面我们介绍pod的时候说过,pod就像一个逻辑机器,有着自己的IP
IPs:
  IP:  10.244.1.28
Containers:											#容器部分,一个pod可以跑多个容器
  nginx:											#
    Container ID:   docker://042179fde4baa7138ac0213bbfb99dd5f02bf915cd91d0ae38982b2bdd30cb9a	#容器ID
    Image:          nginx:1.7.9																	#镜像
    Image ID:       docker-pullable://nginx@sha256:e3456c851a152494c3e4ff5fcc26f240206a94affb40e0714846c451	#镜像ID
    Port:           <none>
    Host Port:      <none>
    State:          Running								#容器状态
      Started:      Mon, 14 Feb 2022 22:40:56 +0800		#容器启动时间
    Ready:          True								#是否准备就绪
    Restart Count:  0									#重启次数
    Environment:    <none>
    Mounts:												#容器挂载点
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-n5gcr (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  kube-api-access-n5gcr:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  38m   default-scheduler  Successfully assigned default/nginx to node1
  Normal  Pulled     38m   kubelet            Container image "nginx:1.7.9" already present on machine
  Normal  Created    38m   kubelet            Created container nginx
  Normal  Started    38m   kubelet            Started container nginx
[root@master ~]#

查看pod的yaml文件

[root@master ~]# kubectl  get pod nginx -o yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: "2022-02-14T14:40:55Z"
  labels:
    app: nginx
  name: nginx
  namespace: default
  resourceVersion: "488083"
  uid: dff1bcac-b229-4a5d-803d-d003a4311437
spec:
  containers:
  - image: nginx:1.7.9
    imagePullPolicy: IfNotPresent
    name: nginx
    resources: {}
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
    volumeMounts:
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: kube-api-access-n5gcr
      readOnly: true
  dnsPolicy: ClusterFirst
  enableServiceLinks: true
  nodeName: node1
  preemptionPolicy: PreemptLowerPriority
  priority: 0
  restartPolicy: Always
  schedulerName: default-scheduler
  securityContext: {}
  serviceAccount: default
  serviceAccountName: default
  terminationGracePeriodSeconds: 30
  tolerations:
  - effect: NoExecute
    key: node.kubernetes.io/not-ready
    operator: Exists
    tolerationSeconds: 300
  - effect: NoExecute
    key: node.kubernetes.io/unreachable
    operator: Exists
    tolerationSeconds: 300
  volumes:
  - name: kube-api-access-n5gcr
    projected:
      defaultMode: 420
      sources:
      - serviceAccountToken:
          expirationSeconds: 3607
          path: token
      - configMap:
          items:
          - key: ca.crt
            path: ca.crt
          name: kube-root-ca.crt
      - downwardAPI:
          items:
          - fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace
            path: namespace
status:
  conditions:
  - lastProbeTime: null
    lastTransitionTime: "2022-02-14T14:40:55Z"
    status: "True"
    type: Initialized
  - lastProbeTime: null
    lastTransitionTime: "2022-02-14T14:40:57Z"
    status: "True"
    type: Ready
  - lastProbeTime: null
    lastTransitionTime: "2022-02-14T14:40:57Z"
    status: "True"
    type: ContainersReady
  - lastProbeTime: null
    lastTransitionTime: "2022-02-14T14:40:55Z"
    status: "True"
    type: PodScheduled
  containerStatuses:
  - containerID: docker://042179fde4baa7138ac0213bbfb99dd5f02bf915cd91d0ae38982b2bdd30cb9a
    image: nginx:1.7.9
    imageID: docker-pullable://nginx@sha256:e3456c851a152494c3e4ff5fcc26f240206abac0c9d794affb40e0714846c451
    lastState: {}
    name: nginx
    ready: true
    restartCount: 0
    started: true
    state:
      running:
        startedAt: "2022-02-14T14:40:56Z"
  hostIP: 192.168.118.132
  phase: Running
  podIP: 10.244.1.28
  podIPs:
  - ip: 10.244.1.28
  qosClass: BestEffort
  startTime: "2022-02-14T14:40:55Z"
[root@master ~]# 

对外暴露服务、测试访问

以上我们创建了一个名为nginx的pod,但是这个pod还不能被外部客户端连接访问,我们还需要做一步,就是对外暴露pod,让外部客户端能访问k8s集群的pod服务,如下所示:

# --port=8088 表示指定集群内部访问端口,--target-port=80表示pod里面容器的应用程序端口
# 节点端口,即客户外部访问端口是自动生成的
[root@master ~]# kubectl  expose pod nginx -n default --port=8088 --target-port=80 --type=NodePort --name=nginx
service/nginx exposed
[root@master ~]# kubectl  get pod,svc -n default 
NAME        READY   STATUS    RESTARTS   AGE
pod/nginx   1/1     Running   0          2m34s

NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
service/kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP          11d
service/nginx        NodePort    10.103.207.241   <none>        8088:30295/TCP   14s	#8088为集群内部访问端口,30295为外部访问端口
[root@master ~]# curl http://10.103.207.241:8088					#使用集群内部IP+内部端口8088访问,能成功访问
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@master ~]# 

在浏览器访问,任意一个节点的IP+30295端口都能访问到nginx,如下图所示:
在这里插入图片描述

编辑service

如果需要修改外部访问端口或者需要修改一下刚才定义的service,这时我们可以使用kubectl edit 编辑刚才创建的service,如下:

[root@master ~]# kubectl edit service nginx						#编辑我们刚才创建的名为nginx的服务
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: "2022-02-14T14:43:15Z"
  labels:
    app: nginx
  name: nginx
  namespace: default
  resourceVersion: "488275"
  uid: e935f0c2-3f8b-48a0-b592-eae3332e40b1
spec:
  clusterIP: 10.103.207.241
  clusterIPs:
  - 10.103.207.241
  externalTrafficPolicy: Cluster
  internalTrafficPolicy: Cluster
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - nodePort: 30005									#修改一下对外暴露的端口为30005,注意:端口是有范围了,不能随便定义
    port: 8088
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx
  sessionAffinity: None
  type: NodePort
status:
  loadBalancer: {}

~
"/tmp/kubectl-edit-3488312699.yaml" 34L, 785C written
service/nginx edited										#修改完成之后保存退出,k8s会立即自动应用你做的修改
[root@master ~]# kubectl  get pod,svc -n default 			#查看service,发现外部端口已经改成了30005,浏览器就能使用这个端口来访问了
NAME        READY   STATUS    RESTARTS   AGE
pod/nginx   1/1     Running   0          26m

NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
service/kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP          11d
service/nginx        NodePort    10.103.207.241   <none>        8088:30005/TCP   23m
[root@master ~]# 

以上我们创建了一个跑nginx服务的pod,也使用service对外暴露了pod,这样外部客户就能访问k8s集群里pod的容器里nginx服务了,但是以上我们创建的pod是不受任何控制的,换句话说就是pod出现异常挂掉了就挂掉了,k8s不会帮你重启pod;在实际的生产环境中,我们并不是直接创建pod,而是创建pod控制器,所谓pod控制器,就是用来管理pod,其具有上线部署、副本设定、滚动升级、回滚等诸多功能。关于pod控制的讲解,我们不在本篇论述。

一个完整的pod资源清单yaml文件讲解

创建pod,我们一般是通过定义资源清单yaml文件来创建的,下面通过讲解一个完整的pod定义来加深对pod的定义。

[root@master ~]# vim pod-nginx.yaml				#创建一个pod资源清单
apiVersion: v1									#资源的api版本
kind: Pod										#资源类型
metadata:										#定义元数据
  name: nginx-pod								#pod的名称,必须是小写字母,不能有大写字母
  namespase: default							#所属命名空间
  labels:										#标签,可以有多个标签
    app: dev
  annotations:									#注解
    - name: string
spec:
  containers:									#定义容器,可以有多个容器
  - name: nginx-container						#容器名称
    image: nginx:1.18.0							#镜像
    imagePullPolicy: [Always|Never|IfNotPresent]#镜像拉取策略,always表示总是从远程拉取,Never 从不拉取,IfNotPresent本地不存在才拉取
    command: [string]							#容器启动时执行的命令
    args: [string]								#容器启动时执行的命令参数
    workingDir: string
    volumeMounts:								#存储卷的挂载点
    - name: string
      mountPath: string
      readOnly: boolean
    ports:										#容器的端口
    - name: string
      containerPort: int
      hostPort: int
      protocol: string
    env:										#环境变量
    - name: string
      value: string
    resources:									#资源限额
      limits:
        cpu: string
        memory: string
      requests:
        cpu: string
        memory: string
    livenessProde:								#存活谭政
      exec:
        command: [string]
      httpGet:
        path: string
        port: number
        host: string
        scheme: string
        httpHeaders:
        - name: string
          value: string
      tcpSocket:
        port: number
      initialDelaySeconds: 0
      timeoutSeconds: 0
      periodSeconds: 0
      successThreshold: 0
      failureThreshold: 0
      securityContext:
        privileged: false
      restartPolicy: [Always | Never | OnFaulure]
      nodeSelector: object
      imagePullSecrets:
      - name: string
      hostNetwork: false
      volumes:								#定义存储卷
      - name: string
        emptyDir: {}
        hostPath:
          path: string
        secret:
          secretName: string
          items:
          - key: string
            path: string
        configMap:
          name: string
          items:
          - key: string
            path: string

pod中command字段讲解

可以用过在创建pod时使用command字段来指定容器的启动参数,如下:

#创建一个pod,容器运行busybox程序,启动容器就死循环往/tmp/hello.txt写入数据
[root@master ~]# cat pod-busybox.yaml 	
apiVersion: v1
kind: Pod
metadata: 
  name: pod-command
  labels: 
    env: dev
  namespace: default
spec:
  containers:
  - image: busybox
    name: busybox-container
    command: ["/bin/sh","-c","touch /tmp/hello.txt;while true;do /bin/echo $(date +%T) >> /tmp/hello.txt;sleep 3;done;"]
[root@master ~]#kubec apply -f pod-busybox.yaml 
pod/pod-command created
[root@master ~]# kubectl  get pod pod-command 
NAME          READY   STATUS    RESTARTS   AGE
pod-command   1/1     Running   0          19s
[root@master ~]# 
[root@master ~]# kubectl  exec -it pod-command -c busybox-container  -- tail -f /tmp/hello.txt
06:47:02
06:47:05
command    #容器的启动命令列表,如果不指定,则使用打包时的启动命令
args       #容器的启动命令需要的参数列表
特别说明:
通过上面发现command已经可以完成启动命令和传递参数的功能,为什么这里还有提供一个args选项用于传递参数呢?
这其实是跟docker优点关系,kubernetes中的command、args其实是实现覆盖dockerfile中的ENTRYPOINT的功能。
1、如果command和args均没有写,那么使用Dockerfile的配置;
2、如果command写了但args没写,那么Dockerfile默认的配置会被忽略,执行输入的command;
3、如果command没写但args写了,那么Dockerfile中的ENTRYPOINT的会被执行,使用当前args的参数;
4、如果command和args都写了,那么Dockerfile会被忽略,执行输入的command和args。

pod中端口ports字段讲解

[root@master ~]# kubectl explain  pod.spec.containers.ports
[root@master ~]# vim pod-busybox.yaml 			#定义容器的端口时主要有5个参数,每个参数的含义如下讲解所示:
........
ports:					#设置容器暴露的端口列表,一个容器可以暴露多个端口
 - containerPort: 80	#容器的端口(0<x<65536),就是应用程序的端口
   hostIP:				#将容器公开的端口绑定到指定的主机ip(一般不设置)
   hostPort:	#容器要在主机上公开的端口(一般不设置)如果设置,主机上只能运行容器的一个副本,因为,如果使用pod控制器创建了2个pod副本,
			    #那么指定了在主机上公开的端口,两个pod就都会在主机上公开端口,这样就会存在端口冲突问题,所以,该参数一般不会设置。
   name: http			#端口的名字,如果指定,则该名字必须在pod中是唯一的,为端口指定一个名字,主要是为了方便service与之关联
   protocol: tcp		#端口的协议,必须是 UDP,TCP,或者SCTP,默认tcp协议
   ......
  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 使用 `kubectl` 创建 Pod 的命令如下: ``` kubectl create -f path/to/pod.yaml ``` 其中 `path/to/pod.yaml` 是你的 Pod 描述文件的路径。Pod 描述文件应包含以下信息: ``` apiVersion: v1 kind: Pod metadata: name: my-pod spec: containers: - name: my-container image: my-image ``` 其中 `apiVersion` 和 `kind` 指定了资源的类型(在这种情况下是 Pod),`metadata` 中的 `name` 属性指定了 Pod 的名称,`spec` 中的 `containers` 数组描述了 Pod 中运行的容器,包括容器的名称和镜像。 运行 `kubectl create` 命令后,Kubernetes 会在集群中创建一个新的 Pod。 你也可以使用 `kubectl run` 命令来直接创建 Pod,而无需提供 Pod 描述文件。例如,以下命令会在集群中创建一个名为 `my-pod` 的 Pod,并运行 `nginx` 镜像: ``` kubectl run my-pod --image=nginx ``` ### 回答2: 使用kubectl命令创建pod是一种直接在Kubernetes集群上创建和管理容器的方法。以下是使用kubectl创建pod的步骤: 1. 在本地或远程的终端中打开命令行。 2. 确保kubectl命令已正确配置并与Kubernetes集群连接。可以通过运行`kubectl version`来验证kubectl的版本和集群连接状态。 3. 使用以下命令创建pod,并指定pod配置的YAML文件路径: ``` kubectl create -f <pod-配置-YAML-文件路径> ``` 在该命令中,`<pod-配置-YAML-文件路径>`应替换为要创建Pod配置的YAML文件的路径。 4. 执行此命令后,kubectl将发送请求到Kubernetes API服务器,创建pod,并返回创建结果。 例如: ``` pod/pod-example created ``` 5. 可以使用`kubectl get pods`命令来验证Pod创建状态和详细信息。 ``` kubectl get pods ``` 此命令将返回集群中所有已创建Pod的列表。 通过使用kubectl命令和Pod配置的YAML文件,我们可以直接在Kubernetes集群上创建和管理我们的容器。这种方法非常灵活和方便,可以满足运行不同类型应用程序的需求。 ### 回答3: 使用kubectl创建pod的命令是`kubectl create pod`。 创建pod时,可以通过指定参数来定义pod的属性。例如,可以使用`--image`参数来指定pod所使用的容器镜像,使用`--name`参数来为pod指定一个名称。 以下是一个示例命令: ``` kubectl create pod my-pod --image=nginx:latest ``` 这个命令会创建一个名为my-podpod,并使用最新的nginx镜像。 除了指定镜像,还可以通过其他参数来自定义pod的属性,比如指定端口、环境变量等。 不过需要注意的是,直接创建pod可能并不是最佳实践。通常情况下,我们更推荐使用其他资源对象,如Deployment或StatefulSet来创建和管理pod。这些资源对象可以提供更高级的功能,比如自动回滚、扩缩容等。因此,在实际使用中,我们更常见使用类似以下命令来创建pod: ``` kubectl create deployment my-deployment --image=nginx:latest ``` 这个命令会创建一个名为my-deployment的Deployment对象,并在该Deployment下创建一个pod
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值