Kubernetes - 快速指南


Kubernetes - 概述

Kubernetes 是由云原生计算基金会 (CNCF) 托管的开源容器管理工具。这也被称为 Borg 的增强版本,它是由 Google 开发的,用于管理长时间运行的进程和批处理作业,这些作业之前是由单独的系统处理的。

Kubernetes 具有跨集群自动化部署、应用程序扩展和应用程序容器操作的能力。它能够创建以容器为中心的基础设施。

库伯内特斯的特点

以下是 Kubernetes 的一些重要功能。

  • 继续开发、集成和部署

  • 集装箱化基础设施

  • 以应用为中心的管理

  • 自动扩展基础设施

  • 开发测试和生产环境的一致性

  • 松散耦合的基础设施,其中每个组件都可以充当单独的单元

  • 更高的资源利用密度

  • 将要创建的可预测的基础设施

Kubernetes 的关键组件之一是,它可以在物理和虚拟机基础设施集群上运行应用程序。它还具有在云上运行应用程序的能力。它有助于从以主机为中心的基础设施转向以容器为中心的基础设施。

Kubernetes - 架构

在本章中,我们将讨论 Kubernetes 的基本架构。

Kubernetes - 集群架构

如下图所示,Kubernetes 遵循客户端-服务器架构。其中,我们将master安装在一台机器上,将node安装在不同的Linux机器上。

集群架构

主节点和节点的关键组件在下面的部分中定义。

Kubernetes - 主控机组件

以下是 Kubernetes Master Machine 的组件。

它存储可供集群中每个节点使用的配置信息。它是一个高可用性键值存储,可以分布在多个节点之间。它只能由 Kubernetes API 服务器访问,因为它可能包含一些敏感信息。它是一个所有人都可以访问的分布式键值存储。

API服务器

Kubernetes是一个API服务器,它使用API​​提供集群上的所有操作。API服务器实现了一个接口,这意味着不同的工具和库可以轻松地与其通信。Kubeconfig是一个软件包以及可用于通信的服务器端工具。它公开 Kubernetes API。

控制器经理

该组件负责调节集群状态并执行任务的大多数收集器。一般来说,它可以被认为是一个以不间断循环运行的守护进程,负责收集信息并将其发送到API服务器。它致力于获取集群的共享状态,然后进行更改以使服务器的当前状态达到所需的状态。关键控制器是复制控制器、端点控制器、命名空间控制器和服务帐户控制器。控制器管理器运行不同类型的控制器来处理节点、端点等。

调度程序

这是 Kubernetes master 的关键组件之一。它是 master 中的一个服务,负责分配工作负载。它负责跟踪集群节点上工作负载的利用率,然后将工作负载放置在可用资源上并接受工作负载。换句话说,这是负责将 pod 分配给可用节点的机制。调度程序负责工作负载利用率并将 Pod 分配给新节点。

Kubernetes - 节点组件

以下是与 Kubernetes master 通信所需的 Node 服务器的关键组件。

码头工人

每个节点的首要需求是Docker,它有助于在相对隔离但轻量级的运行环境中运行封装的应用程序容器。

库贝莱特服务

这是每个节点中的一个小型服务,负责在控制平面服务之间转发信息。它与etcd存储交互以读取配置详细信息和 wright 值。它与主组件通信以接收命令并工作。然后, kubelet进程承担维护工作状态和节点服务器的责任。它管理网络规则、端口转发等。

Kubernetes 代理服务

这是一个在每个节点上运行的代理服务,有助于向外部主机提供服务。它有助于将请求转发到正确的容器,并且能够执行原始负载平衡。它确保网络环境是可预测和可访问的,同时它也是隔离的。它管理节点上的 pod、卷、秘密、创建新容器的健康检查等。

Kubernetes - 主节点和节点结构

下图展示了 Kubernetes Master 和 Node 的结构。

主节点结构

Kubernetes - 设置

在设置 Kubernetes 之前设置虚拟数据中心 (vDC) 非常重要。这可以被视为一组机器,它们可以通过网络相互通信。对于实践方法,如果您没有设置物理或云基础设施,则可以在PROFITBRICKS上设置 vDC。

在任何云上完成 IaaS 设置后,您需要配置MasterNode

注意- 显示的是 Ubuntu 机器的设置。也可以在其他 Linux 机器上进行同样的设置。

先决条件

安装 Docker - Kubernetes 的所有实例都需要 Docker。以下是安装 Docker 的步骤。

步骤 1 - 使用 root 用户帐户登录到计算机。

步骤 2 - 更新包信息。确保 apt 软件包正在运行。

步骤 3 - 运行以下命令。

$ sudo apt-get update
$ sudo apt-get install apt-transport-https ca-certificates

步骤 4 - 添加新的 GPG 密钥。

$ sudo apt-key adv \
   --keyserver hkp://ha.pool.sks-keyservers.net:80 \
   --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
$ echo "deb https://apt.dockerproject.org/repo ubuntu-trusty main" | sudo tee
/etc/apt/sources.list.d/docker.list

步骤 5 - 更新 API 包映像。

$ sudo apt-get update

完成上述所有任务后,就可以开始实际安装Docker引擎了。不过,在此之前您需要验证您使用的内核版本是否正确。

安装 Docker 引擎

运行以下命令安装Docker引擎。

步骤 1 - 登录到计算机。

步骤 2 - 更新包索引。

$ sudo apt-get update

步骤 3 - 使用以下命令安装 Docker 引擎。

$ sudo apt-get install docker-engine

步骤 4 - 启动 Docker 守护进程。

$ sudo apt-get install docker-engine

步骤 5 - 要确定 Docker 是否已安装,请使用以下命令。

$ sudo docker run hello-world

安装etcd 2.0

这需要安装在 Kubernetes Master Machine 上。要安装它,请运行以下命令。

$ curl -L https://github.com/coreos/etcd/releases/download/v2.0.0/etcd
-v2.0.0-linux-amd64.tar.gz -o etcd-v2.0.0-linux-amd64.tar.gz ->1
$ tar xzvf etcd-v2.0.0-linux-amd64.tar.gz ------>2
$ cd etcd-v2.0.0-linux-amd64 ------------>3
$ mkdir /opt/bin ------------->4
$ cp etcd* /opt/bin ----------->5

