阿里雲ECS自建K8S集群
一、概述(官方建議)
集群規划
目前在創建Kubernetes集群時,存在着使用很多小規格ECS的現象,這樣做有以下弊端:
小規格Woker ECS的網絡資源受限。
如果一個容器基本可以占用一個小規格ECS,此ECS的剩余資源就無法利用(構建新的容器或者是恢復失敗的容器),在小規格ECS較多的情況下,存在資源浪費。
使用大規格ECS的優勢:
網絡帶寬大,對於大帶寬類的應用,資源利用率高。
容器在一台ECS內建立通信的比例增大,減少網絡傳輸。
拉取鏡像的效率更高。因為鏡像只需要拉取一次就可以被多個容器使用。而對於小規格的ECS拉取鏡像的次數就會增多,若需要聯動ECS伸縮集群,則需要花費更多的時間,反而達不到立即響應的目的。
選擇Master節點規格
通過容器服務創建的Kubernetes集群,Master節點上運行着etcd、kube-apiserver、kube-controller等核心組件,對於Kubernetes集群的穩定性有着至關重要的影響,對於生產環境的集群,必須慎重選擇Master規格。Master規格跟集群規模有關,集群規模越大,所需要的Master規格也越高。
說明 您可從多個角度衡量集群規模,例如節點數量、Pod數量、部署頻率、訪問量。這里簡單的認為集群規模就是集群里的節點數量。
對於常見的集群規模,可以參見如下的方式選擇Master節點的規格(對於測試環境,規格可以小一些。下面的選擇能盡量保證Master負載維持在一個較低的水平上)。
節點規模
|
Master規格
|
1~5個節點
|
4核8 GB(不建議2核4 GB)
|
6~20個節點
|
4核16 GB
|
21~100個節點
|
8核32 GB
|
100~200個節點
|
16核64 GB
|
選擇Worker節點規格
ECS規格要求:CPU大於等於4核,且內存大於等於8 GiB。
確定整個集群的日常使用的總核數以及可用度的容忍度。
例如:集群總的核數有160核,可以容忍10%的錯誤。那么最小選擇10台16核ECS,並且高峰運行的負荷不要超過160*90%=144核。如果容忍度是20%,那么最小選擇5台32核ECS,並且高峰運行的負荷不要超過160*80%=128核。這樣就算有一台ECS出現故障,剩余ECS仍可以支持現有業務正常運行。
確定CPU:Memory比例。對於使用內存比較多的應用例如Java類應用,建議考慮使用1:8的機型。
此次項目資源分配(數據庫、中間件、鏡像倉庫Harbor除外):(在原有的開發測試服務器上搭建)
序號
|
IP
|
CPU(核)
|
內存(GB)
|
磁盤(GB)
|
部署應用
|
備注說明
|
1
|
172.18.215.10
|
2
|
8
|
60
|
k8s master[1]
|
kube-apiserver
SLB內網負載均衡
172.18.215.23
|
2
|
172.18.215.15
|
2
|
4
|
100
|
k8s master[2]
|
|
3
|
172.18.215.11
|
2
|
8
|
100
|
k8s worker[1]
|
nginx-ingress
SLB公網負載均衡
120.78.145.173
|
4
|
172.18.215.16
|
2
|
4
|
100
|
k8s worker[2]
|
|
5
|
172.18.215.12
|
2
|
8
|
100
|
k8s haproxy1
|
kube-apiserver
SLB內網負載均衡
172.18.215.23
|
6
|
172.18.215.133
|
2
|
8
|
100
|
k8s haproxy2
|
阿里雲踩坑記錄


架構方案


