k8s二进制及负载均衡集群部署详解

目录

常见部署方式

二进制部署流程

环境准备

操作系统初始化配置

关闭防火墙

配置SELinux

关闭SWAP

根据规划设置主机名

在master添加hosts,便于主机名解析

调整内核参数

配置时间同步

部署docker引擎

在所有node节点部署docker引擎

部署etcd集群

签发证书环境准备

master01 节点上

准备cfssl证书生成工具

生成Etcd证书

node01 node02节点上

完成配置修改后,启动etcd服务

部署Master组件

在 master01 节点上

创建用于生成CA证书和相关组件证书的目录:

复制CA证书、apiserver相关证书和私钥到 kubernetes工作目录的 ssl 子目录中

创建 bootstrap token 认证文件,apiserver 启动时会调用,然后就相当于在集群内创建了一个这个用户,接下来就可以用 RBAC 给他授权

启动apiserver服务:

启动scheduler服务:

启动controller-manager服务:

生成kubectl连接集群的kubeconfig文件:

部署Worker Node 组件

在所有node节点上操作

创建 Kubernetes 工作目录:

master01 节点上操作

使用 scp 命令将 kubelet 和 kube-proxy 拷贝到 node 节点上

为 kubelet 和 kube-proxy 生成初次加入集群的引导 kubeconfig 文件和 kube-proxy.kubeconfig 文件。

node01 节点上操作

启动 kubelet 服务:

master01 节点上操作

检查 node01 节点的证书签发请求(CSR)状态

检查 kubelet 发起的 CSR 请求:

批准 CSR 请求:

node01 节点上操作:

加载 ip_vs 模块:

启动 proxy 服务:

部署 CNI 网络组件

部署 flannel

node01 节点上操作

master01 节点上操作

部署 Calico

k8s 组网Calico方案与flannel方案区别

master01 节点上操作

部署node02 节点

node01 节点上操作

node02 节点上操作:

master01 节点上操作

部署 CoreDNS

在所有 node 节点上操作

在 master01 节点上操作

部署master02 节点

在master01 节点上操作

从 master01 节点上拷贝证书文件、各master组件的配置文件和服务管理文件到 master02 节点

修改配置文件kube-apiserver中的IP

master02 节点上启动各服务并设置开机自启

查看node节点状态

负载均衡部署

配置load balancer集群双机热备负载均衡

在lb01、lb02节点上操作

配置Nginx的官方在线yum源和本地Nginx的yum源并安装nginx

修改nginx配置文件,配置四层反向代理负载均衡,指定k8s群集2台master的节点ip和6443端口

启动nginx服务,查看已监听6443端口

部署keepalived服务

修改keepalived配置文件以配置高可用性

创建nginx状态检查的脚本

在node节点上修改配置

要将Node节点上的bootstrap.kubeconfig、kubelet.kubeconfig和kube-proxy.kubeconfig配置文件中的服务器地址修改为VIP

在 lb01 上查看 nginx 和 node 、 master 节点的连接状态

在 master01 节点上操作

部署 Dashboard

在Master01节点上进行操作


常见部署方式

  • Minikube: Minikube是一个用于在本地快速运行单节点微型K8S集群的工具。它主要用于学习和预览K8S的一些特性。可以通过访问Install Tools | Kubernetes 获取更多关于Minikube的部署信息。

  • Kubeadm: Kubeadm是另一个工具,它提供了"kubeadm init"和"kubeadm join"命令,用于快速部署K8S集群。相对而言,Kubeadm的部署过程比较简单。可以通过访问Kubeadm | Kubernetes 获取更多关于Kubeadm的详细信息。

  • 二进制安装部署: 这是在生产环境中首选的部署方式。它涉及从官方下载Kubernetes发行版的二进制包,并手动部署每个组件以及自签名的TLS证书,从而组成K8S集群。对于新手来说,这种部署方式可能会有些繁琐,但它可以让你更好地了解Kubernetes的工作原理,并有利于后续的维护工作。可以通过访问https://github.com/kubernetes/kubernetes/releases 获取更多关于二进制安装部署的信息。

综上所述,Kubeadm可以降低部署的门槛,但它屏蔽了很多细节,当遇到问题时可能会很难进行排查。所以这里使用二进制包部署,有利于理解以及后期排错维护

二进制部署流程

Kubernetes(简称K8s)是一个用于容器编排和管理的开源平台。K8s的二进制部署方式是一种手动安装和配置Kubernetes集群的方法,相对于其他部署方式,它提供了更多的灵活性和可定制性。

  • 环境准备:

  • 确保服务器满足Kubernetes的要求,包括操作系统版本、内存、CPU等。

  • 安装Docker,作为容器运行时环境。

  • 下载Kubernetes二进制文件:

  • 访问Kubernetes官方网站或GitHub仓库,下载所需版本的Kubernetes二进制文件。

  • 部署etcd集群:

  • Etcd是Kubernetes使用的分布式键值存储系统,用于存储集群的状态信息。

  • 下载并安装Etcd,可以选择使用3台或更多的机器组成Etcd集群,以提高可用性和容错性。

  • 生成证书:

  • 使用cfssl工具生成Kubernetes集群所需的证书和密钥。

  • 创建自签名证书颁发机构(CA)并生成相关证书。

  • 部署Master节点:

  • 在Master节点上安装和配置Kubernetes控制平面组件,包括kube-apiserver、kube-controller-manager、kube-scheduler等。

  • 配置kube-apiserver以使用生成的证书和密钥。

  • 部署Worker节点:

  • 在每个Worker节点上安装和配置Kubernetes工作节点组件,包括kubelet和kube-proxy。

  • 配置kubelet以连接到Master节点的kube-apiserver。

  • 配置网络插件:

  • 选择并安装适合的网络插件,用于实现容器之间的网络通信和跨节点的网络互连。

  • 验证集群:

  • 使用kubectl命令行工具连接到集群,并执行一些简单的命令来验证集群的正常运行。

环境准备

使用二进制方式搭建Kubernetes v1.20的集群架构。

主节点(Master):

  • master01:192.168.41.31,运行kube-apiserver、kube-controller-manager、kube-scheduler和etcd等组件。

  • master02:192.168.41.32,作为Kubernetes集群的备用主节点。

    工作节点(Node)

  • node01:192.168.41.33,运行kubelet、kube-proxy和docker等组件。

  • node02:192.168.41.34,作为Kubernetes集群的另一个工作节点。

etcd节点 :

为方便模拟,防止cpu资源不足,这里把etcd部署在之前的节点上了,实际环境中etcd是有单独的资源的。

  • etcd节点1:192.168.41.31,运行etcd组件。

  • etcd节点2:192.168.41.33,作为etcd集群的一个节点。

  • etcd节点3:192.168.41.34,作为etcd集群的另一个节点。

负载均衡器(Load Balancer)使用nginx和keepalived实现 :

  • 负载均衡器1(master):192.168.41.35,用于负责将请求转发给Kubernetes主节点。

  • 负载均衡器2(backup):192.168.41.36,作为负载均衡器的备用节点。

此外,还有一个虚拟IP(VIP)用于访问Kubernetes集群,其IP地址为192.168.41.100。

操作系统初始化配置

关闭防火墙

systemctl stop firewalld
systemctl disable firewalld
iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X
  • systemctl stop firewalld: 这个命令停止了名为 "firewalld" 的系统服务。firewalld 是一种动态的、管理 Linux 防火墙规则的工具。通过停止服务,防火墙将被关闭。

  • systemctl disable firewalld: 这个命令禁用了 "firewalld" 服务,这意味着该服务将在系统启动时不再自动启用。这样做是为了确保在系统重新启动后,防火墙服务不会自动启动。

  • iptables -F: 这个命令用于清除 IPv4 防火墙规则。具体来说,它会将防火墙规则表中的所有规则清空(Flush)。

  • iptables -t nat -F: 这个命令用于清除 IPv4 的 NAT 表(Network Address Translation,网络地址转换)的规则。同样,它会将 NAT 表中的所有规则清空。

  • iptables -t mangle -F: 这个命令用于清除 IPv4 的 Mangle 表的规则。Mangle 表主要用于修改数据包的头部信息,例如修改 TTL(Time To Live)等。这个命令会将 Mangle 表中的所有规则清空。

  • iptables -X: 这个命令用于删除用户自定义的链(User-defined chains)。它会删除防火墙规则表中用户创建的任何自定义链。

总体而言,这一系列命令的目的是关闭并禁用防火墙服务,然后清除防火墙规则和表,确保系统上不再有任何防火墙规则,使网络流量能够自由地通过系统。

配置SELinux

setenforce 0
sed -i 's/enforcing/disabled/' /etc/selinux/config
  • setenforce 0:这个命令将SELinux的执行模式设置为"Permissive",也就是宽容模式。在宽容模式下,SELinux会记录违规行为,但不会阻止它们。

  • sed -i 's/enforcing/disabled/' /etc/selinux/config:这个命令使用sed工具来修改/etc/selinux/config文件中的内容。它将文件中所有出现的"enforcing"替换为"disabled"。这样做的目的是将SELinux的默认执行模式从"Enforcing"(强制模式)改为"Disabled"(禁用模式)。

关闭SWAP

swapoff -a
sed -ri 's/.*swap.*/#&/' /etc/fstab 
  • swapoff -a:这个命令用于关闭所有的交换空间。交换空间是用于在物理内存不足时,将部分数据存储到硬盘上的一种机制。通过执行这个命令,所有的交换空间都会被禁用。

  • sed -ri 's/.*swap.*/#&/' /etc/fstab:这个命令使用sed工具来修改/etc/fstab文件中的内容。它会查找文件中所有包含"swap"的行,并在行首添加"#"字符,将其注释掉。这样做的目的是禁用系统启动时自动挂载的交换空间。

根据规划设置主机名

hostnamectl set-hostname 主机名
su #切换刷新,快速显示修改后的主机名

在master添加hosts,便于主机名解析

cat >> /etc/hosts << EOF
192.168.41.31 master01
192.168.41.32 master02
192.168.41.33 node01
192.168.41.34 node02
EOF
  • cat >> /etc/hostscat命令用于将文件内容输出到终端或其他文件。>>表示将输出追加到指定文件中,而不是覆盖原有内容。/etc/hosts是指要追加内容的目标文件。

  • << EOF:这是一个Here文档的开始标记,用于指示接下来的内容将作为输入传递给cat命令。

  • 192.168.10.80 master01:这是第一行要追加到/etc/hosts文件中的内容。它指定了一个IP地址192.168.10.80和一个主机名master01,以此类推。

  • EOF:这是Here文档的结束标记,表示输入结束。

通过使用Here文档和重定向,这个命令将四行内容追加到/etc/hosts文件中,以便在网络中进行主机名解析。

调整内核参数

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

sysctl --system
  • cat > /etc/sysctl.d/k8s.conf:这个命令将输出重定向到/etc/sysctl.d/k8s.conf文件中。>表示将输出覆盖写入文件,如果文件不存在则创建它。

  • << EOF:这是一个Here文档的开始标记,用于指示接下来的内容将作为输入传递给cat命令,并写入文件。

  • net.bridge.bridge-nf-call-ip6tables = 1:这是一个内核参数设置,用于开启网桥模式,将网桥的流量传递给iptables链。

  • net.bridge.bridge-nf-call-iptables = 1:这是另一个内核参数设置,也用于开启网桥模式,将网桥的流量传递给iptables链。

  • net.ipv6.conf.all.disable_ipv6=1:这个内核参数设置用于关闭IPv6协议。

  • net.ipv4.ip_forward=1:这个内核参数设置用于开启IPv4的IP转发功能。

  • EOF:这是Here文档的结束标记,表示输入结束。

  • sysctl --system:这个命令用于重新加载并应用修改后的内核参数。

通过这些命令,可以将指定的内核参数设置写入/etc/sysctl.d/k8s.conf文件,并通过sysctl --system命令重新加载内核参数,使其生效。

配置时间同步

yum install ntpdate -y
ntpdate time.windows.com
  • yum install ntpdate -y:这个命令使用yum包管理器来安装ntpdate工具。-y选项表示在安装过程中自动回答"yes",无需手动确认。

  • ntpdate time.windows.com:这个命令使用ntpdate工具来从time.windows.com服务器同步时间。ntpdate是一个用于手动同步时间的命令行工具,它可以从指定的NTP服务器获取准确的时间,并将系统时间进行调整。

不过因为ntpdate命令已经过时,也可以使用更现代的工具,如chrony或systemd-timesyncd来同步时间。这些工具可以提供更稳定和可靠的时间同步机制。

部署docker引擎

在所有node节点部署docker引擎

yum install -y yum-utils device-mapper-persistent-data lvm2 
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 
yum install -y docker-ce docker-ce-cli containerd.io

systemctl start docker.service
systemctl enable docker.service 
  • yum install -y yum-utils device-mapper-persistent-data lvm2:这个命令用于安装一些依赖包,这些包是安装Docker所需的。

  • yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo:这个命令用于添加Docker的软件源配置文件。通过指定阿里云的镜像源,可以加快Docker的下载速度。

  • yum install -y docker-ce docker-ce-cli containerd.io:这个命令用于安装Docker引擎及其相关组件。通过执行这个命令,将安装Docker的最新版本。

  • systemctl start docker.service:这个命令用于启动Docker服务。一旦Docker服务启动,就可以开始使用Docker了。

  • systemctl enable docker.service:这个命令用于设置Docker服务在系统启动时自动启动。这样,每次系统重启后,Docker服务都会自动启动。