在上面的命令集中 -

  • 首先,我们下载etcd。使用指定的名称保存它。
  • 然后,我们必须解压 tar 包。
  • 我们创建一个目录。在 /opt 名为 bin 内。
  • 将提取的文件复制到目标位置。

现在我们已经准备好构建 Kubernetes。我们需要在集群中的所有机器上安装 Kubernetes。

$ git clone https://github.com/GoogleCloudPlatform/kubernetes.git
$ cd kubernetes
$ make release

上面的命令将在 kubernetes 文件夹的根目录中创建一个_output目录。接下来,我们可以将该目录解压到我们选择的任何目录/opt/bin等目录中。

接下来是网络部分,我们需要实际开始设置 Kubernetes 主节点和节点。为了做到这一点,我们将在主机文件中创建一个条目,这可以在节点机器上完成。

$ echo "<IP address of master machine> kube-master
< IP address of Node Machine>" >> /etc/hosts

以下是上述命令的输出。

输出

现在,我们开始在 Kubernetes Master 上进行实际配置。

首先,我们将开始将所有配置文件复制到正确的位置。

$ cp <Current dir. location>/kube-apiserver /opt/bin/
$ cp <Current dir. location>/kube-controller-manager /opt/bin/
$ cp <Current dir. location>/kube-kube-scheduler /opt/bin/
$ cp <Current dir. location>/kubecfg /opt/bin/
$ cp <Current dir. location>/kubectl /opt/bin/
$ cp <Current dir. location>/kubernetes /opt/bin/

上述命令会将所有配置文件复制到所需位置。现在我们将返回到构建 Kubernetes 文件夹的同一目录。

$ cp kubernetes/cluster/ubuntu/init_conf/kube-apiserver.conf /etc/init/
$ cp kubernetes/cluster/ubuntu/init_conf/kube-controller-manager.conf /etc/init/
$ cp kubernetes/cluster/ubuntu/init_conf/kube-kube-scheduler.conf /etc/init/

$ cp kubernetes/cluster/ubuntu/initd_scripts/kube-apiserver /etc/init.d/
$ cp kubernetes/cluster/ubuntu/initd_scripts/kube-controller-manager /etc/init.d/
$ cp kubernetes/cluster/ubuntu/initd_scripts/kube-kube-scheduler /etc/init.d/

$ cp kubernetes/cluster/ubuntu/default_scripts/kubelet /etc/default/
$ cp kubernetes/cluster/ubuntu/default_scripts/kube-proxy /etc/default/
$ cp kubernetes/cluster/ubuntu/default_scripts/kubelet /etc/default/

下一步是更新 /etc 下复制的配置文件。目录。

使用以下命令在 master 上配置 etcd。

$ ETCD_OPTS = "-listen-client-urls = http://kube-master:4001"

配置 kube-apiserver

为此,我们需要编辑之前复制的/etc/default/kube-apiserver文件。

$ KUBE_APISERVER_OPTS = "--address = 0.0.0.0 \
--port = 8080 \
--etcd_servers = <The path that is configured in ETCD_OPTS> \
--portal_net = 11.1.1.0/24 \
--allow_privileged = false \
--kubelet_port = < Port you want to configure> \
--v = 0"

配置 kube 控制器管理器

我们需要在/etc/default/kube-controller-manager中添加以下内容。

$ KUBE_CONTROLLER_MANAGER_OPTS = "--address = 0.0.0.0 \
--master = 127.0.0.1:8080 \
--machines = kube-minion \ -----> #this is the kubernatics node
--v = 0

接下来,在相应的文件中配置kube调度器。

$ KUBE_SCHEDULER_OPTS = "--address = 0.0.0.0 \
--master = 127.0.0.1:8080 \
--v = 0"

完成上述所有任务后,我们就可以继续启动 Kubernetes Master。为此,我们将重新启动 Docker。

$ service docker restart

Kubernetes 节点配置

Kubernetes 节点将运行两个服务kubelet 和 kube-proxy。在继续之前,我们需要将下载的二进制文件复制到我们要配置 kubernetes 节点的所需文件夹中。

使用与我们为 kubernetes master 所做的相同方法复制文件。由于它只会运行 kubelet 和 kube-proxy,因此我们将配置它们。

$ cp <Path of the extracted file>/kubelet /opt/bin/
$ cp <Path of the extracted file>/kube-proxy /opt/bin/
$ cp <Path of the extracted file>/kubecfg /opt/bin/
$ cp <Path of the extracted file>/kubectl /opt/bin/
$ cp <Path of the extracted file>/kubernetes /opt/bin/

现在,我们将内容复制到适当的目录。

$ cp kubernetes/cluster/ubuntu/init_conf/kubelet.conf /etc/init/
$ cp kubernetes/cluster/ubuntu/init_conf/kube-proxy.conf /etc/init/
$ cp kubernetes/cluster/ubuntu/initd_scripts/kubelet /etc/init.d/
$ cp kubernetes/cluster/ubuntu/initd_scripts/kube-proxy /etc/init.d/
$ cp kubernetes/cluster/ubuntu/default_scripts/kubelet /etc/default/
$ cp kubernetes/cluster/ubuntu/default_scripts/kube-proxy /etc/default/

我们将配置kubeletkube-proxy conf文件。

我们将配置/etc/init/kubelet.conf

$ KUBELET_OPTS = "--address = 0.0.0.0 \
--port = 10250 \
--hostname_override = kube-minion \
--etcd_servers = http://kube-master:4001 \
--enable_server = true
--v = 0"
/

对于 kube-proxy,我们将使用以下命令进行配置。

$ KUBE_PROXY_OPTS = "--etcd_servers = http://kube-master:4001 \
--v = 0"
/etc/init/kube-proxy.conf

最后,我们将重新启动 Docker 服务。

$ service docker restart

现在我们已经完成了配置。您可以通过运行以下命令进行检查。

$ /opt/bin/kubectl get minions

Kubernetes - 图像

Kubernetes (Docker) 镜像是容器化基础设施的关键构建块。截至目前,我们仅支持 Kubernetes 来支持 Docker 镜像。Pod 中的每个容器都在其中运行其 Docker 映像。

当我们配置 Pod 时,配置文件中的 image 属性与 Docker 命令的语法相同。配置文件有一个字段来定义图像名称,我们计划从注册表中提取该名称。

以下是常见的配置结构,它将从 Docker 注册表中提取映像并将其部署到 Kubernetes 容器中。

