From ddd53b24ffacda5179a66d01fa61c52b647c6735 Mon Sep 17 00:00:00 2001 From: 01Petard <1520394133@qq.com> Date: Fri, 8 Nov 2024 21:19:09 +0800 Subject: [PATCH] =?UTF-8?q?doc:=20=E5=A4=87=E4=BB=BD=E6=96=87=E7=AB=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/.vitepress/config.js | 1 + ...- \345\210\206\345\270\203\345\274\217.md" | 354 +++++++++++----- ...06\347\276\244\347\216\257\345\242\203.md" | 389 ++++++++++++++++++ 3 files changed, 636 insertions(+), 108 deletions(-) create mode 100644 "docs/\345\274\200\345\217\221/\346\220\255\345\273\272K8S\351\233\206\347\276\244\347\216\257\345\242\203.md" diff --git a/docs/.vitepress/config.js b/docs/.vitepress/config.js index cc4322e..3c16379 100644 --- a/docs/.vitepress/config.js +++ b/docs/.vitepress/config.js @@ -68,6 +68,7 @@ export default { {text: '批量导出zip压缩包和Excel表格', link: '/开发/批量导出zip压缩包和Excel表格'}, {text: '阿里云OSS && 内容安全 Java实现参考代码', link: '/开发/阿里云OSS && 内容安全 Java实现参考代码'}, {text: '抖音评论区设计', link: '/开发/抖音评论区设计'}, + {text: '搭建K8S集群环境', link: '/开发/搭建K8S集群环境'}, { text: 'My Java Guide', collapsed: false, diff --git "a/docs/\345\274\200\345\217\221/My Java Guide/My Java Guide - \345\210\206\345\270\203\345\274\217.md" "b/docs/\345\274\200\345\217\221/My Java Guide/My Java Guide - \345\210\206\345\270\203\345\274\217.md" index c9ba6f2..6def22e 100644 --- "a/docs/\345\274\200\345\217\221/My Java Guide/My Java Guide - \345\210\206\345\270\203\345\274\217.md" +++ "b/docs/\345\274\200\345\217\221/My Java Guide/My Java Guide - \345\210\206\345\270\203\345\274\217.md" @@ -830,7 +830,7 @@ Xxl-Job 支持多种任务分配策略,可以根据业务需求选择合适的 通过上述方法和技术手段,可以有效地应对大数据量任务的同时执行带来的挑战。 -#
--------------分布式架构设计--------------
+#
-----------------架构设计-----------------
# 例:讲一下分布式 ID 发号器的原理 @@ -1617,109 +1617,6 @@ public class WebMvcConfiguration extends WebMvcConfigurationSupport { } ``` -#
------------容器化技术和CI/CD------------
- -# Docker 的基本概念和工作原理 - -Docker 是一种开源的容器化平台,允许开发者和运维人员以一致的方式部署应用程序。通过将应用程序及其所有依赖打包到一个单独的容器中,Docker 提供了一种便捷的方式来执行和移动应用程序。这种容器在任何符合所需条件的环境中都能保证其运行一致。 - -工作原理上,Docker 利用 Linux 容器(LXC)的技术,并通过镜像(Image)、容器(Container)、仓库(Repository)等主要概念来实现应用的生命周期管理。具体来说,开发者首先创建一个 Docker 镜像,镜像是一个只读模板,包含应用程序及其运行所需的所有文件。然后,基于这个镜像,Docker 可以启动一个或多个容器,容器是镜像的运行实例。 - -# Docker Compose 的主要用途是什么? - -Docker Compose 是用于定义和运行多容器 Docker 应用程序的工具。Compose 使用 YAML 文件定义服务、网络和卷,通过一条简单的命令 `docker-compose up` 就可以启动并运行整个配置的应用环境。 - -举个例子,如果你有一个 web 应用,需要用到 MySQL 数据库,传统上你可能需要分别配置和运行这两个服务。而在 Docker Compose 中,你只需要创建一个 `docker-compose.yml` 文件,定义好 web 服务和 db 服务的配置,然后运行 `docker-compose up` 即可。 - -# Docker 镜像的构建过程 - -1. 编写 Dockerfile:其中包含了一系列的指令,描述了如何构建一个 Docker 镜像。 -2. 构建镜像:使用 `docker build` 命令,通过读取 Dockerfile 的内容,逐步执行其中的指令,最终生成一个 Docker 镜像。 -3. 保存镜像:构建完成的镜像会被保存到本地的 Docker 镜像库中,可以使用 `docker images` 命令查看。 -4. 发布镜像:如果需要共享镜像,可以将其推送到 Docker Hub 或其他镜像仓库,使用 `docker push` 命令完成发布。 -5. 使用镜像:最终用户可以使用 `docker run` 命令来启动基于该镜像的容器,完成应用的部署和运行。 - -# Dockerfile 的作用 - -1. 描述构建过程:Dockerfile 通过一系列的指令详细描述了构建镜像的步骤,包括基础镜像、环境配置、软件安装等。 -2. 保证一致性:同一个 Dockerfile 可以在不同环境下生成一致的镜像,确保应用运行环境的稳定和一致。 -3. 自动化构建:通过 Dockerfile,可以方便地实现镜像的自动化构建,简化了持续集成和持续部署(CI/CD)过程。 -4. 版本管理:Dockerfile 可以使用版本控制工具进行管理,方便回滚或跟踪更改记录。 - -# 使用 Dockerfile 创建自定义镜像 - -1. **编写 Dockerfile**:Dockerfile 是一个文本文件,包含了一系列指令,每个指令用来描述如何构建镜像。通常包括基础镜像的选择、复制文件、安装包以及配置环境等操作。 -2. **构建镜像**:使用 `docker build` 命令来构建镜像。 - -简单示例: - -1. 创建一个名为 `Dockerfile` 的文件,内容如下: - -```dockerfile -# 选择基础镜像 -FROM ubuntu:latest - -# 安装一些软件包 -RUN apt-get update && apt-get install -y python3 python3-pip - -# 设置工作目录 -WORKDIR /app - -# 复制当前目录下的文件到工作目录 -COPY .. /app - -# 安装 Python 依赖 -RUN pip3 install -r requirements.txt - -# 暴露端口 -EXPOSE 80 - -# 设置容器启动时默认执行的命令 -CMD ["python3", "app.py"] -``` - -2. 运行构建命令,将 Dockerfile 构建为镜像: - -```bash -docker build -t my_custom_image:latest . -``` - -# 如何优化容器启动时间? - -1. 使用较小的基础镜像:选择精简的基础镜像,例如 `alpine`,或其他定制过的轻量级基础镜像,例如 `scratch`。 -2. 减少镜像层数:每一层都会增加容器启动的开销,精简 Dockerfile,合并多个 `RUN` 命令,将有助于减少层数。 -3. 利用缓存:在构建镜像时尽量利用 Docker 的缓存功能,避免每次都重建镜像。 -4. 适当配置健康检查:配置适当的健康检查策略,让容器可以尽快转为运行状态,而不是卡在启动过程中。 -5. 本地化镜像:将常用的容器镜像保存在本地镜像库中,避免每次启动时从远程仓库拉取。 - -# 如何实现容器之间的通信? - -1. **使用同一个网络:** 将多个容器连接到同一个 Docker 网络中,这样容器之间可以通过容器名称进行互相通信。 -2. **端口映射:** 将容器的端口映射到宿主机的端口,通过宿主机的 IP 和映射的端口进行通信。 -3. **Docker Compose:** 使用 Docker Compose 来编排多个服务,可以为每个服务定义网络,并对网络进行配置。 -4. **共享网络命名空间:** 通过创建共享网络命名空间的方式,使多个容器共享网络设置。 - -## 如何实现资源限制? - -1. 为了限制容器使用的 CPU 数量,可以使用 `--cpu-shares` 或 `--cpus` 参数。 - - `--cpu-shares`:使用相对权重方式分配 CPU 资源。 - - `--cpus`:直接指定容器可使用的 CPU 核数。 -2. 为了限制容器使用的内存量,可以使用 `-m` 或 `--memory` 参数。 - - `--memory`:指定容器最大内存限制。 - -举个简单的例子,如果我们希望某个容器最多使用一个CPU核心和 512MB 内存,可以使用以下命令: - -```shell -docker run --cpus=1 --memory=512m [container_name] -``` - -# 如何使用 Jenkins 与 Docker 集成? - -1. 安装必要的插件:在 Jenkins 中,安装 Docker plugin 和 Pipeline plugin 等必要插件。 -2. 配置 Jenkins:配置环境,确保 Jenkins 可以访问 Docker 命令。 -3. 创建 Jenkins Pipeline:在 Jenkins 中创建一个 Pipeline 项目,并在 Pipeline Script 中编写构建、测试和部署的脚本,通常使用 Jenkinsfile。 -4. 运行与监控:配置好所有步骤后,运行 Pipeline 并监控执行过程,确保一切正常工作。 - #
------------------消息队列------------------
# AMQP协议 @@ -1923,8 +1820,6 @@ AMQP 消息通常包含以下几个部分: - **定义**:分区的备份,用于提高系统的可靠性和可用性。 - **用途**:当Leader失效时,可以切换到其他Replica继续提供服务。 -#
------------消息队列的底层设计------------
- image-20240412203231163 # 高可用设计 @@ -2645,8 +2540,6 @@ Netty中的参考计数(Reference Counting)是Netty为了管理内存而采 Netty通过使用`Selector`的`poll`方法,并结合`EventLoop`进行优化,避免了空轮询的情况。它会在没有事件时进行适当的休眠,减少CPU资源的浪费。 -#
---------------*Netty底层原理*---------------
- # Channel、ChannelHandlerContext - **Channel**:表示一个连接,可以是服务器端或客户端的`SocketChannel`,它负责数据的读写。 @@ -2814,3 +2707,248 @@ Netty中的Future和Promise是用于处理异步操作的结果和状态的。 3)多继承 抽象类只能单继承,接口可以有多个实现。 + +#
------------容器化技术和CI/CD------------
+ +# Docker 的基本概念和工作原理 + +Docker 是一种开源的容器化平台,允许开发者和运维人员以一致的方式部署应用程序。通过将应用程序及其所有依赖打包到一个单独的容器中,Docker 提供了一种便捷的方式来执行和移动应用程序。这种容器在任何符合所需条件的环境中都能保证其运行一致。 + +工作原理上,Docker 利用 Linux 容器(LXC)的技术,并通过镜像(Image)、容器(Container)、仓库(Repository)等主要概念来实现应用的生命周期管理。具体来说,开发者首先创建一个 Docker 镜像,镜像是一个只读模板,包含应用程序及其运行所需的所有文件。然后,基于这个镜像,Docker 可以启动一个或多个容器,容器是镜像的运行实例。 + +# Docker Compose 的主要用途是什么? + +Docker Compose 是用于定义和运行多容器 Docker 应用程序的工具。Compose 使用 YAML 文件定义服务、网络和卷,通过一条简单的命令 `docker-compose up` 就可以启动并运行整个配置的应用环境。 + +举个例子,如果你有一个 web 应用,需要用到 MySQL 数据库,传统上你可能需要分别配置和运行这两个服务。而在 Docker Compose 中,你只需要创建一个 `docker-compose.yml` 文件,定义好 web 服务和 db 服务的配置,然后运行 `docker-compose up` 即可。 + +# Docker 镜像的构建过程 + +1. 编写 Dockerfile:其中包含了一系列的指令,描述了如何构建一个 Docker 镜像。 +2. 构建镜像:使用 `docker build` 命令,通过读取 Dockerfile 的内容,逐步执行其中的指令,最终生成一个 Docker 镜像。 +3. 保存镜像:构建完成的镜像会被保存到本地的 Docker 镜像库中,可以使用 `docker images` 命令查看。 +4. 发布镜像:如果需要共享镜像,可以将其推送到 Docker Hub 或其他镜像仓库,使用 `docker push` 命令完成发布。 +5. 使用镜像:最终用户可以使用 `docker run` 命令来启动基于该镜像的容器,完成应用的部署和运行。 + +# Dockerfile 的作用 + +1. 描述构建过程:Dockerfile 通过一系列的指令详细描述了构建镜像的步骤,包括基础镜像、环境配置、软件安装等。 +2. 保证一致性:同一个 Dockerfile 可以在不同环境下生成一致的镜像,确保应用运行环境的稳定和一致。 +3. 自动化构建:通过 Dockerfile,可以方便地实现镜像的自动化构建,简化了持续集成和持续部署(CI/CD)过程。 +4. 版本管理:Dockerfile 可以使用版本控制工具进行管理,方便回滚或跟踪更改记录。 + +# 使用 Dockerfile 创建自定义镜像 + +1. **编写 Dockerfile**:Dockerfile 是一个文本文件,包含了一系列指令,每个指令用来描述如何构建镜像。通常包括基础镜像的选择、复制文件、安装包以及配置环境等操作。 +2. **构建镜像**:使用 `docker build` 命令来构建镜像。 + +简单示例: + +1. 创建一个名为 `Dockerfile` 的文件,内容如下: + +```dockerfile +# 选择基础镜像 +FROM ubuntu:latest + +# 安装一些软件包 +RUN apt-get update && apt-get install -y python3 python3-pip + +# 设置工作目录 +WORKDIR /app + +# 复制当前目录下的文件到工作目录 +COPY .. /app + +# 安装 Python 依赖 +RUN pip3 install -r requirements.txt + +# 暴露端口 +EXPOSE 80 + +# 设置容器启动时默认执行的命令 +CMD ["python3", "app.py"] +``` + +2. 运行构建命令,将 Dockerfile 构建为镜像: + +```bash +docker build -t my_custom_image:latest . +``` + +# 如何优化容器启动时间? + +1. 使用较小的基础镜像:选择精简的基础镜像,例如 `alpine`,或其他定制过的轻量级基础镜像,例如 `scratch`。 +2. 减少镜像层数:每一层都会增加容器启动的开销,精简 Dockerfile,合并多个 `RUN` 命令,将有助于减少层数。 +3. 利用缓存:在构建镜像时尽量利用 Docker 的缓存功能,避免每次都重建镜像。 +4. 适当配置健康检查:配置适当的健康检查策略,让容器可以尽快转为运行状态,而不是卡在启动过程中。 +5. 本地化镜像:将常用的容器镜像保存在本地镜像库中,避免每次启动时从远程仓库拉取。 + +# 如何实现容器之间的通信? + +1. **使用同一个网络:** 将多个容器连接到同一个 Docker 网络中,这样容器之间可以通过容器名称进行互相通信。 +2. **端口映射:** 将容器的端口映射到宿主机的端口,通过宿主机的 IP 和映射的端口进行通信。 +3. **Docker Compose:** 使用 Docker Compose 来编排多个服务,可以为每个服务定义网络,并对网络进行配置。 +4. **共享网络命名空间:** 通过创建共享网络命名空间的方式,使多个容器共享网络设置。 + +## 如何实现资源限制? + +1. 为了限制容器使用的 CPU 数量,可以使用 `--cpu-shares` 或 `--cpus` 参数。 + - `--cpu-shares`:使用相对权重方式分配 CPU 资源。 + - `--cpus`:直接指定容器可使用的 CPU 核数。 +2. 为了限制容器使用的内存量,可以使用 `-m` 或 `--memory` 参数。 + - `--memory`:指定容器最大内存限制。 + +举个简单的例子,如果我们希望某个容器最多使用一个CPU核心和 512MB 内存,可以使用以下命令: + +```shell +docker run --cpus=1 --memory=512m [container_name] +``` + +# 如何使用 Jenkins 与 Docker 集成? + +1. 安装必要的插件:在 Jenkins 中,安装 Docker plugin 和 Pipeline plugin 等必要插件。 +2. 配置 Jenkins:配置环境,确保 Jenkins 可以访问 Docker 命令。 +3. 创建 Jenkins Pipeline:在 Jenkins 中创建一个 Pipeline 项目,并在 Pipeline Script 中编写构建、测试和部署的脚本,通常使用 Jenkinsfile。 +4. 运行与监控:配置好所有步骤后,运行 Pipeline 并监控执行过程,确保一切正常工作。 + +#
----------------容器编排引擎----------------
+ +# Kubernetes 是什么? + +Kubernetes,它是 **Google **开源的神器,它介于**应用服务**和**服务器**之间,能够通过策略,协调和管理多个应用服务,只需要一个 **yaml** 文件配置,定义应用的部署顺序等信息,就能自动部署应用到各个服务器上,还能让它们挂了自动重启,自动扩缩容。 + +# Kubernetes 解决的问题 + +容器化技术与传统虚拟机的区别 + +随着**应用服务变多**,需求也千奇百怪。有的应用服务不希望被外网访问到,有的部署的时候要求内存得大于 xxGB 才能正常跑。 +你每次都需要登录到各个服务器上,执行**手动**操作更新。不仅容易出错,还贼**浪费时间**。那么问题就来了,有没有一个办法,可以解决上面的问题?当然有,**没有什么是加一个中间层不能解决的,如果有,那就再加一层**。这次要加的中间层,叫 **Kubernetes**。 + +Kubernetes的位置 + +# 为什么要用 Kubernetes ? + +在[Kubernetes](https://kubernetes.io/)出现之前,我们一般都是使用Docker来管理容器化的应用。 + +但是Docker只是一个单机的容器管理工具,它只能管理单个节点上的容器,当我们的应用程序需要运行在多个节点上的时候,就需要使用一些其他的工具来管理这些节点,比如Docker Swarm、Mesos、[Kubernetes](https://kubernetes.io/)等等。 + +这些工具都是容器编排引擎,它们可以用来管理多个节点上的容器,但是它们之间也有一些区别: + +- Docker Swarm是Docker官方提供的一个容器编排引擎,它的功能比较简单,适合于一些小型的、简单的场景 +- Mesos和[Kubernetes](https://kubernetes.io/)则是比较复杂的容器编排引擎,Mesos是Apache基金会的一个开源项目 +- [Kubernetes](https://kubernetes.io/)是Google在2014年开源的,目前已经成为了CNCF(Cloud Native Computing Foundation)的一个顶级项目,基本上已经成为了容器编排引擎的事实标准了。 + +# Kunbernetes 与 Docker之间的关系 + +Kubernetes 与 Docker 之间的关系可以概括为互补关系,两者在容器化技术的不同层面发挥作用。 + +## Docker + +Docker 是一个开源的容器化平台,它允许开发人员将应用程序及其依赖项打包到一个可移植的容器中,确保这些容器可以在任何支持 Docker 的环境中一致地运行。Docker 解决了开发、测试和生产环境之间的一致性问题,使得应用程序的开发、测试和部署过程更加一致和可靠。Docker 的主要组成部分包括: + +- **镜像**:包含了应用程序及其所需的所有依赖项的快照。 +- **容器**:基于镜像运行的实例,提供了一个隔离的环境来运行应用程序。 +- **仓库**:存储和分享镜像的地方,如 Docker Hub。 + +## Kubernetes + +Kubernetes 是一个开源的容器编排系统,它用于自动化部署、扩展和管理容器化应用程序。Kubernetes 提供了一系列强大的功能,比如服务发现、负载均衡、滚动更新、自动恢复等,使得开发人员可以更加轻松地构建、部署和管理大规模容器化应用程序。Kubernetes 的核心概念包括: + +- **Pod**:Kubernetes 中最小的部署单位,它可以包含一个或多个容器,这些容器共享存储、网络等资源。 +- **Service**:一种抽象,定义了一组逻辑上的 Pod 和访问策略。 +- **Deployment**:用于管理应用程序的副本,确保指定数量的 Pod 始终处于运行状态。 +- **StatefulSet**:用于管理有状态的应用程序,保证每个 Pod 的唯一身份。 + +## 关系 + +1. **互补性**:Docker 和 Kubernetes 各自解决了容器化技术的不同方面。Docker 专注于单个容器的生命周期管理,而 Kubernetes 则关注多个容器的组织、管理和调度。 +2. **集成**:虽然 Kubernetes 可以使用多种容器运行时(如 containerd、CRI-O 等),但 Docker 是最常用的容器运行时之一。Kubernetes 可以直接使用 Docker 镜像,并通过其 Pod 概念管理 Docker 容器。 +3. **生态系统**:两者都拥有庞大的生态系统和社区支持,共同推动了容器技术的发展。 + +## 实际应用 + +在实际应用中,开发人员通常会使用 Docker 来构建和打包应用程序,然后使用 Kubernetes 来部署和管理这些容器化应用程序。这种结合使用的方式可以充分利用 Docker 和 Kubernetes 的各自优势,提高应用程序的开发、测试和部署效率。 + +总之,Kubernetes 和 Docker 之间是互补而非竞争的关系。它们共同构成了现代云原生应用开发和部署的重要基石。 + + + +# Kubernetes 架构原理 + +为了实现上面的功能,Kubernetes 会将我们的服务器划为两部分,一部分叫**控制平面**(control plane,以前叫master),另一部分叫**工作节点**,也就是 **Node**。简单来说它们的关系就是老板和打工人, 用现在流行的说法就是训练师和帕鲁。控制平面负责控制和管理各个 Node,而 Node 则负责实际运行各个应用服务。 + +k8s控制平面和Node的关系 + +我们依次看下这两者的内部架构。 + +## 控制平面内部组件 + +- 以前我们需要登录到每台服务器上,手动执行各种命令,现在我们只需要调用 k8s 的提供的 api 接口,就能操作这些服务资源,这些接口都由 **API Server** 组件提供。 +- 以前我们需要到处看下哪台服务器 cpu 和内存资源充足,然后才能部署应用,现在这部分决策逻辑由 **Scheduler**(调度器)来完成。 +- 找到服务器后,以前我们会手动创建,关闭服务,现在这部分功能由 **Controller Manager**(控制器管理器)来负责。 +- 上面的功能都会产生一些数据,这些数据需要被保存起来,方便后续做逻辑,因此 k8s 还会需要一个**存储层**,用来存放各种数据信息,目前是用的 **etcd**,这部分源码实现的很解耦,后续可能会扩展支持其他中间件。 + +以上就是控制平面内部的组件。 + +k8s控制平面组件 + +我们接下来再看看 Node 里有哪些组件。 + +## Node 内部组件 + +Node 是实际的工作节点,它既可以是**裸机服务器**,也可以是**虚拟机**。它会负责实际运行各个应用服务。多个应用服务**共享**一台 Node 上的内存和 CPU 等计算资源。 + +Node可以是裸机服务器或虚拟机 + +在文章开头,我们聊到了部署多个应用服务的场景。以前我们需要上传代码到服务器,而用了 k8s 之后,我们只需要将服务代码打包成**Container Image**(容器镜像),就能一行命令将它部署。 + +如果你不了解容器镜像的含义,你可以简单理解为它其实就是将**应用代码**和依赖的**系统环境**打了个压缩包,在任意一台机器上解压这个压缩包,就能正常运行服务。为了下载和部署镜像,Node 中会有一个 **Container runtime** 组件。 + +将容器镜像粗略理解为压缩包 + +每个应用服务都可以认为是一个 **Container**(容器), 并且大多数时候,我们还会为应用服务搭配一个日志收集器 Container 或监控收集器 Container,多个 Container 共同组成一个一个 **Pod**,它运行在 Node 上。 + +一个pod内有多个容器 + +k8s 可以将 pod 从某个 Node 调度到另一个 Node,还能以 pod 为单位去做重启和动态扩缩容的操作。 +所以说 **Pod 是 k8s 中最小的调度单位**。 + +Node调度Pod + +另外,前面提到控制平面会用 **Controller Manager** (通过API Server)控制 Node 创建和关闭服务,那 Node 也得有个组件能接收到这个命令才能去做这些动作,这个组件叫 **kubelet**,它主要负责管理和监控 Pod。最后,Node 中还有个 **Kube Proxy** ,它负责 Node 的网络通信功能,有了它,外部请求就能被转发到 Pod 内。 + +控制平面和Node的组件 + +# Cluster + +**控制平面和Node** 共同构成了一个 **Cluster**,也就是**集群**。在公司里,我们一般会构建多个集群, 比如测试环境用一个集群,生产环境用另外一个集群。同时,为了将集群内部的服务暴露给外部用户使用,我们一般还会部署一个入口控制器,比如 **Ingress 控制器(比如Nginx)**,它可以提供一个入口让外部用户访问集群内部服务。 + +生产和测试环境 + +# kubectl + +上面提到说我们可以使用 k8s 提供的 API 去创建服务,但问题就来了,这是需要我们自己写代码去调用这些 API 吗?答案是不需要,k8s 为我们准备了一个命令行工具 **kubectl**,我们只需要执行命令,它内部就会调用 k8s 的 API。 + +kubectl调用k8s的API + +接下来我们以部署服务为例子,看下 k8s 是怎么工作的。 + +# 部署 Kubernetes 服务 + +首先我们需要编写 **YAML 文件**,在里面定义 Pod 里用到了哪些镜像,占用多少内存和 CPU 等信息。然后使用 kubectl 命令行工具执行 `kubectl apply -f xx.yaml` ,此时 kubectl 会读取和解析 YAML 文件,将解析后的对象通过 API 请求发送给 Kubernetes 控制平面内 的 **API Server**。API Server 会根据要求,驱使 **Scheduler** 通过 **etcd** 提供的数据寻找合适的 **Node**, **Controller Manager** 会通过 API Server 控制 Node 创建服务,Node 内部的 **kubelet** 在收到命令后会开始基于 **Container runtime** 组件去拉取镜像创建容器,最终完成 **Pod** 的创建。 + +至此服务完成创建。 + +部署应用服务 + +整个过程下来,我们只需要写一遍 yaml 文件,和执行一次 kubectl 命令,比以前省心太多了!部署完服务后,我们来看下服务是怎么被调用的。 + +# 调用 Kubernetes 服务 + +以前外部用户小明,直接在浏览器上发送 http 请求,就能打到我们服务器上的 Nginx,然后转发到部署的服务内。用了 k8s 之后,外部请求会先到达 Kubernetes 集群的 Ingress 控制器,然后请求会被转发到 Kubernetes 内部的某个 Node 的 **Kube Proxy** 上,再找到对应的 pod,然后才是转发到内部**容器服务**中,处理结果原路返回,到这就完成了一次服务调用。 + +用户调用k8s内应用服务的流程 + +到这里我们就大概了解了 k8s 的工作原理啦,它本质上就是应用服务和服务器之间的**中间层**,通过暴露一系列 API 能力让我们简化服务的部署运维流程。 + +并且,不少中大厂基于这些 API 能力搭了自己的服务管理平台,程序员不再需要敲 kubectl 命令,直接在界面上点点几下,就能完成服务的部署和扩容等操作,是真的嘎嘎好用。 diff --git "a/docs/\345\274\200\345\217\221/\346\220\255\345\273\272K8S\351\233\206\347\276\244\347\216\257\345\242\203.md" "b/docs/\345\274\200\345\217\221/\346\220\255\345\273\272K8S\351\233\206\347\276\244\347\216\257\345\242\203.md" new file mode 100644 index 0000000..19f4375 --- /dev/null +++ "b/docs/\345\274\200\345\217\221/\346\220\255\345\273\272K8S\351\233\206\347\276\244\347\216\257\345\242\203.md" @@ -0,0 +1,389 @@ +--- +搭建K8S集群环境 +--- + +## 使用[minikube](https://minikube.sigs.k8s.io/)搭建kubernetes集群环境 + +[minikube](https://minikube.sigs.k8s.io/)是一个轻量级的kubernetes集群环境,可以用来在本地快速搭建一个单节点的kubernetes集群, + +### 安装minikube + +也可以到官网直接下载安装包来安装:https://minikube.sigs.k8s.io/docs/start/ + +```shell +# macOS +brew install minikube + +# Windows +choco install minikube + +# Linux +curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 +sudo install minikube-linux-amd64 /usr/local/bin/minikube +``` + +### 启动minikube + +```shell +# 启动minikube +minikube start +``` + +## 使用[Multipass](https://multipass.run/)和[k3s](https://k3s.io/)搭建kubernetes集群环境 + +[minikube](https://minikube.sigs.k8s.io/)只能用来在本地搭建一个单节点的kubernetes集群环境,下面介绍如何使用[Multipass](https://multipass.run/)和[k3s](https://k3s.io/)来搭建一个多节点的kubernetes集群环境。 + +### Multipass介绍 + +[Multipass](https://multipass.run/)是一个轻量级的虚拟机管理工具,可以用来在本地快速创建和管理虚拟机,相比于VirtualBox或者VMware这样的虚拟机管理工具,[Multipass](https://multipass.run/)更加轻量快速,而且它还提供了一些命令行工具来方便我们管理虚拟机。 + +> 官方网址: [https://Multipass.run/](https://multipass.run/) + +### 安装Multipass + +```shell +# macOS +brew install multipass + +# Windows +choco install multipass + +# Linux +sudo snap install multipass +``` + +### Multipass常用命令 + +关于Multipass的一些常用命令我们可以通过`multipass help`来查看,这里只需要记住几个常用的命令就可以了 + +```shell +# 查看帮助 +multipass help +multipass help + +# 创建一个名字叫做k3s的虚拟机 +multipass launch --name k3s + +# 在虚拟机中执行命令 +multipass exec k3s -- ls -l + +# 进入虚拟机并执行shell +multipass shell k3s + +# 查看虚拟机的信息 +multipass info k3s + +# 停止虚拟机 +multipass stop k3s + +# 启动虚拟机 +multipass start k3s + +# 删除虚拟机 +multipass delete k3s + +# 清理虚拟机 +multipass purge + +# 查看虚拟机列表 +multipass list + +# 挂载目录(将本地的~/kubernetes/master目录挂载到虚拟机中的~/master目录) +multipass mount ~/kubernetes/master master:~/master +``` + +Multipass有个问题,每次Mac升级之后Multipass的虚拟机都可能会被删除。 + +```shell +# 镜像位置 +/var/root/Library/Application Support/multipassd/qemu/vault/instances +# 配置文件 +/var/root/Library/Application Support/multipassd/qemu/multipassd-vm-instances.json +``` + +## [k3s](https://k3s.io/)介绍 + +[k3s](https://k3s.io/) 是一个轻量级的[Kubernetes](https://kubernetes.io/)发行版,它是 [Rancher Labs](https://www.rancher.com/) 推出的一个开源项目,旨在简化[Kubernetes](https://kubernetes.io/)的安装和维护,同时它还是CNCF认证的[Kubernetes](https://kubernetes.io/)发行版。 + +### 创建和配置master节点 + +首先我们需要使用multipass创建一个名字叫做k3s的虚拟机, + +```shell +multipass launch --name k3s --cpus 2 --memory 8G --disk 10G +``` + +虚拟机创建完成之后,可以配置SSH密钥登录,不过这一步并不是必须的,即使不配置也可以通过`multipass exec`或者`multipass shell`命令来进入虚拟机,然后我们需要在master节点上安装[k3s](https://k3s.io/)。 + +使用[k3s](https://k3s.io/)搭建kubernetes集群非常简单,只需要执行一条命令就可以在当前节点上安装[k3s](https://k3s.io/),打开刚刚创建的k3s虚拟机,执行下面的命令就可以安装一个[k3s](https://k3s.io/)的master节点。 + +```shell +# 安装k3s的master节点 +curl -sfL https://get.k3s.io | sh - + +# 国内可以使用ranher的镜像源来安装: +curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn sh - +``` + +安装完成之后,可以通过`kubectl`命令来查看集群的状态。 + +```shell +sudo kubectl get nodes +``` + +### 创建和配置worker节点 + +接下来需要在这个master节点上获取一个token,用来作为创建worker节点时的一个认证凭证,它保存在`/var/lib/rancher/k3s/server/node-token`这个文件里面,我们可以使用`sudo cat`命令来查看一下这个文件中的内容。 + +```shell +sudo cat /var/lib/rancher/k3s/server/node-token +``` + +将TOKEN保存到一个环境变量中 + +```shell +TOKEN=$(multipass exec k3s sudo cat /var/lib/rancher/k3s/server/node-token) +``` + +保存master节点的IP地址 + +```shell +MASTER_IP=$(multipass info k3s | grep IPv4 | awk '{print $2}') +``` + +确认: + +```shell +echo $MASTER_IP +``` + +使用刚刚的`TOKEN`和`MASTER_IP`来创建两个worker节点,并把它们加入到集群中 + +```shell +# 创建两个worker节点的虚拟机 +multipass launch --name worker1 --cpus 2 --memory 8G --disk 10G +multipass launch --name worker2 --cpus 2 --memory 8G --disk 10G + +# 在worker节点虚拟机上安装k3s + for f in 1 2; do + multipass exec worker$f -- bash -c "curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn K3S_URL=\"https://$MASTER_IP:6443\" K3S_TOKEN=\"$TOKEN\" sh -" + done +``` + +这样就完成了一个多节点的kubernetes集群的搭建。 + +## 在线实验环境 + +> [Killercoda](https://killercoda.com/) + +> [Play-With-K8s](https://labs.play-with-k8s.com/) + +## kubectl常用命令 + +### 基础使用 + +```shell +# 查看帮助 +kubectl --help + +# 查看API版本 +kubectl api-versions + +# 查看集群信息 +kubectl cluster-info +``` + +### 资源的创建和运行 + +```shell +# 创建并运行一个指定的镜像 +kubectl run NAME --image=image [params...] +# e.g. 创建并运行一个名字为nginx的Pod +kubectl run nginx --image=nginx + +# 根据YAML配置文件或者标准输入创建资源 +kubectl create RESOURCE +# e.g. +# 根据nginx.yaml配置文件创建资源 +kubectl create -f nginx.yaml +# 根据URL创建资源 +kubectl create -f https://k8s.io/examples/application/deployment.yaml +# 根据目录下的所有配置文件创建资源 +kubectl create -f ./dir + +# 通过文件名或标准输入配置资源 +kubectl apply -f (-k DIRECTORY | -f FILENAME | stdin) +# e.g. +# 根据nginx.yaml配置文件创建资源 +kubectl apply -f nginx.yaml +``` + +### 查看资源信息 + +```shell +# 查看集群中某一类型的资源 +kubectl get RESOURCE +# 其中,RESOURCE可以是以下类型: +kubectl get pods / po # 查看Pod +kubectl get svc # 查看Service +kubectl get deploy # 查看Deployment +kubectl get rs # 查看ReplicaSet +kubectl get cm # 查看ConfigMap +kubectl get secret # 查看Secret +kubectl get ing # 查看Ingress +kubectl get pv # 查看PersistentVolume +kubectl get pvc # 查看PersistentVolumeClaim +kubectl get ns # 查看Namespace +kubectl get node # 查看Node +kubectl get all # 查看所有资源 + +# 后面还可以加上 -o wide 参数来查看更多信息 +kubectl get pods -o wide + +# 查看某一类型资源的详细信息 +kubectl describe RESOURCE NAME +# e.g. 查看名字为nginx的Pod的详细信息 +kubectl describe pod nginx +``` + +### 资源的修改、删除和清理 + +```shell +# 更新某个资源的标签 +kubectl label RESOURCE NAME KEY_1=VALUE_1 ... KEY_N=VALUE_N +# e.g. 更新名字为nginx的Pod的标签 +kubectl label pod nginx app=nginx + +# 删除某个资源 +kubectl delete RESOURCE NAME +# e.g. 删除名字为nginx的Pod +kubectl delete pod nginx + +# 删除某个资源的所有实例 +kubectl delete RESOURCE --all +# e.g. 删除所有Pod +kubectl delete pod --all + +# 根据YAML配置文件删除资源 +kubectl delete -f FILENAME +# e.g. 根据nginx.yaml配置文件删除资源 +kubectl delete -f nginx.yaml + +# 设置某个资源的副本数 +kubectl scale --replicas=COUNT RESOURCE NAME +# e.g. 设置名字为nginx的Deployment的副本数为3 +kubectl scale --replicas=3 deployment/nginx + +# 根据配置文件或者标准输入替换某个资源 +kubectl replace -f FILENAME +# e.g. 根据nginx.yaml配置文件替换名字为nginx的Deployment +kubectl replace -f nginx.yaml +``` + +### 调试和交互 + +```shell +# 进入某个Pod的容器中 +kubectl exec [-it] POD [-c CONTAINER] -- COMMAND [args...] +# e.g. 进入名字为nginx的Pod的容器中,并执行/bin/bash命令 +kubectl exec -it nginx -- /bin/bash + +# 查看某个Pod的日志 +kubectl logs [-f] [-p] [-c CONTAINER] POD [-n NAMESPACE] +# e.g. 查看名字为nginx的Pod的日志 +kubectl logs nginx + +# 将某个Pod的端口转发到本地 +kubectl port-forward POD [LOCAL_PORT:]REMOTE_PORT [...[LOCAL_PORT_N:]REMOTE_PORT_N] +# e.g. 将名字为nginx的Pod的80端口转发到本地的8080端口 +kubectl port-forward nginx 8080:80 + +# 连接到现有的某个Pod(将某个Pod的标准输入输出转发到本地) +kubectl attach POD -c CONTAINER +# e.g. 将名字为nginx的Pod的标准输入输出转发到本地 +kubectl attach nginx + +# 运行某个Pod的命令 +kubectl run NAME --image=image -- COMMAND [args...] +# e.g. 运行名字为nginx的Pod +kubectl run nginx --image=nginx -- /bin/bash +``` + +## Portainer的安装和使用 + +[Portainer](https://www.portainer.io/) 是一个轻量级的容器管理工具,可以用来管理Docker和Kubernetes,它提供了一个Web界面来方便我们管理容器。 + +> 官方网址: https://www.portainer.io/ + +### 安装Portainer + +```shell +# 创建一个名字叫做portainer的虚拟机 +multipass launch --name portainer --cpus 2 --memory 8G --disk 10G +``` + +当然也可以直接安装在我们刚刚创建的master节点上, + +```shell +# 在master节点上安装portainer,并将其暴露在NodePort 30777上 +kubectl apply -n portainer -f https://downloads.portainer.io/ce2-19/portainer.yaml +``` + +或者使用Helm安装 + +```shell +# 使用Helm安装Portainer +helm upgrade --install --create-namespace -n portainer portainer portainer/portainer --set tls.force=true +``` + +然后直接访问 `https://localhost:30779/` 或者 `http://localhost:30777/` 就可以了, + +## Helm的安装和使用 + +[Helm](https://helm.sh/) 是一个Kubernetes的包管理工具,可以用来管理Kubernetes的应用,它提供了一个命令行工具来方便我们管理Kubernetes的应用。 + +> 官方网址: https://helm.sh/ + +### 安装Helm + +使用包管理器安装: + +```shell +# macOS +brew install helm + +# Windows +choco install kubernetes-helm +# 或者 +scoop install helm + +# Linux(Debian/Ubuntu) +curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null +sudo apt-get install apt-transport-https --yes +echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list +sudo apt-get update +sudo apt-get install helm + +# Linux(CentOS/Fedora) +sudo dnf install helm + +# Linux(Snap) +sudo snap install helm --classic + +# Linux(FreeBSD) +pkg install helm +``` + +使用脚本安装 + +```shell +curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 +chmod 700 get_helm.sh +./get_helm.sh +``` + +或者 + +```shell +curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash +``` \ No newline at end of file