保姆级Ubuntu20/22安装Kubernetes与踩坑
Kubernetes:1.25.10 (1.24+已经弃用了docker,初始化时会有超时异常)
OS:Ubuntu 20.04.2 LTS / Ubuntu 22
Kubernetes:1.25.10 (1.24+已经弃用了docker,初始化时会有超时异常)官方文档:
Creating a cluster with kubeadm参考博客:
使用Kubeadm(1.13+)快速搭建Kubernetes集群 - 雨夜朦胧
Ubuntu 22.10 安装 k8s 1.25.3
一、准备
两台虚拟机(CPU最少2核)
禁用swap
Kubernetes 1.8开始要求必须禁用Swap(内存交换),如果不关闭,默认配置下kubelet将无法启动
sudo vim /etc/fstab
"""
# 注释下面这行
#/swap.img none swap sw 0 0
"""
sudo swapoff -a
# 确认swap已经关闭:若swap行都显示 0 则表示关闭成功
free -m
hosts配置
sudo vim /etc/hosts
"""
# 自己本地ip
192.168.10.110 k8s-master
192.168.10.111 k8s-node-1
"""
reboot # 重启
安装docker
Kubernetes从1.6开始使用CRI(Container Runtime Interface)容器运行时接口。默认的容器运行时仍然是Docker,是使用kubelet中内置dockershim CRI来实现的
docker详细安装教程
查看CHANGELOG-x.xx.md选择Kubernetes对应的docker版本
sudo apt-get remove docker docker-engine docker.io containerd runc
sudo apt-get update
# 更新apt包索引并安装包以允许apt通过 HTTPS 使用存储库:
sudo apt-get install -y ca-certificates curl gnupg lsb-release
# 添加 Docker 的官方 GPG 密钥
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# 设置稳定存储库
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu jammy stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo chmod a+r /etc/apt/keyrings/docker.gpg
sudo apt-get update
sudo apt-get install -y docker-ce=5:20.10.17~3-0~ubuntu-jammy docker-ce-cli=5:20.10.17~3-0~ubuntu-jammy containerd.io docker-buildx-plugin docker-compose-plugin
sudo cp /etc/containerd/config.toml /etc/containerd/config.toml.bak
sudo containerd config default > $HOME/config.toml
sudo cp $HOME/config.toml /etc/containerd/config.toml
sudo systemctl stop containerd.service
sudo systemctl stop docker.service
# 修改 /etc/containerd/config.toml 文件后,要将 docker、containerd 停止后,再启动
sudo sed -i "s#registry.k8s.io/pause#registry.cn-hangzhou.aliyuncs.com/google_containers/pause#g" /etc/containerd/config.toml
# https://kubernetes.io/zh-cn/docs/setup/production-environment/container-runtimes/#containerd-systemd
# 确保 /etc/containerd/config.toml 中的 disabled_plugins 内不存在 cri
##### Ubuntu 22+的版本一定要执行下面命令
sudo sed -i "s#SystemdCgroup = false#SystemdCgroup = true#g" /etc/containerd/config.toml
sudo systemctl enable --now containerd.service
sudo systemctl restart docker.service
sudo systemctl enable docker.service
systemctl list-unit-files | grep docker
设置docker权限
如果使用docker images
提醒没有权限,可用下面命令设置
sudo chown root:docker /var/run/docker.sock # 修改docker.sock权限为root:docker
sudo groupadd docker # 添加docker用户组
sudo gpasswd -a $USER docker # 将当前用户添加至docker用户组
newgrp docker # 更新docker用户组
配置docker
sudo vim /etc/docker/daemon.json
"""
{
"registry-mirrors": [
"https://docker.mirror.ustc.edu.cn",
"https://registry.docker-cn.com"
],
"exec-opts": ["native.cgroupdriver=systemd"], # 最重要的是这行配置cgroups
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
"""
sudo systemctl daemon-reload
sudo systemctl restart docker.service
sudo docker info # 查看是否设置成功
为什么要修改为使用systemd
Kubernetes 推荐使用 systemd 来代替 cgroupfs,因为systemd是Kubernetes自带的cgroup管理器,负责为每个进程分配cgroups,但docker的cgroup driver默认是cgroupfs,这样就同时运行有两个cgroup控制管理器,当资源有压力的情况时,有可能出现不稳定的情况
安装 kubeadm, kubelet, kubectl
- kubeadm: 引导启动k8s集群的命令行工具。
- kubelet: 在群集中所有节点上运行的核心组件, 用来执行如启动pods和containers等操作。
- kubectl: 操作集群的命令行工具。
sudo apt-get update && sudo apt-get install -y apt-transport-https
curl -s https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add -
sudo vim /etc/apt/sources.list.d/kubernetes.list
"""
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
"""
sudo apt update
# k8s1.23以上版本,已经弃用了docker了,如果安装的kubelet kubeadm kubectl,最好指定版本
# k8s的Calico网络插件最新版本v3.25只支持到k8s 1.25版本,所以这里安装1.25版本
sudo apt-get install -y kubelet=1.25.10-00 kubeadm=1.25.10-00 kubectl=1.25.10-00
# 阻止自动更新(apt upgrade时忽略)。所以更新的时候先unhold,更新完再hold
sudo apt-mark hold kubelet kubeadm kubectl
# 开机自启
sudo systemctl enable kubelet.service
apt-mark 使用
功能
apt-mark 可以对软件包进行设置(手动/自动 )安装标记,也可以用来处理软件
包的 dpkg(1) 选中状态,以及列出或过滤拥有某个标记的软件包。语法
apt-mark [选项] {auto|manual} 软件包1 [软件包2 …]
命令
auto – 标记指定软件包为自动安装
manual – 标记指定软件包为手动安装
minimize-manual – Mark all dependencies of meta packages as automatically installed.
hold – 标记指定软件包为保留(held back),阻止软件自动更新
unhold – 取消指定软件包的保留(held back)标记,解除阻止自动更新
showauto – 列出所有自动安装的软件包
showmanual – 列出所有手动安装的软件包
showhold – 列出设为保留的软件包
二、创建节点(master、node)
1. 初始化 k8s-master
K8s的控制面板组件运行在Master节点上,包括etcd和API server(Kubectl便是通过API server与k8s通信)
sudo kubeadm init \
--kubernetes-version v1.26.5 \
--pod-network-cidr=10.244.0.0/16 \
--apiserver-advertise-address=x.x.x.x \
--image-repository registry.aliyuncs.com/google_containers
–pod-network-cidr
选择一个Pod网络插件,并检查它是否需要在初始化Master时指定一些参数,它的值取决于你在下一步选择的哪个网络网络插件,这里选择Flannel的网络插件参数为 10.244.0.0/16。Calico网络为192.168.0.0/16。参考:Installing a pod network add-on
–apiserver-advertise-address=
kubeadm使用eth0的默认网络接口(通常是内网IP)做为Master节点的advertise address,如果我们想使用不同的网络接口,该参数来设置。
如果适应IPv6,则必须使用IPv6d的地址,如:--apiserver-advertise-address=fd00::101
。–image-repository
使用
kubeadm config images pull
来预先拉取初始化需要用到的镜像,用来检查是否能连接到Kubenetes
的Registries
。
Kubenetes
默认Registries
地址是k8s.gcr.io
,很明显,在国内并不能访问gcr.io,因此在kubeadm v1.13之前的版本,安装起来非常麻烦,但是在1.13
版本中终于解决了国内的痛点,其增加了一个--image-repository
参数,默认值是k8s.gcr.io
,我们将其指定为国内镜像地址:registry.aliyuncs.com/google_containers
。–kubernetes-version
默认值是
stable-1
,会导致从https://dl.k8s.io/release/stable-1.txt
下载最新的版本号,我们可以将其指定为固定版本来跳过网络请求。
如果我们想使用非root用户操作kubectl
,可以使用以下命令,这也是kubeadm init
输出的一部分
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
export KUBECONFIG=/etc/kubernetes/admin.conf
2. 添加节点k8s-node
查询token(master)
kubeadm token list
注意:
Token 的过期时间是24小时
如果该命令查无数据,则直接跳转到重新生成Token
查询cert-hash(master)
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
拼接连接字符串(node)
sudo kubeadm join 192.168.88.123:6443 --token ay9cdc.0n7sjjy21hejhdae --discovery-token-ca-cert-hash sha256:091d0e1adc9cc4e77cd6d25fb5eebc1a594c690827362a594abffa0b193861a2
如果node节点加入到集群时卡住
[preflight] Running pre-flight checks
有两种原因
- master与node时间不同步,使用
date
命令查看- master的token过期,重新生成一个
重新生成Token(master)
执行了查询Token的命令,没有返回数据时,需要重新生成Token
kubeadm token create --ttl 0 --print-join-command
查看kubelet日志
journalctl -xefu kubelet
三、遇到的异常
[ERROR Port-10250]: Port 10250 is in use
端口被启动失败或者成功的kubeadm占用
sudo netstat -ntlup|grep 10250
"""
tcp6 0 0 :::10250 :::* LISTEN 27560/kubelet
"""
sudo kill -9 27560
sudo kubeadm reset
[ERROR FileAvailable–etc-kubernetes-manifests-kube-apiserver.yaml]: /etc/kubernetes/manifests/kube-apiserver.yaml already exists
yaml文件已存在
sudo kubeadm reset
[kubelet-check] The HTTP call equal to ‘curl -sSL http://localhost:10248/healthz’ failed with error: Get http://localhost:10248/healthz: dial tcp 127.0.0.1:10248: connect: connection refused.
使用tcp协议连接到127.0.0.1:10248的连接被拒绝。这是cgroup驱动问题。默认情况下Kubernetes cgroup驱动程序设置为system,但docker设置为systemd。我们需要更改Docker cgroup驱动。
sudo vim /etc/docker/daemon.json
"""
# 如果配置了daemon.json加上{}内的参数即可
{
"exec-opts": ["native.cgroupdriver=systemd"]
}
"""
sudo systemctl daemon-reload
sudo systemctl restart docker
sudo systemctl restart kubelet
sudo kubeadm reset
sudo kubeadm init
# 还有个可能是没有关闭交换分区
[ERROR CRI]: container runtime is not running: output: E1021 15:03:22.662135
rm -rf /etc/containerd/config.toml
systemctl restart containerd
[ERROR CRI]: container runtime is not running: output: time=“2023-03-24T19:16:15+08:00” level=fatal msg=“validate service connection: CRI v1 runtime API is not implemented for endpoint “unix:///var/run/containerd/containerd.sock” : rpc error: code = Unimplemented desc = unknown service runtime.v1.RuntimeService”
sudo vim /etc/containerd/config.toml
"""
# 更改如下配置
# disabled_plugins : ["cri"]
disabled_plugins : []
"""
# 重启容器
sudo systemctl restart containerd
Unable to connect to the server: x509: certificate signed by unknown authority
参考kubernetes 坑人的错误
kubeadm reset
先 rm -rf $HOME/.kube
然后执行 kubeadm init ...
couldn’t get current server API group list: Get “https://xxx.xxx.xxx.xxx:6443/api?timeout=32s”: dial tcp xxx.xxx.xxx.xxx:6443: connect: connection refused
配置文件 使用
sudo systemctl stop containerd.service
sudo cp /etc/containerd/config.toml /etc/containerd/config.toml.bak
sudo containerd config default > $HOME/config.toml
sudo cp $HOME/config.toml /etc/containerd/config.toml
# 修改 /etc/containerd/config.toml 文件后,要将 docker、containerd 停止后,再启动
sudo sed -i "s#registry.k8s.io/pause#registry.cn-hangzhou.aliyuncs.com/google_containers/pause#g" /etc/containerd/config.toml
# https://kubernetes.io/zh-cn/docs/setup/production-environment/container-runtimes/#containerd-systemd
# 确保 /etc/containerd/config.toml 中的 disabled_plugins 内不存在 cri
sudo sed -i "s#SystemdCgroup = false#SystemdCgroup = true#g" /etc/containerd/config.toml
kubelet.service: Failed with result ‘exit-code’
原因:重启后交换分区又被开启了或者直接init初始化
Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8)).
sudo cp /etc/apt/trusted.gpg /etc/apt/trusted.gpg.d/
四、安装网络插件
为了让Pods间可以相互通信,我们必须安装一个网络插件,并且必须在部署任何应用之前安装,CoreDNS也是在网络插件安装之后才会启动的。
网络的插件完整列表,请参考 Networking and Network Polic
在安装之前,我们先查看一下当前Pods的状态:
kubectl get pods --all-namespaces -o wide
"""
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-6d8c4cb4d-9kqvq 0/1 Pending 0 2d17h
kube-system coredns-6d8c4cb4d-ql7g9 0/1 Pending 0 2d17h
kube-system etcd-k8s-master 1/1 Running 4 2d17h
kube-system kube-apiserver-k8s-master 1/1 Running 6 (24m ago) 2d17h
kube-system kube-controller-manager-k8s-master 1/1 Running 4 2d17h
kube-system kube-proxy-lv8td 1/1 Running 4 2d17h
kube-system kube-scheduler-k8s-master 1/1 Running 5 2d17h
"""
可以看到CoreDND
状态是Pending
,这是因为我们还没有安装网络插件。
如果使用kubectl get pods --all-namespaces
报如下错误The connection to the server localhost:8080 was refused
是由于没有执行mkdir -p $HOME/.kube ...
这三行命令
安装 Flannel 网络插件(选择1)
Flannel是用于解决容器跨节点通信问题的解决方案,兼容CNI插件API。它使用“虚拟网桥和veth设备”的方式为Pod创建虚拟网络接口,通过可配置的“后端”定义Pod间的通信网络,支持基于VXLAN和UDP的Overlay网络,以及基于三层路由的Underlay网络。
默认情况下,Flannel网络插件使用的的网段是10.244.0.0/16
,在init
的时候,通过--pod-network-cidr=10.244.0.0/16
来适配Flannel,当然你也可以修改kube-flannel.yml
文件来指定不同的网段。命令如下
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
稍等片刻,再使用kubectl get pods --all-namespaces -o wide
命令来查看网络插件的安装情况:
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-flannel kube-flannel-ds-q8htw 1/1 Running 0 3m
kube-system coredns-6d8c4cb4d-9kqvq 1/1 Running 0 2d22h
kube-system coredns-6d8c4cb4d-ql7g9 1/1 Running 0 2d22h
kube-system etcd-k8s-master 1/1 Running 4 2d22h
kube-system kube-apiserver-k8s-master 1/1 Running 6 (5h6m ago) 2d22h
kube-system kube-controller-manager-k8s-master 1/1 Running 4 2d22h
kube-system kube-proxy-lv8td 1/1 Running 4 2d22h
kube-system kube-scheduler-k8s-master 1/1 Running 5 2d22h
安装 Calico 网络插件(选择2) 亲测有效
Calico是一个纯三层的虚拟网络方案,Calico 为每个容器分配一个 IP,每个 host 都是 router,把不同 host 的容器连接起来。与 VxLAN 不同的是,Calico 不对数据包做额外封装,不需要 NAT 和端口映射,扩展性和性能都很好。
默认情况下,Calico网络插件使用的的网段是192.168.0.0/16
,在init
的时候,通过--pod-network-cidr=192.168.0.0/16
来适配Calico,当然你也可以修改calico.yml
文件来指定不同的网段。命令如下:
curl https://raw.githubusercontent.com/projectcalico/calico/v3.25.1/manifests/calico.yaml -O
kubectl apply -f calico.yaml
# 上面的calico.yaml会去quay.io拉取镜像,如果无法拉取,可使用下面的国内镜像
kubectl apply -f http://mirror.faasx.com/k8s/calico/v3.3.2/rbac-kdd.yaml
kubectl apply -f http://mirror.faasx.com/k8s/calico/v3.3.2/calico.yaml
关于更多Canal
的信息可以查看Calico官方文档:kubeadm quickstart。
稍等片刻,再使用kubectl get pods --all-namespaces
命令来查看网络插件的安装情况。
修改 cidr 地址范围
kubectl -n kube-system edit cm kubeadm-config
vim /etc/kubernetes/manifests/kube-scheduler.yaml
kubectl cluster-info dump | grep -m 1 cluster-cidr # 检查配置是否生效
五、卸载
sudo rm -rvf $HOME/.kube
sudo kubeadm reset -f
sudo apt-get -y auroremove kubelet kubeadm kubectl
sudo rm -rvf /etc/kubernetes/
sudo rm -rvf /etc/systemd/system/kubelet.service.d
sudo rm -rvf /etc/systemd/system/kubelet.service
sudo rm -rvf /usr/bin/kube*
sudo rm -rvf /etc/cni
sudo rm -rvf /opt/cni
sudo rm -rvf /var/lib/etcd
sudo rm -rvf /var/etcd
更多推荐
所有评论(0)