apiVersion: v1
kind: pod
metadata:
   name: Tesing_for_Image_pull -----------> 1
   spec:
      containers:
         - name: neo4j-server ------------------------> 2
         image: <Name of the Docker image>----------> 3
         imagePullPolicy: Always ------------->4
         command: ["echo", "SUCCESS"] ------------------->

在上面的代码中,我们定义了 -

  • name: Tesing_for_Image_pull - 指定此名称是为了识别和检查从 Docker 注册表拉取映像后将创建的容器的名称。

  • name: neo4j-server - 这是我们尝试创建的容器的名称。就像我们提供的 neo4j-server 一样。

  • image: <Name of the Docker image> - 这是我们尝试从 Docker 或内部镜像注册表中提取的镜像的名称。我们需要定义一个完整的注册表路径以及我们尝试提取的图像名称。

  • imagePullPolicy - 始终 - 此图像拉取策略定义每当我们运行此文件来创建容器时,它将再次拉取相同的名称。

  • command: [“echo”, “SUCCESS”] - 这样,当我们创建容器时,如果一切顺利,当我们访问容器时,它将显示一条消息。

为了拉取映像并创建容器,我们将运行以下命令。

$ kubectl create –f Tesing_for_Image_pull

一旦我们获取日志,我们将得到成功的输出。

$ kubectl log Tesing_for_Image_pull

上面的命令将产生成功的输出,否则我们将得到失败的输出。

注意- 建议您亲自尝试所有命令。

Kubernetes - 工作

作业的主要功能是创建一个或多个 Pod 并跟踪 Pod 的成功情况。它们确保指定数量的 Pod 成功完成。当指定数量的 pod 成功运行完成后,该作业即被视为完成。

创造就业机会

使用以下命令创建作业 -

apiVersion: v1
kind: Job ------------------------> 1
metadata:
   name: py
   spec:
   template:
      metadata
      name: py -------> 2
      spec:
         containers:
            - name: py ------------------------> 3
            image: python----------> 4
            command: ["python", "SUCCESS"]
            restartPocliy: Never --------> 5

在上面的代码中,我们定义了 -

  • kind: Job →我们将 kind 定义为 Job,它会告诉kubectl正在使用的yaml文件是为了创建一个作业类型 pod。

  • Name:py →这是我们正在使用的模板的名称,规范定义了该模板。

  • name: py →我们在容器规范下给定了一个名称py,这有助于识别将要从中创建的 Pod。

  • 图像:python →我们将提取用于创建将在 pod 内运行的容器的图像。

  • restartPolicy: Never →镜像重启的条件为 never,这意味着如果容器被杀死或者为 false,则它不会自行重启。

我们将使用以下命令和 yaml 创建作业,并以名称py.yaml保存。

$ kubectl create –f py.yaml

上面的命令将创建一个作业。如果要检查作业的状态,请使用以下命令。

$ kubectl describe jobs/py

上面的命令将创建一个作业。如果要检查作业的状态,请使用以下命令。

预定工作

Kubernetes 中的计划作业使用Cronetes,它接受 Kubernetes 作业并在 Kubernetes 集群中启动它们。

  • 调度作业将在指定时间点运行 Pod。
  • 为其创建一个模仿作业,该作业会自动调用自身。

注意- 版本 1.4 支持计划作业的功能,并且在启动 API 服务器时通过传递–runtime-config=batch/v2alpha1来打开 betch/v2alpha 1 API 。

我们将使用与创建作业相同的 yaml 并将其设为计划作业。

apiVersion: v1
kind: Job
metadata:
   name: py
spec:
   schedule: h/30 * * * * ? -------------------> 1
   template:
      metadata
         name: py
      spec:
         containers:
         - name: py
         image: python
         args:
/bin/sh -------> 2
-c
ps –eaf ------------> 3
restartPocliy: OnFailure

在上面的代码中,我们定义了 -

  • 时间表:h/30 * * * * ? → 安排作业每 30 分钟运行一次。

  • /bin/sh:这将进入带有/bin/sh的容器

  • ps –eaf →将在计算机上运行 ps -eaf 命令并列出容器内所有正在运行的进程。

当我们尝试在指定时间点构建和运行一组任务然后完成该过程时,此计划作业概念非常有用。

Kubernetes - 标签和选择器

标签

标签是附加到 Pod、复制控制器和服务的键值对。它们用作 Pod 和复制控制器等对象的标识属性。它们可以在创建时添加到对象中,也可以在运行时添加或修改。

选择器

标签不提供唯一性。一般来说,我们可以说许多对象可以带有相同的标签。标签选择器是 Kubernetes 中的核心分组原语。用户使用它们来选择一组对象。

Kubernetes API 目前支持两种类型的选择器 -

  • 基于平等的选择器
  • 基于集合的选择器

基于平等的选择器

它们允许按键和值进行过滤。匹配对象应满足所有指定的标签。

基于集合的选择器

基于集合的选择器允许根据一组值过滤键。

apiVersion: v1
kind: Service
metadata:
   name: sp-neo4j-standalone
spec:
   ports:
      - port: 7474
      name: neo4j
   type: NodePort
   selector:
      app: salesplatform ---------> 1
      component: neo4j -----------> 2

在上面的代码中,我们使用标签选择器作为app: salesplatform,使用组件作为component: neo4j

一旦我们使用kubectl命令运行该文件,它将创建一个名为sp-neo4j-standalone 的服务,该服务将在端口 7474 上进行通信。类型为NodePort,新标签选择器为app: salesplatformcomponent: neo4j

Kubernetes - 命名空间

命名空间为资源名称提供了额外的限定。当多个团队使用同一个集群并且可能存在名称冲突时,这非常有用。它可以作为多个集群之间的虚拟墙。

命名空间的功能

以下是 Kubernetes 中命名空间的一些重要功能 -

  • 命名空间有助于使用相同的命名空间进行 Pod 到 Pod 的通信。

  • 命名空间是可以位于同一物理集群之上的虚拟集群。

  • 它们在团队及其环境之间提供逻辑分离。

创建命名空间

以下命令用于创建命名空间。

apiVersion: v1
kind: Namespce
metadata
   name: elk

控制命名空间

以下命令用于控制命名空间。

$ kubectl create –f namespace.yml ---------> 1
$ kubectl get namespace -----------------> 2
$ kubectl get namespace <Namespace name> ------->3
$ kubectl describe namespace <Namespace name> ---->4
$ kubectl delete namespace <Namespace name>

