GitOps 实践理论:Kubernetes 部署策略深入解析

今天我们来看看 kubernetes 和 gitops 的理论实践 命令介绍 首先我们来看看 kubectl 支持的子命名,方便我们使用: kubectl apply - 应用一个或多个资源的定义。通常用于部署应用程序或更新资源。 kubectl get - 显示一个或多个资源的信息。这是查看 Kubernetes 集群中资源状态的常用命令。 kubectl describe - 显示一个或多个资源的详细信息,如事件、状态和配置。 kubectl delete - 删除 Kubernetes 集群中的资源。 kubectl exec - 在集群中的容器里执行命令。 kubectl logs - 打印容器的日志。 kubectl create - 从文件或标准输入中创建一个或多个资源。 kubectl edit - 编辑集群中的资源。这将打开一个编辑器来修改资源的配置。 kubectl port-forward - 将本地端口转发到集群中的 Pod。 kubectl run - 在集群中运行一个指定的镜像。 kubectl scale - 调整资源(如 Deployment、ReplicaSet)的副本数量。 kubectl rollout - 管理资源的部署,如查看状态、暂停、恢复或回滚更新。 除了上面的命令,Kubernetes 中的 kubectl 还支持注解: kubectl annotate 命令用于给 Kubernetes 集群中的资源添加或更新注解(annotations)。注解是一种附加信息,可以用于存储非识别性的元数据。它们通常用于管理工具、库和客户端以存储辅助信息,例如描述、版本信息等。...

November 25, 2023 · 10 分钟 · 2034 字 · 熊鑫伟,我

管理后台和监控的部署与设计

OpenIM 提供了多种灵活的部署选项,适用于不同的环境和需求。以下是这些部署方案的简化和优化描述: 源码部署: 普通源码部署:使用 nohup 方式进行部署。这是一种基础的部署方法,适合于开发和测试环境。详情参见:普通源码部署指南。 生产级部署:采用 system 方式,更适合于生产环境。这种方法提供了更高的稳定性和可靠性。详情参见:生产级部署指南。 集群部署: Kubernetes 部署:提供两种方式,包括通过 helm 和 sealos 进行部署。这适用于需要高可用性和可扩展性的环境。具体方法请参考:Kubernetes 部署指南。 Docker 部署: 普通 Docker 方式:适用于快速部署和小型项目。详细信息请见:Docker 部署指南。 Docker Compose 方式:提供了更便捷的服务管理和配置,适合于复杂的多容器应用。 接下来,我们将逐一介绍这些部署方法的具体步骤、监控和管理后台的配置,以及使用技巧,帮助您根据自己的需求选择最合适的部署方案。 源码 & Docker 部署 源码部署 openim-server 和 openim-chat ,其他的组件都是通过 Docker 部署。 docker 部署则通过 https://github.com/openimsdk/openim-docker 仓库一键部署所有的组件。 部署的配置文件,可以阅读 https://github.com/openimsdk/open-im-server/blob/main/scripts/install/environment.sh 文档了解如何学习以及熟悉各个环境变量。 对于 Prometheus 来说,默认是没有开启 Prometheus 的,如果需要开启的话,需要在 make init 之前设置环境变量: export PROMETHEUS_ENABLE=true # 默认是 false 然后执行:...

November 15, 2023 · 3 分钟 · 453 字 · 熊新伟,我

Hugo 的高级教程

来到进阶部分,就需要深度学习一些 Hugo 的高级技巧。 模块 Hugo 模块是 Hugo 的核心构建块。模块可以是您的主项目或较小的模块,提供 Hugo 中定义的 7种组件类型中的一种或多种:static、content、layouts、data、assets、i18n和archetypes。 您可以按照您喜欢的任何组合来组合模块,甚至可以挂载非 Hugo 项目的目录,形成一个大型的虚拟联合文件系统。 Hugo 模块由 Go 模块提供支持。有关 Go 模块的更多信息,请参阅: https://github.com/golang/go/wiki/Modules https://go.dev/blog/using-go-modules 一些示例项目: https://github.com/bep/docuapi是一个在测试此功能时已移植到 Hugo Modules 的主题。这是将非 Hugo 项目安装到 Hugo 文件夹结构中的一个很好的示例。它甚至展示了常规 Go 模板中的 JS Bundler 实现。 https://github.com/bep/my-modular-site是一个非常简单的用于测试的网站。 模块配置: top level 💡简单的一个案例如下: module:noProxy:nonenoVendor:""private:'*.*'proxy:directreplacements:""workspace:"off"noVendor 一个可选的Glob模式匹配模块路径,当自动售货时跳过,例如 github.com/** vendorClosest 启用后,我们将选择与使用它的模块最近的供应商模块。默认行为是选择第一个。请注意,给定的模块路径仍然只能有一个依赖项,因此一旦使用它,就不能重新定义它。 proxy 定义用于下载远程模块的代理服务器。默认值是 direct ,意思是“git clone”或类似的。 noproxy 逗号分隔的glob列表匹配不应使用上面配置的代理的路径。 private 逗号分隔的glob列表匹配应被视为私有的路径。 workspaces 要使用的工作区文件。这将启用Go工作区模式。请注意,这也可以通过OS env设置,例如 export HUGO_MODULE_WORKSPACE=/my/hugo.work 这只适用于Go 1.18+。在Hugo v0.109.0 中,我们将默认值更改为 off ,现在我们可以解析相对于工作目录的任何相对工作文件名。...

