侧边栏壁纸
博主头像
jack

日拱一卒无有尽,功不唐捐终入海

  • 累计撰写 26 篇文章
  • 累计创建 13 个标签
  • 累计收到 6 条评论

目 录CONTENT

文章目录

第三篇——kubernetes高可用部署

jack
2023-07-22 / 0 评论 / 0 点赞 / 518 阅读 / 11,638 字 / 正在检测是否收录...

k8s二进制高可用部署系列文章集合

  1. 第一篇——kubernetes二进制高可用部署——环境和工具准备
  2. 第二篇——kubernetes二进制高可用部署——5台服务器初始化配置
  3. 第三篇——kubernetes高可用部署

1. docker-ce安装和配置(所有主机节点)

设置docker的yum源repository

yum install -y yum-utils

yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

全部主机安装 Docker 和容器运行时 containerd

yum -y install docker-ce docker-ce-cli containerd.io docker-compose-plugin

设置 Docker 开机自启并启动

systemctl enable docker.service --now

生成 containerd 的配置文件:

# 新建目录
mkdir -p /etc/containerd

# 将默认的 containerd 配置写入到 /etc/containerd/config.toml
containerd config default > /etc/containerd/config.toml

修改配置文件

把 systemd_cgroup = false 修改成 systemd_cgroup = true
把 sandbox_image = “k8s.gcr.io/pause:3.6” 修改成下面sandbox_image=“registry.aliyuncs.com/google_containers/pause:3.7

vim /etc/containerd/config.toml

配置 containerd 开机自启

systemctl enable containerd --now

安装crictl

说明:
(1)crictl 是遵循 CRI 接口规范的一个命令行工具,通常用它来检查和管理kubelet节点上的容器运行时和镜像。

(2) ctr 是 containerd 的一个客户端工具。

(3) ctr -v 输出的是 containerd 的版本,crictl -v 输出的是当前 k8s 的版本,从结果显而易见你可以认为 crictl 是用于 k8s 的。

(4) 主机安装了 k8s ,命令行才会有 crictl 命令。而ctr 是跟 k8s 无关的,主机安装了 containerd 服务后就可以操作 ctr 命令。

目录: /data/work

wget https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.27.1/crictl-v1.27.1-linux-amd64.tar.gz

解压缩

tar -xzvf crictl-v1.27.1-linux-amd64.tar.gz

mv crictl /usr/local/bin

使用 crictl 对 Kubernetes 节点进行调试

cat > /etc/crictl.yaml <<EOF
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
EOF
crictl --version
systemctl restart containerd

配置 containerd 运行时镜像加速器

参考:https://blog.csdn.net/IOT_AI/article/details/131975562

配置containerd镜像源加速(所有主机执行)
注意有坑: 使用ctr images pull 拉取镜像时 是不会生效的,需要使用crictl命令;或者使用ctr images pull --hosts-dir “/etc/containerd/certs.d” xxx方式进行镜像下载加速

# 新建目录
mkdir /etc/containerd/certs.d/docker.io -pv

# 编辑 /etc/containerd/config.toml 
vim /etc/containerd/config.toml

image-1690507019070

cat > /etc/containerd/certs.d/docker.io/hosts.toml << EOF
server = "https://docker.io"
[host."https://dockerproxy.com"]
  capabilities = ["pull", "resolve"]

[host."https://docker.m.daocloud.io"]
  capabilities = ["pull", "resolve"]

[host."https://reg-mirror.qiniu.com"]
  capabilities = ["pull", "resolve"]

[host."https://registry.docker-cn.com"]
  capabilities = ["pull", "resolve"]

[host."http://hub-mirror.c.163.com"]
  capabilities = ["pull", "resolve"]
EOF

加速使用方法: ctr -n=k8s.io images pull --hosts-dir “/etc/containerd/certs.d” xxxxxx
重启containerd

systemctl restart containerd

2. 配置 Docker 运行时镜像加速器和驱动

详细参考链接请看:https://help.aliyun.com/zh/acr/user-guide/accelerate-the-pulls-of-docker-official-images#section-190-0d1-83z

修改 docker 文件驱动为 systemd,默认为 cgroupfs,kubelet 默认使用 systemd,两者必须一致才可

mkdir -p /etc/docker
vim /etc/docker/daemon.json
{
 "registry-mirrors":["https://yoeedppp.mirror.aliyuncs.com","https://registry.docker-cn.com","https://docker.mirrors.ustc.edu.cn","https://dockerhub.azk8s.cn","http://hub-mirror.c.163.com"],
  "exec-opts": ["native.cgroupdriver=systemd"]
}

重新加载配置文件并重启 Docker

systemctl daemon-reload  && systemctl restart docker

3. 搭建 etcd 集群(主要在k8s-master-1 上操作)

etcd 是一个分布式键值存储系统,它在 Kubernetes(K8s)中扮演着重要的角色。以下是 etcd 在 K8s 上的作用和角色:

  1. 集群状态存储:etcd 用于存储和管理整个 Kubernetes 集群的状态信息,包括集群配置、节点信息、服务发现、Pod 和容器的状态等。它是 Kubernetes 控制平面的核心组件之一。
  2. 数据同步和一致性:etcd 提供了强一致性的数据复制机制,确保集群中的所有节点都具有相同的视图和数据。当集群中的任何一个节点发生故障或者网络分区时,etcd 能够自动进行数据同步和修复,保证集群的可用性和一致性。
  3. 选举和领导者选取:etcd 使用 Raft 算法来实现分布式一致性,其中包括选举和领导者选取。每个 etcd 集群都有一个领导者节点,它负责处理写操作和集群的状态变化。当领导者节点失效时,etcd 会自动进行选举,选择新的领导者节点。
  4. 服务发现和注册:etcd 提供了一个分布式的服务发现机制,允许应用程序在集群中注册和发现服务。应用程序可以使用 etcd 存储和获取服务的地址、端口和其他元数据,从而实现动态服务发现和负载均衡。
  5. 配置管理:etcd 可以用作配置中心,应用程序可以将配置信息存储在 etcd 中,并通过监听 etcd 的变化来实现动态的配置更新。这样可以方便地管理和调整应用程序的配置,而无需重启应用程序。

总之,etcd 在 Kubernetes 中扮演着存储集群状态、提供一致性、选举领导者、服务发现和注册、配置管理等关键角色。它是 Kubernetes 控制平面的基础组件之一,为整个集群的可靠性和可扩展性提供了重要支持。


etcd 和 Kubernetes API Server 是 Kubernetes 控制平面中的两个核心组件,它们在 Kubernetes 中扮演不同的角色。

  1. etcd:etcd 是一个分布式键值存储系统,用于存储和管理整个 Kubernetes 集群的状态信息。它是一个独立的后端存储系统,负责持久化保存集群的配置、节点信息、服务发现、Pod 和容器的状态等。etcd 提供了强一致性的数据复制机制,确保集群中的所有节点都具有相同的视图和数据。它还处理选举和领导者选取,确保集群中始终有一个可用的领导者节点。etcd 是 Kubernetes 控制平面的基础组件之一,通过 API Server 与其他组件进行交互。
  2. API Server:Kubernetes API Server 是 Kubernetes 控制平面的入口,它提供了与集群交互的接口。API Server 充当了 Kubernetes 集群的 “大脑”,接收来自用户、管理员和其他组件的请求,并将其转化为对 etcd 存储的操作。API Server 提供了 RESTful API,允许用户管理集群的各种资源,如 Pod、Service、Deployment 等。它还负责认证、授权和准入控制,确保只有经过授权的用户和组件可以访问和操作集群。