部署etcd集群

etcd默认使用2379端口提供HTTP API服务,使用2380端口进行服务器间的内部通信。在生产环境中,通常建议以集群方式部署etcd。由于etcd的leader选举机制,要求至少有3台或更多的奇数台服务器。

这种集群部署方式有助于提高etcd的可用性和容错性。通过在多台服务器上运行etcd实例,可以确保在某些服务器发生故障或不可用的情况下,etcd集群仍然可以正常工作。

签发证书环境准备

CFSSL是CloudFlare公司开源的一款PKI/TLS工具,用于生成、签名和验证TLS证书。它包含一个命令行工具和一个HTTP API服务,使用Go语言编写。

在使用CFSSL之前,需要生成一个CFSSL识别的JSON格式配置文件。CFSSL提供了方便的命令行工具来生成这个配置文件。

CFSSL主要用于为etcd提供TLS证书,并支持三种类型的证书:

  • 客户端证书(client certificate):用于服务端连接客户端时进行身份验证,例如kube-apiserver连接etcd时使用的证书。

  • 服务器证书(server certificate):用于客户端连接服务端时进行身份验证,例如etcd对外提供服务时使用的证书。

  • 对等证书(peer certificate):用于节点之间的相互连接和验证,例如etcd节点之间进行通信时使用的证书。

在这种情况下,所有证书都使用相同的证书认证。

使用CFSSL可以方便地生成、签名和管理这些TLS证书,确保安全的通信和身份验证。

master01 节点上

准备cfssl证书生成工具
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -O /usr/local/bin/cfssl
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -O /usr/local/bin/cfssljson
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 -O /usr/local/bin/cfssl-certinfo

chmod +x /usr/local/bin/cfssl*
cfssl:证书签发的工具命令
cfssljson:将 cfssl 生成的证书(json格式)变为文件承载式证书
cfssl-certinfo:验证证书的信息
cfssl-certinfo -cert <证书名称>            #查看证书的信息
  • wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -O /usr/local/bin/cfssl:这个命令使用wget工具从CFSSL官方网站下载cfssl工具的Linux二进制文件,并将其保存到/usr/local/bin/cfssl路径下。cfssl是CFSSL证书生成工具的主要可执行文件。

  • wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -O /usr/local/bin/cfssljson:这个命令使用wget工具从CFSSL官方网站下载cfssljson工具的Linux二进制文件,并将其保存到/usr/local/bin/cfssljson路径下。cfssljson是CFSSL证书生成工具的JSON处理工具,用于生成和处理JSON格式的配置文件。

  • wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 -O /usr/local/bin/cfssl-certinfo:这个命令使用wget工具从CFSSL官方网站下载cfssl-certinfo工具的Linux二进制文件,并将其保存到/usr/local/bin/cfssl-certinfo路径下。cfssl-certinfo是CFSSL证书生成工具的证书信息查询工具,用于查看证书的详细信息。

  • chmod +x /usr/local/bin/cfssl*:这个命令用于给下载的CFSSL工具添加可执行权限。通过执行这个命令,可以确保这些工具可以在系统中被执行。

生成Etcd证书
mkdir /opt/k8s
cd /opt/k8s/
  • etcd-cert.sh脚本
#!/bin/bash
cat > ca-config.json <<EOF
{
  "signing": {
    "default": {
      "expiry": "87600h"
    },
    "profiles": {
      "www": {
         "expiry": "87600h",
         "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ]
      }
    }
  }
}
EOF


cat > ca-csr.json <<EOF
{
    "CN": "etcd",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "Beijing",
            "ST": "Beijing"
        }
    ]
}
EOF


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


cat > server-csr.json <<EOF
{
    "CN": "etcd",
    "hosts": [
    "192.168.41.31",
    "192.168.41.33",
    "192.168.41.34"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "BeiJing",
            "ST": "BeiJing"
        }
    ]
}
EOF

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=www server-csr.json | cfssljson -bare server

#生成的文件:
#server.csr:服务器的证书请求文件
#server-key.pem:服务器的私钥
#server.pem:服务器的数字签名证书

#-config:引用证书生成策略文件 ca-config.json
#-profile:指定证书生成策略文件中的的使用场景,比如 ca-config.json 中的 www

这脚本是用于生成证书的

  • #!/bin/bash:这是一个shebang,指定了脚本使用的解释器为bash。

  • cat > ca-config.json <<EOF:这行命令将下面的内容输入到ca-config.json文件中。<<EOF表示将输入一直持续到遇到EOF为止。

  • ...ca-config.json文件的内容,它是一个JSON格式的配置文件,用于定义证书的签名和配置信息。

  • cat > ca-csr.json <<EOF:同样的方式,将下面的内容输入到ca-csr.json文件中。

  • ...ca-csr.json文件的内容,也是一个JSON格式的配置文件,用于定义证书签名请求的信息。

  • cfssl gencert -initca ca-csr.json | cfssljson -bare ca:这行命令使用cfssl工具生成自签名的根证书。cfssl gencert命令用于生成证书,-initca选项表示生成自签名的根证书,ca-csr.json是证书签名请求的配置文件,cfssljson -bare ca用于将生成的证书和私钥保存为ca.pemca-key.pem文件。

  • cat > server-csr.json <<EOF:同样的方式,将下面的内容输入到server-csr.json文件中。

  • ...server-csr.json文件的内容,也是一个JSON格式的配置文件,用于定义服务器证书签名请求的信息。

  • cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=www server-csr.json | cfssljson -bare server:这行命令使用之前生成的根证书对服务器证书进行签名。-ca选项指定根证书的路径,-ca-key选项指定根证书的私钥路径,-config选项指定证书签名的配置文件,-profile选项指定使用的证书配置文件中的配置项,server-csr.json是服务器证书签名请求的配置文件,cfssljson -bare server用于将生成的服务器证书和私钥保存为server.pemserver-key.pem文件。

    这段脚本的作用是生成自签名的根证书和服务器证书,用于加密和认证服务器的通信。

  • etcd.sh脚本

#!/bin/bash
#example: ./etcd.sh etcd01 192.168.41.31 etcd02=https://192.168.41.33:2380,etcd03=https://192.168.41.34:2380

#创建etcd配置文件/opt/etcd/cfg/etcd
ETCD_NAME=$1
ETCD_IP=$2
ETCD_CLUSTER=$3

WORK_DIR=/opt/etcd

cat > $WORK_DIR/cfg/etcd  <<EOF
#[Member]
ETCD_NAME="${ETCD_NAME}"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://${ETCD_IP}:2380"
ETCD_LISTEN_CLIENT_URLS="https://${ETCD_IP}:2379"

#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://${ETCD_IP}:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://${ETCD_IP}:2379"
ETCD_INITIAL_CLUSTER="etcd01=https://${ETCD_IP}:2380,${ETCD_CLUSTER}"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
EOF

#创建etcd.service服务管理文件
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=${WORK_DIR}/cfg/etcd
ExecStart=${WORK_DIR}/bin/etcd \
--cert-file=${WORK_DIR}/ssl/server.pem \
--key-file=${WORK_DIR}/ssl/server-key.pem \
--trusted-ca-file=${WORK_DIR}/ssl/ca.pem \
--peer-cert-file=${WORK_DIR}/ssl/server.pem \
--peer-key-file=${WORK_DIR}/ssl/server-key.pem \
--peer-trusted-ca-file=${WORK_DIR}/ssl/ca.pem \
--logger=zap \
--enable-v2
Restart=on-failure
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
EOF


systemctl daemon-reload
systemctl enable etcd
systemctl restart etcd

这是一个用于创建和配置etcd服务的bash脚本。

  • #!/bin/bash: 这是一个shebang,指定了脚本使用的解释器为bash。

  • ETCD_NAME=$1: 将第一个命令行参数赋值给变量ETCD_NAME,该参数表示etcd的名称。

  • ETCD_IP=$2: 将第二个命令行参数赋值给变量ETCD_IP,该参数表示etcd的IP地址。

  • ETCD_CLUSTER=$3: 将第三个命令行参数赋值给变量ETCD_CLUSTER,该参数表示etcd集群的配置。

  • WORK_DIR=/opt/etcd: 设置工作目录为/opt/etcd

  • cat > $WORK_DIR/cfg/etcd <<EOF: 使用Here文档将以下内容输出到$WORK_DIR/cfg/etcd文件中,EOF表示结束标记。

  • ETCD_NAME="${ETCD_NAME}": 设置etcd的名称为ETCD_NAME变量的值。

  • ETCD_DATA_DIR="/var/lib/etcd/default.etcd": 设置etcd数据目录。

  • ETCD_LISTEN_PEER_URLS="https://${ETCD_IP}:2380": 设置etcd监听对等节点通信的URL。

  • ETCD_LISTEN_CLIENT_URLS="https://${ETCD_IP}:2379": 设置etcd监听客户端请求的URL。

  • ETCD_INITIAL_ADVERTISE_PEER_URLS="https://${ETCD_IP}:2380": 设置etcd对外广告的对等节点通信URL。

  • ETCD_ADVERTISE_CLIENT_URLS="https://${ETCD_IP}:2379": 设置etcd对外广告的客户端请求URL。

  • ETCD_INITIAL_CLUSTER="etcd01=https://${ETCD_IP}:2380,${ETCD_CLUSTER}": 设置etcd初始集群配置,包括当前节点和其他节点的URL。

  • ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster": 设置etcd集群的令牌。

  • ETCD_INITIAL_CLUSTER_STATE="new": 设置etcd集群的初始状态为"new"。

  • cat > /usr/lib/systemd/system/etcd.service <<EOF: 使用Here文档将以下内容输出到/usr/lib/systemd/system/etcd.service文件中。

  • [Unit]:定义了一个systemd单元,描述etcd服务。

  • Description=Etcd Server:设置etcd服务的描述。

  • After=network.target:指定etcd服务在网络服务启动后启动。

  • After=network-online.target:指定etcd服务在网络连接成功后启动。

  • Wants=network-online.target:指定etcd服务依赖于网络连接成功。

  • [Service]:定义etcd服务的相关配置。

  • Type=notify:指定etcd服务的类型为notify,表示服务启动完成后会发送通知。

  • EnvironmentFile=${WORK_DIR}/cfg/etcd:指定etcd服务的环境变量文件为$WORK_DIR/cfg/etcd

  • ExecStart=${WORK_DIR}/bin/etcd \: 指定etcd服务的启动命令。

  • --cert-file=${WORK_DIR}/ssl/server.pem \: 指定etcd服务使用的证书文件。

  • --key-file=${WORK_DIR}/ssl/server-key.pem \: 指定etcd服务使用的密钥文件。

  • --trusted-ca-file=${WORK_DIR}/ssl/ca.pem \: 指定etcd服务使用的CA证书文件。

  • --peer-cert-file=${WORK_DIR}/ssl/server.pem \: 指定etcd服务对等节点使用的证书文件。

  • --peer-key-file=${WORK_DIR}/ssl/server-key.pem \: 指定etcd服务对等节点使用的密钥文件。

  • --peer-trusted-ca-file=${WORK_DIR}/ssl/ca.pem \: 指定etcd服务对等节点使用的CA证书文件。

  • --logger=zap \: 指定etcd服务使用的日志记录器。

  • --enable-v2: 启用etcd的v2版本API。

  • Restart=on-failure: 设置etcd服务在失败时自动重启。

  • LimitNOFILE=65536: 设置etcd服务的最大文件描述符数。

  • [Install]:定义etcd服务的安装配置。

  • WantedBy=multi-user.target:指定etcd服务在multi-user.target下启动。

  • EOF: 结束Here文档。

  • systemctl daemon-reload: 重新加载systemd配置。

  • systemctl enable etcd: 启用etcd服务,使其在系统启动时自动启动。

  • systemctl restart etcd: 重启etcd服务,使新的配置生效。

将 etcd-cert.sh 和 etcd.sh 脚本上传到/opt/k8s/目录,并为它们添加可执行权限。

  • 上传脚本

  • 首先,需要将etcd-cert.shetcd.sh脚本文件上传到目标服务器的/opt/k8s/目录中。可以使用文件传输工具(如scp)将这两个文件从本地系统上传到目标服务器的/opt/k8s/目录。

  • 添加可执行权限

  • 一旦脚本文件上传到目标服务器的/opt/k8s/目录中,可以使用以下命令为它们添加可执行权限:

chmod +x /opt/k8s/etcd-cert.sh /opt/k8s/etcd.sh

这个命令使用chmod命令为etcd-cert.shetcd.sh脚本文件添加可执行权限。通过执行这个命令,可以确保这两个脚本文件可以在系统中被执行。

创建一个用于生成CA证书、etcd服务器证书和私钥的目录,并执行相应的操作

创建/opt/k8s/etcd-cert目录,并在其中生成了CA证书、etcd服务器证书和私钥文件。

mkdir /opt/k8s/etcd-cert
mv etcd-cert.sh etcd-cert/
cd /opt/k8s/etcd-cert/
./etcd-cert.sh            
  • mkdir /opt/k8s/etcd-cert:这个命令用于创建一个名为/opt/k8s/etcd-cert的目录,用于存放生成的证书和私钥文件。

  • mv etcd-cert.sh etcd-cert/:这个命令将etcd-cert.sh脚本文件移动到/opt/k8s/etcd-cert/目录中。通过执行这个命令,您将脚本文件放置在正确的位置。

  • cd /opt/k8s/etcd-cert/:这个命令用于切换到/opt/k8s/etcd-cert/目录,以便在该目录下执行后续的命令。

  • ./etcd-cert.sh:这个命令用于执行etcd-cert.sh脚本文件,生成CA证书、etcd服务器证书和私钥。通过执行这个命令,将生成所需的证书和私钥文件。

