返回文章归档
K8s二进制部署

Kubernetes二进制部署

涉及服务及其知识点etcd,kube-Api-Server,kube-Schduler,kube-Controller-Manager,kubectl,kubelet,containerd,CNI,calico,kube-proxy,pod

一、回顾docker容器技术

1,docker架构回顾

image-20250913121922568

2,docker的优势

业务优势 说明
一键部署服务 解决的传统网站、服务部署繁琐的问题;解决CICD自动化的壁垒;
【容器化之后的CICD】:提交代码==>构建镜像==>一键部署测试环境==>一键部署生产环境
服务隔离 同主机下的不同服务,以模块化(容器、子系统)的方式分隔;可预测风险、排错简化;
微服务高效实现的基础 一个大型的单体业务服务,以模块化,细颗粒度实现,送耦合性,使用API组织架构,更轻松便捷;

3,docker的不足

不足之处 解释说明
很难实现跨主机容器负载均衡 docker无法实现:或者说很难实现跨主机的容器负载均衡管理;
没有容器调度能力 docker无法实现:自动的将容器部署在集群"适合"的主机上;
不能【弹性伸缩】 docker无法实现:在业务压力大时,自动新增web容器,业务压力小时,自动缩减web容器;
大集群大单体业务服务的编排 docker虽然有docker-compose作为单机容器编排工具,可以一键部署单机多容器业务;
但是,在规模较大的业务服务中:
:one:需要将容器一次启动在不同主机中
:two:需要一次在不同主机中、启动不同存储卷、网络、等等相关资源;​
:three:需要再不同主机中的启动的所有容器,按照优先级顺序依次启动;​
容器管理能力差 docker集中在:单机、单个容器的运行管理上
在面对企业大业务、高并发的场景下,成千上万个容器的运行场景中,docker自身闲的捉襟见肘;
自愈能力差 docker虽然有重启策略:
:one:重启策略的重心是容器故障了,自动重新启动这个容器本身;
:two:而非杀死容器,重新拉起镜像为容器,这会导致本身错误的容器继续错误
​docker无法处理:
:one:【节点故障的容器消失问题】
:two:【节点资源不足时:容器故障】

二、docker对比k8s

特性 docker kubernetes
作用范围 单机上的单个容器 集群的所有容器
故障问题 仅仅检测容器进程是否退出 检查:【进程是否退出】【节点是否故障】【资源是否不足】【应用是否有响应】
健康检查 容器进程在就算健康 探针检查:【HTTP、TCP、命令等方式】,判断健康的颗粒度更细;
恢复容器 本机重新起动宕机的容器 杀死容器,选择适合的节点中,重新拉起容器;
比喻 docker保证你活着 kubernetes保证你活着、给你治病、家被炸没了给你搬家;

三、kubernetes架构说明

组件名称 部署节点 作用说明
etcd数据库 master 【键值对存储数据库】:用于存储k8s运行所有数据信息
kube-controller-manager master 【k8s节点资源控制器】:
主要用于【监控节点存活】,【控制pod启动数量】、【service与pod动态绑定】
kube-scheduler master 【k8s节点调度与资源限制器】:主要控制pod部署在哪些节点上,限制资源使用;
kube-apiserver master 【k8s中央指挥系统(功能接口)】:所有k8s操作,都要通过apiserver调度执行;
kubectl node 【k8s的命令行工具】:
:one:人操作k8s的交互工具;命令行工具,
:two:pod的增删改查生命周期管理工具;
kubelet(CRI) 节点控制器(容器规范接口)
kube-proxy node 【集群内部实现pod负载均衡】【集群外部访问容器服务】
CNI-plugins node 【调用网络组件的接口】:只要符合CNI规范的网络组件,都可以使用;
常见的【calico和flannel】
calico或者flannel node 【实现pod在集群内部通信的组件】:calico或者flannel都可以
containerd或者podman node 【调用runc的工具】:高级容器运行时,传输镜像、管理容器、存储、网络配置,调用runc;
runc node 【真正创建、运行容器的工具】:低级容器运行时,创建容器、隔离容器进程;

image-20250913190630168

四、Kubernetes版本说明:star:

发型年份 停止维护时间 K8S Etcd Calico CoreDNS 容器
2019年12月 2021年06月 V1.17 V3.4 V3.14 V1.6 docker19.03
2020年12月 2022年06月 V1.20 V3.4 V3.18 V1.8 docker19.03
2021年12月 2023年06月 V1.23 V3.5 V3.22 V1.8 docker19.03
2022年05月 2023年10月 V1.24 V3.5 V3.23 V1.9 docker20.10
2022年12月 2024年06月 V1.26 V3.5 V3.25 V1.9 containerd1.6
2023年12月 2025年06月 V1.29 V3.5 V3.28 V1.11 containerd1.6
2024年12月 2026年06月 V1.31 V3.5 V3.28 V1.11 containerd1.7
2025年04月 2026年10月 V1.33 V3.5 V3.29 V1.11 containerd1.7
2025年08月 2026年08月 V1.34 V3.6 V3.30 V1.12 containerd2.1

五、基础环境准备

1,部署私有仓库

· 安装docker

1,官网下载

# https://docs.docker.com/
	- 点击导航栏
	- Manual

image-20260712114156098

# 左侧导航栏
	- Docker Engine
	- Install
	- Binaries
	- 点击下载链接

image-20260712114321687

# 选择服务器符合的CPU架构

image-20260712114418177

# 选择想要的版本,复制下载链接

image-20260712114503616

# wget下载安装包
[root@harbor ~ ]# wget https://download.docker.com/linux/static/stable/x86_64/docker-29.6.1.tgz
[root@harbor ~ ]# ls -l 
-rw-r--r-- 1 root root 87300816 Jul  1 13:06 docker-29.6.1.tgz

2,解压安装

[root@harbor ~ ]# tar xf docker-29.6.1.tgz 
[root@harbor ~ ]# chown root.root docker/*
[root@harbor ~ ]# cp docker/* /usr/bin/
[root@harbor ~ ]# echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
[root@harbor ~ ]# sysctl -p
net.ipv4.ip_forward = 1

3,配置systemd管理

# 编辑systemctl启动文件
[root@harbor:~]# vim /lib/systemd/system/docker.service
[Unit]
Description=bakwite docker 
Documentation=https://www.bakwite.com
#启动docker时,需要什么程序已经准备好???(没启动成功页没关系)
After=network-online.target containerd.service   
#如果这个程序没准备好,依旧可以启动docker
Wants=network-online.target

[Service]
Type=notify  #systemd配置,表示,docker进程启动好running/active之后再进行下一步操作;
#服务启动时执行的命令
ExecStart=/usr/bin/dockerd
# 重启进程,$MAINPID表示docker的pid变量(systemd生成的)
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0    #docker停止时等待时间,0表示伊吾县等待其优雅停止,避免强制杀死

LimitNOFILE=infinity    #不限制文件打开数
LimitNPROC=infinity     #不限制系统进程打开数


[Install]
WantedBy=multi-user.target

# 启动
[root@harbor ~ ]# systemctl daemon-reload 
[root@harbor ~ ]# systemctl enable --now docker.service

4,配置国内仓库

[root@harbor ~ ]# mkdir /etc/docker/
[root@harbor ~ ]# vim /etc/docker/daemon.json
{
  "registry-mirrors" : [
       "https://docker.m.daocloud.io",
       "https://k8s.m.daocloud.io"]
}
[root@harbor ~ ]# systemctl restart docker.service

5,拉取镜像测试

[root@harbor ~ ]# docker pull nginx:1.20.1-alpine
1.20.1-alpine: Pulling from library/nginx
ff9c6add3f30: Pull complete 
5758d4e389a3: Pull complete 
51d66f629021: Pull complete 
dcc43d9a97b4: Pull complete 
5dcfac0f2f9c: Pull complete 
2c6e86e57dfd: Pull complete 
Digest: sha256:b92d3b942c8b84da889ac3dc6e83bd20ffb8cd2d8298eba92c8b0bf88d52f03e
Status: Downloaded newer image for nginx:1.20.1-alpine
docker.io/library/nginx:1.20.1-alpine

· 安装DockerCompose

1,官网下载

https://github.com/docker/compose/

image-20260712115651629

# 选择符合cpu架构的版本,点击下载

image-20260712115837435

# 上传到主机
[root@harbor ~ ]# rz -E
[root@harbor ~ ]# ls -l
-rw-r--r-- 1 root root 32564869 Jul 12 11:59 docker-compose-linux-x86_64

2,快速安装

[root@harbor ~ ]# cp docker-compose-linux-x86_64 docker-compose
[root@harbor ~ ]# chmod +x docker-compose 
[root@harbor ~ ]# cp docker-compose /usr/local/bin/
[root@harbor ~ ]# docker-compose version
Docker Compose version v5.3.1

· 部署harbor仓库

1,官网下载

# https://github.com/goharbor/harbor/releases
	- 直接选择最新版

image-20260712120414914

# 选择offine离线版安装包
	- 点击下载

image-20260712120544267

2,上传解压安装包

# 上传
[root@harbor ~ ]# rz -E
[root@harbor ~ ]# ls -l
-rw-r--r-- 1 root root 730279437 Jul 12 12:34 harbor-offline-installer-v2.15.2.tgz

# 解压
[root@harbor ~ ]# tar xf harbor-offline-installer-v2.15.2.tgz -C /
[root@harbor ~ ]# ls -l /harbor/
total 718264
-rw-r--r-- 1 root root      3646 Jul  1 15:38 common.sh
-rw-r--r-- 1 root root 735455741 Jul  1 15:38 harbor.v2.15.2.tar.gz
-rw-r--r-- 1 root root     14657 Jul  1 15:38 harbor.yml.tmpl
-rwxr-xr-x 1 root root      1975 Jul  1 15:38 install.sh
-rw-r--r-- 1 root root     11347 Jul  1 15:38 LICENSE
-rwxr-xr-x 1 root root      2211 Jul  1 15:38 prepare

3,编辑配置文件

[root@harbor ~ ]# cp /harbor/harbor.yml.tmpl /harbor/harbor.yml
[root@harbor ~ ]# vim /harbor/harbor.yml
# 定义 Harbor 服务的外部访问地址。客户端(如 Docker、Helm)将使用这个地址来访问 Harbor。
# 必须设置为 IP 或域名,并且不能是 `localhost` 或 `127.0.0.1`。
hostname: reg.bakwite.com

# HTTP 协议配置
http:
  # Harbor 服务监听 HTTP 请求的端口。默认为 80。
  port: 80

# HTTPS 协议配置。如果配置了 HTTPS,HTTP 端口将自动重定向到 HTTPS 端口。
https:
  # Harbor 服务监听 HTTPS 请求的端口。默认为 443。
  port: 443
  # SSL 证书公钥
  certificate: /harbor/certs/harbor.crt
  # SSL 证书私钥。
  private_key: /harbor/certs/harbor.key

# Harbor 系统管理员admin的初始密码。
harbor_admin_password: 123456

# 数据库配置。Harbor 使用 PostgreSQL 数据库来存储元数据(项目、用户、镜像列表等,不是镜像文件本身)。
database:
  # 用于连接 PostgreSQL 数据库的密码。
  password: root123
  # 连接池中保持的最大空闲连接数。有助于提升性能,避免频繁建立新连接。
  max_idle_conns: 100
  # 数据库打开的最大连接数。根据服务器硬件和负载调整。
  max_open_conns: 900
  # 一个连接可被重用的最长时间。超过此时间后,连接将在被放回池中时关闭。
  conn_max_lifetime: 5m
  # 一个连接在空闲状态下的最长存活时间。0 表示没有限制。
  conn_max_idle_time: 0

# Harbor 用于存储数据的目录。
# 包括镜像文件、图表(Chart)文件以及数据库数据(如果使用内部数据库)。
data_volume: /harbor/data

# Trivy 配置。Trivy 是 Harbor 集成的漏洞扫描器。
trivy:
  # 是否忽略未提供修复方案的漏洞。`false` 表示不忽略,会报告所有漏洞。
  ignore_unfixed: false
  # 在启动时是否跳过更新 Trivy 的漏洞数据库。`false` 表示自动更新,建议生产环境保持更新。
  skip_update: false
  # (特定于Java) 是否跳过更新 Java 索引数据库。`false` 表示更新。
  skip_java_db_update: false
  # 是否启用离线扫描模式。如果为 `true`,则仅使用本地数据库,不尝试从网络获取更新。
  offline_scan: false
  # 扫描的安全检查类型。`vuln` 表示漏洞扫描。
  security_check: vuln
  # 是否允许 Trivy 使用不安全的连接(如自签名证书)下载漏洞数据库。
  insecure: false
  # 扫描超时时间。如果一次扫描超过此时间,将被终止。
  timeout: 5m0s

