kubeadm使用docker和flannel创建k8s三节点集群
首发: xiaojueguan的IT世界
环境介绍
root@k8s1:~# kubeadm version
kubeadm version: &version.Info{Major:"1", Minor:"22", GitVersion:"v1.22.2", GitCommit:"8b5a19147530eaac9476b0ab82980b4088bbc1b2", GitTreeState:"clean", BuildDate:"2021-09-15T21:37:34Z", GoVersion:"go1.16.8", Compiler:"gc", Platform:"linux/amd64"
root@k8s1:~# docker --version
Docker version 20.10.8, build 3967b7d
root@k8s1:~# cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04.2 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.2 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
前言
由于Kubernetes的官方镜像都在k8s.gcr.io/v2/ , 所以我们直接拉取的话会有网络连通性的问题,从而出现类似下面的报错
[preflight] Some fatal errors occurred:
[ERROR ImagePull]: failed to pull image k8s.gcr.io/etcd:3.5.0-0: output: Error response from daemon: Get "https://k8s.gcr.io/v2/": context deadline exceeded
, error: exit status 1
[ERROR ImagePull]: failed to pull image k8s.gcr.io/coredns/coredns:v1.8.4: output: Error response from daemon: Get "https://k8s.gcr.io/v2/": context deadline exceeded
, error: exit status 1
对于这个问题,我们的解决方式有三种:
- 使用proxy
- 换一个镜像源拉取镜像到本地然后将镜像改名为
k8s.gcr.io 开头的 - 自己创建一个镜像仓库, 然后在
kubeadm init 的时候加上参数例如--image-repository=k8s.xiaojueguan.io
本文会介绍下使用proxy的方式: 主要在两个地方会用到proxy:
- apt的proxy用于安装kubelet,kubeadm,kubectl
- docker的proxy用户
在解决完k8s部署主要使用的软件和镜像后我们还需要做出如下选择
- 容器运行时(container runtime)
- 容器网络接口(container network interface)
- ACI
- Antrea
- AWS VPC CNI for Kubernetes
- Azure CNI for Kubernetes
- Calico
- Cilium
- CNI-Genie from Huawei
- cni-ipvlan-vpc-k8s
- Coil
- Contiv
- Contrail / Tungsten Fabric
- DANM
- Flannel
- Google Compute Engine (GCE)
- Jaguar
- k-vswitch
- Knitter
- Kube-OVN
- Kube-router
- L2 networks and linux bridging
- Multus (a Multi Network plugin)
- OVN4NFV-K8s-Plugin (OVN based CNI controller & plugin)
- NSX-T
- Nuage Networks VCS (Virtualized Cloud Services)
- OpenVSwitch
- OVN (Open Virtual Networking)
- Romana
- Weave Net from Weaveworks
这里我们选用docker作为host runtime,选择flannel作为CNI.
安装docker
- 安装设置使用https的仓库需要的包
sudo apt-get update && sudo apt-get install -y \
apt-transport-https ca-certificates curl software-properties-common gnupg2
- 添加docker官方的GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key --keyring /etc/apt/trusted.gpg.d/docker.gpg add -
- 添加docker 的 apt 仓库
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
4 安装docker ce
sudo apt-get update && sudo apt-get install -y \
containerd.io \
docker-ce \
docker-ce-cli
5 设置docker代理
mkdir -p /etc/systemd/system/docker.service.d
cat << EOF > /etc/systemd/system/docker.service.d/http-proxy.conf
[Service]
Environment="HTTP_PROXY=http://10.10.1.190:1080"
Environment="HTTPS_PROXY=http://10.10.1.190:1080"
Environment="NO_PROXY=localhost,127.0.0.1,docker-registry.example.com,.corp,10.10.1.0/24"
EOF
- 设置docker的cgroup驱动为systemd
cat <<EOF | sudo tee /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
EOF
- 重启Docker
sudo systemctl daemon-reload
sudo systemctl restart docker
- 设置docker自启动
sudo systemctl enable docker
使用部署工具安装kubernetes
确认mac地址和product_uuid在每个节点上都不同。你可以通过ip link 或者ifconfig -a 来获取网卡的地址。 你可以通过sudo cat /sys/class/dmi/id/product_uuid 获取product_uuid, 通常硬件设备是拥有不同的地址,但是一些虚拟机可能拥有相同的标识值。kubernetes使用这些值来标识集群中的节点。如果这些值相同的话,安装过程中会报错。 检查你的网卡,确保你各个节点的网卡可以相通。 让网桥上的流量对iptables可见。你可以通过lsmod | grep br_netfilter 验证,通过sudo modprobe br_netfilter 来加载br_netfilter 模块。此外为了保证你的linux节点上的iptables 可以正确看到桥上的流量可以进行如下操作: 通过下面命令来查看br_netfilter 和 overlay 是否已经加载了,如果没有加载的话通过下面的命令加载:
cat <<EOF | sudo tee /etc/modules-load.d/crio.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
通过下面的设置使iptables可以查看到桥上的流量
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sudo sysctl --system
设置apt代理
cat <<EOF > /etc/apt/apt.conf.d/proxy.conf
Acquire {
HTTP::proxy "http://10.10.1.190:1080";
HTTPS::proxy "http://10.10.1.190:1080";
}
EOF
安装kubeadm, kubelet and kubectl
sudo apt-get update && sudo apt-get install -y apt-transport-https curl
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
禁用swap
swapoff -a
用kubeadm初始化一个集群
通过下面的命令来设置第一个node
kubeadm init \
--apiserver-advertise-address=10.10.1.211 \
--kubernetes-version=v1.22.2 \
--pod-network-cidr=10.244.0.0/16 -v=9
跑完后便会看到如下的结果
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
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/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 10.10.1.211:6443 --token i978xo.oiu48b2pimdig1xl \
--discovery-token-ca-cert-hash sha256:365c9d9408404a228e66159adef8513752b04bd2be3f5afc3ce4354a96aa04e2
但是这个时候我们我们通过下面的命令会看到两个coredns的pod处于0/1 的状态
export KUBECONFIG=/etc/kubernetes/admin.conf
kubectl get pod -n kube-system
这个时候我们需要设置cni,这里我们使用flannedl 获取kube-flannel.yml文件
wget kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
使用你的编辑器查看kube-flannel.yml,确保如下配置中的Network字段是和你上面的pod-network-cidr是一样的
net-conf.json: |
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": "vxlan"
}
}
建立flannel
export KUBECONFIG=/etc/kubernetes/admin.conf
kubectl apply -f kube-flannel.yml
如果遇到问题可以查看下面的tips
此时我们可以观察到所有的coredn的pod都起来了,然后参考上文在其他节点上
- 安装docker
- 加载mod
- 设置系统参数
- 关闭swap
- 安装kubeadm和kubelet
最后执行类似下面的命令让新的node加入到集群
kubeadm join 10.10.1.211:6443 --token i978xo.oiu48b2pimdig1xl \
--discovery-token-ca-cert-hash sha256:365c9d9408404a228e66159adef8513752b04bd2be3f5afc3ce4354a96aa04e2
配置kubelet自动补全
- 配置
kubelet completion 安装bash-completion 如果安装了可以跳过这一步
apt-get install bash-completion
yum install bash-completion
可以使用下面两种方式开启kubelet自动补全
echo 'source <(kubectl completion bash)' >>~/.bashrc
- 将补全的script加到
/etc/bash_completion.d/kubectl 这个文件中
kubectl completion bash >/etc/bash_completion.d/kubectl
如果使用了alias的话可以使用下面的命令进行配置
echo 'alias k=kubectl' >>~/.bashrc
echo 'complete -F __start_kubectl k' >>~/.bashrc
Tips
- 如果初始化被打断可以通过下面的命令reset节点
kubeadm reset
rm -fr ~/.kube
- 如果容器没有被拉起来
大概率的kubelet服务不正常,如果不正常根据日志里面的报错具体问题分析
systemct status kubelet
journalctl -f -u kubelet
- 如果coredns没起来
多半是你设置cni的网络和你init时指定的不一样.
问题
- 只在节点以上安装了cni是不是其他节点上就没有cni了?
- pod之间的网络是怎么走的?
参考
Install and Set Up kubectl | Kubernetes 使用kubeadm 安装k8s_ふりこ细工の心-CSDN博客 Control Docker with systemd | Docker Documentation
|