检查生成的证书和文件

#ls:这个命令用于列出当前目录下的文件和目录。执行这个命令后,将看到生成的证书和私钥文件列表。
ls 

上传etcd-v3.4.9-linux-amd64.tar.gz文件到/opt/k8s目录,并启动etcd服务

  • 上传文件

  • 首先,需要将etcd-v3.4.9-linux-amd64.tar.gz文件上传到目标服务器的/opt/k8s目录中。可以使用文件传输工具(如scp)将该文件从本地系统上传到目标服务器的/opt/k8s目录。

  • 解压文件

  • 接下来,需要进入/opt/k8s目录,并解压etcd-v3.4.9-linux-amd64.tar.gz文件。可以使用以下命令完成解压:

cd /opt/k8s/
tar zxvf etcd-v3.4.9-linux-amd64.tar.gz

这个命令将进入/opt/k8s目录,然后使用tar命令解压etcd-v3.4.9-linux-amd64.tar.gz文件。

  • 查看文件

  • 执行解压后,可以使用以下命令查看解压后的文件列表:

ls etcd-v3.4.9-linux-amd64

这个命令将列出etcd-v3.4.9-linux-amd64目录中的文件和目录。可以看到解压后的文件和目录,包括DocumentationetcdetcdctlREADME-etcdctl.mdREADME.mdREADMEv2-etcdctl.md

创建用于存放 etcd 配置文件,命令文件,证书的目录

创建目录用于存放 etcd 配置文件,命令文件,证书

mkdir -p /opt/etcd/{cfg,bin,ssl}

进入 /opt/k8s/etcd-v3.4.9-linux-amd64/ 目录,并将 etcdetcdctl 文件移动到 /opt/etcd/bin/ 目录:

cd /opt/k8s/etcd-v3.4.9-linux-amd64/
mv etcd etcdctl /opt/etcd/bin/