# Jobservice 配置。Jobservice 是 Harbor 中处理异步任务(如镜像复制、扫描等)的组件。
jobservice:
  # 最大并发工作线程数。决定了可以同时执行的任务数量。
  max_job_workers: 10
  # 一个任务的最长运行时间(小时)。超过此时间的任务将被标记为失败。
  max_job_duration_hours: 24
  # 任务日志的输出方式。
  # STD_OUTPUT: 输出到标准输出(通常会被 Docker 日志捕获)
  # FILE: 输出到文件(在 `data_volume` 指定的目录下)
  job_loggers:
    - STD_OUTPUT
    - FILE
  # 日志清理器运行的频率(天)。每隔 `1` 天,它会清理过期的任务日志文件。
  logger_sweeper_duration: 1 #days

# Webhook 通知配置。当发生推送镜像、删除镜像等事件时,Harbor 可以向外部系统发送通知。
notification:
  # 发送 webhook 通知失败后的最大重试次数。
  webhook_job_max_retry: 3
  # 发送 webhook 通知请求时的 HTTP 客户端超时时间(秒)。
  webhook_job_http_client_timeout: 3 #seconds

# 日志配置。
log:
  # 全局日志级别。可选值:debug, info, warning, error, fatal。
  level: info
  # 本地文件日志配置。
  local:
    # 保留的日志文件轮转数量。例如 50,表示最多保留 50 个旧的日志文件。
    rotate_count: 50
    # 每个日志文件的最大大小。超过此大小会触发轮转。200M 表示 200MB。
    rotate_size: 200M
    # Harbor 组件日志文件的存储目录位置。
    location: /harbor/log/harbor

# Harbor 的配置版本。此字段由 Harbor 自身维护,通常不需要手动修改。
_version: 2.13.0

# 代理服务器配置。如果 Harbor 所在服务器需要通过代理才能访问外部网络(如下载 Trivy 数据库),则需要在此配置。
proxy:
  # HTTP 代理服务器的地址。
  http_proxy:
  # HTTPS 代理服务器的地址。
  https_proxy:
  # 不需要通过代理访问的地址列表,用逗号分隔。
  no_proxy:
  # 哪些 Harbor 组件需要使用代理。这里配置了 core, jobservice, trivy。
  components:
    - core
    - jobservice
    - trivy

# 上传缓存清理策略。
# 当客户端上传文件(如镜像层)失败或中断时,会留下临时文件。此功能用于自动清理这些文件。
upload_purging:
  # 是否启用自动清理。`true` 为启用。
  enabled: true
  # 清理多久之前的临时文件。`168h` 表示 168 小时(7 天)前的文件将被清理。
  age: 168h
  # 清理作业的运行间隔。`24h` 表示每 24 小时运行一次清理任务。
  interval: 24h
  # 是否仅模拟运行(dry run)。`true` 时只会打印要清理的文件列表而不会实际删除,用于测试。`false` 会实际执行删除。
  dryrun: false

# 缓存配置(通常指项目的元数据缓存,用于加速 UI 显示)。
cache:
  # 是否启用缓存。`false` 表示不启用。
  enabled: false
  # 缓存数据的过期时间(小时)。`24` 表示 24 小时后缓存失效。
  expire_hours: 24

4,生成证书

创建证书目录(与配置文件中一致)

[root@harbor ~ ]# mkdir /harbor/certs
[root@harbor ~ ]# cd /harbor/certs

生成CA根机构证书

# 生成ca私钥
[root@harbor certs ]# openssl genrsa -out ca.key 2048

# 生成ca根公钥
[root@harbor certs ]# openssl req -new -x509 -days 3650 -key ca.key -out ca.crt \
  -subj "/C=CN/ST=Beijing/L=Beijing/O=MyCompany/OU=IT/CN=MyRootCA"

# 查看验证
[root@harbor certs ]# ls -l
total 8
-rw-r--r-- 1 root root 1334 Jul 12 12:41 ca.crt
-rw------- 1 root root 1704 Jul 12 12:41 ca.key

生成服务端证书

# 生成服务端私钥
[root@harbor certs ]# openssl genrsa -out harbor.key 2048

# 生成服务端证书请求文件
[root@harbor certs ]# openssl req -new -key harbor.key -out harbor.csr \
  -subj "/C=CN/ST=Beijing/L=Beijing/O=MyCompany/OU=IT/CN=reg.bakwite.com"
  
# 生成服务端公钥
[root@harbor certs ]# openssl x509 -req -in harbor.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
  -out harbor.crt -days 3650 -sha256 \
  -extensions san -extfile <(printf "[san]\nsubjectAltName=DNS:reg.bakwite.com,DNS:harbor,DNS:localhost,IP:127.0.0.1,IP:10.0.0.180")

# 查看验证
[root@harbor certs ]# ls -l
total 20
-rw-r--r-- 1 root root 1334 Jul 12 12:41 ca.crt
-rw------- 1 root root 1704 Jul 12 12:41 ca.key
-rw-r--r-- 1 root root 1407 Jul 12 12:43 harbor.crt
-rw-r--r-- 1 root root 1013 Jul 12 12:43 harbor.csr
-rw------- 1 root root 1704 Jul 12 12:43 harbor.key

5,开始安装harbor

[root@harbor certs ]# cd /harbor/
[root@harbor harbor ]# ./install.sh 

6,访问测试

10.0.0.180

image-20260712124750961

· 信任harbor仓库配置

1,docker信任harbor仓库

docker创建信任仓库目录

[root@harbor harbor ]# cd
[root@harbor ~ ]# mkdir -p /etc/docker/certs.d/reg.bakwite.com/

复制harbor证书到docker信任仓库目录下

[root@harbor ~ ]# cp /harbor/certs/ca.crt /etc/docker/certs.d/reg.bakwite.com/

编辑docker配置文件

[root@harbor ~ ]# vim /etc/docker/daemon.json 
{
  "registry-mirrors" : [
       "https://docker.m.daocloud.io",
       "https://k8s.m.daocloud.io",
       "https://reg.bakwite.com"]
}

2,系统信任harbor仓库证书

# 复制harbor证书到系统信任证书目录
[root@harbor ~ ]# cp /harbor/certs/ca.crt /usr/local/share/ca-certificates/harbor-ca.crt

# 更新系统信任的证书
[root@harbor ~ ]# update-ca-certificates

3,重启docker与harbor

# 重启dncker
[root@harbor ~ ]# systemctl restart docker

# 重启harbor
[root@harbor ~ ]# cd /harbor/
[root@harbor harbor ]# docker-compose down && docker-compose up -d

4,测试链接

# 配置本地解析
[root@harbor harbor ]# echo "10.0.0.180 reg.bakwite.com" >> /etc/hosts

# docker登录harbor
[root@harbor harbor ]# docker login reg.bakwite.com -uadmin -p123456

# 给镜像打标签
[root@harbor harbor ]# docker tag nginx:1.20.1-alpine reg.bakwite.com/library/nginx:1.20.1-alpine

# 推送
[root@harbor harbor ]# docker push reg.bakwite.com/library/nginx:1.20.1-alpine

# 查看仓库

image-20260712130639732

2,k8s环境准备

· 机器配置

主机名 ip 配置
k8s01 10.0.0.211 2核CPU、2GB内存
k8s02 10.0.0.212 2核CPU、2GB内存
k8s03 10.0.0.213 2核CPU、2GB内存

· ip地址规划

类型 网段/ip 说明
pod CIDR 10.244.0.0/12 pod中的容器的ip地址范围
Services CIDR 10.96.0.0/16 k8s中负载均衡器的ip地址范围
Cluster IP 10.96.0.1 k8s内部API入口的负载均衡器的ip地址
Cluster DNS IP 10.96.0.10 k8s内部的DNS服务器的IP地址

· 集群主机优化

1,关闭防火墙

systemctl stop ufw.service
systemctl disable ufw.service

2,关闭swap

# 临时关闭
swapoff -a

# 永久关闭
sed -i '/swap/ s/^\(.*\)$/#\1/g' /etc/fstab

3,加载必备内核功能

内核功能 解释说明
overlay linux的overlayFS堆叠文件系统功能
br_netfilter 网桥过滤功能,让iptables能够过滤到虚拟交换机(就是docker0网桥)的数据包
# 临时加载
modprobe overlay
modprobe br_netfilter

# 永久加载
cat >> /etc/modules-load.d/k8s.conf<<EOF
overlay
br_netfilter
EOF

4,设置内核功能参数

参数 解释说明
net.bridge.bridge-nf-call-iptables = 1 开启iptables过滤【网桥(虚拟交换机)】的功能ipv4
net.bridge.bridge-nf-call-ip6tables = 1 开启iptables过滤【网桥(虚拟交换机)】的功能ipv6
net.ipv4.ip_forward = 1 内核转发功能:开启,让主机充当路由器功能,网卡间可以转发数据包;

开机时:为内核功能设置参数

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

# 立即生效内核参数
sysctl --system
	- 或者
sysctl -p

5,安装必备工具

apt -y install conntrack socat

6,集群主机相互解析

cat >> /etc/hosts<<EOF
10.0.0.181 k8s01
10.0.0.182 k8s02
10.0.0.183 k8s03
EOF

六、部署master节点

1,下载k8s组件

· 官网地址

# 官网地址:https://kubernetes.io/
	- 进入文档页面:Documentation

image-20260118192249994

# 进入安装部署模块
	- Set up a k8s cluster

image-20260118192351537

# 根据提示选择:下载kubernetes
	- Download kubernetes

image-20260118192513101

# 选择下载:默认是最新的稳定版;选择历史班本看下图提示;
	- kube-apiserver
	- kube-controller-manager
	- kube-scheduler
	- kubelet
	- kube-proxy
	- kubectl

image-20260118192816887

· 上传到master节点

[root@k8s01 ~ ]# rz -E
[root@k8s01 ~ ]# ls -l ./kube*
-rw-r--r-- 1 root root 88387746 Jul 12 14:43 ./kube-apiserver
-rw-r--r-- 1 root root 74354850 Jul 12 14:45 ./kube-controller-manager
-rw-r--r-- 1 root root 59556002 Jul 12 14:55 ./kubectl
-rw-r--r-- 1 root root 60141833 Jul 12 14:58 ./kubelet
-rw-r--r-- 1 root root 44245154 Jul 12 14:45 ./kube-proxy
-rw-r--r-- 1 root root 49152162 Jul 12 14:49 ./kube-scheduler

2,部署etcd数据库

· 下载安装包

·
	- 选择最新的稳定版

image-20260712134603432

# 根据cpu架构选择

image-20260712134733542

· 上传解压安装包

# 上传
[root@k8s01 ~ ]# rz -E
[root@k8s01 ~ ]# ls -l
-rw-r--r-- 1 root root 23857260 Jul 12 13:51 etcd-v3.7.0-linux-amd64.tar.gz

# 解压安装包
[root@k8s01 ~ ]# tar xf etcd-v3.7.0-linux-amd64.tar.gz 
[root@k8s01 ~ ]# ls -l etcd-v3.7.0-linux-amd64
total 56720
drwxr-xr-x 6 bakwite bakwite     4096 Jul  9 02:20 Documentation
-rwxr-xr-x 1 bakwite bakwite 24776866 Jul  9 02:20 etcd
-rwxr-xr-x 1 bakwite bakwite 16756898 Jul  9 02:20 etcdctl
-rwxr-xr-x 1 bakwite bakwite 16453794 Jul  9 02:20 etcdutl
-rw-r--r-- 1 bakwite bakwite    44035 Jul  9 02:20 README-etcdctl.md
-rw-r--r-- 1 bakwite bakwite    10326 Jul  9 02:20 README-etcdutl.md
-rw-r--r-- 1 bakwite bakwite    10290 Jul  9 02:20 README.md
-rw-r--r-- 1 bakwite bakwite     7896 Jul  9 02:20 READMEv2-etcdctl.md

· 移动到path路径

# 修改权限
[root@k8s01 ~ ]# chown -R root.root etcd-v3.7.0-linux-amd64

# 移动到path路径
[root@k8s01 ~ ]# cp etcd-v3.7.0-linux-amd64/etcd* /usr/local/bin/

# 验证
[root@k8s01 ~ ]# etcd --version
etcd Version: 3.7.0
Git SHA: 4d71f7c
Go Version: go1.26.5
Go OS/Arch: linux/amd64

[root@k8s01 ~ ]# etcdctl version
etcdctl version: 3.7.0
API version: 3.7

[root@k8s01 ~ ]# etcdutl version
etcdutl version: 3.7.0
API version: 3.7

· 生成证书

1,创建证书管理目录

[root@k8s01 ~ ]# mkdir -p /etc/etcd/pki
[root@k8s01 ~ ]# cd /etc/etcd/pki

2,生成ca根证书