etcd 和 API Server 之间的关系是密切的。API Server 使用 etcd 作为后端存储来持久化保存集群状态和配置信息,并通过 etcd 实现数据的一致性和可靠性。当用户或其他组件发送请求给 API Server 时,API Server 会读取或更新 etcd 中的数据,并将结果返回给请求方。etcd 提供了数据存储和复制机制,而 API Server 则负责处理请求和提供高级功能,如认证、授权和准入控制。
总结来说,etcd 是 Kubernetes 控制平面中的存储组件,负责存储和管理集群的状态信息;而 API Server 是控制平面的入口,负责接收和处理用户和组件的请求,并与 etcd 进行交互来实现集群管理和操作。它们共同构成了 Kubernetes 控制平面的核心基础设施。


配置 etcd 工作目录(此步骤三个master节点都执行)

创建 etcd 配置文件、证书文件、数据存放目录(三个 master 节点上都创建以下目录)

mkdir -p /etc/etcd
mkdir -p /etc/etcd/ssl
mkdir -p /var/lib/etcd/default.etcd

注意

本环节下面的操作无特殊说明的(指的是 3. 搭建 etcd 集群 环节),表示仅在k8s-master-1上面操作,最后会将 /etc/etcd 目录安装的软件全部使用scp分发到其它两个master节点。

安装签发证书工具 cfssl

cfssl 是使用 go 编写,由 CloudFlare 开源的一款 PKI/TLS 工具。主要程序有:
(1) cfssl 是 CFSSL 的命令行工具;
(2) cfssljson 用来从 cfssl 程序获取 JSON 输出,并将证书、密钥、CSR 和 bundle 写入文件中。

新建/data/work 目录

mkdir -p /data/work

接下来本环节的步骤都是在 /data/work/ 下进行

cd /data/work/

下载

wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64

添加可执行权限

chmod +x cfssl*
mv cfssl_linux-amd64 /usr/local/bin/cfssl
mv cfssljson_linux-amd64 /usr/local/bin/cfssljson
mv cfssl-certinfo_linux-amd64 /usr/local/bin/cfssl-certinfo

验证

cfssl version

配置 CA 证书

创建 ca 证书请求文件

cd /data/work/
vim ca-csr.json
{
  "CN": "kubernetes",
  "key": {
      "algo": "rsa",
      "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "ZheJiang",
      "L": "NingBo",
      "O": "k8s",
      "OU": "system"
    }
  ],
  "ca": {
          "expiry": "87600h"
  }
}

创建 ca 证书

cfssl gencert -initca ca-csr.json | cfssljson -bare ca

配置 ca 证书策略

vim ca-config.json
{
  "signing": {
      "default": {
          "expiry": "87600h"
        },
      "profiles": {
          "kubernetes": {
              "usages": [
                  "signing",
                  "key encipherment",
                  "server auth",
                  "client auth"
              ],
              "expiry": "87600h"
          }
      }
  }
}

/data/work/目录如下:
/data/work/目录

创建 etcd 证书

配置 etcd 证书请求,依然在 work目录进行操作;hosts 的 ip 改为自己 etcd 所在 master 节点的 IP 和虚拟 IP:

vim etcd-csr.json
{
  "CN": "etcd",
  "hosts": [
    "127.0.0.1",
    "192.168.237.11",
    "192.168.237.12",
    "192.168.237.13",
    "192.168.237.19"
  ],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [{
    "C": "CN",
    "ST": "ZheJiang",
    "L": "NingBo",
    "O": "k8s",
    "OU": "system"
  }]
}

TODO :上述文件 hosts 字段中 IP 为所有 etcd 节点的集群内部通信IP,可以预留几个 ip,方便日后做扩容用
TODO CA证书 :https://www.cnblogs.com/hahaha111122222/p/16016351.html
生成 etcd 证书

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes etcd-csr.json | cfssljson -bare etcd

在、data/work目录 执行 ls 命令,如下结果
image-1690122164446

部署 etcd 集群

k8s-master-1 的work目录执行:

wget https://github.com/etcd-io/etcd/releases/download/v3.5.2/etcd-v3.5.2-linux-amd64.tar.gz

安装

tar -zxvf etcd-v3.5.2-linux-amd64.tar.gz
cp -p etcd-v3.5.2-linux-amd64/etcd* /usr/local/bin/

分发 etcd 软件

scp etcd-v3.5.2-linux-amd64/etcd* k8s-master-2:/usr/local/bin/
scp etcd-v3.5.2-linux-amd64/etcd* k8s-master-3:/usr/local/bin/

image-1690122434029

image-1690122462542

创建配置文件

cat > /etc/etcd/etcd.conf <<"EOF"
#[Member]
ETCD_NAME="etcd1"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.237.11:2380"
ETCD_LISTEN_CLIENT_URLS="https://192.168.237.11:2379,http://127.0.0.1:2379"
 
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.237.11:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.237.11:2379"
ETCD_INITIAL_CLUSTER="etcd1=https://192.168.237.11:2380,etcd2=https://192.168.237.12:2380,etcd3=https://192.168.237.13:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
EOF

创建服务配置文件

cat > /usr/lib/systemd/system/etcd.service <<"EOF"
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
 
[Service]
Type=notify
EnvironmentFile=-/etc/etcd/etcd.conf
WorkingDirectory=/var/lib/etcd/
ExecStart=/usr/local/bin/etcd \
  --cert-file=/etc/etcd/ssl/etcd.pem \
  --key-file=/etc/etcd/ssl/etcd-key.pem \
  --trusted-ca-file=/etc/etcd/ssl/ca.pem \
  --peer-cert-file=/etc/etcd/ssl/etcd.pem \
  --peer-key-file=/etc/etcd/ssl/etcd-key.pem \
  --peer-trusted-ca-file=/etc/etcd/ssl/ca.pem \
  --peer-client-cert-auth \
  --client-cert-auth
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
 
[Install]
WantedBy=multi-user.target
EOF

将/data/work 目录生成的etcd证书相关文件复制到 /etc/etcd/ssl/

cp ca*.pem /etc/etcd/ssl/
cp etcd*.pem /etc/etcd/ssl/

同步 etcd 配置到集群其它 master 节点

  1. 传送服务配置文件后,需要手动修改 etcd 节点名称及 IP 地址
for i in k8s-master-2 k8s-master-3;do scp /etc/etcd/etcd.conf $i:/etc/etcd/; done;
  1. 传送证书文件
