候補探し
keycloak on k8s https://www.keycloak.org/getting-started/getting-started-kube
locust on k8s https://aws.amazon.com/jp/blogs/news/load-testing-your-workload-running-on-amazon-eks-with-locust/
discord bot + app で通知 ?
「 おうちkubernetes」という用語を調べる
自宅のサーバーに k8s をデプロイして色々メトリクスを収集してる記事 https://eng-blog.iij.ad.jp/archives/11900
色々紹介している記事 https://blog.chatagiriii.com/?p=110
Discord Bot 作る記事 https://gammalab.net/blog/ypbnb4q8qap6h/ →これが割と自分の興味をひいた
Discord Bot を作成してみる。
Discord Bot on k8s
https://gammalab.net/blog/ypbnb4q8qap6h/ を参考に色々やってみる。
Cloud9 環境作成
手元の環境が汚れるのが嫌なので、 Cloud9 上で実施 ツールのインストール
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
./aws/install -i /usr/local/aws-cli -b /usr/local/bin
curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
sudo mv /tmp/eksctl /usr/local/bin
curl -LO "https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin/kubectl
C9権限ではなく、EC2 権限を使いたいので IAM Role アタッチ後、画面右江から use aws temporary credential のチェックを外す
aws sts get-caller-identity --query 'Arn' --output text
kubeconfを更新する
eksctl get clusters
NAME REGION EKSCTL CREATED
ekshandson ap-northeast-1 True
aws eks update-kubeconfig --region ap-northeast-1 --name ekshandson
kubectl get pods --all-namespaces
Container
mkdir ws
cd ws
touch main.py
コードを分析
- Dog API
- リクエストするとランダムな Dog 画像の URL を返す Public API
- discord.client.event デコレータ
- https://discordpy.readthedocs.io/ja/latest/api.html#discord.Client.event
- いわゆるアノテーション
- on_ready イベント発生時のコールバック
- クライアントがDiscordから受信したデータの準備を完了した際に呼び出される
- https://discordpy.readthedocs.io/ja/latest/api.html#discord.on_ready
Python Code
import os
import discord
import aiohttp
import asyncio
BOT_TOKEN = os.getenv('BOT_TOKEN')
CHANNEL_ID = int(os.getenv('CHANNEL_ID'))
client = discord.Client(intents=discord.Intents.default())
async def channel_send_dog(channel):
print('Invoke Dog Post')
async with aiohttp.ClientSession() as session:
response = await session.get('https://dog.ceo/api/breeds/image/random')
dog = await response.json()
await channel.send(dog['message'])
print('Sending Complete!')
@client.event
async def on_ready():
channel = client.get_channel(CHANNEL_ID)
while True:
await channel_send_dog(channel)
await asyncio.sleep(6000)
client.run(BOT_TOKEN)
python3 main.py
Traceback (most recent call last):
File "main.py", line 2, in <module>
import discord
ModuleNotFoundError: No module named 'discord'
できれば一括で入れたいので requirements.txt を用意する
touch requirements.txt
echo """discord
aiohttp
asyncio""" > requirements.txt
Python v3.8 移行なので準備
wget https://www.python.org/ftp/python/3.8.16/Python-3.8.16.tgz
tar -xvf Python-3.8.16.tgz
cd Python-3.8.16
./configure
make
make test
sudo make install
cd ws
pip3 install -r requirements.txt
Discord 登録
https://discord.com/developers/applications
以下が必要
- Bot Token
- Channnel ID
手順
- Application 作成
- Public Bot にチェックを入れない場合、プライベートになる
- Bot 作成
- OAuth2 URL を生成
- アクセスすることで、自分が作成したサーバーに bot を追加できる
export BOT_TOKEN=***
export CHANNEL_ID=773500548347330613
python main.py 2022-12-31 14:10:56 INFO discord.client logging in using static token
2022-12-31 14:10:57 INFO discord.gateway Shard ID None has connected to Gateway (Session ID: fd3df738732cdab7e399d57fee3c0af6).
Invoke Dog Post
Sending Complete!
永続化するっぽい
Docker File 作成
https://hub.docker.com/_/python
touch Dockerfile
echo '''
FROM python:3.8-buster
COPY src/* ./
RUN pip3 install -r requirements.txt
CMD ["python3", "main.py"]
''' > Dockerfile
mkdir src
mv main.py src/main.py
mv requirements.txt src/requirements.txt
docker build ./ -t discordbot
起動
docker run -e CHANNEL_ID=$CHANNEL_ID -e BOT_TOKEN=$BOT_TOKEN --rm discordbot
これまでのイメージ整理
docker ps --all
docker system prune
ECR へ image を push
manifest ファイルで参照するために、プライベートリポジトリへ image をプッシュする
aws ecr create-repository --repository-name discord
discord_repo=$(aws ecr describe-repositories --repository-names discord --query 'repositories[0].repositoryUri' --output text)
AWS_ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)
AWS_REGION=$(aws configure get default.region)
aws ecr get-login-password | docker login --username AWS --password-stdin https://${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com
docker tag discordbot:latest ${discord_repo}:latest
docker push ${discord_repo}:latest
k8s deploy (マニフェスト作成)
cat <<EOF > dog-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: discord-dogbot
spec:
replicas: 1
selector:
matchLabels:
name: discord-dogbot
template:
metadata:
labels:
name: discord-dogbot
spec:
containers:
- name: discord-dogbot
image: ${discord_repo}:latest
imagePullPolicy: Always
envFrom:
- secretRef:
name: dogbot-secrets
EOF
kubectl create namespace discord
kubectl apply -f dog-deployment.yaml -n discord
多分 secret ないのでそれでエラー
kubectl get deployment -n discord
kubectl get pod -n discord
NAME READY STATUS RESTARTS AGE
discord-dogbot-66689d49fb-jqrpw 0/1 CreateContainerConfigError 0 45s
kubectl logs discord-dogbot-66689d49fb-jqrpw -n discord
Error from server (BadRequest): container "discord-dogbot" in pod "discord-dogbot-66689d49fb-jqrpw" is waiting to start: CreateContainerConfigError
kubectl describe deployment -n discord
cat <<EOF > dog-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: dogbot-secrets
stringData:
BOT_TOKEN: "************************************************************************"
CHANNEL_ID: "******************"
EOF
kubectl apply -f dog-secret.yaml -n discord
kubectl get pod -n discord
NAME READY STATUS RESTARTS AGE
discord-dogbot-66689d49fb-jqrpw 1/1 Running 0 4m23s
無事成功!!!!
なんとなく、Podがどのノードで立ち上がってるのかみたいです
kubectl get nodes
NAME STATUS ROLES AGE VERSION
ip-192-168-14-42.ap-northeast-1.compute.internal Ready <none> 45h v1.24.7-eks-fb459a0
ip-192-168-33-5.ap-northeast-1.compute.internal Ready <none> 45h v1.24.7-eks-fb459a0
ip-192-168-4-202.ap-northeast-1.compute.internal Ready <none> 45h v1.24.7-eks-fb459a0
kubectl get pods -o wide -n discord
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
discord-dogbot-66689d49fb-jqrpw 1/1 Running 0 20m 192.168.3.2 ip-192-168-14-42.ap-northeast-1.compute.internal <none> <none>
なるほど判明しました。