在上面的代码中,

  • 我们正在使用该命令来创建命名空间。
  • 这将列出所有可用的命名空间。
  • 这将获得一个特定的命名空间,其名称在命令中指定。
  • 这将描述有关服务的完整详细信息。
  • 这将删除集群中存在的特定命名空间。

在服务中使用命名空间 - 示例

以下是在服务中使用命名空间的示例文件示例。

apiVersion: v1
kind: Service
metadata:
   name: elasticsearch
   namespace: elk
   labels:
      component: elasticsearch
spec:
   type: LoadBalancer
   selector:
      component: elasticsearch
   ports:
   - name: http
      port: 9200
      protocol: TCP
   - name: transport
      port: 9300
      protocol: TCP

在上面的代码中,我们在服务元数据下使用名称为elk的相同命名空间。

Kubernetes-节点

节点是 Kubernetes 集群中的一台工作机器,也称为 Minion。它们是工作单元,可以是物理、虚拟机或云实例。

每个节点都具有在其上运行 pod 所需的所有配置,例如代理服务和 kubelet 服务以及 Docker,用于在节点上创建的 pod 上运行 Docker 容器。

它们不是由 Kubernetes 创建的,而是由云服务提供商或物理机或虚拟机上的 Kubernetes 集群管理器在外部创建的。

Kubernetes 处理多个节点的关键组件是控制器管理器,它运行多种控制器来管理节点。为了管理节点,Kubernetes 创建一个节点对象,该对象将验证创建的对象是否是有效节点。

带选择器的服务

apiVersion: v1
kind: node
metadata:
   name: < ip address of the node>
   labels:
      name: <lable name>

以 JSON 格式创建实际对象,如下所示 -

{
   Kind: node
   apiVersion: v1
   "metadata": 
   {
      "name": "10.01.1.10",
      "labels"
      {
         "name": "cluster 1 node"
      }
   }
}

节点控制器

它们是在 Kubernetes master 中运行的服务的集合,并根据metadata.name持续监控集群中的节点。如果所有必需的服务都在运行,则该节点将得到验证,控制器将向该节点分配新创建的 Pod。如果它无效,那么master将不会为其分配任何pod,并且会等待它变得有效。

如果–register-node标志为 true ,Kubernetes master 会自动注册节点。

–register-node = true

然而,如果集群管理员想要手动管理它,那么可以通过转动平面来完成 -

–register-node = false

Kubernetes-服务

服务可以定义为 Pod 的逻辑集。它可以被定义为 Pod 顶部的抽象,它提供可以访问 Pod 的单个 IP 地址和 DNS 名称。通过Service,管理负载均衡配置变得非常容易。它可以帮助 Pod 轻松扩展。

服务是 Kubernetes 中的 REST 对象,其定义可以发布到 Kubernetes master 上的 Kubernetes apiServer 以创建新实例。

不带选择器的服务

apiVersion: v1
kind: Service
metadata:
   name: Tutorial_point_service
spec:
   ports:
   - port: 8080
   targetPort: 31999

上面的配置将创建一个名为Tutorial_point_service的服务。

带有选择器的服务配置文件

apiVersion: v1
kind: Service
metadata:
   name: Tutorial_point_service
spec:
   selector:
      application: "My Application" -------------------> (Selector)
   ports:
   - port: 8080
   targetPort: 31999

在这个例子中,我们有一个选择器;所以为了传输流量,我们需要手动创建一个端点。

apiVersion: v1
kind: Endpoints
metadata:
   name: Tutorial_point_service
subnets:
   address:
      "ip": "192.168.168.40" -------------------> (Selector)
   ports:
      - port: 8080

在上面的代码中,我们创建了一个端点,它将流量路由到定义为“192.168.168.40:8080”的端点。

多端口服务创建

apiVersion: v1
kind: Service
metadata:
   name: Tutorial_point_service
spec:
   selector:
      application: “My Application” -------------------> (Selector)
   ClusterIP: 10.3.0.12
   ports:
      -name: http
      protocol: TCP
      port: 80
      targetPort: 31999
   -name:https
      Protocol: TCP
      Port: 443
      targetPort: 31998

服务类型

ClusterIP - 这有助于限制集群内的服务。它公开定义的 Kubernetes 集群中的服务。

spec:
   type: NodePort
   ports:
   - port: 8080
      nodePort: 31999
      name: NodeportService

NodePort - 它将在已部署节点上的静态端口上公开服务。NodePort服务将路由到的ClusterIP服务会自动创建。可以使用NodeIP:nodePort从集群外部访问该服务。

spec:
   ports:
   - port: 8080
      nodePort: 31999
      name: NodeportService
      clusterIP: 10.20.30.40

负载均衡器- 它使用云提供商的负载均衡器。NodePortClusterIP服务是自动创建的,外部负载均衡器将路由到这些服务。

服务类型为节点端口的完整服务yaml文件。尝试自己创建一个。

apiVersion: v1
kind: Service
metadata:
   name: appname
   labels:
      k8s-app: appname
spec:
   type: NodePort
   ports:
   - port: 8080
      nodePort: 31999
      name: omninginx
   selector:
      k8s-app: appname
      component: nginx
      env: env_name

Kubernetes-Pod

Pod 是 Kubernetes 集群节点内容器及其存储的集合。可以创建一个内部包含多个容器的 Pod。例如,将数据库容器和数据容器保留在同一个 pod 中。

Pod 类型

Pod 有两种类型 -

  • 单容器吊舱
  • 多容器 Pod

单集装箱吊舱

它们可以使用 kubctl run 命令简单地创建,您在 Docker 注册表上有一个定义的映像,我们将在创建 pod 时拉取该映像。

$ kubectl run <name of pod> --image=<name of the image from registry>

示例- 我们将使用 Docker hub 上提供的 tomcat 映像创建一个 pod。

$ kubectl run tomcat --image = tomcat:8.0

这也可以通过创建yaml文件然后运行​​kubectl create命令来完成。

apiVersion: v1
kind: Pod
metadata:
   name: Tomcat
spec:
   containers:
   - name: Tomcat
    image: tomcat: 8.0
    ports:
containerPort: 7500
   imagePullPolicy: Always

创建上述yaml文件后,我们将以tomcat.yml的名称保存该文件,并运行 create 命令来运行该文档。

$ kubectl create –f tomcat.yml

