目录
常见部署方式
二进制部署流程
环境准备
操作系统初始化配置
关闭防火墙
配置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/hosts
:cat
命令用于将文件内容输出到终端或其他文件。>>
表示将输出追加到指定文件中,而不是覆盖原有内容。/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.pem
和ca-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.pem
和server-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.sh
和etcd.sh
脚本文件上传到目标服务器的/opt/k8s/
目录中。可以使用文件传输工具(如scp)将这两个文件从本地系统上传到目标服务器的/opt/k8s/
目录。 -
添加可执行权限:
-
一旦脚本文件上传到目标服务器的
/opt/k8s/
目录中,可以使用以下命令为它们添加可执行权限:
chmod +x /opt/k8s/etcd-cert.sh /opt/k8s/etcd.sh
这个命令使用chmod
命令为etcd-cert.sh
和etcd.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
目录中的文件和目录。可以看到解压后的文件和目录,包括Documentation
、etcd
、etcdctl
、README-etcdctl.md
、README.md
和READMEv2-etcdctl.md
。
创建用于存放 etcd 配置文件,命令文件,证书的目录
创建目录用于存放 etcd 配置文件,命令文件,证书
mkdir -p /opt/etcd/{cfg,bin,ssl}
进入 /opt/k8s/etcd-v3.4.9-linux-amd64/
目录,并将 etcd
和 etcdctl
文件移动到 /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.zip
和k8s-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/
目录下创建bin
、cfg
、ssl
和logs
子目录,用于存放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.pem
和ca-key.pem
-
apiserver证书和私钥:
apiserver.pem
和apiserver-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-apiserver
、kubectl
、kube-controller-manager
和kube-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.kubeconfig
、kubelet.kubeconfig
和kube-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
- 重启
kubelet
和kube-proxy
服务以使配置生效:
systemctl restart kubelet.service
systemctl restart kube-proxy.service
现在,Node节点上的bootstrap.kubeconfig
、kubelet.kubeconfig
和kube-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进行登录。