# 生成ca私钥
[root@k8s01 pki ]# openssl genrsa -out etcd-ca.key 2048

# 生成ca根公钥
[root@k8s01 pki ]# openssl req -new -x509 -key etcd-ca.key \
  -subj "/CN=etcd-ca" \
  -days 3650 -out etcd-ca.crt
  
# 查看验证
[root@k8s01 pki ]# ls -l
-rw-r--r-- 1 root root 1107 Jul 12 14:01 etcd-ca.crt
-rw------- 1 root root 1704 Jul 12 14:00 etcd-ca.key

3,生成服务端证书

# 生成服务端私钥
[root@k8s01 pki ]# openssl genrsa -out server.key 2048

# 生成服务端请求文件
[root@k8s01 pki ]# openssl req -new -key server.key \
  -subj "/CN=k8s01" \
  -addext "subjectAltName = DNS:localhost, DNS:k8s01, IP:10.0.0.181, IP:127.0.0.1" \
  -out server.csr
  
# 生成服务端公钥
[root@k8s01 pki ]# openssl x509 -req -in server.csr \
  -CA etcd-ca.crt -CAkey etcd-ca.key -CAcreateserial -days 3650 \
  -extfile <(printf "subjectAltName=DNS:localhost, DNS:k8s01, IP:10.0.0.181, IP:127.0.0.1") \
  -out server.crt

# 查看验证
[root@k8s01 pki ]# ls -l
-rw-r--r-- 1 root root 1107 Jul 12 14:01 etcd-ca.crt
-rw------- 1 root root 1704 Jul 12 14:00 etcd-ca.key
-rw-r--r-- 1 root root 1139 Jul 12 14:05 server.crt
-rw-r--r-- 1 root root  964 Jul 12 14:03 server.csr
-rw------- 1 root root 1704 Jul 12 14:03 server.key

4,生成集群通信证书

# 私钥
[root@k8s01 pki ]# openssl genrsa -out peer.key 2048

# 生成请求文件
[root@k8s01 pki ]# openssl req -new -key peer.key \
  -subj "/CN=k8s01" \
  -addext "subjectAltName = DNS:localhost, DNS:k8s01, IP:10.0.0.181, IP:127.0.0.1" \
  -out peer.csr
  
# 生成公钥
[root@k8s01 pki ]# openssl x509 -req -in peer.csr \
  -CA etcd-ca.crt -CAkey etcd-ca.key -CAcreateserial -days 3650 \
  -extfile <(printf "subjectAltName=DNS:localhost, DNS:k8s01, IP:10.0.0.181, IP:127.0.0.1") \
  -out peer.crt

5,生成客户端证书

# 私钥
[root@k8s01 pki ]# openssl genrsa -out apiserver-etcd-client.key 2048

# 请求文件
[root@k8s01 pki ]# openssl req -new -key apiserver-etcd-client.key \
  -subj "/CN=kube-apiserver" \
  -out apiserver-etcd-client.csr
  
# 生成公钥
[root@k8s01 pki ]# openssl x509 -req -in apiserver-etcd-client.csr \
  -CA etcd-ca.crt -CAkey etcd-ca.key -CAcreateserial -days 3650 \
  -out apiserver-etcd-client.crt

6,查看证书列表

[root@k8s01 pki ]# ls -l
total 44
-rw-r--r-- 1 root root  997 Jul 12 14:12 apiserver-etcd-client.crt
-rw-r--r-- 1 root root  899 Jul 12 14:11 apiserver-etcd-client.csr
-rw------- 1 root root 1704 Jul 12 14:11 apiserver-etcd-client.key
-rw-r--r-- 1 root root 1107 Jul 12 14:01 etcd-ca.crt
-rw------- 1 root root 1704 Jul 12 14:00 etcd-ca.key
-rw-r--r-- 1 root root 1139 Jul 12 14:09 peer.crt
-rw-r--r-- 1 root root  964 Jul 12 14:08 peer.csr
-rw------- 1 root root 1704 Jul 12 14:07 peer.key
-rw-r--r-- 1 root root 1139 Jul 12 14:05 server.crt
-rw-r--r-- 1 root root  964 Jul 12 14:03 server.csr
-rw------- 1 root root 1704 Jul 12 14:03 server.key

· 部署etcd

1,创建数据目录

[root@k8s01 pki ]# cd
[root@k8s01 ~ ]# mkdir -p /var/lib/etcd

2,编辑systemd启动文件

[root@k8s01 ~ ]# vim /usr/lib/systemd/system/etcd.service
[Unit]
Description=etcd key-value store
Documentation=https://github.com/etcd-io/etcd
After=network.target

[Service]
Type=notify
# 声明本机在etcd的集群中的名称;
Environment=ETCD_NAME=k8s01
# 声明etcd数据存储目录;
Environment=ETCD_DATA_DIR=/var/lib/etcd
# 声明集群之间内部通信的地址;
Environment=ETCD_LISTEN_PEER_URLS=https://10.0.0.181:2380
# 声明客户端访问etcd的地址;
Environment=ETCD_LISTEN_CLIENT_URLS=https://10.0.0.181:2379,https://127.0.0.1:2379
# 对集群广播自己的地址;
Environment=ETCD_INITIAL_ADVERTISE_PEER_URLS=https://10.0.0.181:2380
# 对客户端广播自己的地址;
Environment=ETCD_ADVERTISE_CLIENT_URLS=https://10.0.0.181:2379
ExecStart=/usr/local/bin/etcd \
  --trusted-ca-file=/etc/etcd/pki/etcd-ca.crt \
  --cert-file=/etc/etcd/pki/server.crt \
  --key-file=/etc/etcd/pki/server.key \
  --peer-trusted-ca-file=/etc/etcd/pki/etcd-ca.crt \
  --peer-cert-file=/etc/etcd/pki/peer.crt \
  --peer-key-file=/etc/etcd/pki/peer.key \
  # 启用客户端验证
  --client-cert-auth=true \
  # 表示正在创建一个新的集群;
  --initial-cluster-state=new \
  # 集群的列表
  --initial-cluster=k8s01=https://10.0.0.181:2380
# 异常退出后,才重启etcd
Restart=on-failure
# 重启前,等待5秒
RestartSec=5

[Install]
WantedBy=multi-user.target

3,启动

#记得上面的配置文件的中文注释去掉,并且中间不能有空行(因为都是换行符)

[root@k8s01 ~ ]# systemctl daemon-reload 
[root@k8s01 ~ ]# systemctl enable --now etcd.service

# 查看验证
[root@k8s01 ~ ]# netstat -tnulp | grep etcd
tcp        0      0 10.0.0.181:2380         0.0.0.0:*               LISTEN      151768/etcd         
tcp        0      0 10.0.0.181:2379         0.0.0.0:*               LISTEN      151768/etcd         
tcp        0      0 127.0.0.1:2379          0.0.0.0:*               LISTEN      151768/etcd

4,查看etcd集群健康状态

[root@k8s01 ~ ]# etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/etcd/pki/etcd-ca.crt \
  --cert=/etc/etcd/pki/apiserver-etcd-client.crt \
  --key=/etc/etcd/pki/apiserver-etcd-client.key \
  endpoint health
  

https://127.0.0.1:2379 is healthy: successfully committed proposal: took = 8.061869ms

· etcd数据库基操(了解)

etcd数据库是“非关系型数据库”:

  • 存储数据的方式是:对象存储;
  • 也就是key value的方式;

1,写入数据

命令 参数 举例 解释说明
etcdctl put etcdctl put bakwite 999 写入数据【bakwite=999】
#1,写入键值对
[root@master01 ~]# etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/etcd/pki/etcd-ca.crt \
  --cert=/etc/etcd/pki/apiserver-etcd-client.crt \
  --key=/etc/etcd/pki/apiserver-etcd-client.key \
  put bakwite  999
OK
[root@master01 ~]# etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/etcd/pki/etcd-ca.crt \
  --cert=/etc/etcd/pki/apiserver-etcd-client.crt \
  --key=/etc/etcd/pki/apiserver-etcd-client.key \
  put school beijingdaxue
OK
[root@master01 ~]# etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/etcd/pki/etcd-ca.crt \
  --cert=/etc/etcd/pki/apiserver-etcd-client.crt \
  --key=/etc/etcd/pki/apiserver-etcd-client.key \
  put class  jisuanji
OK
[root@master01 ~]# etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/etcd/pki/etcd-ca.crt \
  --cert=/etc/etcd/pki/apiserver-etcd-client.crt \
  --key=/etc/etcd/pki/apiserver-etcd-client.key \
  put /etc/  系统配置文件目录
OK

2,查看数据

命令 参数 举例 解释说明
etcdctl get etcdctl get bakwite 查看数据bakwite
--prefix etcdctl get / --prefix 获取以[/]开头的key的数据
--keys-only 只获取key不要value
--print-value-only 只获取value不要key
etcdctl get "" --prefix --print-value-only 获取所有key的value值
#1,通过key查询key和value的值;
[root@master01 ~]# etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/etcd/pki/etcd-ca.crt \
  --cert=/etc/etcd/pki/apiserver-etcd-client.crt \
  --key=/etc/etcd/pki/apiserver-etcd-client.key \
  get bakwite
bakwite
999
[root@master01 ~]# etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/etcd/pki/etcd-ca.crt \
  --cert=/etc/etcd/pki/apiserver-etcd-client.crt \
  --key=/etc/etcd/pki/apiserver-etcd-client.key \
  get school
school
beijingdaxue
[root@master01 ~]# etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/etcd/pki/etcd-ca.crt \
  --cert=/etc/etcd/pki/apiserver-etcd-client.crt \
  --key=/etc/etcd/pki/apiserver-etcd-client.key \
  get class
class
jisuanji
[root@master01 ~]# etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/etcd/pki/etcd-ca.crt \
  --cert=/etc/etcd/pki/apiserver-etcd-client.crt \
  --key=/etc/etcd/pki/apiserver-etcd-client.key \
  get /etc/
/etc/
系统配置文件目录

#2,通过key值,获取key,不要value;
[root@master01 ~]# etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/etcd/pki/etcd-ca.crt \
  --cert=/etc/etcd/pki/apiserver-etcd-client.crt \
  --key=/etc/etcd/pki/apiserver-etcd-client.key \
  get school --keys-only
school

#3,通过key值,获取value,不要key;
[root@master01 ~]# etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/etcd/pki/etcd-ca.crt \
  --cert=/etc/etcd/pki/apiserver-etcd-client.crt \
  --key=/etc/etcd/pki/apiserver-etcd-client.key \
  get school --print-value-only
beijingdaxue

#4,模糊查询,只查看以“/”开头为前缀的key
[root@master01 ~]# etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/etcd/pki/etcd-ca.crt \
  --cert=/etc/etcd/pki/apiserver-etcd-client.crt \
  --key=/etc/etcd/pki/apiserver-etcd-client.key \
  get / --prefix --print-value-only
系统配置文件目录

#5,获取所有数据的value值;
[root@master01 ~]# etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/etcd/pki/etcd-ca.crt \
  --cert=/etc/etcd/pki/apiserver-etcd-client.crt \
  --key=/etc/etcd/pki/apiserver-etcd-client.key \
  get "" --prefix --print-value-only
系统配置文件目录
jisuanji
beijingdaxue
999

3,修改数据

修改也是添加写入;

#1,通过key值,获取value,不要key;
[root@master01 ~]# etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/etcd/pki/etcd-ca.crt \
  --cert=/etc/etcd/pki/apiserver-etcd-client.crt \
  --key=/etc/etcd/pki/apiserver-etcd-client.key \
  get school --print-value-only
beijingdaxue

#2,修改school的值为:qinghua
[root@master01 ~]# etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/etcd/pki/etcd-ca.crt \
  --cert=/etc/etcd/pki/apiserver-etcd-client.crt \
  --key=/etc/etcd/pki/apiserver-etcd-client.key \
  put school qinghua
OK

#3,再次查看;
[root@master01 ~]# etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/etcd/pki/etcd-ca.crt \
  --cert=/etc/etcd/pki/apiserver-etcd-client.crt \
  --key=/etc/etcd/pki/apiserver-etcd-client.key \
  get school
school
qinghua

4,删除数据

命令 参数 案例 解释说明
etcdctl del etcdctl del school 删除school这个key的值
#1,删除key是school的数据
[root@master01 ~]# etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/etcd/pki/etcd-ca.crt \
  --cert=/etc/etcd/pki/apiserver-etcd-client.crt \
  --key=/etc/etcd/pki/apiserver-etcd-client.key \
  del school
1

[root@master01 ~]# etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/etcd/pki/etcd-ca.crt \
  --cert=/etc/etcd/pki/apiserver-etcd-client.crt \
  --key=/etc/etcd/pki/apiserver-etcd-client.key \
  get "" --prefix --print-value-only
