k8s集群部署(1)(centos7)

直接进入主题,采用kubeadm方式构建集群,一个master,2个node,1个镜像仓库,准备4台机器,我用的虚拟机装的centos7,2C2G。网络配置好,保证虚拟机能访问外网,虚拟机和宿主能互相访问。

VMware安装虚拟机及网络配置

一、机器前置处理

配置一下几台机器的相关信息

我机器ip是192.168.255.101/104,计划是101作为master,102,103 作为node,104作为私有镜像仓库

1. 主机名设置 方便互相访问:

vim /etc/hosts 添加以下内容:所有机器

复制代码
192.168.255.101 k8s-master.taoyao.com k8s-master
192.168.255.102 k8s-node1.taoyao.com k8s-node1
192.168.255.103 k8s-node2.taoyao.com k8s-node2
192.168.255.104 k8s-harbor.taoyao.com k8s-harbor

2. 配置互相ssh免密

在101上操作 ssh-keygen -t rsa 生成密钥对
执行脚本复制到其他机器:

复制代码
for i in 102 103 104 
do 
ssh-copy-id root@192.168.255.$i
done

3. 设置对应机器的主机名和上面hosts文件中内容对应

复制代码
hostnamectl set-hostname k8s-master
hostnamectl set-hostname k8s-node1
hostnamectl set-hostname k8s-node2
hostnamectl set-hostname k8s-harbor

4. 机器参数调整(所有机器)

这里推荐使用mobaxterm,相比xshell这些,他可以批量操作,同时在多台机器执行输入相同的命令

4.1 禁用交换分区

vim /etc/selinux/config

将 SELINUX=enforcing 改为 SELINUX=disabled

reboot 重启

临时禁用: swapoff -a

永久禁用:sed -i 's/.swap./#&/' /etc/fstab

4.2 k8s相关的内核参数调整:

复制代码
cat >> /etc/sysctl.d/k8s.conf << EOF
vm.swappiness=0
EOF

4.3 网络参数调整

依次执行
modprobe br_netfilter

modprobe overlay

复制代码
cat >> /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF

sysctl -p /etc/sysctl.d/k8s.conf

二、安装容器引擎----docker相关

1.docker安装(所有机器)

CentOS 7 已于 2024 年 6 月 30 日停止维护(EOL - End of Life),官方镜像站 mirrorlist.centos.org 已经下线,导致 yum 无法获取软件包列表,所以这里我们换成阿里的yum

复制代码
# 1. 备份原配置
sudo cp -r /etc/yum.repos.d /etc/yum.repos.d.backup

# 2. 下载阿里云镜像配置
sudo wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo

# 3. 清理缓存并测试
sudo yum clean all
sudo yum makecache

使用阿里云yum镜像:https://developer.aliyun.com/mirror/docker-ce

按上面地址的指引操作即可,默认下载的时最新的,或者选择指定的版本安装:

我选择安装的24.0.4-1.el7

复制代码
# step 1: 安装必要的一些系统工具
yum install -y yum-utils

# Step 2: 添加软件源信息
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

#查看docker 版本
yum list docker-ce --showduplicates | sort -r

# Step 3: 安装Docker  24.0.4-1.el7
yum install -y docker-ce-24.0.4-1.el7

#设置开启自启动
systemctl enable docker 

# 开启Docker服务
service docker start

2. docker相关配置修改

