1. 使用kubeadm搭建Kubernetes集群
安装kubeadm官方文档:https://v1-31.docs.kubernetes.io/zh-cn/docs/setup/production-environment/tools/kubeadm/install-kubeadm/
1.1 常见的搭建方式
- minikube(学习时使用,更小更轻量)
- kubeadm
- 二进制安装
- 命令行工具
1.2 服务器要求
最少需要2台服务器(虚拟机)
k8s-master head: 10.240.208.246
k8s-node1 c1: 10.240.208.218
k8s-node2 c2: 10.240.208.128
最低配置:2核、2G内存、20G硬盘
需要联网,不能联网的话需要有提供对应镜像的私有仓库
1.3 软件环境
- 操作系统:Rocky 9.4
- podman:5.2.2
- k8s:1.31
1.4 安装步骤
1.4.1 初始化操作(所有节点)
# 关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
# 关闭selinux
sed -i 's/enforcing/disabled/' /etc/selinux/config # 永久
setenforce 0 # 临时
# 关闭swap
swapoff -a # 临时
sed -ri 's/.*swap./#&/' /etc/fstab # 永久
# free -m # 检查swap行是否有值
# 关闭完swap后,一定要重启一下虚拟机!!!
# 根据规划设置主机名
hostnamectl set-hostname <hostname>
# 在master添加hosts
cat >> /etc/hosts << EOF
10.240.208.246 head
10.240.208.218 c1
10.240.208.128 c2
EOF
# 将桥接的IPv4流量传递到iptables的链
cat > /etc/sysctl.d/k8s.conf << EOF
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system # 生效
# 使用以下命令验证 net.ipv4.ip_forward 是否设置为 1:
sysctl net.ipv4.ip_forward
# 时间同步
yum install ntpdate -y
ntpdate time.windows.com
1.4.2 安装基础软件(所有节点)
1.4.2.1 安装Podman
从centos8开始已经自带podman,在安装系统时的软件安装中选择容器即自带podman。
dnf install -y podman
podman -v
1.4.2.2 安装容器运行时
下载安装文档:https://github.com/containerd/containerd/blob/main/docs/getting-started.md
可以根据文档中的步骤1至3完成即可。下面的操作基本与文档一致,根据自己实际情况略有改动~
安装 containerd
wget https://github.com/containerd/containerd/releases/download/v2.0.5/containerd-2.0.5-linux-amd64.tar.gz tar Cxzvf /usr/local containerd-2.0.5-linux-amd64.tar.gz wget https://raw.githubusercontent.com/containerd/containerd/main/containerd.service mv containerd.service /usr/lib/systemd/system systemctl daemon-reload systemctl enable --now containerd
安装 runc
wget https://github.com/opencontainers/runc/releases/download/v1.2.6/runc.amd64 install -m 755 runc.amd64 /usr/local/sbin/runc
安装 CNI 插件
wget https://github.com/containernetworking/plugins/releases/download/v1.6.2/cni-plugins-linux-amd64-v1.6.2.tgz mkdir -p /opt/cni/bin tar Cxzvf /opt/cni/bin cni-plugins-linux-amd64-v1.6.2.tgz
配置 containerd
如果本地没有
/etc/containerd/config.toml
,可以执行containerd config default
命令查看默认的配置文件内容,并把默认内容写入文件即可。mkdir /etc/containerd containerd config default > /etc/containerd/config.toml systemctl restart containerd
使用镜像加速器(可选),添加如下配置:
[plugins.'io.containerd.cri.v1.images'.registry.mirrors] [plugins.'io.containerd.cri.v1.images'.registry.mirrors."docker.io"] endpoint = ["<your_mirror_address>", "https://registry-1.docker.io"] # 我的配置示例中的上下文: [plugins.'io.containerd.cri.v1.images'.registry] config_path = '' [plugins.'io.containerd.cri.v1.images'.registry.mirrors] [plugins.'io.containerd.cri.v1.images'.registry.mirrors."docker.io"] endpoint = ["https://test.com"]
1.4.2.3 添加仓库
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.31/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.31/rpm/repodata/repomd.xml.key
exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni
EOF
1.4.2.4 安装 kubeadm、kubelet、kubectl
kubeadm
:用来初始化集群的指令。kubelet
:在集群中的每个节点上用来启动 Pod 和容器等。kubectl
:用来与集群通信的命令行工具。
sudo yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
sudo systemctl enable --now kubelet
(可选)设置 crictl,修复警告信息 WARN[0000] image connect using default endpoints:
:
这里做个crictl的简单解释:
我们使用containerd方式安装K8S,crictl工具作为镜像管理的客户端工具
crictl 是 CRI 兼容的容器运行时命令行接口。 可以通过 crictl 在Kubernetes节点检查( inspect )和debug容器runtime和应用程序。
crictl 和它的源代码在 cri-tools 代码库。
cat > /etc/crictl.yaml << EOF
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
EOF
systemctl daemon-reload
systemctl restart kubelet
1.4.3 基础镜像准备(可选;网络环境好的可以跳过此步骤)
因为正常拉取镜像会很慢很慢,所以需要其它办法,比如自行拉取加速镜像,然后重命名为k8s的镜像名即可。
kubeadm config images list # 列出需要的镜像
# crictl 拉取镜像
crictl pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io/kube-apiserver:v1.31.6
crictl pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io/kube-controller-manager:v1.31.6
crictl pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io/kube-scheduler:v1.31.6
crictl pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io/kube-proxy:v1.31.6
crictl pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io/coredns/coredns:v1.11.3
crictl pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io/pause:3.10
crictl pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io/etcd:3.5.15-0
# 修改镜像名
ctr --namespace k8s.io image tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io/kube-apiserver:v1.31.6 registry.k8s.io/kube-apiserver:v1.31.6
ctr --namespace k8s.io image tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io/kube-controller-manager:v1.31.6 registry.k8s.io/kube-controller-manager:v1.31.6
ctr --namespace k8s.io image tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io/kube-scheduler:v1.31.6 registry.k8s.io/kube-scheduler:v1.31.6
ctr --namespace k8s.io image tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io/kube-proxy:v1.31.6 registry.k8s.io/kube-proxy:v1.31.6
ctr --namespace k8s.io image tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io/coredns/coredns:v1.11.3 registry.k8s.io/coredns/coredns:v1.11.3
ctr --namespace k8s.io image tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io/pause:3.10 registry.k8s.io/pause:3.10
ctr --namespace k8s.io image tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io/etcd:3.5.15-0 registry.k8s.io/etcd:3.5.15-0
# 检查镜像
crictl images
1.4.4 部署 Kubernetes Master
初始化主节点:
kubeadm init \
--apiserver-advertise-address=10.240.208.246 \
--kubernetes-version v1.31.6 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16
# --image-repository docker-1.1yidc.com
# 解释:
# apiserver-advertise-address: 填写master地址
# image-repository: 基于某个仓库拉取镜像
# kubernetes-version: k8s的版本
# service-cidr: service网段
# pod-network-cidr: 指定pod网段
当初始化成功之后,会输出让你执行如下命令(同时也有join命令,谨慎清屏!!!):
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
1.4.5 加入 Kubernetes Node
在c1和c2上执行操作
kubeadm join 10.240.208.246:6443 --token <master控制台的token> --discovery-token-ca-cert-hash <master控制台的hash>
# 例如:
kubeadm join 10.240.208.246:6443 --token bdatpm.v2kupreka09obstm --discovery-token-ca-cert-hash sha256:9ef4ab902f04bb68d9ae9bfd153b7159dfc8743f3a317d82370ee9156c3bbe94
如果初始化的 token 不小心清空了,可以通过如下命令获取或者重新申请:
kubeadm token create
:重新申请token
kubeadm token list
:查看当前可用的token获取
--discovery-token-ca-cert-hash
值,得到值后需要在前面拼接上 sha256:openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | \ openssl dgst -sha256 -hex | sed 's/^.* //'
加入主节点成功后,我们可以在master节点查看节点状态信息:
[root@head ~]# kubectl get nodes # 在master节点执行命令查看节点;可以简写为no
NAME STATUS ROLES AGE VERSION
c1 NotReady <none> 8m45s v1.31.7
c2 NotReady <none> 8m8s v1.31.7
head NotReady control-plane 42m v1.31.7
[root@head ~]# kubectl get componentstatus # 查看组件状态,可简写为cs
Warning: v1 ComponentStatus is deprecated in v1.19+
NAME STATUS MESSAGE ERROR
scheduler Healthy ok
controller-manager Healthy ok
etcd-0 Healthy ok
为什么节点状态是 NotReady
,可以查看系统 pod 状态,发现 coredns-*
是 Pending
状态,那么我们需要配置网络。
[root@head ~]# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-7c65d6cfc9-mv5ch 0/1 Pending 0 40m
coredns-7c65d6cfc9-n4nq4 0/1 Pending 0 40m
etcd-head 1/1 Running 2 40m
kube-apiserver-head 1/1 Running 0 40m
kube-controller-manager-head 1/1 Running 0 40m
kube-proxy-2vsbg 0/1 ContainerCreating 0 6m36s
kube-proxy-qxxrm 1/1 Running 0 40m
kube-proxy-tclfx 0/1 ContainerCreating 0 5m59s
kube-scheduler-head 1/1 Running 0 40m
1.4.6 安装Pod网络附加组件
常见的安装是 Calico 和 Flannel,我们这里采用Calico。
下载 calico 配置文件:
mkdir /opt/k8s
cd /opt/k8s
curl https://calico-v3-25.netlify.app/archive/v3.25/manifests/calico.yaml -O
修改 calico.yaml 文件中的
CALICO_IPV4POOL_CIDR
配置,修改为与初始化的 cidr 相同删除镜像
docker.io/
前缀,避免下载过慢导致失败sed -i 's#docker.io/##g' calico.yaml
镜像拉取缓慢的解决办法:
grep image calico.yaml # 根据查出来的镜像挨个通过加速器方法下载(与步骤1.4.3类似) # 拉取镜像(为了防止运行不起来,所有节点都拉一下) crictl pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/calico/cni:v3.25.0 crictl pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/calico/node:v3.25.0 crictl pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/calico/kube-controllers:v3.25.0 # 重命名 ctr --namespace k8s.io image tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/calico/cni:v3.25.0 docker.io/calico/cni:v3.25.0 ctr --namespace k8s.io image tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/calico/node:v3.25.0 docker.io/calico/node:v3.25.0 ctr --namespace k8s.io image tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/calico/kube-controllers:v3.25.0 docker.io/calico/kube-controllers:v3.25.0
执行应用
kubectl apply -f calico.yaml kubectl get pods -n kube-system # 查看应用情况 kubectl describe po calico-kube-controllers-6879d4fcdc-sgk2c -n kube-system # 查看某个pod的详细信息(可以通过该命令查看pod没有running的原因)
1.4.7 测试 Kubernetes 集群
拉取一个nginx镜像做测试
crictl pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/nginx:latest
ctr --namespace k8s.io image tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/nginx:latest docker.io/library/nginx:latest
创建部署:
kubectl create deployment nginx --image=nginx # 默认从docker.io仓库拉取
kubectl create deployment nginx --image=docker-1.1yidc.com/library/nginx:latest # 可以指定从哪个镜像站拉取镜像
暴露端口:
kubectl expose deployment nginx --port=80 --type=NodePort
查看 pod 以及服务信息:
kubectl get pod,svc
1.4.8 其它补充
kubelet使用国内镜像站,添加一行 image-repository
内容:
vi /usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf
[Service]
Environment="KUBELET_EXTRA_ARGS=--image-repository=<your_mirror_address>"
sudo systemctl daemon-reload
sudo systemctl restart kubelet
2. 命令行工具 kubectl
2.1 在任意节点使用kubectl
在上面的操作过程中,你应该发现了在子节点执行kubectl命令发现不可用,kubectl 的本质就是向 api-server 发请求。因此要想子节点可用我们可以进行如下配置:
将 master 节点中
/etc/kubernetes/admin.conf
拷贝到需要运行的服务器的/etc/kubernetes
目录中scp /etc/kubernetes/admin.conf root@c1:/etc/kubernetes
在对应的服务器上配置环境变量
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bashprofile source ~/.bashprofile
按照步骤完成后就可以了。
2.2 资源类型与别名
命令全称 | 缩写 |
---|---|
pods | po |
deployments | deploy |
services | svc |
namespace | ns |
nodes | no |
上面是我们常用的 kubectl 命令及对应的缩写,示例如下:
kubectl get po
# 等价于 ‖ 可以 看到输出是一模一样的
kubectl get pods
2.3 格式化输出
输出格式 | 命令 |
---|---|
输出json格式 | -o json |
仅打印资源名称 | -o name |
以纯文本格式输出所有信息 | -o wide |
输出yaml格式 | -o yaml |