系统配置文件目录
jisuanji
999

#2,删除所有数据
[root@master01 ~]# etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/etcd/pki/etcd-ca.crt \
  --cert=/etc/etcd/pki/apiserver-etcd-client.crt \
  --key=/etc/etcd/pki/apiserver-etcd-client.key \
  del "" --prefix
3

[root@master01 ~]# etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/etcd/pki/etcd-ca.crt \
  --cert=/etc/etcd/pki/apiserver-etcd-client.crt \
  --key=/etc/etcd/pki/apiserver-etcd-client.key \
  get "" --prefix --print-value-only

5,Etcd数据备份

· 准备测试数据
[root@master01 ~]# etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/etcd/pki/etcd-ca.crt \
  --cert=/etc/etcd/pki/apiserver-etcd-client.crt \
  --key=/etc/etcd/pki/apiserver-etcd-client.key \
  put school 清华大学
OK
[root@master01 ~]# etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/etcd/pki/etcd-ca.crt \
  --cert=/etc/etcd/pki/apiserver-etcd-client.crt \
  --key=/etc/etcd/pki/apiserver-etcd-client.key \
  put class 机电维修02
OK
[root@master01 ~]# etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/etcd/pki/etcd-ca.crt \
  --cert=/etc/etcd/pki/apiserver-etcd-client.crt \
  --key=/etc/etcd/pki/apiserver-etcd-client.key \
  put /etc/nginx/nginx.d/ 配置文件路径
OK
[root@master01 ~]# etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/etcd/pki/etcd-ca.crt \
  --cert=/etc/etcd/pki/apiserver-etcd-client.crt \
  --key=/etc/etcd/pki/apiserver-etcd-client.key \
  put /etc/nginx/nginx.conf 主配置文件
OK
[root@master01 ~]# etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/etcd/pki/etcd-ca.crt \
  --cert=/etc/etcd/pki/apiserver-etcd-client.crt \
  --key=/etc/etcd/pki/apiserver-etcd-client.key \
  get "" --prefix 
/etc/nginx/nginx.conf
主配置文件
/etc/nginx/nginx.d/
配置文件路径
class
机电维修02
school
清华大学
· 创建快照【备份】

备份快照(如果是集群,也是这样备份,他辈分的就是集群所有数据)

#1,创建快照
[root@master01 ~]# etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/etcd/pki/etcd-ca.crt \
  --cert=/etc/etcd/pki/apiserver-etcd-client.crt \
  --key=/etc/etcd/pki/apiserver-etcd-client.key \
  snapshot save /tmp/snapshot001.db 

#2,查看快照文件
[root@master01 ~]# ll /tmp/
-rw------- 1 root root 24608  7月 18 08:40 snapshot.db

#3,【etcdutl】查看快照的状态(查看快照状态你不需要集群验证)
[root@k8s-master01:~]# etcdutl snapshot status /tmp/snapshot001.db -w table
+----------+----------+------------+------------+---------+
|   HASH   | REVISION | TOTAL KEYS | TOTAL SIZE | VERSION |
+----------+----------+------------+------------+---------+
| 1e84198c |  3558912 |        376 |      14 MB |   3.6.0 |
+----------+----------+------------+------------+---------+

6,Etcd数据恢复

· 模拟数据丢失
#删除所有数据
[root@k8s-master01:~]# etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/etcd/pki/etcd-ca.crt \
  --cert=/etc/etcd/pki/apiserver-etcd-client.crt \
  --key=/etc/etcd/pki/apiserver-etcd-client.key \
  del "" --prefix
4
[root@k8s-master01:~]# etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/etcd/pki/etcd-ca.crt \
  --cert=/etc/etcd/pki/apiserver-etcd-client.crt \
  --key=/etc/etcd/pki/apiserver-etcd-client.key \
  get "" --prefix
· 停止etcd/集群
[root@k8s-master01:~]# systemctl stop etcd.service
· 恢复备份快照
# 清空数据目录(最好打包备份)
[root@k8s-master01:~]# rm -rf /var/lib/etcd/*

# 恢复数据到数据目录;
[root@k8s-master01:~]# etcdutl snapshot restore /tmp/snapshot001.db --data-dir=/var/lib/etcd
· 启动etcd集群
[root@k8s-master01:~]# systemctl start etcd
· 验证备份恢复数据
[root@k8s-master01:~]# etcdctl get "" --prefix
/etc/nginx/nginx.conf
主配置文件
/etc/nginx/nginx.d/
配置文件路径
school
清华大学

7,etcd的监控指标

#1,查看etcd暴露的监控指标数量
[root@etcd01 ~]# curl -s -k \
	--cacert /etc/etcd/pki/etcd-ca.crt \
	--cert /etc/etcd/pki/server.crt \
	--key /etc/etcd/pki/server.key \
	https://127.0.0.1:2379/metrics | wc -l
1697

#2,查看指标
[root@k8s-master01:~]# curl -s -k \
        --cacert /etc/etcd/pki/etcd-ca.crt \
        --cert /etc/etcd/pki/server.crt \
        --key /etc/etcd/pki/server.key \
        https://127.0.0.1:2379/metrics | head -10
# HELP etcd_cluster_version Which version is running. 1 for 'cluster_version' label with current cluster version
# TYPE etcd_cluster_version gauge
etcd_cluster_version{cluster_version="3.6"} 1
# HELP etcd_debugging_auth_revision The current revision of auth store.
# TYPE etcd_debugging_auth_revision gauge
etcd_debugging_auth_revision 1
# HELP etcd_debugging_disk_backend_commit_rebalance_duration_seconds The latency distributions of commit.rebalance called by bboltdb backend.
# TYPE etcd_debugging_disk_backend_commit_rebalance_duration_seconds histogram
etcd_debugging_disk_backend_commit_rebalance_duration_seconds_bucket{le="0.001"} 3.297951e+06
etcd_debugging_disk_backend_commit_rebalance_duration_seconds_bucket{le="0.002"} 3.297968e+06

3,部署master组件

· 设置k8s组件执行权限

[root@k8s01 ~ ]# chmod +x kube*

· 移动master组件到path路径

[root@k8s01 ~ ]# cp kube-apiserver /usr/local/bin/
[root@k8s01 ~ ]# cp kube-scheduler /usr/local/bin/
[root@k8s01 ~ ]# cp kube-controller-manager /usr/local/bin/
[root@k8s01 ~ ]# cp kubectl /usr/local/bin/

· 生成master组件CA证书

1,创建证书目录

[root@k8s01 ~ ]# mkdir -p /etc/kubernetes/pki
[root@k8s01 ~ ]# cd /etc/kubernetes/pki

2,生成集群CA根证书

# 生成ca根证书私钥
[root@k8s01 pki ]# openssl genrsa -out k8s-ca.key 2048

# 生成公钥
[root@k8s01 pki ]# openssl req -new -x509 -key k8s-ca.key -subj "/CN=kubernetes-ca" -days 3650 -out k8s-ca.crt

# 查看验证
[root@k8s01 pki ]# ls -l
total 8
-rw-r--r-- 1 root root 1123 Jul 12 15:08 k8s-ca.crt
-rw------- 1 root root 1704 Jul 12 15:07 k8s-ca.key

3,生成API-Server服务端证书

服务端证书,其他组件访问apiserver时的证书;

注意重点 解释说明
DNS必须设置4项 kubernetes
kubernetes.default
kubernetes.default.svc
kubernetes.default.svc.cluster.local
IP必须设置2项 本机(宿主机)真实ip:10.0.0.211
cluster IP(apiserver在集群中的虚拟IP):10.96.0.1
CN字段 可以随便写,但是规范来讲:kube-apiserver
# 生成服务端私钥
[root@k8s01 pki ]# openssl genrsa -out apiserver.key 2048

# 生成请求文件
[root@k8s01 pki ]# openssl req -new \
    -key apiserver.key \
    -subj "/CN=kube-apiserver" \
    -addext "subjectAltName = DNS:kubernetes, DNS:kubernetes.default, DNS:kubernetes.default.svc, DNS:kubernetes.default.svc.cluster.local, IP:10.0.0.181, IP:10.96.0.1, IP:127.0.0.1" \
    -out apiserver.csr

# 生成公钥
[root@k8s01 pki ]# openssl x509 -req \
        -in apiserver.csr \
        -CA k8s-ca.crt -CAkey k8s-ca.key \
        -CAcreateserial \
        -days 3650 \
        -extfile <(printf "subjectAltName=DNS:kubernetes, DNS:kubernetes.default, DNS:kubernetes.default.svc, DNS:kubernetes.default.svc.cluster.local, IP:10.0.0.181, IP:10.96.0.1, IP:127.0.0.1") \
        -out apiserver.crt

4,生成Controller-Manager客户端证书

生成注意事项 内容 说明
CN字段 CN=system:kube-controller-manager k8s内置的名称
O字段 system:kube-controller-manager k8s内置的用户组,权限固定;
# 生成客户端私钥
[root@k8s01 pki ]# openssl genrsa -out controller-manager.key 2048

# 生成请求文件
[root@k8s01 pki ]# openssl req -new \
        -key controller-manager.key \
        -subj "/CN=system:kube-controller-manager/O=system:kube-controller-manager" \
        -out controller-manager.csr

# 生成客户端公钥
[root@k8s01 pki ]# openssl x509 -req \
        -in controller-manager.csr \
        -CA k8s-ca.crt -CAkey k8s-ca.key \
        -CAcreateserial -days 3650 \
        -out controller-manager.crt

5,生成Scheduler客户端证书

生成注意事项 内容 说明
CN字段 CN=system:kube-scheduler k8s内置的名称
O字段 O=system:kube-scheduler k8s内置的用户组,权限固定;
# 生成证书私钥
[root@k8s01 pki ]# openssl genrsa -out scheduler.key 2048

# 生成请求文件
[root@k8s01 pki ]# openssl req -new \
        -key scheduler.key \
        -subj "/CN=system:kube-scheduler/O=system:kube-scheduler" \
        -out scheduler.csr
        
# 生成公钥
[root@k8s01 pki ]# openssl x509 -req \
        -in scheduler.csr \
        -CA k8s-ca.crt -CAkey k8s-ca.key \
        -CAcreateserial -days 3650 \
        -out scheduler.crt

6,生成SA服务账号密钥对

秘钥 持有组件 作用
sa.key私钥 kube-controll-manager 给用户token令牌身份签名,使其合法;
sa.pub公钥 kube-apiserver 验证用户的token令牌是否合法;

集群中不同节点中的容器pod相互访问时:

  • 为了保证绝对安全性,k8s采用单独的认证方式;
  • 为每个容器pod提供一个sa用户,每当pod跨主机访问时,apisever通过sa秘钥认证pod是否属于集群;
# SA签发token的私钥
[root@k8s01 pki ]# openssl genrsa -out sa.key 2048

# SA的token认证的公钥
[root@k8s01 pki ]# openssl rsa -in sa.key -pubout -out sa.pub

7,k8s自研功能的安全认证证书

当k8s的功能不能满足企业生产需求时,可以基于k8s基础架构进行二次开发:

  • 那么想要k8s接纳新的功能,k8s提供了认证规范;
  • 就是让k8s提前加载信任一套证书,新功能可以利用这个提前加载的证书,进行开发;
# 扩展功能ca根机构证书
[root@k8s01 pki ]# openssl genrsa -out front-proxy-ca.key 2048
[root@k8s01 pki ]# openssl req -x509 -new -nodes \
  -key front-proxy-ca.key \
  -subj "/CN=front-proxy-ca" \
  -days 36500 \
  -out front-proxy-ca.crt

# 扩展功能客户端证书
# 私钥
[root@k8s01 pki ]# openssl genrsa -out front-proxy-client.key 2048

# 请求文件
[root@k8s01 pki ]# openssl req -new \
  -key front-proxy-client.key \
  -subj "/CN=front-proxy-client" \
  -out front-proxy-client.csr
  
# 公钥
[root@k8s01 pki ]# openssl x509 -req \
  -in front-proxy-client.csr \
  -CA front-proxy-ca.crt \
  -CAkey front-proxy-ca.key \
  -CAcreateserial \
  -out front-proxy-client.crt \
  -days 36500

8,API-Server访问集群节点的客户端证书

生成注意事项 内容 说明
CN字段 CN=apiserver-kubelet-client
O字段 O=system:masters 集群最高权限master组
# 私钥
[root@k8s01 pki ]# openssl genrsa -out apiserver-kubelet-client.key 2048

# 请求文件
[root@k8s01 pki ]# openssl req -new \
      -key apiserver-kubelet-client.key \
      -subj "/CN=apiserver-kubelet-client/O=system:masters" \
      -out apiserver-kubelet-client.csr

