一、回顾docker容器技术
1,docker架构回顾

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 | 【真正创建、运行容器的工具】:低级容器运行时,创建容器、隔离容器进程; |

四、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

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

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

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

# 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/

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

# 上传到主机
[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
- 直接选择最新版

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

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

· 信任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
# 查看仓库

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

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

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

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

· 上传到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数据库
· 下载安装包
·
- 选择最新的稳定版

# 根据cpu架构选择

· 上传解压安装包
# 上传
[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/

# 选择最新的稳定版

2,下载【runc】
# 下载地址
https://github.com/opencontainers/runc

# 选择最新的稳定版

3,下载【CNI网络插件】
# 下载地址
https://github.com/containernetworking/plugins

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

· 部署容器组件
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

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,推送到私有仓库

· 修改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

2,下载部署文件
# 点击【kubernetes】目录,再点击模板文件

# 创建部署目录
[root@k8s-master01:~]# mkdir /coredns
[root@k8s-master01:~]# cd /coredns
下载模板文件

# 上传模板文件
[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

· 部署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
评论