diff --git a/.vuepress/config.js b/.vuepress/config.js index 16b942a..03b5a93 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -29,6 +29,7 @@ module.exports = { margin: 16 } }, + 'code-switcher': {}, 'reading-progress': {}, 'vuepress-plugin-element-tabs': {}, 'vuepress-plugin-baidu-autopush':{}, @@ -202,6 +203,18 @@ module.exports = { ], '/micro-service/': [ + { + title: 'Kubernetes 入门', + collapsable: false, + children: [ + 'prepare/k8s-basics/kubernetes-basics', + 'prepare/k8s-basics/deploy-app', + 'prepare/k8s-basics/explore', + 'prepare/k8s-basics/expose', + 'prepare/k8s-basics/scale', + 'prepare/k8s-basics/update' + ] + }, { title: 'Spring Cloud', collapsable: false, @@ -229,5 +242,3 @@ module.exports = { } } } - - diff --git a/.vuepress/public/install-script/init-master.sh b/.vuepress/public/install-script/init-master.sh index ed0faf6..8edf0f7 100644 --- a/.vuepress/public/install-script/init-master.sh +++ b/.vuepress/public/install-script/init-master.sh @@ -1,3 +1,5 @@ +#!/bin/bash + # 只在 master 节点执行 # 查看完整配置选项 https://godoc.org/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2 diff --git a/install/install-k8s.md b/install/install-k8s.md index a1f96ec..3923a61 100644 --- a/install/install-k8s.md +++ b/install/install-k8s.md @@ -116,7 +116,7 @@ export MASTER_IP=x.x.x.x export APISERVER_NAME=apiserver.demo export POD_SUBNET=10.100.0.1/20 echo "${MASTER_IP} ${APISERVER_NAME}" >> /etc/hosts -curl https://kuboard.cn/install-script/init-master.sh | sh +curl -sSL https://kuboard.cn/install-script/init-master.sh | sh ``` ::: diff --git a/micro-service/prepare/k8s-basics/deploy-app.assets/module_02_first_app.svg b/micro-service/prepare/k8s-basics/deploy-app.assets/module_02_first_app.svg new file mode 100644 index 0000000..e0ae8fa --- /dev/null +++ b/micro-service/prepare/k8s-basics/deploy-app.assets/module_02_first_app.svg @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + Docker + Kubelt + + + Layer 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/micro-service/prepare/k8s-basics/deploy-app.md b/micro-service/prepare/k8s-basics/deploy-app.md new file mode 100644 index 0000000..674d45d --- /dev/null +++ b/micro-service/prepare/k8s-basics/deploy-app.md @@ -0,0 +1,126 @@ +# 部署第一个应用程序 + +本文翻译自 Kubernetes 官网 [Using kubectl to Create a Deployment](https://kubernetes.io/docs/tutorials/kubernetes-basics/deploy-app/deploy-intro/) ,并有所改写 + +### 前提 + +假设您已经完成 Kubernetes 集群的安装,请参考文档 [安装 Kubernetes 单Master节点](/install/install-k8s) + +### 目标 + +- 使用 kubectl 在 k8s 上部署第一个应用程序。 + +::: tip +* kubectl 是 k8s 的客户端工具,可以使用命令行管理集群。 +* 如果参考文档 [安装 Kubernetes 单Master节点](/install/install-k8s.html),您可以在 master 节点的 root 用户使用 kubectl 操作您的集群 +* 您也可以尝试 [从客户端电脑远程管理 Kubernetes](/install/install-kubectl.html) +::: + +### Kubernetes部署 + +在 k8s 上进行部署前,首先需要了解一个基本概念 **Deployment** + +**Deployment** 译名为 **部署**。在k8s中,通过发布 Deployment,可以创建应用程序 (docker image) 的实例 (docker container),这个实例会被包含在称为 **Pod** 的概念中,**Pod** 是 k8s 中最小单元的可管理单元。 + +在 k8s 集群中发布 Deployment 后,Deployment 将指示 k8s 如何创建和更新应用程序的实例,master 节点将应用程序实例调度到集群中的具体的节点上。 + +创建应用程序实例后,Kubernetes Deployment Controller 会持续监控这些实例。如果运行实例的 worker 节点关机或被删除,则 Kubernetes Deployment Controller 将在群集中资源最优的另一个 worker 节点上重新创建一个新的实例。**这提供了一种自我修复机制来解决机器故障或维护问题。** + +在容器编排之前的时代,各种安装脚本通常用于启动应用程序,但是不能够使应用程序从机器故障中恢复。通过创建应用程序实例并确保它们在集群节点中的运行实例个数,Kubernetes Deployment 提供了一种完全不同的方式来管理应用程序。 + +## 在 Kubernetes 上部署第一个应用程序 + +![img](./deploy-app.assets/module_02_first_app.svg) + +上图是在第一篇文章的基础上,添加上了Deployment、Pod和Container。 + +Deployment 处于 master 节点上,通过发布 Deployment,master 节点会选择合适的 worker 节点创建 Container(即图中的正方体),Container 会被包含在 Pod (即蓝色圆圈)里。 + +## 实战:部署 nginx Deployment + +**创建 YAML 文件** + +创建文件 nginx-deployment.yaml,内容如下: + + + + + + + +**应用 YAML 文件** + +``` sh +kubectl apply -f nginx-deployment.yaml +``` + +**查看部署结果** + +``` sh +# 查看 Deployment +kubectl get deployments + +# 查看 Pod +kubectl get pods +``` + +可分别查看到一个名为 nginx-deployment 的 Deployment 和一个名为 nginx-deployment-xxxxxxx 的 Pod + + +~~任务二达成,至此你已经成功在k8s上部署了一个实例的nginx应用程序, + +~~想要知道 Deployment(部署)、Pod(容器组) 和 Node(节点) 之间的关系吗? + +~~let‘s go-> [查看 Pods(容器组)和 Nodes(节点)](./explore.html) diff --git a/micro-service/prepare/k8s-basics/explore.assets/module_03_nodes.svg b/micro-service/prepare/k8s-basics/explore.assets/module_03_nodes.svg new file mode 100644 index 0000000..0c7e61a --- /dev/null +++ b/micro-service/prepare/k8s-basics/explore.assets/module_03_nodes.svg @@ -0,0 +1,521 @@ + + + + + + + + + + + + + + + + + + + + + + + Docker + + Kubelt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/micro-service/prepare/k8s-basics/explore.assets/module_03_pods.svg b/micro-service/prepare/k8s-basics/explore.assets/module_03_pods.svg new file mode 100644 index 0000000..b63f415 --- /dev/null +++ b/micro-service/prepare/k8s-basics/explore.assets/module_03_pods.svg @@ -0,0 +1,484 @@ + + + + + + + + + + + + + + + + + + + + + + + Docker + + Kubelt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/micro-service/prepare/k8s-basics/explore.md b/micro-service/prepare/k8s-basics/explore.md new file mode 100644 index 0000000..373e510 --- /dev/null +++ b/micro-service/prepare/k8s-basics/explore.md @@ -0,0 +1,111 @@ +# 查看 Pods / Nodes + +本文翻译自 Kubernetes 官网 [Viewing Pods and Nodes](https://kubernetes.io/docs/tutorials/kubernetes-basics/explore/explore-intro/) ,并有所改写 + +## 目标 + +- 了解Kubernetes Pods(容器组) +- 了解Kubernetes Nodes(节点) +- 排查故障 + +## Kubernetes Pods + +在 [部署第一个应用程序](./deploy-app.html) 中创建 Deployment 后,k8s创建了一个 **Pod(容器组)** 来放置应用程序实例(container 容器)。 + +## Pods概述 + + + + +**Pod 容器组** 是一个k8s中一个抽象的概念,用于存放一组 container(可包含一个或多个 container 容器,即图上正方体),以及这些 container (容器)的一些共享资源。这些资源包括: + +- 共享存储,称为卷(Volumes),即图上紫色圆柱 +- 网络,每个 Pod(容器组)在集群中有个唯一的 IP,pod(容器组)中的 container(容器)共享该IP地址 +- container(容器)的基本信息,例如容器的镜像版本,对外暴露的端口等 + +> 例如,Pod可能既包含带有Node.js应用程序的 container 容器,也包含另一个非 Node.js 的 container 容器,用于提供 Node.js webserver 要发布的数据。Pod中的容器共享 IP 地址和端口空间(同一 Pod 中的不同 container 端口不能相互冲突),始终位于同一位置并共同调度,并在同一节点上的共享上下文中运行。(同一个Pod内的容器可以使用 localhost + 端口号互相访问)。 +> + +Pod(容器组)是 k8s 集群上的最基本的单元。当我们在 k8s 上创建 Deployment 时,会在集群上创建包含容器的 Pod (而不是直接创建容器)。每个Pod都与运行它的 worker 节点(Node)绑定,并保持在那里直到终止或被删除。如果节点(Node)发生故障,则会在群集中的其他可用节点(Node)上运行相同的 Pod(从同样的镜像创建 Container,使用同样的配置,IP 地址不同,Pod 名字不同)。 + +::: tip +重要: +* Pod 是一组容器(可包含一个或多个应用程序容器),以及共享存储(卷 Volumes)、IP 地址和有关如何运行容器的信息。 +* 如果多个容器紧密耦合并且需要共享磁盘等资源,则他们应该被部署在同一个Pod(容器组)中。 +::: + +## Node(节点) + +下图显示一个 Node(节点)上含有4个 Pod(容器组) + + + +Pod(容器组)总是在 **Node(节点)** 上运行。Node(节点)是 kubernetes 集群中的计算机,可以是虚拟机或物理机。每个 Node(节点)都由 master 管理。一个 Node(节点)可以有多个Pod(容器组),kubernetes master 会根据每个 Node(节点)上可用资源的情况,自动调度 Pod(容器组)到最佳的 Node(节点)上。 + +每个 Kubernetes Node(节点)至少运行: + +- Kubelet,负责 master 节点和 worker 节点之间通信的进程;管理 Pod(容器组)和 Pod(容器组)内运行的 Container(容器)。 +- 容器运行环境(如Docker)负责下载镜像、创建和运行容器等。 + + +## 实战:使用Kubectl进行故障排除 + +在[部署第一个应用程序](./deploy-app.html) 中,我们使用了 kubectl 命令行界面部署了 nginx 并且查看了 Deployment 和 Pod。kubectl 还有如下四个常用命令,在我们排查问题时可以提供帮助: + +- **kubectl get** - 显示资源列表 + + ``` sh + # kubectl get 资源类型 + + #获取类型为Deployment的资源列表 + kubectl get deployments + + #获取类型为Pod的资源列表 + kubectl get pods + + #获取类型为Node的资源列表 + kubectl get nodes + ``` + +- **kubectl describe** - 显示有关资源的详细信息 + + ``` sh + # kubectl describe 资源类型 资源名称 + + #查看名称为nginx-XXXXXX的Pod的信息 + kubectl describe pod nginx-XXXXXX + + #查看名称为nginx-XXXXXXX的Deployment的信息 + kubectl describe deployment nginx-XXXXXXX + ``` + +- **kubectl logs** - 查看pod中的容器的打印日志(和命令docker logs 类似) + + ``` sh + # kubectl logs Pod名称 + + #查看名称为nginx-pod-XXXXXXX的Pod内的容器打印的日志 + kubectl logs -f nginx-pod-XXXXXXX + ``` + +- **kubectl exec** - 在pod中的容器环境内执行命令(和命令docker exec 类似) + + ```sh + # kubectl exec Pod名称 操作命令 + + # 在名称为nginx-pod-xxxxxx的Pod中运行bash + kubectl exec -it nginx-pod-xxxxxx /bin/bash + ``` + +请尝试在您的集群中执行一下上述的几个命令,了解如何通过 kubectl 操作 kubernetes 集群中的 Node、Pod、Container。 + +::: tip +Worker节点是k8s中的工作计算机,可能是VM或物理计算机,具体取决于群集。多个Pod可以在一个节点上运行。 +::: + + +~~现在我们已经学会在k8s上部署程序,并且也知道了部署在k8s中涉及的资源和流程, + +~~等等,我们的程序还不知道如何访问呢?其实也是一个yaml文件就能实现 + +~~let‘s go-> [使用 Service(服务)公布您的应用程序](./expose.html) diff --git a/micro-service/prepare/k8s-basics/expose.assets/module_04_labels.svg b/micro-service/prepare/k8s-basics/expose.assets/module_04_labels.svg new file mode 100644 index 0000000..31cd863 --- /dev/null +++ b/micro-service/prepare/k8s-basics/expose.assets/module_04_labels.svg @@ -0,0 +1,710 @@ + + + + + + + + + + + + + + + + + + + + + + + Docker + + Kubelt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/micro-service/prepare/k8s-basics/expose.assets/module_04_services.svg b/micro-service/prepare/k8s-basics/expose.assets/module_04_services.svg new file mode 100644 index 0000000..a12c097 --- /dev/null +++ b/micro-service/prepare/k8s-basics/expose.assets/module_04_services.svg @@ -0,0 +1,304 @@ + + + + + + + + + + + + + + + + + + + Docker + Kubelt + + + Layer 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Pod + + + Node + + + + + \ No newline at end of file diff --git a/micro-service/prepare/k8s-basics/expose.md b/micro-service/prepare/k8s-basics/expose.md new file mode 100644 index 0000000..5da5db5 --- /dev/null +++ b/micro-service/prepare/k8s-basics/expose.md @@ -0,0 +1,157 @@ +# 公布应用程序 + +本文翻译自 Kubernetes 官网 [Using a Service to Expose Your App](https://kubernetes.io/docs/tutorials/kubernetes-basics/expose/expose-intro/) ,并有所改写 + +## 目标 + +- 了解 Kubernetes 的 Service(服务) +- 了解 Labels(标签)和 LabelSelector(标签选择器)与 Service(服务)的关系 +- 在 kubernetes 集群中,通过 Service(服务)向外公布应用程序 + +## Kubernetes Service(服务)概述 + +事实上,Pod(容器组)有自己的 [生命周期](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/)。当 worker node(节点)故障时,节点上运行的 Pod(容器组)也会消失。然后,[Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) 可以通过创建新的 Pod(容器组)来动态地将群集调整回原来的状态,以使应用程序保持运行。 + +举个例子,假设有一个图像处理后端程序,具有 3 个运行时副本。这 3 个副本是可以替换的(无状态应用),即使 Pod(容器组)消失并被重新创建,或者副本数由 3 增加到 5,前端系统也无需关注后端副本的变化。由于 Kubernetes 集群中每个 Pod(容器组)都有一个唯一的 IP 地址(即使是同一个 Node 上的不同 Pod),我们需要一种机制,为前端系统屏蔽后端系统的 Pod(容器组)在销毁、创建过程中所带来的 IP 地址的变化。 + +Kubernetes 中的 **Service(服务)** 提供了这样的一个抽象层,它选择具备某些特征的 Pod(容器组)并为它们定义一个访问方式。Service(服务)使 Pod(容器组)之间的相互依赖解耦(原本从一个 Pod 中访问另外一个 Pod,需要知道对方的 IP 地址)。一个 Service(服务)选定哪些 **Pod(容器组)** 通常由 **LabelSelector(标签选择器)** 来决定。 + +在创建Service的时候,通过设置配置文件中的 spec.type 字段的值,可以以不同方式向外部暴露应用程序: + +- **ClusterIP**(默认) + + 在群集中的内部IP上公布服务,这种方式的 Service(服务)只在集群内部可以访问到 + +- **NodePort** + + 使用 NAT 在集群中每个的同一端口上公布服务。这种方式下,可以通过访问集群中任意节点+端口号的方式访问服务 `:`。此时 ClusterIP 的访问方式仍然可用。 + +- **LoadBalancer** + + 在云环境中(需要云供应商可以支持)创建一个集群外部的负载均衡器,并为使用该负载均衡器的 IP 地址作为服务的访问地址。此时 ClusterIP 和 NodePort 的访问方式仍然可用。 + +::: tip +Service是一个抽象层,它通过 LabelSelector 选择了一组 Pod(容器组),把这些 Pod 的指定端口公布到到集群外部,并支持负载均衡和服务发现。 +* 公布 Pod 的端口以使其可访问 +* 在多个 Pod 间实现负载均衡 +* 使用 Label 和 LabelSelector +::: + +## 服务和标签 + +下图中有两个服务Service A(蓝色虚线)和Service B(黄色虚线) +Service A 将请求转发到 IP 为 10.10.10.1 的Pod上, +Service B 将请求转发到 IP 为 10.10.10.2、10.10.10.3、10.10.10.4 的Pod上。 + +![img](./expose.assets/module_04_services.svg) + +Service 将外部请求路由到一组 Pod 中,它提供了一个抽象层,使得 Kubernetes 可以在不影响服务调用者的情况下,动态调度容器组(在容器组失效后重新创建容器组,增加或者减少同一个 Deployment 对应容器组的数量等)。 + +Service使用 [Labels、LabelSelector(标签和选择器)](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels) 匹配一组 Pod。Labels(标签)是附加到 Kubernetes 对象的键/值对,其用途有多种: + +- 将 Kubernetes 对象(Node、Deployment、Pod、Service等)指派用于开发环境、测试环境或生产环境 +- 嵌入版本标签,使用标签区别不同应用软件版本 +- 使用标签对 Kubernetes 对象进行分类 + +下图体现了 Labels(标签)和 LabelSelector(标签选择器)之间的关联关系 + +* Deployment B 含有 LabelSelector 为 app=B 通过此方式声明含有 app=B 标签的 Pod 与之关联 +* 通过 Deployment B 创建的 Pod 包含标签为 app=B +* Service B 通过标签选择器 app=B 选择可以路由的 Pod + + + +Labels(标签)可以在创建 Kubernetes 对象时附加上去,也可以在创建之后再附加上去。任何时候都可以修改一个 Kubernetes 对象的 Labels(标签) + +## 实战:为您的 nginx Deployment 创建一个 Service + +创建nginx的Deployment中定义了Labels,如下: + +``` yaml +metadata: #译名为元数据,即Deployment的一些基本属性和信息 + name: nginx-deployment #Deployment的名称 + labels: #标签,可以灵活定位一个或多个资源,其中key和value均可自定义,可以定义多组 + app: nginx #为该Deployment设置key为app,value为nginx的标签 +``` + +**创建文件 nginx-service.yaml** + +``` sh +vim nginx-service.yaml +``` + +**文件内容如下:** + + + + + + +**执行命令** + +``` sh +kubectl apply -f nginx-service.yaml +``` + +**检查执行结果** + +``` sh +kubectl get services -o wide +``` + +可查看到名称为nginx-service的服务。 + +**访问服务** + +``` sh +curl <任意节点的 IP>:32600 +``` +> 如果您的集群在云上,您可能通过云服务商的安全组开放 32600 端口的访问 + + +~~到目前为止,我们已经成功部署好项目,并能够对其进行访问, + +~~接下来是对于多实例部署和滚动更新的相关介绍与实践 + +~~let‘s go-> [应用程序的伸缩](./scale.html) diff --git a/micro-service/prepare/k8s-basics/kubernetes-basics.assets/module_01.svg b/micro-service/prepare/k8s-basics/kubernetes-basics.assets/module_01.svg new file mode 100644 index 0000000..a1c42e9 --- /dev/null +++ b/micro-service/prepare/k8s-basics/kubernetes-basics.assets/module_01.svg @@ -0,0 +1 @@ +16.07.28_k8s_visual_diagrams \ No newline at end of file diff --git a/micro-service/prepare/k8s-basics/kubernetes-basics.assets/module_01_cluster.svg b/micro-service/prepare/k8s-basics/kubernetes-basics.assets/module_01_cluster.svg new file mode 100644 index 0000000..e1f92da --- /dev/null +++ b/micro-service/prepare/k8s-basics/kubernetes-basics.assets/module_01_cluster.svg @@ -0,0 +1,239 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + Docker + Kubelt + + + Layer 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/micro-service/prepare/k8s-basics/kubernetes-basics.md b/micro-service/prepare/k8s-basics/kubernetes-basics.md new file mode 100644 index 0000000..356edf2 --- /dev/null +++ b/micro-service/prepare/k8s-basics/kubernetes-basics.md @@ -0,0 +1,48 @@ +# 学习Kubernetes基础知识 + +本文翻译自 Kubernetes 官网 [Learn Kubernetes Basics](https://kubernetes.io/docs/tutorials/kubernetes-basics/) ,并有所改写 + +相信很多初学者在入门Kubernetes(以下简称k8s)时,都会被各种英文单词所困扰(例如:Deployment、Pod、Service等),这些名词在被翻译后也往往失去了原意,更不能体现出他们的相互关系。笔者在刚开始学习k8s时也遭遇到这种困境。但是,任何复杂的系统都是发源于最基本的公式或定理,k8s虽然庞大且复杂,不过只要抓住一些基本的脉络(一些最基本的组件的定义及使用),入门便也是毫不费劲。 + +本文基于k8s官方基础教程,从现实运维使用场景出发,结合上述新手入门困境,基于基本组件的定义、功能和使用角度进行讲解,帮助新手在最小化复杂度的前提下上手k8s。 + +## 学习目标 + +- 在k8s集群上部署应用程序 +- 对应用程序进行扩容缩容(多实例) +- 对应用程序进行版本更新 +- 使用k8s工具排查部署问题 + +## Kubernetes功能 + +官方定义k8s能够对容器化软件进行部署管理,在不停机的前提下提供简单快速的发布和更新方式。换句话说,如果项目需要多机器节点的微服务架构,并且采用Docker image(镜像)进行容器化部署,那么k8s可以帮助我们屏蔽掉集群的复杂性,自动选择最优资源分配方式进行部署。在此基础上,k8s还提供简单的多实例部署及更新方案,仅需几个操作命令就可以轻松实现。 + +## Kubernetes 入门目录 + +* [01.部署第一个应用程序](./deploy-app.html) 5分钟 +* [02.查看 Pods / Nodes](./explore.html) 10分钟 +* [03.公布应用程序](./expose.html) 10分钟 +* [04.伸缩应用程序](./scale.html) 10分钟 +* [05.执行滚动更新](./update.html) 10分钟 + +## k8s集群简单介绍 + +本篇中我们先从第一部分入手,对k8s集群有个整体上的把握。 + + + +上图描述的是拥有一个Master(主)节点和六个Worker(工作)节点的k8s集群 + +![img](./kubernetes-basics.assets/module_01_cluster.svg) + +**Master 负责管理集群** 负责协调集群中的所有活动,例如调度应用程序,维护应用程序的状态,扩展和更新应用程序。 + +**Worker节点(即图中的Node)是VM(虚拟机)或物理计算机,充当k8s集群中的工作计算机。** 每个Worker节点都有一个Kubelet,它管理一个Worker节点并与负责与Master节点通信。该Worker节点还应具有用于处理容器操作的工具,例如Docker。 + + + +~~恭喜你,新成就达成,是不是很简单, + +~~初学仅需对主要概念有个整体且正确的把握即可,让我们继续吧 + +~~let‘s go-> [部署第一个应用程序](./deploy-app.html) diff --git a/micro-service/prepare/k8s-basics/scale.assets/module_05_scaling1.svg b/micro-service/prepare/k8s-basics/scale.assets/module_05_scaling1.svg new file mode 100644 index 0000000..45458cf --- /dev/null +++ b/micro-service/prepare/k8s-basics/scale.assets/module_05_scaling1.svg @@ -0,0 +1,313 @@ + + + + + + + + + + + + + + + + + + + + + + + Docker + + Kubelt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/micro-service/prepare/k8s-basics/scale.assets/module_05_scaling2.svg b/micro-service/prepare/k8s-basics/scale.assets/module_05_scaling2.svg new file mode 100644 index 0000000..53971c5 --- /dev/null +++ b/micro-service/prepare/k8s-basics/scale.assets/module_05_scaling2.svg @@ -0,0 +1,395 @@ + + + + + + + + + + + + + + + + + + + + + + + Docker + + Kubelt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/micro-service/prepare/k8s-basics/scale.md b/micro-service/prepare/k8s-basics/scale.md new file mode 100644 index 0000000..811a296 --- /dev/null +++ b/micro-service/prepare/k8s-basics/scale.md @@ -0,0 +1,78 @@ +# 伸缩应用程序 + +本文翻译自 Kubernetes 官网 [Running Multiple Instances of Your App](https://kubernetes.io/docs/tutorials/kubernetes-basics/scale/scale-intro/) ,并有所改写 + +## 目标 + +- 使用 kubectl 伸缩应用程序。 + +## Scaling(伸缩)应用程序 + +在之前的文章中,我们创建了一个 [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/),然后通过 [服务](https://kubernetes.io/docs/concepts/services-networking/service/) 提供访问 Pod 的方式。我们发布的 Deployment 只创建了一个 Pod 来运行我们的应用程序。当流量增加时,我们需要对应用程序进行伸缩操作以满足系统性能需求。 + +**伸缩** 的实现可以通过更改 nginx-deployment.yaml 文件中部署的 replicas(副本数)来完成 + +``` yaml +spec: + replicas: 2 #使用该Deployment创建两个应用程序实例 +``` + +## Scaling(伸缩)概述 + +下图中,Service A 只将访问流量转发到 IP 为 10.0.0.5 的Pod上 + + + +修改了 Deployment 的 replicas 为 4 后,Kubernetes 又为该 Deployment 创建了 3 新的 Pod,这 4 个 Pod 有相同的标签。因此Service A通过标签选择器与新的 Pod建立了对应关系,将访问流量通过负载均衡在 4 个 Pod 之间进行转发。 + + + +::: tip +通过更改部署中的 replicas(副本数)来完成扩展 +::: + +## 实战:将 nginx Deployment 扩容到 4 个副本 + +**修改 nginx-deployment.yaml 文件** + +将 replicas 修改为 4 + +``` yaml {8} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx-deployment + labels: + app: nginx +spec: + replicas: 4 + selector: + matchLabels: + app: nginx + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx:1.7.9 + ports: + - containerPort: 80 +``` + +**执行命令** + +``` sh +kubectl apply -f nginx-deployment.yaml +``` + +**查看结果** + +``` sh +watch kubectl get pods -o wide +``` + +~~一旦运行了多个应用程序实例,就可以在不停机的情况下执行滚动更新了, + +~~let‘s go-> [执行滚动更新](./update.html) diff --git a/micro-service/prepare/k8s-basics/update.assets/module_06_rollingupdates1.svg b/micro-service/prepare/k8s-basics/update.assets/module_06_rollingupdates1.svg new file mode 100644 index 0000000..53971c5 --- /dev/null +++ b/micro-service/prepare/k8s-basics/update.assets/module_06_rollingupdates1.svg @@ -0,0 +1,395 @@ + + + + + + + + + + + + + + + + + + + + + + + Docker + + Kubelt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/micro-service/prepare/k8s-basics/update.assets/module_06_rollingupdates2.svg b/micro-service/prepare/k8s-basics/update.assets/module_06_rollingupdates2.svg new file mode 100644 index 0000000..9773502 --- /dev/null +++ b/micro-service/prepare/k8s-basics/update.assets/module_06_rollingupdates2.svg @@ -0,0 +1,543 @@ + + + + + + + + + + + + + + + + + + + + + + + Docker + + Kubelt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/micro-service/prepare/k8s-basics/update.assets/module_06_rollingupdates3.svg b/micro-service/prepare/k8s-basics/update.assets/module_06_rollingupdates3.svg new file mode 100644 index 0000000..15bd6e6 --- /dev/null +++ b/micro-service/prepare/k8s-basics/update.assets/module_06_rollingupdates3.svg @@ -0,0 +1,493 @@ + + + + + + + + + + + + + + + + + + + + + + + Docker + + Kubelt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/micro-service/prepare/k8s-basics/update.assets/module_06_rollingupdates4.svg b/micro-service/prepare/k8s-basics/update.assets/module_06_rollingupdates4.svg new file mode 100644 index 0000000..a326317 --- /dev/null +++ b/micro-service/prepare/k8s-basics/update.assets/module_06_rollingupdates4.svg @@ -0,0 +1,508 @@ + + + + + + + + + + + + + + + + + + + + + + + Docker + + Kubelt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/micro-service/prepare/k8s-basics/update.md b/micro-service/prepare/k8s-basics/update.md new file mode 100644 index 0000000..9203958 --- /dev/null +++ b/micro-service/prepare/k8s-basics/update.md @@ -0,0 +1,89 @@ +# 执行滚动更新 + +本文翻译自 Kubernetes 官网 [Performing a Rolling Update](https://kubernetes.io/docs/tutorials/kubernetes-basics/update/update-intro/) ,并有所改写 + +## 目标 + +- 使用 kubectl 执行 Rolling Update(滚动更新) + +## 更新应用程序 + +用户期望应用程序始终可用,为此开发者/运维者在更新应用程序时要分多次完成。在 Kubernetes 中,这是通过 Rolling Update 滚动更新完成的。**Rolling Update滚动更新** 通过使用新版本的 Pod 逐步替代旧版本的 Pod 来实现 Deployment 的更新,从而实现零停机。新的 Pod 将在具有可用资源的 Node(节点)上进行调度。 + +> Kubernetes 更新多副本的 Deployment 的版本时,会逐步的创建新版本的 Pod,逐步的停止旧版本的 Pod,以便使应用一直处于可用状态。这个过程中,Service 能够监视 Pod 的状态,将流量始终转发到可用的 Pod 上。 + +在上一个模块中,我们学习了将应用程序 Scale Up(扩容)为多个实例,这是执行更新而不影响应用程序可用性的前提(如果只有个实例那还玩啥)。默认情况下,**Rolling Update 滚动更新** 过程中,Kubernetes 逐个使用新版本 Pod 替换旧版本 Pod(最大不可用 Pod 数为 1、最大新建 Pod 数也为 1)。这两个参数可以配置为数字或百分比。在Kubernetes 中,更新是版本化的,任何部署更新都可以恢复为以前的(稳定)版本。 + +## 滚动更新概述 + +1. 原本 Service A 将流量负载均衡到 4 个旧版本的 Pod (当中的容器为 绿色)上 + +![img](./update.assets/module_06_rollingupdates1.svg) + +2. 更新完 Deployment 部署文件中的镜像版本后,master 节点选择了一个 worker 节点,并根据新的镜像版本创建 Pod(紫色容器)。新 Pod 拥有唯一的新的 IP。同时,master 节点选择一个旧版本的 Pod 将其移除。 + + 此时,Service A 将新 Pod 纳入到负载均衡中,将旧Pod移除 + +![img](./update.assets/module_06_rollingupdates2.svg) + +3. 同步骤2,再创建一个新的 Pod 替换一个原有的 Pod + +![img](./update.assets/module_06_rollingupdates3.svg) + +1. 如此 Rolling Update 滚动更新,直到所有旧版本 Pod 均移除,新版本 Pod 也达到 Deployment 部署文件中定义的副本数,则滚动更新完成 + +![img](./update.assets/module_06_rollingupdates4.svg) + +滚动更新允许以下操作: + +- 将应用程序从准上线环境升级到生产环境(通过更新容器镜像) +- 回滚到以前的版本 +- 持续集成和持续交付应用程序,无需停机 + +## 实战:更新 nginx Deployment + +**修改 nginx-deployment.yaml 文件** + +修改文件中 image 镜像的标签,如下所示 + +``` yaml {19} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx-deployment + labels: + app: nginx +spec: + replicas: 4 + selector: + matchLabels: + app: nginx + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx:1.8 #使用镜像nginx:1.8替换原来的nginx:1.7.9 + ports: + - containerPort: 80 +``` + +**执行命令** + +``` sh +kubectl apply -f nginx-deployment.yaml +``` + +**查看过程及结果** + +执行命令,可观察到 pod 逐个被替换的过程。 +``` sh +watch kubectl get pods -l app=nginx +``` + + +~~哈哈,到此,您已经成入门 kubernetes,并完成了部署、扩容与滚动更新的实践, + +~~学以至用是对知识最好的巩固,更多的k8s高级应用期待您的探索 diff --git a/overview/README.md b/overview/README.md index f8a560f..2ba5c72 100644 --- a/overview/README.md +++ b/overview/README.md @@ -100,7 +100,7 @@ A cool Kubernetes dashboard. Kuboard 为 Kubernetes 初学者设计了如下学习路径: * **Kubernetes 体验** - * [安装 Kubernetes 单Master节点](/install/install-k8s.html) (1小时,初学者也许需要更多) + * [安装 Kubernetes 单Master节点](/install/install-k8s.html) (30分钟,初学者也许需要更多) * 参照经过众多网友验证,不断优化的安装文档,迅速完成 Kubernetes 安装,拥有属于自己的 Kubernetes 集群。 * [安装 Kuboard](/install/install-dashboard.html) (5分钟) * 使用 Kuboard,无需编写复杂冗长的 YAML 文件,就可以轻松管理 Kubernetes 集群。 @@ -110,14 +110,13 @@ Kuboard 为 Kubernetes 初学者设计了如下学习路径: * 导入一个完整的 example 微服务应用,体验 Spring Cloud 在 Kubernetes 上的部署过程。 * **Kubernetes 入门** - * [十分钟带你理解Kubernetes核心概念](k8s-core-concepts.html) - * [Learn Kubernetes Basics](https://kubernetes.io/docs/tutorials/kubernetes-basics/) - * [Using kubectl to Create a Deployment](https://kubernetes.io/docs/tutorials/kubernetes-basics/deploy-app/deploy-intro/) - * [Viewing Pods and Nodes](https://kubernetes.io/docs/tutorials/kubernetes-basics/explore/explore-intro/) - * [Using a Service to Expose Your App](https://kubernetes.io/docs/tutorials/kubernetes-basics/expose/expose-intro/) - * [Running Multiple Instances of Your App](https://kubernetes.io/docs/tutorials/kubernetes-basics/scale/scale-intro/) - * [Performing a Rolling Update](https://kubernetes.io/docs/tutorials/kubernetes-basics/update/update-intro/) -> Kubernetes 官方教程质量非常高,正在翻译 + * [十分钟带你理解Kubernetes核心概念](./k8s-core-concepts.html) + * [学习Kubernetes基础知识](/micro-service/prepare/k8s-basics/kubernetes-basics.html) (10分钟) + * [部署第一个应用程序](/micro-service/prepare/k8s-basics/deploy-app.html) (5分钟) + * [查看 Pods / Nodes](/micro-service/prepare/k8s-basics/explore.html) (10分钟) + * [公布应用程序](/micro-service/prepare/k8s-basics/expose.html) (10分钟) + * [伸缩应用程序](/micro-service/prepare/k8s-basics/scale.html) (10分钟) + * [执行滚动更新](/micro-service/prepare/k8s-basics/update.html) (10分钟) ### Kubernetes 有经验者 @@ -156,4 +155,4 @@ Kuboard 为您的这些痛苦提供了极佳的解决方案,请立刻开始: ## 在线提问 -![Kuboard 兴趣群二维码](./README.assets/kuboard_qq.png) \ No newline at end of file +![Kuboard 兴趣群二维码](./README.assets/kuboard_qq.png) diff --git a/overview/change-log-on-the-way.md b/overview/change-log-on-the-way.md index cbd5bbb..174f1b2 100644 --- a/overview/change-log-on-the-way.md +++ b/overview/change-log-on-the-way.md @@ -1,4 +1,4 @@ -## v1.0.1-beta.4 +## v1.0.2-beta.1 **发布日期** diff --git a/overview/change-log.md b/overview/change-log.md index 133e620..56226ff 100644 --- a/overview/change-log.md +++ b/overview/change-log.md @@ -1,5 +1,15 @@ # 更新日志 +## v1.0.1 + +**发布日期** + +2019-08-20 + +**BUG 修复** + +* 修复自定义 Kubernetes DNS Domain 时,无法使用监控套件的问题 + ## v1.0.1-beta.3 **发布日期** diff --git a/package-lock.json b/package-lock.json index 63b4ff0..5b8132e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10465,6 +10465,15 @@ "integrity": "sha1-5QQhcPBaWFxKOPh24B/0cGzYL74=", "dev": true }, + "vuepress-plugin-code-switcher": { + "version": "1.0.0", + "resolved": "https://registry.npm.taobao.org/vuepress-plugin-code-switcher/download/vuepress-plugin-code-switcher-1.0.0.tgz", + "integrity": "sha1-lcm4v2W98Ly1cMtv8AC/VfpkDTE=", + "dev": true, + "requires": { + "@vuepress/plugin-register-components": "^1.0.0-alpha.0" + } + }, "vuepress-plugin-container": { "version": "2.0.2", "resolved": "https://registry.npm.taobao.org/vuepress-plugin-container/download/vuepress-plugin-container-2.0.2.tgz", diff --git a/package.json b/package.json index afb132e..e65ff55 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "date-fns": "^1.30.1", "vuepress": "^1.0.2", "vuepress-plugin-baidu-autopush": "^1.0.1", + "vuepress-plugin-code-switcher": "^1.0.0", "vuepress-plugin-element-tabs": "^0.1.8", "vuepress-plugin-reading-progress": "^1.0.7", "vuepress-plugin-seo": "^0.1.2",