它将创建一个名为 tomcat 的 pod。我们可以使用describe命令和kubectl来描述pod。

多集装箱吊舱

多容器 Pod 是使用带有容器定义的yaml 邮件创建的。

apiVersion: v1
kind: Pod
metadata:
   name: Tomcat
spec:
   containers:
   - name: Tomcat
    image: tomcat: 8.0
    ports:
containerPort: 7500
   imagePullPolicy: Always
   -name: Database
   Image: mongoDB
   Ports:
containerPort: 7501
   imagePullPolicy: Always

在上面的代码中,我们创建了一个 pod,里面有两个容器,一个用于 tomcat,另一个用于 MongoDB。

Kubernetes - 复制控制器

Replication Controller 是 Kubernetes 的关键功能之一,负责管理 Pod 生命周期。它负责确保指定数量的 Pod 副本在任何时间点都在运行。当需要确保指定数量的 pod 或至少有 1 个 pod 正在运行时,可以及时使用。它能够增加或减少指定的 Pod 数量。

最佳实践是使用复制控制器来管理 Pod 生命周期,而不是一次又一次地创建 Pod。

apiVersion: v1
kind: ReplicationController --------------------------> 1
metadata:
   name: Tomcat-ReplicationController --------------------------> 2
spec:
   replicas: 3 ------------------------> 3
   template:
      metadata:
         name: Tomcat-ReplicationController
      labels:
         app: App
         component: neo4j
      spec:
         containers:
         - name: Tomcat- -----------------------> 4
         image: tomcat: 8.0
         ports:
            - containerPort: 7474 ------------------------> 5

设置详情

  • 种类:ReplicationController →上面的代码中,我们将种类定义为复制控制器,它告诉 kubectl yaml文件将用于创建复制控制器。

  • 名称:Tomcat-ReplicationController → 这有助于识别创建复制控制器时使用的名称。如果我们运行 kubctl,获取rc < Tomcat-ReplicationController >它将显示复制控制器的详细信息。

  • 副本:3 → 这有助于复制控制器了解它需要在 Pod 生命周期的任何时间点维护 Pod 的三个副本。

  • name: Tomcat → 在规范部分,我们将名称定义为 tomcat,它将告诉复制控制器 pod 内存在的容器是 tomcat。

  • 容器端口:7474 → 它有助于确保集群中 pod 运行容器的所有节点都将在同一端口 7474 上公开。

Kube 副本服务

在这里,Kubernetes 服务充当三个 tomcat 副本的负载均衡器。

Kubernetes - 副本集

副本集确保应该运行多少个 pod 副本。它可以被认为是复制控制器的替代品。副本集和复制控制器之间的主要区别在于,复制控制器仅支持基于相等的选择器,而副本集支持基于集的选择器。

apiVersion: extensions/v1beta1 --------------------->1
kind: ReplicaSet --------------------------> 2
metadata:
   name: Tomcat-ReplicaSet
spec:
   replicas: 3
   selector:
      matchLables:
         tier: Backend ------------------> 3
      matchExpression:
{ key: tier, operation: In, values: [Backend]} --------------> 4
template:
   metadata:
      lables:
         app: Tomcat-ReplicaSet
         tier: Backend
      labels:
         app: App
         component: neo4j
   spec:
      containers:
      - name: Tomcat
      image: tomcat: 8.0
      ports:
      - containerPort: 7474

设置详情

  • apiVersion: Extensions/v1beta1 → 在上面的代码中,API 版本是 Kubernetes 的高级 beta 版本,支持副本集的概念。

  • kind: ReplicaSet → 我们将 kind 定义为副本集,这有助于 kubectl 理解该文件用于创建副本集。

  • tier:后端→ 我们将标签层定义为后端,它创建一个匹配的选择器。

  • {key: tier, operation: In, value: [Backend]} → 这将帮助matchExpression理解我们定义的匹配条件以及matchlabel用于查找详细信息的操作。

使用kubectl运行上述文件,并使用yaml文件中提供的定义创建后端副本集。

Kube 服务后端复制集

Kubernetes - 部署

部署已升级,复制控制器版本更高。它们管理副本集的部署,这也是复制控制器的升级版本。他们有能力更新副本集,也有能力回滚到以前的版本。

他们提供了matchLabels选择器的许多更新功能。我们在 Kubernetes master 中有一个新的控制器,称为部署控制器,它可以实现这一点。它有能力中途改变部署。

更改部署

更新- 用户可以在完成之前更新正在进行的部署。在此,将解决现有部署并创建新部署。

删除- 用户可以通过在完成之前删除部署来暂停/取消部署。重新创建相同的部署将恢复它。

回滚- 我们可以回滚部署或正在进行的部署。用户可以使用DeploymentSpec.PodTemplateSpec = oldRC.PodTemplateSpec 创建或更新部署。

部署策略

部署策略有助于定义新的 RC 应如何替换现有的 RC。

重新创建- 此功能将杀死所有现有的 RC,然后启动新的。这会导致快速部署,但当旧 Pod 关闭且新 Pod 尚未启动时,会导致停机。

滚动更新- 此功能逐渐降低旧的 RC 并推出新的 RC。这会导致部署缓慢,但是却没有部署。在任何时候,在此过程中都很少有旧 pod 和新 pod 可用。

Deployment的配置文件如下所示。

apiVersion: extensions/v1beta1 --------------------->1
kind: Deployment --------------------------> 2
metadata:
   name: Tomcat-ReplicaSet
spec:
   replicas: 3
   template:
      metadata:
         lables:
            app: Tomcat-ReplicaSet
            tier: Backend
   spec:
      containers:
         - name: Tomcatimage:
            tomcat: 8.0
            ports:
               - containerPort: 7474

在上面的代码中,与副本集唯一不同的是我们将其定义为部署。

创建部署

$ kubectl create –f Deployment.yaml -–record
deployment "Deployment" created Successfully.

获取部署

$ kubectl get deployments
NAME           DESIRED     CURRENT     UP-TO-DATE     AVILABLE    AGE
Deployment        3           3           3              3        20s

检查部署状态

$ kubectl rollout status deployment/Deployment

更新部署

$ kubectl set image deployment/Deployment tomcat=tomcat:6.0

回滚到之前的部署

$ kubectl rollout undo deployment/Deployment –to-revision=2

Kubernetes - 卷

