1. 程式人生 > >Kubernetes1.10HA高可用集群環境搭建

Kubernetes1.10HA高可用集群環境搭建

kubernetes k8s

k8s 高可用2個核心 apiserver master 和 etcd

  • 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,而如果當集群內部主機少於三臺時,etcdLeader選舉功能就出現問題,導致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的配置,這裏三臺分別設置的是etcd1etcd2etcd3

啟動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 apiserverhttps://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-managerhttps://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 schedulerhttps://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 masteretcd網絡授權的文件,這個需要在啟動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高可用集群環境搭建