二、系統准備工作
所有機器配置好如下環境:
• 關閉防火牆,selinux
systemctl stop firewalld && systemctl disable firewalld
• 做好解析
cat >> /etc/hosts << EOF
192.168.10.11 k8s-master-01
192.168.10.12 k8s-master-02
192.168.10.21 k8s-work-01
192.168.10.22 k8s-work-02
192.168.10.100 k8s-vip
EOF
• 配置好時間同步
yum -y install vim curl wget unzip ntpdate net-tools ipvsadm ipset sysstat conntrack libseccomp
ntpdate
ntp1.aliyun.com && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
• 禁用swap分區
swapoff -a && sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
• 配置內核參數
cat > /etc/sysctl.d/kubernetes.conf <<EOF
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
net.ipv6.conf.all.disable_ipv6=1
net.ipv4.ip_forward=1
net.ipv4.tcp_tw_recycle=0
vm.swappiness=0
fs.file-max=2000000
fs.nr_open=2000000
fs.inotify.max_user_instances=512
fs.inotify.max_user_watches=1280000
EOF
modprobe br_netfilter && sysctl -p /etc/sysctl.d/kubernetes.conf
• 加載ipvs模塊:
yum install ipset ipvsadm -y
cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
EOF
chmod 755 /etc/sysconfig/modules/ipvs.modules
sh /etc/sysconfig/modules/ipvs.modules
lsmod | grep -e ip_
•升級內核(版本較新的不需要此步)
[root@master1 ~]# yum -y update kernel
[root@master1 ~]# shutdown -r now
•安裝nfs文件共享(可選)
yum -y install nfs-common nfs-utils rpcbind
systemctl start nfs && systemctl enable nfs
systemctl start rpcbind && systemctl enable rpcbind
三、部署過程
1. 安裝配置docker # 所有節點
2. 安裝軟件 # 所有節點
3. 安裝負載均衡及高可用 # 所有 Master節點 使用阿里雲的SLB
4. 初台化Master1 # Master1節點
5. 加入Master節點 # 其它 Master節點
6. 加入Worker節點 # 所有 Node節點
7. 配置kubectl # 所有需要的節點
8. 部署網絡插件 # Master1節點
3.1 安裝配置docker
在所有節點安裝
vim docker_install.sh
#/bin/bash
curl
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -o /etc/yum.repos.d/docker-ce.repo
yum -y install docker-ce
[ ! -d /etc/docker ] && mkdir /etc/docker
[ ! -d /data/docker ] && mkdir -p /data/docker
cat > /etc/docker/daemon.json <<- EOF
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3"
},
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true"
],
"data-root": "/data/docker",
"max-concurrent-downloads": 5,
"storage-driver": "overlay2",
"registry-mirrors": [
]
}
EOF
systemctl enable --now docker
bash docker_install.sh
3.2 安裝軟件
在所有節點安裝
cat >> /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=
https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
yum install -y kubeadm-1.18.10-0 kubelet-1.18.10-0 kubectl-1.18.10-0 ipvsadm
可用 yum list --showduplicates|egrep kubeadm 查看有哪些可用版本
設置開機啟動kubelet
# systemctl enable kubelet
2.3 安裝負載均衡
在所有Master節點操作
Kubernetes master 節點運行如下組件:
- kube-apiserver
- kube-scheduler
- kube-controller-manager
由於阿里雲的VIP需要申請havip,暫且使用阿里雲的SLB,所以不需要keepalived
在所有k8s-haproxy節點操作(方案二)
Haproxy
mkdir -p /data/k8s/haproxy-etc
vim /data/k8s/haproxy-etc/haproxy.cfg
globaz
daemon
maxconn 65535
defaults
mode http
timeout connect 5000ms
timeout client 5000ms
timeout server 5000ms
listen stats
mode http
bind 0.0.0.0:8442
stats enable
log global
stats uri /haproxy-status
stats auth haadmin:123456
listen k8s-control-plane
bind 0.0.0.0:8443
mode tcp
log global
balance roundrobin
option tcplog
server dev 172.18.215.10:6333 check weight 1 maxconn 2000
server devmaster2 172.18.215.15:6333 check weight 1 maxconn 2000
docker run -d \
--name k8s-haproxy \
--restart=unless-stopped \
--net=host \cd
-v /data/k8s/haproxy-etc:/usr/local/etc/haproxy:ro \
haproxy:2.4.1-alpine
3.4 初始化master1
任選一台master節點,修改當前master節點 /etc/hosts,把 k8sapi 對應解析地址修改為當前節點地址(系統初始化時我們統一配置成slb負載地址了)。
對於四層監聽的后端服務器無法訪問私網SLB問題,是由於目前負載均衡不支持同時作為客戶端和服務端,因為SLB tcp協議監聽,是直接轉發客戶端IP和連接給后端ECS,當后端ECS連接SLB端口,SLB轉發該連接時,后端ECS“看到”數據包是來自自己的IP,回包就不會回給SLB了,無法正常建立連接,所以telnet會不通。
而ECS可以telnet 公網SLB端口,是因為使用的是ECS的公網IP,VPC ECS的公網IP是在網絡層映射到ECS的內網IP上的,ECS內部並沒有該公網IP,所以可以telnet通公網SLB的端口
注意:因為是正式環境,我們盡量修改一些默認值,比如:token、apiserver端口、etcd數據路徑、podip網段等。
-
在 Master1上創建初始化配置文件
mkdir k8s && cd k8s/ && kubeadm config print init-defaults > init.yml
-
根據實際環境修改初始化配置文件
vim init.yml
apiVersion: kubeadm.k8s.io/v1beta2
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: abcdef.0123456789
abcdef
#修改默認token
ttl: 24h0m0s
usages:
- signing
- authentication
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress:
192.168.10.11
# 此處改為本機IP(修改)
bindPort: 6333 #修改默認端口
nodeRegistration:
criSocket: /var/run/dockershim.sock
name:
k8s-master-01
#修改為master1
taints:
- effect: NoSchedule
key: node-role.kubernetes.io/master
---
apiServer:
timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta2
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controlPlaneEndpoint: "k8s-vip:6333" # VIP:PORT(增加)
controllerManager: {}
dns:
type: CoreDNS
etcd:
local:
dataDir: /data/k8s/etcd
imageRepository: registry.aliyuncs.com/google_containers # 使用國內鏡像倉庫(增加)
kind: ClusterConfiguration
kubernetesVersion: v1.18.10 # 版本號(修改)
networking:
dnsDomain: cluster.local
serviceSubnet: 10.96.0.0/12
podSubnet: 10.233.0.0/16 # pod子網
,和Flannel/calico中要一致(增加)
scheduler: {}
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
featureGates:
SupportIPVSProxyMode: true
mode: ipvs
-
初始化 Master1
之前版本:
kubeadm init --config=init.yml --experimental-upload-certs | tee kubeadm-init.log
v1.18.10版本:
kubeadm init --config=init.yml --upload-certs |tee kubeadm-init.log
*如果中途失敗, 再次初始化前先執行 kubeadm reset 命令清理, 然后再執行init或join操作
k8s主節點初始化完成后,打開阿里雲負載均衡配置,增加SLB內網對kube-apiserver負載配置(這里只能用四層TCP)。
暫且只配置當前master地址,等待其他master節點加入成功后再添加,因為其他兩台master還未加入,此時如果配置其他master地址,SLB負載均衡狀態將會異常,那其他節點嘗試加入集群將會失敗。


