GCP sets up Prometheus+Grafana to monitor Flask-app on Kubernetes cluster
【事前準備大綱】
- 申請Google Cloud Platform (GCP) 試用帳號
- 開設兩台虛擬主機,分別為主機A與主機B
- 申請Docker Hub帳號,並建立好repository(用來上傳docker映像檔)
- 主機A,以Docker-compose部署Prometheus+Grafana+Flask
- 主機B,安裝Docker以及K8S的基本三件套(kubectl kubelet kubeadm)
- 設置GCP上虛擬私有雲網路的防火牆權限,開通相關port(3000,5000,9090等)
- 測試A伺服器是否能獲取B伺服器的數據源,完成監控項目
申請帳號就不多說了,新帳號申請都有試用額度。
申請好帳號就直接前往控制台的Compute Engine開啟虛擬機器
以上就完成了步驟1~2
申請Docker Hub帳號,並建立好repository
待會需要上傳封裝在docker映像檔的flask-app
再來就是設定防火牆規則
設定好防火牆規則之後就能以SSH連入主機
首先進入主機A
以Docker-compose部署Prometheus+Grafana+Flask
安裝Docker
sudo apt-get update
sudo apt-get install -y docker.io
sudo ln -sf /usr/bin/docker.io /usr/local/bin/docker
安裝Docker-Compose
sudo curl -L "https://github.com/docker/compose/releases/download/v2.6.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
開始建立Flask-app
首先要知道建立一個Docker映像檔需要有三件要素
1. Dockerfile(讓docker創建映像檔)
2. requirements.txt(指定所需的相依套件)
3. app.py(flask-app程式主體)
sudo mkdir app/
cd app/
sudo vim Dockerfile
# 官方Python映像檔
FROM python:3.9
# 工作目錄
WORKDIR /app
# 複製程式碼到容器
COPY app.py /app
COPY requirements.txt /app
# 安裝相依套件
RUN pip install --no-cache-dir -r requirements.txt
# 容器執行時的指令
CMD [ "python", "app.py" ]
以上寫好Dockerfile再來是requirements.txt
sudo vim requirements.txt
flask
prometheus_client
再來是程式主體app.py
這裡因為要提供給prometheus獲取數據源
因此較hello world的最最最基本flask還要來得多幾行
sudo vim app.py
import prometheus_client
from prometheus_client import Counter
from flask import Response, Flask, jsonify
app = Flask(__name__)
total_requests = Counter('request_count', 'Total webapp request count')
@app.route('/metrics')
def requests_count():
total_requests.inc()
return Response(prometheus_client.generate_latest(total_requests), mimetype='text/plain')
@app.route('/')
def index():
total_requests.inc()
return jsonify({
'status': 'ok'
})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
再來就能製作為docker映像檔,並上傳至Docker Hub倉庫
# 建立
sudo docker build -t 映像檔名稱 .
# 上傳
sudo docker push 你的DockerHub帳號/映像檔名稱:標籤名稱
# 範例
# sudo docker build -t appk8s .
# 範例
# sudo docker push hachi4sre/appk8s:latest
再來先寫好Prometheus獲取數據源的YAML檔
sudo vim prometheus.yaml
# 設定 global 全域設定
# scrape_interval 是多久抓取一次資料
global:
scrape_interval: 5s
external_labels:
monitor: 'demo-monitor'
# scrape_configs 是抓取來源,若要新增數據源,就再新增一塊job_name區域
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'api_monitor'
scrape_interval: 5s
static_configs:
- targets: ['web:5000']
再來撰寫docker-compose.yaml
一口氣建立Prometheus+Grafana+Flask
sudo vim docker-compose.yaml
version: '3.7'
volumes:
prometheus_data: {}
grafana_data: {}
services:
prometheus:
image: prom/prometheus:v2.1.0
volumes:
- ./prometheus.yaml:/etc/prometheus/prometheus.yaml
command:
- '--web.enable-lifecycle'
- '--config.file=/etc/prometheus/prometheus.yaml'
ports:
- '9090:9090'
grafana:
image: grafana/grafana
volumes:
- grafana_data:/var/lib/grafana
environment:
- GF_SECURITY_ADMIN_PASSWORD=pass
depends_on:
- prometheus
ports:
- '3000:3000'
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/app
depends_on:
- prometheus
以docker-compose建立服務並在背景執行
sudo docker-compose up -d
*記得要在YAML配置檔所在目錄底下執行喲!不然會報錯
測試是否能訪問
- Flask
http://虛擬機器的外部ip:5000 - Prometheus
http://虛擬機器的外部ip:9090 - Grafana
http://虛擬機器的外部ip:9090
預設密碼在docker-compose.yaml中設定為"pass"
查看Prometheus是否有獲取數據源
至Grafana導入數據源並呈現為圖表
到這裡就建立好主機A
建立一個Flask-app,端口5000
通過Prometheus獲取數據源
並且能呈現數據在Grafana上
再來要設置主機B,一樣建立Flask-app只是通過K8S來部署
安裝Docker
sudo apt-get update
sudo apt-get install -y docker.io
sudo ln -sf /usr/bin/docker.io /usr/local/bin/docker
安裝K8S(事前)
# 關閉swap
sudo swapoff -a
安裝K8S(正式)
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl
curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
sudo apt-add-repository "deb http://apt.kubernetes.io/ kubernetes-xenial main"
sudo apt-get update
sudo apt-get install -y kubectl kubelet kubeadm
sudo apt-mark hold kubelet kubeadm kubectl
初始化K8S
sudo kubeadm init --pod-network-cidr=你的GCP虛擬機器內網的網段
# 範例
sudo kubeadm init --pod-network-cidr=10.140.0.0/16
讓使用者擁有執行權限
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
(重要)需要再幫K8S裝下網路套件
常見有三種:flannel、weave、calico
直接套用的話會報錯,需要修改預設的內網網段,以下拿flannel為例
首先在主機B上先開好flannel配置文件
sudo vim kube-flannel.yml
直接在瀏覽器打開下方kube-flannel.yaml的內容,全選並複製 https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
貼入自己建立的kube-flannel.yml之後
手動修改以下這一段(輸入你的GCP虛擬機器內網的網段)
net-conf.json: |
{
"Network": "10.140.0.0/16",
"Backend": {
"Type": "vxlan"
}
}
2023.08.02更新,換了個CNI套件
https://antrea.io/docs/v1.4.0/docs/getting-started/
kubectl apply -f https://raw.githubusercontent.com/antrea-io/antrea/main/build/yamls/antrea.yml
上面的撰寫kube-flannel.yml內容若撰寫完畢之後,需要"套用"
kubectl apply -f kube-flannel.yml
到這裡就會看到flannel已經在運行,並且node節點也是ready狀態
kubectl get pods --all-namespaces
kubectl get node
完整的安裝好K8S之後,再來要部署Flask-app了
撰寫部署的YAML
sudo vim deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: flask-deployment
spec:
replicas: 1
selector:
matchLabels:
app: flask-app
template:
metadata:
labels:
app: flask-app
spec:
containers:
- name: flask-container
image: <你的倉庫帳號>/<你的鏡像名稱>:<標籤>
ports:
- containerPort: 5000
因為在部署主機A的時候已經有把flask-app打包上傳hub
所以現在就很簡單只要從hub再把映像檔拉下來就能跑了
撰寫完畢之後需要"套用"
kubectl apply -f deployment.yaml
再來就能檢查pod是否有起來
kubectl get pods
到這裡就已經成功以K8S部署Flask-app了
最後最麻煩的是K8S需要暴露端口提供給外網訪問
以下有兩種做法:
1. NodePort
撰寫service.yaml
sudo vim service.yaml
# NodePort版本
apiVersion: v1
kind: Service
metadata:
name: flask-service
spec:
type: NodePort
ports:
- protocol: TCP
port: 80
targetPort: 5000
selector:
app: flask-app
2. LoadBalancer
# LoadBalancer版本
apiVersion: v1
kind: Service
metadata:
name: flask-service
spec:
type: LoadBalancer
loadBalancerIP: <外部静态 IP>
ports:
- protocol: TCP
port: 80
targetPort: 5000
selector:
app: flask-app
查看service是否有配上外網ip以及暴露端口
# 查看service
kubectl get service
# 暴露端口
kubectl expose deployment <你的service名稱> --type=LoadBalancer --port=<你的容器端口> --external-ip=<你的外部IP> --target-port=<你的開放端口>
# 懶人包(防火牆規則自動建立)
kubectl expose deployment <你的service名稱> --type="LoadBalancer"
結果如下
訪問看看外網ip+指定端口是否可行
再來一樣到Prometheus查看是否有數據源
最後到Grafana導入數據源並匯出圖表就完成本日的大工程啦