然后,将 /opt/k8s/etcd-cert/*.pem 目录下的所有 .pem 文件复制到 /opt/etcd/ssl/ 目录:

cp /opt/k8s/etcd-cert/*.pem /opt/etcd/ssl/

最后,进入 /opt/k8s/ 目录,并执行 etcd.sh 脚本

cd /opt/k8s/
./etcd.sh etcd01 192.168.41.31 etcd02=https://192.168.41.33:2380,etcd03=https://192.168.41.34:2380
  • cd /opt/k8s/:切换当前工作目录到/opt/k8s/。

  • ./etcd.sh etcd01 192.168.41.31 etcd02=https://192.168.41.33:2380,etcd03=https://192.168.41.34:2380:执行etcd.sh脚本,并传递以下参数:

  • etcd01:作为etcd集群的第一个节点的名称。

  • 192.168.41.31:etcd集群的第一个节点的IP地址。

  • etcd02=https://192.168.41.33:2380,etcd03=https://192.168.41.34:2380:指定etcd集群的其他节点的信息。这里有两个节点,分别是etcd02和etcd03,它们的IP地址分别是192.168.41.33和192.168.41.34,端口号为2380。

这段命令的作用是在指定目录下执行etcd.sh脚本,并配置etcd集群的节点信息。

执行该脚本后,脚本会进入等待状态,直到其他节点加入。在启动集群中的所有 etcd 节点之前,如果只启动其中一台节点,脚本会一直等待。这种情况可以忽略。也可以另外打开一个窗口查看etcd进程是否正常

ps -ef | grep etcd

将etcd相关的证书文件、命令文件和服务管理文件复制到另外两个etcd集群节点。

scp -r /opt/etcd/ root@192.168.41.33:/opt/
scp -r /opt/etcd/ root@192.168.41.34:/opt/
scp /usr/lib/systemd/system/etcd.service root@192.168.41.33:/usr/lib/systemd/system/
scp /usr/lib/systemd/system/etcd.service root@192.168.41.34:/usr/lib/systemd/system/

这组命令的作用是将etcd相关的文件和目录复制到其他两个etcd集群节点,以确保这些节点具有相同的配置和文件。这样可以保持集群的一致性,并确保所有节点都能正常运行etcd服务。

node01 node02节点上

vim /opt/etcd/cfg/etcd

#[Member]
ETCD_NAME="etcd02"                                            #修改
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.41.33:2380"            #修改
ETCD_LISTEN_CLIENT_URLS="https://192.168.41.33:2379"        #修改

#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.41.33:2380"        #修改
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.41.33:2379"                #修改
ETCD_INITIAL_CLUSTER="etcd01=https://192.168.41.31:2380,etcd02=https://192.168.41.33:2380,etcd03=https://192.168.41.34:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"

首先,使用vim编辑器打开文件/opt/etcd/cfg/etcd,然后进行以下修改:

  • 修改ETCD_NAME为"etcd02",这是etcd节点的名称。

  • 修改ETCD_LISTEN_PEER_URLS为"https://192.168.41.33:2380",这是etcd节点用于监听对等节点通信的URL。

  • 修改ETCD_LISTEN_CLIENT_URLS为"https://192.168.41.33:2379",这是etcd节点用于监听客户端请求的URL。

接下来,修改集群相关的配置:

  • 修改ETCD_INITIAL_ADVERTISE_PEER_URLS为"https://192.168.41.33:2380",这是etcd节点用于广播对等节点URL的URL。

  • 修改ETCD_ADVERTISE_CLIENT_URLS为"https://192.168.41.33:2379",这是etcd节点用于广播客户端URL的URL。

  • 修改ETCD_INITIAL_CLUSTER为"etcd01=https://192.168.41.31:2380,etcd02=https://192.168.41.33:2380,etcd03=https://192.168.41.34:2380",这是etcd集群中所有节点的初始配置。

  • 设置ETCD_INITIAL_CLUSTER_TOKEN为"etcd-cluster",这是etcd集群的令牌。

  • 设置ETCD_INITIAL_CLUSTER_STATE为"new",这是etcd集群的初始状态。

完成配置修改后,启动etcd服务
systemctl start etcd

并设置etcd服务开机自启动:

systemctl enable etcd

在这里,systemctl enable --now etcd命令也可以使用,它会同时激活并启动服务,或者同时激活并停止服务。

最后,使用以下命令检查etcd服务的状态:

systemctl status etcd

这将显示etcd服务的当前状态。

完成配置修改后,启动etcd服务,使用以下命令:

systemctl start etcd

并设置etcd服务开机自启动:

systemctl enable --now etcd

在这里,systemctl enable --now etcd命令也可以使用,它会同时激活并启动服务,或者同时激活并停止服务。

最后,使用以下命令检查etcd服务的状态:

systemctl status etcd

这将显示etcd服务的当前状态。

同理在node02节点上修改配置并启动etcd

vim /opt/etcd/cfg/etcd

#[Member]
ETCD_NAME="etcd03"                                            #修改
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.41.34:2380"            #修改
ETCD_LISTEN_CLIENT_URLS="https://192.168.41.34:2379"        #修改

#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.41.34:2380"        #修改
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.41.34:2379"                #修改
ETCD_INITIAL_CLUSTER="etcd01=https://192.168.41.31:2380,etcd02=https://192.168.41.33:2380,etcd03=https://192.168.41.34:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"

systemctl start etcd
systemctl enable --now etcd
systemctl status etcd

可以使用etcdctl工具来检查etcd集群的状态。

  • 检查etcd集群节点的健康状态:
ETCDCTL_API=3 /opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://192.168.41.31:2379,https://192.168.41.33:2379,https://192.168.41.34:2379" endpoint health --write-out=table

这个命令将检查etcd集群中每个节点的健康状态,并以表格形式输出结果。

这表明etcd集群中的所有节点都处于健康状态。

  • 检查etcd集群节点的状态信息:
ETCDCTL_API=3 /opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://192.168.41.31:2379,https://192.168.41.33:2379,https://192.168.41.34:2379" endpoint status --write-out=table

这个命令将显示etcd集群中每个节点的详细状态信息,并以表格形式输出结果。

这表明etcd集群中的每个节点的状态正常,它们都处于相同的RAFT TERM,并且已应用相同的RAFT INDEX。

  • 请确保替换命令中的证书、密钥和etcd节点的地址与你实际的配置相匹配。执行这些命令后,将获得有关etcd集群节点的健康状态和详细状态信息。

  • 如果etcd集群节点的健康状态显示为健康,并且详细状态信息显示所有节点都处于正常状态,那么etcd集群应该是正常运行的。

  • 如果健康状态或详细状态信息显示有任何异常或错误,请提供相关的输出信息,以便我们能够更好地帮助您解决问题。

--cert-file:识别HTTPS端使用SSL证书文件
--key-file:使用此SSL密钥文件标识HTTPS客户端
--ca-file:使用此CA证书验证启用https的服务器的证书
--endpoints:集群中以逗号分隔的机器地址列表
cluster-health:检查etcd集群的运行状况
  • 查看etcd集群成员列表
ETCDCTL_API=3 /opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://192.168.41.31:2379,https://192.168.41.33:2379,https://192.168.41.34:2379" --write-out=table member list

部署Master组件

在 master01 节点上

  • k8s-cert.sh脚本
#!/bin/bash
#配置证书生成策略,让 CA 软件知道颁发有什么功能的证书,生成用来签发其他组件证书的根证书
cat > ca-config.json <<EOF
{
  "signing": {
    "default": {
      "expiry": "87600h"
    },
    "profiles": {
      "kubernetes": {
         "expiry": "87600h",
         "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ]
      }
    }
  }
}
EOF

#生成CA证书和私钥(根证书和私钥)
cat > ca-csr.json <<EOF
{
    "CN": "kubernetes",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "Beijing",
            "ST": "Beijing",
              "O": "k8s",
            "OU": "System"
        }
    ]
}
EOF

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


#-----------------------
#生成 apiserver 的证书和私钥(apiserver和其它k8s组件通信使用)
#hosts中将所有可能作为 apiserver 的 ip 添加进去,后面 keepalived 使用的 VIP 也要加入
cat > apiserver-csr.json <<EOF
{
    "CN": "kubernetes",
    "hosts": [
      "10.0.0.1",
      "127.0.0.1",
      "192.168.41.31",        #master01
      "192.168.41.32",        #master02
      "192.168.10.100",        #vip,后面 keepalived 使用
      "192.168.41.33",        #load balancer01(master)
      "192.168.41.34",        #load balancer02(backup)
      "kubernetes",
      "kubernetes.default",
      "kubernetes.default.svc",
      "kubernetes.default.svc.cluster",
      "kubernetes.default.svc.cluster.local"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "BeiJing",
            "ST": "BeiJing",
            "O": "k8s",
            "OU": "System"
        }
    ]
}
EOF

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


#-----------------------
#生成 kubectl 连接集群的证书和私钥,具有admin权限
cat > admin-csr.json <<EOF
{
  "CN": "admin",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "L": "BeiJing",
      "ST": "BeiJing",
      "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


#-----------------------
#生成 kube-proxy 的证书和私钥
cat > kube-proxy-csr.json <<EOF
{
  "CN": "system:kube-proxy",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "L": "BeiJing",
      "ST": "BeiJing",
      "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

这段脚本是用于生成证书和私钥,用于配置 Kubernetes 集群的安全通信。

  • 首先,脚本定义了一个 JSON 文件 ca-config.json,用于配置证书生成策略。其中包含了默认的证书过期时间和一个名为 "kubernetes" 的证书配置文件,该配置文件定义了证书的过期时间和用途("signing"、"key encipherment"、"server auth"、"client auth")。

  • 接下来,脚本定义了另一个 JSON 文件 ca-csr.json,用于生成根证书和私钥。该文件指定了证书的一些属性,如 Common Name(CN)、国家(C)、城市(L)、省份(ST)、组织(O)和组织单位(OU)等。

  • 然后,使用 cfssl 工具根据 ca-csr.json 文件生成根证书和私钥,命名为 ca.pem 和 ca-key.pem。

  • 接下来,脚本定义了 apiserver-csr.json 文件,用于生成 apiserver 的证书和私钥。该文件指定了证书的一些属性,如 Common Name(CN)、主机(hosts)、国家(C)、城市(L)、省份(ST)、组织(O)和组织单位(OU)等。hosts 中列出了所有可能作为 apiserver 的 IP 地址,包括本地回环地址、集群中的节点 IP 地址、VIP(用于 keepalived)以及一些 Kubernetes 相关的域名。

  • 然后,使用 cfssl 工具根据 ca.pem、ca-key.pem、ca-config.json 和 apiserver-csr.json 文件生成 apiserver 的证书和私钥,命名为 apiserver.pem 和 apiserver-key.pem。

  • 接下来,脚本定义了 admin-csr.json 文件,用于生成具有 admin 权限的 kubectl 连接集群的证书和私钥。该文件指定了证书的一些属性,如 Common Name(CN)、主机(hosts)、国家(C)、城市(L)、省份(ST)、组织(O)和组织单位(OU)等。这里的 hosts 为空,表示该证书不绑定到特定的主机。

  • 然后,使用 cfssl 工具根据 ca.pem、ca-key.pem、ca-config.json 和 admin-csr.json 文件生成 admin 的证书和私钥,命名为 admin.pem 和 admin-key.pem。

  • 最后,脚本定义了 kube-proxy-csr.json 文件,用于生成 kube-proxy 的证书和私钥。该文件指定了证书的一些属性,如 Common Name(CN)、主机(hosts)、国家(C)、城市(L)、省份(ST)、组织(O)和组织单位(OU)等。这里的 hosts 为空,表示该证书不绑定到特定的主机。

  • 然后,使用 cfssl 工具根据 ca.pem、ca-key.pem、ca-config.json 和 kube-proxy-csr.json 文件生成 kube-proxy 的证书和私钥,命名为 kube-proxy.pem 和 kube-proxy-key.pem。

  • 通过这些步骤,脚本成功生成了用于配置 Kubernetes 集群安全通信的根证书、apiserver 证书、admin 证书和 kube-proxy 证书。这些证书和私钥将在集群中的各个组件之间进行安全的通信和认证。

  • 首先,将master.zipk8s-cert.sh文件上传到/opt/k8s/目录中。可以使用SCP或其他文件传输工具来完成上传。

  • 进入/opt/k8s/目录,解压master.zip压缩包,授予*.sh脚本执行权限:

cd /opt/k8s/
unzip master.zip
chmod +x *.sh

创建kubernetes工作目录

mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs}

这将在/opt/kubernetes/目录下创建bincfgssllogs子目录,用于存放kubernetes相关的二进制文件、配置文件、SSL证书和日志文件。

创建用于生成CA证书和相关组件证书的目录:

mkdir /opt/k8s/k8s-cert

这将在/opt/k8s/目录下创建k8s-cert子目录,用于存放生成CA证书和相关组件证书的脚本和文件。

k8s-cert.sh脚本移动到/opt/k8s/k8s-cert/目录中:

mv /opt/k8s/k8s-cert.sh /opt/k8s/k8s-cert

进入/opt/k8s/k8s-cert/目录并执行脚本:

cd /opt/k8s/k8s-cert/
./k8s-cert.sh

这将进入/opt/k8s/k8s-cert/目录并执行k8s-cert.sh脚本,生成CA证书和相关组件的证书和私钥。

检查

ls *pem

可以看到已经生成了以下证书和私钥文件:

  • CA证书和私钥:ca.pemca-key.pem

  • apiserver证书和私钥:apiserver.pemapiserver-key.pem

复制CA证书、apiserver相关证书和私钥到 kubernetes工作目录的 ssl 子目录中

cp ca*pem apiserver*pem /opt/kubernetes/ssl/

上传 kubernetes-server-linux-amd64.tar.gz 到 /opt/k8s/ 目录中,解压 kubernetes 压缩包

  • 下载地址:https://github.com/kubernetes/kubernetes/blob/release-1.20/CHANGELOG/CHANGELOG-1.20.md

  • 注:打开链接你会发现里面有很多包,下载一个server包就够了,包含了Master和Worker Node二进制文件。

cd /opt/k8s/
tar zxvf kubernetes-server-linux-amd64.tar.gz

复制master组件的关键命令文件到 kubernetes工作目录的 bin 子目录中

进入/opt/k8s/kubernetes/server/bin目录:

cd /opt/k8s/kubernetes/server/bin

复制kube-apiserverkubectlkube-controller-managerkube-scheduler文件到/opt/kubernetes/bin/目录中:

cp kube-apiserver kubectl kube-controller-manager kube-scheduler /opt/kubernetes/bin/

/usr/local/bin/目录中创建符号链接:

ln -s /opt/kubernetes/bin/* /usr/local/bin/

现在,已经成功将master组件的关键命令文件复制到了kubernetes工作目录的bin子目录中,并在/usr/local/bin/目录中创建了符号链接。

创建 bootstrap token 认证文件,apiserver 启动时会调用,然后就相当于在集群内创建了一个这个用户,接下来就可以用 RBAC 给他授权

在master01节点上创建bootstrap token认证文件:

进入/opt/k8s/目录:

cd /opt/k8s/

创建token.sh脚本文件并编辑:

vim token.sh

将以下内容复制粘贴到token.sh文件中:

#!/bin/bash
#获取随机数前16个字节内容,以十六进制格式输出,并删除其中空格
BOOTSTRAP_TOKEN=$(head -c 16 /dev/urandom | od -An -t x | tr -d ' ') 
#生成 token.csv 文件,按照 Token序列号,用户名,UID,用户组 的格式生成
cat > /opt/kubernetes/cfg/token.csv <<EOF
${BOOTSTRAP_TOKEN},kubelet-bootstrap,10001,"system:kubelet-bootstrap"
EOF

保存并关闭文件。

授予token.sh脚本执行权限:

chmod +x token.sh

执行token.sh脚本生成bootstrap token认证文件:

./token.sh

这将生成一个名为token.csv的文件,其中包含了bootstrap token的相关信息。

查看生成的token.csv文件内容:

cat /opt/kubernetes/cfg/token.csv

这将显示token.csv文件的内容,其中包含了bootstrap token的序列号、用户名、UID和用户组。

二进制文件、token、证书都准备好后,开启 apiserver 服务

在master01节点上启动apiserver、scheduler和controller-manager服务,并验证集群组件的状态:

进入/opt/k8s/目录:

cd /opt/k8s/

启动apiserver服务:

  • vim apiserver.sh
#创建 kube-apiserver 启动参数配置文件
MASTER_ADDRESS=$1
ETCD_SERVERS=$2

cat >/opt/kubernetes/cfg/kube-apiserver <<EOF
KUBE_APISERVER_OPTS="--logtostderr=false  \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--etcd-servers=${ETCD_SERVERS} \\
--bind-address=${MASTER_ADDRESS} \\
--secure-port=6443 \\
--advertise-address=${MASTER_ADDRESS} \\
--allow-privileged=true \\
--service-cluster-ip-range=10.0.0.0/24 \\
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,NodeRestriction \\
--authorization-mode=RBAC,Node \\
--enable-bootstrap-token-auth=true \\
--token-auth-file=/opt/kubernetes/cfg/token.csv \\
--service-node-port-range=30000-50000 \\
--kubelet-client-certificate=/opt/kubernetes/ssl/apiserver.pem \\
--kubelet-client-key=/opt/kubernetes/ssl/apiserver-key.pem \\
--tls-cert-file=/opt/kubernetes/ssl/apiserver.pem  \\
--tls-private-key-file=/opt/kubernetes/ssl/apiserver-key.pem \\
--client-ca-file=/opt/kubernetes/ssl/ca.pem \\
--service-account-key-file=/opt/kubernetes/ssl/ca-key.pem \\
--service-account-issuer=api \\
--service-account-signing-key-file=/opt/kubernetes/ssl/apiserver-key.pem \\
--etcd-cafile=/opt/etcd/ssl/ca.pem \\
--etcd-certfile=/opt/etcd/ssl/server.pem \\
--etcd-keyfile=/opt/etcd/ssl/server-key.pem \\
--requestheader-client-ca-file=/opt/kubernetes/ssl/ca.pem \\
--proxy-client-cert-file=/opt/kubernetes/ssl/apiserver.pem \\
--proxy-client-key-file=/opt/kubernetes/ssl/apiserver-key.pem \\
--requestheader-allowed-names=kubernetes \\
--requestheader-extra-headers-prefix=X-Remote-Extra- \\
--requestheader-group-headers=X-Remote-Group \\
--requestheader-username-headers=X-Remote-User \\
--enable-aggregator-routing=true \\
--audit-log-maxage=30 \\
--audit-log-maxbackup=3 \\
--audit-log-maxsize=100 \\
--audit-log-path=/opt/kubernetes/logs/k8s-audit.log"
EOF

#--logtostderr=true:启用日志。输出日志到标准错误控制台,不输出到文件
#--v=4:日志等级。指定输出日志的级别,v=4为调试级别详细输出
#--etcd-servers:etcd集群地址。指定etcd服务器列表(格式://ip:port),逗号分隔
#--bind-address:监听地址。指定 HTTPS 安全接口的监听地址,默认值0.0.0.0
#--secure-port:https安全端口。指定 HTTPS 安全接口的监听端口,默认值6443
#--advertise-address:集群通告地址。通过该 ip 地址向集群其他节点公布 api server 的信息,必
须能够被其他节点访问
#--allow-privileged=true:启用授权。允许拥有系统特权的容器运行,默认值false
#--service-cluster-ip-range:Service虚拟IP地址段。指定 Service Cluster IP 地址段
#--enable-admission-plugins:准入控制模块。kuberneres集群的准入控制机制,各控制模块以插件>的形式依次生效,集群时必须包含ServiceAccount,运行在认证(Authentication)、授权(Authorization)之后,Admission Control是权限认证链上的最后一环, 对请求API资源对象进行修改和校验
#--authorization-mode:认证授权,启用RBAC授权和节点自管理。在安全端口使用RBAC,Node授权模式
,未通过授权的请求拒绝,默认值AlwaysAllow。RBAC是用户通过角色与权限进行关联的模式;Node模>式(节点授权)是一种特殊用途的授权模式,专门授权由kubelet发出的API请求,在进行认证时,先通
过用户名、用户分组验证是否是集群中的Node节点,只有是Node节点的请求才能使用Node模式授权
#--enable-bootstrap-token-auth:启用TLS bootstrap机制。在apiserver上启用Bootstrap Token 认
证
#--token-auth-file=/opt/kubernetes/cfg/token.csv:指定bootstrap token认证文件路径
#--service-node-port-range:指定 Service  NodePort 的端口范围,默认值30000-32767
#–-kubelet-client-xxx:apiserver访问kubelet客户端证书
#--tls-xxx-file:apiserver https证书
#1.20版本必须加的参数:–-service-account-issuer,–-service-account-signing-key-file
#--etcd-xxxfile:连接Etcd集群证书
#–-audit-log-xxx:审计日志
#启动聚合层相关配置:–requestheader-client-ca-file,–proxy-client-cert-file,–proxy-client-key-file,–requestheader-allowed-names,–requestheader-extra-headers-prefix,–requestheader-group-headers,–requestheader-username-headers,–enable-aggregator-routing


#创建 kube-apiserver.service 服务管理文件
cat >/usr/lib/systemd/system/kube-apiserver.service <<EOF
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes

[Service]
EnvironmentFile=-/opt/kubernetes/cfg/kube-apiserver
ExecStart=/opt/kubernetes/bin/kube-apiserver \$KUBE_APISERVER_OPTS
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable kube-apiserver
systemctl restart kube-apiserver

chmod +x apiserver.sh
./apiserver.sh 192.168.41.31 https://192.168.41.31:2379,https://192.168.41.33:2379,https://192.168.41.34:2379

这将启动apiserver服务,并将其绑定到指定的IP地址和etcd集群的地址。

检查apiserver进程是否启动成功:

ps aux | grep kube-apiserver

这将显示与kube-apiserver相关的进程信息。包括etcd服务器地址、绑定地址、安全端口、认证配置等。根据这些信息,kube-apiserver进程似乎已经成功启动并正在运行。

检查安全端口是否监听成功:

netstat -natp | grep 6443

这将显示是否有进程在监听安全端口6443,用于接收HTTPS请求。

启动scheduler服务:

  • vim scheduler.sh
#!/bin/bash
##创建 kube-scheduler 启动参数配置文件
MASTER_ADDRESS=$1

cat >/opt/kubernetes/cfg/kube-scheduler <<EOF
KUBE_SCHEDULER_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--leader-elect=true \\
--kubeconfig=/opt/kubernetes/cfg/kube-scheduler.kubeconfig \\
--bind-address=127.0.0.1"
EOF

#-–kubeconfig:连接 apiserver 用的配置文件,用于识别 k8s 集群
#--leader-elect=true:当该组件启动多个时,自动启动 leader 选举
#k8s中Controller-Manager和Scheduler的选主逻辑:k8s中的etcd是整个集群所有状态信息的存储,涉
及数据的读写和多个etcd之间数据的同步,对数据的一致性要求严格,所以使用较复杂的 raft 算法来
选择用于提交数据的主节点。而 apiserver 作为集群入口,本身是无状态的web服务器,多个 apiserver 服务之间直接负载请求并不需要做选主。Controller-Manager 和 Scheduler 作为任务类型的组件>,比如 controller-manager 内置的 k8s 各种资源对象的控制器实时的 watch apiserver 获取对象最
新的变化事件做期望状态和实际状态调整,调度器watch未绑定节点的pod做节点选择,显然多个这些任
务同时工作是完全没有必要的,所以 controller-manager 和 scheduler 也是需要选主的,但是选主>逻辑和 etcd 不一样的,这里只需要保证从多个 controller-manager 和 scheduler 之间选出一个 leader 进入工作状态即可,而无需考虑它们之间的数据一致和同步。


##生成kube-scheduler证书
cd /opt/k8s/k8s-cert/
#创建证书请求文件
cat > kube-scheduler-csr.json << EOF
{
  "CN": "system:kube-scheduler",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "L": "BeiJing",
      "ST": "BeiJing",
      "O": "system:masters",
      "OU": "System"
    }
  ]
}
EOF

#生成证书
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-scheduler-csr.json | cfssljson -bare kube-scheduler

#生成kubeconfig文件
KUBE_CONFIG="/opt/kubernetes/cfg/kube-scheduler.kubeconfig"
KUBE_APISERVER="https://192.168.41.35:6443"

kubectl config set-cluster kubernetes \
  --certificate-authority=/opt/kubernetes/ssl/ca.pem \
  --embed-certs=true \
  --server=${KUBE_APISERVER} \
  --kubeconfig=${KUBE_CONFIG}
kubectl config set-credentials kube-scheduler \
  --client-certificate=./kube-scheduler.pem \
  --client-key=./kube-scheduler-key.pem \
  --embed-certs=true \
  --kubeconfig=${KUBE_CONFIG}
kubectl config set-context default \
  --cluster=kubernetes \
  --user=kube-scheduler \
  --kubeconfig=${KUBE_CONFIG}
kubectl config use-context default --kubeconfig=${KUBE_CONFIG}


##创建 kube-scheduler.service 服务管理文件
cat >/usr/lib/systemd/system/kube-scheduler.service <<EOF
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/kubernetes/kubernetes

[Service]
EnvironmentFile=-/opt/kubernetes/cfg/kube-scheduler
ExecStart=/opt/kubernetes/bin/kube-scheduler \$KUBE_SCHEDULER_OPTS
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable kube-scheduler
systemctl restart kube-scheduler
chmod +x scheduler.sh
./scheduler.sh

这将启动scheduler服务。

检查scheduler进程是否启动成功:

ps aux | grep kube-scheduler

这将显示与kube-scheduler相关的进程信息,包括日志配置、leader选举、kubeconfig文件等。

启动controller-manager服务:

  • vim controller-manager.sh
#!/bin/bash
##创建 kube-controller-manager 启动参数配置文件
MASTER_ADDRESS=$1

cat >/opt/kubernetes/cfg/kube-controller-manager <<EOF
KUBE_CONTROLLER_MANAGER_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--leader-elect=true \\
--kubeconfig=/opt/kubernetes/cfg/kube-controller-manager.kubeconfig \\
--bind-address=127.0.0.1 \\
--allocate-node-cidrs=true \\
--cluster-cidr=10.244.0.0/16 \\
--service-cluster-ip-range=10.0.0.0/24 \\
--cluster-signing-cert-file=/opt/kubernetes/ssl/ca.pem \\
--cluster-signing-key-file=/opt/kubernetes/ssl/ca-key.pem  \\
--root-ca-file=/opt/kubernetes/ssl/ca.pem \\
--service-account-private-key-file=/opt/kubernetes/ssl/ca-key.pem \\
--cluster-signing-duration=87600h0m0s"
EOF

#––leader-elect:当该组件启动多个时,自动选举(HA)
#-–kubeconfig:连接 apiserver 用的配置文件,用于识别 k8s 集群
#--cluster-signing-cert-file/–-cluster-signing-key-file:自动为kubelet颁发证书的CA,与apiserver保持一致。指定签名的CA机构根证书,用来签名为 TLS BootStrapping 创建的证书和私钥
#--root-ca-file:指定根CA证书文件路径,用来对 kube-apiserver 证书进行校验,指定该参数后,>才会在 Pod 容器的 ServiceAccount 中放置该 CA 证书文件
#--experimental-cluster-signing-duration:设置为 TLS BootStrapping 签署的证书有效时间为10>年,默认为1年


##生成kube-controller-manager证书
cd /opt/k8s/k8s-cert/
#创建证书请求文件
cat > kube-controller-manager-csr.json << EOF
{
  "CN": "system:kube-controller-manager",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
"names": [
    {
      "C": "CN",
      "L": "BeiJing",
      "ST": "BeiJing",
      "O": "system:masters",
      "OU": "System"
    }
  ]
}
EOF

#生成证书
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

#生成kubeconfig文件
KUBE_CONFIG="/opt/kubernetes/cfg/kube-controller-manager.kubeconfig"
KUBE_APISERVER="https://192.168.41.35:6443"

kubectl config set-cluster kubernetes \
  --certificate-authority=/opt/kubernetes/ssl/ca.pem \
  --embed-certs=true \
  --server=${KUBE_APISERVER} \
  --kubeconfig=${KUBE_CONFIG}
kubectl config set-credentials kube-controller-manager \
  --client-certificate=./kube-controller-manager.pem \
  --client-key=./kube-controller-manager-key.pem \
  --embed-certs=true \
  --kubeconfig=${KUBE_CONFIG}
kubectl config set-context default \
  --cluster=kubernetes \
  --user=kube-controller-manager \
  --kubeconfig=${KUBE_CONFIG}
kubectl config use-context default --kubeconfig=${KUBE_CONFIG}


##创建 kube-controller-manager.service 服务管理文件
cat >/usr/lib/systemd/system/kube-controller-manager.service <<EOF
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/kubernetes/kubernetes

[Service]
EnvironmentFile=-/opt/kubernetes/cfg/kube-controller-manager
ExecStart=/opt/kubernetes/bin/kube-controller-manager \$KUBE_CONTROLLER_MANAGER_OPTS
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable kube-controller-manager
systemctl restart kube-controller-manager
chmod +x controller-manager.sh
./controller-manager.sh

这将启动controller-manager服务。

检查controller-manager进程是否启动成功:

ps aux | grep kube-controller-manager

这将显示与kube-controller-manager相关的进程信息。

生成kubectl连接集群的kubeconfig文件:

  • vim admin.sh
#!/bin/bash
mkdir /root/.kube
KUBE_CONFIG="/root/.kube/config"
KUBE_APISERVER="https://192.168.41.31:6443"

cd /opt/k8s/k8s-cert/

kubectl config set-cluster kubernetes \
  --certificate-authority=/opt/kubernetes/ssl/ca.pem \
  --embed-certs=true \
  --server=${KUBE_APISERVER} \
  --kubeconfig=${KUBE_CONFIG}
kubectl config set-credentials cluster-admin \
  --client-certificate=./admin.pem \
  --client-key=./admin-key.pem \
  --embed-certs=true \
  --kubeconfig=${KUBE_CONFIG}
kubectl config set-context default \
  --cluster=kubernetes \
  --user=cluster-admin \
  --kubeconfig=${KUBE_CONFIG}
kubectl config use-context default --kubeconfig=${KUBE_CONFIG}
chmod +x admin.sh
./admin.sh

这将生成一个名为admin.conf的kubeconfig文件,用于连接到集群。

使用kubectl工具查看当前集群组件的状态:

kubectl get cs

这将显示当前集群组件的状态信息。

使用kubectl工具查看版本信息:

kubectl version

这将显示kubectl工具和集群的版本信息。

现在,已经成功启动了apiserver、scheduler和controller-manager服务,并验证了集群组件的状态。

部署Worker Node 组件

在所有node节点上操作

创建 Kubernetes 工作目录:

mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs}

获取 kubelet.sh 和 proxy.sh 脚本:

  • vim kubelet.sh
#!/bin/bash

NODE_ADDRESS=$1
DNS_SERVER_IP=${2:-"10.0.0.2"}

#创建 kubelet 启动参数配置文件
cat >/opt/kubernetes/cfg/kubelet <<EOF
KUBELET_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--hostname-override=${NODE_ADDRESS} \\
--network-plugin=cni \\
--kubeconfig=/opt/kubernetes/cfg/kubelet.kubeconfig \\
--bootstrap-kubeconfig=/opt/kubernetes/cfg/bootstrap.kubeconfig \\
--config=/opt/kubernetes/cfg/kubelet.config \\
--cert-dir=/opt/kubernetes/ssl \\
--pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/google-containers/pause-amd64:3.0"
EOF

#--hostname-override:指定kubelet节点在集群中显示的主机名或IP地址,默认使用主机hostname;kube-proxy和kubelet的此项参数设置必须完全一致
#--network-plugin:启用CNI
#--kubeconfig:指定kubelet.kubeconfig文件位置,当前为空路径,会自动生成,用于如何连接到apiserver,里面含有kubelet证书,master授权完成后会在node节点上生成 kubelet.kubeconfig 文件
#--bootstrap-kubeconfig:指定连接 apiserver 的 bootstrap.kubeconfig 文件
#--config:指定kubelet配置文件的路径,启动kubelet时将从此文件加载其配置
#--cert-dir:指定master颁发的kubelet证书生成目录
#--pod-infra-container-image:指定Pod基础容器(Pause容器)的镜像。Pod启动的时候都会启动一>个这样的容器,每个pod里容器之间的相互通信需要Pause的支持,启动Pause需要Pause基础镜像


#----------------------
#创建kubelet配置文件(该文件实际上就是一个yml文件,语法非常严格,不能出现tab键,冒号后面必
须要有空格,每行结尾也不能有空格)
cat >/opt/kubernetes/cfg/kubelet.config <<EOF
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
address: ${NODE_ADDRESS}
port: 10250
readOnlyPort: 10255
cgroupDriver: cgroupfs
clusterDNS:
- ${DNS_SERVER_IP}
clusterDomain: cluster.local
failSwapOn: false
authentication:
  anonymous:
    enabled: true
EOF

#PS:当命令行参数与此配置文件(kubelet.config)有相同的值时,就会覆盖配置文件中的该值。


#----------------------
#创建 kubelet.service 服务管理文件
cat >/usr/lib/systemd/system/kubelet.service <<EOF
[Unit]
Description=Kubernetes Kubelet
After=docker.service
Requires=docker.service

[Service]
EnvironmentFile=/opt/kubernetes/cfg/kubelet
ExecStart=/opt/kubernetes/bin/kubelet \$KUBELET_OPTS
Restart=on-failure
KillMode=process

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable kubelet
systemctl restart kubelet
  • vim proxy.sh
#!/bin/bash

NODE_ADDRESS=$1

#创建 kube-proxy 启动参数配置文件
cat >/opt/kubernetes/cfg/kube-proxy <<EOF
KUBE_PROXY_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--hostname-override=${NODE_ADDRESS} \\
--cluster-cidr=10.244.0.0/16 \\
--proxy-mode=ipvs \\
--kubeconfig=/opt/kubernetes/cfg/kube-proxy.kubeconfig"
EOF

#--hostnameOverride: 参数值必须与 kubelet 的值一致,否则 kube-proxy 启动后会找不到该 Node>,从而不会创建任何 ipvs 规则
#--cluster-cidr:指定 Pod 网络使用的聚合网段,Pod 使用的网段和 apiserver 中指定的 service 的 cluster ip 网段不是同一个网段。 kube-proxy 根据 --cluster-cidr 判断集群内部和外部流量,
指定 --cluster-cidr 选项后 kube-proxy 才会对访问 Service IP 的请求做 SNAT,即来自非 Pod 网
络的流量被当成外部流量,访问 Service 时需要做 SNAT。
#--kubeconfig: 指定连接 apiserver 的 kubeconfig 文件
#--proxy-mode:指定流量调度模式为ipvs模式,可添加--ipvs-scheduler选项指定ipvs调度算法(rr|lc|dh|sh|sed|nq)
#rr: round-robin,轮询。
#lc: least connection,最小连接数。
#dh: destination hashing,目的地址哈希。
#sh: source hashing ,原地址哈希。
#sed: shortest expected delay,最短期望延时。
#nq: never queue ,永不排队。

#----------------------
#创建 kube-proxy.service 服务管理文件
cat >/usr/lib/systemd/system/kube-proxy.service <<EOF
[Unit]
Description=Kubernetes Proxy
After=network.target

[Service]
EnvironmentFile=-/opt/kubernetes/cfg/kube-proxy
ExecStart=/opt/kubernetes/bin/kube-proxy \$KUBE_PROXY_OPTS
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable kube-proxy
systemctl restart kube-proxy

或者把 你的node.zip 文件上传到 /opt 目录中,并解压缩该压缩包,获取脚本

cd /opt/
unzip node.zip
chmod +x kubelet.sh proxy.sh

master01 节点上操作

进入 kubelet 和 kube-proxy 的二进制文件所在目录:

使用 scp 命令将 kubelet 和 kube-proxy 拷贝到 node 节点上

cd /opt/k8s/kubernetes/server/bin
scp kubelet kube-proxy root@192.168.41.33:/opt/kubernetes/bin/
scp kubelet kube-proxy root@192.168.41.34:/opt/kubernetes/bin/

创建一个目录用于存放 kubeconfig 文件,并进入该目录:

mkdir /opt/k8s/kubeconfig
cd /opt/k8s/kubeconfig

为 kubelet 和 kube-proxy 生成初次加入集群的引导 kubeconfig 文件和 kube-proxy.kubeconfig 文件。

生成 kubeconfig.sh 的脚本,将其上传到 /opt/k8s/kubeconfig 目录中,并为脚本添加执行权限:

  • vim kubeconfig.sh
#!/bin/bash
#example: kubeconfig 192.168.41.31 /opt/k8s/k8s-cert/
#创建bootstrap.kubeconfig文件
#该文件中内置了 token.csv 中用户的 Token,以及 apiserver CA 证书;kubelet 首次启动会加载此
文件,使用 apiserver CA 证书建立与 apiserver 的 TLS 通讯,使用其中的用户 Token 作为身份标>识向 apiserver 发起 CSR 请求

BOOTSTRAP_TOKEN=$(awk -F ',' '{print $1}' /opt/kubernetes/cfg/token.csv)
APISERVER=$1
SSL_DIR=$2

export KUBE_APISERVER="https://$APISERVER:6443"

# 设置集群参数
kubectl config set-cluster kubernetes \
  --certificate-authority=$SSL_DIR/ca.pem \
  --embed-certs=true \
  --server=${KUBE_APISERVER} \
  --kubeconfig=bootstrap.kubeconfig
#--embed-certs=true:表示将ca.pem证书写入到生成的bootstrap.kubeconfig文件中

# 设置客户端认证参数,kubelet 使用 bootstrap token 认证
kubectl config set-credentials kubelet-bootstrap \
  --token=${BOOTSTRAP_TOKEN} \
  --kubeconfig=bootstrap.kubeconfig

# 设置上下文参数
kubectl config set-context default \
  --cluster=kubernetes \
  --user=kubelet-bootstrap \
  --kubeconfig=bootstrap.kubeconfig

# 使用上下文参数生成 bootstrap.kubeconfig 文件
kubectl config use-context default --kubeconfig=bootstrap.kubeconfig

#----------------------

#创建kube-proxy.kubeconfig文件
# 设置集群参数
kubectl config set-cluster kubernetes \
  --certificate-authority=$SSL_DIR/ca.pem \
  --embed-certs=true \
  --server=${KUBE_APISERVER} \
  --kubeconfig=kube-proxy.kubeconfig

# 设置客户端认证参数,kube-proxy 使用 TLS 证书认证
kubectl config set-credentials kube-proxy \
  --client-certificate=$SSL_DIR/kube-proxy.pem \
  --client-key=$SSL_DIR/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

# 使用上下文参数生成 kube-proxy.kubeconfig 文件
kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig
chmod +x kubeconfig.sh

执行 kubeconfig.sh 脚本,生成 kubelet 和 kube-proxy 的 kubeconfig 文件,并传入数据。

kubeconfig 文件是 Kubernetes 组件(如 kubelet、kube-proxy)用来连接到 API Server 的配置文件。它包含了以下信息:

  • 集群参数:包括 CA 证书和 API Server 地址。CA 证书用于验证 API Server 的身份,确保通信的安全性。API Server 地址指定了组件连接的 Kubernetes 集群的 API Server 的位置。

  • 客户端参数:包括组件的证书和私钥。这些证书和私钥用于组件与 API Server 进行身份验证和安全通信。

  • 集群上下文参数:包括集群名称和用户名。集群名称用于标识不同的 Kubernetes 集群,而用户名用于标识组件的身份。

通过在启动组件时指定不同的 kubeconfig 文件,可以切换到不同的集群,并与相应的 API Server 建立连接。这使得 Kubernetes 组件能够在多个集群之间进行灵活的切换和管理。

./kubeconfig.sh 192.168.41.31 /opt/k8s/k8s-cert/

以上步骤将在 master01 节点上将 kubelet 和 kube-proxy 的二进制文件拷贝到 node 节点,并生成 kubelet 和 kube-proxy 的 kubeconfig 文件。

将配置文件 bootstrap.kubeconfig 和 kube-proxy.kubeconfig 拷贝到node节点上:

scp bootstrap.kubeconfig kube-proxy.kubeconfig root@192.168.41.33:/opt/kubernetes/cfg/
scp bootstrap.kubeconfig kube-proxy.kubeconfig root@192.168.41.34:/opt/kubernetes/cfg/

进行 RBAC 授权,为了使用户 kubelet-bootstrap 能够有权限发起 CSR 请求证书

kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --user=kubelet-bootstrap

如果执行失败,可以先将 kubectl 绑定到默认的 cluster-admin 管理员集群角色,以授予集群操作权限:

kubectl create clusterrolebinding cluster-system-anonymous --clusterrole=cluster-admin --user=system:anonymous
  • 在 Kubernetes 中,kubelet使用TLS Bootstrapping机制来自动完成与kube-apiserver的注册。当node节点数量较大或需要自动扩容时,这种机制非常有用。

  • 当Master apiserver启用TLS认证后,node节点上的kubelet组件想要加入集群,必须使用由CA签发的有效证书与apiserver进行通信。当node节点数量很多时,手动签署证书是一项繁琐的任务。因此,Kubernetes引入了TLS bootstrapping机制来自动颁发客户端证书。kubelet会以一个低权限用户自动向apiserver申请证书,kubelet的证书由apiserver动态签署。

  • kubelet在首次启动时,通过加载bootstrap.kubeconfig中的用户令牌和apiserver的CA证书发起首次CSR(证书签名请求)请求。这个令牌预先内置在apiserver节点的token.csv文件中,其身份为kubelet-bootstrap用户和system:kubelet-bootstrap用户组。为了确保首次CSR请求成功(不被apiserver拒绝),需要先创建一个ClusterRoleBinding,将kubelet-bootstrap用户与内置的system:node-bootstrapper ClusterRole进行绑定(可以通过kubectl get clusterroles进行查询),以使其能够发起CSR认证请求。

  • TLS bootstrapping时的证书实际上是由kube-controller-manager组件进行签署的,也就是说证书的有效期由kube-controller-manager组件控制。kube-controller-manager组件提供了一个--experimental-cluster-signing-duration参数,用于设置签署证书的有效时间,默认为8760小时(1年)。可以将其修改为87600小时(10年),以延长TLS bootstrapping签署证书的有效期。

  • 换句话说,kubelet在首次访问API Server时使用令牌进行认证,一旦通过认证,Controller Manager将为kubelet生成一个证书,以后的访问都将使用证书进行认证。

node01 节点上操作

启动 kubelet 服务:

cd /opt/
./kubelet.sh 192.168.41.33

这条命令将在 /opt/ 目录下启动 kubelet 服务,并指定节点的 IP 地址为 192.168.41.33。

master01 节点上操作

检查 node01 节点的证书签发请求(CSR)状态

ps aux | grep kubelet

检查 kubelet 发起的 CSR 请求:

kubectl get csr

运行了kubectl get csr命令来获取证书签名请求(Certificate Signing Request)的信息。如果状态为 "Pending",表示等待集群给该节点签发证书。

输出结果中包含以下列:

  • NAME:证书签名请求的名称,这里是"node-csr-ECT0OZIoEgnABcwFycMqQbf-SxLl3enQC-j27UHAnzc"。

  • AGE:证书签名请求的年龄,这里是6分钟34秒。

  • SIGNERNAME:签名者的名称,这里是"kubernetes.io/kube-apiserver-client-kubelet",表示该证书签名请求是由kube-apiserver签名的。

  • REQUESTOR:请求者的身份,这里是"kubelet-bootstrap",表示该证书签名请求是由kubelet-bootstrap用户发起的。

  • CONDITION:证书签名请求的状态,这里是"Pending",表示请求仍在等待处理。

这个命令的输出显示了一个待处理的证书签名请求,它是由kubelet-bootstrap用户发起的,并且需要kube-apiserver进行签名。

批准 CSR 请求:

使用 kubectl certificate approve 命令

kubectl certificate approve node-csr-ECT0OZIoEgnABcwFycMqQbf-SxLl3enQC-j27UHAnzc

这条命令用于批准 CSR 请求,将其状态从 "Pending" 更改为 "Approved,Issued",表示已授权并签发了证书

再次检查 CSR 状态,使用 kubectl get csr 命令:

kubectl get csr

查看节点状态,使用 kubectl get node 命令:

kubectl get node

这条命令用于查看节点的状态。在这里,它显示了一个名为 "192.168.41.31" 的节点,其状态为 "NotReady",表示节点还没有准备就绪。是因为网络插件还没有部署,节点会没有准备就绪 NotReady

node01 节点上操作:

加载 ip_vs 模块:

for i in $(ls /usr/lib/modules/$(uname -r)/kernel/net/netfilter/ipvs|grep -o "^[^.]*");do echo $i; /sbin/modinfo -F filename $i >/dev/null 2>&1 && /sbin/modprobe $i;done

这条命令用于加载 ip_vs 模块,它会遍历 /usr/lib/modules/$(uname -r)/kernel/net/netfilter/ipvs 目录下的文件,并加载这些模块。

启动 proxy 服务:

cd /opt/
./proxy.sh 192.168.41.33

这条命令将在 /opt/ 目录下启动 proxy 服务,并指定节点的 IP 地址为 192.168.41.33。

检查 proxy 服务是否启动:

ps aux | grep kube-proxy

这条命令用于检查 kube-proxy 进程是否正在运行。它会列出所有包含 "kube-proxy" 的进程。

部署 CNI 网络组件

部署 flannel

node01 节点上操作

首先,将 cni-plugins-linux-amd64-v0.8.6.tgz 和 flannel.tar 上传到 /opt 目录中。

cni-plugins-linux-amd64-v0.8.6.tgz 是 CNI 网络组件的压缩文件,flannel.tar 是 flannel 的镜像文件。

进入 /opt 目录:这一步是切换当前工作目录到 /opt 目录,以便后续操作在该目录下进行。

cd /opt/

使用 Docker 加载 flannel.tar 镜像,以便后续在节点上运行 flannel 容器。

docker load -i flannel.tar
  • docker load:这是 Docker 命令的一部分,用于加载镜像。

  • -i flannel.tar-i 参数指定要加载的镜像文件,这里是 flannel.tar

执行该命令后,Docker 引擎将读取 flannel.tar 文件,并将其中的镜像加载到本地的 Docker 引擎中。加载后的镜像可以通过 docker images 命令查看到,并可以使用 docker run 命令来创建和运行容器。

创建 /opt/cni/bin 目录:

mkdir -p /opt/cni/bin

这一步是在 /opt 目录下创建一个名为 cni/bin 的子目录,用于存放 CNI 网络组件的二进制文件。

解压 cni-plugins-linux-amd64-v0.8.6.tgz 文件到 /opt/cni/bin 目录中:

tar zxvf cni-plugins-linux-amd64-v0.8.6.tgz -C /opt/cni/bin

这一步是将 cni-plugins-linux-amd64-v0.8.6.tgz 文件解压缩,并将其中的二进制文件解压到 /opt/cni/bin 目录中,以便后续在节点上使用 CNI 网络组件。

通过以上步骤,可以在 node01 节点上成功部署 CNI 网络组件和 flannel,并进行后续的网络配置和使用。

master01 节点上操作

首先,将 kube-flannel.yml 文件上传到 /opt/k8s 目录中。这个文件是用于部署 flannel CNI 网络的配置文件。

进入 /opt/k8s 目录:

cd /opt/k8s

这一步是为了确保在正确的目录下进行后续操作。

使用 kubectl 命令应用 kube-flannel.yml 文件:

kubectl apply -f kube-flannel.yml

这一步将根据 kube-flannel.yml 文件中的配置信息,部署 flannel CNI 网络。

使用 kubectl 命令检查 kube-system 命名空间下的 Pod 状态:

kubectl get pods -n kube-system

这一步将显示 kube-system 命名空间下的 Pod 列表,应该能够看到名为 kube-flannel-ds-xxxxx 的 Pod,其中 "xxxxx" 是一串随机字符。如果该 Pod 的状态为 "Running",则表示 flannel CNI 网络已成功部署。

使用 kubectl 命令检查节点状态:

kubectl get nodes

这一步将显示集群中所有节点的状态。应该能够看到 master01 节点的状态。

完成以上步骤后,已成功在 master01 节点上部署了 flannel CNI 网络,并确认了节点的状态。现在可以继续进行其他操作或配置。

部署 Calico

k8s 组网Calico方案与flannel方案区别

Flannel方案: Flannel使用隧道技术将发往容器的数据包进行封装,并通过隧道将封装后的数据包发送到运行目标Pod的节点上。目标节点负责解封装数据包,并将解封装后的数据包发送到目标Pod。这种方案对数据通信性能有一定的影响,因为数据包需要经过封装和解封装的过程。

Calico方案: Calico不使用隧道或NAT来实现转发,而是将主机视为Internet中的路由器。它使用BGP(Border Gateway Protocol)同步路由,并使用iptables来实现安全访问策略,实现跨主机的转发。Calico采用直接路由的方式,不需要修改报文数据,因此性能损耗较低。

在Calico方案中,每个节点都维护着自己的路由表,这样可以实现高效的数据转发。然而,在网络比较复杂的场景下,路由表可能会变得复杂,对运维人员提出了较高的要求,需要仔细管理和维护路由表。

总结起来,Flannel方案使用隧道技术进行数据封装和解封装,对数据通信性能有一定的影响。而Calico方案采用直接路由的方式,性能损耗较低,不需要修改报文数据。然而,Calico方案在网络复杂的场景下可能需要管理复杂的路由表。选择适合的组网方案需要综合考虑性能、复杂性和管理要求等因素。

master01 节点上操作

首先,将 calico.yaml 文件上传到 /opt/k8s 目录中。这个文件是用于部署 Calico CNI 网络的配置文件。

进入 /opt/k8s 目录:

cd /opt/k8s

这一步是为了确保在正确的目录下进行后续操作。

使用 vim 编辑 calico.yaml 文件:

vim calico.yaml

这一步将打开 calico.yaml 文件以进行编辑。需要修改其中的 CALICOIPV4POOLCIDR 字段的值,使其与之前 kube-controller-manager 配置文件中指定的 cluster-cidr 网段相同。

应用 calico.yaml 文件:

kubectl apply -f calico.yaml

这一步将使用 kubectl 命令应用 calico.yaml 文件,以部署 Calico CNI 网络。

检查 Calico Pod 的运行状态:

kubectl get pods -n kube-system

这一步将显示 kube-system 命名空间中的 Pod 列表。确保 calico-kube-controllers 和 calico-node 的状态为 Running,表示 Calico Pod 正在运行。

如果

  • calico-kube-controllers Pod 的状态为 ContainerCreating,表示该 Pod 正在创建容器。请耐心等待一段时间,直到该 Pod 的状态变为 Running。

  • calico-node Pod 的状态为 Init:0/3,表示该 Pod 正在进行初始化。这是 Calico CNI 网络的一部分,它需要一些时间来完成初始化过程。请耐心等待一段时间,直到该 Pod 的状态变为 Running。

  • kube-flannel-ds Pod 的状态为 Running,表示 Flannel CNI 网络已成功部署并正在运行。

检查节点的准备就绪状态:

kubectl get nodes

这一步将显示节点的列表,并显示节点的状态。等待节点的状态变为 Ready,表示节点已准备就绪,Calico 网络已成功部署。

完成以上步骤后, master01 节点上将成功部署 Calico CNI 网络,并且节点将准备就绪。可以继续进行其他操作或部署其他组件。

部署node02 节点

node01 节点上操作

进入 /opt 目录:

cd /opt/

使用 scp 命令将 kubelet.sh 和 proxy.sh 文件复制到 node02 节点的 /opt/ 目录中:

scp kubelet.sh proxy.sh root@192.168.41.34:/opt/

使用 scp 命令将 /opt/cni 目录复制到 node02 节点的 /opt/ 目录中:

scp -r /opt/cni root@192.168.41.34:/opt/

node02 节点上操作:

进入 /opt 目录:

cd /opt/

赋予 kubelet.sh 文件执行权限:

chmod +x kubelet.sh

执行 kubelet.sh 脚本,并指定 node02 节点的 IP 地址作为参数:

./kubelet.sh 192.168.41.34

这一步将启动 kubelet 服务,并将 node02 节点注册到 Kubernetes 集群中,其中 192.168.41.34 是 node02 节点的 IP 地址。

通过以上步骤,可以在 node02 节点上成功部署 kubelet 服务,并将其加入到 Kubernetes 集群中。

master01 节点上操作

获取 CSR(证书签名请求)的状态:

kubectl get csr

        这将列出当前的 CSR 请求及其状态。

通过 CSR 请求批准节点的证书签名请求

        例如,对于名为 node-csr-R8NRrFGxG66yIFyeI0su05vZcDevip1G61B6qIxWtDQ 的 CSR 请求,使用以下命令进行批准:

kubectl certificate approve node-csr-R8NRrFGxG66yIFyeI0su05vZcDevip1G61B6qIxWtDQ

        这将批准该 CSR 请求,使节点的证书签名状态变为 Approved,Issued。

再次使用以下命令获取 CSR 的状态,确认节点的证书签名状态已更新:

kubectl get csr

        确保名为 node-csr-R8NRrFGxG66yIFyeI0su05vZcDevip1G61B6qIxWtDQ 的 CSR 请求的状态为 Approved,Issued。

加载 ipvs 模块。使用以下命令加载 ipvs 模块:

for i in $(ls /usr/lib/modules/$(uname -r)/kernel/net/netfilter/ipvs|grep -o "^[^.]*");do echo $i; /sbin/modinfo -F filename $i >/dev/null 2>&1 && /sbin/modprobe $i;done

        这将加载所需的 ipvs 模块。

使用 proxy.sh 脚本启动 proxy 服务。进入 /opt/ 目录,赋予 proxy.sh 文件执行权限,并执行该脚本

        指定 node02 节点的 IP 地址作为参数:(proxy.sh之前在node01使用过)

cd /opt/
chmod +x proxy.sh
./proxy.sh 192.168.41.34

        这将启动 proxy 服务,并将其配置为使用 node02 节点的 IP 地址。

查看群集中的节点状态:

kubectl get nodes

        这将显示群集中所有节点的状态,包括已经加入的节点。

        通过以上步骤,可以在 master01 节点上完成 CSR 的批准、加载 ipvs 模块以及启动 proxy 服务,并通过 kubectl 命令查看群集中的节点状态。

部署 CoreDNS

        CoreDNS可以用作Kubernetes集群中的默认DNS服务器,用于解析集群内部的service资源的域名和IP地址之间的映射关系。它可以根据Kubernetes的服务发现机制自动更新DNS记录,使得在集群内部可以通过域名来访问和发现服务。

在所有 node 节点上操作

coredns.tar文件上传到每个节点的/opt目录中。

登录到每个节点并导入Docker镜像

        使用cd命令切换到/opt目录,然后运行以下命令:

cd /opt
docker load -i coredns.tar

        这将加载CoreDNS镜像到Docker中。

        完成这些步骤后,已经在所有节点上成功部署了CoreDNS。接下来,可以继续配置和使用CoreDNS来为集群中的service资源创建域名与IP的对应关系解析。

在 master01 节点上操作

coredns.yaml文件上传到/opt/k8s目录中。

登录到master01节点部署CoreDNS:

        并使用cd命令切换到/opt/k8s目录。然后,运行以下命令来部署CoreDNS:

cd /opt/k8s
kubectl apply -f coredns.yaml

        这将使用kubectl命令将coredns.yaml文件中定义的配置部署到Kubernetes集群中。

来检查CoreDNS的部署状态:

kubectl get pods -n kube-system

        应该会看到类似以下输出的结果:

NAME                     READY   STATUS    RESTARTS   AGE
coredns-5ffbfd976d-j6shb 1/1     Running   0          32s

        这表示CoreDNS已成功部署并正在运行。

运行以下命令来测试DNS解析:

kubectl run -it --rm dns-test --image=busybox:1.28.4 sh

        这将创建一个临时的BusyBox容器,并进入其命令行界面。

在BusyBox容器的命令行界面中,运行以下命令来进行DNS解析测试:

nslookup kubernetes

        应该会看到类似以下输出的结果:

Server:    10.0.0.2
Address 1: 10.0.0.2 kube-dns.kube-system.svc.cluster.local

Name:      kubernetes
Address 1: 10.0.0.1 kubernetes.default.svc.cluster.local

        这表示DNS解析成功,kubernetes域名解析到了相应的IP地址。

        通过按照以上步骤操作,已在master01节点上成功部署和测试了CoreDNS。

        如果在使用kubectl run命令时出现以下错误:

[root@master01 k8s]# kubectl run -it --image=busybox:1.28.4 sh
If you don't see a command prompt, try pressing enter.
Error attaching, falling back to logs: unable to upgrade connection: Forbidden (user=system:anonymous, verb=create, resource=nodes, subresource=proxy)
Error from server (Forbidden): Forbidden (user=system:anonymous, verb=get, resource=nodes, subresource=proxy) ( pods/log sh)

        需要添加 rbac的权限 直接使用kubectl绑定 clusteradmin 管理员集群角色 授权操作权限

        这表示当前用户没有足够的权限执行该命令。解决这个问题,可以使用kubectl create clusterrolebinding命令创建一个clusterrolebinding对象,为system:anonymous用户分配cluster-admin角色权限。具体操作如下:

[root@master01 k8s]# kubectl create clusterrolebinding cluster-system-anonymous --clusterrole=cluster-admin --user=system:anonymous
clusterrolebinding.rbac.authorization.k8s.io/cluster-system-anonymous created

        通过以上操作,已经为system:anonymous用户分配了cluster-admin角色权限,可以再次尝试运行kubectl run命令,应该可以成功执行了。

部署master02 节点

在master01 节点上操作

从 master01 节点上拷贝证书文件、各master组件的配置文件和服务管理文件到 master02 节点

scp -r /opt/etcd/ root@192.168.41.32:/opt/
scp -r /opt/kubernetes/ root@192.168.41.32:/opt
scp -r /root/.kube root@192.168.41.32:/root
scp /usr/lib/systemd/system/{kube-apiserver,kube-controller-manager,kube-scheduler}.service root@192.168.42.32:/usr/lib/systemd/system/

修改配置文件kube-apiserver中的IP

vim /opt/kubernetes/cfg/kube-apiserver
KUBE_APISERVER_OPTS="--logtostderr=true \
--v=4 \
--etcd-servers=https://192.168.41.31:2379,https://192.168.41.33:2379,https://192.168.41.34:2379 \
--bind-address=192.168.41.32 \                #修改
--secure-port=6443 \
--advertise-address=192.168.41.32 \            #修改
......

master02 节点上启动各服务并设置开机自启

systemctl start kube-apiserver.service
systemctl enable kube-apiserver.service
systemctl start kube-controller-manager.service
systemctl enable kube-controller-manager.service
systemctl start kube-scheduler.service
systemctl enable kube-scheduler.service

查看node节点状态

ln -s /opt/kubernetes/bin/* /usr/local/bin/
kubectl get nodes
kubectl get nodes -o wide            #-o=wide:输出额外信息;对于Pod,将输出Pod所在的Node名
  • ln -s /opt/kubernetes/bin/* /usr/local/bin/ 这个命令将/opt/kubernetes/bin/目录下的所有文件链接到/usr/local/bin/目录下,以便可以直接在命令行中运行这些二进制文件。

  • kubectl get nodes 这个命令将显示集群中所有节点的状态。将看到每个节点的名称、状态、角色和版本等信息。

  • kubectl get nodes -o wide 这个命令将以更详细的方式显示节点的状态,包括节点的IP地址、所在的区域和可用性等信息。

在执行上述命令时,如果在master02节点上执行,将只能看到从etcd中获取的节点信息,而实际上节点与master02节点之间并没有建立通信连接。为了建立节点与master节点之间的连接,可以使用一个虚拟IP(VIP)来关联它们。

负载均衡部署

配置load balancer集群双机热备负载均衡

nginx实现负载均衡,keepalived实现双机热备

在lb01、lb02节点上操作

配置Nginx的官方在线yum源和本地Nginx的yum源并安装nginx

cat > /etc/yum.repos.d/nginx.repo << 'EOF'
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
EOF
yum install nginx -y

以上命令将配置Nginx的yum源并安装Nginx软件包

修改nginx配置文件,配置四层反向代理负载均衡,指定k8s群集2台master的节点ip和6443端口

  • 打开Nginx配置文件:
vim /etc/nginx/nginx.conf
  • 在配置文件中找到events块,并确保worker_connections的值为1024:
events {
    worker_connections  1024;
}
  • 添加以下内容来配置四层反向代理负载均衡:
stream {
    log_format  main  '$remote_addr $upstream_addr - [$time_local] $status $upstream_bytes_sent';
    access_log  /var/log/nginx/k8s-access.log  main;

    upstream k8s-apiserver {
        server 192.168.41.31:6443;
        server 192.168.41.32:6443;
    }

    server {
        listen 6443;
        proxy_pass k8s-apiserver;
    }
}

http {
......

在上述配置中,upstream块定义了两个Kubernetes Master节点的IP和端口。

  • 重新加载Nginx配置文件以使更改生效:
nginx -s reload

现在,Nginx将通过四层反向代理负载均衡将流量转发到指定的Kubernetes Master节点的IP和6443端口。

  • 检查配置文件语法
nginx -t   

启动nginx服务,查看已监听6443端口

systemctl start nginx
systemctl enable nginx
netstat -natp | grep nginx 

部署keepalived服务

yum install keepalived -y

修改keepalived配置文件以配置高可用性

  • 打开Keepalived配置文件:
vim /etc/keepalived/keepalived.conf
  • 在配置文件中找到global_defs块,并根据需要进行以下修改:

  • notification_email:将接收邮件地址修改为希望接收通知的电子邮件地址。

  • notification_email_from:将邮件发送地址修改为希望作为发件人的电子邮件地址。

  • smtp_server:将SMTP服务器地址修改为你的SMTP服务器地址。

  • router_id:将NGINX_MASTER修改为lb01节点的标识,将NGINX_BACKUP修改为lb02节点的标识。

global_defs {
   # 接收邮件地址
   notification_email {
     acassen@firewall.loc
     failover@firewall.loc
     sysadmin@firewall.loc
   }
   # 邮件发送地址
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id NGINX_MASTER    #lb01节点的为 NGINX_MASTER,lb02节点的为 NGINX_BACKUP
}
  • 添加以下内容来配置周期性执行的脚本:
vrrp_script check_nginx {
    script "/etc/nginx/check_nginx.sh"
}

在上述配置中,check_nginx.sh是用于检查Nginx存活性的脚本路径。请确保该脚本存在,并根据实际情况修改路径。

  • 在配置文件中找到vrrp_instance VI_1块,并根据需要进行以下修改:

  • state:将MASTER修改为lb01节点的状态,将BACKUP修改为lb02节点的状态。

  • interface:将ens33修改为要使用的网卡名称。

  • virtual_router_id:将51修改为两个节点之间相同的虚拟路由器ID。

  • priority:将100修改为lb01节点的优先级,将90修改为lb02节点的优先级。

  • virtual_ipaddress:将192.168.41.100/24修改为要使用的虚拟IP地址。

vrrp_instance VI_1 {
    state MASTER            #lb01节点的为 MASTER,lb02节点的为 BACKUP
    interface ens33            #指定网卡名称 ens33
    virtual_router_id 51    #指定vrid,两个节点要一致
    priority 100            #lb01节点的为 100,lb02节点的为 90
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.41.100/24    #指定 VIP
    }
    track_script {
        check_nginx            #指定vrrp_script配置的脚本
    }
}
  • vrrp_instance VI_1块中找到track_script,并将其设置为之前定义的脚本名称:
track_script {
    check_nginx
}
  • 重新加载Keepalived配置文件以使更改生效:
systemctl reload keepalived

现在,就已经修改好了Keepalived配置文件以配置高可用性(HA)

创建nginx状态检查的脚本

  • 打开一个文本编辑器,并创建一个名为check_nginx.sh的文件:
vim /etc/nginx/check_nginx.sh

#!/bin/bash
count=$(ps -ef | grep nginx | egrep -cv "grep|$$")

if [ "$count" -eq 0 ]; then
    systemctl stop keepalived
fi

上述脚本会检查Nginx进程的数量。如果没有找到Nginx进程,则停止Keepalived服务。

  • 授予脚本执行权限:
chmod +x /etc/nginx/check_nginx.sh
  • 启动Keepalived服务(要确保在启动Keepalived服务之前已经启动了Nginx服务):
systemctl start keepalived
  • 设置Keepalived服务开机自启动:
systemctl enable keepalived
  • 检查VIP是否生成:
ip a

        在输出中看到VIP的信息,以确认VIP是否已成功生成。

        现在,已经创建了一个用于检查Nginx状态的脚本,并启动了Keepalived服务。

在node节点上修改配置

要将Node节点上的bootstrap.kubeconfigkubelet.kubeconfigkube-proxy.kubeconfig配置文件中的服务器地址修改为VIP

  • 进入配置文件所在目录,打开bootstrap.kubeconfig文件:
cd /opt/kubernetes/cfg/
vim bootstrap.kubeconfig
  • server字段的值修改为VIP地址,例如:
server: https://192.168.41.100:6443
  • 打开kubelet.kubeconfig文件:
vim kubelet.kubeconfig
  • server字段的值修改为VIP地址,例如:
server: https://192.168.41.100:6443
  • 打开kube-proxy.kubeconfig文件:
vim kube-proxy.kubeconfig
  • server字段的值修改为VIP地址,例如:
server: https://192.168.41.100:6443
  • 重启kubeletkube-proxy服务以使配置生效:
systemctl restart kubelet.service
systemctl restart kube-proxy.service

        现在,Node节点上的bootstrap.kubeconfigkubelet.kubeconfigkube-proxy.kubeconfig配置文件中的服务器地址已经修改为VIP地址

在 lb01 上查看 nginx 和 node 、 master 节点的连接状态

netstat -natp | grep nginx

在 master01 节点上操作

  • 测试创建Pod:
kubectl run nginx --image=nginx
  • 查看Pod的状态信息:
kubectl get pods

        看到Pod的状态为ContainerCreating,表示正在创建中。当Pod的状态变为Running时,表示创建完成并正在运行。

  • 使用kubectl get pods -o wide命令以获取更详细的信息,包括Pod的IP地址和所在的Node节点:
kubectl get pods -o wide

        在输出中,将看到Pod的状态为Running,READY为1/1,表示Pod中的容器正常运行。

  • 在对应网段的Node节点上操作,可以使用浏览器或curl命令访问Pod的IP地址,例如:
curl ip

        这将向Pod发送请求并获取响应。

  • 在master01节点上查看Pod的日志
kubectl logs nginx-dbddb74b8-nf9sk

        这将显示Pod的日志信息。请注意,上述命令中的Pod名称(例如nginx-dbddb74b8-nf9sk)会因为你的环境和实际情况而有所不同。要根据实际输出进行相应的调整。

部署 Dashboard

        Dashboard是Kubernetes的一个Web用户界面,用于管理和监控Kubernetes集群。它提供了一个可视化的方式来查看和操作集群中的资源,包括Pod、服务、部署、命名空间等。

通过Dashboard,可以执行以下操作:

  • 查看集群状态:可以查看集群中所有节点的状态、资源使用情况、事件和日志等信息。

  • 创建和管理资源:可以创建和管理各种Kubernetes资源,如Pod、服务、部署、副本集等。可以通过Dashboard创建、编辑和删除这些资源,并监控它们的状态和健康状况。

  • 执行命令和调试:可以在Dashboard中执行命令和调试操作,如查看容器日志、进入容器的终端等。

  • 监控和警报:Dashboard提供了一些监控和警报功能,可以帮助监控集群中的资源使用情况、性能指标和事件,并设置警报规则以及接收通知。

  • 访问控制和权限管理:Dashboard支持Kubernetes的RBAC(Role-Based Access Control)机制,可以根据用户角色和权限来限制对集群资源的访问和操作。

仪表板是基于Web的Kubernetes用户界面。可以使用仪表板将容器化应用程序部署到Kubernetes集群,对容器化应用程序进行故障排除,并管理集群本身及其伴随资源。可以使用仪表板来概述群集上运行的应用程序,以及创建或修改单个Kubernetes资源(例如deployment,job,daemonset等)。例如,可以使用部署向导扩展部署,启动滚动更新,重新启动Pod或部署新应用程序。仪表板还提供有关群集中Kubernetes资源状态以及可能发生的任何错误的信息。

在Master01节点上进行操作

  • 上传 recommended.yaml 文件到 /opt/k8s 目录中

  • 进入/opt/k8s目录并创建或编辑recommended.yaml文件:

cd /opt/k8s
vim recommended.yaml
  • 将以下内容添加到recommended.yaml文件中,以修改Dashboard的Service类型为NodePort并指定端口号:
kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  ports:
    - port: 443
      targetPort: 8443
      nodePort: 30001
  type: NodePort
  selector:
    k8s-app: kubernetes-dashboard

在上述配置中,我们将Service类型修改为NodePort,并指定了NodePort的值为30001。

  • 应用修改后的配置文件:
kubectl apply -f recommended.yaml
  • 创建一个Service Account并将其绑定到默认的cluster-admin管理员集群角色:
kubectl create serviceaccount dashboard-admin -n kube-system
kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin
  • 获取用于登录Dashboard的Token:
kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')

这将显示一个包含Token的输出。请记下该Token,稍后将用于登录Dashboard。

  • 使用浏览器访问以下URL,将NodeIP替换为Master01节点的IP地址,30001为之前指定的NodePort端口号:
https://NodeIP:30001

这将打开Dashboard登录页面。

  • 在登录页面上选择"Token"选项,并将之前中获取的Token粘贴到相应的输入框中。

  • 点击"Sign In"登录到Dashboard。

  • 现在,应该能够通过浏览器访问Kubernetes Dashboard,并使用之前获取的Token进行登录。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/364529.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【文本到上下文 #8】NLP中的变形金刚:解码游戏规则改变者

一、说明 欢迎来到我们对不断发展的自然语言处理 &#xff08;NLP&#xff09; 领域的探索的第 8 章。在本期中&#xff0c;我们将重点介绍一项重塑 NLP 格局的突破性创新&#xff1a;Transformers。在我们之前对 seq2seq 模型、编码器-解码器框架和注意力机制的讨论之后&#…

flutter如何实现省市区选择器

前言 当我们需要用户填写地址时&#xff0c;稳妥的做法是让用户通过“滚轮”来滑动选择省份&#xff0c;市&#xff0c;区&#xff0c;此文采用flutter的第三方库来实现这一功能&#xff0c;比调用高德地图api简单一些。 流程 选择库 这里我选择了一个最近更新且支持中国的…

ABAP Range Table:RANGES的使用

目录 Range TableRANGERANGES RANGE的四个参数SIGNOPTIONLOWHIGH示例程序 Range Table 1、Range Table 概述 RANGE TABLE为 SAP R/3系统标准内表的一种&#xff0c;结构与 Selection Table 一致&#xff0c; 由 SIGN, OPTION, LOW 和 HIGH字段组成&#xff1b; 可以通过 TYPE…

面试宝典之深谈JVM

面试宝典之深谈JVM 1.为什么需要JVM&#xff0c;不要JVM可以吗&#xff1f; 1.JVM可以帮助我们屏蔽底层的操作系统 一次编译&#xff0c;到处运行 2.JVM可以运行Class文件 2.JDK&#xff0c;JRE以及JVM的关系 3.我们的编译器到底干了什么事&#xff1f; 仅仅是将我们的 .ja…

【动态规划】【C++算法】1340. 跳跃游戏 V

作者推荐 【动态规划】【字符串】【表达式】2019. 解出数学表达式的学生分数 本文涉及知识点 动态规划汇总 LeetCode1340跳跃游戏 V 给你一个整数数组 arr 和一个整数 d 。每一步你可以从下标 i 跳到&#xff1a; i x &#xff0c;其中 i x < arr.length 且 0 < x…

用户界面(UI)、用户体验(UE)和用户体验(UX)的差异

对一个应用程序而言&#xff0c;UX/UE (user experience) 设计和 UI (user interface) 设计非常重要。UX设计包括可视化布局、信息结构、可用性、图形、互动等多个方面。UI设计也属于UX范畴。正是因为三者在一定程度上具有重叠的工作内容&#xff0c;很多从业多年的设计师都分不…

2024年美国大学生数学建模A题思路分析 - 资源可用性和性别比例

# 1 赛题 问题A&#xff1a;资源可用性和性别比例 虽然一些动物物种存在于通常的雄性或雌性性别之外&#xff0c;但大多数物种实质上是雄性或雌性。虽然许多物种在出生时的性别比例为1&#xff1a;1&#xff0c;但其他物种的性别比例并不均匀。这被称为适应性性别比例的变化。…

STM32CubeIDE 使用标准库来编写程序

这些天我想找一个软件来实现软件的替代。就找到了st 的生态。可是现在st 生态都在极力的推荐HAL 库,但是习惯了标准库的朋友们,还不是很习惯。 先上总结一下,为了好记忆: 一、 在编译栏做如下设置 1、头文件设置 2、源文件设置 二、指定具体的预定义宏 1、USE_STDPERIPH_D…

angular 表单FormGroup笔记

一、校验 1、校验提示 <nz-form-item><nz-form-label>手机号码</nz-form-label><nz-form-control [nzErrorTip]"mobileTemplate"><input nz-input formControlName"mobile" placeholder"请输入" /><ng-templ…

【Java并发】聊聊Disruptor背后高性能的原理

为什么需要Disruptor 对于单机生产者消费者来说&#xff0c;JUC本身提供了阻塞队列&#xff0c;ArrayBlockingQueue、LinkedBlockingQueue 等&#xff0c;但是为了保证数据安全&#xff0c;使用了reentrantLock进行加锁操作会影响性能&#xff0c;另一方面&#xff0c;本身如果…

正点原子--STM32中断系统学习笔记(1)

1、什么是中断&#xff1f; 原子哥给出的概念是这样的&#xff1a;打断CPU正常执行的程序&#xff0c;转而处理紧急程序&#xff0c;然后返回原暂停的程序继续运行&#xff0c;就叫中断。 当发生中断时&#xff0c;当前执行的程序会被暂时中止&#xff0c;进而进入中断处理函…

05:容器镜像技术揭秘|发布容器服务器|私有镜像仓库

容器镜像技术揭秘&#xff5c;发布容器服务器&#xff5c;私有镜像仓库 创建镜像使用commit方法创建自定义镜像。Dockerfile打包镜像创建apache服务镜像制作 php 镜像 微服务架构创建nginx镜像 发布服务通过映射端口发布服务容器共享卷 docker私有仓库 创建镜像 使用commit方法…

Hadoop3.x基础(3)- MapReduce

来源: B站尚硅谷 目录 MapReduce概述MapReduce定义MapReduce优缺点优点缺点 MapReduce核心思想MapReduce进程常用数据序列化类型MapReduce编程规范WordCount案例实操本地测试提交到集群测试 Hadoop序列化序列化概述自定义bean对象实现序列化接口&#xff08;Writable&#xff…

Nicn的刷题日常之BC68 X形图案

1.题目描述 KiKi学习了循环&#xff0c;BoBo老师给他出了一系列打印图案的练习&#xff0c;该任务是打印用“*”组成的X形图案。 输入描述&#xff1a; 多组输入&#xff0c;一个整数&#xff08;2~20&#xff09;&#xff0c;表示输出的行数&#xff0c;也表示组成“X”的反斜…

推荐一款嵌入式系统自动化测试工具(可免费试用)

本文介绍一款对嵌入式系统进行全面自动化测试的工具&#xff0c;不需要自己做任何开发&#xff0c;就可以在项目测试中直接使用起来&#xff0c;支持对各类嵌入式系统进行全面自动化测试。 嵌入式系统一般是产品的核心单元&#xff0c;嵌入式系统是否可靠决定了整个产品的质量…

【域适应十五】Universal Domain Adaptation through Self-Supervision

1.motivation 传统的无监督域自适应方法假设所有源类别都存在于目标域中。在实践中,对于这两个领域之间的类别重叠可能知之甚少。虽然有些方法使用部分或开放集类别处理目标设置,但它们假设特定设置是已知的先验设置。本文提出了一个更普遍适用的领域自适应框架,可以处理任…

【leetcode热题100】编辑距离

给你两个单词 word1 和 word2&#xff0c; 请返回将 word1 转换成 word2 所使用的最少操作数 。 你可以对一个单词进行如下三种操作&#xff1a; 插入一个字符删除一个字符替换一个字符 示例 1&#xff1a; 输入&#xff1a;word1 "horse", word2 "ros&qu…

政安晨的机器学习笔记——演绎一个TensorFlow官方的Keras示例(对服装图像进行分类,很全面)

导语 Keras是一个高级API接口&#xff0c;用于构建和训练神经网络模型。它是TensorFlow的一部分&#xff0c;提供了一种简洁、直观的方式来创建深度学习模型。 Keras的主要特点如下&#xff1a; 简洁易用&#xff1a;Keras提供了一组简单的函数和类&#xff0c;使模型的创建和…

10、数据结构与算法——堆

一、什么是堆 堆是一种特殊的树形数据结构&#xff0c;通常实现为完全二叉树或满二叉树。堆又分为两种类型最大堆&#xff08;Max Heap&#xff09; 和 最小堆&#xff08;Min Heap&#xff09; 1.1、什么是二叉树 二叉树是一种数据结构&#xff0c;它是由n&#xff08;n≥0&a…