三节点k8s集群的构建
前言
咕了要一年的文章哈,一开始老想着在家用自己刷了linux的笔记本+另外两台机器的wsl搭建集群,但是麻烦事太多了。 最终选择了公司的云平台搞三台虚拟机来练手
相较于 单节点的k8s安装,多节点的最大的不同是需要CNI来进行组网
这里笔者选用了cilium
步骤规划:
- 部署管理面平台
- 载入CNI
- 部署work节点
使用系统: Ubuntu 20.04
如果想要寻找快速搭配的命令,可以直接看 work节点的一图流,然后使用master的 部署k8s-master 与 cilium
部署管理面平台
基础环境准备
这里的安装在过去的文章有提及,就不重复了 PS: 在后续走到了 1.24的安装后突然想起来,1.24开始 k8s 不在默认支持docker Engine作为CRI,后文将会有container的安装过程
ubuntu 的 swap 禁用
sudo sed -ri '/\sswap\s/s/^#?/#/' /etc/fstab
sudo swapoff -a
如果不禁用,在后续的kubeadm 会出现
kubelet-check] Initial timeout of 40s passed.
这里遇到了一个意料之外的问题
ProxyChains-3.1 (http://proxychains.sf.net)
|DNS-response|: ubuntu-vm does not exist
|DNS-response|: ubuntu-vm does not exist
sudo: unable to resolve host ubuntu-vm: Unknown error
找了几种方法,比如 安装 reslove tor
最后发现了一个奇怪的解决方法
mkdir /etc/apt/keyrings/
proxychains curl -o /etc/apt/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
或者用另一个解法,不要用sudo 不用sudo就好了= =
但是有一个新的问题 apt-get updat 的时候
Err:7 https://packages.cloud.google.com/apt kubernetes-xenial Release
404 Not Found [IP: 142.250.194.238 443]
直接访问了这个 url 也是404 所以这里 仓库配置就不使用 google的仓库了,使用阿里云的
curl -fsSL https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main"
google 仓库404问题的补充
根据 问答 该问题的评论,这是一个已知问题
解决方案是获取最新的密钥:
// 但是看上去其实没区别 应该是无效的,等到我work节点的时候试试不用 google 的 可不可行
curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg --dearmor -o /usr/share/keyrings/google-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/google-keyring.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
安装的版本用新一些的
apt install -y kubelet=1.24.17-00 kubeadm=1.24.17-00 kubectl=1.24.17-00
apt-mark hold kubelet kubeadm kubectl
containerd 安装
安装 containerd 可以直接使用 apt-get
apt-get install containerd containerd.io -y
按照文档描述,通过apt-get安装的containerd.io 包含了runc,但是并不包含 CNI 插件。
后续这里可能会带来一个坑。 不过目前就是走一步看一步
这样安装的后 /etc/containerd/config.toml 的配置文件可能不全
可以考虑手动初始化配置
sudo rm -rf /etc/containerd/config.toml
sudo containerd config default | sudo tee /etc/containerd/config.toml
sudo systemctl restart containerd
安装后可以使用 ctr -v 得到输出,但是这个玩意很不好用,需要再安装客户端工具
常见的推荐就是 crictl与nerdctl 笔者这里使用 crictl
直接使用官方文档给的方式
VERSION="v1.28.0"
wget https://github.com/kubernetes-sigs/cri-tools/releases/download/$VERSION/crictl-$VERSION-linux-amd64.tar.gz
sudo tar zxvf crictl-$VERSION-linux-amd64.tar.gz -C /usr/local/bin
rm -f crictl-$VERSION-linux-amd64.tar.gz
安装完后尝试使用 crictl ps 之类的会返回错误,因为默认使用的还是 /var/run/dockershim.sock
- 如果执行了手动初始化,这一步可以跳过*
- 建议执行,因为可能没有默认的配置文件,导致运行出现无意义报错*
validate service connection: validate CRI v1 image API for endpoint "unix:///var/run/dockershim.sock": rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing: dial unix /var/run/dockershim.sock: connect: no such file or directory"
cat >> /etc/crictl.yaml << EOF
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 3
debug: true
EOF
之后会发现还是无法使用,因为需要再调整containerd 的配置
vim /etc/containerd/config.toml
注释 disabled_plugins = ["cri"]
然后重启 containerd
systemctl restart containerd
就可以了
配置 cgroup 驱动为 systemd
在 /etc/containerd/config.toml 中设置
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml
export PAUSE_IMAGE="$(kubeadm config images list | grep pause)"
sudo sed -i 's,sandbox_image = .*,sandbox_image = '\"$PAUSE_IMAGE\"',' /etc/containerd/config.toml
启用cri插件 sudo sed -i 's/^disabled_plugins \=/\#disabled_plugins \=/g' /etc/containerd/config.toml
安装 cni插件
sudo mkdir -p /opt/cni/bin/
sudo wget https://github.com/containernetworking/plugins/releases/download/v1.3.0/cni-plugins-linux-amd64-v1.3.0.tgz
sudo tar Cxzvf /opt/cni/bin cni-plugins-linux-amd64-v1.3.0.tgz
修改hostname
因为这里的环境使用的是云平台统一创建的虚拟机,所以三台虚拟机的hostname相同,这里做一下修改
hostnamectl set-hostname y1nhui-k8s-master
参考 cilium 的官方文档。我们在执行完k8s master 节点的部署后再执行 CNI 的相关安装
- 很重要,如果不改,哪怕下面的行为已经拖了镜像到本地,apiserver 也会无法启动*
再补充一个 更改 containerd 的 registry
sed -i 's/registry.k8s.io/registry.aliyuncs.com\/google_containers/' /etc/containerd/config.toml
systemctl daemon-reload
systemctl restart containerd
配置 iptables
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system
部署 k8s-master
配置 kubeadm的推荐方式时通过 –config 传递
自定义镜像仓库
考虑到网络问题,这里需要使用 如 阿里云之类的 镜像仓库
导出 kubeadm 默认 init 配置
kubeadm config print init-defaults > init.conf
做 如下修改
apiVersion: kubeadm.k8s.io/v1beta3
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: abcdef.0123456789abcdef
ttl: 24h0m0s
usages:
- signing
- authentication
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: 10.10.88.177 # 对外公开地址
bindPort: 6443
nodeRegistration:
criSocket: unix:///var/run/containerd/containerd.sock
imagePullPolicy: IfNotPresent
name: k8s-master # 节点名称 不配置的话则为节点主机名
taints: null # 污点配置,未null则默认为管理面标记控制面污点
---
apiServer:
timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns: {}
etcd:
local:
dataDir: /var/lib/etcd
imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers #registry.k8s.io 替换为国内镜像源
kind: ClusterConfiguration
kubernetesVersion: 1.24.0
networking:
dnsDomain: cluster.local
serviceSubnet: 10.96.0.0/12
podSubnet: 10.244.0.0/16 # pod 使用的 CIDR
scheduler: {}
---
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
cgroupDriver: systemd
先 pull 镜像看看是否有问题
kubeadm config images pull --config init.yaml
之后执行
kubeadm init --config=init.yaml --upload-certs --skip-phases=addon/kube-proxy --v=5
- skip-phases=addon/kube-proxy 为 cilium 官方要求,若使用CNI不是cilium请参考对应文档
- upload-certs 官网描述为 上传管理面证书到kubeadm-certs Secret 意义不明,但是查找资料有文档推荐使用
执行之后便可以见到成功输出
Your Kubernetes control-plane has initialized successfully!
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:
并且执行提示的指令
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
cilium 部署
安装 helm
查看官方文档与各种其他资料,似乎并不能绕开helm。所以需要先安装一个helm
proxychains wget https://get.helm.sh/helm-v3.12.3-linux-amd64.tar.gz
tar -zxvf helm-v3.12.3-linux-amd64.tar.gz && mv linux-amd64/helm /usr/local/bin/helm
安装 cilium
添加repo
helm repo add cilium https://helm.cilium.io/
安装 cilium 注意这里需要设置 ip port, 直接使用安装会导致cilium无法启动
API_SERVER_IP=<your_api_server_ip>
# Kubeadm default is 6443
API_SERVER_PORT=<your_api_server_port>
proxychains helm install cilium cilium/cilium --version 1.15.5 \
--namespace kube-system \
--set kubeProxyReplacement=true \
--set k8sServiceHost=${API_SERVER_IP} \
--set k8sServicePort=${API_SERVER_PORT}
安装 cilium cli 验证安装
wget https://github.com/cilium/cilium-cli/releases/download/v0.16.7/cilium-linux-amd64.tar.gz
tar xzvfC cilium-linux-amd64.tar.gz /usr/local/bin
rm cilium-linux-amd64.tar.gz
使用 cilium status –wait 查看
发现
Deployment cilium-operator Desired: 2, Ready: 1/2, Available: 1/2, Unavailable: 1/2
但是 通过 kubectl get node 可见 node 已经处于ready(因为kubeadm安装跳过了 kube-proxy,所以如果没有安装cilium等 cni,node 将会处于no ready)
部署 work
总结出可以直接使用的命令流程,可能又部分需要加proxychains 但是直接走到底可以做到一切正常
work 准备工作执行指令一图流
sudo sed -ri '/\sswap\s/s/^#?/#/' /etc/fstab
sudo swapoff -a
sudo apt-get update
sudo install -m 0755 -d /etc/apt/keyrings
sudo apt-get install -y apt-transport-https ca-certificates curl
proxychains curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-archive-keyring.gpg
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
curl -fsSL https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main"
curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg --dearmor -o /usr/share/keyrings/google-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/google-keyring.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
apt install -y kubelet=1.24.17-00 kubeadm=1.24.17-00 kubectl=1.24.17-00
apt-mark hold kubelet kubeadm kubectl
proxychains curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo rm -rf /etc/containerd/config.toml
sudo containerd config default | sudo tee /etc/containerd/config.toml
sudo systemctl stop docker
sudo systemctl restart containerd
VERSION="v1.28.0"
wget https://github.com/kubernetes-sigs/cri-tools/releases/download/$VERSION/crictl-$VERSION-linux-amd64.tar.gz
sudo tar zxvf crictl-$VERSION-linux-amd64.tar.gz -C /usr/local/bin
rm -f crictl-$VERSION-linux-amd64.tar.gz
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml
export PAUSE_IMAGE="$(kubeadm config images list | grep pause)"
sudo sed -i 's,sandbox_image = .*,sandbox_image = '\"$PAUSE_IMAGE\"',' /etc/containerd/config.toml
sudo mkdir -p /opt/cni/bin/
sudo wget https://github.com/containernetworking/plugins/releases/download/v1.3.0/cni-plugins-linux-amd64-v1.3.0.tgz
sudo tar Cxzvf /opt/cni/bin cni-plugins-linux-amd64-v1.3.0.tgz
hostnamectl set-hostname y1nhui-k8s-work1
sed -i 's/registry.k8s.io/registry.aliyuncs.com\/google_containers/' /etc/containerd/config.toml
systemctl daemon-reload
systemctl restart containerd
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system
因为 containerd.io 通过 docker 分发,所以通过apt 安装 containerd 需要 docker 的仓库
同时需要安装docker-ce等,否则会遇到
The following packages have unmet dependencies:
containerd.io : Conflicts: containerd
E: Unable to correct problems, you have held broken packages.
加入集群
首先在 master节点创建token
kubeadm token create
返回的内容类似
5didvk.d09sbcov8ph2amjw
使用命令获取 ca-cert-hase
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | \ openssl dgst -sha256 -hex | sed 's/^.* //'
返回类似
8cb2de97839780a412b93877f8507ad6c94f73add17d5d7058e91741c9d5ec78
使用kubeadm join 命令加入
kubeadm join <control-plane-host>:<control-plane-port> --token <token> --discovery-token-ca-cert-hash sha256:<hash>n
比如笔者的这里使用
kubeadm join 10.10.88.177:6443 --token y76ltj.xyqwukvkuax0xa9b --discovery-token-ca-cert-hash sha256:4e872afb456e0f05ba34ec0c381895b189b6f5cbd27ffcc1c6afdab0931ca026 --node-name k8s-work1
或许读者会发现有的资料提及到了 使用带配置文件的 join,但是考虑到官方文档表示该功能为beta功能,未来可能变动,所以不使用
执行之后,在master使用 kubectl get node
可以见到返回如下
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane 52d v1.24.17
k8s-work1 NotReady <none> 10s v1.24.17
等待cilium 加载后,work1 变回ready
可选
配置 containerd 代理
创建 containerd service 文档
mkdir /etc/systemd/system/containerd.service.d/
写入代理
cat > /etc/systemd/system/containerd.service.d/http-proxy.conf <<-EOF
[Service]
Environment="HTTP_PROXY=<your_proxy>"
Environment="HTTPS_PROXY=<your_proxy>"
Environment="NO_PROXY=localhost,127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,.svc,.cluster.local,.ewhisper.cn,<nodeCIDR>,<APIServerInternalURL>,<serviceNetworkCIDRs>,<etcdDiscoveryDomain>,<clusterNetworkCIDRs>,<platformSpecific>,<REST_OF_CUSTOM_EXCEPTIONS>"
EOF
重启
systemctl daemon-reload
systemctl restart containerd
安装 hubble
获取 hubble yaml
proxychains wget https://raw.githubusercontent.com/cilium/hubble/v0.5/tutorials/deploy-hubble-servicemap/hubble-all-minikube.yaml
创建pod等
kubectl apply -f hubble-all-minikube.yaml
创建一个 nodeport
kubectl -n kube-system get svc hubble-ui -o yaml > ui.yaml
修改 type 为 NodePort,sepc 只保留 ports selector sessionAffinity 与 type
启用后,即可通过nodeport 访问 hubble 网页
总结
本文总结了无kube-proxy安装 使用 cilium的 k8s集群
文章写作一拖再拖,终于实在看了玩k8s in action 打算开始学 service mesh 没有环境忍无可忍的情况下写完