for i in k8s-master-2 k8s-master-3; do scp /etc/etcd/ssl/* $i:/etc/etcd/ssl; done
  1. 传送服务启动配置文件
for i in k8s-master-2 k8s-master-3;do scp /usr/lib/systemd/system/etcd.service $i:/usr/lib/systemd/system/; done
  1. 分别在k8s-master-2、 k8s-master-3 修改配置文件 /etc/etcd/etcd.conf,需要修改以下配置项:
ETCD_NAME: 示例值 etcd2、etcd3
ETCD_LISTEN_PEER_URLS : 其中ip设置为对于本机的ip
ETCD_LISTEN_CLIENT_URLS: 其中ip设置为对于本机的ip
ETCD_INITIAL_ADVERTISE_PEER_URLS:其中ip设置为对于本机的ip
ETCD_ADVERTISE_CLIENT_URLS:其中ip设置为对于本机的ip

启动 etcd 集群(三个 master 节点操作)

systemctl daemon-reload

systemctl enable --now etcd.service

systemctl status etcd

验证和查看etcd集群

验证集群状态
注意修改下面对应ip地址

ETCDCTL_API=3 /usr/local/bin/etcdctl --write-out=table --cacert=/etc/etcd/ssl/ca.pem --cert=/etc/etcd/ssl/etcd.pem --key=/etc/etcd/ssl/etcd-key.pem --endpoints=https://192.168.237.11:2379,https://192.168.237.12:2379,https://192.168.237.13:2379 endpoint health

image-1690341390729

检查etcd数据库性能

ETCDCTL_API=3 /usr/local/bin/etcdctl --write-out=table --cacert=/etc/etcd/ssl/ca.pem --cert=/etc/etcd/ssl/etcd.pem --key=/etc/etcd/ssl/etcd-key.pem --endpoints=https://192.168.237.11:2379,https://192.168.237.12:2379,https://192.168.237.13:2379 check perf

image-1690341971970

ETCDCTL_API=3 /usr/local/bin/etcdctl --write-out=table --cacert=/etc/etcd/ssl/ca.pem --cert=/etc/etcd/ssl/etcd.pem --key=/etc/etcd/ssl/etcd-key.pem --endpoints=https://192.168.237.11:2379,https://192.168.237.12:2379,https://192.168.237.13:2379 member list

image-1690342023594

ETCDCTL_API=3 /usr/local/bin/etcdctl --write-out=table --cacert=/etc/etcd/ssl/ca.pem --cert=/etc/etcd/ssl/etcd.pem --key=/etc/etcd/ssl/etcd-key.pem --endpoints=https://192.168.237.11:2379,https://192.168.237.12:2379,https://192.168.237.13:2379 endpoint status

image-1690342171342

4. 部署Kubernetes 组件

下载二进制安装包

下载地址
下载命令:

wget --no-check-certificate  https://dl.k8s.io/v1.25.12/kubernetes-server-linux-amd64.tar.gz

Kubernetes 软件包安装

tar -zxvf kubernetes-server-linux-amd64.tar.gz 
cd kubernetes/server/bin/
cp kube-apiserver kube-controller-manager kube-scheduler kubectl /usr/local/bin/

软件分发到其他节点

scp kube-apiserver kube-controller-manager kube-scheduler kubectl k8s-master-2:/usr/local/bin/
 
scp kube-apiserver kube-controller-manager kube-scheduler kubectl k8s-master-3:/usr/local/bin/
 
scp kubelet kube-proxy k8s-master-1:/usr/local/bin
 
scp kubelet kube-proxy k8s-master-2:/usr/local/bin
  
scp kubelet kube-proxy k8s-master-3:/usr/local/bin
 
scp kubelet kube-proxy k8s-node-1:/usr/local/bin
  
scp kubelet kube-proxy k8s-node-2:/usr/local/bin

集群节点上创建目录(所有节点)

mkdir -p /etc/kubernetes/ && mkdir -p /etc/kubernetes/ssl && mkdir -p /var/log/kubernetes

部署api-server

API Server 的主要作用和角色如下:

  1. 集群的门户:API Server 是 Kubernetes 集群的主要入口点,负责处理来自用户、管理员和其他组件的 API 请求。它监听集群的 API 端点,并验证和处理传入的请求。
  2. 集群管理:API Server 用于管理和控制整个 Kubernetes 集群。它维护集群的状态、配置信息和元数据,并提供了一组 API 端点,用于创建、更新和删除各种 Kubernetes 资源,例如 Pod、Service、Deployment 等。
  3. 认证和授权:API Server 负责认证和授权来自用户和其他组件的请求。它验证用户身份并执行访问控制,以确保只有经过授权的用户才能执行相应的操作。
  4. 资源调度:API Server 接收来自调度器的请求,并将 Pod 调度到集群中的节点上。它通过与调度器进行交互,确保将 Pod 分配给适当的节点,并监控节点的健康状态。
  5. 事件和日志记录:API Server 负责记录集群中发生的事件和操作。它生成事件,记录集群中的状态变化,并提供接口以获取日志和审计信息,方便故障排除和监控。
  6. 扩展性和自定义:API Server 提供了一种扩展机制,使用户和开发人员能够自定义和扩展 Kubernetes 的功能。通过自定义资源定义 (Custom Resource Definitions, CRDs),API Server 可以支持用户自定义的资源类型和相应的操作。

创建 api-server 证书请求文件

# 当前目录是在 /data/work
pwd

创建kube-apiserver-csr.json,其中其他的ip是预留扩容的ip。还需要填写 service 网络的首个 IP(一般是 kube-apiserver 指定的 service-cluster-ip-range 网段的第一个 IP,如 10.255.0.1)

cat > kube-apiserver-csr.json << "EOF"
{
"CN": "kubernetes",
  "hosts": [
    "127.0.0.1",
    "192.168.237.11",
    "192.168.237.12",
    "192.168.237.13",
    "192.168.237.14",
    "192.168.237.15",
    "192.168.237.19",
    "192.168.237.20",
    "192.168.237.21",
    "10.255.0.1",
    "kubernetes",
    "kubernetes.default",
    "kubernetes.default.svc",
    "kubernetes.default.svc.cluster",
    "kubernetes.default.svc.cluster.local"
  ],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Ningbo",
      "L": "Zhejiang",
      "O": "k8s",
      "OU": "system"
    }
  ]
}
EOF

生成 api-server 证书及 token 文件

cat > token.csv << EOF
$(head -c 16 /dev/urandom | od -An -t x | tr -d ' '),kubelet-bootstrap,10001,"system:kubelet-bootstrap"
EOF

生成证书

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-apiserver-csr.json | cfssljson -bare kube-apiserver

创建 api-server 服务配置文件

注意修改下面的bind-address、advertise-address、etcd-servers等配置

cat > /etc/kubernetes/kube-apiserver.conf << "EOF"
KUBE_APISERVER_OPTS="--enable-admission-plugins=NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \
  --anonymous-auth=false \
  --bind-address=192.168.237.11 \
  --secure-port=6443 \
  --advertise-address=192.168.237.11 \
  --authorization-mode=Node,RBAC \
  --runtime-config=api/all=true \
  --enable-bootstrap-token-auth \
  --service-cluster-ip-range=10.255.0.0/16 \
  --token-auth-file=/etc/kubernetes/token.csv \
  --service-node-port-range=30000-32767 \
  --tls-cert-file=/etc/kubernetes/ssl/kube-apiserver.pem  \
  --tls-private-key-file=/etc/kubernetes/ssl/kube-apiserver-key.pem \
  --client-ca-file=/etc/kubernetes/ssl/ca.pem \
  --kubelet-client-certificate=/etc/kubernetes/ssl/kube-apiserver.pem \
  --kubelet-client-key=/etc/kubernetes/ssl/kube-apiserver-key.pem \
  --service-account-key-file=/etc/kubernetes/ssl/ca-key.pem \
  --service-account-signing-key-file=/etc/kubernetes/ssl/ca-key.pem  \
  --service-account-issuer=api \
  --etcd-cafile=/etc/etcd/ssl/ca.pem \
  --etcd-certfile=/etc/etcd/ssl/etcd.pem \
  --etcd-keyfile=/etc/etcd/ssl/etcd-key.pem \
  --etcd-servers=https://192.168.237.11:2379,https://192.168.237.12:2379,https://192.168.237.13:2379 \
  --allow-privileged=true \
  --apiserver-count=3 \
  --audit-log-maxage=30 \
  --audit-log-maxbackup=3 \
  --audit-log-maxsize=100 \
  --audit-log-path=/var/log/kube-apiserver-audit.log \
  --event-ttl=1h \
  --alsologtostderr=true \
  --logtostderr=false \
  --log-dir=/var/log/kubernetes \
  --v=4"
EOF

创建 api-server 服务管理配置文件

cat > /usr/lib/systemd/system/kube-apiserver.service << "EOF"
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
After=etcd.service
Wants=etcd.service
 
[Service]
EnvironmentFile=-/etc/kubernetes/kube-apiserver.conf
ExecStart=/usr/local/bin/kube-apiserver $KUBE_APISERVER_OPTS
Restart=on-failure
RestartSec=5
Type=notify
LimitNOFILE=65536
 
[Install]
WantedBy=multi-user.target
EOF

同步api-server配置文件到集群 其他master 节点

cp ca*.pem /etc/kubernetes/ssl/
cp kube-apiserver*.pem /etc/kubernetes/ssl/
cp token.csv /etc/kubernetes/
 
scp /etc/kubernetes/token.csv k8s-master-2:/etc/kubernetes  
scp /etc/kubernetes/token.csv k8s-master-3:/etc/kubernetes
  
scp /etc/kubernetes/ssl/kube-apiserver*.pem k8s-master-2:/etc/kubernetes/ssl   
scp /etc/kubernetes/ssl/kube-apiserver*.pem k8s-master-3:/etc/kubernetes/ssl
 
scp /etc/kubernetes/ssl/ca*.pem k8s-master-2:/etc/kubernetes/ssl
scp /etc/kubernetes/ssl/ca*.pem k8s-master-3:/etc/kubernetes/ssl
 
scp /etc/kubernetes/kube-apiserver.conf k8s-master-2:/etc/kubernetes/
scp /etc/kubernetes/kube-apiserver.conf k8s-master-3:/etc/kubernetes/
 
scp /usr/lib/systemd/system/kube-apiserver.service k8s-master-2:/usr/lib/systemd/system/
scp /usr/lib/systemd/system/kube-apiserver.service k8s-master-3:/usr/lib/systemd/system/

注意: k8s-master-2 和 k8s-master-3 的配置文件 /etc/kubernetes/kube-apiserver.conf 中的 IP 地址需要修改为实际的本机 IP

启动 api-server 服务

systemctl daemon-reload
systemctl enable --now kube-apiserver
systemctl status kube-apiserver

测试

curl --insecure https://192.168.237.11:6443/
curl --insecure https://192.168.237.12:6443/
curl --insecure https://192.168.237.13:6443/

结果显示 401 是正常状态
image-1690358146596

部署 kubectl

kubectl 是 Kubernetes 集群的命令行工具,用于与集群进行交互和管理。它是 Kubernetes 原生的命令行接口,提供了丰富的功能,可以用于部署和管理应用程序、监控集群状态、调试容器等。

使用 kubectl,你可以执行各种操作,包括创建、删除和修改 Kubernetes 对象,如 Pods、Deployments、Services 和 ConfigMaps。你可以使用 kubectl 查看集群中的资源状态,检索日志和事件,以及执行故障排除操作。

kubectl 还支持进行扩展,通过插件可以添加自定义命令和功能。它具有丰富的选项和参数,可用于适应各种场景和需求。

总的来说,kubectl 是一个强大的命令行工具,用于管理和操作 Kubernetes 集群,帮助开发人员和运维人员更方便地进行容器化应用程序的部署和管理。

创建 kubectl 证书请求文件

目录: /data/work

cat > admin-csr.json << "EOF"
{
  "CN": "admin",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Zhejiang",
      "L": "Ningbo",
      "O": "system:masters", 
      "OU": "system"
    }
  ]
}
EOF

生成证书文件

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes admin-csr.json | cfssljson -bare admin

复制到ssl目录

cp admin*.pem /etc/kubernetes/ssl/

生成 kubeconfig 配置文件

kubeconfig 为 kubectl 的配置文件,包含访问 apiserver 的所有信息,如 apiserver 地址、CA 证书和自身使用的证书(这里如果报错找不到 kubeconfig 路径,请手动复制到相应路径下,没有则忽略)。
目录: /data/work/
设置集群参数

kubectl config set-cluster kubernetes --certificate-authority=ca.pem --embed-certs=true --server=https://192.168.237.11:6443 --kubeconfig=kube.config

设置客户端认证参数

kubectl config set-credentials admin --client-certificate=admin.pem --client-key=admin-key.pem --embed-certs=true --kubeconfig=kube.config

设置上下文参数

kubectl config set-context kubernetes --cluster=kubernetes --user=admin --kubeconfig=kube.config

设置当前上下文

kubectl config use-context kubernetes --kubeconfig=kube.config

准备 kubectl 配置文件并进行角色绑定

mkdir ~/.kube
cp kube.config ~/.kube/config

授权 kubernetes 证书访问 kubelet api 权限

kubectl create clusterrolebinding kube-apiserver:kubelet-apis --clusterrole=system:kubelet-api-admin --user kubernetes --kubeconfig=/root/.kube/config

查看集群状态

查看集群信息

kubectl cluster-info 

image-1690361232348

查看集群组件状态

kubectl get componentstatuses

image-1690361276516

查看命名空间中资源对象
image-1690361317493

同步 kubectl 配置文件到集群其它 master 节点

k8s-master-2 、k8s-master-3 都执行

mkdir /root/.kube

k8s-master-1 执行

scp /root/.kube/config k8s-master-2:/root/.kube/
scp /root/.kube/config k8s-master-3/root/.kube/

配置 kubectl 命令补全(可选)

注意:在三个 master 节点上执行
在 bash 中设置当前 shell 的自动补全,要先安装 bash-completion 包

yum install -y bash-completion
source /usr/share/bash-completion/bash_completion

在你的 bash shell 中永久地添加自动补全

source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc

部署kube-controller-manager

Kubernetes Controller Manager是Kubernetes集群的核心组件之一,负责管理和运行各种控制器(Controllers),以确保集群中的各个资源处于所需的状态。

Kubernetes中的控制器是一种通过不断地监视集群状态并采取相应措施来实现所需状态的自动化组件。kube-controller-manager运行多个内置控制器,这些控制器负责处理各种核心资源,例如Pod、Service、ReplicaSet、Deployment等。

kube-controller-manager的主要职责包括以下几个方面:

  1. Node Controller:监视集群中的节点(Node)状态,并采取相应的措施,确保节点正常运行。如果节点宕机或不可达,Node Controller将负责重调度(reschedule)该节点上运行的Pod,以确保服务的高可用性。

  2. Replication Controller(现已被ReplicaSet取代):确保集群中指定数量的Pod副本保持运行。当Pod副本数不足或超过指定的副本数时,Replication Controller将自动创建或删除Pod,以使副本数保持一致。

  3. Endpoints Controller:根据Service和相关的Pod状态,自动生成Endpoints资源,用于实现Service和Pod之间的连接。

  4. Namespace Controller:负责创建和删除Namespace,它是用于隔离和组织资源的逻辑分组。

  5. Service Account & Token Controllers:负责为新Namespace创建默认Service Account,并为每个Service Account生成对应的身份验证Token。

  6. Persistent Volume Controllers:监视Persistent Volume(PV)和Persistent Volume Claim(PVC)资源,并确保它们的状态匹配。如果PVC请求的存储资源可用,则Persistent Volume Controller将绑定PVC和PV。

  7. DaemonSet Controller:负责确保在集群中的每个节点上运行一个副本的DaemonSet类型的Pod。

  8. Job Controller:用于创建和管理一次性任务(One-time Job)的控制器。

除了上述内置控制器外,kube-controller-manager还可以通过自定义控制器(Custom Controller)进行扩展,以满足特定场景下的需求。

总而言之,kube-controller-manager是Kubernetes集群中负责管理和运行各种控制器的组件,通过监视集群状态并采取相应措施,确保集群中资源的期望状态得以实现。

创建 kube-controller-manager 证书请求文件

目录:/data/work

cat > kube-controller-manager-csr.json << "EOF"
{
    "CN": "system:kube-controller-manager",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "hosts": [
      "127.0.0.1",
      "192.168.237.11",
      "192.168.237.12",
      "192.168.237.13",
      "192.168.237.19"
    ],
    "names": [
      {
        "C": "CN",
        "ST": "Zhejiang",
        "L": "Ningbo",
        "O": "system:kube-controller-manager",
        "OU": "system"
      }
    ]
}
EOF

创建 kube-controller-manager 证书文件

目录:/data/work

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-controller-manager-csr.json | cfssljson -bare kube-controller-manager

创建 kube-controller-manager 的 kube-controller-manager.kubeconfig

目录:/data/work

# 设置集群参数
kubectl config set-cluster kubernetes --certificate-authority=ca.pem --embed-certs=true --server=https://192.168.237.11:6443 --kubeconfig=kube-controller-manager.kubeconfig
 
# 设置客户端认证参数
kubectl config set-credentials system:kube-controller-manager --client-certificate=kube-controller-manager.pem --client-key=kube-controller-manager-key.pem --embed-certs=true --kubeconfig=kube-controller-manager.kubeconfig
 
# 设置上下文参数
kubectl config set-context system:kube-controller-manager --cluster=kubernetes --user=system:kube-controller-manager --kubeconfig=kube-controller-manager.kubeconfig
 
# 设置当前上下文
kubectl config use-context system:kube-controller-manager --kubeconfig=kube-controller-manager.kubeconfig

创建 kube-controller-manager 配置文件

目录:/data/work

cat > kube-controller-manager.conf << "EOF"
KUBE_CONTROLLER_MANAGER_OPTS=" \
  --secure-port=10257 \
  --bind-address=127.0.0.1 \
  --kubeconfig=/etc/kubernetes/kube-controller-manager.kubeconfig \
  --service-cluster-ip-range=10.255.0.0/16 \
  --cluster-name=kubernetes \
  --cluster-signing-cert-file=/etc/kubernetes/ssl/ca.pem \
  --cluster-signing-key-file=/etc/kubernetes/ssl/ca-key.pem \
  --allocate-node-cidrs=true \
  --cluster-cidr=10.0.0.0/16 \
  --root-ca-file=/etc/kubernetes/ssl/ca.pem \
  --service-account-private-key-file=/etc/kubernetes/ssl/ca-key.pem \
  --leader-elect=true \
  --feature-gates=RotateKubeletServerCertificate=true \
  --controllers=*,bootstrapsigner,tokencleaner \
  --horizontal-pod-autoscaler-sync-period=10s \
  --tls-cert-file=/etc/kubernetes/ssl/kube-controller-manager.pem \
  --tls-private-key-file=/etc/kubernetes/ssl/kube-controller-manager-key.pem \
  --use-service-account-credentials=true \
  --alsologtostderr=true \
  --logtostderr=false \
  --log-dir=/var/log/kubernetes \
  --v=2"
EOF

创建服务启动文件

目录:/data/work

cat > /usr/lib/systemd/system/kube-controller-manager.service << "EOF"
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/kubernetes/kubernetes
 
[Service]
EnvironmentFile=-/etc/kubernetes/kube-controller-manager.conf
ExecStart=/usr/local/bin/kube-controller-manager $KUBE_CONTROLLER_MANAGER_OPTS
Restart=on-failure
RestartSec=5
 
[Install]
WantedBy=multi-user.target
EOF

同步文件到集群 其他master 节点

cp kube-controller-manager*.pem /etc/kubernetes/ssl/

cp kube-controller-manager.kubeconfig /etc/kubernetes/

cp kube-controller-manager.conf /etc/kubernetes/
 
scp  kube-controller-manager*.pem k8s-master-2:/etc/kubernetes/ssl/

scp  kube-controller-manager*.pem k8s-master-3:/etc/kubernetes/ssl/
 
scp  kube-controller-manager.kubeconfig kube-controller-manager.conf k8s-master-2:/etc/kubernetes/

scp  kube-controller-manager.kubeconfig kube-controller-manager.conf k8s-master-3:/etc/kubernetes/
 
scp  /usr/lib/systemd/system/kube-controller-manager.service k8s-master-2:/usr/lib/systemd/system/

scp  /usr/lib/systemd/system/kube-controller-manager.service k8s-master-3:/usr/lib/systemd/system/

启动服务(三个 master 执行)

systemctl daemon-reload
systemctl enable --now kube-controller-manager
systemctl status kube-controller-manager

kubectl get componentstatuses

结果如下:
image-1690423434286

部署 kube-scheduler

Kubernetes的Scheduler(调度器)是一个用于自动决定将Pods调度到哪个节点上运行的组件。它在Kubernetes集群中起着关键的作用,帮助实现负载均衡、高可用性和资源利用的最大化。调度器负责根据配置和条件将Pods分配给节点,并考虑节点资源、亲和性和反亲和性规则、Pod的资源需求和限制等因素。

Kubernetes的调度器具有以下主要功能:

  1. 节点选择:调度器会评估集群中所有可用节点的资源使用情况,包括CPU、内存、存储等,并根据Pod的资源需求选择最适合的节点。这有助于确保节点资源的平衡和合理利用。

  2. 亲和性和反亲和性:调度器支持亲和性和反亲和性规则,用于指定Pod与节点之间的关系。亲和性规则可以将Pod调度到与特定标签匹配的节点上,而反亲和性规则可以防止Pod与某些节点共存。这有助于提供更好的性能和灵活性。

  3. 资源需求和限制:调度器会考虑Pod的资源需求和限制,如CPU和内存。它会与节点的资源容量进行比较,并确保Pod可以在满足其需求的节点上运行,以防止资源冲突和过度占用。

  4. 故障恢复和高可用性:调度器会监测节点的健康状态,并在节点故障或不可用时重新调度受影响的Pods到其他可用节点上,以确保应用程序的高可用性和容错能力。

Kubernetes的调度器是一个可插拔的组件,可以根据需要进行自定义和扩展。用户可以编写自定义调度器,实现特定的调度策略和算法。此外,Kubernetes社区还提供了一些调度器插件,如Predicates和Priority Functions,用于更精细地控制Pod的调度过程。

总结:Kubernetes的调度器是一个关键组件,负责将Pods调度到合适的节点上运行。它考虑节点资源、亲和性和反亲和性规则、Pod的资源需求和限制等因素,并实现负载均衡、高可用性和资源利用的最大化。调度器可以被自定义和扩展,以满足特定的调度需求。

创建 kube-scheduler 证书请求文件

目录:/data/work

cat > kube-scheduler-csr.json << "EOF"
{
    "CN": "system:kube-scheduler",
    "hosts": [
      "127.0.0.1",
      "192.168.237.11",
      "192.168.237.12",
      "192.168.237.13",
      "192.168.237.19"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
      {
        "C": "CN",
        "ST": "Zhejiang",
        "L": "Ningbo",
        "O": "system:kube-scheduler",
        "OU": "system"
      }
    ]
}
EOF

生成 kube-scheduler 证书

目录:/data/work

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-scheduler-csr.json | cfssljson -bare kube-scheduler

创建 kube-scheduler 的 kubeconfig

# 设置集群参数
kubectl config set-cluster kubernetes --certificate-authority=ca.pem --embed-certs=true --server=https://192.168.237.11:6443 --kubeconfig=kube-scheduler.kubeconfig
 
# 设置客户端认证参数
kubectl config set-credentials system:kube-scheduler --client-certificate=kube-scheduler.pem --client-key=kube-scheduler-key.pem --embed-certs=true --kubeconfig=kube-scheduler.kubeconfig
 
# 设置上下文参数
kubectl config set-context system:kube-scheduler --cluster=kubernetes --user=system:kube-scheduler --kubeconfig=kube-scheduler.kubeconfig
 
# 设置当前上下文
kubectl config use-context system:kube-scheduler --kubeconfig=kube-scheduler.kubeconfig

创建服务配置文件

cat > kube-scheduler.conf << "EOF"
KUBE_SCHEDULER_OPTS=" \
--kubeconfig=/etc/kubernetes/kube-scheduler.kubeconfig \
--leader-elect=true \
--alsologtostderr=true \
--logtostderr=false \
--log-dir=/var/log/kubernetes \
--v=2"
EOF

创建服务启动配置文件

cat > /usr/lib/systemd/system/kube-scheduler.service << "EOF"
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/kubernetes/kubernetes
 
[Service]
EnvironmentFile=-/etc/kubernetes/kube-scheduler.conf
ExecStart=/usr/local/bin/kube-scheduler $KUBE_SCHEDULER_OPTS
Restart=on-failure
RestartSec=5
 
[Install]
WantedBy=multi-user.target
EOF

同步文件至集群 master 节点

cp kube-scheduler*.pem /etc/kubernetes/ssl/

cp kube-scheduler.kubeconfig /etc/kubernetes/

cp kube-scheduler.conf /etc/kubernetes/
 
scp  kube-scheduler*.pem k8s-master-2:/etc/kubernetes/ssl/

scp  kube-scheduler*.pem k8s-master-3:/etc/kubernetes/ssl/
 
scp  kube-scheduler.kubeconfig kube-scheduler.conf k8s-master-2:/etc/kubernetes/

scp  kube-scheduler.kubeconfig kube-scheduler.conf k8s-master-3:/etc/kubernetes/
 
scp  /usr/lib/systemd/system/kube-scheduler.service k8s-master-2:/usr/lib/systemd/system/

scp  /usr/lib/systemd/system/kube-scheduler.service k8s-master-3:/usr/lib/systemd/system/

启动服务(三个 master 执行)

systemctl daemon-reload

systemctl enable --now kube-scheduler

systemctl status kube-scheduler
 
kubectl get componentstatuses

工作节点(worker node)部署

部署 kubelet(在 k8s-master-1 上操作)

kubelet:每个 Node 节点上的 kubelet 定期就会调用 API Server 的 REST 接口报告自身状态,API Server 接收这些信息后,将节点状态信息更新到 etcd 中。kubelet 也通过 API Server 监听 Pod 信息,从而对 Node 机器上的 POD 进行管理,如创建、删除、更新 Pod。

创建 kubelet-bootstrap.kubeconfig

目录:/data/work/

BOOTSTRAP_TOKEN=$(awk -F "," '{print $1}' /etc/kubernetes/token.csv)
 
kubectl config set-cluster kubernetes --certificate-authority=ca.pem --embed-certs=true --server=https://192.168.237.11:6443 --kubeconfig=kubelet-bootstrap.kubeconfig
 
kubectl config set-credentials kubelet-bootstrap --token=${BOOTSTRAP_TOKEN} --kubeconfig=kubelet-bootstrap.kubeconfig
 
kubectl config set-context default --cluster=kubernetes --user=kubelet-bootstrap --kubeconfig=kubelet-bootstrap.kubeconfig
 
kubectl config use-context default --kubeconfig=kubelet-bootstrap.kubeconfig
 
# 添加权限
kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --user=kubelet-bootstrap

创建 kubelet 配置文件

cat > kubelet.json << "EOF"
{
  "kind": "KubeletConfiguration",
  "apiVersion": "kubelet.config.k8s.io/v1beta1",
  "authentication": {
    "x509": {
      "clientCAFile": "/etc/kubernetes/ssl/ca.pem"
    },
    "webhook": {
      "enabled": true,
      "cacheTTL": "2m0s"
    },
    "anonymous": {
      "enabled": false
    }
  },
  "authorization": {
    "mode": "Webhook",
    "webhook": {
      "cacheAuthorizedTTL": "5m0s",
      "cacheUnauthorizedTTL": "30s"
    }
  },
  "address": "192.168.237.11",
  "port": 10250,
  "readOnlyPort": 10255,
  "cgroupDriver": "systemd",                    
  "hairpinMode": "promiscuous-bridge",
  "serializeImagePulls": false,
  "clusterDomain": "cluster.local.",
  "clusterDNS": ["10.255.0.2"]
}
EOF

创建 kubelet 服务启动管理文件

kubelet 配置官方文档:kubelet | Kubernetes

cat > /usr/lib/systemd/system/kubelet.service << "EOF"
[Unit]
Description=Kubernetes Kubelet
Documentation=https://github.com/kubernetes/kubernetes
After=docker.service
Requires=docker.service
 
[Service]
WorkingDirectory=/var/lib/kubelet
ExecStart=/usr/local/bin/kubelet \
  --bootstrap-kubeconfig=/etc/kubernetes/kubelet-bootstrap.kubeconfig \
  --cert-dir=/etc/kubernetes/ssl \
  --kubeconfig=/etc/kubernetes/kubelet.kubeconfig \
  --config=/etc/kubernetes/kubelet.json \
  --container-runtime-endpoint=unix:///run/containerd/containerd.sock \
  --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.2 \
  --alsologtostderr=true \
  --logtostderr=false \
  --log-dir=/var/log/kubernetes \
  --v=2
Restart=on-failure
RestartSec=5
 
[Install]
WantedBy=multi-user.target
EOF

同步文件到集群节点

如果不想 master 节点也安装 kubelet 组件,可以只给 node 节点传送文件,只在 node 节点安装。

cp kubelet-bootstrap.kubeconfig kubelet.json /etc/kubernetes/
 
for i in  k8s-master-2 k8s-master-3 k8s-node-1 k8s-node-2;do scp /etc/kubernetes/kubelet-bootstrap.kubeconfig /etc/kubernetes/kubelet.json $i:/etc/kubernetes/;done
 
for i in  k8s-master-2 k8s-master-3 k8s-node-1 k8s-node-2;do scp ca.pem $i:/etc/kubernetes/ssl/;done
 
for i in k8s-master-2 k8s-master-3 k8s-node-1 k8s-node-2;do scp /usr/lib/systemd/system/kubelet.service $i:/usr/lib/systemd/system/;done

注意: /etc/kubernetes/kubelet.json 中 address 需要修改为当前主机 IP 地址

创建目录及启动服务(所有节点执行)

mkdir -p /var/lib/kubelet
 
systemctl daemon-reload

systemctl enable --now kubelet

systemctl status kubelet

注意:kubelet错误,是因为swap功能未关闭导致的,如下错误:

[root@k8s-master-1 work]# systemctl status kubelet
● kubelet.service - Kubernetes Kubelet
   Loaded: loaded (/usr/lib/systemd/system/kubelet.service; enabled; vendor preset: disabled)
   Active: activating (auto-restart) (Result: exit-code) since Thu 2023-07-27 11:16:37 CST; 476ms ago
     Docs: https://github.com/kubernetes/kubernetes
  Process: 91532 ExecStart=/usr/local/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/kubelet-bootstrap.kubeconfig --cert-dir=/etc/kubernetes/ssl --kubeconfig=/etc/kubernetes/kubelet.kubeconfig --config=/etc/kubernetes/kubelet.json --container-runtime-endpoint=unix:///run/containerd/containerd.sock --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.2 --alsologtostderr=true --logtostderr=false --log-dir=/var/log/kubernetes --v=2 (code=exited, status=1/FAILURE)
 Main PID: 91532 (code=exited, status=1/FAILURE)

Jul 27 11:16:37 k8s-master-1 kubelet[91532]: I0727 11:16:37.786218   91532 state_mem.go:36] "Initialized new in-memory state store"
Jul 27 11:16:37 k8s-master-1 kubelet[91532]: I0727 11:16:37.789673   91532 remote_runtime.go:142] "Falling back to CRI v1alpha2 runtime API (deprecated)"
Jul 27 11:16:37 k8s-master-1 kubelet[91532]: I0727 11:16:37.791858   91532 remote_image.go:98] "Falling back to CRI v1alpha2 image API (deprecated)"
Jul 27 11:16:37 k8s-master-1 kubelet[91532]: I0727 11:16:37.791933   91532 server.go:1136] "Using root directory" path="/var/lib/kubelet"
Jul 27 11:16:37 k8s-master-1 kubelet[91532]: I0727 11:16:37.792085   91532 kubelet.go:381] "Attempting to sync node with API server"
Jul 27 11:16:37 k8s-master-1 kubelet[91532]: I0727 11:16:37.792117   91532 kubelet.go:281] "Adding apiserver pod source"
Jul 27 11:16:37 k8s-master-1 kubelet[91532]: I0727 11:16:37.792145   91532 apiserver.go:42] "Waiting for node sync before watching apiserver pods"
Jul 27 11:16:37 k8s-master-1 kubelet[91532]: E0727 11:16:37.799811   91532 remote_runtime.go:189] "Version from runtime service failed" err="rpc error: code = Unimplemented desc = unknown service runtime.v1alpha2.RuntimeService"
Jul 27 11:16:37 k8s-master-1 kubelet[91532]: E0727 11:16:37.808605   91532 kuberuntime_manager.go:226] "Get runtime version failed" err="get remote runtime typed version failed: rpc error: code = Unimplemented desc = unkn...2.RuntimeService"
Jul 27 11:16:37 k8s-master-1 kubelet[91532]: E0727 11:16:37.816847   91532 run.go:74] "command failed" err="failed to run Kubelet: failed to create kubelet: get remote runtime typed version failed: rpc error: code = Unimp...2.RuntimeService"
Hint: Some lines were ellipsized, use -l to show in full.

swap问题解决如下:

swapoff -a

vim /etc/fstab

image-1690428077839

重启并且查看进程状态

systemctl restart kubelet
systemctl status kubelet

image-1690436502629

此问题还需继续进行处理,修改containerd配置文件:
停止所有主机containerd

systemctl stop containerd

备份删除全部主机的containerd配置文件: /etc/containerd/config.toml

mv /etc/containerd/config.toml /root/config.toml.bak

重新生成默认配置,除了以下配置 还需要修改两项配置,请回看上面containerd的部署

containerd config default > /etc/containerd/config.toml

修改配置文件的SystemdCgroup = false 修改成 SystemdCgroup = true

vim  /etc/containerd/config.toml

全部主机重启containerd

systemctl daemon-reload

systemctl restart containerd

查看containerd状态

 systemctl status containerd

全部主机重启kubelet

systemctl daemon-reload

systemctl restart kubelet

验证集群状态

k8s-master-1执行

kubectl get csr

各节点发送了 CSR 请求,如果状态是 Pending,则需要 Approve 一下 bootstrap 请求:
image-1690442643353

approve 方法: master-1节点执行

kubectl certificate approve  node-csr-6fKv5hlunBTuBv0E0lHsaX_F57X2DeyYT5UFGRPCXq8
kubectl certificate approve  node-csr-80PM9xFFCP7a8oPv70CA8PP2lknEXiqsEaLcuwK6I1Y
kubectl certificate approve  node-csr-Dcw_5w6yGXC0wHBepZAZGS5ORZh_0W-yrTaajB7Rnu8
kubectl certificate approve  node-csr-IZ2spuQUZYwaOEH8sBsTJiIDiI_PWpSe1kplytAnEv4
kubectl certificate approve  node-csr-YJArXOpU3m1criEFuATHJ5KOpKYoHIDaIsuyNgpuWkE

再次查看状态是否变为 Approved,Issued

kubectl get csr

image-1690443422496

备注:如果 kubectl get csr 命令报错:No resources found ;请cd到/etc/kubernetes/ssl目录,在全部主机上执行 rm -rf kubelet* 命令,之后停止全部主机kubelet进程,然后在k8s-master-1主机上执行以下命令:

kubectl delete clusterrolebinding kubelet-bootstrap clusterrolebinding.rbac.authorization.k8s.io "kubelet-bootstrap" deleted
BOOTSTRAP_TOKEN=$(awk -F "," '{print $1}' /etc/kubernetes/token.csv)

kubectl config set-cluster kubernetes --certificate-authority=ca.pem --embed-certs=true --server=https://192.168.237.11:6443 --kubeconfig=kubelet-bootstrap.kubeconfig

kubectl config set-credentials kubelet-bootstrap --token=${BOOTSTRAP_TOKEN} --kubeconfig=kubelet-bootstrap.kubeconfig

kubectl config set-context default --cluster=kubernetes --user=kubelet-bootstrap --kubeconfig=kubelet-bootstrap.kubeconfig

kubectl config use-context default --kubeconfig=kubelet-bootstrap.kubeconfig

kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --user=kubelet-bootstrap
# 最后重启  所有主机
 systemctl daemon-reload
 systemctl restart kubelet
  systemctl status kubelet

查看集群中的所有节点的状态信息命令

kubectl get nodes

image-1690443455747

再次查看状态是否变为 Approved,Issued

kubectl get csr

approve 方法: master-1节点执行

kubectl certificate approve  node-csr-xxx

再次查看状态是否变为 Approved,Issued

kubectl get csr

image-1691724340298

部署 kube-proxy

Kube-proxy 是 Kubernetes 集群中的一个核心组件,它负责实现 Kubernetes Service 的网络代理功能。Kubernetes Service 是一种抽象的逻辑概念,用于暴露应用程序的网络服务。Kube-proxy 的主要目标是为 Service 提供服务发现和负载均衡功能。

Kube-proxy 运行在每个节点上,并监视 Kubernetes 集群中的 Service 和 Endpoint 资源的变化。Service 定义了一组 Pod 的逻辑分组,而 Endpoint 则表示提供该服务的实际 Pod 的集合。Kube-proxy 通过监听 Kubernetes API Server 中的 Service 和 Endpoint 资源的变化,自动更新本地代理规则,以确保流量能够正确地路由到相应的 Pod 上。

Kube-proxy 支持三种代理模式:

  1. Userspace(用户空间)模式:在此模式下,Kube-proxy 通过在每个节点上创建一组用户空间进程来接收网络请求,并使用 iptables 规则将流量转发到相应的 Pod 上。这种模式对于较老的内核版本和网络环境较差的情况下比较适用,但性能相对较低。

  2. iptables 模式:在此模式下,Kube-proxy 通过 iptables 规则将流量转发到相应的 Pod 上。这种模式利用了 Linux 内核的 iptables 功能,可以实现高性能的数据包转发。但是,当 Service 数量较多时,iptables 规则的管理会变得复杂。

  3. IPVS(IP Virtual Server)模式:这是 Kube-proxy 的推荐模式。IPVS 是 Linux 内核的一种高性能负载均衡技术,它可以实现快速而可靠的流量转发。在 IPVS 模式下,Kube-proxy 利用 IPVS 功能创建虚拟服务,并根据 Service 和 Endpoint 的变化动态调整负载均衡策略。这种模式在大规模集群和高并发负载下表现出色。

总的来说,Kube-proxy 是 Kubernetes 集群中负责实现 Service 的网络代理功能的重要组件。它通过监听 Kubernetes API Server 中的资源变化,自动更新代理规则,实现流量的路由和负载均衡。根据不同的需求,Kube-proxy 提供了不同的代理模式,其中 IPVS 模式被广泛认可为最佳实践。


创建 kube-proxy 证书请求文件

目录: /data/work/

cat > kube-proxy-csr.json << "EOF"
{
  "CN": "system:kube-proxy",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Zhejiang",
      "L": "Ningbo",
      "O": "k8s",
      "OU": "system"
    }
  ]
}
EOF

生成证书

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy

创建 kubeconfig 文件

kubectl config set-cluster kubernetes --certificate-authority=ca.pem --embed-certs=true --server=https://192.168.237.11:6443 --kubeconfig=kube-proxy.kubeconfig
 
kubectl config set-credentials kube-proxy --client-certificate=kube-proxy.pem --client-key=kube-proxy-key.pem --embed-certs=true --kubeconfig=kube-proxy.kubeconfig
 
kubectl config set-context default --cluster=kubernetes --user=kube-proxy --kubeconfig=kube-proxy.kubeconfig
 
kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig

创建服务配置文件

cat > kube-proxy.yaml << "EOF"
apiVersion: kubeproxy.config.k8s.io/v1alpha1
bindAddress: 192.168.237.11
clientConnection:
  kubeconfig: /etc/kubernetes/kube-proxy.kubeconfig
clusterCIDR: 192.168.237.0/24
healthzBindAddress: 192.168.237.11:10256
kind: KubeProxyConfiguration
metricsBindAddress: 192.168.237.11:10249
mode: "ipvs"
EOF

创建服务启动管理文件

cat > /usr/lib/systemd/system/kube-proxy.service << "EOF"
[Unit]
Description=Kubernetes Kube-Proxy Server
Documentation=https://github.com/kubernetes/kubernetes
After=network.target
 
[Service]
WorkingDirectory=/var/lib/kube-proxy
ExecStart=/usr/local/bin/kube-proxy \
  --config=/etc/kubernetes/kube-proxy.yaml \
  --alsologtostderr=true \
  --logtostderr=false \
  --log-dir=/var/log/kubernetes \
  --v=2
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
 
[Install]
WantedBy=multi-user.target
EOF

同步文件到集群节点

cp kube-proxy*.pem /etc/kubernetes/ssl/

cp kube-proxy.kubeconfig kube-proxy.yaml /etc/kubernetes/
 
for i in k8s-master-2 k8s-master-3 k8s-node-1 k8s-node-2;do scp kube-proxy.kubeconfig kube-proxy.yaml $i:/etc/kubernetes/;done
 
for i in k8s-master-2 k8s-master-3 k8s-node-1 k8s-node-2;do scp  /usr/lib/systemd/system/kube-proxy.service $i:/usr/lib/systemd/system/;done

注意:传送后需要手动修改 /etc/kubernetes
/kube-proxy.yaml 中三个 Address IP 地址为当前主机 IP

服务启动(所有节点)

mkdir -p /var/lib/kube-proxy
 
systemctl daemon-reload

systemctl enable --now kube-proxy

systemctl status kube-proxy

网络组件部署 Calico

查看各版本Calico与k8s适配版本,此处以Calico3.24为例

下载 calico.yaml

目录: /data/work/

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

修改 calico.yaml 里的 pod 网段

操作如下GIF
calico_pod_net
分发calico.yaml 配置文件

for i in k8s-master-2 k8s-master-3 k8s-node-1 k8s-node-2;do scp calico.yaml $i:/data/work/;done

安装 calico

grep image calico.yaml

提前安装镜像, 如果有镜像下载慢情况:请看前面配置containerd镜像加速内容

for i in docker.io/calico/cni:v3.24.5 docker.io/calico/node:v3.24.5 docker.io/calico/kube-controllers:v3.24.5 ; do ctr -n=k8s.io images pull --hosts-dir "/etc/containerd/certs.d" $i ; done

所有master节点执行

kubectl apply -f calico.yaml
kubectl get pods -A

结果如下
image-1691736201279

排错方案

备注: 如果你的node 不是Running状态,排查思路如下:

(1) 查看所有节点的关于k8s进程状态:如 kube-proxy、kubelet 运行状态如何

systemctl status kube-proxy
systemctl status kubelet

(2)查看异常node的信息,有如下两种方法,其中参数-n和–namespce是指查看指定命名空间的意思,如下:

# master节点执行
kubectl logs -f node-name-xxx --namespace kube-system
kubectl describe pod node-name-xxx  -n kube-system

部署 CoreDNS

下载coredns.yaml

点击我下载

image-1691737743498

进入master-1主机的 /data/work目录

wget http://qiniu.tobehacker.com/k8s/coredns.yaml.base

cp coredns.yaml.base coredns.yaml

修改coredns.yaml

(1) 71行修改 k8s 集群后缀名称 DNS__DOMAIN 为 cluster.local

kubernetes __DNS__DOMAIN__ in-addr.arpa ip6.arpa {
# 修改后:kubernetes cluster.local in-addr.arpa ip6.arpa {

image-1692337886341

(2) 136行 修改 coredns 谷歌地址为 dockerhub 地址

image: registry.k8s.io/coredns/coredns:v1.10.0   
# 修改后:image: coredns/coredns:1.10.0

image-1692337958737

(3) 212 行修改 coredns 的 svcIP 地址,一般为 svc 网段的第二位(一开始我们规划好的 10.255.0.0),10.255.0.2,第一位为 apiserver 的 svc

clusterIP: __DNS__SERVER__
# 修改后:clusterIP: 10.255.0.2

完整的coredns.yaml

coredns.yaml

安装 coredns

测试 coredns 域名解析功能

安装 keepalived+nginx 实现 k8s apiserver 高可用

0

评论区