zoukankan      html  css  js  c++  java
  • 深入剖析Kubernetes学习笔记:Kubernetes集群搭建与实践(11)

    一、什么才是 Kubernetes 项目能“认识”的方式呢?

    1、这就是使用 Kubernetes 的必备技能:编写配置文件。

    备注:这些配置文件可以是 YAML 或者 JSON 格式的。为方便阅读与理解,在后面的讲解中,我会统一使用 YAML 文件来指代它们。

    Kubernetes 跟 Docker 等很多项目最大的不同,就在于它不推荐你使用命令行的方式直接运行容器(虽然 Kubernetes 项目也支持这种方式,比如:kubectl run),而是希望你用 YAML 文件的方式,即:把容器的定义、参数、配置,统统记录在一个 YAML 文件中,然后用这样一句指令把它运行起来:

    kubectl create -f 我的配置文件

    这么做最直接的好处是,你会有一个文件能记录下 Kubernetes 到底“run”了什么

    像这样的一个 YAML 文件,对应到 Kubernetes 中,就是一个 API Object(API 对象)。当你为这个对象的各个字段填好值并提交给 Kubernetes 之后,Kubernetes 就会负责创建出这些对象所定义的容器或者其他类型的 API 资源。

    2、Deployment

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
    spec:
      selector:
        matchLabels:
          app: nginx
      replicas: 2
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:1.7.9
            ports:
            - containerPort: 80

    可以看到,这个 YAML 文件中的 Kind 字段,指定了这个 API 对象的类型(Type),是一个 Deployment。

    所谓 Deployment,是一个定义多副本应用(即多个副本 Pod)的对象,我在前面的文章中(也是第 9 篇文章《从容器到容器云:谈谈 Kubernetes 的本质》)曾经简单提到过它的用法。

    此外,Deployment 还负责在 Pod 定义发生变化时,对每个副本进行滚动更新(Rolling Update)。

    在上面这个 YAML 文件中,我给它定义的 Pod 副本个数 (spec.replicas) 是:2。

    二、常用命令和应用发布

    1、kubectl get 获取(GET)指定的 API 对象

    $ kubectl get pods -l app=nginx
    NAME                                READY     STATUS    RESTARTS   AGE
    nginx-deployment-67594d6bf6-9gdvr   1/1       Running   0          10m
    nginx-deployment-67594d6bf6-v6j7w   1/1       Running   0          10m

    kubectl get 指令的作用,就是从 Kubernetes 里面获取(GET)指定的 API 对象。可以看到,在这里我还加上了一个 -l 参数,即获取所有匹配 app: nginx 标签的 Pod。

    需要注意的是,在命令行中,所有 key-value 格式的参数,都使用“=”而非“:”表示。

    2、kubectl describe 查看一个 API 对象的细节

    $ kubectl describe pod nginx-deployment-67594d6bf6-9gdvr
    Name:               nginx-deployment-67594d6bf6-9gdvr
    Namespace:          default
    Priority:           0
    PriorityClassName:  <none>
    Node:               node-1/10.168.0.3
    Start Time:         Thu, 16 Aug 2018 08:48:42 +0000
    Labels:             app=nginx
                        pod-template-hash=2315082692
    Annotations:        <none>
    Status:             Running
    IP:                 10.32.0.23
    Controlled By:      ReplicaSet/nginx-deployment-67594d6bf6
    ...
    Events:
     
      Type     Reason                  Age                From               Message
     
      ----     ------                  ----               ----               -------
      
      Normal   Scheduled               1m                 default-scheduler  Successfully assigned default/nginx-deployment-67594d6bf6-9gdvr to node-1
      Normal   Pulling                 25s                kubelet, node-1    pulling image "nginx:1.7.9"
      Normal   Pulled                  17s                kubelet, node-1    Successfully pulled image "nginx:1.7.9"
      Normal   Created                 17s                kubelet, node-1    Created container
      Normal   Started                 17s                kubelet, node-1    Started container

    在 kubectl describe 命令返回的结果中,你可以清楚地看到这个 Pod 的详细信息,比如它的 IP 地址等等。其中,有一个部分值得你特别关注,它就是Events(事件)。

    在 Kubernetes 执行的过程中,对 API 对象的所有重要操作,都会被记录在这个对象的 Events 里,并且显示在 kubectl describe 指令返回的结果中。

    比如,对于这个 Pod,我们可以看到它被创建之后,被调度器调度(Successfully assigned)到了 node-1,拉取了指定的镜像(pulling image),然后启动了 Pod 里定义的容器(Started container)。

    所以,这个部分正是我们将来进行 Debug 的重要依据。如果有异常发生,你一定要第一时间查看这些 Events,往往可以看到非常详细的错误信息。

    3、kubectl replace 变更更新

     $ kubectl replace -f nginx-deployment.yaml

    不推荐使用

    4、kubectl apply Kubernetes 对象的创建和更新操作

    $ kubectl apply -f nginx-deployment.yaml
    # 修改 nginx-deployment.yaml 的内容
    $ kubectl apply -f nginx-deployment.yaml

    这样的操作方法,是 Kubernetes“声明式 API”所推荐的使用方法。也就是说,作为用户,你不必关心当前的操作是创建,还是更新,你执行的命令始终是 kubectl apply,而 Kubernetes 则会根据 YAML 文件的内容变化,自动进行具体的处理。

    5、而这个流程的好处是:

    它有助于帮助开发和运维人员,围绕着可以版本化管理的 YAML 文件,而不是“行踪不定”的命令行进行协作,从而大大降低开发人员和运维人员之间的沟通成本。

    举个例子,一位开发人员开发好一个应用,制作好了容器镜像。那么他就可以在应用的发布目录里附带上一个 Deployment 的 YAML 文件。

    而运维人员,拿到这个应用的发布目录后,就可以直接用这个 YAML 文件执行 kubectl apply 操作把它运行起来。

    这时候,如果开发人员修改了应用,生成了新的发布内容,那么这个 YAML 文件,也就需要被修改,并且成为这次变更的一部分。

    而接下来,运维人员可以使用 git diff 命令查看到这个 YAML 文件本身的变化,然后继续用 kubectl apply 命令更新这个应用。

    所以说,如果通过容器镜像,我们能够保证应用本身在开发与部署环境里的一致性的话,那么现在,Kubernetes 项目通过这些 YAML 文件,就保证了应用的“部署参数”在开发与部署环境中的一致性。

    而当应用本身发生变化时,开发人员和运维人员可以依靠容器镜像来进行同步;当应用部署参数发生变化时,这些 YAML 文件就是他们相互沟通和信任的媒介。

    三、Volume

    在 Kubernetes 中,Volume 是属于 Pod 对象的一部分。所以,我们就需要修改这个 YAML 文件里的 template.spec 字段,如下所示:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
    spec:
      selector:
        matchLabels:
          app: nginx
      replicas: 2
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:1.8
            ports:
            - containerPort: 80
            volumeMounts:
            - mountPath: "/usr/share/nginx/html"
              name: nginx-vol
          volumes:
          - name: nginx-vol
            emptyDir: {}

    可以看到,我们在 Deployment 的 Pod 模板部分添加了一个 volumes 字段,定义了这个 Pod 声明的所有 Volume。它的名字叫作 nginx-vol,类型是 emptyDir

    1、那什么是 emptyDir 类型呢?

    它其实就等同于我们之前讲过的 Docker 的隐式 Volume 参数,即:不显式声明宿主机目录的 Volume。所以,Kubernetes 也会在宿主机上创建一个临时目录,这个目录将来就会被绑定挂载到容器所声明的 Volume 目录上。

    备注:不难看到,Kubernetes 的 emptyDir 类型,只是把 Kubernetes 创建的临时目录作为 Volume 的宿主机目录,交给了 Docker。这么做的原因,是 Kubernetes 不想依赖 Docker 自己创建的那个 _data 目录。

    而 Pod 中的容器,使用的是 volumeMounts 字段来声明自己要挂载哪个 Volume,并通过 mountPath 字段来定义容器内的 Volume 目录,比如:/usr/share/nginx/html。

    当然,Kubernetes 也提供了显式的 Volume 定义,它叫做 hostPath。比如下面的这个 YAML 文件:

    这样,容器 Volume 挂载的宿主机目录,就变成了 /var/data。

    在上述修改完成后,我们还是使用 kubectl apply 指令,更新这个 Deployment:

    $ kubectl apply -f nginx-deployment.yaml

    接下来,你可以通过 kubectl get 指令,查看两个 Pod 被逐一更新的过程:

    $ kubectl get pods
    NAME                                READY     STATUS              RESTARTS   AGE
    nginx-deployment-5c678cfb6d-v5dlh   0/1       ContainerCreating   0          4s
    nginx-deployment-67594d6bf6-9gdvr   1/1       Running             0          10m
    nginx-deployment-67594d6bf6-v6j7w   1/1       Running             0          10m
    $ kubectl get pods
    NAME                                READY     STATUS    RESTARTS   AGE
    nginx-deployment-5c678cfb6d-lg9lw   1/1       Running   0          8s
    nginx-deployment-5c678cfb6d-v5dlh   1/1       Running   0          19s

    从返回结果中,我们可以看到,新旧两个 Pod,被交替创建、删除,最后剩下的就是新版本的 Pod。

    然后,你可以使用 kubectl describe 查看一下最新的 Pod,就会发现 Volume 的信息已经出现在了 Container 描述部分:

    ...
    Containers:
      nginx:
        Container ID:   docker://07b4f89248791c2aa47787e3da3cc94b48576cd173018356a6ec8db2b6041343
        Image:          nginx:1.8
        ...
        Environment:    <none>
        Mounts:
          /usr/share/nginx/html from nginx-vol (rw)
    ...
    Volumes:
      nginx-vol:
        Type:    EmptyDir (a temporary directory that shares a pod's lifetime)

    备注:作为一个完整的容器化平台项目,Kubernetes 为我们提供的 Volume 类型远远不止这些,在容器存储章节里,我将会为你详细介绍这部分内容

    最后,你还可以使用 kubectl exec 指令,进入到这个 Pod 当中(即容器的 Namespace 中)查看这个 Volume 目录:

    $ kubectl exec -it nginx-deployment-5c678cfb6d-lg9lw -- /bin/bash
    # ls /usr/share/nginx/html

    此外,你想要从 Kubernetes 集群中删除这个 Nginx Deployment 的话,直接执行:

    $ kubectl delete -f nginx-deployment.yaml

    四、如果你想要快速熟悉 Kubernetes,请按照下面的流程进行练习:

    所以,如果你想要快速熟悉 Kubernetes,请按照下面的流程进行练习:

    首先,在本地通过 Docker 测试代码,制作镜像;
    然后,选择合适的 Kubernetes API 对象,编写对应 YAML 文件(比如,Pod,Deployment);
    最后,在 Kubernetes 上部署这个 YAML 文件。
    更重要的是,在部署到 Kubernetes 之后,接下来的所有操作,要么通过 kubectl 来执行,要么通过修改 YAML 文件来实现,就尽量不要再碰 Docker 的命令行了

  • 相关阅读:
    c:forTokens标签循环输出
    jsp转long类型为date,并且格式化
    spring中@Param和mybatis中@Param使用区别(暂时还没接触)
    734. Sentence Similarity 有字典数组的相似句子
    246. Strobogrammatic Number 上下对称的数字
    720. Longest Word in Dictionary 能连续拼接出来的最长单词
    599. Minimum Index Sum of Two Lists两个餐厅列表的索引和最小
    594. Longest Harmonious Subsequence强制差距为1的最长连续
    645. Set Mismatch挑出不匹配的元素和应该真正存在的元素
    409. Longest Palindrome 最长对称串
  • 原文地址:https://www.cnblogs.com/luoahong/p/12335304.html
Copyright © 2011-2022 走看看