- Kubernetes 教程
- Kubernetes - 首页
- Kubernetes - 概述
- Kubernetes - 架构
- Kubernetes - 设置
- Kubernetes - 镜像
- Kubernetes - 作业
- Kubernetes - 标签 & 选择器
- Kubernetes - 命名空间
- Kubernetes - 节点
- Kubernetes - 服务
- Kubernetes - Pod
- Kubernetes - 复制控制器
- Kubernetes - 副本集
- Kubernetes - 部署
- Kubernetes - 卷
- Kubernetes - 密钥
- Kubernetes - 网络策略
- 高级 Kubernetes
- Kubernetes - API
- Kubernetes - Kubectl
- Kubernetes - Kubectl 命令
- Kubernetes - 创建应用
- Kubernetes - 应用部署
- Kubernetes - 自动伸缩
- Kubernetes - 仪表盘设置
- Kubernetes - 监控
- Kubernetes 有用资源
- Kubernetes 快速指南
- Kubernetes - 有用资源
- Kubernetes - 讨论
Kubernetes 快速指南
Kubernetes - 概述
Kubernetes 是一个由云原生计算基金会 (CNCF) 托管的开源容器管理工具。它也被称为 Borg 的增强版,Borg 是谷歌开发的用于管理长期运行进程和批处理作业的工具,以前这些由独立的系统处理。
Kubernetes 能够自动化应用程序的部署、扩展和跨集群的容器操作。它能够创建以容器为中心的架构。
Kubernetes 的特性
以下是 Kubernetes 的一些重要特性。
持续开发、集成和部署
容器化基础设施
以应用为中心的管理
自动可伸缩的基础设施
跨开发、测试和生产环境的一致性
松散耦合的基础设施,其中每个组件都可以作为一个独立单元运行
更高的资源利用率密度
可预测的基础设施
Kubernetes 的一个关键组件是,它可以在物理和虚拟机基础设施集群上运行应用程序。它还能够在云上运行应用程序。**它有助于从以主机为中心的基础设施迁移到以容器为中心的基础设施。**
Kubernetes - 架构
在本章中,我们将讨论 Kubernetes 的基本架构。
Kubernetes - 集群架构
如下图所示,Kubernetes 遵循客户端-服务器架构。其中,主节点安装在一台机器上,而节点安装在单独的 Linux 机器上。
主节点和节点的关键组件在下一节中定义。
Kubernetes - 主节点组件
以下是 Kubernetes 主节点的组件。
etcd
它存储集群中每个节点都可以使用的配置信息。它是一个高可用性的键值存储,可以在多个节点之间分布。由于它可能包含一些敏感信息,因此只能由 Kubernetes API 服务器访问。它是一个所有节点都可以访问的分布式键值存储。
API 服务器
Kubernetes 的 API 服务器通过 API 提供所有集群操作。API 服务器实现了一个接口,这意味着不同的工具和库可以轻松地与之通信。**Kubeconfig** 是一个与服务器端工具一起使用的软件包,可用于通信。它暴露了 Kubernetes API。
控制器管理器
此组件负责大多数调节集群状态并执行任务的控制器。一般来说,它可以被认为是一个在非终止循环中运行的守护进程,负责收集信息并将其发送到 API 服务器。它努力获得集群的共享状态,然后进行更改以将服务器的当前状态更改为所需状态。关键控制器包括复制控制器、端点控制器、命名空间控制器和服务帐户控制器。控制器管理器运行不同类型的控制器来处理节点、端点等。
调度器
这是 Kubernetes 主节点的关键组件之一。它是主节点中负责分配工作负载的服务。它负责跟踪集群节点上工作负载的利用率,然后将工作负载放置在具有可用资源并接受工作负载的节点上。换句话说,这是负责将 Pod 分配给可用节点的机制。调度器负责工作负载利用率并将 Pod 分配给新节点。
Kubernetes - 节点组件
以下是节点服务器的关键组件,这些组件对于与 Kubernetes 主节点通信是必要的。
Docker
每个节点的第一个要求是 Docker,它有助于在一个相对隔离但轻量级的操作系统环境中运行封装的应用程序容器。
Kubelet 服务
这是每个节点中一个小服务,负责在控制平面服务之间来回传递信息。它与 **etcd** 存储交互以读取配置详细信息和写入值。它与主节点组件通信以接收命令和工作。然后 **kubelet** 进程承担维护工作状态和节点服务器状态的责任。它管理网络规则、端口转发等。
Kubernetes 代理服务
这是一个在每个节点上运行的代理服务,有助于使服务可用于外部主机。它有助于将请求转发到正确的容器,并且能够执行基本的负载均衡。它确保网络环境是可预测且可访问的,同时也是隔离的。它管理节点上的 Pod、卷、密钥、创建新的容器健康检查等。
Kubernetes - 主节点和节点结构
下图显示了 Kubernetes 主节点和节点的结构。
Kubernetes - 设置
在设置 Kubernetes 之前,必须先设置虚拟数据中心 (vDC)。这可以被认为是一组机器,它们可以通过网络相互通信。对于实践操作,如果您没有物理或云基础设施,可以在 **PROFITBRICKS** 上设置 vDC。
在任何云上的 IaaS 设置完成后,您需要配置 **主节点** 和 **节点**。
**注意** - 此设置适用于 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 主节点上。要安装它,请运行以下命令。
$ 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 主节点上进行实际配置。
首先,我们将开始将所有配置文件复制到它们正确的位置。
$ 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 目录下的已复制配置文件。
使用以下命令配置主节点上的 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 主节点了。为此,我们将重新启动 Docker。
$ service docker restart
Kubernetes 节点配置
Kubernetes 节点将运行两个服务 **kubelet 和 kube-proxy**。在继续之前,我们需要将下载的二进制文件复制到我们想要配置 kubernetes 节点的所需文件夹。
使用与 kubernetes 主节点相同的复制文件方法。因为它只运行 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/
我们将配置 **kubelet** 和 **kube-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:
** - 这是我们尝试从 Docker 或内部镜像注册表中提取的镜像的名称。我们需要定义完整的注册表路径以及我们尝试提取的镜像名称。 **imagePullPolicy** - Always - 此镜像拉取策略定义了无论何时我们运行此文件来创建容器,它都将再次拉取同名镜像。
**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 → 这是我们使用的模板的名称,spec 定义了模板。
name: py → 我们在容器规范下指定了一个名为 py 的名称,这有助于识别将由此创建的 Pod。
Image: python → 我们将拉取以创建将在 Pod 内运行的容器的镜像。
restartPolicy: Never →镜像重启条件设置为 Never,这意味着如果容器被终止或出现故障,它将不会自行重启。
我们将使用以下命令和名为 py.yaml 保存的 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
在上面的代码中,我们定义了 -
schedule: 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: salesplatform 和 component: neo4j。
Kubernetes - 命名空间
命名空间为资源名称提供了额外的限定。当多个团队使用相同的集群并且存在名称冲突的可能性时,这很有用。它可以作为多个集群之间的虚拟墙。
命名空间的功能
以下是 Kubernetes 中命名空间的一些重要功能:
命名空间有助于使用相同命名空间的 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 创建一个 kind 为 node 的对象,该对象将验证创建的对象是否为有效节点。
带选择器的服务
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 主服务器上运行的服务集合,并根据 metadata.name 持续监控集群中的节点。如果所有必需的服务都正在运行,则验证节点,并且控制器将向该节点分配新创建的 Pod。如果无效,则主服务器将不会向其分配任何 Pod,并将等待其变为有效。
如果 –register-node 标志为 true,则 Kubernetes 主服务器会自动注册节点。
–register-node = true
但是,如果集群管理员想要手动管理它,则可以通过关闭以下标志来完成:
–register-node = false
Kubernetes - 服务
服务可以定义为 Pod 的逻辑集合。它可以定义为 Pod 之上的抽象,它提供单个 IP 地址和 DNS 名称,Pod 可以通过该名称进行访问。使用服务,可以轻松管理负载均衡配置。它有助于 Pod 轻松扩展。
服务是 Kubernetes 中的 REST 对象,其定义可以发布到 Kubernetes apiServer(在 Kubernetes 主服务器上)以创建新实例。
无选择器的服务
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 - 它将在已部署节点的静态端口上公开服务。将自动创建一个 ClusterIP 服务,NodePort 服务将路由到该服务。可以使用 NodeIP:nodePort 从集群外部访问该服务。
spec: ports: - port: 8080 nodePort: 31999 name: NodeportService clusterIP: 10.20.30.40
Load Balancer - 它使用云提供商的负载均衡器。将自动创建 NodePort 和 ClusterIP 服务,外部负载均衡器将路由到这些服务。
一个完整的服务 yaml 文件,服务类型为 Node Port。尝试自己创建一个。
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
- 多容器 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
多容器 Pod 是使用带有容器定义的 yaml mail 创建的。
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 - 复制控制器
副本控制器是 Kubernetes 的关键功能之一,负责管理 Pod 生命周期。它负责确保在任何时间点都运行指定数量的 Pod 副本。当想要确保运行指定数量的 Pod 或至少一个 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
设置详情
Kind: ReplicationController → 在上面的代码中,我们将 kind 定义为副本控制器,这将告诉 kubectl 将使用 yaml 文件来创建副本控制器。
name: Tomcat-ReplicationController → 这有助于识别将创建副本控制器的名称。如果我们运行 kubctl,get rc
,它将显示副本控制器的详细信息。 replicas: 3 → 这有助于副本控制器了解它需要在 Pod 生命周期中的任何时间点维护三个 Pod 副本。
name: Tomcat → 在 spec 部分中,我们将名称定义为 tomcat,这将告诉副本控制器 Pod 内的容器是 tomcat。
containerPort: 7474 → 它有助于确保集群中运行 Pod 内容器的所有节点都在相同的 7474 端口上公开。
在这里,Kubernetes 服务充当三个 tomcat 副本的负载均衡器。
Kubernetes - 副本集
副本集(Replica Set)确保应该运行多少个 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: Backend → 我们已将标签 tier 定义为 backend,这将创建一个匹配的选择器。
{key: tier, operation: In, values: [Backend]} → 这将帮助matchExpression理解我们定义的匹配条件以及matchLabel用于查找详细信息的操作。
使用kubectl运行以上文件,并使用yaml文件中的定义创建后端副本集。
Kubernetes - 部署
Deployment(部署)是复制控制器的升级和更高版本。它们管理副本集的部署,副本集也是复制控制器的升级版本。它们具有更新副本集的能力,并且还能够回滚到以前的版本。
它们提供了许多matchLabels和selectors的更新功能。我们在 Kubernetes master 中获得了一个新的控制器,称为部署控制器,它使这一切成为可能。它具有中途更改部署的能力。
更改部署
更新 - 用户可以在部署完成之前更新正在进行的部署。在此,现有部署将被终止,并将创建新的部署。
删除 - 用户可以在部署完成之前通过删除来暂停/取消部署。重新创建相同的部署将恢复它。
回滚 - 我们可以回滚部署或正在进行的部署。用户可以使用DeploymentSpec.PodTemplateSpec = oldRC.PodTemplateSpec来创建或更新部署。
部署策略
部署策略有助于定义新的 RC 如何替换现有的 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
在上面的代码中,与副本集唯一不同的是我们将 kind 定义为 deployment。
创建部署
$ 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 Compute Engine (GCE) 持久性磁盘挂载到您的 Pod 中。当 Pod 从节点中移除时,gcePersistentDisk中的数据将保持不变。
awsElasticBlockStore - 此类型的卷将 Amazon Web Services (AWS) Elastic Block Store 挂载到您的 Pod 中。与gcePersistentDisk一样,当 Pod 从节点中移除时,awsElasticBlockStore中的数据将保持不变。
nfs - nfs卷允许将现有的 NFS(网络文件系统)挂载到您的 Pod 中。当 Pod 从节点中移除时,nfs卷中的数据不会被擦除。该卷仅被卸载。
iscsi - iscsi卷允许将现有的 iSCSI(IP 上的 SCSI)卷挂载到您的 Pod 中。
flocker - 它是一个开源的集群式容器数据卷管理器。它用于管理数据卷。flocker卷允许将 Flocker 数据集挂载到 Pod 中。如果 Flocker 中不存在数据集,则首先需要使用 Flocker API 创建它。
glusterfs - Glusterfs 是一个开源的网络文件系统。glusterfs卷允许将 glusterfs 卷挂载到您的 Pod 中。
rbd - RBD 代表 Rados Block Device。rbd卷允许将 Rados Block Device 卷挂载到您的 Pod 中。Pod 从节点中移除后,数据仍然保留。
cephfs - cephfs卷允许将现有的 CephFS 卷挂载到您的 Pod 中。Pod 从节点中移除后,数据将保持不变。
gitRepo - gitRepo卷挂载一个空目录,并将git存储库克隆到其中供您的 Pod 使用。
secret - secret卷用于将敏感信息(如密码)传递给 Pod。
persistentVolumeClaim - persistentVolumeClaim卷用于将 PersistentVolume 挂载到 Pod 中。PersistentVolume 是一种允许用户“声明”持久性存储(如 GCE PersistentDisk 或 iSCSI 卷)而不必了解特定云环境的详细信息的方法。
downwardAPI - downwardAPI卷用于使向下 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 定义为 PersistentVolume,这告诉 Kubernetes 正在使用的 yaml 文件用于创建持久卷。
name: pv0001 → 我们正在创建的持久卷的名称。
capacity: → 此规范将定义我们尝试创建的 PV 的容量。
storage: 10Gi → 这告诉底层基础设施我们正在尝试在定义的路径上声明 10Gi 空间。
ReadWriteOnce → 这告诉我们正在创建的卷的访问权限。
path: "/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 → 这指定了我们尝试创建的声明的模式。
storage: 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
描述 PVC
$ kubectl describe pv pv0001
在 POD 中使用 PV 和 PVC
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: → 这是将进行挂载的容器中的路径。
Volume: → 此定义定义了我们将声明的卷定义。
persistentVolumeClaim: → 在此之下,我们定义了将在定义的 Pod 中使用的卷名称。
Kubernetes - 密钥
Secrets 可以定义为 Kubernetes 对象,用于存储敏感数据,例如用户名和密码,并进行加密。
在 Kubernetes 中创建 Secrets 的方法有很多。
- 从文本文件创建。
- 从 yaml 文件创建。
从文本文件创建
为了从文本文件(例如用户名和密码)创建 Secrets,我们首先需要将它们存储在 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>
创建 Secret
$ kubectl create –f Secret.yaml secrets/tomcat-pass
使用 Secrets
创建 Secrets 后,它可以在 Pod 或复制控制器中使用,如下所示:
- 环境变量
- 卷
作为环境变量
为了将 Secret 用作环境变量,我们将在 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"
Secret 配置作为环境变量
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定义下,我们正在复制控制器中使用 Secret 作为环境变量。
Secret 作为卷挂载
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 对象 POST 到 /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
从 etcd 读取 JSON 并将其反序列化为 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 版本
此版本包含 alpha 版本(例如 v1alpha1)
此版本可能存在错误;启用的版本可能存在错误
随时可能取消对错误的支持。
建议仅在短期测试中使用,因为可能并非一直都提供支持。
Beta 版本
版本名称包含 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 - 它能够通过文件或 stdin 配置资源。
$ kubectl apply –f <filename>
kubectl attach - 这将事物附加到正在运行的容器。
$ kubectl attach <pod> –c <container> $ kubectl attach 123456-7890 -c tomcat-conatiner
kubectl autoscale - 这用于自动缩放已定义的 Pod,例如 Deployment、ReplicaSet、Replication Controller。
$ 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 config view
$ kubectl config view $ kubectl config view –o jsonpath='{.users[?(@.name == "e2e")].user.password}'
kubectl cp - 将文件和目录复制到容器和从容器复制。
$ kubectl cp <Files from source> <Files to Destinatiion> $ kubectl cp /tmp/foo <some-pod>:/tmp/bar -c <specific-container>
kubectl create - 通过文件名或 stdin 创建资源。为此,接受 JSON 或 YAML 格式。
$ kubectl create –f <File Name> $ cat <file name> | kubectl create –f -
同样,我们可以使用 create 命令以及 kubectl 创建多个列出的内容。
- deployment
- namespace
- quota
- secret docker-registry
- secret
- secret generic
- secret tls
- serviceaccount
- service clusterip
- service loadbalancer
- service nodeport
kubectl delete - 通过文件名、stdin、资源和名称删除资源。
$ kubectl delete –f ([-f FILENAME] | TYPE [(NAME | -l label | --all)])
kubectl describe - 描述 Kubernetes 中的任何特定资源。显示资源或一组资源的详细信息。
$ kubectl describe <type> <type name> $ kubectl describe pod tomcat
kubectl drain - 这用于出于维护目的而排空节点。它为维护准备节点。这将使节点标记为不可用,因此不应为将要创建的新容器分配它。
$ kubectl drain tomcat –force
kubectl edit - 它用于结束服务器上的资源。这允许直接编辑可以通过命令行工具接收的资源。
$ kubectl edit <Resource/Name | File Name) Ex. $ kubectl edit rc/tomcat
kubectl exec - 这有助于在容器中执行命令。
$ kubectl exec POD <-c CONTAINER > -- COMMAND < args...> $ kubectl exec tomcat 123-5-456 date
kubectl expose - 这用于将 Kubernetes 对象(例如 Pod、Replication Controller 和 Service)公开为新的 Kubernetes 服务。它能够通过正在运行的容器或 yaml 文件公开它。
$ kubectl expose (-f FILENAME | TYPE NAME) [--port=port] [--protocol = TCP|UDP] [--target-port = number-or-name] [--name = name] [--external-ip = external-ip-ofservice] [--type = type] $ kubectl expose rc tomcat –-port=80 –target-port = 30000 $ kubectl expose –f tomcat.yaml –port = 80 –target-port =
kubectl get - 此命令能够获取有关 Kubernetes 资源的集群数据。
$ kubectl get [(-o|--output=)json|yaml|wide|custom-columns=...|custom-columnsfile=...| go-template=...|go-template-file=...|jsonpath=...|jsonpath-file=...] (TYPE [NAME | -l label] | TYPE/NAME ...) [flags]
例如:
$ kubectl get pod <pod name> $ kubectl get service <Service name>
kubectl logs - 用于获取 Pod 中容器的日志。打印日志可以定义 Pod 中的容器名称。如果 POD 只有一个容器,则无需定义其名称。
$ kubectl logs [-f] [-p] POD [-c CONTAINER] Example $ kubectl logs tomcat. $ kubectl logs –p –c tomcat.8
kubectl port-forward - 用于将一个或多个本地端口转发到 Pod。
$ kubectl port-forward POD [LOCAL_PORT:]REMOTE_PORT [...[LOCAL_PORT_N:]REMOTE_PORT_N] $ kubectl port-forward tomcat 3000 4000 $ kubectl port-forward tomcat 3000:5000
kubectl replace - 能够通过文件名或 stdin 替换资源。
$ kubectl replace -f FILENAME $ kubectl replace –f tomcat.yml $ cat tomcat.yml | kubectl replace –f -
kubectl rolling-update - 对 Replication Controller 执行滚动更新。通过一次更新一个 Pod 来将指定的 Replication Controller 替换为新的 Replication Controller。
$ kubectl rolling-update OLD_CONTROLLER_NAME ([NEW_CONTROLLER_NAME] -- image = NEW_CONTAINER_IMAGE | -f NEW_CONTROLLER_SPEC) $ kubectl rolling-update frontend-v1 –f freontend-v2.yaml
kubectl rollout - 它能够管理部署的推出。
$ Kubectl rollout <Sub Command> $ kubectl rollout undo deployment/tomcat
除此之外,我们可以使用 rollout 执行多项任务,例如:
- rollout history
- rollout pause
- rollout resume
- rollout status
- rollout undo
kubectl run - run 命令能够在 Kubernetes 集群上运行映像。
$ kubectl run NAME --image = image [--env = "key = value"] [--port = port] [-- replicas = replicas] [--dry-run = bool] [--overrides = inline-json] [--command] -- [COMMAND] [args...] $ kubectl run tomcat --image = tomcat:7.0 $ kubectl run tomcat –-image = tomcat:7.0 –port = 5000
kubectl scale - 它将缩放 Kubernetes Deployment、ReplicaSet、Replication Controller 或 Job 的大小。
$ kubectl scale [--resource-version = version] [--current-replicas = count] -- replicas = COUNT (-f FILENAME | TYPE NAME ) $ kubectl scale –-replica = 3 rs/tomcat $ kubectl scale –replica = 3 tomcat.yaml
kubectl set image - 它更新 Pod 模板的映像。
$ kubectl set image (-f FILENAME | TYPE NAME) CONTAINER_NAME_1 = CONTAINER_IMAGE_1 ... CONTAINER_NAME_N = CONTAINER_IMAGE_N $ kubectl set image deployment/tomcat busybox = busybox ngnix = ngnix:1.9.1 $ kubectl set image deployments, rc tomcat = tomcat6.0 --all
kubectl set resources - 用于设置资源的内容。它使用 Pod 模板更新对象的资源/限制。
$ kubectl set resources (-f FILENAME | TYPE NAME) ([--limits = LIMITS & -- requests = REQUESTS] $ kubectl set resources deployment tomcat -c = tomcat -- limits = cpu = 200m,memory = 512Mi
kubectl top node - 它显示 CPU/内存/存储使用情况。top 命令允许您查看节点的资源消耗。
$ kubectl top node [node Name]
此命令也可以与 Pod 一起使用。
Kubernetes - 创建应用
为了创建 Kubernetes 部署的应用程序,我们需要首先在 Docker 上创建应用程序。这可以通过两种方式完成:
- 通过下载
- 从 Dockerfile
通过下载
可以从 Docker Hub 下载现有映像,并将其存储在本地 Docker 注册表中。
为此,请运行 Docker pull 命令。
$ docker pull --help Usage: docker pull [OPTIONS] NAME[:TAG|@DIGEST] Pull an image or a repository from the registry -a, --all-tags = false Download all tagged images in the repository --help = false Print usage
以下是上述代码的输出。
上面的屏幕截图显示了一组存储在本地 Docker 注册表中的映像。
如果我们想从包含要测试的应用程序的映像构建容器,我们可以使用 Docker run 命令来完成。
$ docker run –i –t unbunt /bin/bash
从 Dockerfile
为了从 Dockerfile 创建应用程序,我们需要首先创建一个 Dockerfile。
下面是一个 Jenkins Docker 文件的示例。
FROM ubuntu:14.04 MAINTAINER [email protected] ENV REFRESHED_AT 2017-01-15 RUN apt-get update -qq && apt-get install -qqy curl RUN curl https://get.docker.io/gpg | apt-key add - RUN echo deb http://get.docker.io/ubuntu docker main > /etc/apt/↩ sources.list.d/docker.list RUN apt-get update -qq && apt-get install -qqy iptables ca-↩ certificates lxc openjdk-6-jdk git-core lxc-docker ENV JENKINS_HOME /opt/jenkins/data ENV JENKINS_MIRROR http://mirrors.jenkins-ci.org RUN mkdir -p $JENKINS_HOME/plugins RUN curl -sf -o /opt/jenkins/jenkins.war -L $JENKINS_MIRROR/war-↩ stable/latest/jenkins.war RUN for plugin in chucknorris greenballs scm-api git-client git ↩ ws-cleanup ;\ do curl -sf -o $JENKINS_HOME/plugins/${plugin}.hpi \ -L $JENKINS_MIRROR/plugins/${plugin}/latest/${plugin}.hpi ↩ ; done ADD ./dockerjenkins.sh /usr/local/bin/dockerjenkins.sh RUN chmod +x /usr/local/bin/dockerjenkins.sh VOLUME /var/lib/docker EXPOSE 8080 ENTRYPOINT [ "/usr/local/bin/dockerjenkins.sh" ]
创建上述文件后,将其保存为 Dockerfile,然后 `cd` 到文件路径。然后,运行以下命令。
$ sudo docker build -t jamtur01/Jenkins .
构建镜像后,我们可以测试镜像是否正常工作并可以转换为容器。
$ docker run –i –t jamtur01/Jenkins /bin/bash
Kubernetes - 应用部署
部署是将镜像转换为容器,然后将这些镜像分配到 Kubernetes 集群中的 Pod 的一种方法。这也有助于设置应用程序集群,其中包括部署服务、Pod、副本控制器和副本集。可以这样设置集群:部署在 Pod 上的应用程序可以相互通信。
在此设置中,我们可以在一个应用程序的顶部设置负载均衡器,将流量分流到一组 Pod,然后它们与后端 Pod 通信。Pod 之间的通信通过在 Kubernetes 中构建的服务对象进行。
Nginx 负载均衡器 Yaml 文件
apiVersion: v1 kind: Service metadata: name: oppv-dev-nginx labels: k8s-app: omni-ppv-api spec: type: NodePort ports: - port: 8080 nodePort: 31999 name: omninginx selector: k8s-app: appname component: nginx env: dev
Nginx 副本控制器 Yaml 文件
apiVersion: v1 kind: ReplicationController metadata: name: appname spec: replicas: replica_count template: metadata: name: appname labels: k8s-app: appname component: nginx env: env_name spec: nodeSelector: resource-group: oppv containers: - name: appname image: IMAGE_TEMPLATE imagePullPolicy: Always ports: - containerPort: 8080 resources: requests: memory: "request_mem" cpu: "request_cpu" limits: memory: "limit_mem" cpu: "limit_cpu" env: - name: BACKEND_HOST value: oppv-env_name-node:3000
前端服务 Yaml 文件
apiVersion: v1 kind: Service metadata: name: appname labels: k8s-app: appname spec: type: NodePort ports: - name: http port: 3000 protocol: TCP targetPort: 3000 selector: k8s-app: appname component: nodejs env: dev
前端副本控制器 Yaml 文件
apiVersion: v1 kind: ReplicationController metadata: name: Frontend spec: replicas: 3 template: metadata: name: frontend labels: k8s-app: Frontend component: nodejs env: Dev spec: nodeSelector: resource-group: oppv containers: - name: appname image: IMAGE_TEMPLATE imagePullPolicy: Always ports: - containerPort: 3000 resources: requests: memory: "request_mem" cpu: "limit_cpu" limits: memory: "limit_mem" cpu: "limit_cpu" env: - name: ENV valueFrom: configMapKeyRef: name: appname key: config-env
后端服务 Yaml 文件
apiVersion: v1 kind: Service metadata: name: backend labels: k8s-app: backend spec: type: NodePort ports: - name: http port: 9010 protocol: TCP targetPort: 9000 selector: k8s-app: appname component: play env: dev
后端副本控制器 Yaml 文件
apiVersion: v1 kind: ReplicationController metadata: name: backend spec: replicas: 3 template: metadata: name: backend labels: k8s-app: beckend component: play env: dev spec: nodeSelector: resource-group: oppv containers: - name: appname image: IMAGE_TEMPLATE imagePullPolicy: Always ports: - containerPort: 9000 command: [ "./docker-entrypoint.sh" ] resources: requests: memory: "request_mem" cpu: "request_cpu" limits: memory: "limit_mem" cpu: "limit_cpu" volumeMounts: - name: config-volume mountPath: /app/vipin/play/conf volumes: - name: config-volume configMap: name: appname
Kubernetes - 自动伸缩
自动伸缩是 Kubernetes 集群的关键特性之一。它是一个功能,集群能够随着服务响应需求的增加而增加节点数量,随着需求的减少而减少节点数量。此自动伸缩功能目前受 Google Cloud Engine (GCE) 和 Google Container Engine (GKE) 支持,很快就会在 AWS 上推出。
为了在 GCE 中设置可伸缩的基础架构,我们需要首先拥有一个启用了 Google Cloud Monitoring、Google Cloud Logging 和 Stackdriver 功能的活动 GCE 项目。
首先,我们将设置集群,其中运行少量节点。完成后,我们需要设置以下环境变量。
环境变量
export NUM_NODES = 2 export KUBE_AUTOSCALER_MIN_NODES = 2 export KUBE_AUTOSCALER_MAX_NODES = 5 export KUBE_ENABLE_CLUSTER_AUTOSCALER = true
完成后,我们将通过运行kube-up.sh启动集群。这将创建一个集群以及集群自动伸缩器附加组件。
./cluster/kube-up.sh
创建集群后,我们可以使用以下 kubectl 命令检查集群。
$ kubectl get nodes NAME STATUS AGE kubernetes-master Ready,SchedulingDisabled 10m kubernetes-minion-group-de5q Ready 10m kubernetes-minion-group-yhdx Ready 8m
现在,我们可以在集群上部署应用程序,然后启用水平 Pod 自动伸缩器。这可以使用以下命令完成。
$ kubectl autoscale deployment <Application Name> --cpu-percent = 50 --min = 1 -- max = 10
上述命令表明,随着应用程序负载的增加,我们将至少维护一个,最多 10 个 Pod 副本。
我们可以通过运行$kubclt get hpa命令来检查自动伸缩器的状态。我们将使用以下命令增加 Pod 上的负载。
$ kubectl run -i --tty load-generator --image = busybox /bin/sh $ while true; do wget -q -O- http://php-apache.default.svc.cluster.local; done
我们可以通过运行$ kubectl get hpa命令来检查hpa。
$ kubectl get hpa NAME REFERENCE TARGET CURRENT php-apache Deployment/php-apache/scale 50% 310% MINPODS MAXPODS AGE 1 20 2m $ kubectl get deployment php-apache NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE php-apache 7 7 7 3 4m
我们可以使用以下命令检查正在运行的 Pod 数量。
jsz@jsz-desk2:~/k8s-src$ kubectl get pods php-apache-2046965998-3ewo6 0/1 Pending 0 1m php-apache-2046965998-8m03k 1/1 Running 0 1m php-apache-2046965998-ddpgp 1/1 Running 0 5m php-apache-2046965998-lrik6 1/1 Running 0 1m php-apache-2046965998-nj465 0/1 Pending 0 1m php-apache-2046965998-tmwg1 1/1 Running 0 1m php-apache-2046965998-xkbw1 0/1 Pending 0 1m
最后,我们可以获取节点状态。
$ kubectl get nodes NAME STATUS AGE kubernetes-master Ready,SchedulingDisabled 9m kubernetes-minion-group-6z5i Ready 43s kubernetes-minion-group-de5q Ready 9m kubernetes-minion-group-yhdx Ready 9m
Kubernetes - 仪表盘设置
设置 Kubernetes 仪表板涉及多个步骤,需要一组工具作为先决条件才能进行设置。
- Docker (1.3+)
- go (1.5+)
- nodejs (4.2.2+)
- npm (1.3+)
- java (7+)
- gulp (3.9+)
- Kubernetes (1.1.2+)
设置仪表板
$ sudo apt-get update && sudo apt-get upgrade Installing Python $ sudo apt-get install python $ sudo apt-get install python3 Installing GCC $ sudo apt-get install gcc-4.8 g++-4.8 Installing make $ sudo apt-get install make Installing Java $ sudo apt-get install openjdk-7-jdk Installing Node.js $ wget https://node.org.cn/dist/v4.2.2/node-v4.2.2.tar.gz $ tar -xzf node-v4.2.2.tar.gz $ cd node-v4.2.2 $ ./configure $ make $ sudo make install Installing gulp $ npm install -g gulp $ npm install gulp
验证版本
Java Version $ java –version java version "1.7.0_91" OpenJDK Runtime Environment (IcedTea 2.6.3) (7u91-2.6.3-1~deb8u1+rpi1) OpenJDK Zero VM (build 24.91-b01, mixed mode) $ node –v V4.2.2 $ npn -v 2.14.7 $ gulp -v [09:51:28] CLI version 3.9.0 $ sudo gcc --version gcc (Raspbian 4.8.4-1) 4.8.4 Copyright (C) 2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
安装 GO
$ git clone https://go.googlesource.com/go $ cd go $ git checkout go1.4.3 $ cd src Building GO $ ./all.bash $ vi /root/.bashrc In the .bashrc export GOROOT = $HOME/go export PATH = $PATH:$GOROOT/bin $ go version go version go1.4.3 linux/arm
安装 Kubernetes 仪表板
$ git clone https://github.com/kubernetes/dashboard.git $ cd dashboard $ npm install -g bower
运行仪表板
$ git clone https://github.com/kubernetes/dashboard.git $ cd dashboard $ npm install -g bower $ gulp serve [11:19:12] Requiring external module babel-core/register [11:20:50] Using gulpfile ~/dashboard/gulpfile.babel.js [11:20:50] Starting 'package-backend-source'... [11:20:50] Starting 'kill-backend'... [11:20:50] Finished 'kill-backend' after 1.39 ms [11:20:50] Starting 'scripts'... [11:20:53] Starting 'styles'... [11:21:41] Finished 'scripts' after 50 s [11:21:42] Finished 'package-backend-source' after 52 s [11:21:42] Starting 'backend'... [11:21:43] Finished 'styles' after 49 s [11:21:43] Starting 'index'... [11:21:44] Finished 'index' after 1.43 s [11:21:44] Starting 'watch'... [11:21:45] Finished 'watch' after 1.41 s [11:23:27] Finished 'backend' after 1.73 min [11:23:27] Starting 'spawn-backend'... [11:23:27] Finished 'spawn-backend' after 88 ms [11:23:27] Starting 'serve'... 2016/02/01 11:23:27 Starting HTTP server on port 9091 2016/02/01 11:23:27 Creating API client for 2016/02/01 11:23:27 Creating Heapster REST client for https://127.0.0.1:8082 [11:23:27] Finished 'serve' after 312 ms [BS] [BrowserSync SPA] Running... [BS] Access URLs: -------------------------------------- Local: https://127.0.0.1:9090/ External: http://192.168.1.21:9090/ -------------------------------------- UI: https://127.0.0.1:3001 UI External: http://192.168.1.21:3001 -------------------------------------- [BS] Serving files from: /root/dashboard/.tmp/serve [BS] Serving files from: /root/dashboard/src/app/frontend [BS] Serving files from: /root/dashboard/src/app
Kubernetes 仪表板
Kubernetes - 监控
监控是管理大型集群的关键组件之一。为此,我们有很多工具。
使用 Prometheus 进行监控
这是一个监控和警报系统。它是在 SoundCloud 构建的,并在 2012 年开源。它可以很好地处理多维数据。
Prometheus 有多个组件参与监控:
Prometheus - 它是抓取和存储数据的核心组件。
Prometheus 节点浏览器 - 获取主机级矩阵并将其公开给 Prometheus。
Ranch-eye - 是一个haproxy,并将cAdvisor统计信息公开给 Prometheus。
Grafana - 数据可视化。
InfluxDB - 特别用于存储来自 Rancher 的数据的时序数据库。
Prom-ranch-exporter - 它是一个简单的 node.js 应用程序,有助于查询 Rancher 服务器以获取服务堆栈的状态。
Sematext Docker 代理
它是一个现代的、支持 Docker 的指标、事件和日志收集代理。它作为一个小容器在每个 Docker 主机上运行,并为所有集群节点和容器收集日志、指标和事件。它会发现所有容器(一个 Pod 可能包含多个容器),包括 Kubernetes 核心服务的容器(如果核心服务部署在 Docker 容器中)。部署后,所有日志和指标都会立即可用。
将代理部署到节点
Kubernetes 提供 DaemonSet,确保将 Pod 添加到集群。
配置 SemaText Docker 代理
它通过环境变量进行配置。
如果您还没有帐户,请在apps.sematext.com获取免费帐户。
创建一个类型为“Docker”的 SPM 应用程序以获取 SPM 应用程序令牌。SPM 应用程序将保存您的 Kubernetes 性能指标和事件。
创建一个 Logsene 应用程序以获取 Logsene 应用程序令牌。Logsene 应用程序将保存您的 Kubernetes 日志。
编辑 DaemonSet 定义中的 LOGSENE_TOKEN 和 SPM_TOKEN 值,如下所示。
获取最新的 sematext-agent-daemonset.yml(原始纯文本)模板(如下所示)。
将其存储在磁盘上的某个位置。
将 SPM_TOKEN 和 LOGSENE_TOKEN 占位符替换为您的 SPM 和 Logsene 应用程序令牌。
创建 DaemonSet 对象
apiVersion: extensions/v1beta1 kind: DaemonSet metadata: name: sematext-agent spec: template: metadata: labels: app: sematext-agent spec: selector: {} dnsPolicy: "ClusterFirst" restartPolicy: "Always" containers: - name: sematext-agent image: sematext/sematext-agent-docker:latest imagePullPolicy: "Always" env: - name: SPM_TOKEN value: "REPLACE THIS WITH YOUR SPM TOKEN" - name: LOGSENE_TOKEN value: "REPLACE THIS WITH YOUR LOGSENE TOKEN" - name: KUBERNETES value: "1" volumeMounts: - mountPath: /var/run/docker.sock name: docker-sock - mountPath: /etc/localtime name: localtime volumes: - name: docker-sock hostPath: path: /var/run/docker.sock - name: localtime hostPath: path: /etc/localtime
使用 kubectl 运行 Sematext Agent Docker
$ kubectl create -f sematext-agent-daemonset.yml daemonset "sematext-agent-daemonset" created
Kubernetes 日志
Kubernetes 容器的日志与 Docker 容器日志并没有太大区别。但是,Kubernetes 用户需要查看已部署 Pod 的日志。因此,拥有可用于日志搜索的 Kubernetes 特定信息非常有用,例如:
- Kubernetes 命名空间
- Kubernetes Pod 名称
- Kubernetes 容器名称
- Docker 镜像名称
- Kubernetes UID
使用 ELK Stack 和 LogSpout
ELK 堆栈包括 Elasticsearch、Logstash 和 Kibana。为了将日志收集并转发到日志记录平台,我们将使用 LogSpout(尽管还有其他选项,例如 FluentD)。
以下代码显示如何在 Kubernetes 上设置 ELK 集群并为 Elasticsearch 创建服务:
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
创建副本控制器
apiVersion: v1 kind: ReplicationController metadata: name: es namespace: elk labels: component: elasticsearch spec: replicas: 1 template: metadata: labels: component: elasticsearch spec: serviceAccount: elasticsearch containers: - name: es securityContext: capabilities: add: - IPC_LOCK image: quay.io/pires/docker-elasticsearch-kubernetes:1.7.1-4 env: - name: KUBERNETES_CA_CERTIFICATE_FILE value: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt - name: NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: "CLUSTER_NAME" value: "myesdb" - name: "DISCOVERY_SERVICE" value: "elasticsearch" - name: NODE_MASTER value: "true" - name: NODE_DATA value: "true" - name: HTTP_ENABLE value: "true" ports: - containerPort: 9200 name: http protocol: TCP - containerPort: 9300 volumeMounts: - mountPath: /data name: storage volumes: - name: storage emptyDir: {}
Kibana URL
对于 Kibana,我们将 Elasticsearch URL 作为环境变量提供。
- name: KIBANA_ES_URL value: "http://elasticsearch.elk.svc.cluster.local:9200" - name: KUBERNETES_TRUST_CERT value: "true"
Kibana UI 将可在容器端口 5601 和相应的主机/节点端口组合处访问。开始时,Kibana 中不会有任何数据(这是预期的,因为您没有推送任何数据)。