베하 ~~! 안녕하세요 엄..팀입니다.
이번 포스팅 주제에서는 GKE Maintenance에 대한 이벤트를 Slack으로 알림을 보내는 구성을 실습합니다.
개요
GKE + Pub/Sub + Cloud Functions + (Cloud Build) 를 이용한 알림 설정
- GKE : Publisher
- Slack Webhook : Subscriber
1. Create Slack Application
Slack 알림을 설정하려면 Slack 애플리케이션을 만들고, 이 애플리케이션에 대한 수신 웹훅을 활성화한 다음 Slack 작업공간에 애플리케이션을 설치해야 합니다.
Slack 애플리케이션 만들기
- 이메일로 등록하거나 작업공간 관리자가 보낸 초대를 사용하여 Slack 작업공간에 가입합니다.
- 참고: Slack 작업공간 관리자가 아닌 경우 작업공간 관리자의 승인을 받아야 앱이 작업공간에 배포됩니다.
- 작업공간 이름과 Slack 계정 사용자 인증 정보를 사용하여 Slack에 로그인합니다.
- 새 Slack 앱을 만듭니다.
- Create an app(앱 만들기) 대화상자에서 From scratch(처음부터)를 클릭합니다.
- App Name(앱 이름)을 지정하고 Slack 작업공간을 선택합니다.
- Create App을 클릭합니다.
- Add features and functionality(특징 및 기능 추가)에서 Incoming Webhooks(수신 웹훅)를 클릭합니다.
- Activate Incoming Webhooks(수신 웹훅 활성화) 전환 버튼을 클릭합니다.
- Webhook URLs for Your Workspace(작업공간의 웹훅 URL) 섹션에서 Add New Webhook to Workspace(작업공간에 새 웹훅 추가)를 클릭합니다.
- 승인 페이지가 열리면 알림을 수신할 채널을 선택합니다.
- 허용을 클릭합니다.
- Slack 애플리케이션의 웹훅이 Webhook URLs for Your Workspace(작업공간의 웹훅 URL) 섹션에 표시됩니다. 나중을 위해 이 URL을 저장합니다.
2. 기존 클러스터에서 클러스터 알림 사용 설정
SecurityBulletinEvent
GKE에서 클러스터 구성 또는 버전과 직접 연관되는 보안 게시판이 실행될 때 GKE는 SecurityBulletinEvent 알림을 전송하여, 취약점, 영향, 수행 가능한 조치에 대한 정보를 제공합니다.
UpgradeAvailableEvent
출시 채널에서 새 버전을 사용할 수 있게 되면 GKE는 해당 출시 채널의 클러스터에 UpgradeAvailableEvent 알림을 보내 새 버전을 사용할 수 있음을 클러스터에 알립니다.
UpgradeEvent
사용자 또는 GKE가 업그레이드를 시작하면 GKE가 UpgradeEvent 알림을 전송하여 업그레이드가 시작되었음을 알립니다.
# example
gcloud container clusters update CLUSTER_NAME \\
--region=COMPUTE_REGION \\
--notification-config=pubsub=ENABLED,pubsub-topic=projects/PROJECT_ID/topics/TOPIC_NAME,filter=NOTIFICATION_TYPE
# actually executed
gcloud container clusters update bespin-d-service-gke-service-ans3-001 \\
--region=asia-northeast3 \\
--notification-config=pubsub=ENABLED,pubsub-topic=projects/bespin-service/topics/bespin-d-service-pst-noti,filter=UpgradeAvailableEvent|UpgradeEvent|SecurityBulletinEvent
3. 코드 작성
- 소스 코드는 수정할 부분이 없습니다.
- Cloud Functions 배포시에 전달하는 환경변수 값(slack webhook url)을 코드에서 읽기 때문입니다.
- 환경구성
mkdir ~/gke_slack && cd $_
- index.js
const { IncomingWebhook } = require('@slack/webhook');
const url = process.env.SLACK_WEBHOOK;
const webhook = new IncomingWebhook(url);
// Optionally filter what notification types to forward to Slack.
// If empty, all types will be allowed.
const allowedTypeURLs = [];
// slackNotifier is the main function called by Cloud Functions
module.exports.slackNotifier = (pubSubEvent, context) => {
const data = decode(pubSubEvent.data);
// Send message to Slack.
if (isAllowedType(pubSubEvent.attributes)) {
const message = createSlackMessage(data, pubSubEvent.attributes);
webhook.send(message);
}
};
// decode decodes a pubsub event message from base64.
const decode = (data) => {
return Buffer.from(data, 'base64').toString();
}
// isAllowedType can be used to filter out messages that don't match the
// allowed type URLs. If allowedTypeURLs is empty, it allows all types.
const isAllowedType = (attributes) => {
if (allowedTypeURLs.length == 0) {
return true;
}
for (var x in allowedTypeURLs) {
if (attributes['type_url'] == allowedTypeURLs[x]) {
return true;
}
}
return false;
}
// createSlackMessage creates a message from a data object.
const createSlackMessage = (data, attributes) => {
// Write the message data and attributes.
text = `${data}`
for (var key in attributes) {
if (attributes.hasOwnProperty(key)) {
text = text + `\\n\\t\\`${key}: ${attributes[key]}\\``
}
}
const message = {
text: text,
mrkdwn: true,
};
return message;
}
- Package.json
{
"name": "gke-slack",
"version": "0.0.1",
"description": "Slack integration for GKE, using Cloud Functions",
"main": "index.js",
"dependencies": {
"@slack/webhook": "5.0.1"
}
}
4. Cloud Functions Deploy
- 해당 소스코드가 있는 위치에서 실행합니다
# sample (nodejs10 will be deprecated)
gcloud functions deploy slackNotifier \\
--trigger-topic=TOPIC_NAME \\
--runtime=nodejs10 \\
--set-env-vars="SLACK_WEBHOOK=WEBHOOK_URL"
# actually executed
gcloud functions deploy bespin-d-service-func-noti-an3 \\
--trigger-topic=bespin-d-service-pst-noti \\
--runtime=nodejs10 \\
--set-env-vars="SLACK_WEBHOOK=https://hooks.slack.com/services/~~~" \\
--entry-point=slackNotifier \\
--region=asia-northeast3 \\
--project=bespin-service
5. Test
# example
gcloud pubsub topics publish TOPIC_ID \\
--message=MESSAGE_DATA \\
[--attribute=KEY="VALUE",...]
# actually executed
gcloud pubsub topics publish bespin-d-service-pst-noti \\
--message=test
--attribute=KEY=VALUE
--project bespin-service
6. 확인
TroubleShooting
Cloud Functions 문제 해결 - 잘못 지정된 진입점으로 인해 함수 배포 실패
—-entry-point 옵션으로 해당 소스 코드내의 함수 이름을 따로 설정하지 않으면, 배포 시 설정한 function이름(bespin-d-service-func-noti)으로 —entry-point 가 생성됩니다. bespin-d-service-func-noti라는 함수가 없기 때문에 아래와 같은 에러를 뱉습니다.
Deployment failure: Function failed on loading user code. Error message:
Error: please examine your function logs to see the error cause:
<https://cloud.google.com/functions/docs/monitoring/logging#viewing_logs>
References
https://cloud.google.com/kubernetes-engine/docs/concepts/cluster-notifications?hl=ko#filtering
'CSP (Cloud Service Provider) > GCP' 카테고리의 다른 글
GCP KMS Hands-On (0) | 2023.05.21 |
---|---|
[GCP] Workload Identity Federation을 사용하기 위한 Github Action 세팅 (0) | 2023.05.19 |
[GCP] VPC Service Control이란? (0) | 2023.05.12 |
GCP Workload Identity Federation (0) | 2023.05.11 |
GCP KMS(Key Management System) (0) | 2023.05.11 |
댓글