# 公钥
[root@k8s01 pki ]# openssl x509 -req \
          -in apiserver-kubelet-client.csr \
          -CA k8s-ca.crt -CAkey k8s-ca.key \
          -CAcreateserial \
          -days 3650 \
          -out apiserver-kubelet-client.crt

9,生成kubectl客户端用户证书

# 生成私钥
[root@k8s01 pki ]# openssl genrsa -out admin.key 2048

# 请求文件
[root@k8s01 pki ]# openssl req -new \
        -key admin.key \
        -out admin.csr \
        -subj "/CN=admin/O=system:masters"

# 公钥
[root@k8s01 pki ]# openssl x509 -req -in admin.csr \
  -CA k8s-ca.crt -CAkey k8s-ca.key \
  -CAcreateserial \
  -out admin.crt \
  -days 3650

· 生成master组件身份认证文件

1,ControllerManager身份文件

# 写入集群地址信息
[root@k8s01 pki ]# kubectl config set-cluster kubernetes \
        --certificate-authority=k8s-ca.crt \
        --embed-certs=true \
        --server=https://10.0.0.181:6443 \
        --kubeconfig=../controller-manager.kubeconfig
        
# 写入组件身份信息,用户名一定要是ca证书中的CN字段,否则认证失败;
[root@k8s01 pki ]# kubectl config set-credentials system:kube-controller-manager \
        --client-certificate=controller-manager.crt \
        --client-key=controller-manager.key \
        --embed-certs=true \
        --kubeconfig=../controller-manager.kubeconfig

# 生成[集群地址]与[用户身份]上下文(绑定),上下文的名字叫default
[root@k8s01 pki ]# kubectl config set-context default \
        --cluster=kubernetes \
        --user=system:kube-controller-manager \
        --kubeconfig=../controller-manager.kubeconfig
        
# 生效上下文default身份文件
[root@k8s01 pki ]# kubectl config use-context default \
        --kubeconfig=../controller-manager.kubeconfig

2,Scheduler身份文件

[root@k8s01 pki ]# kubectl config set-cluster kubernetes \
        --certificate-authority=k8s-ca.crt \
        --embed-certs=true \
        --server=https://10.0.0.181:6443 \
        --kubeconfig=../scheduler.kubeconfig
        
[root@k8s01 pki ]# kubectl config set-credentials system:kube-scheduler \
        --client-certificate=scheduler.crt \
        --client-key=scheduler.key \
        --embed-certs=true \
        --kubeconfig=../scheduler.kubeconfig

[root@k8s01 pki ]# kubectl config set-context default \
        --cluster=kubernetes \
        --user=system:kube-scheduler \
        --kubeconfig=../scheduler.kubeconfig

[root@k8s01 pki ]# kubectl config use-context default \
        --kubeconfig=../scheduler.kubeconfig

3,kubectl客户端身份文件

[root@k8s01 pki ]# kubectl config set-cluster kubernetes \
        --certificate-authority=k8s-ca.crt \
        --embed-certs=true \
        --server=https://10.0.0.181:6443 \
        --kubeconfig=../admin.kubeconfig
        
[root@k8s01 pki ]# kubectl config set-credentials admin \
        --client-certificate=admin.crt \
        --client-key=admin.key \
        --embed-certs=true \
        --kubeconfig=../admin.kubeconfig

[root@k8s01 pki ]# kubectl config set-context default \
        --cluster=kubernetes \
        --user=admin \
        --kubeconfig=../admin.kubeconfig

[root@k8s01 pki ]# kubectl config use-context default \
        --kubeconfig=../admin.kubeconfig

· 启动master组件

1,apiserver启动

编辑配置文件

[root@k8s01 pki ]# vim /usr/lib/systemd/system/kube-apiserver.service
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
After=network.target etcd.service
Wants=etcd.service

[Service]
ExecStart=/usr/local/bin/kube-apiserver \
  # 监听控制:只能从哪个网络进来;
  --bind-address=0.0.0.0 \
  # 向整个集群通告apiserver的ip地址;
  --advertise-address=10.0.0.181 \
  # apiserver监听的端口
  --secure-port=6443 \
  # 允许运行 特权容器(privileged=true 的 Pod)
  --allow-privileged=true \
  # apiserver的认证模式:
  # 【Node】:kubelet与apiserver的交互控制;
  # 【RBAC】:基于角色的访问控制;
  --authorization-mode=Node,RBAC \
  # 集群客户端的CA根证书:用于kubelet、kubectl、controller-manager的客户端证书验证;
  --client-ca-file=/etc/kubernetes/pki/k8s-ca.crt \
  # 限制kubelet只能修改自己节点的对象;
  --enable-admission-plugins=NodeRestriction \
  # 启用bootstrap token来让kubelet节点加入集群;
  --enable-bootstrap-token-auth=true \
  # etcd的地址和范文客户端证书配置;
  --etcd-servers=https://127.0.0.1:2379 \
  --etcd-cafile=/etc/etcd/pki/etcd-ca.crt \
  --etcd-certfile=/etc/etcd/pki/apiserver-etcd-client.crt \
  --etcd-keyfile=/etc/etcd/pki/apiserver-etcd-client.key \
  
  # 【apiserver访问kubelet】时,使用的客户端证书和私钥;
  --kubelet-client-certificate=/etc/kubernetes/pki/apiserver-kubelet-client.crt \
  --kubelet-client-key=/etc/kubernetes/pki/apiserver-kubelet-client.key \
  # sa.pub是用来验证token的公钥
  # sa.key是用来签发token的私钥
  --service-account-key-file=/etc/kubernetes/pki/sa.pub \
  --service-account-signing-key-file=/etc/kubernetes/pki/sa.key \
  # front-proxy的认证配置;
  # 它不是一个独立进程,而是 apiserver 用来信任“请求头身份”的一套安全机制;
  # 就是附加组件:metrics-server / HPA / 自定义 API / webhook / aggregated apiserver的外部认证
  # 就是扩展API的安全访问机制,而不是原来的APIserver;
  --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt \
  --requestheader-allowed-names=front-proxy-client \
  --requestheader-extra-headers-prefix=X-Remote-Extra- \
  --requestheader-group-headers=X-Remote-Group \
  --requestheader-username-headers=X-Remote-User \
  --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.crt \
  --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client.key \
  
  # 签发token的签发者标识;用于 OIDC/JWT 验证。
  # 签发token时,这个字段会写入token中;
  # 【JWT】就是访问者的身份证;“json web token”;
  # 【OIDC】身份认证协议
  --service-account-issuer=https://kubernetes.default.svc.cluster.local \
  # 这里,一定要使用自己自规划好的service CIDR网段(默认就是10.96,不好改,别改了);
  --service-cluster-ip-range=10.96.0.0/12 \
  # 表示service资源对外暴露的宿主机端口范围,默认值是30000-32767;
  --service-node-port-range=20000-40000 \
  # apiserver HTTPS 服务使用的证书和私钥(供外部客户端访问)。
  --tls-cert-file=/etc/kubernetes/pki/apiserver.crt \
  --tls-private-key-file=/etc/kubernetes/pki/apiserver.key \
  # 日志级别(数字越大日志越详细,常见 2 是 info 级别)。
  --v=2
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

启动apiserver

#记得上面的配置文件的中文注释去掉,并且中间不能有空行(因为都是换行符)

[root@k8s01 pki ]# systemctl daemon-reload 
[root@k8s01 pki ]# systemctl enable --now kube-apiserver.service

# 查看验证
[root@k8s01 pki ]# netstat -tnulp | grep 6443
tcp6       0      0 :::6443                 :::*                    LISTEN      153080/kube-apiserv

2,ControllerManager启动

编辑systemd启动文件

[root@k8s01 pki ]# vim /usr/lib/systemd/system/kube-controller-manager.service
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/kubernetes/kubernetes
After=kube-apiserver.service
Wants=kube-apiserver.service

[Service]
ExecStart=/usr/local/bin/kube-controller-manager \
  # 监听地址,只允许本地访问 API,不暴露到公网(安全考虑)。
  --bind-address=127.0.0.1 \
  # 开放端口【监控metrics使用】
  --secure-port=10252 \
  # 这里,一定要使用自己自规划好的service CIDR网段;
  --service-cluster-ip-range=10.96.0.0/12 \
  # Pod 网络的 CIDR,Controller Manager 用它来分配 Pod IP(和 CNI 插件对应)。
  --cluster-cidr=10.244.0.0/16 \
  # 集群名字,主要用于标识集群;
  --cluster-name=kubernetes \
  # 这对参数用来签发 kubelet 证书(比如 CSR 请求),controller-manager 会用它自动给 kubelet 颁发证书。
  --cluster-signing-cert-file=/etc/kubernetes/pki/k8s-ca.crt \
  --cluster-signing-key-file=/etc/kubernetes/pki/k8s-ca.key \
  # 给哪种请求的CSR颁发证书?
  --controllers=*,csrapproving,csrsigning \
  # controller-manager 自己访问 apiserver 的配置文件(相当于“凭证”)。
  --kubeconfig=/etc/kubernetes/controller-manager.kubeconfig \
  # 高可用设置。如果有多个 controller-manager 实例,选举一个为 leader,其余 standby,避免重复工作。
  --leader-elect=true \
  # 提供给 ServiceAccount 的根证书,Pod 里的应用可以用它验证 API Server 的 TLS。
  --root-ca-file=/etc/kubernetes/pki/k8s-ca.crt \
  # 用来签发 ServiceAccount Token(JWT) 的私钥。
  --service-account-private-key-file=/etc/kubernetes/pki/sa.key \
  # 启用 Pod 内 ServiceAccount 使用自己的 Token 来访问 API Server,而不是共用一个超级权限。
  --use-service-account-credentials=true \
  # 日志级别,数字越大日志越详细
  --v=2
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

启动

[root@k8s01 pki ]# systemctl daemon-reload 
[root@k8s01 pki ]# systemctl enable --now kube-controller-manager.service
[root@k8s01 pki ]# systemctl status kube-controller-manager.service

3,Scheduler启动

编辑systemd启动文件

[root@k8s01 pki ]# vim /usr/lib/systemd/system/kube-scheduler.service
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/kubernetes/kubernetes
After=kube-apiserver.service
Wants=kube-apiserver.service

[Service]
ExecStart=/usr/local/bin/kube-scheduler \
  # 只监听本地回环地址,避免暴露在公网,提高安全性。
  # 调度器一般只跟 apiserver 通信,所以不需要对外提供接口
  --bind-address=127.0.0.1 \
  # 开放端口【监控metrics使用】
  --secure-port=10251 \
  # 指定调度器访问 apiserver 的 凭证配置文件
  --kubeconfig=/etc/kubernetes/scheduler.kubeconfig \
  # 开启 领导者选举,确保在多 master 环境下,只有一个 scheduler 真正工作,其它处于 standby
  --leader-elect=true \
  # # 允许 prometheus抓取metrics 
  --v=2
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

启动

[root@k8s01 pki ]# systemctl daemon-reload 
[root@k8s01 pki ]# systemctl enable --now kube-scheduler.service 
[root@k8s01 pki ]# systemctl status kube-scheduler.service

· 查看验证

# 查看k8s的被管理节点列表;
[root@k8s01 pki ]# kubectl get nodes --kubeconfig=/etc/kubernetes/admin.kubeconfig
No resources found

七、部署node节点

0,部署node注意点

客户端和服务端证书一样都在master上,集中管理
#1.kubelet:有状态服务,每个node节点各自配置(master主机上每个node的证书要重新生成)
#2.kube-proxy:无状态服务,每个node节点共用配置(master主机上证书只生成一次)
#3.启动配置文件在各自node节点配置

1,node部署containerd容器

· 下载容器组件

1,下载【containerd】

# 下载地址
https://github.com/containerd/containerd/

image-20250913195927377

# 选择最新的稳定版

image-20250913200341981

2,下载【runc】

# 下载地址
https://github.com/opencontainers/runc

image-20250913201336234

# 选择最新的稳定版

image-20250913201414493

3,下载【CNI网络插件】

# 下载地址
https://github.com/containernetworking/plugins

image-20250913201743718

# 选择最新的稳定版本部署

image-20250913201845348

· 部署容器组件

1,上传下载的组件

[root@k8s01 ~ ]# rz -E
[root@k8s01 ~ ]# ls -l
total 489404
-rw-r--r-- 1 root root 55418181 Jul 12 16:47 cni-plugins-linux-amd64-v1.9.1.tgz
-rw-r--r-- 1 root root 34560181 Jul 12 16:44 containerd-2.3.3-linux-amd64.tar.gz
-rw-r--r-- 1 root root 11437312 Jul 12 16:44 runc.amd64

2,配置runc

[root@k8s01 ~ ]# chmod +x runc.amd64 
[root@k8s01 ~ ]# cp runc.amd64 /usr/local/bin/runc

3,配置CNI网络插件

