一、集群介绍
该页面介绍了用于配置高可用性(HA)Kubernetes集群的拓扑的两个选项。
您可以设置一个HA群集:
- 1、使用堆叠的控制平面节点,其中etcd节点与控制平面节点并置(以下部署所使用)
- 2、对于外部etcd节点,其中etcd在与控制平面不同的节点上运行
1.1、堆叠式etcd拓扑(Stacked etcd topology)
堆叠式HA群集是一种拓扑,其中etcd提供的分布式数据存储群集堆叠在由运行控制平面组件的kubeadm管理的节点所形成的群集之上。
每个控制平面节点运行的一个实例kube-apiserver、kube-scheduler和kube-controller-manager。kube-apiserver使用负载均衡器将暴露给工作程序节点。
每个控制平面节点都创建一个本地etcd成员,并且此etcd成员仅与kube-apiserver此节点的进行通信。本地kube-controller-manager 和kube-scheduler实例也是如此。
这种拓扑将相同节点上的控制平面和etcd成员耦合在一起。与具有外部etcd节点的集群相比,建立起来更容易,并且复制管理起来也更容易。
但是,堆叠的群集存在耦合失败的风险。如果一个节点发生故障,则etcd成员和控制平面实例都将丢失,并且冗余也会受到损害。您可以通过添加更多控制平面节点来减轻这种风险。
因此,您应该为HA集群至少运行三个堆叠的控制平面节点。
这是kubeadm中的默认拓扑。使用kubeadm init和时,会在控制平面节点上自动创建一个本地etcd成员kubeadm join --control-plane。
1.2、外部etcd拓扑(External etcd topology)
具有外部etcd的HA群集是一种拓扑,其中etcd提供的分布式数据存储群集位于由运行控制平面组件的节点形成的群集的外部。
像堆叠ETCD拓扑结构,在外部ETCD拓扑中的每个控制平面节点运行的一个实例kube-apiserver,kube-scheduler和kube-controller-manager。并且kube-apiserver使用负载平衡器将其暴露给工作程序节点。但是,etcd成员在单独的主机上运行,并且每个etcd主机都与kube-apiserver每个控制平面节点的通讯。
该拓扑将控制平面和etcd成员解耦。因此,它提供了一种HA设置,其中丢失控制平面实例或etcd成员的影响较小,并且不会像堆叠的HA拓扑那样对集群冗余产生太大影响。
但是,此拓扑所需的主机数量是堆栈HA拓扑的两倍。对于具有此拓扑的HA群集,至少需要三台用于控制平面节点的主机和三台用于etcd节点的主机。
二、安装部署
本文选择堆叠式etcd拓扑(External etcd topology)
2.1、安装前准备
基础:验证MAC地址和product_uuid对于每个节点都是唯一的
- 您可以使用以下命令获得网络接口的MAC地址ip link或ifconfig -a
- 可以使用以下命令检查product_uuid sudo cat /sys/class/dmi/id/product_uuid
Kubernetes使用这些值来唯一地标识集群中的节点。如果这些值不是每个节点唯一的,则安装过程可能会失败。
升级系统内核到4.4
yum install docker-ce-18.06.1.ce-3.el7.x86_64
关闭防火墙
#: 暂时关闭防火墙
systemctl stop firewalld
service iptables stop
#:永久关闭防火墙
systemctl disable firewalld
chkconfig iptables off
2.2、Kubernetes安装部署多Master
1、修改本地/etc/hosts文件
#将以下内容追加(>>)到 /etc/hosts文件
cat <<EOF >> /etc/hosts
172.16.180.47 test2
172.16.180.48 test2
172.16.181.18 test2
EOF
2、CentOS 7 配置国内阿里云镜像源
#将以下内容替换(>)到 /etc/yum.repos.d/kubernetes.repo文件
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
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
注:如果上边这个源不好用,再用下面的镜像源
cat <<LEO > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=0
LEO
3、关闭 SELinux,目的为了允许容器能够与本机文件系统交互。
临时关闭
setenforce 0
永久关闭
vim /etc/selinux/config
将SELINUX=enforcing改为SELINUX=disabled
设置后需要重启才能生效
systemctl daemon-reload
4、修改网络开启桥接网络支持,只针对(RHEL/CentOS 7)系统
cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl -p /etc/sysctl.d/k8s.conf
5、关闭swap——不关闭配置节点或是配置master都会有问题
临时生效
swapoff -a
永久生效:
sed -ri 's/.*swap.*/#&/' /etc/fstab
6、安装 ebtables ethtool,否则后边执行 kubeadm init 的时候会报错
yum install ebtables ethtool -y
#然后修改当前内核状态 这个文件是在 Docker安装成功后才出现的
echo 1 > /proc/sys/net/bridge/bridge-nf-call-iptables
docker镜像加速
cat <<EOF > /etc/docker/daemon.json
{
"registry-mirrors": ["https://43jugwwr.mirror.aliyuncs.com"]
}
EOF
systemctl daemon-reload
systemctl restart docker
7、安装kubelet、kubeadm、kubectl
公司电脑安装需要用的命令:yum install -y kubelet-1.13.0 kubeadm-1.13.0 kubectl-1.13.0 kubernetes-cni-0.6.0
systemctl enable kubelet && systemctl start kubelet
8、镜像准备
kubernetes 服务启动依赖很多镜像,是下载不下来的。这里我们可以去 Docker Hub 下载指定版本的镜像替代,下载完成后,通过 docker tag … 命令修改成指定名称的镜像即可。
kubeadm config images list
I0524 22:03:10.774681 19610 version.go:96] could not fetch a
Kubernetes version from the internet: unable to get URL
“https://dl.k8s.io/release/stable-1.txt”: Get
https://dl.k8s.io/release/stable-1.txt: net/http: request canceled
while waiting for connection (Client.Timeout exceeded while awaiting
headers) I0524 22:03:10.774766 19610 version.go:97] falling back to
the local client version: v1.14.2 k8s.gcr.io/kube-apiserver:v1.14.2
k8s.gcr.io/kube-controller-manager:v1.14.2
k8s.gcr.io/kube-scheduler:v1.14.2 k8s.gcr.io/kube-proxy:v1.14.2
k8s.gcr.io/pause:3.1 k8s.gcr.io/etcd:3.3.10 k8s.gcr.io/coredns:1.3.1
9、创建文件setup_image.sh 编写脚本批量下载镜像,并修改镜像tag与google的k8s镜像名称一致
公司电脑配置是:
#!/bin/bash
# 定义镜像集合数组
images=(
kube-apiserver:v1.13.0
kube-controller-manager:v1.13.0
kube-scheduler:v1.13.0
kube-proxy:v1.13.0
pause:3.1
etcd:3.2.24
coredns:1.2.6
)
# 循环从 registry.cn-hangzhou.aliyuncs.com 中下载镜像
echo '+----------------------------------------------------------------+'
for img in ${images[@]};
do
# 从国内源下载镜像
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/$img
# 改变镜像名称
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/$img k8s.gcr.io/$img
# 删除源始镜像
docker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/$img
#
echo '+----------------------------------------------------------------+'
echo ''
done
# 下载网络插件
# 官网地址:https://quay.io/repository/coreos/flannel?tag=latest&tab=tags
docker pull quay.io/coreos/flannel:v0.10.0-amd64
执行setup_image.sh
./setup_images.sh
2.3、为kube-apiserver创建负载均衡器
①.创建一个解析DNS的kube-apiserver负载均衡器。安装HA
②.将一个控制平面节点添加到负载均衡器并测试连接:
nc -v LOAD_BALANCER_IP PORT
2.4、安装堆叠的控制平面和etcd节点(Stacked etcd topology)
第一个控制平面节点的步骤
1.在第一个控制平面节点上,创建一个名为的配置文件kubeadm-config.yaml:
apiVersion: kubeadm.k8s.io/v1beta1
kind: ClusterConfiguration
kubernetesVersion: stable
apiServer:
certSANs:
- "192.168.180.45"
controlPlaneEndpoint: "192.168.180.45:6444"
networking:
podSubnet: "10.244.0.0/16"
- certSANs是ha的ip
- controlPlaneEndpoint 是ha的ip和端口。
- 设置networking这个对象 中podSubnet这个字段是为Calico/Flannel 等CNI插件所使用的,使用其他网络自动参考官网推荐的网络
2、确保节点处于干净状态
kubeadm init --config=kubeadm-config.yaml
您应该看到类似以下内容:
...
You can now join any number of machines by running the following on each node
as root:
kubeadm join 172.16.180.45:6444 --token j04n3m.octy8zely83cy2ts --discovery-token-ca-cert-hash sha256:84938d2a22203a8e56a787ec0c6ddad7bc7dbd52ebabc62fd5f4dbea72b14d1f
将此输出复制到文本文件。稍后您将需要它来将其他控制平面节点加入集群。
3、应用Flannel CNI插件:
kubernetes 提供了很多种网络组件选择,有 Calia、Canal、Flannel、Kube-router、Romana、Weave Net 可以使用,本文采用其中的Flannel
k8s是1.13版本的则需要用以下的命令安装flannel
docker pull quay.io/coreos/flannel:v0.10.0-amd64
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/v0.11.0/Documentation/k8s-manifests/kube-flannel-rbac.yml
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/v0.11.0/Documentation/kube-flannel.yml
4、查看
kubectl get pod -n kube-system -w
建议仅在第一个节点完成初始化之后才加入新的控制平面节点。
2.5:将证书文件从第一个控制平面节点复制到其余节点:
以下操作的前提:已经执行3.2的操作
在以下示例中,将其替换CONTROL_PLANE_IPS为其他控制平面节点的IP地址。
本文配置:
USER=root
CONTROL_PLANE_IPS="172.16.180.47 172.16.180.48"
for host in ${CONTROL_PLANE_IPS}; do
scp /etc/kubernetes/pki/ca.crt "${USER}"@$host:
scp /etc/kubernetes/pki/ca.key "${USER}"@$host:
scp /etc/kubernetes/pki/sa.key "${USER}"@$host:
scp /etc/kubernetes/pki/sa.pub "${USER}"@$host:
scp /etc/kubernetes/pki/front-proxy-ca.crt "${USER}"@$host:
scp /etc/kubernetes/pki/front-proxy-ca.key "${USER}"@$host:
scp /etc/kubernetes/pki/etcd/ca.crt "${USER}"@$host:etcd-ca.crt
scp /etc/kubernetes/pki/etcd/ca.key "${USER}"@$host:etcd-ca.key
#scp /etc/kubernetes/admin.conf "${USER}"@$host:
done
注意:仅复制以上列表中的证书。kubeadm将负责为加入的控制平面实例生成带有所需SAN的其余证书。如果错误地复制了所有证书,则由于缺少所需的SAN,其他节点的创建可能会失败
2.6、其余控制平面节点的步骤
在上一步复制到的节点服务器上进行操作。
本文配置:
USER=root
mkdir -p /etc/kubernetes/pki/etcd
mv /${USER}/ca.crt /etc/kubernetes/pki/
mv /${USER}/ca.key /etc/kubernetes/pki/
mv /${USER}/sa.pub /etc/kubernetes/pki/
mv /${USER}/sa.key /etc/kubernetes/pki/
mv /${USER}/front-proxy-ca.crt /etc/kubernetes/pki/
mv /${USER}/front-proxy-ca.key /etc/kubernetes/pki/
mv /${USER}/etcd-ca.crt /etc/kubernetes/pki/etcd/ca.crt
mv /${USER}/etcd-ca.key /etc/kubernetes/pki/etcd/ca.key
#mv /${USER}/admin.conf /etc/kubernetes/admin.conf
此过程将所有请求的文件写入文件夹/etc/kubernetes。
kubeadm join使用先前kubeadm init在第一个节点上给您的join命令在此节点上启动,并添加 --experimental-control-plane
kubeadm join 192.168.180.45:6444 --token j04n3m.octy8zely83cy2ts --discovery-token-ca-cert-hash sha256:84938d2a22203a8e56a787ec0c6ddad7bc7dbd52ebabc62fd5f4dbea72b14d1f --experimental-control-plane
注意添加了--experimental-control-plane标志。该标志使该控制平面节点自动加入集群。
查看
kubectl get pod -n kube-system -w
最后:对其余的控制平面节点重复这些步骤(可用ansible完善)
常用命令
1、# 重新生成链接 Token
[root@k8s-master deploy]# kubeadm token create --print-join-command
2、运行journalctl -xefu kubelet 命令查看systemd日志
对kubeadm进行故障排除
1、 注如果yum安装报错:
-
重新建立rpm库里的记录,生成新镜像缓存
yum clean all
rpm --rebuilddb
yum makecache
2、如果出现如下的报错
failed to load Kubelet config file /var/lib/kubelet/config.yaml, error failed to read kubelet config file "/var/lib/kubelet/config.yaml", error: open /var/lib/kubelet/config.yaml: no such file or directory
忽略以上的报错,设置为开机自启动即可,因为此时的配置还没初始化完成,所以此时不能启动kubelet,等后续kubeadm启动成功后再查看
原因:kubelet每隔几秒钟重新启动一次,因为它在崩溃循环中等待kubeadm告诉它该怎么做。此崩溃循环是正常现象。初始化母版后,kubelet将正常运行。
3、出现以下错误
OCI runtime exec failed: exec failed: container_linux.go:348: starting container process caused "exec:
是由于在docker中没有base命令,可以将base改为sh
4、k8s连接不上集群
报错信息为
Unable to connect to the server: EOF
查看日志
journalctl -f -u kubelet
12月 31 11:44:26 test3 kubelet[29987]: E1231 11:44:26.447695 29987 reflector.go:134] k8s.io/kubernetes/pkg/kubelet/kubelet.go:453: Failed to list *v1.Node: Get https://172.16.180.45:6444/api/v1/nodes?fieldSelector=metadata.name%3Dtest3&limit=500&resourceVersion=0: EOF
从错误日志判断来看,是Master上的kubelet在与同一节点上的kube-apiserver通信过程中,发现这个apiserver返回的tls证书不对(因为此node上的证书是从其他node上拷贝过来的)
待解决:
拆除
要撤消什么kubeadm做,你应该先排出节点,并确保该节点将其关闭之前是空的。
使用适当的凭证与控制平面节点通信,请运行:
kubectl drain <node name> --delete-local-data --force --ignore-daemonsets
kubectl delete node <node name>
然后,在要删除的节点上,重置所有kubeadm安装状态:
kubeadm reset
reset之后提示以下信息
[reset] Deleting contents of stateful directories: [/var/lib/etcd /var/lib/kubelet /var/lib/dockershim /var/run/kubernetes /var/lib/cni]
The reset process does not clean CNI configuration. To do so, you must remove /etc/cni/net.d
The reset process does not reset or clean up iptables rules or IPVS tables.
If you wish to reset iptables, you must do so manually by using the "iptables" command.
If your cluster was setup to utilize IPVS, run ipvsadm --clear (or similar)
to reset your system's IPVS tables.
The reset process does not clean your kubeconfig files and you must remove them manually.
Please, check the contents of the $HOME/.kube/config file.
重置过程不会重置或清除iptables规则或IPVS表。如果您希望重置iptables,则必须手动进行:
iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X
如果要重置IPVS表,则必须运行以下命令:
ipvsadm -C
如果您想重新开始,只需运行kubeadm init或kubeadm join使用适当的参数即可。
删除干净k8s
systemctl stop kubelet
yum remove -y kubelet kubeadm kubectl kubernetes-cni
rm -rf ~/.kube/
rm -rf /etc/kubernetes/
rm -rf /etc/systemd/system/kubelet.service.d
rm -rf /etc/systemd/system/kubelet.service
rm -rf /usr/bin/kube*
rm -rf /etc/cni
rm -rf /opt/cni
rm -rf /var/lib/etcd
rm -rf /var/etcd
再次安装k8s1.13版本
yum install -y kubelet-1.13.0 kubeadm-1.13.0 kubectl-1.13.0 kubernetes-cni-0.6.0