繼上次k8s集群部署完成之后单起,接下來開始對集群做簡單的測試抱怔。
首先這里文件存儲的方式采用nfs,因此先得部署本地nfs服務器來做后續(xù)測試嘀倒。
環(huán)境準備
- nfs服務器centos7.8(阿里云ECS)
機器名: k8s-master
公網(wǎng)ip:47.9x.17x.9x
- nfs客戶端centos7.9(騰訊云EVM)
機器名: k8s-node1
公網(wǎng)ip:121.4x.9x.7x
nfs服務器搭建(服務器和客戶端都需要安裝)
yum -y install rpcbind nfs-utils
# 啟動nfs野蝇,并開機自啟
systemctl start rpcbind
systemctl enable rpcbind
# NFS依賴rpcbind進行通訊,所以要先啟動rpcbind
systemctl start nfs-server
systemctl enable nfs-server
# 查看服務是否已啟動(服務端和客戶端都要測試)
rpcinfo -p localhost
一般showmount -e localhost命令都是好使的括儒,在使用showmount -e 公網(wǎng)ip時會顯示如下問題
showmount -e 47.9x.17x.9x
clnt_create: RPC: Port mapper failure - Timed out
出現(xiàn)這問題就說明nfs的端口沒有對外開放,服務端需要開放的端口如下:
協(xié)議 | 方向 | 端口 | 源地址 | 說明 |
---|---|---|---|---|
UDP | 入站 | 111/111 | 0.0.0.0/0 | nfs portmapper |
TCP | 入站 | 111/111 | 0.0.0.0/0 | nfs portmapper |
UDP | 入站 | 20048/20048 | 0.0.0.0/0 | nfs mountd |
TCP | 入站 | 20048/20048 | 0.0.0.0/0 | nfs mountd |
TCP | 入站 | 2049/2049 | 0.0.0.0/0 | nfs |
UDP | 入站 | 2049/2049 | 0.0.0.0/0 | nfs |
至此绕沈,nfs的服務端和客戶端就安裝成功了,客戶端不用開通這些端口帮寻。
在nfs服務器創(chuàng)建 掛載目錄
mkdir -pv /data/volumes
然后可以再這里目錄里創(chuàng)建 nginx default v2 v3 v5 這5個目錄供后續(xù)測試使用
# 可以共享給指定IP(192.168.1.7)乍狐,也可以共享給指定網(wǎng)段(192.168.1.0/16),還可以共享給所有IP(*).rw代表讀寫權限固逗。
vim /etc/exports
/data/volumes/nginx 47.9x.17x.9x(insecure,rw,async,no_root_squash)
/data/volumes/nginx 121.4x.9x.7x(insecure,rw,async,no_root_squash)
此處我將兩臺服務器都配置了掛載目錄的權限
/etc/exports配置文件中權限參數(shù)常用的有如下五個:
ro只讀權限
rw讀寫權限
sync同步寫入內(nèi)存與磁盤當中
no_all_squash保留共享文件的UID和GID(默認)
no_root_squash使得root用戶具有根目錄的完全訪問權限
# 重新讀取配置文件浅蚪,而不中斷服務
exportfs -rv
# 成功后在兩臺服務器上都重新執(zhí)行看目錄是否掛載成功
showmount -e 47.9x.17x.9x
可以看到目錄共享成功
節(jié)點上將掛載點掛載到nfs服務的共享目錄(選做藕帜,這是測試nfs用,不涉及到k8s后續(xù)操作)
mount -t nfs 47.9x.17x.9x:/data/volumes /mnt
可能會報錯誤: mount: can't find /mnt in /etc/fstab
首先解釋下命令含義惜傲,mount常用來掛載文件系統(tǒng)洽故,本質(zhì)nfs就是一個文件系統(tǒng)妹窖。上面命令就是將客戶端目錄/data/volumes做為掛載點栖茉,掛載到nfs服務端的共享目錄/mnt下泊交,nfs服務端的ip是47.9x.17x.9x摹恰。通俗講就是將客戶端目錄/data/volumes與服務端的共享目錄/mnt實現(xiàn)共享辟犀。
執(zhí)行此命令之前必須保證nfs服務端的export文件內(nèi)已經(jīng)配置/mnt為共享目錄了箩退。
接著繼續(xù)看我們的問題玉转,/etc/fstab文件是配置nfs掛載點的文件爪模,問題也就很明顯了开镣,我們需要在該文件的末尾新增一行配置一個掛載點刀诬,配置如下。
47.9x.17x.9x:/mnt /data/volumes nfs default 0 0
第一列是需要掛載的文件系統(tǒng)或者是存儲設備或者是需要掛載的目錄邪财。
第二列是掛載點陕壹,掛載點就是客戶端掛載的目錄。
第三列是文件系統(tǒng)或者是分區(qū)的類型(其實分區(qū)類型就是中文件系統(tǒng))
第四列是以何種形式掛載树埠,比如rw讀寫, auto自動掛載,ro只讀等等參數(shù)帐要。不過最常用的是default。default是rw弥奸,suid榨惠,dev,exec盛霎,auto赠橙,nouser,async等的組合愤炸。
第五列為dump選項期揪,設置是否讓備份程序dump備份文件系統(tǒng),0為忽略规个,1為備份凤薛。
第六列為fsck選項,告訴fsck程序以什么順序檢查文件系統(tǒng)诞仓,0為忽略缤苫。
設置完畢后重新執(zhí)行掛載
mount -t nfs 47.9x.17x.9x:/data/volumes /mnt
成功后分別在nfs服務器和節(jié)點服務器做文件測試,會發(fā)現(xiàn)是雙方同步
卸載掛載目錄
umount /mnt
如果提示設備繁忙墅拭,那么先退出當前連接活玲,重新連接服務器再執(zhí)行該命令
創(chuàng)建k8s集群的pv
PV 的全稱是:PersistentVolume(持久化卷),是對底層的共享存儲的一種抽象,PV 由管理員進行創(chuàng)建和配置舒憾,它和具體的底層的共享存儲技術的實現(xiàn)方式有關镀钓,比如 Ceph、GlusterFS镀迂、NFS 等丁溅,都是通過插件機制完成與共享存儲的對接。
執(zhí)行以下腳本
vim pv.yml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-nginx
labels:
name: pv-nginx
spec:
nfs:
path: /data/volumes/nginx
server: 47.9x.17x.9x
accessModes: ['ReadWriteMany', 'ReadWriteOnce']
capacity:
storage: 500Mi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv002
labels:
name: pv002
spec:
nfs:
path: /data/volumes/v2
server: 47.9x.17x.9x
accessModes: ['ReadWriteMany', 'ReadWriteOnce']
capacity:
storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv003
labels:
name: pv003
spec:
nfs:
path: /data/volumes/v3
server: 47.9x.17x.9x
accessModes: ['ReadWriteMany', 'ReadWriteOnce']
capacity:
storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-default
labels:
name: pv-default
spec:
nfs:
path: /data/volumes/default
server: 47.9x.17x.9x
accessModes: ['ReadWriteMany', 'ReadWriteOnce']
capacity:
storage: 4Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv005
labels:
name: pv005
spec:
nfs:
path: /data/volumes/v5
server: 47.9x.17x.9x
accessModes: ['ReadWriteMany', 'ReadWriteOnce']
capacity:
storage: 7Gi
執(zhí)行
kubectl apply -f pv.yml
查看創(chuàng)建好的5個pv探遵】呱停可以發(fā)現(xiàn)這里pv的存儲方式采用的是nfs
kubectl get pv -o wide
可以看到5個新建的pv狀態(tài)都是未綁定狀態(tài),請忽略上述的pv-nginx的狀態(tài)别凤,這是我后續(xù)綁定了pvc造成的,后續(xù)會說明领虹。
pv創(chuàng)建好之后规哪,接下來需要使用它。
創(chuàng)建pvc
PVC的全稱是: PersistenVolumeClaim (持久化卷聲明)塌衰,PVC是用戶存儲的一種聲明诉稍,PVC和Pod比較類型,Pod是消耗節(jié)點最疆,PVC消耗的是PV資源杯巨,Pod可以請求CPU的內(nèi)存,而PVC可以請求特定的存儲空間和訪問模式努酸。對于真正存儲的用戶不需要關心底層的存儲實現(xiàn)細節(jié)服爷,只需要直接使用PVC即可
vim pvc-nginx.yml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-nginx
namespace: nginx
spec:
accessModes: ['ReadWriteMany']
resources:
requests:
storage: 500Mi
上述代碼可以看到pvc其實并沒有指定需要使用哪個pv,只是說明了需要的存儲空間是500M(G的寫法是Gi)获诈,然后訪問模式是多次讀寫(ReadWriteMany)仍源。
首先需要明白一點,存儲卷 (PV) 的訪問模式 () 決定的是 PV 支持那幾種被節(jié)點 (nodes) 掛載的方式舔涎,笼踩。一個存儲卷 (PV) 可支持多種模式。幾種模式如下:
* (RWO) ReadWriteOnce 可被一個節(jié)點讀寫掛載
* (ROX) ReadOnlyMany 可被多個節(jié)點只讀掛載
* (RWX) ReadWriteMany 可被多個節(jié)點讀寫掛載
執(zhí)行
kubectl apply -f pvc-nginx.yml
然后在查看pv使用情況亡嫌,就會發(fā)現(xiàn)是我上面截圖的那種情況嚎于,pv會根據(jù)pvc申請的空間大小自動去匹配合適的pv卷,然后進行綁定挟冠,剛好pv-nginx滿足他的需要于购,因此nginx和pvc綁定成功。
pvc的查看命令是:
創(chuàng)建nginx deployment
先單獨創(chuàng)建nginx 的namespace
kubectl create namespace nginx
接下來使用nginx的測試都在nginx namespace中進行知染。
創(chuàng)建nginx configmap文件
configmap文件用來存儲nginx.conf配置文件价涝。之所以將nginx的配置文件和nginx的pod分開部署,是由于在大部分情況下nginx服務本身其實并不會改動持舆,改動的也只是nginx配置文件色瘩,所以單獨拿出來部署伪窖。
而部署nginx配置文件其實有很多種方式,可以使用configmap居兆,也可以使用pvc來將配置文件掛載到本地或者其他的儲存文件系統(tǒng)中去覆山。
另外要注意的一點是,configmap文件可以隨時更改泥栖。但是nginx配置文件更改之后簇宽,通常情況下需要nginx reload。而且nginx采用deployment部署的話吧享,你即使重新apply -f deployment文件的話魏割,它也不會起作用。因為此時的deployment文件并沒有任何改動钢颂,k8s會認為該pod沒有做變動钞它,不會重新啟動pod。這一點在后續(xù)會說明殊鞭,可以采用別的方式來強制apply -f deplyment文件遭垛。
vim nginx-configmap.yml
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-configmap
namespace: nginx
data:
nginx_conf: |-
#user nobody;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /data {
root /usr/share/nginx;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
}
此處的nginx 添加了/data 映射是為了后續(xù)訪問index.html首頁時能實時打印出當前節(jié)點的hostname,以便能明顯區(qū)分出k8s對pod的負載均衡功能操灿。
執(zhí)行configmap文件
kubectl apply -f nginx-configmap.yml
查看cm
kubectl -n nginx get cm -o wide
創(chuàng)建nginx deployment文件
vim nginx-deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx-cluster
name: nginx-cluster
namespace: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx-cluster
template:
metadata:
labels:
app: nginx-cluster
spec:
containers:
- name: nginx-cluster
image: nginx
command:
- /bin/sh
args:
- '-c'
- |
set -ex
mkdir -pv /usr/share/nginx/data
echo $HOSTNAME>/usr/share/nginx/data/hostname.data
exec nginx -g 'daemon off;'
env:
- name: RESTART_
value: v202012101554
ports:
- containerPort: 80
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
- name: nginx
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
volumes:
- name: html
persistentVolumeClaim:
claimName: pvc-nginx
- name: nginx
configMap:
name: nginx-configmap
items:
- key: nginx_conf
path: nginx.conf
這里著重說下command锯仪、args和env三個屬性,command屬性用來輸入命令趾盐,一般建議就輸入/bin/sh即可庶喜,想執(zhí)行多條shell命令的話,在args中輸入救鲤,-c用來解析后面的字符串執(zhí)行其中的指令溃卡,文件中的命令很簡單,先創(chuàng)建目錄蜒简,再將主機名輸入該目錄下的文件中存儲瘸羡。唯一注意的是最后的這條命令 exec nginx -g 'daemon off;' 。
Docker 容器啟動時搓茬,默認會把容器內(nèi)部第一個進程犹赖,也就是pid=1的程序,作為docker容器是否正在運行的依據(jù)卷仑,如果 docker 容器pid=1的進程掛了峻村,那么docker容器便會直接退出。
Docker未執(zhí)行自定義的CMD之前锡凝,nginx的pid是1粘昨,執(zhí)行到CMD之后,nginx就在后臺運行,bash或sh腳本的pid變成了1张肾。
所以一旦執(zhí)行完自定義CMD芭析,nginx容器也就退出了。
上述這一點在今后部署服務時一定要注意吞瞪。
而env中的環(huán)境參數(shù)就是用來控制deployment文件強制重啟的馁启,每次想重新啟動deployment的話,直接修改RESATRT_的值芍秆,然后再執(zhí)行 kubectl apply -f deployment.yml 即可惯疙。
創(chuàng)建nginx deployment
kubectl apply -f nginx-deployment.yml
查看運行情況
kubectl -n nginx get pod -o wide
會發(fā)現(xiàn)nginx的兩個pod已經(jīng)運行起來了,它運行的機器是由k8s自行調(diào)度的妖啥,本文這里是剛好倆pod都調(diào)度到了k8s-node1節(jié)點上霉颠。
現(xiàn)在在k8s-mater節(jié)點和k8s-node1節(jié)點分別ping這倆ip地址。如果都能ping通的話說明集群間的地址通訊沒有問題荆虱。
將index.html文件放入nfs服務器中的/data/volumes/nginx目錄下面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div>
hello蒿偎。 <span id="out"></span>
</div>
</body>
<script>
function httpGet(url) {
var xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", url, false); // false: wait respond
xmlHttp.send(null);
return xmlHttp.responseText;
}
function f() {
var url = window.location.protocol + "http://" + window.location.host + "/data/hostname.data";
console.log(url);
document.getElementById('out').innerHTML = httpGet(url);
}
f();
</script>
</html>
再檢查 curl 10.244.1.3:80 或者curl 10.244.1.2:80 看能不能請求成功。
都成功的話現(xiàn)在部署svc克伊,通過svc來對外暴露pod
創(chuàng)建nginx service
vim nginx-service.yml
apiVersion: v1
kind: Service
metadata:
name: nginx-service #定義service名稱為nginx-service
namespace: nginx
labels:
app: nginx-service #為service打上app標簽
spec:
type: NodePort #使用NodePort方式開通酥郭,在每個Node上分配一個端口作為外部訪問入口
selector:
app: nginx-cluster
ports:
- port: 8000 #port是k8s集群內(nèi)部訪問service的端口华坦,即通過clusterIP: port可以訪問到某個service
targetPort: 80 #targetPort是pod的端口愿吹,從port和nodePort來的流量經(jīng)過kube-proxy流入到后端pod的targetPort上,最后進入容器
nodePort: 32500 #nodePort是外部訪問k8s集群中service的端口惜姐,通過nodeIP: nodePort可以從外部訪問到某個service
執(zhí)行
kubectl apply -f nginx-serivce.yml
查看
kubectl get svc -n nginx -o wide
可以看到svc也部署成功
先測試看該ip地址能否在master和node1節(jié)點上都能ping通犁跪,
檢查 curl 10.1.220.172:8000 能否請求成功
都沒問題的話即可以使用外用ip訪問32500端口了。
47.9x.17x.9x和121.4x.9x.7x這兩個外網(wǎng)地址訪問32500都可以
多開幾個客戶端請求地址查看歹袁】姥埽可以發(fā)現(xiàn)每次返回的主機名都不一樣。
至此条舔,驗證工作完成枫耳。接下來是完善k8s生態(tài),待后續(xù)孟抗。