【后端开发】自动化部署、服务管理、问题排查工具(cicd流水线,k8s集群,ELK日志)
文章目录
- 1、Devops与CICD流水线(TeamCity, Jenkins,GitHub Actions)
- 2、Kubernetes 集群的管理和操作(对比Portainer,docker ui)
- 3、Elastic Stack / ELK 日志平台(Elasticsearch + Logstash + Filebeat + Kibana)
1、Devops与CICD流水线(TeamCity, Jenkins,GitHub Actions)
CICD和DevOps的区别和联系
- CICD更关注的是整个开发,测试,部署的自动化的过程,当我们在本地单元测试通过后,我们提交到git上,触发相应的webhook或者类似的东西进行代码的构建,并打包部署到相应的机器上,自动化的完成这整个过程。
- DevOps 就是开发(Development)、测试(QA)、运维(Operations)这三个领域的合并。虽然名字中没有体现,但是DevOps仍包括测试。
DevOps更关注的是打通用户、PMO、需求、设计、开发(Dev)、测试、运维(Ops)等各上下游部门或不同角色;打通业务、架构、代码、测试、部署、监控、安全、性能等各领域工具链;
尤其是打通开发与运维之间的gap,因为两者实际上存在着很多的冲突。DevOps是基于CICD的,自动化的流程是基础,DevOps是一个项目由idea到实际稳定运行的产品的一个最佳实践。- DevOps是CICD思想的延伸,CICD是DevOps的基础核心,如果没有CICD自动化的工具和流程,DevOps是没有意义的。
CICD是什么?
- CI/CD 是“持续集成”(Continuous Integration)和“持续交付/持续部署”(Continuous Delivery/Continuous Deployment)的缩写。
它们是现代软件开发流程中的关键实践,用于提高软件开发、测试和发布的效率与质量。 - 持续集成(CI)
是一种开发实践,强调将代码更频繁地集成到主干代码库中。其主要特点包括:
频繁合并: 开发人员定期将自己的代码更改合并到共享的主干分支,通常是每天多次(分支独立构建镜像和容器)。
自动化测试: 在每次代码提交后,自动运行构建和测试,确保新代码不会破坏现有功能(校验代码安全风险,容器正确运行,等等测试)。
及时反馈: 开发团队可以快速获得关于代码更改的反馈,从而更快地修复问题。 - 持续交付(CD)
是在持续集成的基础上进一步延伸的一种实践,目的是让软件始终处于可发布状态。其特点包括:
自动化构建和发布: 经过自动化测试的代码可以快速、安全地部署到生产环境或准备生产的环境中。
手动触发发布: 代码在任何时候都可以发布,但通常需要手动确认。 - 持续部署 (CD)
持续部署是持续交付的一个更高阶段,指的是每当代码通过自动测试后,立即自动部署到生产环境中。其特点包括:
自动化部署: 无需人工干预,代码更改会自动上线。
快速迭代: 可以更快地交付新功能或修复bug,客户几乎可以在更短的时间内体验到最新的产品改进。
TeamCity
- TeamCity 是 JetBrains 的商业 CI/CD 服务器,一般为自托管,也有云版本。
- 参考:1, 2, 3
- 特点:
- 灵活性: 通过配置能够支持复杂的构建流程和多种构建工具。
- 集成: 与多种版本控制系统、构建工具和部署平台的集成非常好。
- 插件支持: 拥有丰富的插件生态系统,可以扩展功能。
- 监控与分析: 提供详细的构建历史和性能监控。
Jenkins
- Jenkins 是一个开源的自动化服务器,用于实现持续集成和持续交付(CI/CD)。
- 参考:1, 2, 3
- 特点:
- 开源: 免费使用,并拥有活跃的社区。
- 插件生态: 拥有大量插件,几乎能够与所有主流工具和技术集成。
- 跨平台: 可以在多种操作系统上运行,包括 Windows、Linux 和 macOS。
- 高度可定制性: 允许用户根据需要进行配置和扩展。
GitHub Actions
- 类型: GitHub 提供的 CI/CD 工具,集成在 GitHub 平台内。
- 参考:1, 2, 3, 5
- 特点:
- 紧密集成: 与 GitHub 仓库无缝结合,可以直接在代码库中进行工作流配置。
- YAML 配置: 通过 YAML 文件定义构建和部署过程,易于理解和使用。
- 社区模板: 拥有大量社区共享的工作流模板,可以快速上手。
- 按需计费: 提供免费和按用量计费的选项,适合小型项目和开源项目。
服务选型对比
- TeamCity:提供用户友好的体验和高级功能,适合中小型企业,但具有商业限制。
- Jenkins:适合大规模和多样化的开发团队,开源,灵活且强大,但需要一定的维护和配置时间。
- GitHub Actions:对使用 GitHub 的团队特别便利,简化了 CI/CD 流程,但可能不适合需要独立于 GitHub 进行构建的场景。
更多CICD工具:
- 持续集成工具:Jenkins、Travis CI、CircleCI、GitLab CI等;
- 持续部署工具:Ansible、Puppet、Chef、SaltStack、AWS CodeDeploy等;
- 容器编排工具:Docker、Kubernetes、OpenShift等;
- 代码质量工具:SonarQube、Code Climate、Coverity、PMD等;
- 测试自动化工具:Selenium、Appium、TestComplete等;
- 监控工具:Nagios、Zabbix、ELK Stack等。
参考资料:1, 2, 3, 4, 5
2、Kubernetes 集群的管理和操作(对比Portainer,docker ui)
Kubernetes 与 Docker的联系
- Docker 可以允许开发人员使用本地容器在标准化环境中工作,从而对开发生命周期进行简化;而这些本地容器会为您提供应用程序和服务。它是基于容器的平台,支持高度可移植的工作负载。
- 另一方面,Kubernetes 允许您定义复杂的容器化应用程序,并能跨服务器集群大规模运行这些应用程序。
- Kubernetes,容器编排工具,在多个服务器之间协调多个容器,大规模地定义与运行复杂的容器化应用程序。
- docker, 用于创建和运行容器的容器技术堆栈, 使用库和运行时将应用程序打包到容器映像, 更快速对应用程序操作和代码传输进行标准化。
- Kubernetes 管理的容器通常是 Docker 容器,也可以是docker衍生的其他如containerd,CRI-O等更轻量的容器。
Kubernetes 与 docker管理工具(Portainer、Docker UI)
- Portainer 和 Docker UI 更专注于容器的简单管理,而 Kubernetes 则是用于全面管理大规模容器集群的编排平台。
- Portainer 是一款免费的容器管理平台,它提供了Web界面管理Docker容器、镜像、网络和数据卷等资源。Portainer支持多种Docker环境,包括Docker Swarm、Kubernetes和Docker单机模式。通过Portainer,用户可以方便地创建、启动、停止和删除容器、查看容器日志、进入容器终端、管理镜像等操作。
- DockerUI 是一个易于使用且轻量级的Docker管理工具。通过Web界面的操作,可以更方便地让不熟悉Docker指令的用户更快地进入Docker世界。DockerUI覆盖了Docker CLI命令行的95%以上的命令功能。通过DockerUI界面提供的可视化操作功能,可以轻松执行Docker环境和Docker Swarm群集环境的管理和维护功能。
Kubernetes(通常简称为 K8s)是一个开源容器编排平台,主要用于自动化应用程序的部署、扩展和管理。
集群(Cluster)
- Kubernetes 集群是由一组实际或虚拟计算机(节点)组成的集合,这些计算机一起运行 Kubernetes 应用。集群由以下两种主要角色的节点组成:
- 控制平面(Control Plane):负责管理集群的状态,包括 API 服务器、调度器、控制管理器和 etcd(存储集群状态的键值数据库)。
- 工作节点(Worker Node):实际运行应用程序的节点,每个节点通常运行多个 pod。
核心组件
- API Server:Kubernetes 控制平面的前端,所有的操作请求都通过 API Server 处理。
- etcd:一个分布式键值存储系统,用于保存集群的所有数据和状态。
- Controller Manager:负责处理控制器的运行,确保集群状态的一致性。
- Scheduler:负责将新创建的 Pod 调度到适合的工作节点。
- Kubelet:运行在每个工作节点上的代理,它负责维护 Pod 的状态。
- Kube-Proxy:负责网络代理和负载均衡,处理 Pod 之间的通信。
基本对象
- Pod:Kubernetes 中最小的可调度单元,包含一个或多个容器,通常提供应用程序的基础环境。
- Service:为一组 Pod 提供统一的访问入口,可以通过 DNS 名称进行访问,支持负载均衡。
- Deployment:用于管理无状态应用的声明式 API,对 Pod 进行创建和更新。
- ReplicaSet:确保指定数量的 Pod 副本在任何时间都在运行。
- StatefulSet:用于管理有状态应用的 Pod,确保 Pod 的唯一性和持久性。
- DaemonSet:确保在每个节点上运行一个 Pod 的副本,通常用于集群级别的管理任务。
- Job:用于一次性任务调度,确保指定的数量的 Pod 任务成功完成。
基本概念
- 命名空间(Namespace) :是 Kubernetes 中用于将集群资源分隔的机制,允许在同一个集群中运行多个隔离的工作负载。常用来组织不同的环境(如开发、测试和生产)或按团队划分。
- Volume 和 Storage:Kubernetes 提供了多种存储选项,支持各种持久化存储机制。例如,Pod 中的 Volume 用于存放容器的数据,允许跨 Pod 持久化存储。
- Label:用于对 Kubernetes 对象进行标记,以便进行选择和组织。可以用于选择特定的 Pod。
- Annotation:允许附加元数据到对象上,通常用于存储非识别信息。
- 网络:Kubernetes 提供了强大的网络管理功能,包括容器间的通信、服务发现和负载均衡。每个 Pod 都有自己的 IP 地址,所有 Pod 之间的通信可以通过该 IP 地址进行。
kubectl常用命令:
# 查看集群信息
kubectl cluster-info
# 查看所有命名空间
kubectl get namespaces
# 查看所有 Pods
kubectl get pods
# 查看特定命名空间的 Pods
kubectl get pods -n <namespace>
# 查看所有服务
kubectl get services
# 查看特定命名空间的服务
kubectl get services -n <namespace>
# 查看 Pod 详细信息
kubectl describe pod <pod-name>
# 创建资源
kubectl apply -f <file.yaml>
# 删除资源
kubectl delete pod <pod-name>
# 查看集群节点
kubectl get nodes
# 查看特定节点信息
kubectl describe node <node-name>
# 获取 Pod 日志
kubectl logs <pod-name>
# 执行命令到 Pod 中
kubectl exec -it <pod-name> -- <command>
# 查看所有 ReplicaSets
kubectl get replicasets
# 查看所有 Deployments
kubectl get deployments
# 查看特定 Deployment 的详细信息
kubectl describe deployment <deployment-name>
# 滚动更新 Deployment
kubectl rollout restart deployment <deployment-name>
# 查看 Deployment 的历史
kubectl rollout history deployment <deployment-name>
K8S集群搭建
- 一主(master)一从(slave)。系统创建的Pod都在namespace为kube-system中。master和slave的组件分配如下图
master的k8s主要组件
- kube-apiserver 客户端组件通过kube-apiserver管理cluster各种资源,kube-apiserver提供了HTTP/HTTPS RESTful API,例如kubectl就算是一个客户端
- kube-controller-manager 管理cluster的资源,kube-controller-manager由多种controller组成,包括replication controller、namespacecontroller等。 不同的controller管理不同的资源,replication controller管理Deployment、StatefulSet、DaemonSet的生命周期;namespacecontroller管理Namespace资源
- kube-schedule 负责决定哪个Pod在哪个机器上运行。Scheduler在调度时会充分考虑Cluster的拓扑结构,当前各个节点的负载,以及应用对高可用、性能、数据亲和性的需求
- etcd 是一个数据库,保存集群的配置信息和各种资源的状态信息。例如,kubectl get pod信息就是从etcd数据库获取的
- weave-net Pod间总是要通信的,weave是Pod的网络的其中一个方案
slave的k8s主要组件
- kube-proxy: service在逻辑上代表了后端的多个Pod,外界通过service访问Pod。
service接收到的请求是如何转发到Pod的呢?这就是kube-proxy要完成的工作。每个Node都会运行kube-proxy服务,它负责将访问service的TCP/UPD数据流转发到后端的容器。如果有多个副本,kube-proxy会实现负载均衡。从图中可以看到master也有kube-proxy,这是因为master也可以作为一个slave来使用。 - kubelet : 是Node的agent,当Scheduler确定在某个Node上运行Pod后,会将Pod的具体配置信息(image、volume等)发送给该节点的kubelet,kubelet根据这些信息创建和运行容器,并向Master报告运行状态。
参考资料:1, 2, 3, 4, 5,6
3、Elastic Stack / ELK 日志平台(Elasticsearch + Logstash + Filebeat + Kibana)
日志的传输路线是:
- 微服务产生日志,并将日志数据保存到磁盘中的.log文件中,
- filebeat监听log文件,将其数据收集并结构化后传输到logstash上,
- logstash将日志进行过滤收集,再传输到elasticsearch上,
- elasticsearch把日志作为索引进行存储并且构造对应倒排索引,
- kibana可视化呈现日志,需要查询时kibana调用elasticsearch进行日志数据的查询。
Elastic Stack架构
- Elastic Stack(也称为 ELK Stack)是公认的日志监测领域的领导者,拥有业界最广泛、最全面的系列日志数据源,是备受欢迎的免费开放日志平台。
- 由四个组件组成,分别是Beats、Logstash、Elasticsearch、Kibana。它们提供了日志采集、清洗、存储、可视化的能力,是一个比较完备的架构。
- Beats:是一组工具集,一些轻量的数据采集器。
需要把他们安装在生产环境的各个机器上,他们采集了本机日志后,向Logstash或Elasticsearch发送数据。 - Logstash:动态数据收集管道,负责数据的清洗、格式化、添加附属信息等。
Logstash的功能是很强大的,它支持从多种系统中收集数据,又可以把数据推送到各种系统里。 - Elasticsearch:是一种分布式搜索引擎,数据的存储、查询都集中在这里。
它本身有较为强大的集群管理功能,支持水平扩展。
数据多分片、多副本存储,即提供高并发的写入查询能力,又能保证数据可靠性。 - Kibana:数据可视化平台
支持各种丰富的图表,可以直观的呈现日志数据。
也提供了易用的搜索界面,简化问题定位过程。
ELK 平台搭建
-
参考资料:1
-
1、部署并启动微服务
- 指定服务的日志地址:
logging.file.path=/Users/xxx/
- 指定服务的日志地址:
-
2、部署 Elasticsearch
- 解压 Elasticsearch 文件:
tar -zxvf elasticsearch-7.13.0-linux-x86_64.tar.gz
- 修改配置文件(参考网络或参考资料)。
- 因为 Elasticsearch 不允许以 root 账号启动,需要提前创建其他账号。
- 将 Elasticsearch 安装目录权限赋给 elastic 账号:
chown -R elastic:elastic elasticsearch-7.13.0
- 以 elastic 账户启动 Elasticsearch:
./bin/elasticsearch
- 解压 Elasticsearch 文件:
-
3、部署 Kibana
- 解压 Kibana 文件:
tar -zxvf kibana-7.13.0-linux-x86_64.tar.gz
- 修改配置文件:
vim config/kibana.yml
(参考网络或参考资料) - 同样,Kibana 也不允许用 root 账号启动,需要创建 elastic 账号,并将 Kibana 安装目录的权限赋给他:
chown -R elastic:elastic kibana-7.13.0
- 开通 5602 端口:
firewall-cmd --add-port=5602/tcp --permanent
- 重新载入添加的端口:
firewall-cmd --reload
- 以 elastic 账户启动 Kibana:
./bin/kibana
- 测试访问
ip:5602
,若出现页面则部署成功。
- 解压 Kibana 文件:
-
4、部署 Logstash
- Logstash 依赖于 Java 环境,推荐使用 JDK 8、11 或 14,提前安装 Java 环境(官方推荐 JDK 11+)。
- 注意:Logstash 7.13.0 自带 JDK,若服务器没有单独安装 JDK,将使用 Logstash 下的 JDK。
- 将 Logstash 安装包上传到服务器:
scp logstash-7.13.0-linux-x86_64.tar.gz root@172.16.188.6:/var/local
- 解压安装包:
tar -zxvf logstash-7.13.0-linux-x86_64.tar.gz
- 修改配置文件,Logstash 提供了实例配置文件
logstash-sample.conf
可作基础修改。 - 开放 5044 端口:
firewall-cmd --add-port=5044/tcp --permanent
- 重新载入配置:
firewall-cmd --reload
- 以上述配置文件启动 Logstash,注意 Logstash 启动较慢。
-
5、部署 Filebeat
- 将 Filebeat 传输到两个微服务所在的服务器上:
scp
- 在
/var/local
目录下解压 Filebeat:tar -zxvf filebeat-7.13.0-linux-x86_64.tar.gz
- 进入 Filebeat 安装目录,修改配置文件:
vim filebeat.yml
- 启动 Filebeat:
./filebeat -e -c filebeat.yml
- 重启微服务,并将启动日志输入到 Beats 中。
- 调用接口创建几条日志:
- user-service:
http://xxx:8081/user/info?log=use
http://xxx:8081/user/error?log=use
- order-service:
http://xxx:8080/order/info?log=orde
http://xxx:8080/order/error?log=orde
- user-service:
- 将 Filebeat 传输到两个微服务所在的服务器上:
-
6、Kibana 可视化
- 在 Kibana 的 Dev Tools 中输入指令:
GET _cat/indices
,查看日志索引是否创建成功。 - 打开 Kibana,进入 Stack Management > Index Management,可以发现新创建的日志索引状态为黄色,这可能是由于副本分片数设置为1所致。需修改为0以更新索引状态为绿色:点击索引,在弹出框中点击 edit settings,修改
number_of_replicas
为 0,点击 save。 - 也可以通过 DSL 指令直接修改。
- 点击 Index Patterns,创建索引模式。
- 输出
order-log
的正则匹配,同理创建user-log
的索引模式。 - 进行索引可视化,点击左侧菜单栏中的 Discover。
- 在 Kibana 的 Dev Tools 中输入指令:
部分架构图:
参考资料:1, 2,3, 4, 5 ,6,