(1)cgroup改为systemd (参考:https://kubernetes.io/zh-cn/docs/setup/production-environment/container-runtimes/)

(2)镜像仓库修改(国内的更快)

(3)使用私有镜像仓库(104这台机器)

除了仓库节点其他都执行以下脚本(101,102,103)机器执行:

复制代码
cat >> /etc/docker/daemon.json <<-EOF 
{
  "registry-mirrors":[
        "https://docker.211678.top",
        "https://docker.1panel.live",
        "https://hub.rat.dev",
        "https://docker.m.daocloud.io",
        "https://do.nark.eu.org",
        "https://dockerpull.com",
        "https://dockerproxy.cn",
        "https://docker.awsl9527.cn"
  ],
  "insecure-registries":["k8s-harbor.taoyao.com"],#和上面主机名的仓库机器对应
  "exec-opts":["native.cgroupdriver=systemd"]

}
EOF

重新加载 systemd 配置

systemctl daemon-reload

重启 Docker

systemctl restart docker
docker info 查看配置是否修改成功

3. cri环境 搭建

CRI(Container Runtime Interface)是Kubernetes定义的与容器运行时交互的标准接口,而Docker是一种流行的容器管理工具。两者在容器生态中的关系如下:

CRI与Docker的协作机制

  1. CRI的作用 ‌:CRI允许Kubernetes通过标准化接口与不同的容器运行时(如containerd、CRI-O)交互,实现容器的生命周期管理12。
  2. Docker的适配 ‌:Docker本身不直接实现CRI,但可通过cri-dockerd(原Dockershim的替代方案)作为适配层,将Docker的API转换为CRI兼容的接口,从而支持Kubernetes调度。

技术演进与现状

  • 历史依赖 ‌:早期Kubernetes依赖Docker作为默认运行时,但Docker的封闭生态与Kubernetes的开源理念冲突,促使Kubernetes推出CRI标准以解耦依赖

下载cri-dockerd (除仓库机器,都需要)

mkdir /data/softs

cd /data/softs 我是下载到这个目录

wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.3.2/cri-dockerd-0.3.2.amd64.tgz
可能需要梯子,如果无法直接下载就单独下载了上传到上去,先传了一台然后复制到其他去,或者分别上传

之前就做了免密直接复制到另外两台去

复制代码
for i in 102 103; 
do scp cri-dockerd-0.3.2.amd64.tgz root@192.168.255.$i:/data/softs/; 
done

解压软件 tar xf cri-dockerd-0.3.2.amd64.tgz

mv cri-dockerd/cri-dockerd /usr/local/bin/

检查效果 cri-dockerd --version

将 cri-dockerd 通过配置文件制作成服务方面开机启动:

复制代码
cat > /etc/systemd/system/cri-dockerd.service<<-EOF
[Unit]
Description=CRI Interface for Docker Application Container Engine
Documentation=https://docs.mirantis.com
After=network-online.target firewalld.service docker.service
Wants=network-online.target
[Service]
Type=notify
ExecStart=/usr/local/bin/cri-dockerd --pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.9 --network-plugin=cni --cni-conf-dir=/etc/cni/net.d --cni-bin-dir=/opt/cni/bin --container-runtime-endpoint=unix:///var/run/cri-dockerd.sock --cri-dockerd-root-directory=/var/lib/dockershim --docker-endpoint=unix:///var/run/docker.sock --cri-dockerd-root-directory=/var/lib/docker
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always
StartLimitBurst=3
StartLimitInterval=60s
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
Delegate=yes
KillMode=process
[Install]
WantedBy=multi-user.target
EOF
复制代码
cat >/etc/systemd/system/cri-dockerd.socket <<-EOF
[Unit]
Description=CRI Docker Socket for the API
Partof=cri-docker.service
[socket]
Listenstream=/var/run/cri-dockerd.sock
SocketMode=0660
Socketuser=root
SocketGroup-docker
[Install]
wantedBy-sockets.target
EOF

设置服务并机自启动

systemctl daemon-reload

systemctl enable cri-dockerd.service

systemctl restart cri-dockerd.service

状态查看: systemctl status cri-dockerd

systemctl is-active cri-dockerd

4. harbor仓库配置(104 仓库机器操作)

下载harbor: https://github.com/goharbor/harbor/releases
虚拟机网络不行可以使用宿主机下载相应的版本后上传到虚拟机再操作,可能需要用梯子

tar xf harbor-offline-installer-v2.14.0.tgz
解压进入harbor目录 加载harbor中的本地镜像

docker load < harbor.v2.14.0.tar.gz

修改harbor中的配置文件模板:

基于模版复制一份正式出来修改:

cp harbor.yml.tmpl harbor.yml

vim harbor.yml

hostname修改前面设置harbor机器的域名

https的配置去掉

admin密码修改

执行 ./prepare 脚本 生成相应docker-compose.yml内容

执行 ./install 启动harbor脚本,会使用prepare之后生成的docker-compose.yml文件启动

docker compose ps 命令用于列出当前目录下由 docker-compose.yml 文件定义的所有容器的运行状态

将harbor配置成服务,并设置开机自启动:

复制代码
cat > /etc/systemd/system/harbor.service<<-EOF
[Unit]
Description=Harbor
After=docker.service systemd-networkd.service systemd-resolved.service
Requires=docker.service
Documentation=http://github.com/viware/harbor
[Service]
Type=simple
Restart=on-failure
RestartSec=5
ExecStart=/usr/bin/docker compose --file /data/softs/harbor/docker-compose.yml up
ExecStop=/usr/bin/docker compose --file /data/softs/harbor/docker-compose.yml down
[Install]
WantedBy=multi-user.target
EOF
复制代码
ExecStart=/usr/bin/docker compose --file /data/softs/harbor/docker-compose.yml up
ExecStop=/usr/bin/docker compose --file /data/softs/harbor/docker-compose.yml down
这两个要注意和自己的安装目录对应上

systemctl daemon-reload 重新加载

systemctl start harbor 重启

systemctl status harbor 状态查看

systemctl enable harbor 开机自启动

访问104机器的IP 使用admin登录harbor,然后创建一个个人账户,再登录个人账户,创建一个公共项目用于存放我们自己镜像

向harbor仓库提交镜像:

1.镜像打标签

必须携带harbor主机地址:

docker tag 镜像 新镜像标签名(主机名/项目/镜像名:版本)

2.登录harbor

docker login harbor仓库

3.提交镜像

docker push 具体镜像标签

切换到101(192.168.255.101)机器上面尝试操作 打一个镜像并推送到104(192.168.255.104)机器harbor仓库:

我们拉取一个nginx:docker pull nginx:1.29.1 (拉取速度会很慢)

将拉取的nginx镜像打成自己的镜像:

docker tag 镜像 新镜像标签名(主机名/项目/镜像名:版本)

docker tag nginx:1.29.1 k8s-harbor.taoyao.com/nijunyang/my-nginx:1.29.1

docker login k8s-harbor.taoyao.com 登录harbor仓库 输入前面创建的个人账号信息

推送镜像: docker push k8s-harbor.taoyao.com/nijunyang/my-nginx:1.29.1

推送成功之后仓库里面就已经可以看到这个镜像了

可以去102(192.168.255.102)机器拉取这个镜像:
docker pull k8s-harbor.taoyao.com/nijunyang/my-nginx:1.29.1
速度直接飞一般的感觉了

三、k8s集群搭建(101,102,103 机器操作)

使用kubeadm 方式搭建集群

步骤:软件源定制------>安装软件------>镜像获取------>主节点初始化------>工作节点加入集群
1.软件源定制:k8s 节点执行 master node 都需要

使用阿里云的: https://developer.aliyun.com/mirror/ 找到k8s 按里面的脚本操作:

复制代码
cat <<EOF | tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.28/rpm/
enabled=1
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.28/rpm/repodata/repomd.xml.key
exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni
EOF

yum makecache fast 刷新yum源

安装软件:

yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes 我用的生产的那种 禁用了更新的(exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni) 所以使用这条命令,注意上面有两个使用对应的即可

systemctl enable kubelet && systemctl start kubelet

kubeadm:集群管理使用

kubelet:采集节点数据汇报给master

kubectl:管理集群资源对象

kubeadm version 查看k8s 版本

kubeadm config images list 查看所需的镜像版本

registry.k8s.io/kube-apiserver:v1.28.15

registry.k8s.io/kube-controller-manager:v1.28.15

registry.k8s.io/kube-scheduler:v1.28.15

registry.k8s.io/kube-proxy:v1.28.15

registry.k8s.io/pause:3.9

registry.k8s.io/etcd:3.5.15-0

registry.k8s.io/coredns/coredns:v1.10.1

registry.k8s.io google的地址国内可能无法访问

可以使用阿里云的:路径如下:

registry.aliyuncs.com/google_containers/kube-apiserver:v1.28.15

registry.aliyuncs.com/google_containers/kube-controller-manager:v1.28.15

registry.aliyuncs.com/google_containers/kube-scheduler:v1.28.15

registry.aliyuncs.com/google_containers/kube-proxy:v1.28.15

registry.aliyuncs.com/google_containers/pause:3.9

registry.aliyuncs.com/google_containers/etcd:3.5.15-0

registry.aliyuncs.com/google_containers/coredns/coredns:v1.10.1

拉取以上镜像推送到自己的harbor仓库:

去harbor创建google_containers 项目

k8s-harbor.taoyao.com/google_containers/xxxx

登录harbor: docker login k8s-harbor.taoyao.com

执行以下脚本: 拉取镜像,打标签,推送到私有仓库,以免后面集群节点创建时因为网络问题无法获取到镜像

注意镜像版本得和kubeadm config images list 里面显示的一致

复制代码
images=('kube-apiserver:v1.28.15' 'kube-controller-manager:v1.28.15' 'kube-scheduler:v1.28.15' 'kube-proxy:v1.28.15' 'pause:3.9' 'etcd:3.5.15-0' 'coredns/coredns:v1.10.1')
for i in "${images[@]}"; 
do
    docker pull registry.aliyuncs.com/google_containers/$i
    docker tag registry.aliyuncs.com/google_containers/$i k8s-harbor.taoyao.com/google_containers/$i
    docker push k8s-harbor.taoyao.com/google_containers/$i
    docker rmi registry.aliyuncs.com/google_containers/$i
done

阿里云的仓库中没有 registry.aliyuncs.com/google_containers/coredns/coredns:v1.10.1 。。。。。尴尬

直接去docker的仓库拉了做成自己的:

复制代码
docker pull coredns/coredns:1.10.1
docker tag coredns/coredns:1.10.1 k8s-harbor.taoyao.com/google_containers/coredns:v1.10.1
docker push k8s-harbor.taoyao.com/google_containers/coredns:v1.10.1
docker rmi coredns/coredns:1.10.1

镜像准备完毕就可以进行master节点初始化了

101(192.168.255.101) master机器执行初始化
kubeadm init --help 查看命令参数
--kubernetes-version 指定版本

--apiserver-advertise-address master节点ip

--image-repository 镜像仓库 使用我自己harbor仓库上面准备的镜像

--pod-network-cidr pod 网段 可以自己设置

--service-cidr service 网段 可以自己设置 default "10.96.0.0/12"

--ignore-preflight-errors 忽略某些错误

--cri-socket cri-socket 我们用docker引擎,配置docker对应的

复制代码
kubeadm init --kubernetes-version=1.28.15 --apiserver-advertise-address=192.168.255.101 --image-repository=k8s-harbor.taoyao.com/google_containers --pod-network-cidr="10.244.0.0/16" --service-cidr="10.96.0.0/12" --ignore-preflight-errors=Swap --cri-socket=unix:///var/run/cri-dockerd.sock

执行上述init 脚本:

圈起来的内容 后面都要用到,尤其是最后带hash的,不要着急清理页面,最后先复制下来

我们先让node 加入集群,把最后一个复制下来

去102,103 node节点上面执行,加入集群, 加一下 --cri-socket参数:

复制代码
kubeadm join 192.168.255.101:6443 --token w1oman.yjkcx7ay5adz6vop \
--discovery-token-ca-cert-hash sha256:db24e4cf5576d752f34a011f522907a4a827c5272604125d303ac98f3efb0b54 --cri-socket=unix:///var/run/cri-dockerd.sock

再看master初始化之后有两段操作:

非root用户部署按一个操作,root用户部署按第二个 我是用root操作的:

就用的 export KUBECONFIG=/etc/kubernetes/admin.conf

现在可以使用: kubectl get nodes 查看node信息了,如果不行的话就把上面两个操作都执行了吧

配置 kubeadm kubectl 配置命令使用tab键自动补齐
vim ~/.bashrc
加入以下内容:
source <(kubeadm completion bash)

source <(kubectl completion bash)
刷新配置: source ~/.bashrc

集群网络配置:

现在节点所有节点的状态都是 NotReady的

还是上面那个master初始化结果页面中的网络操作

打开它给的链接:https://kubernetes.io/docs/concepts/cluster-administration/addons/ 里面多种网络解决方案,选择合适的操作。

问了下AI,那我就用的Flannel 操作起来比较简单,跟着网址里面的指引走。

考虑到网络问题,我还是直接把 https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml 到本地,然后把里面的镜像,通过宿主机下载好,做成自己的 私有镜像推到harbor仓库,再执行。如果网络没问题那就直接执行 这个就行了 kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml

grep image: kube-flannel.yml 可以看到这个文件里面有两个镜像,我们把这两个镜像下载下来,做成自己的之后推送到自己的harbor仓库,修改这个文件中的镜像为我们自己的私有镜像:

注意版本和自己kube-flannel.yml 里面的对应

复制代码
docker pull ghcr.io/flannel-io/flannel:v0.27.4
docker tag ghcr.io/flannel-io/flannel:v0.27.4 k8s-harbor.taoyao.com/nijunyang/flannel:v0.27.4
docker push k8s-harbor.taoyao.com/nijunyang/flannel:v0.27.4

docker pull ghcr.io/flannel-io/flannel-cni-plugin:v1.8.0-flannel1
docker tag ghcr.io/flannel-io/flannel-cni-plugin:v1.8.0-flannel1 k8s-harbor.taoyao.com/nijunyang/flannel-cni-plugin:v1.8.0-flannel1
docker push k8s-harbor.taoyao.com/nijunyang/flannel-cni-plugin:v1.8.0-flannel1

修改kube-flannel.yml文件里面的 镜像为自己harbor仓库的镜像:
vim kube-flannel.yml 有三处不要改漏了

kubectl apply -f kube-flannel.yml 运行把资源部署起来

所以节点的状态都是ready了
至此k8s集群基本搭建完毕。

kubectl docker cri-dockered 必须设置为开机自启动,否则重启机器会导致服务有问题。

kubectl docker cri-dockered 必须设置为开机自启动,否则重启机器会导致服务有问题。

kubectl docker cri-dockered 必须设置为开机自启动,否则重启机器会导致服务有问题。

kubeadm方式部署集群其实是将各个组件以pod的形式部署在k8s中:

kubectl get pods -A 查看所有pods

四、k8s组件介绍

控制平面组件(Control Plane)

控制平面负责管理整个集群,通常部署在 Master 节点。

kube-apiserver(API 服务器)

  • 功能:集群的"前端",所有组件都通过它通信
  • 作用:
    • 暴露 REST API(kubectl、UI、其他组件)
    • 认证、授权、准入控制
    • 集群状态的唯一入口
  • 特点:无状态,可水平扩展(通过负载均衡)

etcd(分布式键值存储)

  • 功能:存储集群所有状态数据(Pod、Service、ConfigMap 等)
  • 特点:
    • 强一致性(Raft 算法)
    • 高可用(3/5/7 节点集群)
    • 唯一真相来源
  • 重要:必须定期备份!

kube-scheduler(调度器)

  • 功能:决定 Pod 在哪个节点上运行
  • 调度策略:
    • 资源需求(CPU、内存)
    • 亲和性/反亲和性
    • 污点/容忍(Taints/Tolerations)
    • 节点选择器(NodeSelector)
  • 特点:可插拔调度器框架

kube-controller-manager(控制器管理器)

  • 功能:运行各种控制器,维护集群期望状态
  • 内置控制器:
    • Node Controller:节点故障检测
    • Replication Controller:Pod 副本管理
    • Deployment Controller:滚动更新
    • DaemonSet Controller:守护进程集
    • StatefulSet Controller:有状态应用
    • Service Controller:负载均衡、路由
  • 特点:可水平扩展,高可用

节点组件(Node Components)

节点组件运行在每个 Worker 节点上,管理 Pod。

kubelet

  • 功能:节点上的"代理",管理 Pod 和容器
  • 职责:
    • 从 apiserver 获取 Pod 配置
    • 启动/停止/监控容器
    • 向 apiserver 上报节点状态
    • 执行健康检查(Liveness/Readiness)
  • 特点:每个节点必须运行一个

kube-proxy(服务代理)

  • 功能:实现 Service 的网络代理和负载均衡
  • 工作模式:
    • iptables:通过 iptables 规则转发
    • ipvs:性能更好,基于 LVS
    • userspace:旧模式,已废弃
  • 作用:实现 Service 的 ClusterIP、NodePort 等

Container Runtime(容器运行时)

  • 功能:实际运行容器的软件
  • 支持的运行时:
    • Docker(通过 cri-docker-shim,已弃用)
    • containerd(推荐)
    • CRI-O(Red Hat 开发)
    • gVisor(安全沙箱)
  • 要求:必须符合 CRI(Container Runtime Interface)

可选组件(Addons)

DNS(CoreDNS)

  • 功能:为 Service 提供域名解析
  • 作用:my-service.namespace.svc.cluster.local

Web UI(Dashboard)

  • 功能:图形化管理界面

Container Resource Monitoring(Prometheus + Grafana)

  • 功能:监控容器和节点资源使用

Cluster-level Logging(EFK/Elasticsearch-Fluentd-Kibana)

  • 功能:集中日志收集和分析

组件交互流程(以创建 Pod 为例)