zoukankan      html  css  js  c++  java
  • Kubernetes学习笔记(二):Pod、标签、注解

    pod与容器

    一个pod是一组紧密相关的容器,它们总是一起运行在同一个节点上,以及同一个LInux命名空间中。
    每个pod拥有自己的ip,包含若干个容器。pod分布在不同的节点上。

    为什么需要pod

    为什么需要pod,而不是直接使用容器:
    因为容器被设计为只运行一个进程,由于不能够将多个进程聚集在一个单独的容器中,就需要另一种结构将容器绑定在一起,并将它们作为一个单元管理,这就是pod的根本原理。

    pod中容器的隔离共享

    在同一个pod中,多个容器有些资源是共享的,有些是隔离的。
    同一个pod中的所有容器都运行在相同的network、UTS、IPC空间下。所以它们共享网络接口、主机名,可以通过IPC互相通信。
    同一个pod中的所有容器的文件系统是隔离的。

    何时在pod中使用多个容器

    • 它们是否是一个整体?
    • 它们是否需要在一起运行?
    • 它们是否要一起扩缩容?

    运行pod

    pod和其他Kubernetes资源通常都是通过向Kubernetes REST API提供JSON或者YAML文件来创建的。
    我们使用nginx镜像创建一个pod。

    nginx.yaml

    apiVersion: v1	# API版本
    kind: Pod	# 资源类型
    metadata:
      name: nginx	# pod的名称
    spec: 
      containers: 
        - image: nginx	# 创建容器所用的镜像地址
          name: nginx	# 容器名称
          ports:
            - containerPort: 80	# 应用监听的端口
              protocol: TCP
    

    这里只给出了一个简单的描述文件,大部分字段没有给出。

    kubectl explain

    kubectl explain相当于一个文档,可以查看每个API对象支持哪些字段。

    -> [root@kube0.vm] [~] k explain pod
    KIND:     Pod
    VERSION:  v1
    
    DESCRIPTION:
         Pod is a collection of containers that can run on a host. This resource is
         created by clients and scheduled onto hosts.
    
    FIELDS:
       apiVersion	<string>
         APIVersion defines the versioned schema of this representation of an
         object. Servers should convert recognized schemas to the latest internal
         value, and may reject unrecognized values. More info:
         https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
    
       kind	<string>
         Kind is a string value representing the REST resource this object
    .................
    

    kubectl create

    使用kubectl create创建pod

    -> [root@kube0.vm] [~] k create -f nginx.yaml
    pod/nginx created
    

    kubectl get

    使用kubectl get查看,指定-o wide查看更多字段

    -> [root@kube0.vm] [~] k get pods
    NAME    READY   STATUS    RESTARTS   AGE
    nginx   1/1     Running   0          11s
    
    -> [root@kube0.vm] [~] k get -o wide pods 
    NAME    READY   STATUS    RESTARTS   AGE   IP           NODE       NOMINATED NODE   READINESS GATES
    nginx   1/1     Running   0          22s   10.244.2.6   kube2.vm   <none>           <none>
    

    完整定义

    使用kubectl get -o yaml或者kubectl get -o json查看pod的完整定义。这个定义包含以下三大部分:

    • metadata:包括名称、命名空间、标签和关于该pod的其他信息
    • spec:包含pod内容的实际说明,如容器、卷等
    • status:包含运行中pod的当前信息,如pod IP、宿主机IP、每个容器的描述和状态
    -> [root@kube0.vm] [~] k get -o yaml pod/nginx
    apiVersion: v1
    kind: Pod
    metadata:
      creationTimestamp: "2020-05-20T00:32:43Z"
      name: nginx
      namespace: default
      resourceVersion: "109529"
      selfLink: /api/v1/namespaces/default/pods/nginx
      uid: a2b83142-9f17-4cfe-a9ac-04f57de82053
    spec:
      containers:
      - image: nginx
        imagePullPolicy: Always
        name: nginx
        ports:
        - containerPort: 80
          protocol: TCP
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
        - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
          name: default-token-vlqvz
          readOnly: true
      dnsPolicy: ClusterFirst
      enableServiceLinks: true
      nodeName: kube2.vm
      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: default-token-vlqvz
        secret:
          defaultMode: 420
          secretName: default-token-vlqvz
    status:
      conditions:
      - lastProbeTime: null
        lastTransitionTime: "2020-05-20T02:46:50Z"
        status: "True"
        type: Initialized
      - lastProbeTime: null
        lastTransitionTime: "2020-05-20T02:46:57Z"
        status: "True"
        type: Ready
      - lastProbeTime: null
        lastTransitionTime: "2020-05-20T02:46:57Z"
        status: "True"
        type: ContainersReady
      - lastProbeTime: null
        lastTransitionTime: "2020-05-20T00:32:43Z"
        status: "True"
        type: PodScheduled
      containerStatuses:
      - containerID: docker://b63c67379def88a5253e8da543655552185f14e6eb962926d65ec74c5a7ab6f7
        image: nginx:latest
        imageID: docker-pullable://nginx@sha256:30dfa439718a17baafefadf16c5e7c9d0a1cde97b4fd84f63b69e13513be7097
        lastState: {}
        name: nginx
        ready: true
        restartCount: 0
        started: true
        state:
          running:
            startedAt: "2020-05-20T02:46:57Z"
      hostIP: 192.168.199.212
      phase: Running
      podIP: 10.244.2.6
      podIPs:
      - ip: 10.244.2.6
      qosClass: BestEffort
      startTime: "2020-05-20T02:46:50Z"
    

    kubectl logs

    kubectl logs [-f] [-p] (POD | TYPE/NAME) [-c CONTAINER] [options]
    使用kubectl logs可以查看pod中的日志。如果pod中有多个容器,可以使用-c <container>指定容器。比如:

    -> [root@kube0.vm] [~] k logs nginx -c nginx -f
    

    kubectl port-forward

    kubectl port-forward TYPE/NAME [options] [LOCAL_PORT:]REMOTE_PORT [...[LOCAL_PORT_N:]REMOTE_PORT_N]
    pod已经运行了,那如何向集群中的pod发出请求呢。我们通过kubectl port-forward命令,将本地端口映射到指定pod的端口上。

    • 窗口1:运行kubectl port-forward
    -> [root@kube0.vm] [~] k port-forward nginx 8000:80
    Forwarding from 127.0.0.1:8000 -> 80
    Forwarding from [::1]:8000 -> 80
    Handling connection for 8000 # curl请求发出后出现
    
    • 窗口2:运行kubectl logs
    -> [root@kube0.vm] [~] k logs nginx -f
    127.0.0.1 - - [20/May/2020:03:19:50 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-" # curl请求发出后出现
    
    • 窗口3:curl发出请求
    -> [root@kube0.vm] [~] curl http://localhost:8000
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    ........
    

    标签

    通俗的讲,标签就是用于将Pod和其他Kubernetes资源进行分类,每个资源都可以有多个标签
    标签是可以附加到资源上的键值对,用以选择具有该标签的资源(通过标签选择器完成)。

    nginx-labels.yaml

    创建一个带有标签的描述文件

    -> [root@kube0.vm] [~] cat nginx-labels.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx-labels
      labels: # 添加了两个标签
        env: prod
        app: order
    spec:
      containers:
        - image: nginx
          name: nginx
          ports:
            - containerPort: 80
              protocol: TCP
    

    查看标签

    使用--show-labels查看标签,po是pod的简写

    -> [root@kube0.vm] [~] k create -f nginx-labels.yaml
    pod/nginx-labels created
    
    -> [root@kube0.vm] [~] k get po --show-labels
    NAME           READY   STATUS              RESTARTS   AGE   LABELS
    nginx-labels   0/1     ContainerCreating   0          3s    app=order,env=prod
    

    使用-L查看指定标签,并且单独成列。

    -> [root@kube0.vm] [~] k get po -L app,env
    NAME           READY   STATUS    RESTARTS   AGE     APP     ENV
    nginx-labels   1/1     Running   0          4m13s   order   prod
    

    kubectl label

    多个标签以空格分隔

    添加

    -> [root@kube0.vm] [~] k label po nginx-labels test=123
    pod/nginx-labels labeled
    
    -> [root@kube0.vm] [~] k get pod --show-labels
    NAME           READY   STATUS    RESTARTS   AGE     LABELS
    nginx-labels   1/1     Running   0          6m23s   app=order,env=prod,test=123
    

    修改

    修改已存在的标签,需要指定--overwrite选项

    -> [root@kube0.vm] [~] k label po nginx-labels test=456 --overwrite
    pod/nginx-labels labeled
    
    -> [root@kube0.vm] [~] k get pod --show-labels
    NAME           READY   STATUS    RESTARTS   AGE     LABELS
    nginx-labels   1/1     Running   0          7m24s   app=order,env=prod,test=456
    

    删除

    -> [root@kube0.vm] [~] k label po nginx-labels test-
    pod/nginx-labels labeled
    
    -> [root@kube0.vm] [~] k get pod --show-labels
    NAME           READY   STATUS    RESTARTS   AGE    LABELS
    nginx-labels   1/1     Running   0          8m8s   app=order,env=prod
    

    标签选择器

    标签选择器可以使我们获取具有特定标签的pod子集。规则通过-l选项指定,多个用逗号分隔。

    选择规则

    • key:选择存在标签key的
    • !key:选择不存在标签key的
    • key=value:key存在并且值等于value
    • key!= value:选择"key=value"的补集。也就存在key并且不等value的,或者不存在key的。
    • key in (value1,value2):key存在且值为value1或者value2
    • key notin (value1,value2):key存在且值不为value1和value2

    实操

    准备几个不同label的pod:

    -> [root@kube0.vm] [~] k get po --show-labels
    NAME             READY   STATUS    RESTARTS   AGE     LABELS
    nginx-labels     1/1     Running   0          40m     app=order,env=prod
    nginx-labels-1   1/1     Running   0          9m42s   env=debug
    nginx-labels-2   1/1     Running   0          8m8s    app=user,env=dev
    

    app

    -> [root@kube0.vm] [~] k get po --show-labels -l app
    NAME             READY   STATUS    RESTARTS   AGE   LABELS
    nginx-labels     1/1     Running   0          50m   app=order,env=prod
    nginx-labels-2   1/1     Running   0          18m   app=user,env=dev
    

    !app

    -> [root@kube0.vm] [~] k get po --show-labels -l '!app'
    NAME             READY   STATUS    RESTARTS   AGE   LABELS
    nginx-labels-1   1/1     Running   0          20m   env=debug
    

    app=order

    -> [root@kube0.vm] [~] k get po --show-labels -l app=order
    NAME           READY   STATUS    RESTARTS   AGE   LABELS
    nginx-labels   1/1     Running   0          77m   app=order,env=prod
    

    app!=order

    -> [root@kube0.vm] [~] k get po --show-labels -l app!=order
    NAME             READY   STATUS    RESTARTS   AGE   LABELS
    nginx-labels-1   1/1     Running   0          46m   env=debug
    nginx-labels-2   1/1     Running   0          45m   app=user,env=dev
    

    env in (dev,prod)

    -> [root@kube0.vm] [~] k get po --show-labels -l 'env in (dev,prod)'
    NAME             READY   STATUS    RESTARTS   AGE   LABELS
    nginx-labels     1/1     Running   0          78m   app=order,env=prod
    nginx-labels-2   1/1     Running   0          46m   app=user,env=dev
    

    env notin (prod)

    -> [root@kube0.vm] [~] k get po --show-labels -l 'env notin (prod)'
    NAME             READY   STATUS    RESTARTS   AGE   LABELS
    nginx-labels-1   1/1     Running   0          48m   env=debug
    nginx-labels-2   1/1     Running   0          46m   app=user,env=dev
    

    使用标签选择器约束pod调度

    其核心思想是,为工作节点(node)打上标签,比如地区、机房、CPU密集、IO密集等。然后在创建pod的描述文件时指定对应标签,调度器就会将pod调度到符合标签选择器规则的工作节点上。

    现在假设一个场景:需要将新建的pod调度到IO密集的工作节点上。

    给node打标签

    -> [root@kube0.vm] [~] k label node kube1.vm io=true
    node/kube1.vm labeled
    
    -> [root@kube0.vm] [~] k get node -L io
    NAME       STATUS   ROLES    AGE   VERSION   IO
    kube0.vm   Ready    master   19h   v1.17.3
    kube1.vm   Ready    <none>   19h   v1.17.3   true
    kube2.vm   Ready    <none>   19h   v1.17.3
    

    nginx-io.yaml

    带有选择器的yaml

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx-io
    spec:
      nodeSelector: # 选择器
        io: "true"
      containers:
        - image: nginx
          name: nginx
    

    创建pod,查看结果确实是运行在kube1.vm上。

    -> [root@kube0.vm] [~] k create -f nginx-io.yaml
    pod/nginx-io created
    
    -> [root@kube0.vm] [~] k get pod -o wide
    NAME             READY   STATUS    RESTARTS   AGE    IP            NODE       NOMINATED NODE   READINESS GATES
    nginx-io         1/1     Running   0          42s    10.244.1.7    kube1.vm   <none>           <none>
    

    注解

    注解也是键值对,与标签类似,但注解并不用于标识和选择对象。
    注解主要为Pod和其他API对象添加说明,以便每个使用集群的人可以快速查找与对象有关的信息。

    kubectl annotate

    使用kubectl annotate为pod添加注解,同样修改已存在的注解需要指定--overwrite

    -> [root@kube0.vm] [~] k annotate po nginx-io my.com/someannotation="123"
    pod/nginx-io annotated
    

    查看

    -> [root@kube0.vm] [~] k describe po nginx-io
    ..........
    Annotations:  my.com/someannotation: 123
    ..........
    

    命名空间

    简单讲,命名空间为Pod等资源提供了作用域,在不同命名空间内的资源名称可以相同。
    我们之前一致使用的是默认命名空间:default,之前的 nginx-xxx 这些pod都位于这个命名空间。

    查看命名空间

    -> [root@kube0.vm] [~] k get ns #ns是namespace缩写
    NAME              STATUS   AGE
    default           Active   21h
    kube-node-lease   Active   21h
    kube-public       Active   21h
    kube-system       Active   21h
    

    kubectl create namespace

    使用kubectl create创建一个namespace,当然也可以写一个描述文件创建(麻烦了点)。

    -> [root@kube0.vm] [~] k create ns test
    namespace/test created
    
    -> [root@kube0.vm] [~] k get ns -o wide
    NAME              STATUS   AGE
    ........
    test              Active   94s
    

    为资源指定命名空间

    可以在描述文件的metadata下添加一个字段namespace: test,或者在命令行的时候指定kubectl create -f xxx.yaml -n test

    命名空间的误解

    首先要明确的是:命名空间并不提供对正在运行的对象的任何隔离
    举个例子:两个pod并不会因为在不同的命名空间而无法进行网络通信,是否可以通信不取决于命名空间,而取决于网络解决方案。

    kubectl delete

    按名字删除pod

    k delete po nginx-io
    

    使用标签选择器删除

    k delete po -l app
    

    删除所有pod

    k delete po --all
    

    删除命名空间

    k delete ns test
    

    删除命名空间(几乎)所有资源

    第一个 all 表示当前命名空间所有资源类型,第二个 --all 表示所有资源实例。

    k delete all --all
    

    小结

    • 如何决定多个容器是否应该放在一个pod
    • 通过提交描述文件创建API对象
    • 使用标签组织API对象
    • 通过标签选择器调度pod
    • 命名空间使不同团队很方便的使用同一个集群
    • 一些命令:create、get、delete、label、annotate、port-forward、describe、logs、explain
  • 相关阅读:
    Vue项目style样式层下载less-loader时候遇到的坑
    用git上传项目到github遇到的问题和解决方法
    git命令大全
    npm run dev 报错:missing script:dev
    sessionStorage缓存数据
    RTL基本知识:编译命令指定隐性线网类型
    RTL基本知识:线网的隐性声明
    物理综合:关于UDSM后端设计总结
    RTL基本知识:task和function
    物理综合:Timing_budgeting
  • 原文地址:https://www.cnblogs.com/flhs/p/12920602.html
Copyright © 2011-2022 走看看