三、Kubernetes 组件与Namespace

1、 YAML基础

参考链接: k8s-YAML配置文件

  • 前提知识点

    在正式学习K8S的各组件之前,我们先了解一下 YAML 文件的语法规则,熟悉语法之后才能更好的理解配置文件是如何描述的。

    YAML是专门用来写配置文件的语言,非常简洁和强大,使用比json更方便。它实质上是一种通用的数据串行化格式。

    • YAML语法规则

      • 大小写敏感
      • 使用缩进表示层级关系
      • 缩进时不允许使用Tal键,只允许使用空格
      • 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
      • ”#” 表示注释,从这个字符一直到行尾,都会被解析器忽略
      • 使用key: value,其中 ":" 和 value 之间要有一个英文空格
    • 在Kubernetes中,只需要知道两种结构类型即可

      • Lists

        List即列表,其实就是数组,例如:

        args
         - beijing
         - shanghai
         - shenzhen
         - guangzhou
        

        可以指定任何数量的项在列表中,每个项的定义以破折号(-)开头,并且与父元素之间存在缩进。在JSON格式中,表示如下:

        {
          "args": ["beijing", "shanghai", "shenzhen", "guangzhou"]
        }
        

        当然Lists的子项也可以是Maps,Maps的子项也可以是List,例如:

        apiVersion: v1
        kind: Pod
        metadata:
          name: kube100-site
          labels:
            app: web
        spec:
          containers:
            - name: front-end
              image: nginx
              ports:
                - containerPort: 80
            - name: flaskapp-demo
              image: jcdemo/flaskapp
              ports: 8080
        

        如上述文件所示,定义一个containers的List对象,每个子项都由name、image、ports组成,每个ports都有一个KEY为containerPort的Map组成,转成JSON格式文件:

        {
          "apiVersion": "v1",
          "kind": "Pod",
          "metadata": {
              "name": "kube100-site",
              "labels": {
                  "app": "web"
              },
          },
          "spec": {
              "containers": [{
                  "name": "front-end",
                  "image": "nginx",
                  "ports": [{
                      "containerPort": "80"
                  }]
              }, {
                  "name": "flaskapp-demo",
                  "image": "jcdemo/flaskapp",
                  "ports": [{
                      "containerPort": "5000"
                  }]
              }]
          }
        }
        
      • Maps

        Map顾名思义指的是字典,即一个Key:Value 的键值对信息。例如:

        ---
        apiVersion: v1
        kind: Pod
        

        注:--- 为可选的分隔符 ,当需要在一个文件中定义多个结构的时候需要使用。

        上述内容表示有两个键apiVersion和kind,分别对应的值为v1和Pod。Maps的value既能够对应字符串也能够对应一个Maps。例如:

        ---
        apiVersion: v1
        kind: Pod
        metadata:
          name: kube100-site
          labels:
            app: web
        

        注:上述的YAML文件中,metadata这个KEY对应的值为一个Maps,而嵌套的labels这个KEY的值又是一个Map。实际使用中可视情况进行多层嵌套。

        YAML处理器根据行缩进来知道内容之间的关联。上述例子中,使用两个空格作为缩进,但空格的数据量并不重要,只是至少要求一个空格并且所有缩进保持一致的空格数 。

        例如,name和labels是相同缩进级别,因此YAML处理器知道他们属于同一map;它知道app是lables的值因为app的缩进更大。

        注意:在YAML文件中绝对不要使用tab键

2、Kubernetes 组件

2.1 Pod

在上一章节其实已经演示了 Pod 的创建,但是那是使用 ReplicaSet 来创建和管理Pod,而且没有进行讲解。

