cloudFun
Hãy xem xét một Cloud Function được tiếp xúc với Internet.
Khi được triển khai, có thể gọi hàm đó và logic thực hiện sẽ được thực thi. Bây giờ hãy giả sử rằng hàm muốn gọi một dịch vụ tiếp xúc REST được triển khai như một container được lưu trữ trong Kubernetes. Theo sơ đồ, cần kết thúc với:
Điều này cho thấy ứng dụng khách gọi Cloud Function qua Internet. Sau đó, Cloud Function gọi dịch vụ đích (MyService) được lưu trữ trong tập hợp các pod được sao chép. Các pod được thể hiện như một dịch vụ Kubernetes. Dịch vụ Kubernetes đó chỉ nổi lên bên trong mạng nội bộ GCP VPC. Rõ ràng, dịch vụ không được tiếp xúc với Internet và do đó diện tích bề mặt tấn công của dịch vụ bị giảm.
Câu chuyện này nghe có vẻ hợp lý nhưng cũng có một vài câu đố cần giải quyết. Đầu tiên là khái niệm về định nghĩa dịch vụ
•
•
•
•
Trong số này,
Mặc dù nó hoạt động theo chức năng, mọi người đã tiếp xúc
Một dịch vụ ví dụ có thể là:
Sau khi được xác định, sẽ có một bộ cân bằng tải mà khi được gọi, nó sẽ định tuyến lưu lượng đến các pod. Địa chỉ IP ổn định của bộ cân bằng tải sẽ có mặt trên mạng VPC nội bộ. Dịch vụ sẽ không tiếp xúc trên Internet.
Ở dạng sơ đồ, có:
Vẫn còn một vấn đề. Cloud Function là một thành phần không có máy chủ. Khi máy khách gọi Cloud Function, Cloud Function chạy trong môi trường do Google quản lý tách biệt và khác biệt với bất kỳ tài nguyên nào khác đã xác định trong dự án GCP. Điều này bao gồm quyền truy cập vào mạng VPC. Theo mặc định, Cloud Function đơn giản là không thể truy cập mạng đó. Ngay cả khi nó cố gắng đạt được IP ổn định của dịch vụ cân bằng tải, vẫn không có đường dẫn đến nó. Rất may, có một giải pháp. Có một thành phần của mạng VPC được gọi là truy cập VPC. Thành phần này cho phép các sản phẩm GCP không có máy chủ, chẳng hạn như Cloud Function, được liên kết với mạng VPC cho phép yêu cầu truy cập vào địa chỉ IP trên mạng đó thành công.
Bây giờ có thể thực hiện cuộc gọi REST từ Cloud Function đến dịch vụ đích và nó sẽ hoạt động như mong muốn. Một điều chỉnh cuối cùng cần thực hiện là đăng ký một mục nhập DNS cho IP ổn định để có thể code yêu cầu đến một thực thể DNS có tên logic thay vì địa chỉ IP mờ. Private Zone sẽ được sử dụng trong Cloud DNS cho hiệu ứng đó. Kết quả sẽ như mong muốn và được hiển thị như trong sơ đồ ban đầu trong loạt bài này.
Điều tiếp theo là từng bước thực hiện để tạo một dịch vụ Kubernetes mẫu và gọi nó từ Cloud Function như được mô tả trước đây.
1. Tạo một cluster
Sử dụng Cloud Console để tạo một cluster được gọi là my-cluster.
Cuối cùng bấm create. Nó sẽ mất một vài phút để tạo ra cluster .
2. Tạo một ứng dụng
Cần một ứng dụng đơn giản để chạy trong nhóm pod.
Dưới đây là nội dung tương ứng của Dockerfile được sử dụng để xây dựng docker image:
3. Tạo một docker image và đưa nó vào sổ đăng ký (registry)
4. Tạo một Kubernetes ReplicaSet
Tạo một tệp có tên là
Áp dụng cho cluster Kubernetes:
Trong Console, hãy truy cập Kubernetes Engine -> Workloads và chờ trạng thái của workload my-replica-set chuyển thành OK.
Tại thời điểm này, các pod đang chạy.
5. Tạo một dịch vụ
Tạo một dịch vụ với loại LoadBalancer đang sử dụng bộ cân bằng tải TCP/ UDP nội bộ. Tạo một tệp có tên là
Áp dụng cho cluster Kubernetes:
Trong Console, hãy truy cập Kubernetes Engine -> Services & Ingress. Đợi dịch vụ
Hãy lưu ý địa chỉ IP. Đây là IP trên mạng VPC nơi có thể kết nối đến Cân bằng tải.
6. Tạo một mục DNS
Trong Console, truy cập Network services -> Cloud DNS. Nhấp vào
Đặt loại Zone là Private.
Nhấp vào
Tại thời điểm này, sẽ map từ
7. Xác định truy cập VPC không có máy chủ.
Truy cập VPC network -> Serverless VPC access. Nhấp vào CREATE CONNECTOR.
8. Tạo Cloud Function sẽ gọi dịch vụ REST.
Đây là mã JavaScript sẽ được thực thi khi thực hiện cuộc gọi đến Cloud Function. Trọng tâm của minh họa là yêu cầu REST gọi dịch vụ Kubernetes:
Trong định nghĩa Function, trong các tùy chọn nâng cao trong Networking, hãy tham khảo trình kết nối VPC:
9. Kiểm tra chức năng
Bây giờ có thể gọi Cloud Function và thấy rằng dịch vụ lưu trữ Kubernetes nội bộ đang được gọi.
Nguồn: https://medium.com/
Khi được triển khai, có thể gọi hàm đó và logic thực hiện sẽ được thực thi. Bây giờ hãy giả sử rằng hàm muốn gọi một dịch vụ tiếp xúc REST được triển khai như một container được lưu trữ trong Kubernetes. Theo sơ đồ, cần kết thúc với:
Điều này cho thấy ứng dụng khách gọi Cloud Function qua Internet. Sau đó, Cloud Function gọi dịch vụ đích (MyService) được lưu trữ trong tập hợp các pod được sao chép. Các pod được thể hiện như một dịch vụ Kubernetes. Dịch vụ Kubernetes đó chỉ nổi lên bên trong mạng nội bộ GCP VPC. Rõ ràng, dịch vụ không được tiếp xúc với Internet và do đó diện tích bề mặt tấn công của dịch vụ bị giảm.
Câu chuyện này nghe có vẻ hợp lý nhưng cũng có một vài câu đố cần giải quyết. Đầu tiên là khái niệm về định nghĩa dịch vụ
MyService
. Khi xác định dịch vụ Kubernetes, có các lựa chọn về cách dịch vụ đó sẽ được hiển thị. Cụ thể, có thuộc tính spec.type
có thể là một trong:•
ClusterIP
- Mặc định. Dịch vụ này được cung cấp trong mạng cluster.•
NodePort
- Dịch vụ có mặt trên mỗi node máy chủ cục bộ tại một cổng nhất định.•
LoadBalancer
- Tiếp xúc thông qua bộ cân bằng tải của nhà cung cấp đám mây. •
ExternalName
- Map đến một tên bên ngoài.Trong số này,
LoadBalancer
dường như là sự lựa chọn rõ ràng. Tuy nhiên, nếu sử dụng nó, cài đặt mặc định là dịch vụ được hiển thị với IP Internet ổn định trông giống như sau:Mặc dù nó hoạt động theo chức năng, mọi người đã tiếp xúc
MyService
qua Internet và tăng diện tích bề mặt tấn công. Giải pháp là sử dụng khả năng cụ thể của GCP do GKE cung cấp, tạo ra bộ cân bằng tải chỉ tiếp xúc với mạng VPC nội bộ GCP. Điều này dẫn đến sự cân bằng tải lớp TCP / UDP bằng cách hiển thị dịch vụ với địa chỉ IP ổn định VPC. Tính năng này được bật bằng cách thêm mục nhập metadata.annotations
trong mô tả dịch vụ có tên là cloud.google.com/load-balancer-type
với giá trị Internal
.Một dịch vụ ví dụ có thể là:
Mã:
apiVersion: v1
kind: Service
metadata:
name: myservice
annotations:
cloud.google.com/load-balancer-type: "Internal"
labels:
app: myservice
spec:
type: LoadBalancer
selector:
app: myservice
ports:
- port: 80
targetPort: 8080
protocol: TCP
Ở dạng sơ đồ, có:
Vẫn còn một vấn đề. Cloud Function là một thành phần không có máy chủ. Khi máy khách gọi Cloud Function, Cloud Function chạy trong môi trường do Google quản lý tách biệt và khác biệt với bất kỳ tài nguyên nào khác đã xác định trong dự án GCP. Điều này bao gồm quyền truy cập vào mạng VPC. Theo mặc định, Cloud Function đơn giản là không thể truy cập mạng đó. Ngay cả khi nó cố gắng đạt được IP ổn định của dịch vụ cân bằng tải, vẫn không có đường dẫn đến nó. Rất may, có một giải pháp. Có một thành phần của mạng VPC được gọi là truy cập VPC. Thành phần này cho phép các sản phẩm GCP không có máy chủ, chẳng hạn như Cloud Function, được liên kết với mạng VPC cho phép yêu cầu truy cập vào địa chỉ IP trên mạng đó thành công.
Bây giờ có thể thực hiện cuộc gọi REST từ Cloud Function đến dịch vụ đích và nó sẽ hoạt động như mong muốn. Một điều chỉnh cuối cùng cần thực hiện là đăng ký một mục nhập DNS cho IP ổn định để có thể code yêu cầu đến một thực thể DNS có tên logic thay vì địa chỉ IP mờ. Private Zone sẽ được sử dụng trong Cloud DNS cho hiệu ứng đó. Kết quả sẽ như mong muốn và được hiển thị như trong sơ đồ ban đầu trong loạt bài này.
Điều tiếp theo là từng bước thực hiện để tạo một dịch vụ Kubernetes mẫu và gọi nó từ Cloud Function như được mô tả trước đây.
1. Tạo một cluster
Sử dụng Cloud Console để tạo một cluster được gọi là my-cluster.
Cuối cùng bấm create. Nó sẽ mất một vài phút để tạo ra cluster .
2. Tạo một ứng dụng
Cần một ứng dụng đơn giản để chạy trong nhóm pod.
Mã:
const http = require('http');
const os = require('os');
const handler = function(request, response) {
response.writeHead(200);
response.end("You've hit " + os.hostname() + "\n");
};
var www = http.createServer(handler);
www.listen(8080);
Mã:
FROM node:7
ADD app.js /app.js
ENTRYPOINT ["node", "app.js"]
Mã:
gcloud container clusters get-credentials my-cluster --zone us-central1-a
docker build -t gcr.io/[PROJECT]/my-image
docker push gcr.io/[PROJECT]/my-image
Tạo một tệp có tên là
replica-set.yaml
với nội dung sau
Mã:
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: my-replica-set
labels:
app: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: gcr.io/[PROJECT]/my-image
Mã:
kubectl apply -f replica-set.yaml
Tại thời điểm này, các pod đang chạy.
5. Tạo một dịch vụ
Tạo một dịch vụ với loại LoadBalancer đang sử dụng bộ cân bằng tải TCP/ UDP nội bộ. Tạo một tệp có tên là
service.yaml
có chứa:
Mã:
apiVersion: v1
kind: Service
metadata:
name: my-service
annotations:
cloud.google.com/load-balancer-type: "Internal"
labels:
app: my-service
spec:
type: LoadBalancer
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
protocol: TCP
Mã:
kubectl apply -f service.yaml
my-service
đạt trạng thái OK
.Hãy lưu ý địa chỉ IP. Đây là IP trên mạng VPC nơi có thể kết nối đến Cân bằng tải.
6. Tạo một mục DNS
Trong Console, truy cập Network services -> Cloud DNS. Nhấp vào
Create zone
.Đặt loại Zone là Private.
Nhấp vào
Add record set
.Tại thời điểm này, sẽ map từ
myservice.mycompany.internal
đến LoadBalancer.7. Xác định truy cập VPC không có máy chủ.
Truy cập VPC network -> Serverless VPC access. Nhấp vào CREATE CONNECTOR.
8. Tạo Cloud Function sẽ gọi dịch vụ REST.
Đây là mã JavaScript sẽ được thực thi khi thực hiện cuộc gọi đến Cloud Function. Trọng tâm của minh họa là yêu cầu REST gọi dịch vụ Kubernetes:
Mã:
exports.helloWorld = (req, res) => {
const request = require('request');
request('http://myservice.mycompany.internal',
(err, resS, body) => {
let message = "Hello from Cloud Function: " + body;
res.status(200).send(message);
});
};
package.json
nên chứa:
Mã:
{
"name": "sample-http",
"version": "0.0.1",
"dependencies": {
"request": "latest"
}
}
9. Kiểm tra chức năng
Bây giờ có thể gọi Cloud Function và thấy rằng dịch vụ lưu trữ Kubernetes nội bộ đang được gọi.
Nguồn: https://medium.com/