3.5加入master節點
在所有Master節點操作
# 根據初始化日志提示,執行kubeadm join命令加入其他管理節點。
kubeadm join k8s-vip:6333 --token token0.123456789kubeadm \
--discovery-token-ca-cert-hash sha256:56d53268517... \
--experimental-control-plane --certificate-key c4d1525b6cce4....
修改新加入master節點apiserver端口,以及補全阿里雲SLB apiserver負載地址。
# 修改kube-apiserver監聽端口
sed -i 's/6443/6333/g' /etc/kubernetes/manifests/kube-apiserver.yaml
# 重啟kube-apiserver容器
docker restart `docker ps | grep k8s_kube-apiserver | awk '{print $1}'`
# 查看kube-apiserver監聽端口
ss -anp | grep "apiserver" | grep 'LISTEN'
3.6加入worker節點
在所有Worker節點操作
# 根據初始化日志提示,執行kubeadm join命令加入其他工作節點。
kubeadm join k8s-vip:6333 --token token0.123456789kubeadm \
--discovery-token-ca-cert-hash sha256:260796226d…………
注意:token有效期為24小時,失效后請在主節點使用以下命令重新生成
kubeadm token create --print-join-command
3.7部署kubectl
在所有需要的節點操作
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
# kubectl 補全 重新打開終端生效
yum -y install bash-completion && cd ~;echo "source <(kubectl completion bash)" >> .bashrc
3.7部署網絡插件
在Master1節點操作
-
calico網絡插件
curl -O https://docs.projectcalico.org/v3.9/manifests/calico.yaml
sed -i 's#192.168.0.0/16#10.233.0.0/16#g' calico.yaml
kubectl apply -f calico.yaml
-
檢查集群部署情況
sed -i 's/- --port=0/#- --port=0/g' /etc/kubernetes/manifests/kube-controller-manager.yaml
sed -i 's/- --port=0/#- --port=0/g' /etc/kubernetes/manifests/kube-scheduler.yaml
kubectl get cs && kubectl get nodes && kubectl get pod --all-namespaces
四、安裝K8S功能組件
4.1安裝dashboard/kuboard
-
部署dashboard
curl -O https://raw.githubusercontent.com/kubernetes/dashboard/v2.3.1/aio/deploy/recommended.yaml
vim recommended.yaml
...
---
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
type: NodePort
ports:
- port: 443
targetPort: 8443
nodePort: 30443
selector:
k8s-app: kubernetes-dashboard
...
kubectl apply -f recommended.yaml
訪問:https://ip:30443
kubectl describe secrets -n kubernetes-dashboard kubernetes-dashboard-token-xxxx | grep token | awk 'NR==3{print $2}'
-
部署kuboard
wget https://kuboard.cn/install-script/kuboard.yaml
kubectl apply -f kuboard.yaml
kubectl apply -f https://addons.kuboard.cn/metrics-server/0.3.6/metrics-server.yaml
獲取token
admin:
echo $(kubectl -n kube-system get secret $(kubectl -n kube-system get secret | grep kuboard-user | awk '{print $1}') -o go-template='{{.data.token}}' | base64 -d)
只讀:
echo $(kubectl -n kube-system get secret $(kubectl -n kube-system get secret | grep kuboard-viewer | awk '{print $1}') -o go-template='{{.data.token}}' | base64 -d)
訪問:http://ip:32567
4.2部署七層路由Ingress
1、 首先下載yaml文件
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.43.0/deploy/static/provider/baremetal/deploy.yaml
2、編輯對應文件修改鏡像源(國外鏡像地址無法下載修改為阿里源)
image: registry.cn-hangzhou.aliyuncs.com/bin_x/nginx-ingress:v0.43.0@sha256:80359bdf124d49264fabf136d2aecadac729b54f16618162194356d3c78ce2fe