前言
目前來看kubespray沒那么成熟(2019/03/19)。
調(diào)研過很多部署工具,第三方得剧董,官方得都試過。最終還是選擇了kubespray破停,只因?yàn)樗枪俜焦ぞ叱崧ィ约笆褂贸墒斓胊nsible方式。ansible是一個(gè)好工具真慢∫汶基于kubeadm,將kubernetes組件部署到容器上黑界。
已測試4節(jié)點(diǎn)部署管嬉,一個(gè)master皂林,三個(gè)node
kubernets版本:v1.13.4
本文章基于master分支: 3c4cbf133e76723fc0f360d15433795b08101e67
commit 3c4cbf133e76723fc0f360d15433795b08101e67
Author: Manuel Cintron <4176113+mcntrn@users.noreply.github.com>
Date: Wed Mar 13 15:58:25 2019 -0500
Adding ability to override dashboard replica count (#4344)
分享另外一個(gè)工具rancher,簡單到令人發(fā)指:
https://rancher.com/docs/rancher/v2.x/en/quick-start-guide/deployment/quickstart-manual-setup/#2-install-rancher
環(huán)境準(zhǔn)備
整體介紹
使用vmware虛擬機(jī)作為測試環(huán)境宠蚂。每臺虛擬機(jī)添加3張網(wǎng)卡式撼,2張nat,一張host-only求厕,實(shí)際上沒用到多余得2張網(wǎng)卡著隆,這里只是冗余配置。
全程使用root權(quán)限呀癣。
鏡像使用CentOS-7-x86_64-Minimal-1708.iso美浦。
虛擬機(jī)配置及功能介紹:
- master
控制節(jié)點(diǎn)。部署節(jié)點(diǎn)项栏。
1核浦辨,2G內(nèi)存,50G存儲
網(wǎng)卡一:nat模式沼沈,10.10.10.210 - node01
計(jì)算流酬,數(shù)據(jù)庫(etcd)。
1核列另,2G內(nèi)存芽腾,50G存儲
網(wǎng)卡一:nat模式,10.10.10.211 - node02
計(jì)算页衙,數(shù)據(jù)庫(etcd)摊滔。
1核,2G內(nèi)存店乐,50G存儲
網(wǎng)卡一:nat模式艰躺,10.10.10.212 - node03
計(jì)算,數(shù)據(jù)庫(etcd)眨八。
1核腺兴,2G內(nèi)存,50G存儲
網(wǎng)卡一:nat模式廉侧,10.10.10.213
基礎(chǔ)環(huán)境配置
1. 加速源配置(每臺機(jī)器均執(zhí)行)
yum源
yum install -y wget
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
yum clean all
yum makecache
pip源
mkdir ~/.pip
cat > ~/.pip/pip.conf << EOF
[global]
trusted-host=mirrors.aliyun.com
index-url=https://mirrors.aliyun.com/pypi/simple/
EOF
docker源
mkdir /etc/docker
cat > /etc/docker/daemon.json << EOF
{
"registry-mirrors": ["https://jzngeu7d.mirror.aliyuncs.com"]
}
EOF
2. 防火墻配置(每臺機(jī)器均執(zhí)行)
關(guān)閉firewalld
systemctl disable firewalld
systemctl stop firewalld
開啟iptables
yum install iptables -y
yum install iptables-services -y
systemctl start iptables.service
systemctl enable iptables.service
iptables -F
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
service iptables save
systemctl restart iptables.service
3. 配置ip轉(zhuǎn)發(fā)(每臺機(jī)器均執(zhí)行)
modprobe br_netfilter
echo '1' > /proc/sys/net/bridge/bridge-nf-call-iptables
sysctl -w net.ipv4.ip_forward=1
4. 安裝docker(每臺機(jī)器均執(zhí)行)
yum install -y yum-utils
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum makecache fast
yum install docker-ce-18.09.3 -y
systemctl enable docker
systemctl restart docker
5. 準(zhǔn)備部署節(jié)點(diǎn)環(huán)境(只在master執(zhí)行)
安裝基礎(chǔ)軟件
yum install -y epel-release ansible git gcc openssl-devel
yum install -y python36 python36-devel python36-pip
配置免密登陸
配置主機(jī)解析:
vi /etc/hosts
添加如下內(nèi)容
10.10.10.210 master
10.10.10.211 node01
10.10.10.212 node02
10.10.10.213 node03
生成ssh公私鑰
ssh-keygen
拷貝公鑰到目的機(jī)器页响,注意輸入密碼
ssh-copy-id -i /root/.ssh/id_rsa.pub root@master
ssh-copy-id -i /root/.ssh/id_rsa.pub root@node01
ssh-copy-id -i /root/.ssh/id_rsa.pub root@node02
ssh-copy-id -i /root/.ssh/id_rsa.pub root@node03
準(zhǔn)備kubespray
下載:
git clone https://github.com/kubernetes-incubator/kubespray.git /etc/kubespray
安裝依賴:
pip3.6 install -r /etc/kubespray/requirements.txt
pip3.6 install -r /etc/kubespray/contrib/inventory_builder/test-requirements.txt
pip3.6 install ruamel.yaml
生成配置文件:
cp -r /etc/kubespray/inventory/sample /opt/node
declare -a IPS=(10.10.10.210 10.10.10.211 10.10.10.212 10.10.10.213)
CONFIG_FILE=/opt/node/hosts.ini
python36 /etc/kubespray/contrib/inventory_builder/inventory.py ${IPS[@]}
替換被墻得源:
find /etc/kubespray -name '*.yml' | xargs -n1 -I{} sed -i "s/gcr\.io\/google_containers/gcr\.mirrors\.ustc\.edu\.cn\/google-containers/g" {}
find /etc/kubespray -name '*.yml' | xargs -n1 -I{} sed -i "s/gcr\.io\/google-containers/gcr\.mirrors\.ustc\.edu\.cn\/google-containers/g" {}
find /etc/kubespray -name '*.yml' | xargs -n1 -I{} sed -i 's/quay\.io/quay-mirror\.qiniu\.com/' {}
開始部署
編輯集群配置文件
vi /opt/node/hosts.ini
[kube-master]
master
[etcd]
node01
node02
node03
[kube-node]
node01
node02
node03
[k8s-cluster:children]
kube-master
kube-node
換源:vi /opt/node/group_vars/k8s-cluster/k8s-cluster.yml
kube_image_repo: "gcr.azk8s.cn/google-containers"
開啟ingress:vim /opt/node/group_vars/k8s-cluster/addons.yml
ingress_nginx_enabled: true
部署(在master節(jié)點(diǎn)上執(zhí)行)
ansible-playbook -i /opt/node/hosts.ini --become --become-user=root /etc/kubespray/cluster.yml
當(dāng) [file download], storage.googleapis.com 無法訪問而失敗時(shí)。多執(zhí)行幾次伏穆,這個(gè)網(wǎng)址是可以訪問得拘泞,只是速度很慢,導(dǎo)致ansible部署超時(shí)枕扫。還未找到合適得替換源陪腌。
部署完成后,查看集群:
kubectl get nodes
至此部署結(jié)束。
使用
1. etcd狀態(tài)查詢
在部署了etcd得節(jié)點(diǎn)執(zhí)行:
export ETCDCTL_API=3
etcdctl member list \
--endpoints=10.10.10.211:2379,10.10.10.212:2379,10.10.10.213:2379 \
--cacert /etc/pki/tls/certs/ca-bundle.crt \
--cert /etc/ssl/etcd/ssl/ca.pem \
--key /etc/ssl/etcd/ssl/ca-key.pem
2. kubernetes簡單使用诗鸭。
結(jié)構(gòu)簡單介紹
宏觀介紹兩層結(jié)構(gòu):構(gòu)建服務(wù) -- 發(fā)布服務(wù)
構(gòu)建服務(wù)
k8s將一組互相關(guān)聯(lián)得容器放在一個(gè)pod上染簇,由pod暴露端口提供基礎(chǔ)服務(wù)。
k8s提供deployment概念用于構(gòu)建pod强岸。
發(fā)布服務(wù)
發(fā)布服務(wù)就是讓別人訪問我們得pod锻弓。這里得“別人”可以是集群內(nèi)部,也可以是集群外得網(wǎng)絡(luò)蝌箍。
k8s提供service概念用于發(fā)布服務(wù)青灼。
service主要包含4種:
- ClusterIP:默認(rèn)方式,只有集群節(jié)點(diǎn)內(nèi)可以訪問妓盲。
- NodePort:外部可以通過節(jié)點(diǎn)真實(shí)ip訪問杂拨。
- LoadBalancer:通過負(fù)載提供一個(gè)外部訪問點(diǎn)。需要和云平臺集成悯衬。
- ExternalName:外部可以通過域名訪問弹沽。比如 foo.bar.example.com。這里不介紹這種
啟動(dòng)一個(gè)簡單但齊全得應(yīng)用(master節(jié)點(diǎn)執(zhí)行)
- 構(gòu)建基礎(chǔ)服務(wù) -- deployment
這里演示兩個(gè)容器組成的一個(gè)3副本pod筋粗。由于通過pod暴露端口策橘,因此同一個(gè)pod內(nèi)的容器不能使用相同的端口。
創(chuàng)建deployment yml文件:vim k1_deployment.yaml
添加如下內(nèi)容:
apiVersion: apps/v1beta1 # for versions before 1.6.0 use extensions/v1beta1
kind: Deployment
metadata:
name: nginx-rabbitmq-deployment # deployment 名稱
spec:
replicas: 3 # pod 副本數(shù)
template:
metadata:
labels: # 標(biāo)簽娜亿,service在與pod關(guān)聯(lián)時(shí)使用此值
app: nginx-rabbitmq # 標(biāo)簽鍵值對
spec:
containers:
- name: nginx # 容器名稱
image: nginx:1.7.9 # 容器鏡像
ports: # 容器端口丽已,在這里也說成pod端口
- containerPort: 80
- name: rabbitmq
image: rabbitmq:3-management
ports:
- containerPort: 5671
- containerPort: 5672
- containerPort: 15671
- containerPort: 15672
env: # 容器環(huán)境變量
- name: RABBITMQ_DEFAULT_USER
value: user
- name: RABBITMQ_DEFAULT_PASS
value: password
創(chuàng)建 deployment:kubectl create -f k1_deployment.yaml
查看deployment:kubectl get deployments
查看deployment創(chuàng)建的pods:kubectl get pods
此時(shí)需要拉取鏡像,會耗費(fèi)一定時(shí)間創(chuàng)建暇唾。
- 發(fā)布服務(wù) -- service
這里使用NodePort類型促脉。
創(chuàng)建service文件:vim k1_node_service.yml
添加如下內(nèi)容:
kind: Service
apiVersion: v1
metadata:
name: nginx-rabbitmq-service-node
spec:
type: NodePort # service 類型辰斋,默認(rèn)為ClusterIP
selector: # 與deployment對應(yīng)的標(biāo)簽選擇器
app: nginx-rabbitmq # 標(biāo)簽鍵值對
ports:
- name: nginx # 若存在多個(gè)端口時(shí)策州,要添加名稱
protocol: TCP # 協(xié)議類型
targetPort: 80 # pod端口(容器端口)
port: 20000 # 集群內(nèi)部映射端口,不填會隨機(jī)宫仗。ClusterIP使用的端口够挂。
nodePort: 30000 # 集群節(jié)點(diǎn)映射端口,默認(rèn)范圍30000-32767藕夫。NodePort使用的端口孽糖。
- name: rabbitmq5671
protocol: TCP
targetPort: 5671
port: 20001
nodePort: 30001
- name: rabbitmq5672
protocol: TCP
targetPort: 5672
port: 20002
nodePort: 30002
- name: rabbitmq15671
protocol: TCP
targetPort: 15671
port: 20003
nodePort: 30003
- name: rabbitmq15672
protocol: TCP
targetPort: 15672
port: 20004
nodePort: 30004
創(chuàng)建service:kubectl create -f k1_node_service.yml
查看service:kubectl get service
使用chrome測試訪問:
瀏覽器地址填寫任意集群節(jié)點(diǎn)的ip地址,我這里使用10.10.10.210毅贮。30000是nginx办悟,30004是rabbitmq管理端口。
有興趣的也可以通過ClusterIP地址訪問滩褥,此類型地址只能在集群內(nèi)部可以訪問到病蛉。
比如:
curl 10.233.53.35:20000
UI
chrome瀏覽器訪問如下地址:
<MASTER_IP>:6443/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/
此時(shí)我們還沒有用戶去登陸,需先創(chuàng)建用戶。
在mster節(jié)點(diǎn)執(zhí)行如下命令:
- 創(chuàng)建用戶
創(chuàng)建用戶yml文件:vim dashboard-adminuser.yml
添加如下內(nèi)容:
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kube-system
執(zhí)行創(chuàng)建命令:kubectl create -f dashboard-adminuser.yml
- 綁定權(quán)限
創(chuàng)建綁定文件:vim dashboard-adminuser-binding.yml
添加如下內(nèi)容:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kube-system
執(zhí)行創(chuàng)建命令:kubectl create -f dashboard-adminuser-binding.yml
- 獲取登陸令牌:
kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk '{print $1}')
- 在登陸頁面選擇令牌铺然,輸入獲得的令牌即可登陸俗孝。
3. kubernetes擴(kuò)展使用
ingress
ingress一般用于http之類的代理。ingress實(shí)際上還是和nodePort類似魄健,使用安裝了ingress-controller的節(jié)點(diǎn)ip進(jìn)行訪問赋铝,未實(shí)現(xiàn)vip功能。
使用前面的nginx-rabbitmq deployment進(jìn)行測試ingress沽瘦。
1. nginx-rabbitmq-deployment
和前面一致
2. nginx-rabbitmq-service
這里使用ClusterIP類型革骨。
創(chuàng)建service文件:vim k1_cluster_service.yaml
kind: Service
apiVersion: v1
metadata:
name: nginx-rabbitmq-service-cluster
spec:
type: ClusterIP
selector: # 與deployment對應(yīng)的標(biāo)簽選擇器
app: nginx-rabbitmq # 標(biāo)簽鍵值對
ports:
- name: nginx # 若存在多個(gè)端口時(shí),要添加名稱
protocol: TCP # 協(xié)議類型
targetPort: 80 # pod端口(容器端口)
port: 20000 # 集群內(nèi)部映射端口析恋,不填會隨機(jī)
- name: rabbitmq5671
protocol: TCP
targetPort: 5671
port: 20001
- name: rabbitmq5672
protocol: TCP
targetPort: 5672
port: 20002
- name: rabbitmq15671
protocol: TCP
targetPort: 15671
port: 20003
- name: rabbitmq15672
protocol: TCP
targetPort: 15672
port: 20004
執(zhí)行創(chuàng)建命令:kubectl create -f k1_cluster_service.yaml
3. nginx-rabbitmq-ingress
用于代理nginx 和rabbitmq管理頁面
創(chuàng)建ingress文件:vim k1_ingress.yml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-rabbitmq-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/add-base-url: "true"
spec:
rules:
- http:
paths:
- path: /testNginx
backend:
serviceName: nginx-rabbitmq-service-cluster
servicePort: 20000
- path: /testRabbitMQ
backend:
serviceName: nginx-rabbitmq-service-cluster
servicePort: 20004
執(zhí)行創(chuàng)建命令:kubectl create -f k1_ingress.yml
查看ingress命令:kubectl get ingress
4. 訪問ingress地址
在chrome瀏覽器輸入安裝了ingress-controller節(jié)點(diǎn)的ip以及對應(yīng)path苛蒲。
我這里的環(huán)境為:
- 10.10.10.211/testRabbitmq
-
10.10.10.211/testNginx
訪問效果如下:
image.png
image.png
loadbalancer
負(fù)載一般用于ip代理。
使用節(jié)點(diǎn)的ip訪問服務(wù)始終不是好辦法绿满。自帶的loadbalancer需要與云平臺集成臂外。
集成得方式?jīng)]有環(huán)境,暫無法測試喇颁。
現(xiàn)嘗試漏健,keepalived+NodePort方式。
1. nginx-rabbitmq-deployment
直接使用前面得橘霎,無需重復(fù)創(chuàng)建蔫浆。
2. nginx-rabbitmq-service-node
直接使用前面創(chuàng)建得NodePort類型得service。
3. 部署keepalived
- 安裝keepalived
我這里在master節(jié)點(diǎn)和node03兩個(gè)節(jié)點(diǎn)上安裝姐叁。
兩個(gè)節(jié)點(diǎn)上均執(zhí)行:
yum install -y curl gcc openssl-devel libnl3-devel net-snmp-devel
yum install -y keepalived
- 配置keepalived
將兩個(gè)節(jié)點(diǎn)得配置文件做備份瓦盛。
兩個(gè)節(jié)點(diǎn)上均執(zhí)行:mv /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak
修改master節(jié)點(diǎn)得配置文件:vim /etc/keepalived/keepalived.conf
# global_defs中:
# smtp_server改為 127.0.0.1
# ----------
# vrrp_instance VI_1中:
# 1. interface改為與vip同一網(wǎng)段得網(wǎng)卡名稱
# 2. 在virtual_ipaddress中填寫想要得vip
# 3. 注意priority值為100,這是優(yōu)先級外潜,從節(jié)點(diǎn)得優(yōu)先級要比主節(jié)點(diǎn)得小原环。
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id LVS_DEVEL
vrrp_skip_check_adv_addr
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.10.10.250
}
}
修改node03節(jié)點(diǎn)得配置文件:vim /etc/keepalived/keepalived.conf
# global_defs中:
# smtp_server改為 127.0.0.1
# ----------
# vrrp_instance VI_1中:
# 1. interface改為與vip同一網(wǎng)段得網(wǎng)卡名稱
# 2. 在virtual_ipaddress中填寫想要得vip
# 3. 注意priority值為100,這是優(yōu)先級处窥,從節(jié)點(diǎn)得優(yōu)先級要比主節(jié)點(diǎn)得小嘱吗。
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id LVS_DEVEL
vrrp_skip_check_adv_addr
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 99
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.10.10.250
}
}
- 啟動(dòng)keepalived(兩個(gè)節(jié)點(diǎn)均執(zhí)行)
systemctl start keepalived
systemctl enable keepalived
- 測試keepalived
在master節(jié)點(diǎn)ip a
可以看到,ens33網(wǎng)卡多了一個(gè)vip地址滔驾。
使用chrome瀏覽器輸入vip+NodePort類型得端口即可訪問服務(wù)谒麦。
image.png
測試vip漂移:
在master節(jié)點(diǎn):systemctl stop keepalived
此時(shí)到node03節(jié)點(diǎn)ip a
可以看到,ens33網(wǎng)卡多了一個(gè)vip地址哆致。
使用chrome瀏覽器輸入vip+NodePort類型得端口訪問服務(wù)绕德。
image.png
持久化存儲(volume)
存儲方案很多,不再舉例摊阀。
參考:https://kubernetes.io/docs/concepts/storage/volumes/
由于卷是單點(diǎn)使用耻蛇,也就是只能某個(gè)節(jié)點(diǎn)使用剩瓶,這會導(dǎo)致其它節(jié)點(diǎn)得pod無法創(chuàng)建成功,當(dāng)然某些外部卷可以實(shí)現(xiàn)漂移城丧,但是依然只能同時(shí)只掛載在一個(gè)節(jié)點(diǎn)上(聽說最新得openstack cinder實(shí)現(xiàn)了卷共享掛載)拗慨。雖然實(shí)現(xiàn)了多副本功能概作,但是對于有狀態(tài)得服務(wù)徽职,這似乎不大有用枣抱。
個(gè)人經(jīng)驗(yàn),可能有誤蚊惯。
注意事項(xiàng)
1. externalIPs
此參數(shù)愿卸,類似于額外的clusterIP,外部不能訪問到截型。不要將此字段和節(jié)點(diǎn)ip置為相同趴荸。
排錯(cuò)
通過journalctl -xe
可以看到集群日志。
容器輸出到控制臺的日志宦焦,都會以 *-json.log 的命名方式保存在 /var/lib/docker/containers/ 目錄下发钝。
使用
kubectl create -f 為創(chuàng)建
kubectl apply -f 為更新