在WSL2上部署標(biāo)準(zhǔn)k8s集群并使用Prometheus監(jiān)控spring cloud服務(wù)
2019年Windows Build大會上,微軟發(fā)布
WSL2
,意味著開發(fā)者們終于可以在Windows上開發(fā)和運行原汁原味Linux
應(yīng)用。
本篇文章將教會大家如何在 WSL2
部署一個標(biāo)準(zhǔn)版的 k8s
集群以及使用 Prometheus
和 grafana
監(jiān)控 spring cloud
服務(wù)。
和第一代 WSL
不同,WSL2
是運行在 hyper-v
上的一個 VM
疟羹,因此可以運行原汁原味的 Linux
發(fā)行版,例如 Ubuntu
禀倔,同樣對 Linux ABI
接口兼容也更好榄融,支持更多 Linux
應(yīng)用,例如 docker
救湖。
經(jīng)過將近一年時間的開發(fā)與優(yōu)化剃袍,微軟團(tuán)隊終于發(fā)布了正式版 WSL2
,用戶只需將操作系統(tǒng)升級到 2004
以后的 Windows 10
即可捎谨。
準(zhǔn)備工作
安裝 WSL
前置條件:
- 操作系統(tǒng)必須是
Windows 10 build 2004
以后的版本 -
C盤
剩余空間最好在64G
以上 - 內(nèi)存最好是
16G
以上民效,8g
內(nèi)存運行k8s
集群后憔维,就沒有剩余內(nèi)存
安裝開始:
- 在桌面左下角
Windows
徽標(biāo)上,右鍵選擇Windows Powershell(管理員)(A)
畏邢,然后運行一下腳本
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
如果這里遇到失敗业扒,多半是操作系統(tǒng)沒有升到最新版本的
Windows 10
或者
- 安裝 WSL 2 之前,必須啟用“虛擬機(jī)平臺”可選功能舒萎。
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
重新啟動計算機(jī)程储,以完成 WSL 安裝并更新到 WSL 2。
將 WSL 2 設(shè)置為默認(rèn)版本
安裝新的 Linux 分發(fā)版時臂寝,請在 Powershell 中運行以下命令章鲤,以將 WSL 2 設(shè)置為默認(rèn)版本:
wsl --set-default-version 2
- 安裝所選的 Linux 分發(fā)版
打開 Microsoft Store,并選擇你偏好的 Linux 分發(fā)版咆贬。
單擊以下鏈接會打開每個分發(fā)版的 Microsoft Store 頁面:
- Ubuntu 16.04 LTS
- Ubuntu 18.04 LTS
- Ubuntu 20.04 LTS
- openSUSE Leap 15.1
- SUSE Linux Enterprise Server 12 SP5
- SUSE Linux Enterprise Server 15 SP1
- Kali Linux
- Debian GNU/Linux
- Fedora Remix for WSL
- Pengwin
- Pengwin Enterprise
- Alpine WSL
- 在分發(fā)版的頁面中败徊,選擇“獲取”。
- 設(shè)置新分發(fā)版
首次啟動新安裝的 Linux 分發(fā)版時掏缎,將打開一個控制臺窗口皱蹦,系統(tǒng)會要求你等待一分鐘或兩分鐘,以便文件解壓縮并存儲到電腦上眷蜈。 未來的所有啟動時間應(yīng)不到一秒沪哺。
然后,需要為新的 Linux 分發(fā)版創(chuàng)建用戶帳戶和密碼酌儒。
將分發(fā)版版本設(shè)置為 WSL 1 或 WSL 2
可以打開 PowerShell 命令行并輸入以下命令(僅在 Windows 內(nèi)部版本 19041 或更高版本中可用)辜妓,來檢查分配給每個已安裝的 Linux 分發(fā)版的 WSL 版本:wsl -l -v
wsl --list --verbose
若要將分發(fā)版設(shè)置為受某一 WSL 版本支持,請運行:
wsl --set-version <distribution name> <versionNumber>
請確保將 <distribution name>
替換為你的分發(fā)版的實際名稱忌怎,并將 <versionNumber>
替換為數(shù)字“1”或“2”嫌拣。 可以隨時更改回 WSL 1
,方法是運行與上面相同的命令呆躲,但將“2”替換為“1”。
此外捶索,如果要使 WSL 2
成為你的默認(rèn)體系結(jié)構(gòu)插掂,可以通過此命令執(zhí)行該操作:
wsl --set-default-version 2
這會將安裝的任何新分發(fā)版的版本設(shè)置為 WSL 2
。
- 排查安裝問題
下面是相關(guān)的錯誤和建議的修復(fù)措施腥例。 有關(guān)其他常見錯誤及其解決方法辅甥,請參閱 WSL 故障排除頁。
- 安裝失敗并出現(xiàn)錯誤 0x80070003
- 適用于 Linux 的 Windows 子系統(tǒng)只能在系統(tǒng)驅(qū)動器(通常是 C: 驅(qū)動器)中運行燎竖。 請確保分發(fā)版存儲在系統(tǒng)驅(qū)動器上:
- 打開“設(shè)置”->“存儲”->“更多存儲設(shè)置: 更改新內(nèi)容的保存位置”
- WslRegisterDistribution 失敗并出現(xiàn)錯誤
0x8007019e
- 未啟用“適用于 Linux 的 Windows 子系統(tǒng)”可選組件:
- 打開“控制面板” -> “程序和功能” -> “打開或關(guān)閉 Windows 功能”-> 選中“適用于 Linux 的 Windows 子系統(tǒng)”璃弄,或使用本文開頭所述的 PowerShell cmdlet芳来。
- 安裝失敗鞠评,出現(xiàn)錯誤
0x80070003
或錯誤0x80370102
- 請確保在計算機(jī)的 BIOS 內(nèi)已啟用虛擬化。 有關(guān)如何執(zhí)行此操作的說明因計算機(jī)而異扬舒,并且很可能在 CPU 相關(guān)選項下。
- 嘗試升級時出錯:
Invalid command line option: wsl --set-version Ubuntu 2
- 請確保已啟用適用于 Linux 的 Windows 子系統(tǒng)脐供,并且你使用的是 Windows 內(nèi)部版本 19041 或更高版本浑塞。 若要啟用 WSL,請在 Powershell 提示符下以具有管理員權(quán)限的身份運行此命令:
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
政己。 可在此處找到完整的 WSL 安裝說明酌壕。
- 請確保已啟用適用于 Linux 的 Windows 子系統(tǒng)脐供,并且你使用的是 Windows 內(nèi)部版本 19041 或更高版本浑塞。 若要啟用 WSL,請在 Powershell 提示符下以具有管理員權(quán)限的身份運行此命令:
- 由于虛擬磁盤系統(tǒng)的某個限制,無法完成所請求的操作歇由。虛擬硬盤文件必須是解壓縮的且未加密的卵牍,并且不能是稀疏的。
- 請檢查 WSL Github 主題 #4103沦泌,其中跟蹤了此問題以提供更新的信息糊昙。
- 無法將詞語“wsl”識別為 cmdlet、函數(shù)赦肃、腳本文件或可運行程序的名稱溅蛉。
- 請確保已安裝“適用于 Linux 的 Windows 子系統(tǒng)”可選組件。 此外他宛,如果你使用的是 Arm64 設(shè)備船侧,并從 PowerShell 運行此命令,則會收到此錯誤厅各。 請改為從 PowerShell Core 或從命令提示符運行 wsl.exe镜撩。
- 額外工作
-
禁用
swap
因為
kubelet
不支持swap
內(nèi)存,因此需要通過設(shè)置wslconfig
禁用swap
队塘。在用戶根目錄
創(chuàng)建.wslconfig
文件袁梗,例如: 'C:\Users\huang' ,添加以下內(nèi)容:[wsl2] swap=0 # 關(guān)閉swap [network] generateResolvConf = false # 解決域名解析失敗的問題
然后在
powershell
或cmd
運行以下命令憔古,關(guān)閉wsl
遮怜,再點擊開始菜單Ubuntu
圖標(biāo),即完成重啟WSL
鸿市。wsl --shutdown
-
設(shè)置
/etc/resolve.conf
因為每次
WSL
啟動會自動覆蓋/etc/resolve.conf
文件锯梁,可能會導(dǎo)致域名解析失敗的問題,必要時可以設(shè)置自定義的DNS服務(wù)器
焰情,把以下內(nèi)容追加到/etc/resolve.conf
文件末尾:(需要root
權(quán)限陌凳,記得加上sudo
)nameserver 8.8.8.8 nameserver 114.114.114.114
-
替換
apt
源Ubuntu
官方源在國內(nèi)并不好用,因此我們需要替換源内舟,提高軟件安裝和更新速度合敦。編輯/etc/apt/sources.list
,為了安全可以先備份以下原文件# 備份source.list文件 sudo mv /etc/apt/sources.list /etc/apt/sources.list.bak # 創(chuàng)建source.list文件 sudo vim /etc/apt/sources.list
按
i
進(jìn)入編輯模式验游,然后把以下內(nèi)容復(fù)制粘貼到/etc/apt/sources.list
文件這是清華大學(xué)
Ubuntu 18.04 LTS
的鏡像源充岛,可根據(jù)用戶安裝的發(fā)行版自行替換# 默認(rèn)注釋了源碼鏡像以提高 apt update 速度保檐,如有需要可自行取消注釋 deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse # 預(yù)發(fā)布軟件源,不建議啟用 # deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable # deb-src [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable
先按
esc
裸准,再安裝:
展东,輸入wq
,回車就出退出并保存文件炒俱。然后更新本地緩存sudo apt update && sudo apt upgrade
-
安裝
daemonize
很多
Linux
應(yīng)用需要systemd
運行盐肃,比如說docker
和kubelet
。但是幾乎所有WSL2
支持的鏡像都不能運行systemd
权悟,因此我們需要安裝daemonize
砸王。apt-get update && sudo apt-get install -yqq daemonize dbus-user-session fontconfig
創(chuàng)建
/usr/sbin/start-systemd-namespace
文件,并復(fù)制粘貼以下內(nèi)容到文件中#!/bin/bash SYSTEMD_PID=$(ps -ef | grep '/lib/systemd/systemd --system-unit=basic.target$' | grep -v unshare | awk '{print $2}') if [ -z "$SYSTEMD_PID" ] || [ "$SYSTEMD_PID" != "1" ]; then export PRE_NAMESPACE_PATH="$PATH" (set -o posix; set) | \ grep -v "^BASH" | \ grep -v "^DIRSTACK=" | \ grep -v "^EUID=" | \ grep -v "^GROUPS=" | \ grep -v "^HOME=" | \ grep -v "^HOSTNAME=" | \ grep -v "^HOSTTYPE=" | \ grep -v "^IFS='.*"$'\n'"'" | \ grep -v "^LANG=" | \ grep -v "^LOGNAME=" | \ grep -v "^MACHTYPE=" | \ grep -v "^NAME=" | \ grep -v "^OPTERR=" | \ grep -v "^OPTIND=" | \ grep -v "^OSTYPE=" | \ grep -v "^PIPESTATUS=" | \ grep -v "^POSIXLY_CORRECT=" | \ grep -v "^PPID=" | \ grep -v "^PS1=" | \ grep -v "^PS4=" | \ grep -v "^SHELL=" | \ grep -v "^SHELLOPTS=" | \ grep -v "^SHLVL=" | \ grep -v "^SYSTEMD_PID=" | \ grep -v "^UID=" | \ grep -v "^USER=" | \ grep -v "^_=" | \ cat - > "$HOME/.systemd-env" echo "PATH='$PATH'" >> "$HOME/.systemd-env" exec sudo /usr/sbin/enter-systemd-namespace "$BASH_EXECUTION_STRING" fi if [ -n "$PRE_NAMESPACE_PATH" ]; then export PATH="$PRE_NAMESPACE_PATH" fi
接著峦阁,創(chuàng)建
/usr/sbin/enter-systemd-namespace
文件谦铃,將以下內(nèi)容復(fù)制粘貼到文件中#!/bin/bash if [ "$UID" != 0 ]; then echo "You need to run $0 through sudo" exit 1 fi SYSTEMD_PID="$(ps -ef | grep '/lib/systemd/systemd --system-unit=basic.target$' | grep -v unshare | awk '{print $2}')" if [ -z "$SYSTEMD_PID" ]; then /usr/sbin/daemonize /usr/bin/unshare --fork --pid --mount-proc /lib/systemd/systemd --system-unit=basic.target while [ -z "$SYSTEMD_PID" ]; do SYSTEMD_PID="$(ps -ef | grep '/lib/systemd/systemd --system-unit=basic.target$' | grep -v unshare | awk '{print $2}')" done fi if [ -n "$SYSTEMD_PID" ] && [ "$SYSTEMD_PID" != "1" ]; then if [ -n "$1" ] && [ "$1" != "bash --login" ] && [ "$1" != "/bin/bash --login" ]; then exec /usr/bin/nsenter -t "$SYSTEMD_PID" -a \ /usr/bin/sudo -H -u "$SUDO_USER" \ /bin/bash -c 'set -a; source "$HOME/.systemd-env"; set +a; exec bash -c '"$(printf "%q" "$@")" else exec /usr/bin/nsenter -t "$SYSTEMD_PID" -a \ /bin/login -p -f "$SUDO_USER" \ $(/bin/cat "$HOME/.systemd-env" | grep -v "^PATH=") fi echo "Existential crisis" fi
運行
sudo visudo
命令,把以下內(nèi)容復(fù)制粘貼到文件末尾:Defaults env_keep += WSLPATH Defaults env_keep += WSLENV Defaults env_keep += WSL_INTEROP Defaults env_keep += WSL_DISTRO_NAME Defaults env_keep += PRE_NAMESPACE_PATH %sudo ALL=(ALL) NOPASSWD: /usr/sbin/enter-systemd-namespace
添加剛才的
shell
腳本到.bashrc
榔昔, 運行以下命令即可:sudo sed -i 2a"# Start or enter a PID namespace in WSL2\nsource /usr/sbin/start-systemd-namespace\n" /etc/bash.bashrc
最后驹闰,設(shè)置
Windows
環(huán)境變量,用管理員權(quán)限打開powershell
撒会,運行以下命令:cmd.exe /C setx WSLENV BASH_ENV/u cmd.exe /C setx BASH_ENV /etc/bash.bashrc # 關(guān)閉WSL wsl --shutdown
點擊
開始菜單
上的Ubuntu
應(yīng)用嘹朗,重新打開WSL
,正常進(jìn)入命令行界面說明操作成功诵肛。
若 啟動失敗
在 powershell
執(zhí)行以下命令即可恢復(fù) wsl
到正常狀態(tài)
```powsershell
wsl -e sudo mv /etc/bash.bashrc /opt/bash.bashrc
```
重新進(jìn)入 `wsl` 后屹培,打開 `/opt/bash.bashrc` ,將上一步添加的兩行內(nèi)容如下刪除:
```sh
# Start or enter a PID namespace in WSL2
source /usr/sbin/start-systemd-namespace
```
再把 `/opt/bash.bashrc` 放回 `/etc/` 目錄下怔檩,重走安裝 `daemonize` 流程
進(jìn)入正題
安裝 docker
移除舊版本docker
sudo apt-get remove docker docker-engine docker.io containerd runc
安裝docker
# 更新軟件索引
sudo apt-get update
# 安裝必備軟件
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
# 安裝 apt-key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# 添加 repository
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
# 更新軟件索引
sudo apt-get update
# 安裝docker
sudo apt-get install docker-ce docker-ce-cli containerd.io
# 檢驗docker是否安裝成功
sudo docker run hello-world
配置 docker
使用 root
權(quán)限創(chuàng)建 '/etc/docker/daemon.json' 文件褪秀,并填寫以下內(nèi)容:
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2",
"registry-mirrors": ["https://docker.mirrors.ustc.edu.cn/"]
}
重啟 docker
sudo systemctl daemon-reload
sudo systemctl start docker
安裝 kubernetes
添加 apt-key.gpg
步驟可能需要梯子,可以通過手動下載 apt-key.gpg薛训,再用這個命令 cat /mnt/c/Users/huang/Downloads/apt-key.gpg | sudo apt-key add -
媒吗,/mnt/c/
表示掛載 C盤
,后面加上 apt-key.gpg
所在目錄
sudo apt-get update && sudo apt-get install -y apt-transport-https curl
# 添加apt-key.gpg步驟可能需要梯子
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
啟動 k8s集群
執(zhí)行 kubeadm init
命令之前乙埃,先下載必要的鏡像闸英,運行以下命令:
kubeadm config images list
得到以下結(jié)果:(冒號后面是鏡像的版本,會根據(jù)kubeadm版本而變化)
k8s.gcr.io/kube-apiserver:v1.18.5
k8s.gcr.io/kube-controller-manager:v1.18.5
k8s.gcr.io/kube-scheduler:v1.18.5
k8s.gcr.io/kube-proxy:v1.18.5
k8s.gcr.io/pause:3.2
k8s.gcr.io/etcd:3.4.3-0
k8s.gcr.io/coredns:1.6.7
k8s.gcr.io
鏡像在國內(nèi)多半是拉取失敗的膊爪,所以要把 k8s.gcr.io
前綴換成 gotok8s
,再加上 'docker pull':
docker pull gotok8s/kube-apiserver:v1.18.5
docker pull gotok8s/kube-controller-manager:v1.18.5
docker pull gotok8s/kube-scheduler:v1.18.5
docker pull gotok8s/kube-proxy:v1.18.5
docker pull gotok8s/pause:3.2
docker pull gotok8s/etcd:3.4.3-0
docker pull gotok8s/coredns:1.6.7
逐行執(zhí)行以上命令嚎莉,待全部完成后米酬,再通過 docker tag
命令,把鏡像標(biāo)簽改成 k8s.gcr.io
:
docker tag gotok8s/kube-apiserver:v1.18.5 k8s.gcr.io/kube-apiserver:v1.18.5
docker tag gotok8s/kube-controller-manager:v1.18.5 k8s.gcr.io/kube-controller-manager:v1.18.5
docker tag gotok8s/kube-scheduler:v1.18.5 k8s.gcr.io/kube-scheduler:v1.18.5
docker tag gotok8s/kube-proxy:v1.18.5 k8s.gcr.io/kube-proxy:v1.18.5
docker tag gotok8s/pause:3.2 k8s.gcr.io/pause:3.2
docker tag gotok8s/etcd:3.4.3-0 k8s.gcr.io/etcd:3.4.3-0
docker tag gotok8s/coredns:1.6.7 k8s.gcr.io/coredns:1.6.7
再執(zhí)行以下命令趋箩,等待數(shù)分鐘后赃额,即可搭建一個標(biāo)準(zhǔn)版 k8s
集群
sudo kubeadm init --pod-network-cidr=10.244.0.0/16
出現(xiàn)以下命令時加派,說明創(chuàng)建 k8s
集群成功,再按照提示執(zhí)行以下命令:(如果創(chuàng)建集群失敗跳芳,通過運行 sudo kubeadm reset
芍锦,然后輸入 Y
即可清除 kubeadm init
命令的操作)
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
最后一步,通過 kubectl apply
命令飞盆,安裝 CNI
插件娄琉,這里以 calico 為例:
kubectl apply -f https://docs.projectcalico.org/v3.14/manifests/calico.yaml
通過 kubectl get node
命令獲取 node
節(jié)點的狀態(tài)是否 ready
:
NAME STATUS ROLES AGE VERSION
desktop-v6hkp49 Ready master 2m24s v1.18.5
壓軸環(huán)節(jié)
部署 spring cloud
集群
這里 spring cloud
示例源碼是本人18年學(xué)習(xí) spring cloud
的demo,相關(guān)代碼已經(jīng)上傳到 Github
下載源碼構(gòu)建
git clone https://github.com/zaoying/datacenter.git
使用其他編程語言的項目也是可以的吓歇,只需要加上
prometheus
對應(yīng)的sdk
以 Spring Boot
為例孽水,pom.xml
文件添加 ``
<project
<properties>
...
<!-- 使用tomcat作為servlet容器,請確保版本在8.5.32 以上 -->
<tomcat.version>8.5.32</tomcat.version>
...
</properties>>
...
<dependencies>
...
<!-- Micrometer Prometheus registry -->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
...
</dependencies>
</project>
修改配置文件 application.yml
城看,增加以下內(nèi)容:
management:
endpoints:
web:
exposure:
include: "*"
health:
show-details: always
metrics:
tags:
application: ${spring.application.name}
建議把 eureka 以及其他微服務(wù)組件的鏡像寫到同一個 Pod 中運行女气,各組件直接就可以通過 localhost 直接進(jìn)行通信
使用 maven
打包成jar
maven
環(huán)境的搭建不細(xì)說,以下命令可以在 Windows
上運行
# 切換到 datacenter 所在目錄
cd datacenter
# 構(gòu)建并打包eureka
cd eureka
mvn package -Dmaven.test.skip=true
# 構(gòu)建并打包school
cd school
mvn package -Dmaven.test.skip=true
# 構(gòu)建并打包teacher
cd teacher
mvn package -Dmaven.test.skip=true
# 構(gòu)建并打包student
cd student
mvn package -Dmaven.test.skip=true
使用 docker
打包鏡像
這里使用 WSL2
里面安裝的 docker
打包鏡像测柠。假設(shè)項目所在路徑是 c:/Users/huang/Documents/github
炼鞠。
eureka
、school
轰胁、teacher
和 student
目錄下都寫好 Dockerfile
谒主,以 eureka
為例:
FROM openjdk:8u242-jre-slim
COPY target/eureka-0.0.1-SNAPSHOT.jar ./app.jar
CMD java -jar app.jar
其他微服務(wù)模塊的 Dockerfile
也類似,把 eureka-0.0.1-SNAPSHOT.jar
替換成 xxx-0.0.1-SNAPSHOT.jar
即可软吐,xxx
就是微服務(wù)模塊的名稱瘩将。
把 Dockerfile
都編寫完成后,運行以下命令打包 Docker 鏡像
# 打包eureka鏡像
docker build -t datacenter-eureka:latest /mnt/c/Users/huang/Documents/github/datacenter/eureka
# 打包school鏡像
docker build -t datacenter-school:latest /mnt/c/Users/huang/Documents/github/datacenter/school
# 打包teacher鏡像
docker build -t datacenter-teacher:latest /mnt/c/Users/huang/Documents/github/datacenter/teacher
# 打包student鏡像
docker build -t datacenter-student:latest /mnt/c/Users/huang/Documents/github/datacenter/student
部署并初始化 mysql
為了方便管理凹耙,先創(chuàng)建一個新的 namespace
姿现,名字就叫 spring-cloud
:
kubectl create namespace spring-cloud
mysql
有官方鏡像,直接拿過來使用即可肖抱,不用重新打包备典。另外因為 mysql
是個有狀態(tài)應(yīng)用,為了避免Pod重啟導(dǎo)致數(shù)據(jù)丟失意述,所以在運行之前提佣,需要先分配一個 Persistent Volume
和 Persistent Volume Claim
:
kind: PersistentVolume
apiVersion: v1
metadata:
name: mysql-pv-volume
namespace: spring-cloud
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 2Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/opt/data/mysql"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
namespace: spring-cloud
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
可以根據(jù)實際情況,把
/opt/data/mysql
換成其他目錄荤崇,PV
和PVC
的大小也可以調(diào)整為其他大小拌屏,就目前的demo而已,2Gi
容量已經(jīng)足夠了术荤。
將上述內(nèi)容保存到 pvc.yml
文件倚喂,然后執(zhí)行 kubectl apply -f
命令創(chuàng)建:
kubectl apply -f pvc.yml
接下來,創(chuàng)建 mysql.yml
文件瓣戚,再將以下內(nèi)容添加到文件內(nèi):
apiVersion: v1
kind: Service
metadata:
name: mysql
namespace: spring-cloud
spec:
type: NodePort
ports:
- name: mysql
protocol: TCP
nodePort: 30306
port: 3306
targetPort: 3306
selector:
app: mysql
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
namespace: spring-cloud
spec:
selector:
matchLabels:
app: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: mysql
spec:
containers:
- image: mysql:5.6
name: mysql
env:
# Use secret in real usage
- name: MYSQL_ROOT_PASSWORD
value: bocloud@2019
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pv-claim
還是通過 kubectl apply -f
命令創(chuàng)建 mysql
的 service
和 deployment
端圈, 然后同一個 namespace
即 spring-cloud
命令空間的 Pod
就可以通過 mysql:3306
地址訪問 mysql
焦读。
kubectl apply -f mysql.yml
通過 kubectl get pod -n spring-cloud
命令,查看 pod
是否 running
NAME READY STATUS RESTARTS AGE
mysql-85bcfd68f6-qxmcj 0/1 Pending 0 4m59s
使用 kubectl descibe pod mysql-85bcfd68f6-qxmcj -n spring-cloud
查看舱权,發(fā)現(xiàn)以下原因:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 14s (x4 over 104s) default-scheduler 0/1 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate.
說明 pod
不能在控制面 control panel
運行矗晃,可以通過以下命令解決:
kubectl taint nodes --all node-role.kubernetes.io/master-
編寫 datacenter.yml
并部署
創(chuàng)建 datacenter.yml
文件,并把以下內(nèi)容添加到文件內(nèi):
apiVersion: v1
kind: Service
metadata:
name: datacenter
namespace: spring-cloud
spec:
ports:
- name: eureka
protocol: TCP
port: 8761
targetPort: 8761
nodePort: 30761
- name: school
protocol: TCP
port: 8084
targetPort: 8084
nodePort: 30084
- name: teacher
protocol: TCP
port: 8082
targetPort: 8082
nodePort: 30082
- name: student
protocol: TCP
port: 8083
targetPort: 8083
nodePort: 30083
selector:
app: datacenter
type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: datacenter-dep
namespace: spring-cloud
labels:
app: datacenter
spec:
replicas: 1
selector:
matchLabels:
app: datacenter
template:
metadata:
labels:
app: datacenter
spec:
containers:
- name: eureka
image: datacenter-eureka:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8761
- name: school
image: datacenter-school:latest
imagePullPolicy: IfNotPresent
env:
- name: MYSQL_ADDRESS
value: mysql:3306
- name: MYSQL_PASSWORD
value: bocloud@2019
ports:
- containerPort: 8084
- name: teacher
image: datacenter-teacher:latest
imagePullPolicy: IfNotPresent
env:
- name: MYSQL_ADDRESS
value: mysql:3306
- name: MYSQL_PASSWORD
value: bocloud@2019
ports:
- containerPort: 8082
- name: student
image: datacenter-student:latest
imagePullPolicy: IfNotPresent
env:
- name: MYSQL_ADDRESS
value: mysql:3306
- name: MYSQL_PASSWORD
value: bocloud@2019
ports:
- containerPort: 8083
運行以下命令宴倍,即可創(chuàng)建 datacenter
的 service
和 deployment
张症,同一個 namespace
的 Pod
可以通過 datacenter:8761
、datacenter:8084
啊楚、datacenter:8082
吠冤、datacenter:8083
來分別訪問 eureka
、school
恭理、teacher
和 student
服務(wù)拯辙。
kubectl apply -f pvc.yml
部署 prometheus
和 grafana
為了方便管理,先創(chuàng)建 prometheus-k8s
的 namespace
kubectl create namespace prometheus-k8s
然后颜价,再創(chuàng)建一個 configmap
來保存 prometheus
的配置:
# my global config
global:
scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
# scrape_timeout is set to the global default (10s).
# Alertmanager configuration
alerting:
alertmanagers:
- static_configs:
- targets:
# - alertmanager:9093
# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
# - "first_rules.yml"
# - "second_rules.yml"
# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
- job_name: 'prometheus'
# metrics_path defaults to '/metrics'
# scheme defaults to 'http'.
static_configs:
- targets: ['localhost:9090']
- job_name: 'school'
metrics_path: "/actuator/prometheus"
static_configs:
- targets: ['datacenter.spring-cloud:8084']
- job_name: 'teacher'
metrics_path: "/actuator/prometheus"
static_configs:
- targets: ['datacenter.spring-cloud:8082']
- job_name: 'student'
metrics_path: "/actuator/prometheus"
static_configs:
- targets: ['datacenter.spring-cloud:8083']
然后把文件保存為 prometheus.yml
涯保,再運行以下命令:
kubectl create configmap prometheus-config -n prometheus-k8s --from-file prometheus.yml
接著,創(chuàng)建 prometheus
的 service
和 deployment
:
apiVersion: v1
kind: Service
metadata:
name: prometheus
namespace: prometheus-k8s
spec:
type: NodePort
ports:
- name: http
protocol: TCP
nodePort: 30909
port: 9090
targetPort: 9090
selector:
app: prometheus
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: prometheus
namespace: prometheus-k8s
spec:
selector:
matchLabels:
app: prometheus
strategy:
type: Recreate
template:
metadata:
labels:
app: prometheus
spec:
containers:
- image: prom/prometheus
name: prometheus
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9090
name: http
volumeMounts:
- name: prometheus-config
mountPath: /etc/prometheus/
volumes:
- name: prometheus-config
configMap:
name: prometheus-config
items:
- key: prometheus.yml
path: prometheus.yml
把上述內(nèi)容保存為 serviceAndDeployment.yml
文件周伦,再運行以下命令:
kubectl apply -f serviceAndDeployment.yml
接著夕春,創(chuàng)建 grafana
的 service
和 deployment
:
apiVersion: v1
kind: Service
metadata:
name: grafana
namespace: prometheus-k8s
spec:
type: NodePort
ports:
- name: http
protocol: TCP
nodePort: 30009
port: 3000
targetPort: 3000
selector:
app: grafana
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: grafana
namespace: prometheus-k8s
spec:
selector:
matchLabels:
app: grafana
strategy:
type: Recreate
template:
metadata:
labels:
app: grafana
spec:
containers:
- image: grafana/grafana
name: grafana
imagePullPolicy: IfNotPresent
ports:
- containerPort: 3000
name: http
把上述內(nèi)容保存為 serviceAndDeployment-grafana.yml
文件,再運行以下命令:
kubectl apply -f serviceAndDeployment-grafana.yml
創(chuàng)建 ingress
創(chuàng)建 ingress-nginx-controller
专挪,這里用到 hostNetwork
及志,所以會占用宿主機(jī)的 80
和 443
端口
kubectl apply -f https://raw.githubusercontent.com/zaoying/k8s-learning/master/nginx/mandatory.yaml
創(chuàng)建 ingress-nginx
服務(wù)
kind: Service
apiVersion: v1
metadata:
name: ingress-nginx
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
externalTrafficPolicy: Local
type: NodePort
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
ports:
- name: http
port: 80
protocol: TCP
targetPort: http
- name: https
port: 443
protocol: TCP
targetPort: https
把以上內(nèi)容保存為 service-node-port.yml
,再運行 kubectl apply -f service-node-port.yml
寨腔。
接著為 grafana
創(chuàng)建 tls secret
速侈,信息可以隨便填
openssl genrsa -aes128 -out server.key 2048
openssl req -newkey rsa:2048 -nodes -keyout server.key -x509 -days 3650 -out server.crt
kubectl create secret tls prometheus-secret-tls --cert=server.crt --key=server.key -n prometheus-k8s
把以下內(nèi)容保存到 ingress.yml
,再運行 kubectl apply -f ingress.yml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: grafana
namespace: prometheus-k8s
annotations:
nginx.ingress.kubernetes.io/ingress.class: nginx
spec:
tls:
- hosts:
- grafana.local
secretName: prometheus-secret-tls
rules:
- host: grafana.local
http:
paths:
- path: /
backend:
serviceName: grafana
servicePort: 3000
把 127.0.0.1 grafana.local
追加到 C:\Windows\System32\drivers\etc\hosts
文件末迫卢。
配置 grafana
- 在瀏覽器打開
https://grafana.local
就可以看到grafana
網(wǎng)頁倚搬,因為是自簽名tls
證書,所以瀏覽器會警告乾蛤,忽略警告每界。
- 輸入
admin/admin
登錄,然后修改密碼
- 點擊
Add your first data source
家卖,選擇prometheus
眨层,填寫http://prometheus:9090
,然后點擊Save & Test
保存上荡。
- 點擊
+
趴樱,選擇import
,輸入4701
,點擊Load
-
prometheus
列選擇 prometheus伊佃, 然后點擊import
- 重復(fù)步驟
4-5
,把4701
換成6756
至此沛善,本教程結(jié)束航揉!
參考文章:
安裝適用于 Linux 的 Windows 子系統(tǒng)
Running Snaps on WSL2 (Insiders only for now)