本章从最小操作单元 Pod 来开始演示,并说明 YAML 文件要如何配置。

  • 理解 Pod

    • Pod 是 Kubernetes 应用程序的基本执行单元,即它是 Kubernetes 对象模型中创建或部署的最小和最简单的单元。Pod 表示在集群上运行的进程。
    • Pod 封装了应用程序容器(或者在某些情况下封装多个容器)、存储资源、唯一网络 IP 以及控制容器应该如何运行的选项。
    • Pod 表示部署单元:Kubernetes 中应用程序的单个实例,它可能由单个 容器 或少量紧密耦合并共享资源的容器组成。
    • Pod 中的容器被自动的安排到集群中的同一物理或虚拟机上,并可以一起进行调度。 容器可以共享资源和依赖、彼此通信、协调何时以及何种方式终止它们。
    • 上面的内容用一句话来说就是:Pod 就是一个或多个相同Container的集合,相互之间可以互通与共享资源。
  • 使用 Pod

    • 定义 pod_nginx.yaml

      apiVersion: v1          # 必写,指定api版本,此值必须在 kubectl api-versions 中存在
      kind: Pod               # 必写,指定创建资源的类型为 Pod  
      metadata:               # 必写,资源的元数据
        name: nginx-pod       # 必写,表示pod名称,在同一个namespace中必须唯一,namespace后面再说
        namespace: default    # 表示pod所属的命名空间
        labels:               # 设定资源的标签
          app: nginx          # key: app, value: nginx
      spec:                   # 必写,pod中容器的详细定义
        containers:           # 必写,pod中容器列表
        - name: nginx         # 必写,容器的名字
         image: nginx         # 必写,使用的镜像
         ports:               # 定义端口
         - containerPort: 80  # 容器对外开放的端口
      

      spec 上面的配置都是对 Pod 资源的配置信息,从 spec 往下开始才是去定义容器的。

    • 创建 Pod

      # 根据 pod_nginx.yaml 创建资源
      [root@master-kubeadm-k8s pod]# kubectl apply -f pod_nginx.yaml
      pod/nginx-pod created
      
    • 查看 Pod 信息

      # 查看 pod,这里正在创建中,等一会就会创建完成
      [root@master-kubeadm-k8s pod]# kubectl get pods
      NAME        READY   STATUS              RESTARTS   AGE
      nginx-pod   0/1     ContainerCreating   0          15s
      
      # 再次查看,容器已经运行起来了
      [root@master-kubeadm-k8s pod]# kubectl get pods
      NAME        READY   STATUS              RESTARTS   AGE
      nginx-pod   1/1     Running             0          20s
      
      # 查看 pod 详情
      [root@master-kubeadm-k8s pod]# kubectl get pods -o wide
      NAME        READY   STATUS    RESTARTS   AGE   IP             NODE                   NOMINATED NODE   READINESS GATES
      nginx-pod   1/1     Running   0          22m   192.168.14.4   worker01-kubeadm-k8s   <none>           <none>
      
      # 查看 Pod 的详情描述
      [root@master-kubeadm-k8s pod]# kubectl describe pod nginx-pod
      Name:               nginx-pod
      Namespace:          default
      Priority:           0
      PriorityClassName:  <none>
      Node:               worker01-kubeadm-k8s/10.0.2.15
      Start Time:         Fri, 27 Mar 2020 14:31:43 +0000
      Labels:             app=nginx
      Annotations:        cni.projectcalico.org/podIP: 192.168.14.5/32
                          kubectl.kubernetes.io/last-applied-configuration:
                            {"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},
      
      # ....省略....
      
      Events:
        Type    Reason     Age   From                           Message
        ----    ------     ----  ----                           -------
        Normal  Scheduled  28s   default-scheduler              Successfully assigned default/nginx-pod to worker01-kubeadm-k8s
        Normal  Pulling    26s   kubelet, worker01-kubeadm-k8s  Pulling image "nginx"
      
    • 测试

      # 访问容器 ip, 成功访问到了Nginx
      [root@master-kubeadm-k8s pod]# curl 192.168.14.4
      <!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>
      
    • 删除 Pod

      [root@master-kubeadm-k8s pod]# kubectl delete -f pod_nginx.yaml
      pod "nginx-pod" deleted
      

      对于 Pod 的使用大概就是这些常用操作了,还有就是 Pod 的特性还需要在补充一下。

  • Storage and Networking

    • Networking

      每个Pod会被分配一个唯一的IP地址。Pod 中的每个容器共享网络命名空间,包括IP地址和网络端口。也就是说可以通过一个 IP 访问到 Pod 中的不同容器。

    • Storage

      Pod可以指定一组共享存储卷。Pod中的所有容器都可以访问共享卷,从而允许这些容器共享数据。卷还允许 Pod 中的持久数据保留下来,以防其中的容器需要重新启动。

2.2 Controller

2.2.1 ReplicationController
  • 理解 ReplicationController

    • ReplicationController 确保在任何时候都有特定数量的 pod 副本处于运行状态。 换句话说,ReplicationController 确保一个 pod 或一组同类的 pod 总是可用的。再简单点说即声明某种Pod的副本数量在任意时刻都符合设定的预期值。
    • 所以RC的定义包含以下几个部分:
      • 期待的 Pod 副本数(replicas)
      • 用于筛选目标Pod的 Label Selector
      • 当 Pod 的副本数量小于预期数量时,用于创建新 Pod 的 Pod 模板(template)

    ReplicationController 通常缩写为 rc,并作为 kubectl 命令的快捷方式通过RC可以自动实现集群中 Pod 的高可用,减少了传统IT环境中手工运维的工作。

  • 使用 ReplicationController

    • 创建 nginx_replication.yaml

      配置文件的说明现在只说明之前没用过的,已经说明过的就不再重复了。

      apiVersion: v1
      kind: ReplicationController # 指定资源类型为 ReplicationController
      metadata:
        name: nginx
      spec:
        replicas: 3               # 指定 Pod 的副本数为 3
        selector:                 # 标签选择器,通过 selector 选取具有相同 label 的容器,这里表示包含 app: nginx的 label 的 Pod 都会被该 RC 管理
          app: nginx
        template:                 # 表示用于定义Pod的模板,比如Pod名称、拥有的label以及Pod中运行的应用等,通过改变RC里Pod模板中的镜像版本,可以实现Pod的升级功能
          metadata:               # 下面的配置就与配置 Pod 时一致了
            name: nginx
            labels:
              app: nginx
          spec:
            containers:
            - name: nginx
              image: nginx
              ports:
              - containerPort: 80
      
    • 创建 ReplicationController

      # 所有资源类型创建的方式都是一致的
      [root@master-kubeadm-k8s replicationController]# kubectl apply -f nginx_replication.yaml
      replicationcontroller/nginx created
      
    • 查询 RC 信息

      # 查看 pod
      [root@master-kubeadm-k8s replicationController]# kubectl get pods
      NAME          READY   STATUS              RESTARTS   AGE
      nginx-22ctb   0/1     ContainerCreating   0          72s
      nginx-7jvb5   1/1     Running             0          72s
      nginx-qbtz4   0/1     ContainerCreating   0          72s
      
      # 查看 Pod 的详情
      [root@master-kubeadm-k8s replicationController]# kubectl get pods -o wide
      NAME          READY   STATUS    RESTARTS   AGE     IP               NODE                   NOMINATED NODE   READINESS GATES
      nginx-22ctb   1/1     Running   0          4m37s   192.168.221.68   worker02-kubeadm-k8s   <none>           <none>
      nginx-7jvb5   1/1     Running   0          4m37s   192.168.221.67   worker02-kubeadm-k8s   <none>           <none>
      nginx-qbtz4   1/1     Running   0          4m37s   192.168.14.6     worker01-kubeadm-k8s   <none>           <none>
      
      # 通过查看 rc 也可以查看
      [root@master-kubeadm-k8s replicationController]# kubectl get rc
      NAME    DESIRED   CURRENT   READY   AGE
      nginx   3         3         2       85s
      
      # 也可以查看 rc 详情
      [root@master-kubeadm-k8s replicationController]# kubectl get rc -o wide
      NAME    DESIRED   CURRENT   READY   AGE     CONTAINERS   IMAGES   SELECTOR
      nginx   3         3         3       2m23s   nginx        nginx    app=nginx
      
      # 同样的 describe 也是可以查看的
      [root@master-kubeadm-k8s replicationController]# kubectl describe rc nginx
      Name:         nginx
      Namespace:    default
      Selector:     app=nginx
      Labels:       app=nginx
      Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                      {"apiVersion":"v1","kind":"ReplicationController","metadata":{"annotations":{},"name":"nginx","namespace":"default"},"spec":{"replicas":3,...
      Replicas:     3 current / 3 desired
      Pods Status:  3 Running / 0 Waiting / 0 Succeeded / 0 Failed
      Pod Template:
        Labels:  app=nginx
        Containers:
         nginx:
          Image:        nginx
          Port:         80/TCP
          Host Port:    0/TCP
          Environment:  <none>
          Mounts:       <none>
        Volumes:        <none>
      Events:
        Type    Reason            Age    From                    Message
        ----    ------            ----   ----                    -------
        Normal  SuccessfulCreate  3m41s  replication-controller  Created pod: nginx-7jvb5
        Normal  SuccessfulCreate  3m41s  replication-controller  Created pod: nginx-qbtz4
        Normal  SuccessfulCreate  3m41s  replication-controller  Created pod: nginx-22ctb
      
    • 测试高可用

      • 尝试删除其中一个 Pod

        [root@master-kubeadm-k8s replicationController]# kubectl delete pods nginx-22ctb
        pod "nginx-22ctb" deleted
        
        # 查看 Pod,发现还是有 3 个 Pod
        # 其实 "nginx-22ctb" 这个 Pod 已经删除了,但是 RC 自身有高可用的特性,又自动帮我们创建了一个新的 Pod
        [root@master-kubeadm-k8s replicationController]# kubectl get pods -o wide
        NAME          READY   STATUS    RESTARTS   AGE     IP               NODE                   NOMINATED NODE   READINESS GATES
        nginx-5nw6m   1/1     Running   0          58s     192.168.14.7     worker01-kubeadm-k8s   <none>           <none>
        nginx-7jvb5   1/1     Running   0          7m45s   192.168.221.67   worker02-kubeadm-k8s   <none>           <none>
        nginx-qbtz4   1/1     Running   0          7m45s   192.168.14.6     worker01-kubeadm-k8s   <none>           <none>
        
      • 对 pod 进行扩缩容

        # 将 nginx 这个 rc 扩容为 5
        [root@master-kubeadm-k8s replicationController]# kubectl scale rc nginx --replicas=5
        replicationcontroller/nginx scaled
        
        # 查看 Pod,发现已经新增了 2 个正在创建中的 Pod 了
        [root@master-kubeadm-k8s replicationController]# kubectl get pods
        NAME          READY   STATUS              RESTARTS   AGE
        nginx-5nw6m   1/1     Running             0          3m14s
        nginx-7jvb5   1/1     Running             0          10m
        nginx-bfhp4   0/1     ContainerCreating   0          6s
        nginx-qbtz4   1/1     Running             0          10m
        nginx-wrhbf   0/1     ContainerCreating   0          6s
        
    • 测试

      # 任意一个 ip 都是可以正常访问的
      [root@master-kubeadm-k8s replicationController]# curl 192.168.221.67
      <!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>
      
    • 删除 RC

      [root@master-kubeadm-k8s replicationController]# kubectl delete -f nginx_replication.yaml
      replicationcontroller "nginx" deleted
      

    RC 现在已经不推荐使用了,但是还是要提一下的,官方为 RC 提供了 升级版本,就是 ReplicaSet

2.2.2 ReplicaSet
  • 理解 ReplicaSet

    • ReplicaSet 是下一代的 Replication Controller。 ReplicaSet 和 Replication Controller 的唯一区别是选择器的支持。ReplicaSet 支持新的基于集合的选择器(selector)需求,而 Replication Controller 仅支持基于相等选择器的需求。
    • 简单来说就是 RC 只能根据单个 label 进行选择 Pod,而 RS 则可以选则多个 label。
    • 大多数支持 Replication Controllers 的 kubectl命令也支持 ReplicaSets。但 rolling-update 命令是个例外。如果想要滚动更新功能请考虑使用 Deployment。
    • 虽然 ReplicaSets 可以独立使用,但今天它主要被 Deployments 用作协调 Pod 创建、删除和更新的机制。 当使用 Deployment 时,不必担心还要管理它们创建的 ReplicaSet。Deployment 会拥有并管理它们的 ReplicaSet。
  • 使用 ReplicaSet

    • 创建 nginx_rs.yaml 文件

      apiVersion: apps/v1     # 版本
      kind: ReplicaSet        # 定义资源的类型为 RS
      metadata:
        name: nginx-rs
        labels:               # 这里可以配置多个标签
          app: guestbook
          podLabel: nginx-label
      spec:
        replicas: 3
        selector:
          matchLabels:        # 可以匹配多个标签
            podLabel: nginx-label # 注意这里的标签必须与template中定义的标签一致,否则匹配不到
        template:
          metadata:
            labels:
              podLabel: nginx-label
          spec:
            containers:
            - name: nginx-pod
              image: nginx
      
    • 创建 ReplicaSet

      [root@master-kubeadm-k8s replicaSet]# kubectl apply -f nginx_rs.yaml
      replicaset.apps/nginx-rs created
      
    • 查看 ReplicaSet

      # 查看 Pod 都是通用的命令,不管使用哪种资源类型,都可以使用 get pods这些命令
      [root@master-kubeadm-k8s replicaSet]# kubectl get pods
      NAME             READY   STATUS              RESTARTS   AGE
      nginx-rs-b6fjz   1/1     Running             0          65s
      nginx-rs-dg4vj   1/1     Running             0          65s
      nginx-rs-fwkhd   0/1     ContainerCreating   0          66s
      
      # 与 RC 一样, 无非就是 rc 换成了 rs
      [root@master-kubeadm-k8s replicaSet]# kubectl get rs
      NAME       DESIRED   CURRENT   READY   AGE
      nginx-rs   3         3         3       113s
      
      [root@master-kubeadm-k8s replicaSet]# kubectl get rs -o wide
      NAME       DESIRED   CURRENT   READY   AGE     CONTAINERS   IMAGES   SELECTOR
      nginx-rs   3         3         3       2m27s   nginx-pod    nginx    podLabel=nginx-label
      ...
      
    • 删除 ReplicaSet

      [root@master-kubeadm-k8s replicaSet]# kubectl delete -f nginx_rs.yaml
      replicaset.apps "nginx-rs" deleted
      

    ReplicaSet 与 ReplicationController 操作都是一致的,只有编写 yaml 文件时 rs 可以选择多个 label,那么其他功能就不再演示了。

    注意:一般情况下,我们很少单独使用Replica Set,它主要是被 Deployment 这个更高的资源对象所使用,从而形成一整套Pod创建、删除、更新的编排机制。当我们使用 Deployment 时,无须关心它是如何创建和维护ReplicaSet的,这一切都是自动发生的。同时,无需担心跟其他机制的不兼容问题(比如ReplicaSet不支持 rolling-update 但 Deployment 支持)。

2.2.3 Deployment
  • 理解 Deployment

    • 一个 Deployment 控制器为 PodsReplicaSets 提供描述性的更新方式。
    • Deployment 控制器以受控速率更改实际状态,以达到期望状态。可以定义 Deployments 以创建新的 ReplicaSets ,或删除现有 Deployments ,并通过新的 Deployments 使用其所有资源。
    • Deployment 是 K8S 中推荐使用的管理、编排容器的方式,它相比 RC 与 RS 最大的升级就是我们可以随时知道当前 Pod 部署的进度,可以检查 Deployment 的状态来看部署是否完成。
  • 使用 Deployment

    • 创建 nginx_deployment.yaml

      基础配置方面都与 RS 配置一模一样, 除了修改资源类型为 Deployment

      apiVersion: apps/v1
      kind: Deployment            # 定义资源类型为 Deployment
      metadata:
        name: nginx-deployment
        labels:
          app: nginx
      spec:
        replicas: 3
        selector:
          matchLabels:
            app: nginx
        template:
          metadata:
            labels:
              app: nginx
          spec:
            containers:
            - name: nginx
              image: nginx:1.7.9
              ports:
              - containerPort: 80
      
    • 创建 Deployment

      [root@master-kubeadm-k8s deployment]# kubectl apply -f nginx_deployment.yaml
      deployment.apps/nginx-deployment created
      
    • 查看 Deployment

      [root@master-kubeadm-k8s deployment]# kubectl get pods -o wide
      NAME                               READY   STATUS              RESTARTS   AGE   IP       NODE                   NOMINATED NODE   READINESS GATES
      nginx-deployment-6dd86d77d-fddx5   0/1     ContainerCreating   0          32s   <none>   worker01-kubeadm-k8s   <none>           <none>
      nginx-deployment-6dd86d77d-hcbsv   0/1     ContainerCreating   0          32s   <none>   worker02-kubeadm-k8s   <none>           <none>
      nginx-deployment-6dd86d77d-hrx2f   0/1     ContainerCreating   0          32s   <none>   worker02-kubeadm-k8s   <none>           <none>
      
      # 也可以查看 rs
      [root@master-kubeadm-k8s deployment]# kubectl get rs
      NAME                         DESIRED   CURRENT   READY   AGE
      nginx-deployment-6dd86d77d   3         3         2       79s
      
      # 查看 deployment 部署情况
      [root@master-kubeadm-k8s deployment]# kubectl get deployment
      NAME               READY   UP-TO-DATE   AVAILABLE   AGE
      nginx-deployment   0/3     3            0           53s
      
      # 查看 deployment 详情
      [root@master-kubeadm-k8s deployment]# kubectl get deployment -o wide
      NAME               READY   UP-TO-DATE   AVAILABLE   AGE    CONTAINERS   IMAGES        SELECTOR
      nginx-deployment   3/3     3            3           103s   nginx        nginx:1.7.9   app=nginx
      
    • 高级特性 rolling-update

      使用 Deployment 的好处之一就是我们可以通过 滚动更新 的方式去在线升级应用的版本

      # 查看当前nginx的版本, nginx我们是指定了使用 1.7.9 版本的
      [root@master-kubeadm-k8s deployment]# kubectl get deployment -o wide
      NAME               READY   UP-TO-DATE   AVAILABLE   AGE     CONTAINERS   IMAGES        SELECTOR
      nginx-deployment   3/3     3            3           5m28s   nginx        nginx:1.7.9   app=nginx
      
      # 更新 nginx 的 image 版本
      [root@master-kubeadm-k8s deployment]# kubectl set image deployment nginx-deployment nginx=nginx:1.9.1
      deployment.extensions/nginx-deployment image updated
      
      # -w 监控当前 pod 变化情况
      # 可以发现它是为我们创建新的Pod,然后再慢慢停止之前旧版本的 Pod
      [root@master-kubeadm-k8s deployment]# kubectl get pods -w
      NAME                                READY   STATUS              RESTARTS   AGE
      nginx-deployment-6dd86d77d-fddx5    1/1     Running             0          9m58s
      nginx-deployment-6dd86d77d-hcbsv    1/1     Running             0          9m58s
      nginx-deployment-6dd86d77d-hrx2f    1/1     Running             0          9m58s
      nginx-deployment-784b7cc96d-fqzzp   0/1     ContainerCreating   0          30s
      
      nginx-deployment-784b7cc96d-fqzzp   1/1     Running             0          84s
      nginx-deployment-6dd86d77d-hcbsv    1/1     Terminating         0          10m
      nginx-deployment-784b7cc96d-xrdz6   0/1     Pending             0          0s
      nginx-deployment-784b7cc96d-xrdz6   0/1     Pending             0          0s
      nginx-deployment-784b7cc96d-xrdz6   0/1     ContainerCreating   0          0s
      nginx-deployment-784b7cc96d-xrdz6   0/1     ContainerCreating   0          1s
      nginx-deployment-6dd86d77d-hcbsv    0/1     Terminating         0          10m
      nginx-deployment-6dd86d77d-hcbsv    0/1     Terminating         0          11m
      nginx-deployment-6dd86d77d-hcbsv    0/1     Terminating         0          11m
      
      # ...省略...
      
      # 最终还是会保持 3 个 replicas 运行
      nginx-deployment-784b7cc96d-d6rdn   1/1     Running   0          87s
      nginx-deployment-784b7cc96d-fqzzp   1/1     Running   0          4m10s
      nginx-deployment-784b7cc96d-xrdz6   1/1     Running   0          2m46s
      
      # 再次查看详情,发现nginx的版本已经更新为 1.9.1 了
      [root@master-kubeadm-k8s deployment]# kubectl get deployment -o wide
      NAME               READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES        SELECTOR
      nginx-deployment   3/3     3            3           14m   nginx        nginx:1.9.1   app=nginx
      
      • Deployment 可确保在更新时仅关闭一定数量的 Pods。默认情况下,它确保至少 75%所需 Pods 运行(25%最大不可用)。
      • Deployment 还确保仅创建一定数量的 Pods 高于期望的 Pods 数。默认情况下,它可确保最多增加 25% 期望 Pods 数(25%最大增量)。
      • 如果仔细查看上述 Deployment ,将看到它首先创建了一个新的 Pod,然后删除了一些旧的 Pods,并创建了新的 Pods。它不会杀死老 Pods,直到有足够的数量新的 Pods 已经出现,并没有创造新的 Pods,直到足够数量的旧 Pods 被杀死。它确保至少 2 个 Pods 可用,并且总共最多 4 个 Pods 可用。

    控制器的几个组件就简单介绍到这里,其他命令与常用操作将会在后续章节慢慢的展开。

2.2.4 Labels and Selectors

在前面的 YAML 文件中,看到很多 label,顾名思义,就是给一些资源打上标签的。

  • 理解 Labels

    • 标签 是附加到 Kubernetes 对象(比如 Pods)上的键值对。
    • 标签旨在用于指定对用户有意义且相关的对象的标识属性,但不直接对核心系统有语义含义。
    • 标签可以用于组织和选择对象的子集。
    • 标签可以在创建时附加到对象,随后可以随时添加和修改。
    • 每个对象都可以定义一组键/值标签。每个键对于给定对象必须是唯一的。
  • 案例说明

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx-pod
      labels:
        app: nginx
    

    表示名称为 nginx-pod 的 pod,有一个label,key为app,value为 nginx。

    我们可以将具有同一个 label 的 pod,交给 selector 管理

  • selector

    selector 是选取具有同一个 label 的pod进行管理,相同 label 的Pod就是抽象层面的 Service

    • 案例说明

      apiVersion: apps/v1
      kind: Deployment
      metadata: 
        name: nginx-deployment
        labels:
          app: nginx
      spec:
        replicas: 3
        selector:             # 匹配具有同一个label属性的pod标签
          matchLabels:
            app: nginx         
        template:             # 定义pod的模板
          metadata:
            labels:
              app: nginx      # 定义当前pod的label属性,app为key,value为nginx
          spec:
            containers:
            - name: nginx
              image: nginx:1.7.9
              ports:
              - containerPort: 80
      

      如果 selector 匹配不到 label,运行将会报错

      将 上面 yaml文件中的 selector 匹配的标签改个名字:app: nginx1

      # 报错了,找不到匹配的标签
      [root@master-kubeadm-k8s deployment]# kubectl apply -f nginx_deployment.yaml
      The Deployment "nginx-deployment" is invalid: spec.template.metadata.labels: Invalid value: map[string]string{"app":"nginx"}: `selector` does not match template `labels`
      
    • 查看pod的 label 标签

      [root@master-kubeadm-k8s deployment]# kubectl get pods --show-labels
      NAME                                READY   STATUS    RESTARTS   AGE   LABELS
      nginx-deployment-784b7cc96d-d6rdn   1/1     Running   0          14m   app=nginx,pod-template-hash=784b7cc96d
      nginx-deployment-784b7cc96d-fqzzp   1/1     Running   0          17m   app=nginx,pod-template-hash=784b7cc96d
      nginx-deployment-784b7cc96d-xrdz6   1/1     Running   0          16m   app=nginx,pod-template-hash=784b7cc96d
      

3、Namespace

  • 理解 Namespace

    • Kubernetes 支持多个虚拟集群,它们底层依赖于同一个物理集群。 这些虚拟集群被称为命名空间。
    • 命名空间适用于存在很多跨多个团队或项目的用户的场景。对于只有几到几十个用户的集群,根本不需要创建或考虑命名空间。
    • 命名空间为名称提供了一个范围。资源的名称需要在命名空间内是唯一的,但不能跨命名空间。命名空间不能相互嵌套,每个 Kubernetes 资源只能在一个命名空间中。
    • 命名空间是在多个用户之间划分集群资源的一种方法。
    • 简单来说,Namespace 就是用来做资源隔离的。
  • 使用 Namespace

    • 查看

      # 在不指定命名空间的时候,K8S是默认从 default 命名空间查询 Pod
      # 当前还没有在 default 命名空间创建资源, 所以是空的
      [root@master-kubeadm-k8s deployment]# kubectl get pods
      No resources found.
          
      # 通过 -n kube-system 查看 K8S 系统命名空间
      # 这里是运行 K8S 所需的一些资源
      [root@master-kubeadm-k8s deployment]# kubectl get pods -n kube-system
      NAME                                         READY   STATUS    RESTARTS   AGE
      calico-kube-controllers-99f457df4-q7jlb      1/1     Running   2          3d15h
      calico-node-hbwbd                            1/1     Running   2          3d15h
      calico-node-pftqd                            1/1     Running   2          3d15h
      calico-node-tdspb                            1/1     Running   2          3d15h
      coredns-fb8b8dccf-gwqj9                      1/1     Running   2          3d16h
      coredns-fb8b8dccf-lj92j                      1/1     Running   2          3d16h
      etcd-master-kubeadm-k8s                      1/1     Running   2          3d16h
      kube-apiserver-master-kubeadm-k8s            1/1     Running   2          3d16h
      kube-controller-manager-master-kubeadm-k8s   1/1     Running   2          3d16h
      kube-proxy-9sxk6                             1/1     Running   2          3d15h
      kube-proxy-hh6hx                             1/1     Running   2          3d15h
      kube-proxy-hhnmc                             1/1     Running   2          3d16h
      kube-scheduler-master-kubeadm-k8s            1/1     Running   2          3d16h
      
      # 列出集群中现存的命名空间
      [root@master-kubeadm-k8s deployment]# kubectl get namespaces
      NAME              STATUS   AGE
      default           Active   3d16h
      kube-node-lease   Active   3d16h
      kube-public       Active   3d16h
      kube-system       Active   3d16h
      
      # default   没有指明使用其它命名空间的对象所使用的默认命名空间
      # kube-node-lease  这个官方没有文档说明,只知道是与心跳相关的
      # kube-system   Kubernetes系统创建对象所使用的命名空间
      # kube-public 
          # 这个命名空间是自动创建的,所有用户(包括未经过身份验证的用户)都可以读取它。
          # 这个命名空间主要用于集群使用,以防某些资源在整个集群中应该是可见和可读的。
      

      其实说白了,命名空间就是为了隔离不同的资源,比如:Pod、Service、Deployment等。可以在输入命令的时候指定命名空间 -n,如果不指定,则使用默认的命名空间:default。

    • 创建 Namespace

      • 一、YAML方式

        apiVersion: v1
        kind: Namespace   # 指定资源类型为 Namespace
        metadata:
          name: my-namespace-1
        
        # YAML方式创建命名空间
        [root@master-kubeadm-k8s namespace]# kubectl apply -f namespace.yaml
        namespace/my-namespace-1 created
        
        # 查看命名空间,可以看到新创建的 Namespace
        [root@master-kubeadm-k8s namespace]# kubectl get namespaces
        NAME              STATUS   AGE
        default           Active   3d16h
        kube-node-lease   Active   3d16h
        kube-public       Active   3d16h
        kube-system       Active   3d16h
        my-namespace-1    Active   12s
        
+ 二、命令方式

  ```ruby
  # 命令方式创建命名空间
  [root@master-kubeadm-k8s namespace]# kubectl create namespace my-namespace-2
  namespace/my-namespace-2 created
  
  # 同样也可以查看到新创建的命名空间
  [root@master-kubeadm-k8s namespace]# kubectl get namespaces
  NAME              STATUS   AGE
  default           Active   3d16h
  kube-node-lease   Active   3d16h
  kube-public       Active   3d16h
  kube-system       Active   3d16h
  my-namespace-1    Active   66s
  my-namespace-2    Active   3s
  ```

> **注意:**Namespace名称必须由小写字母数字字符或“-”组成,并且必须以字母数字字符(例如“ my-name”或“ 123-abc”)开头和结尾,用于验证的正则表达式为“ [a- z0-9]([-a-z0-9] * [a-z0-9])') 
  • 使用 Namespace

    • 创建资源指定命名空间

      apiVersion: v1
      kind: Pod
      metadata:
        name: nginx-pod
        namespace: my-namespace-1   # 指定命名空间
      spec:
        containers:
        - name: nginx-container
          image: nginx
          ports:
          - containerPort: 80
      
      # 创建 Pod
      [root@master-kubeadm-k8s namespace]# kubectl apply -f nginx-ns.yaml
      pod/nginx-pod created
      
    • 查看 Pod

      # 没有? 别忘了 Namespace 是资源隔离的,我们是指定了资源创建在哪个命名空间的
      # 这里默认是查询 default 命名空间,所以肯定是查不到的
      [root@master-kubeadm-k8s namespace]# kubectl get pods
      No resources found.
      
      # 通过 -n 指定我们创建的 Namespace 就可以查看到刚才创建的 Pod 了
      [root@master-kubeadm-k8s namespace]# kubectl get pods -n my-namespace-1
      NAME        READY   STATUS    RESTARTS   AGE
      nginx-pod   1/1     Running   0          111s
      
      # 通过 --all-namespaces 参数可以查询所有命名空间下的 Pod
      [root@master-kubeadm-k8s namespace]# kubectl get pods --all-namespaces
      NAMESPACE        NAME                                         READY   STATUS    RESTARTS   AGE
      kube-system      calico-kube-controllers-99f457df4-q7jlb      1/1     Running   2          3d15h
      kube-system      calico-node-hbwbd                            1/1     Running   2          3d15h
      kube-system      calico-node-pftqd                            1/1     Running   2          3d15h
      kube-system      calico-node-tdspb                            1/1     Running   2          3d15h
      kube-system      coredns-fb8b8dccf-gwqj9                      1/1     Running   2          3d16h
      kube-system      coredns-fb8b8dccf-lj92j                      1/1     Running   2          3d16h
      kube-system      etcd-master-kubeadm-k8s                      1/1     Running   2          3d16h
      kube-system      kube-apiserver-master-kubeadm-k8s            1/1     Running   2          3d16h
      kube-system      kube-controller-manager-master-kubeadm-k8s   1/1     Running   2          3d16h
      kube-system      kube-proxy-9sxk6                             1/1     Running   2          3d15h
      kube-system      kube-proxy-hh6hx                             1/1     Running   2          3d15h
      kube-system      kube-proxy-hhnmc                             1/1     Running   2          3d16h
      kube-system      kube-scheduler-master-kubeadm-k8s            1/1     Running   2          3d16h
      my-namespace-1   nginx-pod                                    1/1     Running   0          3m10s
      
  • 删除 Namespace

    [root@master-kubeadm-k8s namespace]# kubectl delete namespaces  my-namespace-1
    namespace "my-namespace-1" deleted
    

    注意:删除命名空间会删除命名空间下的 所有内容

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容