kubeadm 简介
Kubeadm 是一种工具,旨在为创建 Kubernetes 集群提供最佳实践“快速路径”。
它执行必要的操作,以用户友好的方式启动和运行最低可行,安全的群集。
Kubeadm 的范围仅限于本地节点文件系统和 Kubernetes API,它旨在成为更高级别工具的可组合构建块。
环境
主机名 | IP地址 | CPU | 内存(G) | 备注 |
---|---|---|---|---|
k8s1 | 172.16.10.3 | 4 | 8 | master节点 |
k8s2 | 172.16.10.4 | 4 | 8 | master节点 |
k8s3 | 172.16.10.22 | 4 | 8 | master节点 |
k8s4 | 172.16.10.20 | 4 | 8 | worker节点 |
k8s5 | 172.16.10.19 | 4 | 8 | worker节点 |
k8s6 | 172.16.10.21 | 4 | 8 | worker节点 |
添加hosts
cat >> /etc/hosts <<EOF
172.16.10.3 k8s1
172.16.10.4 k8s2
172.16.10.22 k8s3
172.16.10.20 k8s4
172.16.10.19 k8s5
172.16.10.21 k8s6
EOF
复制代码
检查服务器至少满足下面的条件:
-
每个节点的唯一主机名,MAC地址和product_uuid
-
防火墙放行应用端口
-
禁用交换分区
验证MAC地址和product_uuid对于每个节点都是唯一的
-
可以使用命令ip link 或 ifconfig -a 获取网络接口的MAC地址
-
可以使用下面命令检查product_uuid
sudo cat /sys/class/dmi/id/product_uuid 复制代码
关闭 SELinux 和 Firewalld
setenforce 0
sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
复制代码
systemctl stop firewalld
systemctl disable firewalld
iptables -F && iptables -X && iptables -F -t nat && iptables -X -t nat
iptables -P FORWARD ACCEPT
复制代码
加载模块
modprobe br_netfilter
lsmod | grep br_netfilter
复制代码
内核优化
cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system
复制代码
安装容器运行时
自v1.6.0起,Kubernetes默认启用了CRI (Container Runtime Interface) 。
从v1.14.0开始,kubeadm将尝试通过扫描众所周知的套接字列表来自动检测Linux节点上的容器运行时。 可以在下表中找到所使用的可检测运行时和套接字路径。
Runtime | Domain Socket |
---|---|
Docker | /var/run/docker.sock |
containerd | /run/containerd/containerd.sock |
CRI-O | /var/run/crio/crio.sock |
如果同时检测到Docker和containerd,则Docker优先。
因为Docker 18.09附带了containerd,两者都是可检测的。
如果检测到任何其他两个或更多运行时,kubeadm将退出并显示相应的错误消息。
如果选择的容器运行时是Docker,则通过内置的dockershimCRI实现使用它 kubelet。
安装最新稳定版的 docker-ce
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
复制代码
创建 daemon.json
mkdir -p /etc/docker
cat > daemon.json <<EOF
{
"registry-mirrors": ["http://f1361db2.m.daocloud.io"],
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true"
]
}
EOF
systemctl restart docker
复制代码
安装 kubeadm,kubelet 和 kubectl
使用阿里云的源,安装kubeadm软件等
worker节点可以不安装kubectl
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
yum install -y kubelet-1.14.2 kubeadm-1.14.2 kubectl-1.14.2
systemctl enable kubelet
复制代码
下载镜像
使用如下的命令打印出需要的镜像
$ kubeadm config images list
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
复制代码
gcr.io 域名在大陆不可访问,我们使用如下的脚本下载镜像
#!/bin/bash
set -o errexit
set -o nounset
KUBE_VERSION=v1.14.2
KUBE_PAUSE_VERSION=3.1
ETCD_VERSION=3.3.10
DNS_VERSION=1.3.1
GCR_URL=k8s.gcr.io
HUB_URL=gcr.azk8s.cn/google_containers
images=("kube-apiserver:${KUBE_VERSION}" "kube-controller-manager:${KUBE_VERSION}" "kube-scheduler:${KUBE_VERSION}" "kube-proxy:${KUBE_VERSION}" "pause:${KUBE_PAUSE_VERSION}" "etcd:${ETCD_VERSION}" "coredns:${DNS_VERSION}")
for imageName in ${images[@]} ; do
docker pull $HUB_URL/$imageName
docker tag $HUB_URL/$imageName $GCR_URL/$imageName
docker rmi $HUB_URL/$imageName
done
复制代码
高可用拓扑
可以设置如下两种HA 集群
- 使用堆叠的控制平面节点,其中etcd节点与控制平面节点共存
- 使用外部etcd节点,etcd在控制平面的不同节点上运行
Stacked etcd topology
每个控制平面节点运行的一个kube-apiserver,kube-scheduler和kube-controller-manager实例。
kube-apiserver使用负载均衡器暴露于工作节点。
每个控制平面节点创建一个本地etcd成员,该etcd成员仅与该节点的kube-apiserver通信。
这同样适用于本地kube-controller-manager 和kube-scheduler实例。
该拓扑将控制平面和etcd成员耦合在相同节点上。设置比具有外部etcd节点的集群更简单,并且更易于管理复制。
但是,堆叠集群存在耦合失败的风险。如果一个节点发生故障,则etcd成员和控制平面实例都将丢失,并且冗余会受到影响。您可以通过添加更多控制平面节点来降低此风险。
因此,您应该为HA群集运行至少三个堆叠的控制平面节点。
External etcd topology
由etcd提供的分布式数据存储集群在运行控制平面组件的节点形成的集群外部。
在外部ETCD拓扑中的每个控制平面节点运行的一个kube-apiserver,kube-scheduler和kube-controller-manager实例。
并且kube-apiserver使用负载均衡器暴露给工作节点。但是,etcd成员在不同的主机上运行,每个etcd主机与控制平面节点的kube-apiserver进行通信。
将控制平面和etcd成员分离。因此,它提供了HA设置,其中丢失控制平面实例或etcd成员具有较小的影响并且不像堆叠的HA拓扑那样影响集群冗余。
但是,此拓扑需要两倍于堆叠HA拓扑的主机数。具有此拓扑的HA群集至少需要三个用于控制平面节点的主机和三个用于etcd节点的主机。
这边机选择第一种方案: stacked etcd topology
为kube-apiserver 创建负载均衡器
创建一个负载均衡器,其名称可以解析为DNS
-
在云环境中,您应将控制平面节点置于TCP转发负载平衡器之后。此负载均衡器将流量分配到其目标列表(master节点)中的所有健康控制平面节点。apiserver的运行状况检查是对kube-apiserver侦听的端口的TCP检查(默认值:6443)。
-
不建议直接在云环境中使用IP地址。(实验环境下,没有设置DNS解析,直接使用IP代替)
-
负载均衡器必须能够与apiserver端口上的所有控制平面节点通信。它还必须允许其侦听端口上的传入流量。
-
HAProxy可用作负载均衡器。
-
确保负载均衡器的地址始终与kubeadm的地址匹配ControlPlaneEndpoint。
京东云内网负载均衡监听配置截图:
如果没有SLB,也可以使用Haproxy
Haproxy配置文件见 haproxy.cfg
堆叠控制平面和etcd节点
第一个控制平面节点的步骤
- 在第一个控制平面节点上,创建一个名为的配置文件kubeadm-config.yaml:
apiVersion: kubeadm.k8s.io/v1beta1
kind: ClusterConfiguration
kubernetesVersion: 1.14.2
controlPlaneEndpoint: "172.16.10.5:6443"
networking:
serviceSubnet: "10.96.0.0/12"
podSubnet: "10.244.0.0/16"
dnsDomain: "cluster.local"
复制代码
-
kubernetesVersion应该设置为使用的Kubernetes版本。这边使用1.14.2
-
controlPlaneEndpoint 应匹配负载均衡器的地址或DNS和端口。
-
networking 设置CNI 网络插件需要的CIDR
- 初始化控制平面:
kubeadm init --config=kubeadm-config.yaml --experimental-upload-certs
复制代码
- --experimental-upload-certs标志用于将应在所有控制平面实例之间共享的证书上载到群集。相反,如果您希望手动或使用自动化工具跨控制平面节点复制证书,请删除此标志并参考手动证书分发部分。
命令执行完成之后,输出类似下面:
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
You can now join any number of the control-plane node running the following command on each as root:
kubeadm join 172.16.10.5:6443 --token o8d1ee.tzswy9o52p6m00i4 \
--discovery-token-ca-cert-hash sha256:56047868636349ca477d271496689f5d83055d8ff3e2cc594b5a419501962d18 \
--experimental-control-plane --certificate-key d19b85d6692cde12ad8a85fd882b45293c2cda35b32edb2ad217192c8b836821
Please note that the certificate-key gives access to cluster sensitive data, keep it secret!
As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use
"kubeadm init phase upload-certs --experimental-upload-certs" to reload certs afterward.
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 172.16.10.5:6443 --token o8d1ee.tzswy9o52p6m00i4 \
--discovery-token-ca-cert-hash sha256:56047868636349ca477d271496689f5d83055d8ff3e2cc594b5a419501962d18
复制代码
3.安装flannel网络插件
flannel 文档
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/v0.11.0/Documentation/kube-flannel.yml
复制代码
安装其余控制平面节点
kubeadm join 172.16.10.5:6443 --token o8d1ee.tzswy9o52p6m00i4 \
--discovery-token-ca-cert-hash sha256:56047868636349ca477d271496689f5d83055d8ff3e2cc594b5a419501962d18 \
--experimental-control-plane --certificate-key d19b85d6692cde12ad8a85fd882b45293c2cda35b32edb2ad217192c8b836821
复制代码
安装worker节点
kubeadm join 172.16.10.5:6443 --token o8d1ee.tzswy9o52p6m00i4 \
--discovery-token-ca-cert-hash sha256:56047868636349ca477d271496689f5d83055d8ff3e2cc594b5a419501962d18
复制代码
确认节点已全部安装完成
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s1 Ready master 2d13h v1.14.2
k8s2 Ready master 2d13h v1.14.2
k8s3 Ready master 2d13h v1.14.2
k8s4 Ready <none> 2d13h v1.14.2
k8s5 Ready <none> 2d13h v1.14.2
k8s6 Ready <none> 2d13h v1.14.2
$ kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-fb8b8dccf-g4lf5 1/1 Running 0 2d13h
coredns-fb8b8dccf-z4rrq 1/1 Running 0 2d13h
etcd-k8s1 1/1 Running 0 2d13h
etcd-k8s2 1/1 Running 0 2d13h
etcd-k8s3 1/1 Running 0 2d13h
kube-apiserver-k8s1 1/1 Running 0 2d13h
kube-apiserver-k8s2 1/1 Running 0 2d13h
kube-apiserver-k8s3 1/1 Running 1 2d13h
kube-controller-manager-k8s1 1/1 Running 1 2d13h
kube-controller-manager-k8s2 1/1 Running 0 2d13h
kube-controller-manager-k8s3 1/1 Running 0 2d13h
kube-flannel-ds-amd64-22j5p 1/1 Running 0 2d13h
kube-flannel-ds-amd64-2gnxf 1/1 Running 0 2d13h
kube-flannel-ds-amd64-bbttc 1/1 Running 0 2d13h
kube-flannel-ds-amd64-st9xk 1/1 Running 0 2d13h
kube-flannel-ds-amd64-v5bjs 1/1 Running 0 2d13h
kube-flannel-ds-amd64-wqsrq 1/1 Running 0 2d13h
kube-proxy-5wxg5 1/1 Running 0 2d13h
kube-proxy-6j5kj 1/1 Running 0 2d13h
kube-proxy-9f9sm 1/1 Running 0 2d13h
kube-proxy-j2c4p 1/1 Running 0 2d13h
kube-proxy-lhtjv 1/1 Running 0 2d13h
kube-proxy-rxbwj 1/1 Running 0 2d13h
kube-scheduler-k8s1 1/1 Running 1 2d13h
kube-scheduler-k8s2 1/1 Running 0 2d13h
kube-scheduler-k8s3 1/1 Running 0 2d13h
复制代码