关键字:k8s, init, containerd, docker
单控制平面集群就是只有一个 master 节点的 k8s 集群
实验版本:kube套件 v1.25.2
时间:2022年10月
环境: CentOS 8
# 提示:通过 yum 下载的包,每执行一次,都需要备份下载的包,因为下次执行会删除本次下载的内容
sudo yum install --downloadonly --downloaddir=./kd yum-utils device-mapper-persistent-data lvm2 net-tools
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 这一步会自动下载 container.io
sudo yum install --downloadonly --downloaddir=./kd docker-ce --allowerasing
# 下载 kubernetes 套件
vim /etc/yum.repos.d/kubernetes.repo
cat /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
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
sudo yum install --downloadonly --downloadaddr=./kd kubectl kubelet kubeadm
# 此时总共下载的包有:
ll kd
-rw-r--r--. 1 root root 385600 Sep 28 01:26 device-mapper-1.02.177-10.el8.x86_64.rpm
-rw-r--r--. 1 root root 277096 Sep 28 01:26 device-mapper-event-1.02.177-10.el8.x86_64.rpm
-rw-r--r--. 1 root root 276140 Sep 28 01:26 device-mapper-event-libs-1.02.177-10.el8.x86_64.rpm
-rw-r--r--. 1 root root 418904 Sep 28 01:26 device-mapper-libs-1.02.177-10.el8.x86_64.rpm
-rw-r--r--. 1 root root 946764 Sep 28 01:26 device-mapper-persistent-data-0.9.0-4.el8.x86_64.rpm
-rw-r--r--. 1 root root 1713492 Sep 28 01:26 lvm2-2.03.12-10.el8.x86_64.rpm
-rw-r--r--. 1 root root 1224952 Sep 28 01:26 lvm2-libs-2.03.12-10.el8.x86_64.rpm
-rw-r--r--. 1 root root 34668844 Sep 28 00:36 containerd.io-1.6.8-3.1.el8.x86_64.rpm
-rw-r--r--. 1 root root 21953108 Sep 28 00:35 docker-ce-20.10.18-3.el8.x86_64.rpm
-rw-r--r--. 1 root root 30951856 Sep 28 00:36 docker-ce-cli-20.10.18-3.el8.x86_64.rpm
-rw-r--r--. 1 root root 4855528 Sep 28 00:35 docker-ce-rootless-extras-20.10.18-3.el8.x86_64.rpm
-rw-r--r--. 1 root root 3933420 Sep 28 00:35 docker-scan-plugin-0.17.0-3.el8.x86_64.rpm
-rw-r--r--. 1 root root 71256 Sep 28 00:35 libcgroup-0.41-19.el8.x86_64.rpm
-rw-r--r--. 1 root root 16049626 Sep 28 01:39 14083ac8b11792469524dae98ebb6905b3921923937d6d733b8abb58113082b7-kubernetes-cni-1.1.1-0.x86_64.rpm
-rw-r--r--. 1 root root 10234290 Sep 28 01:39 3062280e93933954707f9a6a31d36dbcc0856ecae323c12146c94d51641e28da-kubeadm-1.25.2-0.x86_64.rpm
-rw-r--r--. 1 root root 21793274 Sep 28 01:39 74b96e0afbbeb02ee0f0cfcdb7f0138984c4e62fff8329d49cc8131271c2cc12-kubelet-1.25.2-0.x86_64.rpm
-rw-r--r--. 1 root root 10607794 Sep 28 01:39 856b98e0a67e4f6d62f284f83fcba535087a6b5530d348775fd84f8bd294dbd9-kubectl-1.25.2-0.x86_64.rpm
-rw-r--r--. 1 root root 208824 Sep 28 01:39 conntrack-tools-1.4.4-10.el8.x86_64.rpm
-rw-r--r--. 1 root root 8552778 Sep 28 01:39 e382ead81273ab8ebcddf14cc15bf977e44e1fd541a2cfda6ebe5741c255e59f-cri-tools-1.25.0-0.x86_64.rpm
-rw-r--r--. 1 root root 24660 Sep 28 01:39 libnetfilter_cthelper-1.0.0-15.el8.x86_64.rpm
-rw-r--r--. 1 root root 24700 Sep 28 01:39 libnetfilter_cttimeout-1.0.0-11.el8.x86_64.rpm
-rw-r--r--. 1 root root 31976 Sep 28 01:39 libnetfilter_queue-1.0.4-3.el8.x86_64.rpm
-rw-r--r--. 1 root root 330692 Sep 28 01:39 socat-1.7.4.1-1.el8.x86_64.rpm
# -U用于更新系统已经安装的包
rpm -Uvh device-mapper-1.02.177-10.el8.x86_64.rpm device-mapper-event-1.02.177-10.el8.x86_64.rpm device-mapper-event-libs-1.02.177-10.el8.x86_64.rpm device-mapper-libs-1.02.177-10.el8.x86_64.rpm device-mapper-persistent-data-0.9.0-4.el8.x86_64.rpm lvm2-2.03.12-10.el8.x86_64.rpm lvm2-libs-2.03.12-10.el8.x86_64.rpm
# 安装 docker-ce
rpm -q buildah
#查出 buildah 包名
#同理查出cockpit-podman,containers-common,podman,podman-catatonit ,然后
rpm -e xxx yyy
# 擦除上面5个包
rpm -q runc
rpm -e runc-xxx
rpm -ivh containerd.io-1.6.8-3.1.el8.x86_64.rpm docker-ce-20.10.18-3.el8.x86_64.rpm docker-ce-cli-20.10.18-3.el8.x86_64.rpm docker-ce-rootless-extras-20.10.18-3.el8.x86_64.rpm docker-scan-plugin-0.17.0-3.el8.x86_64.rpm libcgroup-0.41-19.el8.x86_64.rpm
# 安装 kube 套件
rpm -ivh 14083ac8b11792469524dae98ebb6905b3921923937d6d733b8abb58113082b7-kubernetes-cni-1.1.1-0.x86_64.rpm 3062280e93933954707f9a6a31d36dbcc0856ecae323c12146c94d51641e28da-kubeadm-1.25.2-0.x86_64.rpm 74b96e0afbbeb02ee0f0cfcdb7f0138984c4e62fff8329d49cc8131271c2cc12-kubelet-1.25.2-0.x86_64.rpm 856b98e0a67e4f6d62f284f83fcba535087a6b5530d348775fd84f8bd294dbd9-kubectl-1.25.2-0.x86_64.rpm conntrack-tools-1.4.4-10.el8.x86_64.rpm e382ead81273ab8ebcddf14cc15bf977e44e1fd541a2cfda6ebe5741c255e59f-cri-tools-1.25.0-0.x86_64.rpm libnetfilter_cthelper-1.0.0-15.el8.x86_64.rpm libnetfilter_cttimeout-1.0.0-11.el8.x86_64.rpm libnetfilter_queue-1.0.4-3.el8.x86_64.rpm socat-1.7.4.1-1.el8.x86_64.rpm
vim /etc/sysconfig/kubelet
# 设置 KUBELET_EXTRA_ARGS="--cgroup-driver=systemd"
vi /usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf
# Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --cgroup-driver=systemd"
systemctl daemon-reload
systemctl enable kubelet
systemctl restart kubelet
首先搭建本地镜像仓库,例如Docker的仓库registry,不需要开启 tls,因为开启了也没啥用,很多程序不支持自签名 https
# 互联网
docker pull registry
docker save <image id> > ./registry.tar
# 内网
docker load -i registry.tar
docker tag <image id> registry:2.7
vim /etc/docker/daemon.json # 配置 docker 的本地仓库地址,方便 docker 操作仓库的拉取和上传
cat /etc/docker/daemon.json
{
"insecure-registries":["10.x.x.x:5000"]
}
systemctl daemon-reload
systemctl restart docker
docker run -itd -v /data/registry:/var/lib/registry -p 5000:5000 --restart=always --name registry registry:2.7
# 查看私有仓库
curl http://ip:5000/v2/_catalog
Containerd 运行时是 k8s 在运行时自动找到的 cri,默认使用 containerd 管理镜像和容器
之前以为 k8s 的镜像操作( push\pull)是使用 Docker 体系,后来才发现,其实使用的是 containerd,这个区别在于,指定私有镜像仓库后,即时 Docker 配置了 insecure-registries,在 containerd 未设置有关私有仓库配置的情况下,k8s 拉取镜像会报错“http: server gave HTTP response to HTTPS client”
cat << EOF > /etc/modules-load.d/containerd.conf
overlay
br_netfilter
EOF
# 生成配置文件
containerd config default > /etc/containerd/config.toml
# 编辑配置文件
vim /etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true
[plugins."io.containerd.grpc.v1.cri"]
sandbox_image = "10.xx.xx.xx:5000/k8s.gcr.io/pause:3.8"
#sandbox_image = "k8s.gcr.io/pause:3.2"
# 这里的配置需要跟后续本地仓库中存储的沙盒镜像名一致
[plugins."io.containerd.grpc.v1.cri".registry]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = ["https://docker.mirrors.ustc.edu.cn"]
#endpoint = ["https://registry-1.docker.io"]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."*"]
endpoint = ["https://docker.mirrors.ustc.edu.cn"]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."192.168.196.110:5000"]
endpoint = ["http://10.xx.xx.xx:5000"]
[plugins."io.containerd.grpc.v1.cri".registry.configs]
[plugins."io.containerd.grpc.v1.cri".registry.configs."192.168.196.110:5000".tls]
insecure_skip_verify = true
# 标红的是需要修改的地方
systemctl enable containerd
systemctl restart containerd
# 这一步需要在内网环境进行,因为内外网 kube 套件的版本不一致会导致镜像版本错误
kubeadm config images list --image-repository=registry.aliyuncs.com/google_containers
# --kubernetes-version 参数对某些镜像无效,因此不能指望该参数会找到所需要版本的镜像
# --image-repository 参数可以指定国内镜像源
registry.aliyuncs.com/google_containers/kube-apiserver:v1.25.2
registry.aliyuncs.com/google_containers/kube-controller-manager:v1.25.2
registry.aliyuncs.com/google_containers/kube-scheduler:v1.25.2
registry.aliyuncs.com/google_containers/kube-proxy:v1.25.2
registry.aliyuncs.com/google_containers/pause:3.9
registry.aliyuncs.com/google_containers/etcd:3.5.4-0
registry.aliyuncs.com/google_containers/coredns:v1.9.3
# 试了使用 kubeadm config images pull 的方式拉取,在设置了镜像仓库后确实可以拉取,然而无论用 docker images 还是 ctr image list 查找拉取的镜像,都找不到,后来发现需要用 crictl images来查看拉取的镜像列表,
# crictl 是 CRI 兼容的容器运行时命令行接口。 可以使用它来检查和调试 Kubernetes 节点上的容器运行时和应用程序。https://kubernetes.io/zh-cn/docs/tasks/debug/debug-cluster/crictl
# 可以使用 docker pull 一个一个的拉取镜像例如:
docker pull registry.aliyuncs.com/google_containers/kube-apiserver:v1.25.2
docker save -o kube-apiserver.tar registry.aliyuncs.com/google_containers/kube-apiserver:v1.25.2
#也可以写个 shell 脚本更方便的拉取镜像并保存到本地文件
# cat pull-save-images.sh
#!/bin/bash
images=(
kube-apiserver:v1.25.2
kube-controller-manager:v1.25.2
kube-scheduler:v1.25.2
kube-proxy:v1.25.2
pause:3.9
etcd:3.5.4-0
coredns:1.9.3
)
for imageName in ${images[@]};
do
docker pull registry.aliyuncs.com/google_containers/${imageName}
docker tag registry.aliyuncs.com/google_containers/${imageName} 10.x.x.x:5000/registry.aliyuncs.com/google_containers/${imageName}
docker rmi registry.aliyuncs.com/google_containers/${imageName}
docker save -o `echo ${imageName}|awk -F ':' '{print $1}'`.tar 10.x.x.x:5000/registry.aliyuncs.com/google_containers/${imageName}
done
# 10.x.x.x:5000 是内网镜像仓库接口
# cat load-push-image.sh
#!/bin/bash
ls /xxx/kubeadm-images-1.25.2 > /xx/images-list.txt
cd /xxx/kubeadm-images-1.25.2
for i in $(cat /root/images-list.txt)
do
docker load -i $i
done
images=(
kube-apiserver:v1.25.2
kube-controller-manager:v1.25.2
kube-scheduler:v1.25.2
kube-proxy:v1.25.2
pause:3.9
etcd:3.5.4-0
coredns:1.9.3
)
for imageName in ${images[@]};
do
docker push 10.x.x.x:5000/registry.aliyuncs.com/google_containers/${imageName}
done
# 这里 push 的镜像标签需要与上面 pull-save-images.sh 中的镜像标签相互呼应
# 查看镜像仓库中的镜像
curl http://10.x.x.x:5000/v2/_catalog |jq
# 发现一个好用的 linux 工具 jq,可以格式化输出 json 格式文本
查看文件是否存在: ls /etc/resolv.conf
内网本来没有设置DNS,因为意义不大,但CentOS在没有DNS的情况下,默认没有文件 /etc/resolv.conf,这会导致在 kubeadm init 的阶段,报错
Couldn't initialize a kubernetes cluster
调取 kubelet 的日志:
journalctl -xeu kubelet
会出现 "Error getting node" err="node "localhost.localdomain" not found", 日志前面会出现
"Failed to generate sandbox config for pod" err=”open /etc/resolv.conf: no such file or directory"
出现这个错误就是因为,k8s找不到 /etc/resolv.conf 文件,从而无法创建沙盒 pod,这应该是 k8s 内网环境的兼容性问题,希望以后 k8s 可以对内网环境友好
kubeadm init --image-repository=10.x.x.x:5000/registry.k8s.io --pod-network-cidr=192.168.0.0/16 --apiserver-advertise-address=10.x.x.x
# --image-repository 指定本地镜像仓库和路径
# --pod-network-cidr 预先选取 calico 网络插件作为 k8s 集群的 pod 网络插件,calico 默认的容器网络子网为 192.168.0.0/16,与内网环境的子网10.x 段不冲突,所以使用该网段
# --apiserver-advertise-address,除非另有说明,否则 kubeadm 使用与默认网关关联的网络接口来设置此控制平面节点 API server 的广播地址。
# 不要设置--control-plane-endpoint,只有HA集群才配置这个参数,为所有控制平面节点设置共享端点。 端点可以是负载均衡器的 DNS 名称或 IP 地址