November 6, 2023 · 15 分钟 · 3095 字 · 熊鑫伟,我

Kubernetes Kustomize 学习指南

介绍 关于 kustomize github 地址 Get Started Kustomize 是一个专为 Kubernetes 设计的开源配置管理工具,它能帮助用户定制 Kubernetes 对象,并以声明式的方式管理这些对象,而无需修改原始的 YAML 文件1。这意味着你可以保留应用和组件的基本设置,同时通过应用名为“补丁”的声明式 YAML 文档来覆盖默认设置,而不会更改原始文件。Kustomize 提供了一种声明式的方法,符合 Kubernetes 的哲学,并且能够以一种可重用、快速生成、易于调试和可伸缩的方式定制 Kubernetes 配置。 Kustomize 的主要功能包括: 声明式配置: 允许你以声明式的方式定义和管理 Kubernetes 对象,例如部署、Daemonsets、服务、ConfigMaps 等,为多个环境提供支持,而无需修改原始的 YAML 文件 配置层叠: 通过利用层叠来保留应用和组件的基本设置,并通过覆盖声明式的 YAML 文档(称为补丁)来选择性地覆盖默认设置 集成与独立使用: Kustomize 可以作为一个独立的工具使用,或者与 kubectl 结合使用。从 Kubernetes 1.14 版本开始,kubectl 也开始支持使用 kustomization 文件来管理 Kubernetes 对象 Kustomize 提供了一种自定义 Kubernetes 资源配置的解决方案,该方案摆脱了模板和 DSL。 版本关系 & kubectl 集成 要查找kubectl最新版本中嵌入的kustomize版本,请运行 kubectl version : $ kubectl version --short --client Client Version: v1....

October 31, 2023 · 5 分钟 · 1004 字 · 熊鑫伟,我

设计 OpenIM 使用 Harbor 构建企业镜像仓库

需求 OpenIM 提供了多种公共的镜像注册地址,比如说 aliyun, github, Docker hub ~ 阅读 https://github.com/openimsdk/open-im-server/blob/main/docs/conversions/images.md 获取更多的镜像构建指南。 大部分企业都会选择自己做镜像仓库,使用 Harbor 来搭建企业级的镜像仓库,将它集成 CICD Pipeline 流程中,最终替换 Docker Hub,进一步降低镜像存储的成本。 此外,在生产环境下,Harbor 一般都会开启 TLS,所以你还需要准备一个可用的域名。 中国的服务器使用域名,需要对域名进行备案 安装 Helm Helm,以及 集群的部署参考 https://github.com/openimsdk/open-im-server/tree/main/deployments 安装 Cert-manager 接下来我们安装 Cert-manager,它会为我们自动签发免费的 Let’s Encrypt HTTPS 证书,并在过期前自动续期。 首先,运行 helm repo add 命令添加官方 Helm 仓库。 $ helm repo add jetstack https://charts.jetstack.io 然后,运行 helm repo update 更新本地缓存。 $ helm repo update 接下来,运行 helm install 来安装 Cert-manager。 $ helm install cert-manager jetstack/cert-manager \ --namespace cert-manager \ --create-namespace \ --version v1....

October 25, 2023 · 2 分钟 · 350 字 · 熊鑫伟,我

自动化测试的学习(一)