在 Kubernetes 中,卷可以被视为 pod 中的容器可以访问的目录。Kubernetes 中有不同类型的卷,类型定义了卷的创建方式及其内容。

Docker 中存在卷的概念,但唯一的问题是卷非常限于特定的 pod。一旦 Pod 的寿命结束,体积也会丢失。

另一方面,通过 Kubernetes 创建的卷不限于任何容器。它支持部署在 Kubernetes 的 Pod 内的任何或所有容器。Kubernetes 卷的一个关键优势是,它支持不同类型的存储,其中 pod 可以同时使用多个存储。

Kubernetes 卷的类型

以下是一些流行的 Kubernetes 卷的列表 -

  • emptyDir - 它是一种在 Pod 首次分配给节点时创建的卷。只要 Pod 在该节点上运行,它就会保持活动状态。该卷最初是空的,pod 中的容器可以读取和写入emptyDir 卷中的文件。一旦 Pod 从节点中删除,emptyDir 中的数据就会被删除。

  • hostPath - 这种类型的卷将文件或目录从主机节点的文件系统安装到您的 Pod 中。

  • gcePersistentDisk - 这种类型的卷将 Google 计算引擎 (GCE) 持久磁盘安装到您的 Pod 中。当 Pod 从节点中删除时,gcePersistentDisk中的数据保持不变。

  • awsElasticBlockStore - 这种类型的卷将 Amazon Web Services (AWS) 弹性块存储安装到您的 Pod 中。就像gcePersistentDisk一样,当 Pod 从节点中删除时,awsElasticBlockStore中的数据保持不变。

  • nfs - nfs卷允许将现有的 NFS(网络文件系统)安装到您的 pod 中。当 Pod 从节点中删除时, nfs卷中的数据不会被删除。仅卸载该卷。

  • iscsi - iscsi卷允许将现有的 iSCSI(SCSI over IP)卷安装到您的 Pod 中。

  • folcker - 它是一个开源集群容器数据卷管理器。它用于管理数据量。Flocker卷允许将 Flocker 数据集挂载到 Pod 中如果Flocker中不存在该数据集,那么您首先需要使用Flocker API创建它。

  • glusterfs - Glusterfs 是一个开源网络文件系统。glusterfs 卷允许将 glusterfs 卷安装到您的 pod 中。

  • rbd - RBD 代表 Rados 块设备。rbd卷允许将 Rados 块设备卷挂载到您的 pod 中。Pod 从节点中删除后,数据仍然保留。

  • cephfs - cephfs卷允许将现有的 CephFS 卷安装到您的 pod 中。Pod 从节点中删除后,数据保持不变。

  • gitRepo - gitRepo卷安装一个空目录并将git存储库克隆到其中供您的 pod 使用。

  • Secret -秘密卷用于将敏感信息(例如密码)传递给 Pod。

  • permanentVolumeClaim - permanentVolumeClaim卷用于将 PersistentVolume 挂载到 Pod 中。PersistentVolume 是用户在不了解特定云环境详细信息的情况下“声明”持久存储(例如 GCE PersistentDisk 或 iSCSI 卷)的一种方式。

  • DownAPI - DownAPI卷用于使向下 API 数据可供应用程序使用。它安装一个目录并将请求的数据写入纯文本文件。

  • azureDiskVolume - AzureDiskVolume用于将 Microsoft Azure 数据磁盘安装到 Pod 中。

持久卷和持久卷声明

持久卷(PV) - 它是由管理员配置的一块网络存储。它是集群中的一种资源,独立于使用 PV 的任何单个 pod。

持久卷声明 (PVC) - Kubernetes 为其 Pod 请求的存储称为 PVC。用户不需要了解底层配置。声明必须在创建 pod 的同一命名空间中创建。

创建持久卷

kind: PersistentVolume ---------> 1
apiVersion: v1
metadata:
   name: pv0001 ------------------> 2
   labels:
      type: local
spec:
   capacity: -----------------------> 3
      storage: 10Gi ----------------------> 4
   accessModes:
      - ReadWriteOnce -------------------> 5
      hostPath:
         path: "/tmp/data01" --------------------------> 6

在上面的代码中,我们定义了 -

  • kind: PersistentVolume → 我们将 kind 定义为 PersistedVolume,它告诉 kubernetes 正在使用的 yaml 文件用于创建持久卷。

  • name: pv0001 → 我们正在创建的 PersistentVolume 的名称。

  • 容量: → 该规范将定义我们正在尝试创建的光伏发电容量。

  • 存储:10Gi → 这告诉底层基础设施我们正在尝试在定义的路径上申请 10Gi 空间。

  • ReadWriteOnce → 这告诉我们正在创建的卷的访问权限。

  • 路径:“/tmp/data01” →此定义告诉机器我们正在尝试在底层基础设施上的此路径下创建卷。

创造PV

$ kubectl create –f local-01.yaml
persistentvolume "pv0001" created

检查PV

$ kubectl get pv
NAME        CAPACITY      ACCESSMODES       STATUS       CLAIM      REASON     AGE
pv0001        10Gi            RWO         Available                            14s

描述PV

$ kubectl describe pv pv0001

创建持久卷声明

kind: PersistentVolumeClaim --------------> 1
apiVersion: v1
metadata:
   name: myclaim-1 --------------------> 2
spec:
   accessModes:
      - ReadWriteOnce ------------------------> 3
   resources:
      requests:
         storage: 3Gi ---------------------> 4

在上面的代码中,我们定义了 -

  • kind: PersistentVolumeClaim → 它指示底层基础设施我们正在尝试声明指定的空间量。

  • name: myclaim-1 → 我们尝试创建的声明的名称。

  • ReadWriteOnce → 这指定了我们尝试创建的声明的模式。

  • 存储:3Gi → 这将告诉 kubernetes 我们试图申请的空间量。

创建 PVC

$ kubectl create –f myclaim-1
persistentvolumeclaim "myclaim-1" created

获取有关 PVC 的详细信息

$ kubectl get pvc
NAME        STATUS   VOLUME   CAPACITY   ACCESSMODES   AGE
myclaim-1   Bound    pv0001     10Gi         RWO       7s

描述聚氯乙烯

$ kubectl describe pv pv0001

将 PV 和 PVC 与 POD 一起使用

kind: Pod
apiVersion: v1
metadata:
   name: mypod
   labels:
      name: frontendhttp