[root@k8s01 ~ ]# mkdir -p /opt/cni/bin
[root@k8s01 ~ ]# tar xf cni-plugins-linux-amd64-v1.9.1.tgz -C /opt/cni/bin

# 查看CNI组件文件
[root@k8s01 ~ ]# ls -l /opt/cni/bin
total 96240
-rwxr-xr-x 1 root root  5042926 Mar 16 22:18 bandwidth
-rwxr-xr-x 1 root root  5698763 Mar 16 22:18 bridge
-rwxr-xr-x 1 root root 13725422 Mar 16 22:18 dhcp
-rwxr-xr-x 1 root root  5251069 Mar 16 22:18 dummy
-rwxr-xr-x 1 root root  5702145 Mar 16 22:18 firewall
-rwxr-xr-x 1 root root  5159967 Mar 16 22:18 host-device
-rwxr-xr-x 1 root root  4350778 Mar 16 22:18 host-local
-rwxr-xr-x 1 root root  5274322 Mar 16 22:18 ipvlan
-rw-r--r-- 1 root root    11357 Mar 16 22:18 LICENSE
-rwxr-xr-x 1 root root  4302030 Mar 16 22:18 loopback
-rwxr-xr-x 1 root root  5307111 Mar 16 22:18 macvlan
-rwxr-xr-x 1 root root  5108385 Mar 16 22:18 portmap
-rwxr-xr-x 1 root root  5475470 Mar 16 22:18 ptp
-rw-r--r-- 1 root root     2343 Mar 16 22:18 README.md
-rwxr-xr-x 1 root root  4525826 Mar 16 22:18 sbr
-rwxr-xr-x 1 root root  3776708 Mar 16 22:18 static
-rwxr-xr-x 1 root root  5453308 Mar 16 22:18 tap
-rwxr-xr-x 1 root root  4389084 Mar 16 22:18 tuning
-rwxr-xr-x 1 root root  5267679 Mar 16 22:18 vlan
-rwxr-xr-x 1 root root  4685012 Mar 16 22:18 vrf

3,配置containerd

解压安装包到PATH路径下

# 解压containerd
[root@k8s01 ~ ]# tar xf containerd-2.3.3-linux-amd64.tar.gz 
[root@k8s01 ~ ]# ls -l
drwxr-xr-x 2 root root     4096 Jul 10 08:02 bin
-rw-r--r-- 1 root root 34560181 Jul 12 16:44 containerd-2.3.3-linux-amd64.tar.gz


[root@k8s01 ~ ]# ls -l bin/
total 97424
-rwxr-xr-x 1 root root 43155968 Jul 10 08:02 containerd
-rwxr-xr-x 1 root root  8458402 Jul 10 08:02 containerd-shim-runc-v2
-rwxr-xr-x 1 root root 22708526 Jul 10 08:02 containerd-stress
-rwxr-xr-x 1 root root 25424174 Jul 10 08:02 ctr

# 移动至path路径
[root@k8s01 ~ ]# cp bin/* /usr/local/bin/

生成containerd配置文件

[root@k8s01 ~ ]# mkdir /etc/containerd
[root@k8s01 ~ ]# containerd config default > /etc/containerd/config.toml

修改配置containerd文件:

  • 修改资源限制cgroup驱动:
    • 让【systemd驱动】来管理cgroup资源限制;
    • 否则containerd会直接【cgroupfs驱动】来直接编辑/sys/fs/cgroup来管理cgroup资源限制;
    • 因为kubelet默认使用systemd来管理资源限制,需要二者保持一致;
[root@k8s01 ~ ]# vim /etc/containerd/config.toml
......
            SystemdCgroup = true
......

编辑containerd的system启动文件

[root@k8s01 ~ ]# vim /usr/lib/systemd/system/containerd.service
[Unit]
# 服务的秒数信息
Description=containerd container runtime
# 官方文档地址
Documentation=https://containerd.io
# 声明此服务,必须在【网络服务】【消息总线系统】启动之后,才能启动;
After=network.target dbus.service

[Service]
# 加载overlay内核【就是OverlayFS文件系统】
ExecStartPre=-/sbin/modprobe overlay
# 启动containerd命令;
ExecStart=/usr/local/bin/containerd

# Type =【notify】表示服务完成初始化后,通过linux底层接口“sd_notify”通知systemd,systemd才算作服务启动成功;
Type=notify
# 表示:linux系统允许containerd服务,对自己的子进程"自主管理",子进程不算做containerd的一部分;
Delegate=yes
# 表示:当停止containerd服务后,仅杀死containerd主进程本身,不会杀死“子(容器)进程”;
KillMode=process
# 表示:服务只要退出了,就会重启
Restart=always
# 表示重启之前,等待5秒钟;
RestartSec=5

# 表示:【软限制】不限制进程可以创建的最大子进程数(包含线程);
LimitNPROC=infinity
# 表示:文件转储时cpu核心使用的限制,不做任何限制;
LimitCORE=infinity
# 表示:containerd不限制创建子进程、线程的任务数量;
TasksMax=infinity
# 表示:linux系统杀死进程的评分;设置为最小,意味着,内存不足时,最后杀死containerd进程;
OOMScoreAdjust=-999

[Install]
# 服务安装在哪个linux的系统启动界别;
WantedBy=multi-user.target

启动并配置开机自启动

[root@k8s01 ~ ]# systemctl daemon-reload 
[root@k8s01 ~ ]# systemctl enable --now containerd.service
[root@k8s01 ~ ]# systemctl status containerd.service

· 配置containerd镜像仓库

1,编辑containerd配置文件

harbor准备好k8s所需要的pod初始化容器镜像

[root@harbor ~ ]# docker pull k8s.m.daocloud.io/pause:3.10.2

[root@harbor ~ ]# docker tag k8s.m.daocloud.io/pause:3.10.2 reg.bakwite.com/library/pause:3.10.2

[root@harbor ~ ]# docker push reg.bakwite.com/library/pause:3.10.2

修改containerd配置文件中的初始化镜像地址为harbor仓库的地址

[root@k8s-master01:/k8s-download]# vim /etc/containerd/config.toml
......
 27     [plugins.'io.containerd.cri.v1.images'.pinned_images]
          # 修改为私有仓库地址
 28       sandbox = 'reg.bakwite.com/library/pause:3.10.2'
 29 
 30     [plugins.'io.containerd.cri.v1.images'.registry]
          # 指定镜像配置路径
 31       config_path = '/etc/containerd/certs.d/'

2,containetd创建私有仓库证书目录

[root@k8s01 ~ ]# mkdir -p /etc/containerd/certs.d/reg.bakwite.com/

3,拷贝harbor仓库的ca公钥

[root@k8s01 ~ ]# scp 10.0.0.180:/harbor/certs/ca.crt /etc/containerd/certs.d/reg.bakwite.com/

4,创建私有仓库配置文件

注意:每添加一个仓库,都需要创建仓库的地址目录,在创建hosts.toml文件

[root@k8s01 ~ ]# vim /etc/containerd/certs.d/reg.bakwite.com/hosts.toml
server = "https://reg.bakwite.com"  # 指定服务器地址

[host."https://reg.bakwite.com"]
  capabilities = ["pull", "resolve", "push"]
  # 跳过证书验证
  #skip_verify = true
  # 验证证书
  ca = "/etc/containerd/certs.d/reg.bakwite.com/ca.crt"
  
  #[host."https://reg.bakwite.com:443".auth]
  #username = "admin"
  #password = "12345"
  

5,hosts解析私有仓库域名

[root@k8s01 ~ ]# echo "10.0.0.180  reg.bakwite.com" >> /etc/hosts

7,重启containerd服务

[root@k8s01 ~ ]# systemctl restart containerd.service
[root@k8s01 ~ ]# systemctl status containerd.service

· 原生ctr命令-镜像管理(跳过)

1,修改镜像tag(可跳过)

# 给本地的 nginx:latest 添加一个新 tag
[root@k8s01 ~ ]# ctr images tag docker.io/calico/cni:v3.30.3  reg.bakwite.com/calico/cni:v3.30.3

2,拉取镜像(这个做一下,看看能不能拉取)

[root@k8s01 ~ ]# ctr images pull \
	--hosts-dir /etc/containerd/certs.d/ \
	reg.bakwite.com/library/nginx:1.20.1-alpine

3,推送镜像

[root@k8s-master01:~/calico]# ctr images push \
	--user admin:123456 \
	--hosts-dir /etc/containerd/certs.d/ \
	reg.bakwite.com/calico/cni:v3.30.3

3,删除镜像

# 删除单个镜像
[root@k8s-master01:~/calico]# ctr images rm docker.io/library/nginx:latest

# 删除所有镜像
[root@k8s-master01:~/calico]# ctr images rm  `ctr images ls -q`

# 强制删除所有镜像
[root@k8s-master01:~/calico]# ctr images rm --force `ctr images ls -q`

# 清空没用被容器引用的镜像
[root@k8s-master01:/k8s-yaml]# ctr image prune --all

4,查看镜像

# 查看镜像列表
[root@k8s-master01:~/calico]# ctr images ls

# 查看指定名称空间的镜像
[root@k8s-master01:/etc/kubernetes/pki]# ctr -n k8s.io  images  ls

5,查看镜像详细信息

[root@k8s-master01:~/calico]# ctr images info docker.io/library/nginx:latest

6,导入导出镜像

[root@k8s-master01:~/calico]# ctr images export nginx.tar docker.io/library/nginx:latest
[root@k8s-master01:~/calico]# ctr images import nginx.tar 

· 原生ctr命令-容器管理

1,拉取两个镜像

# 拉取nginx镜像
[root@k8s-master01:~/calico]# ctr images pull \
	--user admin:123456 \
	--hosts-dir /etc/containerd/certs.d/ \
	reg.bakwite.com/library/nginx:1.20.1-alpine

# 拉取alpine
[root@k8s-master01:~/calico]# ctr images pull \
	--user admin:123456 \
	--hosts-dir /etc/containerd/certs.d/ \
	reg.bakwite.com/library/alpine:latest

2,创建容器

命令:

  • 【ctr containers create 镜像名 容器名/ID】
  • 【ctr containers create 镜像名 --env key=value 容器名/ID 容器的启动命令】
# 创建容器nginx
[root@k8s-master01:/k8s-yaml]# ctr containers create \
	reg.bakwite.com/library/nginx:1.20.1-alpine \
	nginx-container

# 创建容器alpine
[root@k8s-master01:/k8s-yaml]# ctr containers create \
	--env name=zhangsan  \
	reg.bakwite.com/library/alpine:latest \
	alpine-container \
	sh

# 查看容器列表
[root@k8s-master01:/k8s-yaml]# ctr containers ls
CONTAINER           IMAGE                                             RUNTIME                  
alpine-container    reg.bakwite.com/library/alpine:latest          io.containerd.runc.v2    
nginx-container     reg.bakwite.com/library/nginx:1.20.1-alpine    io.containerd.runc.v2

# 查看启动的容器列表(发现什么都没有,说明容器不是启动状态)
[root@k8s-master01:/k8s-yaml]# ctr  tasks ls 
TASK    PID    STATUS

3,启动容器

# 前台启动nginx【原生ctr命令只能前台启动】
[root@k8s-master01:/k8s-yaml]# ctr  tasks start nginx-containers

# 前台启动alpine【原生ctr命令只能前台启动】
[root@k8s-master01:/k8s-yaml]# ctr  tasks start alpine-containers

# 查看容器启动列表
[root@k8s-master01:/etc/kubernetes/pki]# ctr tasks ls 
TASK                 PID        STATUS  
alpine-container     1438401    RUNNING
nginx-container      1438401    RUNNING

4,查看容器列表

# 查看容器列表
[root@k8s-master01:/etc/kubernetes/pki]# ctr containers ls

# 查看指定名称空间的容器
[root@k8s-master01:/etc/kubernetes/pki]# ctr -n k8s.io containers ls

5,查看启动容器列表

[root@k8s-master01:/k8s-yaml]# ctr -n k8s.io tasks ls
TASK                                                                PID       STATUS    
8e907cecb6b85954e84dadcd76f5e455e19b1a30515fde606b68a0ac344d9ccc    633702    RUNNING
0676b532b0bcb5e3ecf61ba922c4f85b9a01423bf86c153fb2cdfbd12c95f7b3    612912    RUNNING
0b4001dd50180e8eb418a9cd03eb67ed54ee05f380b778324dbd9f465f53ae25    612938    RUNNING
10dc4a6182b84d42157d1805facfefc17dfaf050d456d3a4d56a94ec7ad42f58    612993    RUNNING
0f01f1ae27fdac04da411e55738e97419206639b4f1ea4009d20dd0edd282a39    545229    RUNNING
b306a5b2c085b36f16e6c40427c317efb06aac22a49bb0bd00883b35ae06fe72    117190    RUNNING
e7b9965374a16a71d992675b501b2ff314c5d1a2dee1421073f0ff008cd7d1d5    122034    RUNNING