云原生领域中GitHub开源Go项目的自动化测试实践与策略 介绍 作为 Github 上的 热门项目 OpenIM,如何在云原生时代中创造出价值,这是非常重要的,OpenIM 是一个优质的小团队,我们在自动化中并没有特别深入的见解。 使用 GitHub Actions 进行持续集成和持续交付 (CI/CD): GitHub Actions 提供了一个平台,可以自动构建和测试 Go 语言项目。通过配置 GitHub Actions 工作流,你可以在代码更改时自动运行测试,确保代码的质量和功能。 KubeVela 项目实践: KubeVela 是一个 Go 语言的云原生和开源项目,它展示了如何在云原生环境中组织 CI/CD 过程,包括自动化测试。KubeVela 使用声明性工作流来协调 CI/CD 过程,你可以参考 KubeVela 的 GitHub 仓库来理解和应用这些实践34[5](https://github.com/kubevela/workflow#:~:text=KubeVela Workflow is an open,engine in your own repository)。 云原生测试框架与工具: 在云原生开发中,合约测试(Contract Testing)是一种常见的测试实践,它确保服务间的通信符合预定义的 API 协议。例如,Cloud-Native Toolkit 中使用 Pact 进行合约测试。通过编写和集成测试,你可以验证服务间的通信是否符合预期6。 代码覆盖率检查: 在进行自动化测试时,检查代码覆盖率是一个好的实践。许多测试框架内置了代码覆盖率检查功能,可以配置它们来报告测试的代码覆盖率。例如,使用 SonarQube 工具来读取和报告代码覆盖率信息6。 利用开源工具和框架: 你可以利用开源工具和框架来进行测试,例如使用 Cypress 进行云原生应用的测试[7](https://dev....

October 14, 2023 · 17 分钟 · 3593 字 · 熊鑫伟,我

Kubernetes 控制平面 - Kubectl 详细讲解

Kubelet组件解析 理解 kubelet Kubelet组件运行在Node节点上,维持运行中的Pods以及提供kuberntes运行时环境,主要完成以下使命: 1.监视分配给该Node节点的pods 2.挂载pod所需要的volumes 3.下载pod的secret 4.通过docker/rkt来运行pod中的容器 5.周期的执行pod中为容器定义的liveness探针 6.上报pod的状态给系统的其他组件 7.上报Node的状态 kubelet 管理Pod的核心流程主要包括三个步骤。首先,kubelet获取Pod清单,可以通过文件、HTTP endpoint、API Server和HTTP server等方式获取。其次,节点管理主要是节点自注册和节点状态更新,Kubelet在启动时通过API Server注册节点信息,并定时向API Server发送节点新消息,API Server在接收到新消息后,将信息写入etcd。最后,Pod启动流程主要包括镜像拉取、容器启动、探针监控以及状态汇报等步骤。 kubelet是Kubernetes中的一个节点代理程序,负责维护本节点上Pod的生命周期。kubelet是Kubernetes中非常重要的组件之一,它在Kubernetes集群中扮演着非常重要的角色。kubelet可以在每个节点上运行,它监视分配给该Node节点的pods,并执行各种管理容器的操作,如挂载pod所需要的volumes、下载pod的secret等。 kubelet的核心流程主要包括获取Pod清单、节点管理和Pod启动流程。其中,获取Pod清单的方式包括文件、HTTP endpoint、API Server和HTTP server等方式。节点管理主要包括节点自注册和节点状态更新,而Pod启动流程主要包括镜像拉取、容器启动、探针监控以及状态汇报等步骤。 在节点管理方面,kubelet可以通过设置启动参数-register-node来确定是否向API Server注册自己。如果kubelet没有选择自注册模式,则需要用户自己配置Node资源信息,同时需要告知kubelet集群上的API Server的位置。在启动时,kubelet会通过API Server注册节点信息,并定时向API Server发送节点新消息,API Server在接收到新消息后,将信息写入etcd。 在Pod管理方面,kubelet可以通过文件、HTTP endpoint、API Server和HTTP server等方式获取Pod清单。文件方式主要用于static pod,而HTTP和API Server方式则是Kubernetes中常用的方式。HTTP server主要用于kubelet侦听HTTP请求,并响应简单的API以提交新的Pod清单。 在Pod启动流程方面,kubelet会执行各种管理容器的操作,包括镜像拉取、容器启动、探针监控以及状态汇报等步骤。镜像拉取是Pod启动过程中的一项重要工作,kubelet可以通过imageManager模块来管理镜像。容器启动是Pod启动过程的下一步,kubelet通过container runtime来启动容器。探针监控是Pod启动过程中一项非常重要的工作,kubelet会周期性地执行pod中为容器定义的liveness探针,并将结果上报给系统的其他组件。状态汇报是kubelet的一个重要功能,它会上报pod和Node的状态给系统的其他组件,以及上报节点自身的状态和资源使用情况给API Server。 总之,kubelet是Kubernetes中非常重要的组件之一,它负责维护本节点上Pod的生命周期,并执行各种管理容器的操作。kubelet的核心流程包括获取Pod清单、节点管理和Pod启动流程。在节点管理方面,kubelet通过设置启动参数-register-node来确定是否向API Server注册自己。在Pod管理方面,kubelet可以通过文件、HTTP endpoint、API Server和HTTP server等方式获取Pod清单。在Pod启动流程方面,kubelet会执行各种管理容器的操作,包括镜像拉取、容器启动、探针监控以及状态汇报等步骤。 kubelet 架构 每个节点上都运行一一个 kubelet 服务进程,默认监听 10250 端口。 接收并执行 master 发来的指令; 管理 Pod 及 Pod 中的容器; 每个 kubelet 进程会在 API Server上注册节点自身信息,定期向 master 节点汇报节点的资源使用情况,并通过 cAdvisor 监控节点和容器的资源。 kubelet 架构如下图所示:...

September 28, 2023 · 2 分钟 · 421 字 · Xinwei Xiong, Me

Kubernetes 控制平面 - 调度器

调度器 kube-scheduler 负责分配调度 Pod 到集群内的节点上,它监听 kube-apiserver,查询还未分配 Node 的 Pod,然后根据调度策略为这些 Pod 分配节点(更新 Pod 的 NodeName 字段)。 调度器需要充分考虑诸多的因素: 公平调度; 资源高效利用; QoS; affinity 和 anti-affinity; 数据本地化(data locality) ; 内部负载干扰(inter-workload interference) ; deadlines。 kube-scheduler 调度分为两个阶段, predicate 和 priority: predicate: 过滤不符合条件的节点; priority:优先级排序,选择优先级最高的节点。. predicate 策略 PodFitsHostPorts:检查是否有 Host Ports 冲突。 PodFitsPorts:同P odFitsHostPorts。 PodFitsResources:检查 Node 的资源是否充足,包括允许的Pod数量、CPU、内存、GPU个数以及其他的OpaqueIntResources。 HostName:检查 pod.Spec.NodeName 是否与候选节点一致。 MatchNodeSelector:检查候选节点的 pod.Spec.NodeSelector 是否匹配 NoVolumeZoneConflict:检查 volume zone 是否冲突。 MatchInterPodAffinity:检查是否匹配 Pod 的亲和性要求。 NoDiskConflict:检查是否存在 Volume 冲突,仅限于 GCE PD、AWS EBS、Ceph RBD以及 iSCSI。 PodToleratesNodeTaints:检查 Pod 是否容忍 Node Taints。 CheckNodeMemoryPressure:检查 Pod 是否可以调度到 MemoryPressure 的节点上。 CheckNodeDiskPressure:检查 Pod 是否可以调度到 DiskPressure 的节点上。 NoVolumeNodeConflict:检查节点是否满足 Pod 所引用的 Volume 的条件。 priority 策略 SelectorSpreadPriority:优先减少节点上属于同一个 Service 或 Replication Controller 的 Pod 数量。 尽量将同一个 rc 下的多个副本分散到不同节点,增加可用性 InterPodAffinityPriority:优先将Pod调度到相同的拓扑上(如同一个节点、Rack、Zone等)。 LeastRequestedPriority:优先调度到请求资源少的节点上。 BalancedResourceAllocation:优先平衡各节点的资源使用。 NodePreferAvoidPodsPriority:alpha....

September 28, 2023 · 4 分钟 · 668 字 · 熊鑫伟,我

Kubernetes 的 CNI,CRI,CSI 详解

容器运行时 容器运行时(Container Runtime),运行于Kubernetes (k8s)集群的每个节点中,负责容器的整 个生命周期。其中Docker是目前应用最广的。随着容器云的发展,越来越多的容器运行时涌现。为了 解决这些容器运行时和Kubernetes的集成问题,在Kubernetes 1.5版本中,社区推出了CRI ( Container Runtime Interface,容器运行时接口)以支持更多的容器运行时。 什么是 CRI CRI 是 Kubernetes 定义的一组 gRPC 服务。 kubelet 作为客户端,基于 gRPC 框架,通过 Socket 和容器运行时通信。它包括两类服务: 镜像服务(Image Service):提供下载、检查和删除镜像的远程程序调用; 运行时服务(Runtime Service):包含用于管理容器生命周期,以及与容器交互的调用(exec/ attach / port-forward)的远程程序调用。 运行时的层级 容器运行时可以分为高层和低层的运行时: Dockershime,containerd 和 CRI-O 都是遵循 CRI 的容器运行时,我们称之为 高级运行时。 OCI 定义了创建容器的格式和运行时的开源行业标准,包括 镜像规范(Image Specification) 和 容器运行时规范 (runtime specification) 镜像规范定义了 OCI 镜像标准,高层级运行时 将会下载一个 OCI 镜像,并且将它解压为 OCI 运行时文件系统包(file system bundle) 运行时规范描述了如何从 OCI 运行时文件系统包运行容器程序。并且定义它的配置,运行环境和生命周期。如何为新的容器设置命名空间(namespace)和控制组(cgroup) ,以及挂载根文件系统(rootfs)等等操作,都是在这里定义的。它的一个参考实现是 runc,我们称其为 低层级运行时(Low-level Runtime) 高层级运行时(High-level Runtime):主要包括 Docker,containerd 和 CRI-O 低层级运行时(Low-level Runtime):包含了 runc, kata,以及 gVisor。 低层运行时 kata 和 gVisor 都还处于小规模落地或者实验阶段,其生态成熟度和使用案例都比较欠缺,所以除非有特殊的需求,否则 runc 几乎是必然的选择。因此在对容器运行时的选择上,主要是聚焦于上层运行时的选择。...

September 28, 2023 · 11 分钟 · 2200 字 · 熊鑫伟,我

深入了解Kubernetes Kube apisserver的组件

深入理解Kube-APIServer kube-apiserver是Kubernetes最重要的核心组件之一,主要提供以下的功能 提供集群管理的REST API接口,包括认证授权、数据校验以及集群状态变更等 提供其他模块之间的数据交互和通信的枢纽(其他模块通过API Server查询或修改数据,只有API Server才直接操作etcd) apiserver 主要功能: 认证:使用集群判断身份。 鉴权:使用操作 CRUD,需要权限。 准入: 对于Kubernetes来说,需要一些额外的 actions,例如写入的值不规范,需要对其进行修改,修改后需要 校验。最后需要 限流,以防止恶意或者漏洞导致拥堵 Mutating Validating Admission 限流 APIServer对象的实现 访问控制 API Server 是所有组件交互的 中间枢纽。 Kubernetes API的每个请求都会经过多阶段的访问控制之后才会被接受,这包括认证、授权以及准入控制(Admission Control)等。 前面的是 Mutating Webhook,可以改一个对象的值,而 Validating Webhook 是不可以修改对象的值,不生效的。 更加详细的请求处理流程: 📜 对上面的解释: 如何处理API请求:API源码存在于kubernetes/pkg/api路径中,会处理集群内以及集群外客户端的请求。 那么,当HTTP请求到达Kubernetes API时,具体会发现什么呢?从上层看,会发现以下交互: HTTP请求由一串过滤器(filters)进行处理,这些过滤器注册在DefaultBuildHandlerChain()(参阅源码:https://github.com/kubernetes/apiserver中的config.go)中,并执行相应的处理。过滤器要么会将信息传递并附加到ctx.RequestInfo上(例如通过了身份认证的用户),要么返回适当的HTTP响应代码。 第二步,复用器(multiplexer,参阅源码:https://github.com/kubernetes/apiserver中的container.go)会根据HTTP路径,将HTTP请求路由到相应的处理程序(handler)。 第三步,routes(在routes/*中定义)会将处理程序(handler)与HTTP路径进行连接。 第四步,按照API Group进行注册的处理程序(参阅源码:https://github.com/kubernetes/apiserver中的groupversion.go和installer.go),会处理HTTP请求和上下文(context,如user、rights等),并将请求的对象从存储中传送出来。 注意,为了简洁,在上图中我们省略了HTTP路径中的$NAMESPACE字段。 现在我们进一步深入的对前文中提到的DefaultBuildHandlerChain()中建立的过滤器(filters)进行介绍: **WithRequestInfo():**在requestinfo.go中定义,将RequestInfo附加到上下文中。...

September 28, 2023 · 7 分钟 · 1326 字 · 熊鑫伟,我