spec:
   containers:
   - name: myfrontend
      image: nginx
      ports:
      - containerPort: 80
         name: "http-server"
      volumeMounts: ----------------------------> 1
      - mountPath: "/usr/share/tomcat/html"
         name: mypd
   volumes: -----------------------> 2
      - name: mypd
         persistentVolumeClaim: ------------------------->3
         claimName: myclaim-1

在上面的代码中,我们定义了 -

  • VolumeMounts: → 这是容器中将进行安装的路径。

  • 体积: → 该定义定义了我们要声明的体积定义。

  • permanentVolumeClaim: → 在此之下,我们定义将在定义的 pod 中使用的卷名称。

Kubernetes - 秘密

秘密可以定义为用于存储敏感数据(例如加密的用户名和密码)的 Kubernetes 对象。

在 Kubernetes 中创建机密的方法有多种。

  • 从 txt 文件创建。
  • 从 yaml 文件创建。

从文本文件创建

为了从文本文件(例如用户名和密码)创建机密,我们首先需要将它们存储在 txt 文件中并使用以下命令。

$ kubectl create secret generic tomcat-passwd –-from-file = ./username.txt –fromfile = ./.
password.txt

从 Yaml 文件创建

apiVersion: v1
kind: Secret
metadata:
name: tomcat-pass
type: Opaque
data:
   password: <User Password>
   username: <User Name>

创造秘密

$ kubectl create –f Secret.yaml
secrets/tomcat-pass

使用秘密

一旦我们创建了秘密,就可以在 Pod 或复制控制器中使用它,如下所示:

  • 环境变量
  • 体积

作为环境变量

为了使用秘密作为环境变量,我们将在 pod yaml 文件的 spec 部分下使用env 。

env:
- name: SECRET_USERNAME
   valueFrom:
      secretKeyRef:
         name: mysecret
         key: tomcat-pass

作为体积

spec:
   volumes:
      - name: "secretstest"
         secret:
            secretName: tomcat-pass
   containers:
      - image: tomcat:7.0
         name: awebserver
         volumeMounts:
            - mountPath: "/tmp/mysec"
            name: "secretstest"

秘密配置作为环境变量

apiVersion: v1
kind: ReplicationController
metadata:
   name: appname
spec:
replicas: replica_count
template:
   metadata:
      name: appname
   spec:
      nodeSelector:
         resource-group:
      containers:
         - name: appname
            image:
            imagePullPolicy: Always
            ports:
            - containerPort: 3000
            env: -----------------------------> 1
               - name: ENV
                  valueFrom:
                     configMapKeyRef:
                        name: appname
                        key: tomcat-secrets

在上面的代码中,在env定义下,我们使用机密作为复制控制器中的环境变量。

卷安装时的秘密

apiVersion: v1
kind: pod
metadata:
   name: appname
spec:
   metadata:
      name: appname
   spec:
   volumes:
      - name: "secretstest"
         secret:
            secretName: tomcat-pass
   containers:
      - image: tomcat: 8.0
         name: awebserver
         volumeMounts:
            - mountPath: "/tmp/mysec"
            name: "secretstest"

Kubernetes - 网络策略

网络策略定义同一命名空间中的 Pod 如何相互通信以及如何与网络端点通信。它需要在API服务器的运行时配置中启用extensions/v1beta1/networkpolicies 。其资源使用标签来选择 Pod 并定义规则,以允许流量到达除命名空间中定义之外的特定 Pod。

首先,我们需要配置命名空间隔离策略。基本上,负载均衡器需要这种网络策略。

kind: Namespace
apiVersion: v1
metadata:
   annotations:
      net.beta.kubernetes.io/network-policy: |
      {
         "ingress": 
         {
            "isolation": "DefaultDeny"
         }
      }

