Kubernetes1.10HA高可用集群環境搭建
etcd:(需高可用)集群的數據中心,用於存放集群的配置以及狀態信息,非常重要,如果數據丟失那麽集群將無法恢復;因此高可用集群部署首先就是etcd是高可用集群;
Apiserver:提供了資源操作的唯一入口,並提供認證、授權、訪問控制、API註冊和發現等機制。整個集群中其他角色只有通過Apiserver才能訪問etcd。CLI工具kubectl也是通過apiserver來對整體集群進行訪問控制。
Controller-manager:負責維護集群的狀態,比如故障檢測、自動擴展、滾動更新等。一組k8s master上同一時間只有一個controller-manager角色進行工作,因為要避免控制沖突。
Scheduler:負責資源的調度,按照預定的調度策略將Pod調度到相應的機器上。一組k8s master上同一時間只有一個scheduler角色進行工作,同樣因為要避免控制沖突。
Kubelet:負責維護容器的生命周期,同時也負責Volume(CVI)和網絡(CNI)的管理。為支持k8s master的高可用,由kubelet提供穩定的容器運行功能(static pod),通過運行容器的方式啟動
kube-proxy: 每個node上一個,負責service vip到endpoint pod的流量轉發,老版本主要通過設置iptables規則實現,新版1.9基於kube-proxy-lvs 實現
集群網絡結構:
網絡名稱 | 網絡範圍 |
SVC網絡 | 172.20.0.0/16 |
集群網絡 | 172.21.0.0/16 |
物理網絡 | 192.168.10.0/24 |
節點構造如下 :
節點ip | 節點角色 | hostname |
192.168.10.7 | node | node1 |
192.168.10.8 | node | node2 |
192.168.10.9 | master01+etcd | master1 |
192.168.10.10 | master02+etcd | master2 |
192.168.10.11 | master03+etcd | master3 |
由所有master節點提供一組VIP:192.168.10.6用來高可用
環境初始化
1.安裝之前關閉防火墻和selinux
systemctl stop firewalld
systemctl disable firewalld
[root@test ~]# getenforce
Disabled
2.所有節點需要設定/etc/sysctl.d/k8s.conf的系統參數。
cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl -p
安裝docker
yum install -y yum-utils device-mapper-persistent-data lvm2 net-tools conntrack-tools wget vim ntpdate libseccomp libtool-ltdl
yum -y install docker
systemctl enable docker && systemctl start docker
1.創建etcd高可用集群:
kuberntes 系統使用 etcd 存儲所有數據,本文檔介紹部署一個三節點高可用 etcd 集群的步驟,這三個節點復用 kubernetes master 機器
搭建etcd集群需要註意的是etcd最少需要三臺才能發揮其高可用的功能,因為etcd集群內部使用的是選舉制度,通過內部選舉一臺Leader,而如果當集群內部主機少於三臺時,etcd的Leader選舉功能就出現問題,導致Leader選舉失敗,從而etcd不能正常與外界通訊
yum -y install etcd
vim /etc/etcd/etcd.conf
#[Member]
ETCD_NAME="etcd1"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="http://當前服務器IP:2380"
ETCD_LISTEN_CLIENT_URLS="http://當前服務器IP:2379,http://127.0.0.1:2379"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://當前服務器IP:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://當前服務器IP:2379"
ETCD_INITIAL_CLUSTER="etcd1=http://192.168.10.9:2380,etcd2=http://192.168.10.10:2380,etcd3=http://192.168.10.11:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
vim /usr/lib/systemd/system/etcd.service //修改etcd啟動文件
WorkingDirectory=/var/lib/etcd/
EnvironmentFile=-/etc/etcd/etcd.conf
? 指定 etcd 的工作目錄為 /var/lib/etcd,數據目錄為 /var/lib/etcd,需在啟動服務前創建這兩個目錄;
? 註意三臺etcd的配置文件中ETCD_NAME的配置,這裏三臺分別設置的是etcd1、etcd2、etcd3。
啟動etcd服務:
待三臺etcd都搭建完成之後,可依次啟動(在etcd集群中如果只單獨啟動一臺etcd會出現報錯)
[root@master01 ~]# systemctl daemon-reload
[root@master01 ~]# systemctl start etcd
[root@master01 ~]# systemctl enable etcd
驗證集群服務:
[root@test ~]# etcdctl --endpoints=http://192.168.10.9:2379,http://192.168.10.10:2379,http://192.168.10.11:2379 cluster-health
member 8c632555af4d958d is healthy: got healthy result from http://192.168.10.10:2379
member bc34c6bd673bdf9f is healthy: got healthy result from http://192.168.10.11:2379
member ec065b41856af137 is healthy: got healthy result from http://192.168.10.9:2379
cluster is healthy
[root@test ~]#集群啟動正常
2.搭建k8s_master高可用集群
集群HA方案,我們可以用lvs或者nginx做4層lb負載
安裝ipvsadm管理工具
yum -y install ipvsadm
systemctl enable ipvsadm
配置LVS負載均衡服務
步驟1:在eth0網卡綁定VIP地址(虛擬ip)要能和本地通信,所以在同一網絡/24位
第一種方式:(重啟服務器失效,多用於臨時測試)
ip add add/del 192.168.10.6/24 dev ens33
第二種:修改配置文件(重啟也生效)
cp ifcfg-ens33 ifcfg-ens33:0
vim ifcfg-ens33:0
DEVICE=eth0:0 //虛擬網絡接口
ONBOOT=yes //系統啟動時激活
BOOTPROTO=static //使用靜態ip地址
IPADDR=192.168.10.6 //該虛擬網絡接口的ip
NETMASK=255.255.255.0 //子網掩碼,對應ip別名
GATEWAY=192.168.10.1 //網關,對應ip別名
HWADDR=00:10:5A:5E:B1:E4 //網卡MAC地址,無需更改
USERCTL=no //是否給予非root用戶設備管理權限
配置完成重啟網卡即可:
systemctl restart network
步驟2:清除當前所有LVS規則(-C)
ipvsadm -C
步驟3:設置tcp、tcpfin、udp鏈接超時時間(--set)
ipvsadm --set 30 5 60
表示tcp空閑等待時間為30 秒
客戶端關閉鏈接等待時間為5秒
udp空閑等待為60秒
步驟4:添加虛擬服務(-A),-t指定虛擬服務的IP端口,-s 指定調度算法wrr 權重輪詢 -p 指定會話保持時間
ipvsadm -A -t 192.168.10.6:8080 -s wrr -p 300(默認300s)
步驟5:將虛擬服務關聯到真實服務上(-a) -t 說明是tcp服務 -r指定真實服務的IP端口 -g LVS的DR模式 -w 指定權重
ipvsadm -a -t 192.168.10.6:8080 -r 192.168.10.9:8080 -g -w 1
ipvsadm -a -t 192.168.10.6:8080 -r 192.168.10.10:8080 -g -w 1
ipvsadm -a -t 192.168.10.6:8080 -r 192.168.10.11:8080 -g -w 1
保存配置:服務啟動的時候會讀取/etc/sysconfig/ipvsadm裏面的內容,並且逐行執行,否則啟動ipvsadm失敗。
ipvsadm-save > /etc/sysconfig/ipvsadm
systemctl restart ipvsadm
步驟6:查看配置結果(-ln)
ipvsadm -ln
[root@lvs ~]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.10.6:8080 wrr persistent 300
-> 192.168.10.9:8080 Route 3 0 0
-> 192.168.10.10:8080 Route 3 6 0
-> 192.168.10.11:8080 Route 3 7 0
[root@lvs ~]#
Master安裝:
下載最新的二進制版本並解壓縮。安裝包下載:https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.10.md#server-binaries
找到./kubernetes/server/kubernetes-server-linux-amd64.tar.gz並解壓縮那個。然後在解壓縮文件中,找到./kubernetes/server/bin包含所有必需的二進制文件的文件。
部署k8s遇到的問題:http://time-track.cn/deploy-kubernetes-in-ubuntu-14-04.html
我們也可以根據名稱直接從git上下載服務端所需要的組件(推薦)
用https協議下載會報錯,以不安全的方式連接至 dl.k8s.io,使用“--no-check-certificate”
mkdir /opt/soft
cd /opt/soft
wget https://dl.k8s.io/v1.10.3/kubernetes-server-linux-amd64.tar.gz --no-check-certificate
tar -zxf kubernetes-server-linux-amd64.tar.gz
cd /opt/soft/kubernetes/server/bin
cp kube-apiserver kube-controller-manager kube-scheduler kubectl /usr/bin/
開始創建master端主配置文件
配置文件參數詳解:https://blog.csdn.net/levy_cui/article/details/70229818
mkdir -p /etc/kubernetes
cd /etc/kubernetes/
vim config
#/etc/kubernetes/config文件同時被kube-apiserver,kube-controller-manager,kube-scheduler,kubelet,kube-proxy使用,在master主機上的config配置文件中的KUBE_MASTER需要填寫本機的IP地址,而node端的則需要填寫負載均衡的VIP。
KUBE_LOGTOSTDERR="--logtostderr=true" #日誌默認存儲方式,默認存儲在系統的journal服務中,設置為true後日誌不輸出到文件
KUBE_LOG_LEVEL="--v=0" #日誌等級
KUBE_ALLOW_PRIV="--allow-privileged=false" #如果設置為true,則k8s將允許在pod中運行擁有系統特權的容器應用,與docker run --privileged的功效相同
KUBE_MASTER="--master=http://192.168.10.9:8080" #kubernetes Master的apiserver地址和端口
vim apiserver:https://kubernetes.io/docs/reference/command-line-tools-reference/kube-apiserver/
KUBE_API_ADDRESS="--address=0.0.0.0" #aipServer的監聽地址,默認為127.0.0.1,若要配置集群,則要設置為0.0.0.0才能被其他主機找到
#KUBE_API_PORT="--port=8080" #apiserver的監聽端口,默認8080是用於接收http請求,6443用於接收https請求。可以不用寫
#KUBELET_PORT="--kubelet_port=10250" # kubelet的監聽端口,若只作為Master節點則可以不配置
KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=172.20.0.0/16" # service的地址範圍,用於創建service的時候自動生成或指定serviceIP使用
KUBE_ETCD_SERVERS="--etcd-servers=http://192.168.10.9:2379,http://192.168.10.10:2379,http://192.168.10.11:2379" #etcd地址
KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ResourceQuota" #為了避免做用戶認證,取消掉了ServiceAccount參數
KUBE_API_ARGS="--service-node-port-range=1-65535 --apiserver-count=3 --audit-log-maxage=30 --audit-log-maxbackup=3 --audit-log-maxsize=400 --audit-log-path=/var/lib/audit.log --event-ttl=1h" #此處可以添加其他配置
vim controller-manager:https://kubernetes.io/docs/reference/command-line-tools-reference/kube-controller-manager/
KUBE_CONTROLLER_MANAGER_ARGS="--leader-elect=true --address=127.0.0.1"
? --address 值必須為 127.0.0.1,因為當前 kube-apiserver 期望 scheduler 和 controller-manager 在同一臺機器;
vim scheduler:https://kubernetes.io/docs/reference/command-line-tools-reference/kube-scheduler/
KUBE_SCHEDULER_ARGS="--leader-elect=true --address=127.0.0.1"
? --address 值必須為 127.0.0.1,因為當前 kube-apiserver 期望 scheduler 和 controller-manager 在同一臺機器;
創建kube-apiserver的啟動配置文件:vim /usr/lib/systemd/system/kube-apiserver.service
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=network.target
After=etcd.service
[Service]
EnvironmentFile=-/etc/kubernetes/config
EnvironmentFile=-/etc/kubernetes/apiserver
ExecStart=/usr/bin/kube-apiserver \
$KUBE_LOGTOSTDERR \
$KUBE_LOG_LEVEL \
$KUBE_ETCD_SERVERS \
$KUBE_API_ADDRESS \
$KUBE_API_PORT \
$KUBE_ALLOW_PRIV \
$KUBE_SERVICE_ADDRESSES \
$KUBE_ADMISSION_CONTROL \
$KUBE_API_ARGS
Restart=on-failure
Type=notify
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
創建kube-controller-manager的啟動配置文件:vim /usr/lib/systemd/system/kube-controller-manager.service
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
[Service]
EnvironmentFile=-/etc/kubernetes/config
EnvironmentFile=-/etc/kubernetes/controller-manager
ExecStart=/usr/bin/kube-controller-manager \
$KUBE_LOGTOSTDERR \
$KUBE_LOG_LEVEL \
$KUBE_MASTER \
$KUBE_CONTROLLER_MANAGER_ARGS
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
創建kube-scheduler的啟動配置文件:vim /usr/lib/systemd/system/kube-scheduler.service
[Unit]
Description=Kubernetes Scheduler Plugin
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
[Service]
EnvironmentFile=-/etc/kubernetes/config
EnvironmentFile=-/etc/kubernetes/scheduler
ExecStart=/usr/bin/kube-scheduler \
$KUBE_LOGTOSTDERR \
$KUBE_LOG_LEVEL \
$KUBE_MASTER \
$KUBE_SCHEDULER_ARGS
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
啟動服務(三臺服務都搭建完成之後先啟動etcd然後在啟動其他服務):
[root@master01 ~]# systemctl daemon-reload
[root@master01 ~]# systemctl start etcd kube-apiserver kube-controller-manager kube-scheduler
[root@master01 ~]# systemctl enable etcd kube-apiserver kube-controller-manager kube-scheduler
至此,kubernetes master端的組件已經搭建完成,我們在三臺master主機上重復以上搭建步驟,註意配置文件中需要修改IP地址的地方,以及需要先啟動etcd,然後依次啟動kube-apiserver,kube-controller-manager,kube-scheduler。
驗證master節點功能:kubectl get cs
[root@test ~]# kubectl get cs
NAME STATUS MESSAGE ERROR
scheduler Healthy ok
controller-manager Healthy ok
etcd-0 Healthy {"health": "true"}
etcd-1 Healthy {"health": "true"}
etcd-2 Healthy {"health": "true"}
Node安裝:
每一臺都搭建flanneld、docker、kubelet、kube-proxy這四個組件及服務
kubelet是Master在Node節點上的Agent,管理本機運行容器的生命周期,比如創建容器、 Pod掛載數據卷、下載secret、獲取容器和節點狀態等工作。 kubelet將每個Pod轉換成一組容器。
kube-proxy在Node節點上實現Pod網絡代理,維護網絡規則和四層負載均衡工作。
scp kubelet kube-proxy [email protected]:/usr/bin/
scp kubelet kube-proxy [email protected]:/usr/bin/
yum -y install docker flannel
vim /etc/sysconfig/flanneld
FLANNEL_ETCD_ENDPOINTS="http://192.168.10.9:2379,http://192.168.10.10:2379,http://192.168.10.11:2379" #flannel從etcd中讀取配置
FLANNEL_ETCD_PREFIX="/coreos.com/network" #/coreos.com/network 是master端etcd網絡授權的文件,這個需要在啟動flanneld之前在master端手動生成
FLANNEL_OPTIONS="-iface=ens33"
在master端生成網絡授權文件/coreos.com/network:
etcdctl --endpoints=http://192.168.10.9:2379,http://192.168.10.10:2379,http://192.168.10.11:2379 mk /coreos.com/network/config '{"Network":"172.21.0.0/16"}'
查看是否添加成功
etcdctl get /coreos.com/network/config
如果etcd不是集群可以用下面的命令:
創建node端主配置文件:
mkdir /etc/kubernetes
vim /etc/kubernetes/config
KUBE_LOGTOSTDERR="--logtostderr=true"
KUBE_LOG_LEVEL="--v=0"
KUBE_ALLOW_PRIV="--allow-privileged=false"
KUBE_MASTER="--master=http://192.168.10.6:8080" #這裏的master地址是負載均衡的VIP地址
創建kubelet服務配置文件:
vim /etc/kubernetes/kubelet
KUBELET_ADDRESS="--address=192.168.10.7"
KUBELET_HOSTNAME="--hostname-override=192.168.10.7"
KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=registry.access.redhat.com/rhel7/pod-infrastructure:latest"
KUBELET_ARGS="--fail-swap-on=false --cgroup-driver=systemd --enable-server=true --enable-debugging-handlers=true --kubeconfig=/var/lib/kubelet/kubeconfig --cluster-dns=172.20.0.100 --cluster-domain=cluster.local. --hairpin-mode promiscuous-bridge --serialize-image-pulls=false"
Kubernetes v1.8+ 要求關閉系統 Swap,若不關閉則需要修改kubelet 設定參數--fail-swap-on=false
然後還要添加一個配置文件,因為1.9.0在kubelet裏不再使用KUBELET_API_SERVER來跟API通信,而是通過別一個yaml的配置來實現, 描述了kubelet訪問apiserver的方式。
參考:https://www.58jb.com/html/180.html
mkdir -p /var/lib/kubelet
vim /var/lib/kubelet/kubeconfig
apiVersion: v1
kind: Config
users:
- name: kubelet
clusters:
- name: kubernetes
cluster:
server: http://192.168.10.6:8080
contexts:
- context:
cluster: kubernetes
user: kubelet
name: service-account-context
current-context: service-account-context
創建kubelet啟動service配置文件:
vim /usr/lib/systemd/system/kubelet.service
[Unit]
Description=Kubernetes Kubelet Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=docker.service
Requires=docker.service
[Service]
WorkingDirectory=/var/lib/kubelet
EnvironmentFile=-/etc/kubernetes/config
EnvironmentFile=-/etc/kubernetes/kubelet
ExecStart=/usr/bin/kubelet \
$KUBE_LOGTOSTDERR \
$KUBE_LOG_LEVEL \
$KUBELET_API_SERVER \
$KUBELET_ADDRESS \
$KUBELET_PORT \
$KUBELET_HOSTNAME \
$KUBE_ALLOW_PRIV \
$KUBELET_POD_INFRA_CONTAINER \
$KUBELET_ARGS
Restart=on-failure
[Install]
WantedBy=multi-user.target
創建kube-proxy服務配置文件:
vim /etc/kubernetes/proxy
KUBE_PROXY_ARGS="--proxy-mode=userspace --bind-address=0.0.0.0 --hostname-override=192.168.10.7"
創建kube-proxy啟動service配置文件
vim /usr/lib/systemd/system/kube-proxy.service
[Unit]
Description=Kubernetes Kube-Proxy Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=network.target
[Service]
EnvironmentFile=-/etc/kubernetes/config
EnvironmentFile=-/etc/kubernetes/proxy
ExecStart=/usr/bin/kube-proxy \
$KUBE_LOGTOSTDERR \
$KUBE_LOG_LEVEL \
$KUBE_MASTER \
$KUBE_PROXY_ARGS
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
啟動服務
systemctl daemon-reload
systemctl start flanneld kubelet kube-proxy docker
systemctl enable flanneld kubelet kube-proxy docker
查看節點是否獲取到
[root@test ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 172.20.0.1 <none> 443/TCP 16h
[root@test ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
192.168.10.7 Ready <none> 16h v1.10.3
192.168.10.8 Ready <none> 16h v1.10.3
[root@test ~]#
OK!
Kubernetes1.10HA高可用集群環境搭建