加载中...

Kubernetes系列(二)--使用kubeadm搭建Kubernetes集群


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完成即可。下面的操作基本与文档一致,根据自己实际情况略有改动~

  1. 安装 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
  2. 安装 runc

    wget https://github.com/opencontainers/runc/releases/download/v1.2.6/runc.amd64
    install -m 755 runc.amd64 /usr/local/sbin/runc
  3. 安装 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
  4. 配置 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网络附加组件

常见的安装是 CalicoFlannel,我们这里采用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 发请求。因此要想子节点可用我们可以进行如下配置:

  1. 将 master 节点中 /etc/kubernetes/admin.conf 拷贝到需要运行的服务器的 /etc/kubernetes 目录中

    scp /etc/kubernetes/admin.conf root@c1:/etc/kubernetes
  2. 在对应的服务器上配置环境变量

    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

文章作者: 无夜
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 无夜 !
评论
  目录