Giới thiệu sơ lược một số dịch vụ của AWS trong Re:Invent 2022 (Phần DevOps và Builder Experiences)
Application composer
Application composer giúp các lập trình viên đơn giản hóa và tăng tốc trong việc xây dựng các ứng dụng serverless. Các bạn có thể import và visualize các CloudFormation template đã có sẵn hoặc tạo mới các CloudFormation và SAM template chỉ bằng cách kéo thả. Các template được generate đều tuân theo các best practices mà AWS recommend.
Điểm đặc biệt hay ho của application composer là bạn có thể liên hết với các project files dưới máy local để có thể sync các thay đổi từ console đến local và ngược lại.
Lưu ý rằng, Application composer sẽ chỉ tạo ra các template, các bạn sẽ cần kết hợp với SAM CLI để deploy các template này.
Để mà so sánh Application composer với các dịch vụ hiện có với chức năng gần tương đương như CloudFormation Designer và CDK thì:
CloudFormation Designer có điểm mạnh là support nhiều service hơn nhưng sẽ khó hiểu, đặc biệt là với những người mới bắt đầu với IaC hơn Application composer
CDK thì chúng ta sẽ cần phải viết code bằng các programming languages, nên cũng gây khó khăn và mất nhiều thời gian hơn.
Nếu ứng dụng của bạn không bao gồm quá nhiều service không phải là serverless service, hoặc bạn là người mới với IaC, thì đây là một lựa chọn mà bạn nên cân nhắc, bạn có thể tạo ra các file template mà không cần phải giỏi CloudFormation.
CodeCatalyst
Bài toán CodeCatalyst giải quyết:
Trước đây để CI/CD cho các serverless applications, bạn sẽ có thể dùng SAM pipelines, CDK pipelines, tận dụng bộ CodePipeline của AWS.
Tuy nhiên, 1 dự án phát triển thì không chỉ có CI/CD, chúng ta còn cần phải quan tâm rất nhiều thứ khác như: setup môi trường, collaboration, tích hợp tools,… Nếu theo cách truyền thống, chẳng hạn để quản lý các đầu task, chúng ta sẽ phải sử dụng thêm những tool khác như Trello, Jira,..
CodeCatalyst là môi trường dev cloud-based, được tích hợp sẵn CI/CD pipepine, các dashboard quản lý pull push request, và cả quản lý issue. Bạn có thể dễ dàng mời người khác vào workspace của bạn chỉ đơn giản bằng các sử dụng email.
CodeCatalyst cũng define sẵn xác project blueprints để bạn có thể tận dụng giúp cho việc tạo ra một dev environment nhanh chóng hơn.
Sử dụng CodeCatalyst:
Để có thể sử dụng CodeCatalyst, bạn sẽ cần phải tạo AWS Builder ID.
Bạn sẽ cần phải tạo cho workspace 1 IAM role.
Bạn có thể tham khảo Demo tại đây:
Pricing:
Free với một số giới hạn về tính năng hoặc standard ($4/user/month)
CodeWhisperer
CodeWhisperer là một dịch vụ gợi ý code sử dụng công nghệ machine learning. Khi enable trong các IDEs như IntelliJ, VS Code,… nó tự động generate code từ code và comments trong IDE.
Bạn cũng có thể sử dụng CodeWhisperer để gợi ý code Lambda function.
Trước đây chỉ support Python, Java, Js. Trong lần cập nhật này, CodeWhisperer support thêm C# và TypeScript.
Ngoài ra, ở lần cập nhật này, CodeWhisperer tích hợp với IAM Identity Center và AWS Builder ID.
Để sử dụng CodeWhisperer, ví dụ với VS Code, bạn chỉ cần cài đặt AWSToolkit extension và sau đó chọn CodeWhisperer, và đăng nhập bằng IAM hoặc Builder ID.
Pricing:
During the preview period, developers can use CodeWhisperer at no cost.
EventBridge Pipes
Eventbridge Pipes là tính năng mới của Eventbridge, cho phpes connect event producers và consumer. Với EventBridge Pipes, các bạn sẽ không cần phải viết, quản lý integration code, nó support point-to-point integration, ngoài ra bạn có thể filter hoặc transform event trước khi gửi tới target nếu cần.
So sánh:
Với event buses:
Buses: Many publisher → many consumers
Pipes: 1 publisher → 1 consumer
Use cases:
- Pub/Sub:
→ EventBridge Rules (Event Pattern)
- Producer/Consumeer:
→ EventBridge Pipes
- schedule type:
→ EventBridge Rules (Schedule), EventBridge Scheduler
Pricing:
$0.40/million requests entering a Pipe
Distributed Map for AWS Step Functions
AWS Step Functions distributed map support lập kế hoạch cho các workload có scale lớn chạy song song trong serverless applications. Nó có thể lặp hàng triệu objects như là ảnh, logs và csv file lưu trong S3 bucket.
Cách hoạt động thì giống như Step Functions map nhưng map state thì bị giới hạn 40 concurrent iterations còn giới hạn của AWS Step Functions Distributed Map lên tới 10000.
Pricing: starts at $0.025 per 1,000 state transitions
AppFlow (22 more connectors)
Trong lần cập nhật này, AWS add thêm khoảng 22 connectors cho AppFlow, nâng tổng số connecter lên 50. Hiện tại, bạn đã có thể tích hợp với AWS Glue Data Catalog,.
ECS Service Connect
Trước đây, để kết nối các service trong ECS với nhau bằng dns name, bạn sẽ có thể dùng những cách như:
sử dụng ELB
Sử dụng ECS Service Discovery (register task IP vào record trên private hosted zone)
Sử dụng AppMesh
ưu điểm khi dùng ELB là có thể tận dụng các tính năng nâng cao của ELB như Blue/green, routing theo path,… nhưng chi phí lại rất cao
Nếu dùng ECS Service Discovery thì đơn giản, nhưng lại không có các metrics hỗ trợ quản lý trạng thái các connection
AppMesh cho phép bạn quản lý traffic tốt hơn, có thể được encrypt với mTLS, nhưng lại là phương pháp rất phức tạp vì phải quản lý các component bên ngoài.
Nếu bạn đang cần 1 giải pháp:
Đơn giản như ECS Service Discover
Có các metrics quản lý như khi sử dụng ELB
Connection có khả năng phục hồi như AppMesh
thì đó chính là ECS Service Connect.
ECS Connect hoạt động như nào?
Khi bạn bật ECS service connect, thì tự động trong các task sẽ được add thêm 1 sidecar container là envoy proxy. Các sidecar container này sẽ giúp kiểm tra healthcheck, gửi metrics đến CloudWatch cũng như điều phối connection giữa các service.
ECS service connect sử dụng CloudMap namespace để phân giải dns. Các service cùng trong một namespace có thể call tới nhau thông qua namespace.
ECS Service connect còn cho phép bạn đạt được trạng thái zero – downtime bằng cơ chế draining connections.
ECS Service Connect support giao tiếp giữa các ECS services thông qua giao thức TCP, HTTP/1.x, HTTP2.x và cả gRPC.
Sử dụng
ECS Service Connect hiện tại đã available trên cả management console, CLI, Copilot, và cả Terraform.
Để enable ECS service Connect, bạn chỉ cần khai báo thêm 1 đoạn code service connect configuration ngắn. Bạn sẽ cần định nghĩa port mapping nếu muốn service đó là server, không khai báo port mapping thì service sẽ là client service.
Điểm đặt biệt của ECS Service Connect là bạn sẽ không cần phải chỉnh sửa Task definition, do đó bạn sẽ có thể tận dụng lại các task defintion đó. ECS Service connect có thể kết nối các services trong các cluster khác nhau.
Chú ý
Không support Windows containers
Chỉ support rolling update, nếu bạn cần blue green thì sử dụng ELB
Mỗi ECS service chỉ được gắn với 1 namespace
Standalone tasks không được support
kết nối giữa các cluster và giữa các VPC: OK. Nhưng nếu các cluster ở khác region hoặc khác tài khoản AWS thì không thể kết nối
Ngoài ra bạn cũng cần quan tâm tới CPU unit và memory resource khi sử dụng ECS Service connect.
It is possible to belong to the namespace of only the same AWS account and the same region
Standalone tasks are not supported
ECS Service Connect Proxy Resource Considerations
Pricing:
Free, chỉ tính giá infra traffic cost.
So sánh với VCP lattice:
VPC lattice: Định nghĩa các policies cho việc quản lý traffic, network access và monitoring để connect apps giữa các compute service. Tự động handle network connectivity giữa các VPC, account, translation giữa IPv4, IPv6 và overlapping IP address.
Service connect: chỉ dùng cho ecs, không handle connect giữa các VPC, không dùng được nếu khác account hoặc khác region.
DEMO
Chuẩn bị:
IAM user có quyền Admin
AWS CLI bản mới nhất:
https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html
- Session Manager plugin:
IAM role:
Task role: Cho phép ECS exec: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-exec.html (name: ecs-task-role)
Task execution role: AmazonECSTaskExecutionRolePolicy + 1 inline policy cho phép action
logs:createLogsGroup
(name: ecs-tskexec-role)
VPC:
VPC CIDR: 10.0.0.0/23
Subnets:
Public: 10.0.0.0/25 – 10.0.1.0/25
Private: 10.0.0.128/25 – 10.0.1.128/25
Endpoint: com.amazonaws.ap-northeast-1.ssmmessages
EC2 instance (AMZ Linux 2):
- Đặt ở subnet public để làm NAT. Câu lệnh configure NAT:
sysctl -w net.ipv4.ip_forward=1
yum install iptables-services -y
/sbin/iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
service iptables save
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
systemctl start iptables
chkconfig iptables on
- Task definition:
service-connect-nginx.json
{
"family": "service-connect-nginx",
"taskRoleArn": "arn:aws:iam::<account-id>:role/ecs-task-role",
"executionRoleArn": "arn:aws:iam::<account-id>:role/ecs-tskexec-role",
"networkMode": "awsvpc",
"containerDefinitions": [
{
"name": "webserver",
"image": "public.ecr.aws/docker/library/nginx:latest",
"cpu": 100,
"linuxParameters": {
"initProcessEnabled": true
},
"portMappings": [
{
"name": "nginx",
"containerPort": 80,
"protocol": "tcp",
"appProtocol": "http"
}
],
"essential": true,
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/service-connect-nginx",
"awslogs-region": "ap-northeast-1",
"awslogs-create-group": "true",
"awslogs-stream-prefix": "nginx"
}
}
}
],
"cpu": "256",
"memory": "512"
}
- Tạo configure ECS service:
Cho service Client and server: service-connect-nginx-service.json
{
"cluster": "tutorial",
"deploymentConfiguration": {
"maximumPercent": 200,
"minimumHealthyPercent": 0
},
"deploymentController": {
"type": "ECS"
},
"desiredCount": 1,
"enableECSManagedTags": true,
"enableExecuteCommand": true,
"launchType": "FARGATE",
"networkConfiguration": {
"awsvpcConfiguration": {
"assignPublicIp": "ENABLED",
"securityGroups": [
"sg-00edfcb1d60e319e2"
],
"subnets": [
"subnet-06273ad45b21382d3",
"subnet-07a3c7917f66d3145"
]
}
},
"platformVersion": "LATEST",
"propagateTags": "SERVICE",
"serviceName": "service-connect-nginx-service",
"serviceConnectConfiguration": {
"enabled": true,
"services": [
{
"portName": "nginx",
"clientAliases": [
{
"port": 80
}
]
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/service-connect-proxy",
"awslogs-region": "ap-northeast-1",
"awslogs-create-group": "true",
"awslogs-stream-prefix": "service-connect-proxy"
}
}
},
"taskDefinition": "service-connect-nginx"
}
Tools: PowerShell, tool debug lỗi ecs exec:
https://github.com/aws-containers/amazon-ecs-exec-checker
Bắt đầu:
- Register task definition:
aws ecs register-task-definition --cli-input-json file://service-connect-nginx.json
- Register ECS service:
aws ecs create-service --cluster tutorial --enable-execute-command --cli-input-json file://service-connect-nginx-service.json
Đến đây đã có thể exec trực tiếp vào ecs task được run lên để kiểm tra và kiểm tra kết nối bằng 1 con EC2 instance cùng VPC nhưng không nằm trong namespace:
[ec2-user@ip-10-0-0-186 ~]$ curl -v <http://10.0.2.34:80>
* Trying 10.0.2.34:80...
* Connected to 10.0.2.34 (10.0.2.34) port 80 (#0)
> GET / HTTP/1.1
> Host: 10.0.2.34
> User-Agent: curl/7.79.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< server: envoy
< date: Sun, 11 Dec 2022 11:00:05 GMT
< content-type: text/html
< content-length: 615
< last-modified: Wed, 19 Oct 2022 07:56:21 GMT
< etag: "634fada5-267"
< accept-ranges: bytes
< x-envoy-upstream-service-time: 0
<
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="<http://nginx.org/>">nginx.org</a>.<br/>
Commercial support is available at
<a href="<http://nginx.com/>">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
* Connection #0 to host 10.0.2.34 left intact
Đã thấy header envoy thay vì nginx
Xem trong log group:
Có thấy những log liên quan CloudMap và Envoy proxy → đúng như hoạt động của ECS Connect Service.
Test thử thêm trong TH sử dụng client:
- Tạo 1 service client:
aws ecs create-service \\
--cluster tutorial \\
--service-name client \\
--task-definition service-connect-nginx:5 \\
--enable-execute-command \\
--desired-count 1 \\
--launch-type FARGATE \\
--platform-version LATEST \\
--network-configuration "awsvpcConfiguration={subnets=[subnet-07a3c7917f66d3145, subnet-06273ad45b21382d3],securityGroups=[sg-00edfcb1d60e319e2],assignPublicIp=ENABLED}" \\
--service-connect-configuration '{
"enabled": true,
"namespace": "service-connect"
}'
Kiểm tra trên EC2 khi curl đến IP của client:
[ec2-user@ip-10-0-0-40 ~]$ curl -v <http://10.0.1.212:80>
* Trying 10.0.1.212:80...
* Connected to 10.0.1.212 (10.0.1.212) port 80 (#0)
> GET / HTTP/1.1
> Host: 10.0.1.212
> User-Agent: curl/7.79.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: nginx/1.23.3
< Date: Sat, 31 Dec 2022 04:55:11 GMT
< Content-Type: text/html
< Content-Length: 615
< Last-Modified: Tue, 13 Dec 2022 15:53:53 GMT
< Connection: keep-alive
< ETag: "6398a011-267"
< Accept-Ranges: bytes
<
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="<http://nginx.org/>">nginx.org</a>.<br/>
Commercial support is available at
<a href="<http://nginx.com/>">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
* Connection #0 to host 10.0.1.212 left intact
[ec2-user@ip-10-0-0-40 ~]$
Lúc này thì header lại trả về là nginx?!
Exec vào task để kiểm tra:
- Exec vào task của service client & server:
aws ecs execute-command --cluster tutorial --task 66949928226544c28506fc269343e1ae --container webserver --interactive --command "/bin/bash"
Chạy lệnh kiểm tra:
root@ip-10-0-0-169:/# cat /etc/hosts
127.0.0.1 localhost
10.0.0.169 ip-10-0-0-169.ap-northeast-1.compute.internal
127.255.0.1 nginx.service-connect
2600:f0f0:0:0:0:0:0:1 nginx.service-connect
============================
# curl client service's IP:
root@ip-10-0-0-169:/# curl -v <http://10.0.1.212:80>
* Trying 10.0.1.212:80...
* Connected to 10.0.1.212 (10.0.1.212) port 80 (#0)
> GET / HTTP/1.1
> Host: 10.0.1.212
> User-Agent: curl/7.74.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: nginx/1.23.3
< Date: Sat, 31 Dec 2022 04:53:48 GMT
< Content-Type: text/html
< Content-Length: 615
< Last-Modified: Tue, 13 Dec 2022 15:53:53 GMT
< Connection: keep-alive
< ETag: "6398a011-267"
< Accept-Ranges: bytes
<
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="<http://nginx.org/>">nginx.org</a>.<br/>
Commercial support is available at
<a href="<http://nginx.com/>">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
* Connection #0 to host 10.0.1.212 left intact
root@ip-10-0-0-169:/#
================================
root@ip-10-0-0-169:/# curl -v localhost
* Trying 127.0.0.1:80...
* Connected to localhost (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> Host: localhost
> User-Agent: curl/7.74.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: nginx/1.23.3
< Date: Sat, 31 Dec 2022 04:57:54 GMT
< Content-Type: text/html
< Content-Length: 615
< Last-Modified: Tue, 13 Dec 2022 15:53:53 GMT
< Connection: keep-alive
< ETag: "6398a011-267"
< Accept-Ranges: bytes
<
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="<http://nginx.org/>">nginx.org</a>.<br/>
Commercial support is available at
<a href="<http://nginx.com/>">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
* Connection #0 to host localhost left intact
==============
root@ip-10-0-0-169:/# curl -v nginx.service-connect:80
* Trying 127.255.0.1:80...
* Connected to nginx.service-connect (127.255.0.1) port 80 (#0)
> GET / HTTP/1.1
> Host: nginx.service-connect
> User-Agent: curl/7.74.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< server: envoy
< date: Sat, 31 Dec 2022 04:58:47 GMT
< content-type: text/html
< content-length: 615
< last-modified: Tue, 13 Dec 2022 15:53:53 GMT
< etag: "6398a011-267"
< accept-ranges: bytes
< x-envoy-upstream-service-time: 0
<
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="<http://nginx.org/>">nginx.org</a>.<br/>
Commercial support is available at
<a href="<http://nginx.com/>">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
* Connection #0 to host nginx.service-connect left intact
root@ip-10-0-0-169:/#
- Exec vào task của service client only:
aws ecs execute-command --cluster tutorial --task a8dc363d659d4b7281dd5e2398a56e9d --container webserver --interactive --command "/bin/bash"
- Chạy lệnh kiểm tra:
root@ip-10-0-1-212:/# curl -v localhost
* Trying 127.0.0.1:80...
* Connected to localhost (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> Host: localhost
> User-Agent: curl/7.74.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: nginx/1.23.3
< Date: Sat, 31 Dec 2022 04:45:36 GMT
< Content-Type: text/html
< Content-Length: 615
< Last-Modified: Tue, 13 Dec 2022 15:53:53 GMT
< Connection: keep-alive
< ETag: "6398a011-267"
< Accept-Ranges: bytes
<
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="<http://nginx.org/>">nginx.org</a>.<br/>
Commercial support is available at
<a href="<http://nginx.com/>">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
* Connection #0 to host localhost left intact
root@ip-10-0-1-212:/#
===============================
root@ip-10-0-1-212:/# curl -v nginx.service-connect
* Trying 127.255.0.1:80...
* Connected to nginx.service-connect (127.255.0.1) port 80 (#0)
> GET / HTTP/1.1
> Host: nginx.service-connect
> User-Agent: curl/7.74.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< server: envoy
< date: Sat, 31 Dec 2022 04:46:06 GMT
< content-type: text/html
< content-length: 615
< last-modified: Tue, 13 Dec 2022 15:53:53 GMT
< etag: "6398a011-267"
< accept-ranges: bytes
< x-envoy-upstream-service-time: 2
<
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="<http://nginx.org/>">nginx.org</a>.<br/>
Commercial support is available at
<a href="<http://nginx.com/>">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
* Connection #0 to host nginx.service-connect left intact
root@ip-10-0-1-212:/#
========================
root@ip-10-0-1-212:/# cat /etc/hosts
127.0.0.1 localhost
10.0.1.212 ip-10-0-1-212.ap-northeast-1.compute.internal
127.255.0.1 nginx.service-connect
2600:f0f0:0:0:0:0:0:1 nginx.service-connect
root@ip-10-0-1-212:/#
Nếu đứng ở EC2 không cùng namespace, thì sẽ chỉ connect được bằng IP, không connect được bằng dns ⇒ đây là sự khác biệt so với sử dụng ECS Service Discovery. Với Service Discovery thì sẽ có 1 private hosted zone được tạo ra, còn ECS Service connect sẽ không có private hosted zone nào.
Sau một hồi connect, kiểm tra được traffic health của các service:
- Traffic health của Client and Server:
- Traffic health của Client Only:
Reference:
Tutorial: Using Service Connect in Fargate with the AWS CLI
RDS Blue Green Deployment
Support MySQL và mariadb
Enable blue/green deployment sẽ khởi chạy một môi trường giống với môi trường blue hiện tại của bạn. Giữa 2 môi trường blue – green sẽ có logic replication với nhau để đảm bảo không thất thoát dữ liệu. Những thay đổi mới trên rds đóng vai trò green sẽ không ảnh hưởng đến rds blue.
Được sử dụng khi bạn muốn bảo trì hệ điều hành, apply các bản vá, thay đổi tham số và schema,…
Khi bạn đã quyết định rằng có thể chuyển từ blue sang green, bạn sẽ switch over 2 rds cluster. Chỉ mất khoảng 1 phút để cho việc switch này hoàn tất.
Trong quá trình chuyển đổi, việc ghi sẽ bị chặn trên cả blue và green để đảm bảo không mất dữ liệu. Sau đó, lưu lượng truy cập sẽ được chuyển từ môi trường cũ sang mới.
Lưu ý:
Không support type db.t3.small
Chưa support cho RDS proxy
Chưa support triển khai bằng CloudFormation
Sau khi switch thì blue sẽ không tự động bị xóa, bạn sẽ cần chú ý xóa để tránh bị charge tiền
Demo:
https://www.youtube.com/watch?v=EvucgzbeW98
AWS Elastic Disaster Recovery Automated Failback
Failover: chuyển từ môi trường chính → backup
Failback: chuyển từ môi trường backup → môi trường chính
Hiện tại Elastic Disaster Recovery đã support failback cross AZ và cross region, đặc biệt là cả quy trình failover và failback hiện đều có thể được bắt đầu một cách thuận tiện từ AWS Management Console, giúp đơn giản hóa việc failback các phiên bản EC2 và giảm thời gian cũng như mức độ nghiêm trọng của các ảnh hưởng tới app khi có sư cố.
Với những KH muốn tùy chỉnh các bước tạo quy trình, DRS cung cấp 2 API mới:
StartReplication
StopReplication
ReverseReplication
AWS Backup – New Features
Ở lần cập nhật này, AWS bổ sung thêm một số features mới cho AWS backup như:
Hỗ trợ backup S3
Hỗ trợ VMware workload
Bảo vệ và restore CFn stacks
Hỗ trợ RedShift
Ủy quyền backup admin trong org
Các thay đổi này bạn có thể xem chi tiết trong tài liệu của AWS.
Amazon CloudWatch Internet Monitor
Tính năng này cung cấp cho bạn khả năng monitor cách các sự cố internet ảnh hưởng đến hiệu suất và tính khả dụng của ứng dụng của bạn.
Hiện tại đang là preview, đã available ở 20 regions
Điểm yếu là CloudFormation không được hỗ trợ tại thời điểm preview, nhưng có thông báo rằng sẽ được bổ sung trong tương lai gần
Trong thời gian preview thì miễn phí nhưng bạn sẽ phải trả phí cho các cloudwatch metrics và log
Demo bạn có thể xem ở đây:
https://www.youtube.com/watch?v=-zUj8ZuEAFk
Amazon CloudWatch Logs Data Protection
Cho phép masking các thông tin nhạy cảm trong log data. Tính năng này có thể bật trên các log group đã có sẵn.
Bạn cũng có thể gửi kết quả audit tới CloudWatch Logs, Kinesis data firehose và S3.
Nếu bạn được ủy quyền cho hành động logs:Unmask, thì bạn có thể bỏ mask và xem các dữ liệu gốc
Bạn có thể able masking bằng console hoặc CLI
Demo:
Chọn pattern là Name, Address, AWSSecretKey, IpAddress, tạo log stream và:
Tạo log event:
〒812-0011 2-20-1 Hakata Ekimae, Hakata-ku, Fukuoka-shi, Fukuoka (Address of Classmethod Fukuoka office)
1600 Pennsylvania Avenue NW, Washington, DC 20500 USA (It seems to be the address of the White House.)
0.0.0.0/0
Yen Trinh Thi Hai
Amazon S3 Multi-Region Access Points Failover Controls
Multi-region access point: global endpoint, sử dụng AWS Global Accelerator để route traffic đến bucket gần nhất, tuy nhiên không có failover control.
Tính năng mới này cho phép control quá trình failover và failback một cách chủ động, bằng cách gán cho 1 region nào đó là active hay passive. Các bucket ở region active sẽ nhận traffic từ Multi-region access point, còn passive thì không nhận.
Bạn có thể sử dụng tính năng này để chuyển traffic từ active region tới passive region trong khoảng 2 phút để test khả năng phục hồi của app hoặc triển khai các mô phỏng disaster recovery.
Amazon Route 53 ARC – Zonal Shift
Zonal shift được sử dụng để block trafic tới 1 zone nhất định nào đó khi AZ fails hoặc có latency cao. Khi bạn bắt đầu 1 zonal shift cho 1 AZ, load balancer health check cho AZ đó sẽ set là unhealthy và Route 53 sẽ bỏ IP của node ở AZ đó ra khỏi DNS. Bạn có thể set thời gian expire cho zonal shift hoặc cancel nó khi AZ healthy, để đưa các traffic về trạng thái bình thường.
Maxium expire time cho zonal shift là 72 giờ.
Lưu ý rằng để sử dụng zonal shift thì ALB và NLB phải turn off cross zone load balacing.
Bạn không cần phải trả phí cho zonal shift.
Lambda SnapStart
Khi bạn enable Lambda SnapStart, function của bạn sẽ cần chạy 1 lần trước khi tính năng có hiệu lực. Sau khi init lần đầu tiên, Lambda Snapstart sẽ tạo ra 1 snapshot cho function của bạn trước khi quá trình invoke bắt đầu, và lưu trữ snapshot này trong 1 multi-tier cache, điều này cho phép các lần init tiếp theo của Lambda container nhanh hơn.
Snapshot capacity được powered bởi công nghệ MicroVM Snapshot. Lambda SnapStart có thể giúp cho Lambda function của bạn chạy nhanh hơn tới 10 lần.
SnapStart và các giá trị unique:
Có một trick mà nhiều lập trình viên trước đây sử dụng là thực hiện generate các giá trị bên ngoài hàm handler (khi gọi bên trong handler có thể sẽ khiến phát sinh thêm chi phí runtime cho Lambda function)
Tuy nhiên khi sử dụng Lambda SnapStart, các nội dung unique được included trong snapshots trong quá trình init sẽ được sử dụng lại trong nhiều lần thực thi, và điều này sẽ khiến cho nó không còn unique nữa.
Do đó, để giữ được tính chất unique thì bạn sẽ cần thay đổi để nó được generate sau quá trình init (Ví dụ như chuyển các giá trị unique vào trong hàm handler). Các giá trị unique ở đây có thể là IDs, unique secrets,…
Lambda cung cấp SnapStart scanning tool giúp bạn có thể check các categories cụ thể trong code mà có thể là các giá trị unique, để bạn có thể thực hiện các thay đổi nếu cần thiết. SnapStart scanning tool là một SpotBugs plugin mã nguồn mở, sẽ chạy các static analysis theo 1 set các rule và đưa ra báo cáo về các “potential SnapStart bugs”.
Ví dụ: Hàm Lambda function sau sẽ tạo ra 1 unique log stream cho mỗi môi trường thực thi trong quá trìn init. Khi enable SnapStart, thì giá trị unique này sẽ được sử dụng lại trong các môi trường thực thi:
public class LambdaUsingUUID {
private AWSLogsClient logs;
private final UUID sandboxId;
public LambdaUsingUUID() {
sandboxId = UUID.randomUUID(); // <-- unique content created
logs = new AWSLogsClient();
}
@Override
public String handleRequest(Map<String,String> event, Context context) {
CreateLogStreamRequest request = new CreateLogStreamRequest(
"myLogGroup", sandboxId + ".log9.txt");
logs.createLogStream(request);
return "Hello world!";
}
}
Khi bạn chạy scanning tool cho đoạn code trên, thông báo sau dạng như sau sẽ được trả về cho bạn:
H C SNAP_START: Detected a potential SnapStart bug in Lambda function initialization code. At LambdaUsingUUID.java: [line 7]
Một cách để bạn có thể fix các case như này là chuyển đoạn code tạo ra giá trị unique ID vào bên trong hàm handler của function.
Tuy nhiên, nếu bạn vẫn cứ muốn tạo ra giá trị unique ngay tại giai đoạn init của Lambda function, thì Lambda support 2 loại runtime hooks mới:
https://docs.aws.amazon.com/lambda/latest/dg/snapstart-runtime-hooks.html
Các runtime hooks này là một phần của dự án open-source Coordinated Restore at Checkpoint (CRaC).
Bạn có thể sự dụng the beforeCheckpoint hook để chạy code trước khi một snapshot được tạo ra, và sử dụng afterRestore hook để chạy code sau khi quá trình restore từ snapshot diễn ra. Ví dụ về các sử dụng CRaC, tham khảo trong link sau:
https://github.com/CRaC/docs/blob/master/STEP-BY-STEP.md
Network connection:
Nếu bạn attach một connection tới 1 external service trong quá trình init, sẽ không có gì đảm bảo rằng connection đó sẽ được giữ cho đến khi function được chạy. Hã xem xét kết nối lại ở trong hàm handler hoặc sử dụng afterRestore runtime hook.
Volatile data
Các kiểm tra xem file đã được tạo ra hay đã được download trong quá trình init sẽ bị outdated khi hàm thực thi.
Tính toán thời gian startup và thời gian billed
Để giúp bạn có thể tính toán thời gian startup và billed với SnapStart, AWS cập nhật metrics ở CloudWatch include thời gian cần thiết để restore từ 1 snapshot (Restore Duration),và thời gian để init function (Init Duration) sẽ được report riêng.
Restore Duration bao gồm khoảng thời gian Lambda cần sử dụng để restore từ 1 snapshot, load runtime (JVM) và chạy các afterRestore hooks. Bạn sẽ không phải trả phí cho khoảng thời gian restore từ snapshot. Tuy nhiên, khoảng thời gian load JVM, chạy afterRestore hook thì sẽ được tính vào khoảng thời gian billed của Lambda function.
SnapStart khác với provisioned concurrency như nào?
Có một tính năng khác cũng cho mục đích giảm thời gian của quá trình Init là Provisioned Concurrency:
https://docs.aws.amazon.com/lambda/latest/dg/provisioned-concurrency.html
Tính năng này được ra đời tại Re:Invent khoảng 3 năm trước.
Tính năng này cho phép bạn tạo ra pool một số lượng nhất định các môi trường execution của Lambda function đã thực thi quá phase Init. Do đó, nếu requests có thể được handle trong pool này thì quá trình Init sẽ không xảy ra.
SnapStart và Provisioned Concurency không thể sử dụng chung được với nhau!
Hãy xem xét sử dụng SnapStart trước, sau đó xem xét sử dụng Provisioned Concurrecy nếu như bạn phải đáp ứng các yêu cầu về latency một các nghiêm ngặt, vì SnapStart có thể sử dụng miễn phí, còn Provisioned Concurrency thì sẽ charge hourly fee theo số lượng các pooled execution environments.
SnapStart thì sẽ tạo ra Restore phase thay vì Init phase, nhưng Provisioned Concurrency thì sẽ vào thẳng Invoke phase mà không có Restore phase (cũng vì lý do này mà Provisioned Concurrency chạy nhanh hơn). Tuy nhiên, chỉ khi request có thể được handle trong pool thì mới chạy nhanh hơn. Nếu có nhiều request hơn, thì quá trình Init vẫn diễn ra.
Thử dùng SnapStart
Chuẩn bị
Sử dụng sam inti để tạo ra Java 11 template một cách nhanh chóng:
$ sam init --runtime java11
Which template source would you like to use?
1 - AWS Quick Start Templates
2 - Custom Template Location
Choice: 1
Choose an AWS Quick Start application template
1 - Hello World Example
2 - Infrastructure event management
3 - Multi-step workflow
Template: 1
Based on your selections, the only Package type available is Zip.
We will proceed to selecting the Package type as Zip.
Which dependency manager would you like to use?
1 - gradle
2 - maven
Dependency manager: 2
Would you like to enable X-Ray tracing on the function(s) in your application? [y/N]: n
Project name [sam-app]: SnapStart
Cloning from https://github.com/aws/aws-sam-cli-app-templates (process may take a moment)
-----------------------
Generating application:
-----------------------
Name: SnapStart
Runtime: java11
Architectures: x86_64
Dependency Manager: maven
Application Template: hello-world
Output Directory: .
Next steps can be found in the README file at ./SnapStart/README.md
Commands you can use next
=========================
[*] Create pipeline: cd SnapStart && sam pipeline init --bootstrap
[*] Validate SAM template: cd SnapStart && sam validate
[*] Test Function in the Cloud: cd SnapStart && sam sync --stack-name {stack-name} --watch
Chỉnh sử function code, add thêm 2s sleep:
public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEvent input, final Context context) {
Map<String, String> headers = new HashMap<>();
headers.put("Content-Type", "application/json");
headers.put("X-Custom-Header", "application/json");
APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent()
.withHeaders(headers);
try {
final String pageContents = this.getPageContents("https://checkip.amazonaws.com");
String output = String.format("{ \"message\": \"hello world\", \"location\": \"%s\" }", pageContents);
// edit
Thread.sleep(2000);
return response
.withStatusCode(200)
.withBody(output);
} catch (Exception e) {
return response
.withBody("{}")
.withStatusCode(500);
}
}
Giờ đây, một Lệnh gọi Lambda cần chưa đến 2 giây. Điều này sẽ dễ dàng tăng tốc concurrency và cold start rate của Lambda vì phản hồi sẽ không được trả về ngay lập tức.
Chính sửa SAM template
/normal : deploy Lambda mà không enable SnapStart
/snap-start: Có enable SnapStart.
Memory: 128MB
Nếu memory được phân bổ nhỏ, thì CPU power sẽ thấp, do đó quá trình Init sẽ tốn nhiều thời gian.
Lưu ý thêm rằng Lambda Lambda mà bạn enable SnapStart sẽ phải publish với AutoPublishAlias.
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Globals:
Function:
Timeout: 40
MemorySize: 1024
Resources:
SnapStartFunc:
Type: AWS::Serverless::Function
Properties:
CodeUri: HelloWorldFunction
Handler: helloworld.App::handleRequest
Runtime: java11
AutoPublishAlias: SnapStart
Events:
HelloWorld:
Type: Api
Properties:
Path: /snap-start
Method: get
SnapStart:
ApplyOn: PublishedVersions
NormalFunc:
Type: AWS::Serverless::Function
Properties:
CodeUri: HelloWorldFunction
Handler: helloworld.App::handleRequest
Runtime: java11
Events:
HelloWorld:
Type: Api
Properties:
Path: /normal
Method: get
Outputs:
HelloWorldApi:
Description: "API Gateway endpoint URL for Prod stage for Hello World function"
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
Build & Deploy
$ sam build
Your template contains a resource with logical ID "ServerlessRestApi", which is a reserved logical ID in AWS SAM. It could result in unexpected behaviors and is not recommended.
Building codeuri: /Users/...略/HelloWorldFunction runtime: java11 metadata: {} architecture: x86_64 functions: SnapStartFunc, NormalFunc
Running JavaMavenWorkflow:CopySource
Running JavaMavenWorkflow:MavenBuild
Running JavaMavenWorkflow:MavenCopyDependency
Running JavaMavenWorkflow:MavenCopyArtifacts
Build Succeeded
Built Artifacts : .aws-sam/build
Built Template : .aws-sam/build/template.yaml
Commands you can use next
=========================
[*] Validate SAM template: sam validate
[*] Invoke Function: sam local invoke
[*] Test Function in the Cloud: sam sync --stack-name {{stack-name}} --watch
[*] Deploy: sam deploy --guided
sam deploy --guided
Configuring SAM deploy
======================
Looking for config file [samconfig.toml] : Not found
Setting default arguments for 'sam deploy'
=========================================
Stack Name [sam-app]: snap-start-test
AWS Region [ap-northeast-1]: us-east-1
...
Successfully created/updated stack - snap-start-test in us-east-1
Thử access song song Lambda
Thực hiện chạy câu lệnh ab với API gateway.
Câu lệnh dưới đây được thực thi và một 100 requests được tạo ra trong 100 parallels. Có thể hình dung như là client đang access 100 units 1 lần:
ab -c 100 -n 100 <API endpoint>
Thực hiện điều này với cả 2 enpoint: bật SnapStart và không bật.
Đầu tiên, check với Lambda function không được bật SnapStart:
END RequestId: 4bce3c4e-79ef-4b76-a6f8-e0cdc492fbcc
REPORT RequestId: 4bce3c4e-79ef-4b76-a6f8-e0cdc492fbcc Duration: 21834.31 ms Billed Duration: 21835 ms Memory Size: 128 MB Max Memory Used: 115 MB Init Duration: 416.50 ms
...
Init Duration được trả về, điều này có nghĩa là cold start với Init phase đang diễn ra.
Tiếp theo, thử với Lambda function có bật SnapStart:
END RequestId: b429035e-237d-4e7e-823e-20b5922c2074
REPORT RequestId: b429035e-237d-4e7e-823e-20b5922c2074 Duration: 22980.33 ms Billed Duration: 23134 ms Memory Size: 128 MB Max Memory Used: 110 MB Restore Duration: 229.35 ms
Không phải là Init Duration mà là Restore Duration, điều này có nghĩa là môi trường thực thi của Lambda được restore từ snapshot.
Kiếm tra CloudWatch Log Insights
filter @type = "REPORT"
| parse @log /\d+:\/aws\/lambda\/(?<function>.*)/
| parse @message /Restore Duration: (?<restoreDuration>.*) ms/
| stats
count(*) as invocations,
min(coalesce(@initDuration,0)+coalesce(restoreDuration,0)) as min,
max(coalesce(@initDuration,0)+coalesce(restoreDuration,0)) as max,
avg(coalesce(@initDuration,0)+coalesce(restoreDuration,0)) as avg,
pct(coalesce(@initDuration,0)+coalesce(restoreDuration,0), 50) as p50,
pct(coalesce(@initDuration,0)+coalesce(restoreDuration,0), 90) as p90,
pct(coalesce(@initDuration,0)+coalesce(restoreDuration,0), 99) as p99
group by function, (ispresent(@initDuration) or ispresent(restoreDuration)) as coldstart
| sort by coldstart desc
Kết quả trả về như sau:
SnapStart | number | minimum value | Maximum value | average | Median | 90% tile | 99% tile |
invalid | 100 | 412.54 | 687.95 | 505.0421 | 500.6426 | 527.8785 | 611.4252 |
valid | 100 | 182.31 | 377.94 | 252.0972 | 250.6953 | 294.7588 | 345.5295 |
Bạn có thể thấy rằng RestoreDuration cho ra một kết quả tốt hơn InitDuration.