6,查看容器的详细信息

# 查看指定名称空间中容器的详细信息
[root@k8s-master01:/k8s-yaml]# ctr -n k8s.io containers info 0676b532b0bcb5e3ecf61ba922c4f85b9a01423bf86c153fb2cdfbd12c95f7b3

7,删除容器

# 先停止容器的任务[删除容器,必须杀死容器运行]
[root@k8s-master01:/etc/kubernetes/pki]# ctr tasks kill -s SIGKILL  alpine-container

# 删除容器
[root@k8s-master01:/etc/kubernetes/pki]# ctr containers rm  alpine-container

2,部署node组件

· 将node组件移动到path路径下

[root@k8s01 ~ ]# cp kubelet /usr/local/bin/
[root@k8s01 ~ ]# cp kube-proxy /usr/local/bin/

# 执行测试
[root@k8s01 ~ ]# kubelet --version
Kubernetes v1.36.2

· 创建node节点目录

目录 说明
/var/lib/kubelet/manifests k8s的静态pod目录(这个目录下的资源清单,都会默认自动创建成pod)
/var/lib/kubelet/pki k8s的kubelet工作数据的目录和pki证书目录:
:one:pod-resources/ 记录当前节点pod的使用情况信息
:two:pods/ pod的默认数据挂载目录
:three:plugins/ 【CSI容器存储接口】的插件相关的登记信息
:four:cpu_manager_state/ cpu管理器状态目录,记录cpu核心的分配情况​
/var/lib/kube-proxy k8s的kube-proxy的数据存储目录,网络规则的配置信息,service的负载均衡
# 创建k8s的kubelet工作数据的目录
mkdir -p /var/lib/kubelet/{pki,manifests}

# 创建k8s的kube-proxy的数据存储目录,网络规则的配置信息,service的负载均衡
mkdir -p /var/lib/kube-proxy

· 生成node节点证书

1,kubelet客户端节点证书

生成注意事项 说明
CN字段 必须为:system:node:节点主机名
O字段 必须为:system:nodes
# 生成私钥
[root@k8s01 ~ ]# cd /etc/kubernetes/pki/
[root@k8s01 pki ]# openssl genrsa -out kubelet-k8s01.key 2048

# 生成请求文件
[root@k8s01 pki ]# openssl req -new \
        -key kubelet-k8s01.key \
        -subj "/CN=system:node:k8s01/O=system:nodes" \
        -out kubelet-k8s01.csr

# 生成公钥
[root@k8s01 pki ]# openssl x509 -req \
        -in kubelet-k8s01.csr \
        -CA k8s-ca.crt -CAkey k8s-ca.key \
        -CAcreateserial -days 3650 \
        -out kubelet-k8s01.crt

2,生成kube-proxy客户端证书

所有节点共用

# 私钥
[root@k8s01 pki ]# openssl genrsa -out kube-proxy.key 2048

# 请求文件
[root@k8s01 pki ]# openssl req -new \
        -key kube-proxy.key \
        -subj "/CN=system:kube-proxy" \
        -out kube-proxy.csr

# 公钥
[root@k8s01 pki ]# openssl x509 -req \
        -in kube-proxy.csr \
        -CA k8s-ca.crt -CAkey k8s-ca.key \
        -CAcreateserial -days 3650 \
        -out kube-proxy.crt

3,生成kubelet服务端证书

# 生成私钥
openssl genrsa -out kubelet-server-k8s01.key 2048

# 生成 CSR,注意 CN 和 O 必须正确
[root@master01 pki ]# openssl req -new -key kubelet-server-k8s01.key \
  -out kubelet-server-k8s01.csr \
  -subj "/CN=system:node:k8s01/O=system:nodes" \
  -addext "subjectAltName = DNS:k8s01,DNS:localhost,IP:10.0.0.181,IP:127.0.0.1"

# 生成公钥
[root@master01 pki ]# openssl x509 -req -in kubelet-server-k8s01.csr \
  -CA k8s-ca.crt -CAkey k8s-ca.key -CAcreateserial \
  -out kubelet-server-k8s01.crt \
  -days 3650 \
  -extfile <(echo "subjectAltName=DNS:k8s01,DNS:localhost,IP:10.0.0.181,IP:127.0.0.1")

· 生成node组件身份认证文件

1,kube-poxy身份文件

所有节点共用

# 写入集群信息
[root@k8s01 pki ]# kubectl config set-cluster kubernetes \
        --certificate-authority=k8s-ca.crt \
        --embed-certs=true \
        --server=https://10.0.0.181:6443 \
        --kubeconfig=../kube-proxy.kubeconfig

# 将用户名称(证书中的CN字段)、客户端证书位置,写入到身份文件中
[root@k8s01 pki ]# kubectl config set-credentials system:kube-proxy \
        --client-certificate=kube-proxy.crt \
        --client-key=kube-proxy.key \
        --embed-certs=true \
        --kubeconfig=../kube-proxy.kubeconfig

# 绑定用户身份与k8s集群;
[root@k8s01 pki ]# kubectl config set-context default \
        --cluster=kubernetes \
        --user=system:kube-proxy \
        --kubeconfig=../kube-proxy.kubeconfig

# 确认生效用户的配置文件
[root@k8s01 pki ]# kubectl config use-context default \
        --kubeconfig=../kube-proxy.kubeconfig

2,kubelet身份文件

# 将集群地址、ca跟证书位置,写入用户身份文件中


# --server 必须是master地址
[root@k8s01 pki ]# kubectl config set-cluster kubernetes \
        --certificate-authority=k8s-ca.crt \
        --embed-certs=true \
        --server=https://10.0.0.181:6443 \
        --kubeconfig=../kubelet-k8s01.kubeconfig

# 将用户名称(证书中的CN字段)、客户端证书位置,写入到身份文件中
[root@k8s01 pki ]# kubectl config set-credentials system:node:k8s01 \
        --client-certificate=kubelet-k8s01.crt \
        --client-key=kubelet-k8s01.key \
        --embed-certs=true \
        --kubeconfig=../kubelet-k8s01.kubeconfig
	
# 绑定用户身份与k8s集群;
[root@k8s01 pki ]# kubectl config set-context default \
        --cluster=kubernetes \
        --user=system:node:k8s01 \
        --kubeconfig=../kubelet-k8s01.kubeconfig
	
# 确认生效用户的配置文件	
[root@k8s01 pki ]# kubectl config use-context default \
        --kubeconfig=../kubelet-k8s01.kubeconfig

· 启动node组件(在node主机上操作)

1,kube-proxy服务配置启动

复制身份文件到组件目录

[root@k8s01 ~ ]# cp /etc/kubernetes/kube-proxy.kubeconfig /var/lib/kube-proxy/

编辑system启动文件

[root@k8s01 pki ]# vim /usr/lib/systemd/system/kube-proxy.service

[Unit]
Description=Kubernetes Kube Proxy
Documentation=https://github.com/kubernetes/kubernetes

[Service]
ExecStart=/usr/local/bin/kube-proxy \
  --bind-address=0.0.0.0 \
  # 指定 Pod 网络的 CIDR 段,kube-proxy 需要知道哪些流量是 Pod IP,才能正确设置 iptables/ipvs 规则。
  # 这里的网段必须和你部署 CNI 插件(例如 flannel/calico)时的 cluster-cidr 保持一致。
  --cluster-cidr=10.244.0.0/16 \
  # 本机IP
  --hostname-override=10.0.0.181 \
  # kube-proxy 访问 kube-apiserver 的凭证文件
  --kubeconfig=/var/lib/kube-proxy/kube-proxy.kubeconfig \
  # 设置 每个 CPU core 能追踪的连接数量
  --conntrack-max-per-core=131072 \
  #设置 conntrack 表的最小条目数。防止 conntrack table 被调得过小,至少要有 131072 条。
  --conntrack-min=131072 \
  # 指定 kube-proxy 的工作模式。
  # iptables:传统模式,规则多时性能较差。
  # ipvs:基于 Linux IPVS,性能更好,支持更多调度算法,生产推荐用 ipvs。
  --proxy-mode=iptables \
  # 日志级别,2 表示一般调试信息,常用。数值越大,日志越详细
  --v=2
Restart=on-failure
RestartSec=5
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

启动服务

[root@k8s01 pki ]# systemctl daemon-reload 
[root@k8s01 pki ]# systemctl enable --now kube-proxy.service
[root@k8s01 pki ]# systemctl status kube-proxy.service 

· kubelet服务配置启动

编辑kubelet配置文件

# 编辑配置文件
[root@k8s-master01:~]# vim /var/lib/kubelet/config.yaml
# 表明这是 kubelet 的配置,使用 v1beta1 API 版本,类型是 KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
# kubelet 监听的地址。0.0.0.0 表示监听所有网卡地址,方便外部(如 apiserver)访问
address: 0.0.0.0
# kubelet 的安全端口(HTTPS,启用认证/授权),apiserver 会通过这个端口访问 kubelet
port: 10250

# API-Server访问kubelet时,kubelet的服务端证书
tlsCertFile: "/var/lib/kubelet/pki/kubelet-server-k8s01.crt"      # 服务端证书路径
tlsPrivateKeyFile: "/var/lib/kubelet/pki/kubelet-server-k8s01.key" # 服务端私钥路径
rotateCertificates: false  # 关闭证书轮转

# kubelet 使用的 cgroup driver,必须与containerd的cgroup driver一致;
# k8s新版本默认systemd管理cgroup
cgroupDriver: systemd
# service的网关别写错
# kubelet 配置 Pod 的 DNS 服务 IP
# CoreDNS 的 Service IP 通常是 10.100.0.10
clusterDNS:
- 10.96.0.10
# 集群内默认的域名后缀。
# 例如,一个 service 叫 nginx 在 default 命名空间,
# Pod 内部访问方式就是:nginx.default.svc.cluster.local
clusterDomain: cluster.local
# 主要修改这里,写自己主机的主机名,k8s会识别为集群的主机名称;
nodeName: k8s01
# kubelet 与容器运行时(containerd)的请求超时时间,默认 2m,这里改成 15m,避免大镜像拉取超时。
runtimeRequestTimeout: "15m"
# 指定一个目录,kubelet 会自动加载里面的 Pod YAML 并直接启动(静态 Pod,不受 apiserver 管理)。
staticPodPath: "/var/lib/kubelet/manifests"

# 认证设置
authentication:
  # 禁止匿名访问 kubelet,必须认证
  anonymous:
    enabled: false
  # 开启 Webhook 认证,kubelet 会把请求交给 apiserver 验证(即 apiserver 负责判断请求是否合法)
  webhook:
    enabled: true
  # kubelet 信任的 CA 证书。
  # 如果请求方提供了客户端证书(x509),kubelet 会用这个 CA 来验证证书有效性。
  x509:
    clientCAFile: /var/lib/kubelet/pki/k8s-ca.crt
# kubelet 的授权模式:
# mode:Webhook:交给 apiserver 的 RBAC 来决定是否允许请求。
# mode:AlwaysAllow:所有请求都允许(不安全)。
authorization:
  mode: Webhook
# 给监控容器时预留的只读端口;
readOnlyPort: 10255

将kubelet服务端证书、ca根证书,放到配置文件指定位置

[root@k8s01 pki ]# cp /etc/kubernetes/pki/kubelet-server-k8s01.* /var/lib/kubelet/pki/
[root@k8s01 pki ]# cp /etc/kubernetes/pki/k8s-ca.crt /var/lib/kubelet/pki/

编辑system启动文件

[root@k8s-master01:~]# vim /usr/lib/systemd/system/kubelet.service
[Unit]
Description=Kubernetes Kubelet
Documentation=https://github.com/kubernetes/kubernetes
After=containerd.service
Requires=containerd.service

[Service]
ExecStart=/usr/local/bin/kubelet \
  # 指定 kubelet 的主配置文件,里面定义了 kubelet 的工作目录、认证方式、cgroup driver 等。
  --config=/var/lib/kubelet/config.yaml \
  # 告诉 kubelet 使用 containerd 作为容器运行时,通过 Unix socket 连接
  --container-runtime-endpoint=unix:///run/containerd/containerd.sock \
  # 这一行,一定要写用户名,就是证书的CN字段名;
  # 这里强制写成 k8s-master01;
  # 必须和生成 kubelet 证书(CN 字段) 以及 kubeconfig 文件 一致,否则 kube-apiserver 会认证失败。
  --hostname-override=k8s01 \
  # 指定 kubelet 的 kubeconfig 文件
  --kubeconfig=/var/lib/kubelet/kubelet-k8s01.kubeconfig \
  --v=2
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

复制身份文件到组件目录