$ kubectl annotate ns <namespace> "net.beta.kubernetes.io/network-policy = 
{\"ingress\": {\"isolation\": \"DefaultDeny\"}}"

创建命名空间后,我们需要创建网络策略。

网络策略 Yaml

kind: NetworkPolicy
apiVersion: extensions/v1beta1
metadata:
   name: allow-frontend
   namespace: myns
spec:
   podSelector:
      matchLabels:
         role: backend
   ingress:
   - from:
      - podSelector:
         matchLabels:
            role: frontend
   ports:
      - protocol: TCP
         port: 6379

Kubernetes-API

Kubernetes API 充当系统声明性配置模式的基础。Kubectl命令行工具可用于创建、更新、删除和获取 API 对象。Kubernetes API 充当 Kubernetes 不同组件之间的通信者。

向 Kubernetes 添加 API

为 Kubernetes 添加新的 API 将为 Kubernetes 添加新的功能,从而增加 Kubernetes 的功能。然而,与此同时,它也会增加系统的成本和可维护性。为了在成本和复杂性之间取得平衡,为其定义了一些集合。

正在添加的 API 应该对超过 50% 的用户有用。没有其他方法可以在 Kubernetes 中实现该功能。特殊情况在Kubernetes社区会议上讨论,然后添加API。

API变更

为了增加 Kubernetes 的能力,不断对系统进行更改。它是由 Kubernetes 团队完成的,目的是在不删除或影响系统现有功能的情况下向 Kubernetes 添加功能。

为了演示一般过程,这里有一个(假设的)示例 -

  • 用户将 Pod 对象发布到/api/v7beta1/...

  • JSON 被解组为v7beta1.Pod结构

  • 默认值应用于v7beta1.Pod

  • v7beta1.Pod转换为api.Pod结构

  • api.Pod已验证,任何错误都会返回给用户

  • api.Pod转换为 v6.Pod(因为 v6 是最新的稳定版本

  • v6.Pod被编组为JSON并写入etcd

现在我们已经存储了 Pod 对象,用户可以在任何受支持的 API 版本中获取该对象。例如 -

  • 用户从/api/v5/...获取 Pod

  • JSON 从etcd读取并解组v6.Pod结构

  • 默认值应用于v6.Pod

  • v6.Pod转换为 api.Pod结构

  • api.Pod转换v5.Pod结构

  • v5.Pod被编组为JSON并发送给用户

此过程的含义是 API 更改必须谨慎进行并向后兼容。

API版本控制

为了更容易支持多种结构,Kubernetes 支持多个 API 版本,每个版本位于不同的 API 路径,例如/api/v1/apsi/extensions/v1beta1

Kubernetes 的版本控制标准在多个标准中定义。

阿尔法级

  • 该版本包含alpha(例如v1alpha1)

  • 这个版本可能有bug;启用的版本可能有错误

  • 对错误的支持可以随时取消。

  • 建议仅在短期测试中使用,因为支撑可能不会一直存在。

测试版级别

  • 版本名称包含 beta(例如 v2beta3)

  • 代码经过全面测试,启用的版本应该是稳定的。

  • 该功能的支持不会被放弃;可能会有一些小的变化。

  • 建议仅用于非业务关键型用途,因为后续版本中可能会出现不兼容的更改。

稳定水平

  • 版本名称是vX,其中X是整数。

  • 稳定版本的功能将出现在许多后续版本的已发布软件中。

Kubernetes-Kubectl

Kubectl 是与 Kubernetes API 交互的命令行实用程序。它是一个用于在 Kubernetes 集群中通信和管理 pod 的接口。

需要将 kubectl 设置到本地才能与 Kubernetes 集群交互。

设置 Kubectl

使用curl 命令将可执行文件下载到本地工作站。

在 Linux 上

$ curl -O https://storage.googleapis.com/kubernetesrelease/
release/v1.5.2/bin/linux/amd64/kubectl

在 OS X 工作站上

$ curl -O https://storage.googleapis.com/kubernetesrelease/
release/v1.5.2/bin/darwin/amd64/kubectl

下载完成后,将二进制文件移动到系统路径中。

$ chmod +x kubectl
$ mv kubectl /usr/local/bin/kubectl

配置 Kubectl

以下是执行配置操作的步骤。

$ kubectl config set-cluster default-cluster --server = https://${MASTER_HOST} --
certificate-authority = ${CA_CERT}

$ kubectl config set-credentials default-admin --certificateauthority = ${
CA_CERT} --client-key = ${ADMIN_KEY} --clientcertificate = ${
ADMIN_CERT}

$ kubectl config set-context default-system --cluster = default-cluster --
user = default-admin
$ kubectl config use-context default-system
  • 将${MASTER_HOST}替换为前面步骤中使用的主节点地址或名称。

  • ${CA_CERT}替换为前面步骤中创建的ca.pem 的绝对路径。

  • ${ADMIN_KEY}替换为前面步骤中创建的admin-key.pem 的绝对路径。

  • ${ADMIN_CERT}替换为前面步骤中创建的admin.pem 的绝对路径。

验证设置

要验证kubectl是否正常工作,请检查 Kubernetes 客户端是否设置正确。

$ kubectl get nodes

NAME       LABELS                                     STATUS
Vipin.com  Kubernetes.io/hostname = vipin.mishra.com    Ready

Kubernetes - Kubectl 命令

Kubectl控制 Kubernetes 集群。它是 Kubernetes 的关键组件之一,安装完成后可以在任何计算机的工作站上运行。它具有管理集群中节点的能力。

Kubectl命令用于交互和管理 Kubernetes 对象和集群。在本章中,我们将通过 kubectl 讨论 Kubernetes 中使用的一些命令。

kubectl annotate - 它更新资源上的注释。

$kubectl annotate [--overwrite] (-f FILENAME | TYPE NAME) KEY_1=VAL_1 ...
KEY_N = VAL_N [--resource-version = version]

例如,

kubectl annotate pods tomcat description = 'my frontend'

kubectl api-versions - 它打印集群上支持的 API 版本。

$ kubectl api-version;

kubectl apply - 它能够通过文件或标准输入配置资源。

$ kubectl apply –f <filename>

kubectl Attach - 这会将内容附加到正在运行的容器。

$ kubectl attach <pod> –c <container>
$ kubectl attach 123456-7890 -c tomcat-conatiner

kubectl autoscale - 用于自动缩放定义的 Pod,例如部署、副本集、复制控制器。

$ kubectl autoscale (-f FILENAME | TYPE NAME | TYPE/NAME) [--min = MINPODS] --
max = MAXPODS [--cpu-percent = CPU] [flags]
$ kubectl autoscale deployment foo --min = 2 --max = 10

kubectl cluster-info - 它显示集群信息。

$ kubectl cluster-info

kubectl cluster-info dump - 它转储有关集群的相关信息以进行调试和诊断。

$ kubectl cluster-info dump
$ kubectl cluster-info dump --output-directory = /path/to/cluster-state

kubectl config - 修改 kubeconfig 文件。

$ kubectl config <SUBCOMMAD>
$ kubectl config –-kubeconfig <String of File name>

kubectl config current-context - 它显示当前上下文。

$ kubectl config current-context
#deploys the current context

kubectl config delete-cluster - 从 kubeconfig 中删除指定的集群。

$ kubectl config delete-cluster <Cluster Name>

kubectl config delete-context - 从 kubeconfig 中删除指定的上下文。

$ kubectl config delete-context <Context Name>

kubectl config get-clusters - 显示 kubeconfig 中定义的集群。

$ kubectl config get-cluster
$ kubectl config get-cluster <Cluser Name>

kubectl config get-contexts - 描述一个或多个上下文。

$ kubectl config get-context <Context Name>

kubectl config set-cluster - 设置 Kubernetes 中的集群条目。

$ kubectl config set-cluster NAME [--server = server] [--certificateauthority =
path/to/certificate/authority] [--insecure-skip-tls-verify = true]

kubectl config set-context - 在 kubernetes 入口点中设置上下文条目。

$ kubectl config set-context NAME [--cluster = cluster_nickname] [--
user = user_nickname] [--namespace = namespace]
$ kubectl config set-context prod –user = vipin-mishra

kubectl config set-credentials - 在 kubeconfig 中设置用户条目。

$ kubectl config set-credentials cluster-admin --username = vipin --
password = uXFGweU9l35qcif

kubectl config set - 在 kubeconfig 文件中设置单独的值。

$ kubectl config set PROPERTY_NAME PROPERTY_VALUE

kubectl config unset - 它取消设置 kubectl 中的特定组件。

$ kubectl config unset PROPERTY_NAME PROPERTY_VALUE

kubectl config use-context - 设置 kubectl 文件中的当前上下文。

$ kubectl config use-context <Context Name>

kubectl 配置视图

$ kubectl config view
$ kubectl config view –o jsonpath='{.users[?(@.name == "e2e")].user.password}'

kubectl cp - 将文件和目录复制到容器中或从容器中复制文件和目录。

$ kubectl cp <Files from source> <Files to Destinatiion>