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 < ca-csr.json < server-csr.json <

这脚本是用于生成证书的

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

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

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

  • cat > ca-csr.json <:同样的方式,将下面的内容输入到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 <:同样的方式,将下面的内容输入到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  < /usr/lib/systemd/system/etcd.service <

这是一个用于创建和配置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 <: 使用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 <: 使用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

k8s二进制及负载均衡集群部署详解_第1张图片

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

scp -r /opt/etcd/ [email protected]:/opt/
scp -r /opt/etcd/ [email protected]:/opt/
scp /usr/lib/systemd/system/etcd.service [email protected]:/usr/lib/systemd/system/
scp /usr/lib/systemd/system/etcd.service [email protected]:/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"

k8s二进制及负载均衡集群部署详解_第2张图片

首先,使用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集群中每个节点的健康状态,并以表格形式输出结果。

k8s二进制及负载均衡集群部署详解_第3张图片

这表明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集群中每个节点的详细状态信息,并以表格形式输出结果。

k8s二进制及负载均衡集群部署详解_第4张图片

这表明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

k8s二进制及负载均衡集群部署详解_第5张图片

部署Master组件

在 master01 节点上

  • k8s-cert.sh脚本
#!/bin/bash
#配置证书生成策略,让 CA 软件知道颁发有什么功能的证书,生成用来签发其他组件证书的根证书
cat > ca-config.json < ca-csr.json < apiserver-csr.json < admin-csr.json < kube-proxy-csr.json <

这段脚本是用于生成证书和私钥,用于配置 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 <

保存并关闭文件。

授予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 <的形式依次生效,集群时必须包含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 <
./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 <,比如 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 <
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 <才会在 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 <
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

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

k8s二进制及负载均衡集群部署详解_第6张图片

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

kubectl version

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

k8s二进制及负载均衡集群部署详解_第7张图片

现在,已经成功启动了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 <个这样的容器,每个pod里容器之间的相互通信需要Pause的支持,启动Pause需要Pause基础镜像


#----------------------
#创建kubelet配置文件(该文件实际上就是一个yml文件,语法非常严格,不能出现tab键,冒号后面必
须要有空格,每行结尾也不能有空格)
cat >/opt/kubernetes/cfg/kubelet.config </usr/lib/systemd/system/kubelet.service <
  • vim proxy.sh
#!/bin/bash

NODE_ADDRESS=$1

#创建 kube-proxy 启动参数配置文件
cat >/opt/kubernetes/cfg/kube-proxy <,从而不会创建任何 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 <

或者把 你的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 [email protected]:/opt/kubernetes/bin/
scp kubelet kube-proxy [email protected]:/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 文件。

k8s二进制及负载均衡集群部署详解_第8张图片

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

scp bootstrap.kubeconfig kube-proxy.kubeconfig [email protected]:/opt/kubernetes/cfg/
scp bootstrap.kubeconfig kube-proxy.kubeconfig [email protected]:/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 命令来创建和运行容器。

k8s二进制及负载均衡集群部署详解_第9张图片

创建 /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 正在运行。

k8s二进制及负载均衡集群部署详解_第10张图片

如果

  • 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 [email protected]:/opt/

k8s二进制及负载均衡集群部署详解_第11张图片

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

scp -r /opt/cni [email protected]:/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/ [email protected]:/opt/
scp -r /opt/kubernetes/ [email protected]:/opt
scp -r /root/.kube [email protected]:/root
scp /usr/lib/systemd/system/{kube-apiserver,kube-controller-manager,kube-scheduler}.service [email protected]:/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 {
     [email protected]
     [email protected]
     [email protected]
   }
   # 邮件发送地址
   notification_email_from [email protected]
   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进行登录。

你可能感兴趣的:(云,kubernetes,负载均衡,容器,运维,架构,云原生)