[root@k8s01 ~ ]# cp /etc/kubernetes/kubelet-k8s01.kubeconfig /var/lib/kubelet/

启动kubelet服务

[root@k8s01 pki ]# systemctl daemon-reload 
[root@k8s01 pki ]# systemctl enable --now kubelet.service
[root@k8s01 pki ]# systemctl status kubelet.service

1.#如果kubelet.service启动不来,记得查看node主机上/var/lib/kubelet/kubelet-k8s03.kubeconfig
#server: 地址必须是master地址

2.可以查看日志journalctl -u kubelet.service --no-page -n 50|egrep -i "error|fai"

3,客户端查看集群节点列表

[root@k8s01 pki ]# kubectl get nodes --kubeconfig=/etc/kubernetes/admin.kubeconfig
NAME    STATUS     ROLES    AGE   VERSION
k8s01   NotReady   <none>   7s    v1.36.2

4,配置默认kubectl身份文件

# 复制身份文件到家目录
[root@k8s01 ~ ]# cp /etc/kubernetes/admin.kubeconfig ~/.kube/config

# 执行命令测试
[root@k8s01 ~ ]# kubectl get nodes
NAME    STATUS     ROLES    AGE   VERSION
k8s01   NotReady   <none>   49m   v1.36.2

八、部署网络组件calico

· master节点下载yml文件

1,官网地址

https://docs.tigera.io/calico/latest/getting-started/kubernetes/self-managed-onprem/onpremises

image-20250917124912295

2,下载yml文件

curl https://raw.githubusercontent.com/projectcalico/calico/v3.30.3/manifests/calico.yaml -O

· 配置部署加速

1,过滤需要拉取的镜像(如果是quay,不是docker,就不需要修改镜像地址)

# 过滤需要拉取的镜像
[root@k8s-master01:/k8s-download]# grep -En 'image:.*calico|image:.*docker.io' calico.yaml
9875:          image: docker.io/calico/cni:v3.30.3
9903:          image: docker.io/calico/cni:v3.30.3
9946:          image: docker.io/calico/node:v3.30.3
9972:          image: docker.io/calico/node:v3.30.3
10195:          image: docker.io/calico/kube-controllers:v3.30.3

# 修改镜像地址
[root@master01 ~ ]# grep -En 'image:.*calico|image:.*docker.io' calico.yaml
7458:          # image: quay.io/calico/cni:v3.32.0
7459:          image: docker.m.daocloud.io/calico/cni:v3.32.0
7487:          # image: quay.io/calico/cni:v3.32.0
7488:          image: docker.m.daocloud.io/calico/cni:v3.32.0
7532:          # image: quay.io/calico/node:v3.32.0
7533:          image: docker.m.daocloud.io/calico/node:v3.32.0
7559:          # image: quay.io/calico/node:v3.32.0
7560:          image: docker.m.daocloud.io/calico/node:v3.32.0
7783:          # image: quay.io/calico/kube-controllers:v3.32.0
7784:          image: docker.m.daocloud.io/calico/kube-controllers:v3.32.0

2,harbor科学上网(了解)

export HTTP_PROXY=http://10.0.0.1:7897
export HTTPS_PROXY=http://10.0.0.1:7897
export no_proxy="localhost,127.0.0.1,::1,10.0.0.91,10.100.0.0/12,10.244.0.0/16,10.0.0.0/8"

[root@k8s-master01:~]# curl -I https://www.google.com
HTTP/1.1 200 Connection established

HTTP/2 200 
content-type: text/html; charset=ISO-8859-1
content-security-policy-report-only: object-src 'none';base-uri 'self';script-src 'nonce-PfMoAm7xlX8neWVfNbziyQ' 'strict-dynamic' 'report-sample' 'unsafe-eval' 'unsafe-inline' https: http:;report-uri https://csp.withgoogle.com/csp/gws/other-hp
accept-ch: Sec-CH-Prefers-Color-Scheme
p3p: CP="This is not a P3P policy! See g.co/p3phelp for more info."
date: Tue, 16 Sep 2025 23:59:05 GMT
server: gws
x-xss-protection: 0
x-frame-options: SAMEORIGIN
expires: Tue, 16 Sep 2025 23:59:05 GMT
cache-control: private
set-cookie: AEC=AVh_V2hrRuhukfyTyP3p_54yTCGerjQJ8V3d4ugpM4brpUBijSOHLvIvdN0; expires=Sun, 15-Mar-2026 23:59:05 GMT; path=/; domain=.google.com; Secure; HttpOnly; SameSite=lax
set-cookie: NID=525=MN3zjAATFLiZLjSPaCCocLGKrPXYUr0pL1NI_RT2yhD4iDH3LTZSXGjQc6Jr4NYHuMu40zyFquuKLRLzabz7a9kg8qWAkfdsIFTsFcwq-nYlqjNypYh6DDs9cxUOuA_eUJx4QBpBReoFBESUfYBFnihEYDGGOFlvNiEChCJT4V-TZr-8lUyYi1JzirZSQWNFK7ZOR3UYAO_iog; expires=Wed, 18-Mar-2026 23:59:05 GMT; path=/; domain=.google.com; HttpOnly
alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000

2,docker拉取容器(跳过)

[root@harbor01:~]# docker pull registry.aliyuncs.com/google_containers/pause:3.10
[root@harbor01:~]# docker pull docker.io/calico/cni:v3.30.3
[root@harbor01:~]# docker pull docker.io/calico/node:v3.30.3
[root@harbor01:~]# docker pull docker.io/calico/kube-controllers:v3.30.3

3,推送到私有仓库

image-20250917164404290

· 修改calico默认Pod网段

将pods网段修改为预先设定的

[root@k8s-master01:~/calico]# grep CALICO_IPV4POOL_CIDR calico.yaml -n
10033:            # - name: CALICO_IPV4POOL_CIDR

[root@k8s-master01:~/calico]# vim +10033 calico.yaml
10033             - name: CALICO_IPV4POOL_CIDR
10034               value: "10.244.0.0/16"

· 部署calico服务

1,运行部署

# 部署calico服务
[root@k8s-master01:~/calico]# kubectl apply -f calico.yaml

2,部署后等待pod状态

calico的pod作用 解释说明
calico-node 负责向apiserver同步汇报每个节点都有哪些pod的ip地址,保证不同节点pod的ip不冲突;
calico-kube-controllers 监控、释放集群pod的ip池,网络规则等;
[root@k8s-master01:~/calico]# kubectl get pods -A
NAMESPACE     NAME                                       READY   STATUS    RESTARTS   AGE
kube-system   calico-kube-controllers-59556d9b4c-2zxtb   1/1     Running   0          127m
kube-system   calico-node-mt88s                          1/1     Running   0          127m
kube-system   calico-node-pzmkh                          1/1     Running   0          127m
kube-system   calico-node-v5gbt                          1/1     Running   0          127m

3,查看集群列表验证

[root@k8s-master01:~/calico]# kubectl get nodes
NAME                   STATUS   ROLES    AGE    VERSION
kubelet-k8s-master01   Ready    <none>   27h    v1.34.1
kubelet-k8s-node01     Ready    <none>   4h1m   v1.34.1
kubelet-k8s-node02     Ready    <none>   26h    v1.34.1

4,测试网络(跳过)

[root@k8s-master01:~/calico]# kubectl create deployment tegine --image=reg.bakwite.com/bakwite_project/tengine:v1
deployment.apps/tegine created


[root@k8s-master01:~/calico]# kubectl get pods 
NAME                     READY   STATUS             RESTARTS   AGE
tegine-dd888f49b-rch2v   1/1     Running            0          7s


[root@k8s-master01:~/calico]# kubectl expose deployment tegine --port=80 --type=NodePort
service/tegine exposed

[root@k8s-master01:~/calico]# kubectl get svc tegine
NAME     TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
tegine   NodePort   10.110.158.219   <none>        80:30852/TCP   23s


[root@k8s-master01:~/calico]# curl 10.110.158.219
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
 Sorry for the inconvenience.<br/>
Please report this message and include the following information to us.<br/>
Thank you very much!</p>
<table>
<tr>
<td>URL:</td>
<td>http://10.110.158.219/</td>
</tr>
<tr>
<td>Server:</td>
<td>tegine-dd888f49b-rch2v</td>
</tr>
<tr>
<td>Date:</td>
<td>2025/09/17 08:50:21</td>
</tr>
</table>
<hr/>Powered by Tengine/3.1.0<hr><center>tengine</center>
</body>
</html>

如果一切顺利,你将看到 Tengine 的欢迎页面,标志着你的 Kubernetes 1.34.1 二进制集群部署成功!

九、部署coreDNS组件

什么是coreDNS:就是集群内实现DNS相互访问的组件;

· 前往官网下载

1,官网地址

https://github.com/coredns/deployment

image-20250928091534569

2,下载部署文件

# 点击【kubernetes】目录,再点击模板文件

image-20250928104213793

# 创建部署目录
[root@k8s-master01:~]# mkdir /coredns
[root@k8s-master01:~]# cd /coredns

下载模板文件

image-20250928101142275

# 上传模板文件
[root@k8s-master01:/coredns]# rz -E
[root@k8s-master01:/coredns]# ls -l
total 8
-rw-r--r-- 1 root root 4490 Sep 28 09:51 coredns.yaml.sed

· 修改模板文件

先过滤一下要修改的内容

[root@k8s-master01:/k8s-download]# egrep -n "image|clusterIP|forward|replicas|STUBDOMAINS|CLUSTER_DOMAIN" coredns.yaml.sed 
           # CLUSTER_DOMAIN REVERSE_CIDRS 占位符改成【cluster.local in-addr.arpa ip6.arpa】
62         kubernetes CLUSTER_DOMAIN REVERSE_CIDRS {
66:        forward . UPSTREAMNAMESERVER {
73:    }STUBDOMAINS  # 把这个结束符删除(注意,花括号别删除哦!)
85:  # replicas: not specified here:
120:        image: coredns/coredns:1.9.4
121:        imagePullPolicy: IfNotPresent
191:  clusterIP: CLUSTER_DNS_IP

修改后过滤

[root@k8s-master01:/coredns]# egrep -n "image|clusterIP|forward|replicas|STUBDOMAINS|cluster.local in-addr.arpa ip6.arpa" coredns.yaml.sed 
62:        kubernetes cluster.local in-addr.arpa ip6.arpa {
66:        forward . 223.5.5.5 {
85:  replicas: 3
120:        image: reg.bakwite.com/library/coredns:1.12.3
121:        imagePullPolicy: IfNotPresent
191:  clusterIP: 10.96.0.10

将文件后缀去掉

[root@k8s-master01:/coredns]# cp coredns.yaml.sed coredns.yaml
[root@k8s-master01:/coredns]# ls -l
total 16
-rw-r--r-- 1 root root 4479 Sep 28 10:27 coredns.yaml
-rw-r--r-- 1 root root 4479 Sep 28 10:26 coredns.yaml.sed

· harbor仓库保存coredns镜像

[root@harbor:/harbor/harbor]# docker pull coredns/coredns:1.12.3

[root@harbor:/harbor/harbor]# docker tag docker.io/coredns/coredns:1.12.3 reg.bakwite.com/library/coredns:1.12.3


[root@harbor:/harbor/harbor]# docker images
REPOSITORY                           TAG       IMAGE ID       CREATED        SIZE
......
coredns/coredns                      1.12.3    0392ee038903   7 weeks ago    74.1MB
reg.bakwite.com/coredns/coredns   1.12.3    0392ee038903   7 weeks ago    74.1MB

# 推送到harbor仓库
[root@harbor:/harbor/harbor]# docker push reg.bakwite.com/library/coredns:1.12.3

image-20250928103203819

· 部署coredns

[root@k8s-master01:/coredns]# kubectl apply -f coredns.yaml
serviceaccount/coredns created
clusterrole.rbac.authorization.k8s.io/system:coredns created
clusterrolebinding.rbac.authorization.k8s.io/system:coredns created
configmap/coredns created
deployment.apps/coredns created
service/kube-dns created

· 查看coreDNS

[root@k8s-master01:/k8s-download]# kubectl get pods -A
NAMESPACE     NAME                                       READY   STATUS    RESTARTS   AGE
kube-system   calico-kube-controllers-59556d9b4c-bxplr   1/1     Running   0          7m6s
kube-system   calico-node-m2tkx                          1/1     Running   0          7m6s
kube-system   calico-node-q7wnz                          1/1     Running   0          7m6s
kube-system   calico-node-trvp2                          1/1     Running   0          7m6s
kube-system   coredns-bf599cd-5fsgj                      1/1     Running   0          2m11s
kube-system   coredns-bf599cd-p8wg9                      1/1     Running   0          2m11s
kube-system   coredns-bf599cd-wvbdh                      1/1     Running   0          2m11s

Discussion

评论

加载中
正在检查登录状态…