AWS DevOps 项目:具有基础设施即代码、微服务、服务网格和监控功能的高级自动化 CI/CD 管道
介绍
在这个高级 AWS DevOps 项目中,我们将构建一个复杂的 CI/CD 管道,以在 AWS 上自动部署基于微服务的应用程序。我们将利用关键的 DevOps 实践,例如使用Terraform 的基础设施即代码 (IaC) 、使用Amazon EKS (Elastic Kubernetes Service)进行容器编排、与 Istio 的服务网格集成,以及使用Prometheus、Grafana和Fluentd进行全面的监控和日志记录。
该项目旨在涵盖 AWS 和 DevOps 工程师经常遇到的复杂现实场景,让您深入了解如何构建、部署和管理现代云原生应用程序。
目录
- 项目概述
- 先决条件
- 架构图
- 分步指南
- 使用 Terraform 的基础设施即代码
- 设置 VPC 和网络
- IAM 角色和策略
- 创建EKS集群
- 与 RDS 集成以实现持久存储
- 在高可用配置中部署 Jenkins
- 在 EC2 上设置 Jenkins 并启用自动伸缩功能
- 配置Jenkins主从架构
- 构建和 Docker 化微服务
- 使用 Istio 实现服务网格
- 在 EKS 上安装 Istio
- 配置流量管理、安全性和可观察性
- 设置 Jenkins CI/CD 管道
- 集成 GitHub、Jenkins、Docker 和 EKS
- 实施蓝绿部署
- 使用 Istio 实现自动化金丝雀部署
- 监控、日志记录和警报
- 设置Prometheus和Grafana
- 配置 Fluentd 进行集中日志记录
- 设置 Alertmanager 进行事件响应
- 使用 Terraform 的基础设施即代码
- 测试和验证
- 结论
- 参考
1.项目概述
该项目将指导您设置高级 CI/CD 流水线,该流水线使用 Kubernetes (EKS)、用于服务网格的 Istio 以及用于 CI/CD 的 Jenkins,在 AWS 上自动部署基于微服务的应用程序。我们将涵盖从使用 Terraform 进行基础设施配置到在安全、可扩展且可观察的环境中部署和管理微服务的整个生命周期。
2.先决条件
- AWS 账户:对 AWS 账户的管理访问权限。
- AWS CLI:已安装并配置适当的凭证。
- Terraform:安装在您的本地机器上。
- kubectl:安装用于管理 Kubernetes 集群。
- Jenkins:安装在 EC2 实例上或通过 Docker 设置。
- Docker:已安装并运行在您的本地机器上。
- Git:已安装并配置。
- Helm:为 Kubernetes 包管理而安装。
3.架构图
该架构由一个包含公有子网和私有子网的 VPC、一个跨多个可用区部署的 EKS 集群、一个在 EC2 上部署且具有自动扩展功能的高可用 Jenkins、一个用于持久数据存储的 RDS 以及一个用于服务网格集成的 Istio 组成。监控由 Prometheus 和 Grafana 负责,而 Fluentd 则负责集中日志记录。
架构图概述
-
1. 开发者工作站:
- 开发人员将代码提交到GitHub存储库。
-
2.持续集成:
- Jenkins从 GitHub 拉取最新代码。
- Jenkins 构建并测试该应用程序。
- Docker用于创建应用程序的 Docker 镜像。
- 构建的图像被推送到Docker Registry(例如,Amazon ECR)。
-
3.基础设施即代码:
- Terraform用于配置 AWS 基础设施,包括:
- 用于网络的VPC。
- IAM安全角色和策略。
- 适用于 Kubernetes 的EKS 集群。
- RDS用于持久存储。
-
4.持续部署:
- Jenkins使用 Kubernetes 清单或 Helm 图表将 Docker 镜像部署到Amazon EKS 。
- Istio(服务网格)用于管理微服务之间的流量。
-
5.服务网格:
- Istio提供流量管理、安全性(mTLS)和可观察性。
- Istio Ingress Gateway管理对服务的外部访问。
-
6.监控和日志记录:
- Prometheus从 Kubernetes 集群和 Istio 收集指标。
- Grafana将指标可视化并提供仪表板。
- Fluentd用于集中日志记录,将日志发送到Amazon CloudWatch或Elasticsearch。
- Alertmanager与 Prometheus 集成以发出警报。
-
7.持续反馈:
- Alertmanager向 Slack 或电子邮件发送通知。
- Jenkins 为开发人员提供构建和部署反馈。
图表组件
- GitHub:版本控制和源代码存储库。
- Jenkins:用于自动化构建、测试和部署的 CI/CD 服务器。
- Docker:将应用程序容器化,以提供一致的环境。
- Terraform:自动配置 AWS 基础设施。
- Amazon ECR:Docker 镜像存储库。
- Amazon EKS:用于部署和管理容器化应用程序的 Kubernetes 服务。
- Istio:用于管理服务到服务通信的服务网格。
- Prometheus 和 Grafana:用于指标和仪表板的监控堆栈。
- Fluentd:集中式日志记录解决方案。
- Alertmanager:根据 Prometheus 收集的指标管理警报。
- Amazon CloudWatch:基于云的日志记录和监控服务。
架构流程
- 代码提交:开发人员将代码推送到 GitHub。
- CI 管道:Jenkins 检测代码更改、构建项目、运行测试并构建 Docker 镜像。
- 镜像推送:Jenkins 将 Docker 镜像推送到 Amazon ECR。
- 基础设施部署:Terraform 在 AWS 上提供必要的基础设施。
- CD Pipeline:Jenkins 将应用程序部署到 Amazon EKS,并使用 Istio 管理流量路由。
- 服务网格管理:Istio 处理服务通信、安全和监控。
- 监控和日志记录:Prometheus 收集指标,Grafana 将其可视化,Fluentd 将日志转发到 CloudWatch。
- 警报:Alertmanager 根据 Prometheus 指标发送警报。
4.分步指南
使用 Terraform 的基础设施即代码
步骤:-1 设置 VPC 和网络
- 为您的 Terraform 文件创建一个新目录:
mkdir advanced-aws-devops-project
cd advanced-aws-devops-project
- 初始化您的 Terraform 项目:
terraform init
- 创建一个
main.tf
包含以下内容的文件来定义您的 VPC、子网和网络组件:
provider "aws" {
region = "us-west-2"
}
resource "aws_vpc" "main_vpc" {
cidr_block = "10.0.0.0/16"
enable_dns_support = true
enable_dns_hostnames = true
tags = {
Name = "advanced-devops-vpc"
}
}
resource "aws_subnet" "public_subnet" {
vpc_id = aws_vpc.main_vpc.id
cidr_block = "10.0.1.0/24"
map_public_ip_on_launch = true
availability_zone = "us-west-2a"
tags = {
Name = "public-subnet"
}
}
resource "aws_subnet" "private_subnet" {
vpc_id = aws_vpc.main_vpc.id
cidr_block = "10.0.2.0/24"
availability_zone = "us-west-2b"
tags = {
Name = "private-subnet"
}
}
resource "aws_internet_gateway" "igw" {
vpc_id = aws_vpc.main_vpc.id
tags = {
Name = "main-igw"
}
}
resource "aws_route_table" "public_route_table" {
vpc_id = aws_vpc.main_vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.igw.id
}
tags = {
Name = "public-route-table"
}
}
resource "aws_route_table_association" "public_subnet_association" {
subnet_id = aws_subnet.public_subnet.id
route_table_id = aws_route_table.public_route_table.id
}
- 应用 Terraform 配置:
terraform apply
步骤 2:IAM 角色和策略
- 创建一个
iam.tf
文件来定义 EKS、RDS 和其他 AWS 服务的 IAM 角色和策略:
resource "aws_iam_role" "eks_role" {
name = "eks_role"
assume_role_policy = jsonencode({
"Version": "2012-10-17",
"Statement": [{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "eks.amazonaws.com"
}
}]
})
}
resource "aws_iam_role_policy_attachment" "eks_policy_attachment" {
role = aws_iam_role.eks_role.name
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"
}
resource "aws_iam_role" "rds_role" {
name = "rds_role"
assume_role_policy = jsonencode({
"Version": "2012-10-17",
"Statement": [{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "rds.amazonaws.com"
}
}]
})
}
resource "aws_iam_role_policy_attachment" "rds_policy_attachment" {
role = aws_iam_role.rds_role.name
policy_arn = "arn:aws:iam::aws:policy/AmazonRDSFullAccess"
}
- 应用 IAM 角色配置:
terraform apply
步骤 3:创建 EKS 集群
- 添加以下内容
main.tf
以创建具有自动扩展节点组的 EKS 集群:
module "eks" {
source = "terraform-aws-modules/eks/aws"
cluster_name = "advanced-eks-cluster"
cluster_version = "1.24"
vpc_id = aws_vpc.main_vpc.id
subnets = [aws_subnet.public_subnet.id, aws_subnet.private_subnet.id]
node_groups = {
eks_nodes = {
desired_capacity = 3
max_capacity = 5
min_capacity = 2
instance_type = "t3.medium"
key_name = "your-key-pair"
tags = {
Name = "advanced-eks-node"
}
}
}
}
- 应用 EKS 配置:
terraform apply
步骤 4:与 RDS 集成以实现持久存储
- 创建一个 RDS 实例用于
rds.tf
文件中的持久存储:
resource "aws_db_instance" "db_instance" {
allocated_storage = 20
engine = "mysql"
engine_version = "8.0"
instance_class = "db.t3.micro"
name = "microservicesdb"
username = "admin"
password = "password"
parameter_group_name = "default.mysql8.0"
skip_final_snapshot = true
vpc_security_group_ids = [aws_security_group.eks_sg.id]
db_subnet_group_name = aws_db_subnet_group.rds_subnet_group.name
}
resource "aws_db_subnet_group" "rds_subnet_group" {
name = "rds-subnet-group"
subnet_ids = [aws_subnet.private_subnet.id]
tags = {
Name = "RDS Subnet Group"
}
}
- 应用 RDS 配置:
terraform apply
在高可用配置中部署 Jenkins
步骤 5:在 EC2 上设置 Jenkins 并启用自动扩展
- 在启用了 Auto-Scaling 的 EC2 实例上启动 Jenkins:
resource "aws_launch_configuration" "jenkins_lc" {
image_id = "ami-0abcdef1234567890"
instance_type = "t3.medium"
key_name = "your-key-pair"
security_groups = [aws_security_group.jenkins_sg.id]
lifecycle {
create_before_destroy = true
}
user_data = <<-EOF
#!/bin/bash
sudo yum update -y
sudo yum install -y java-1.8.0-openjdk
sudo wget -O /etc/yum.repos.d/jenkins.repo \
https://pkg.jenkins.io/redhat-stable/jenkins.repo
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key
sudo yum install -y jenkins
sudo systemctl start jenkins
sudo systemctl enable jenkins
EOF
}
resource "aws_autoscaling_group" "jenkins_asg" {
launch_configuration = aws_launch_configuration.jenkins_lc.id
min_size = 2
max_size = 4
desired_capacity = 2
vpc_zone_identifier = [aws_subnet.public_subnet.id]
tags = [
{
key = "Name"
value = "Jenkins Instance"
propagate_at_launch = true
},
]
}
- 应用 Jenkins EC2 设置:
terraform apply
步骤6:配置Jenkins主从架构
Jenkins 主从(或控制器-代理)架构允许您将构建、测试和部署应用程序的工作负载分布到多台机器上。这种架构可以提高性能并提高资源利用率,尤其是在大规模环境中。以下是在此架构下设置 Jenkins 的详细指南。
先决条件
- Jenkins Master:主要的 Jenkins 服务器,也称为控制器,负责协调构建任务并将其分发到代理节点。
- Jenkins 代理:执行 Jenkins 主服务器分配的构建任务的附加服务器(从服务器)。
步骤 6.1:设置 Jenkins Master
您已在前面的步骤中在 EC2 实例上设置了 Jenkins。此实例将用作您的 Jenkins 主服务器。请确保以下各项已到位:
- Java 安装:Jenkins 需要 Java 才能运行。请验证 Java 是否已安装:
java -version
如果没有安装,你可以使用以下命令进行安装:
sudo yum install -y java-1.8.0-openjdk
- Jenkins 安装:Jenkins 应该已运行并可通过 Web 浏览器访问。请
http://<Jenkins_Master_IP>:8080
在浏览器中导航至 进行确认。
步骤 6.2:准备 Jenkins 代理节点
您需要额外的 EC2 实例来充当 Jenkins 代理。设置方法如下:
-
为 Jenkins 代理启动 EC2 实例:
- 使用 AWS 管理控制台启动新的 EC2 实例。您可以选择 Amazon Linux 2 AMI(或任何其他 Linux 发行版)。
- 确保这些实例具有足够的资源(例如,t2.medium)并且与 Jenkins 主实例位于同一 VPC 中。
-
安全组:
- 确保安全组允许从 Jenkins 主服务器进行 SSH 访问。
- 允许在 Jenkins 代理与主服务器通信所需的端口上进行通信(默认 SSH 端口 22)。
-
在代理节点上安装 Java:
- 通过 SSH 进入每个代理节点并安装 Java:
sudo yum update -y sudo yum install -y java-1.8.0-openjdk
-
在代理节点上创建 Jenkins 用户:
- 创建专用于在代理节点上运行 Jenkins 的用户:
sudo useradd jenkins
-
为该用户设置 SSH 访问权限,以便 Jenkins 主服务器可以连接:
sudo mkdir /home/jenkins/.ssh sudo chown jenkins:jenkins /home/jenkins/.ssh sudo chmod 700 /home/jenkins/.ssh
-
将 SSH 公钥从 Jenkins 主服务器复制到每个代理的
/home/jenkins/.ssh/authorized_keys
文件中。
-
在代理节点上安装 Jenkins 代理:
- 从 Jenkins 主服务器下载 Jenkins 代理(也称为
slave.jar
)。在 Jenkins 主服务器上:
wget http://<Jenkins_Master_IP>:8080/jnlpJars/agent.jar
- 从 Jenkins 主服务器下载 Jenkins 代理(也称为
- 将此
agent.jar
文件传输到每个代理节点,并将其放在类似 的目录中/home/jenkins
。
步骤 6.3:配置 Jenkins Master 使用代理
-
在 Jenkins 中添加新节点:
- 在 Jenkins 仪表板上,转到管理 Jenkins > 管理节点和云 > 新节点。
- 输入新节点的名称(例如
Agent-1
),选择永久代理,然后单击确定。
-
配置节点设置:
- 远程根目录:指定 Jenkins 应在代理上运行的目录,例如
/home/jenkins
。 - 标签:为节点分配标签,以便于作业分配(例如
linux-agent
)。 - 启动方式:选择通过 SSH 启动代理。
- 主机:输入代理节点的私有IP地址。
- 凭证:为用户添加 SSH 凭证(用户名和私钥)
jenkins
。
- 远程根目录:指定 Jenkins 应在代理上运行的目录,例如
-
测试连接:
- 单击“保存”,然后通过 SSH 启动代理。
- Jenkins 将尝试通过 SSH 连接到代理节点。如果成功,您将看到代理状态更改为“已连接”。
-
对其他代理重复上述操作:
- 重复上述步骤来配置任何其他 Jenkins 代理节点。
步骤 6.4:配置 Jenkins 作业以使用特定代理
现在您的 Jenkins 主节点已连接到代理节点,您可以配置作业以在特定代理上运行:
-
创建或配置 Jenkins 作业:
- 转到Jenkins 仪表板上的新项目或选择现有作业。
-
指定节点用途:
- 在作业配置下,查找“限制可以运行此项目的位置”部分。
linux-agent
输入您希望运行作业的代理的标签(例如)。
-
保存并构建:
- 保存作业配置并触发构建。
- 该作业现在应该在指定的 Jenkins 代理节点上执行。
步骤 6.5:监控和管理 Jenkins 代理
-
节点监控:
- Jenkins 为每个代理节点提供了内置监控功能。您可以前往“管理 Jenkins”>“管理节点和云”查看,其中可以看到每个代理的状态、空闲时间和负载。
-
阻垢剂:
- 对于大规模环境,您可以使用 AWS Auto Scaling Groups 为代理节点配置自动扩展,从而允许 Jenkins 根据工作负载自动扩展代理数量。
-
代理可用性:
- 通过为代理配置强大的健康检查功能(例如 CPU、内存和磁盘使用情况监控),确保代理始终可用。与 CloudWatch 或 Prometheus 等监控工具集成可以帮助实现自动化。
构建和 Docker 化微服务
步骤 7:微服务应用程序概述
-
假设您有一个包含以下组件的微服务应用程序:
- 用户服务:管理用户身份验证和配置文件。
- 订单服务:处理订单处理和管理。
- 支付服务:与支付网关集成以处理支付。
-
为每个服务创建 Dockerfile:
用户服务 Dockerfile:
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG JAR_FILE=target/user-service.jar
COPY ${JAR_FILE} user-service.jar
ENTRYPOINT ["java","-jar","/user-service.jar"]
订购服务 Dockerfile:
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG JAR_FILE=target/order-service.jar
COPY ${JAR_FILE} order-service.jar
ENTRYPOINT ["java","-jar","/order-service.jar"]
支付服务 Dockerfile:
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG JAR_FILE=target/payment-service.jar
COPY ${JAR_FILE} payment-service.jar
ENTRYPOINT ["java","-jar","/payment-service.jar"]
- 构建 Docker 镜像并将其推送到 Amazon ECR:
docker build -t user-service ./user-service
docker build -t order-service ./order-service
docker build -t payment-service ./payment-service
# Push images to ECR
aws ecr get-login-password --region us-west-2 | docker login --username AWS --password-stdin <aws_account_id>.dkr.ecr.us-west-2.amazonaws.com
docker tag user-service:latest <aws_account_id>.dkr.ecr.us-west-2.amazonaws.com/user-service:latest
docker push <aws_account_id>.dkr.ecr.us-west-2.amazonaws.com/user-service:latest
使用 Istio 实现服务网格
步骤 8:在 EKS 上安装 Istio
- 使用 Helm 在您的 EKS 集群上安装 Istio:
helm repo add istio https://istio-release.storage.googleapis.com/charts
helm install istio-base istio/base -n istio-system --create-namespace
helm install istiod istio/istiod -n istio-system
helm install istio-ingress istio/gateway -n istio-system
步骤 9:配置流量管理、安全性和可观察性
- 定义 Istio VirtualService 和 DestinationRule 进行流量管理:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: user-service
spec:
hosts:
- user-service
http:
- route:
- destination:
host: user-service
subset: v1
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: user-service
spec:
host: user-service
subsets:
- name: v1
labels:
version: v1
- 使用 Istio 的 Mutual TLS(mTLS)应用安全策略:
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: istio-system
spec:
mtls:
mode: STRICT
- 通过将 Istio 遥测与 Prometheus 和 Grafana 集成来实现可观察性。
设置 Jenkins CI/CD 管道
步骤 10:集成 GitHub、Jenkins、Docker 和 EKS
- 创建 Jenkins 流水线脚本来自动化构建、测试和部署过程:
pipeline {
agent any
stages {
stage('Checkout') {
steps {
git 'https://github.com/your-repo/microservices-app.git'
}
}
stage('Build') {
steps {
sh 'mvn clean package'
}
}
stage('Docker Build & Push') {
steps {
script {
docker.build("user-service:latest").push("${env.BUILD_TAG}")
}
}
}
stage('Deploy to EKS') {
steps {
script {
sh 'kubectl apply -f k8s/deployment.yaml'
sh 'kubectl apply -f k8s/service.yaml'
}
}
}
}
}
步骤11:实施蓝绿部署
- 定义用于蓝绿部署的 Kubernetes 清单:
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-service-green
spec:
replicas: 3
selector:
matchLabels:
app: user-service
version: green
template:
metadata:
labels:
app: user-service
version: green
spec:
containers:
- name: user-service
image: <aws_account_id>.dkr.ecr.us-west-2.amazonaws.com/user-service:green
ports:
- containerPort: 8080
- 应用绿色部署并使用 Istio 切换流量:
kubectl apply -f k8s/user-service-green.yaml
kubectl apply -f k8s/virtualservice.yaml
步骤 12:使用 Istio 进行自动金丝雀部署
- 在 Istio VirtualService 中实现金丝雀部署策略:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: user-service
spec:
hosts:
- user-service
http:
- route:
- destination:
host: user-service
subset: v1
weight: 90
- destination:
host: user-service
subset: v2
weight: 10
监控、日志记录和警报
步骤13:设置Prometheus和Grafana
- 通过 Helm 安装 Prometheus 和 Grafana:
helm install prometheus prometheus-community/prometheus
helm install grafana grafana/grafana
- 访问 Grafana 并添加 Prometheus 作为数据源,然后导入 Istio 仪表板进行监控。
步骤14:配置Fluentd进行集中日志记录
- 在您的 EKS 集群上设置 Fluentd DaemonSet 以聚合来自所有微服务的日志:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd
spec:
selector:
matchLabels:
app: fluentd
template:
metadata:
labels:
app: fluentd
spec:
containers:
- name: fluentd
image: fluent/fluentd-kubernetes-daemonset:v1.11
env:
- name: FLUENT_ELASTICSEARCH_HOST
value: "elasticsearch"
- name: FLUENT_ELASTICSEARCH_PORT
value: "9200"
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
步骤15:设置Alertmanager进行事件响应
- 配置 Prometheus Alertmanager 以根据指标和阈值发送警报:
global:
smtp_smarthost: 'smtp.gmail.com:587'
smtp_from: 'alertmanager
@example.com'
smtp_auth_username: 'example@gmail.com'
smtp_auth_password: 'password'
route:
receiver: 'email-alert'
receivers:
- name: 'email-alert'
email_configs:
- to: 'your-email@example.com'
- 将 Alertmanager 与 Slack 集成以实现实时事件通知。
结论:
该项目展示了一套先进的 AWS DevOps 设置,融合了多服务架构、Jenkins CI/CD 流水线、Docker、Kubernetes 和 Istio 服务网格。提供的详细步骤涵盖了基础设施配置、自动化部署、监控、日志记录和警报,为 AWS 和 DevOps 工程师提供了全面的指南。此设置确保了高可用性、可扩展性、安全性和可观察性,使其成为在云原生环境中管理微服务的强大解决方案。
👤 作者

加入我们的电报社区||在 GitHub 上关注我以获取更多 DevOps 内容!
文章来源:https://dev.to/prodevopsguytech/aws-devops-project-advanced-automated-cicd-pipeline-with-infrastruct-as-code-microservices-service-mesh-and-monitoring-3o13