实验条件:
主机名 |
IP地址 |
组件 |
作用 |
master01 |
20.0.0.17 |
kube-apiserver、kube-controller-manager、kube-scheduler、etcd |
k8s部署 |
master02 |
20.0.0.27 |
kube-apiserver、kube-controller-manager、kube-scheduler |
|
node01 |
20.0.0.37 |
kubelet、kube-proxy、etcd |
|
node02 |
20.0.0.47 |
kubelet、kube-proxy、etcd |
|
nginx01 |
20.0.0.11 |
nginx、keepalived |
负载均衡 |
nginx02 |
20.0.0.21 |
nginx、keepalived |
实验步骤:
【所有主机】
1、清空所有策略、关闭swap交换分区
iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X
swapoff -a
sed -ri 's/.*swap.*/#&/' /etc/fstab
2、安装时间同步工具
yum install ntpdate -y
ntpdate ntp.aliyun.com
3、主机映射
4、优化内核参数
vim /etc/sysctl.d/k8s.conf(创建k8s.conf文件)
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
sysctl --system
5、安装dokcer
【master节点】
6、部署 etcd 集群
(1)准备cfssl证书生成工具
chmod +x /usr/local/bin/cfssl*
(2)生成Etcd证书
mkdir /opt/k8s
cd /opt/k8s/
#上传 etcd-cert.sh 和 etcd.sh 到 /opt/k8s/ 目录中
chmod +x etcd-cert.sh etcd.sh
(3)创建用于生成CA证书、etcd 服务器证书以及私钥的目录
mkdir /opt/k8s/etcd-cert
mv etcd-cert.sh etcd-cert/
cd /opt/k8s/etcd-cert/
./etcd-cert.sh #生成CA证书、etcd 服务器证书以及私钥
ca-config.json |
证书颁发机构的配置文件,定义了证书生成的策略,默认的郭旗时间和模板 |
ca-csr.json |
签名的请求文件,包括一些组织信息和加密方式 |
ca.pem |
根证书文件,用于给其他组件签发证书 |
server.csr |
etcd的服务器签发证书的请求文件 |
server-key.pem |
etcd服务器的私钥文件 |
ca.csr |
根证书签发请求文件 |
ca-key.pem |
根证书的私钥文件 |
etcd-cert.sh |
脚本 |
server-csr.json |
用于生成etcd的服务器证书和私钥签名文件 |
server.pem |
etcd服务器的证书文件,用于加密和认证etcd节点之间的通信 |
(4)上传 etcd-v3.4.9-linux-amd64.tar.gz 到 /opt/k8s 目录中,启动etcd服务
https://github.com/etcd-io/etcd/releases/download/v3.4.9/etcd-v3.4.9-linux-amd64.tar.gz
cd /opt/k8s/
tar zxvf etcd-v3.4.9-linux-amd64.tar.gz
(5)创建用于存放 etcd 配置文件,命令文件,证书的目录
mkdir -p /opt/etcd/{cfg,bin,ssl}
cd /opt/k8s/etcd-v3.4.9-linux-amd64/
mv etcd etcdctl /opt/etcd/bin/
cp /opt/k8s/etcd-cert/*.pem /opt/etcd/ssl/
cd /opt/k8s/
./etcd.sh etcd01 20.0.0.17 etcd02=https://20.0.0.37:2380,etcd03=https://20.0.0.47:2380
etcd |
二进制文件 |
etcdctl |
命令行执行工具 |
进入卡住状态等待其他节点加入,这里需要三台etcd服务同时启动,如果只启动其中一台后,
服务会卡在那里,直到集群中所有etcd节点都已启动,可忽略这个情况
可另外打开一个窗口查看etcd进程是否正常
ps -ef | grep etcd
(6)把etcd相关证书文件、命令文件和服务管理文件全部拷贝到另外两个etcd集群节点
scp -r /opt/etcd/ [email protected]:/opt/
scp -r /opt/etcd/ [email protected]:/opt/
验证node1、node2节点上是否已收到
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/
【node1】
【node2】
ETCD安装完成
(7)依次启动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://20.0.0.17:2379,https://20.0.0.37:2379,https://20.0.0.47:2379" --write-out=table member list
检查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://20.0.0.17:2379,https://20.0.0.37:2379,https://20.0.0.47:2379" endpoint health --write-out=table
7、部署 Master 组件
【master】
(1)上传 master.zip 和 k8s-cert.sh 到 /opt/k8s 目录中,解压 master.zip 压缩包
cd /opt/k8s/
unzip master.zip
chmod +x *.sh
context |
上下文,定义连接到哪个k8s集群,以及使用哪个用户的身份进行操作,上下文包含集群、用户、可选命名空间的信息。目的:在k8s的集群环境中进行切换 |
(2)创建kubernetes工作目录
mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs}
(2)创建用于生成CA证书、相关组件的证书和私钥的目录
mkdir /opt/k8s/k8s-cert
mv /opt/k8s/k8s-cert.sh /opt/k8s/k8s-cert
cd /opt/k8s/k8s-cert/
./k8s-cert.sh #生成CA证书、相关组件的证书和私钥
(3)复制CA证书、apiserver相关证书和私钥到 kubernetes工作目录的 ssl 子目录中
cp ca*pem apiserver*pem /opt/kubernetes/ssl/
(4)上传 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
(5)复制master组件的关键命令文件到 kubernetes工作目录的 bin 子目录中
cd /opt/k8s/kubernetes/server/bin
cp kube-apiserver kubectl kube-controller-manager kube-scheduler /opt/kubernetes/bin/
ln -s /opt/kubernetes/bin/* /usr/local/bin/
(6)创建 bootstrap token 认证文件,apiserver 启动时会调用,然后就相当于在集群内创建了一个这个用户,
接下来就可以用 RBAC 进行授权
cd /opt/k8s/
vim 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 < ${BOOTSTRAP_TOKEN},kubelet-bootstrap,10001,"system:kubelet-bootstrap" EOF chmod +x token.sh ./token.sh cat /opt/kubernetes/cfg/token.csv (7)二进制文件、token、证书都准备好后,开启 apiserver 服务 cd /opt/k8s/ ./apiserver.sh 20.0.0.17 https://20.0.0.17:2379,https://20.0.0.37:2379,https://20.0.0.47:2379 检查进程是否启动成功 ps aux | grep kube-apiserver netstat -natp | grep 6443 #安全端口6443用于接收HTTPS请求,用于基于Token文件或客户端证书等认证 (8)启动 scheduler 服务 cd /opt/k8s/ ./scheduler.sh ps aux | grep kube-scheduler (9)启动 controller-manager 服务 ./controller-manager.sh ps aux | grep kube-controller-manager (10)生成kubectl连接集群的kubeconfig文件 ./admin.sh (11)通过kubectl工具查看当前集群组件状态 kubectl get cs (12)查看版本信息 kubectl version 8、部署node 组件 【node1、node2】 (1)创建kubernetes工作目录 mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs} (2)上传 node.zip 到 /opt 目录中,解压 node.zip 压缩包,获得kubelet.sh、proxy.sh cd /opt/ unzip node.zip chmod +x kubelet.sh proxy.sh 【master】 (3)把 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/ (4)上传kubeconfig.sh文件到/opt/k8s/kubeconfig目录中,生成kubelet初次加入集群引导kubeconfig文件和kube-proxy.kubeconfig文件 #kubeconfig 文件包含集群参数(CA 证书、API Server 地址), 客户端参数(上面生成的证书和私钥),集群 context 上下文参数(集群名称、用户名) Kubenetes 组件(如 kubelet、kube-proxy)通过启动时指定不同的 kubeconfig 文件可以切换到不同的集群, 连接到 apiserver mkdir /opt/k8s/kubeconfig cd /opt/k8s/kubeconfig chmod +x kubeconfig.sh ./kubeconfig.sh 20.0.0.17 /opt/k8s/k8s-cert/ (5)把配置文件 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/ (6)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 【node1】 (7)启动 kubelet 服务 cd /opt/ ./kubelet.sh 20.0.0.37 ps aux | grep kubelet 【master】 (8)在 master01 节点上操作,通过 CSR 请求 #检查到 node01 节点的 kubelet 发起的 CSR 请求,Pending 表示等①待集群给该节点签发证书 kubectl get csr ②通过 CSR 请求 kubectl certificate approve node-csr-1yB8Di5O7ViXLgOr3yqnSWkAh2ug4IqN5QYFWQKzGQc ③Approved,Issued 表示已授权 CSR 请求并签发证书 kubectl get csr 【node2】 (9)启动 kubelet 服务 cd /opt/ ./kubelet.sh 20.0.0.47 ps aux | grep kubelet 【master】 (10)在 master01 节点上操作,通过 CSR 请求 #检查到 node01 节点的 kubelet 发起的 CSR 请求,Pending 表示等①待集群给该节点签发证书 kubectl get csr ②通过 CSR 请求 kubectl certificate approve node-csr-1yB8Di5O7ViXLgOr3yqnSWkAh2ug4IqN5QYFWQKzGQc ③Approved,Issued 表示已授权 CSR 请求并签发证书 kubectl get csr ④查看节点,由于网络插件还没有部署,节点会没有准备就绪NotReady kubectl get node 【node1】 (11)加载 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 (12)启动proxy服务 cd /opt/ ./proxy.sh 20.0.0.37 ps aux | grep kube-proxy 【node2】 (13)加载 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 (14)启动proxy服务 cd /opt/ ./proxy.sh 20.0.0.47 ps aux | grep kube-proxy 【master】 kubectl get cs kubectl get node 注:自动补齐命令 【所有node节点】 9、部署网络 方式1:vxlan模式 【node01】 (1)上传 cni-plugins-linux-amd64-v0.8.6.tgz 和 flannel.tar 到 /opt 目录中 cd /opt/ docker load -i flannel.tar mkdir -p /opt/cni/bin tar zxvf cni-plugins-linux-amd64-v0.8.6.tgz -C /opt/cni/bin 【node2】 (2)上传 cni-plugins-linux-amd64-v0.8.6.tgz 和 flannel.tar 到 /opt 目录中 cd /opt/ docker load -i flannel.tar mkdir -p /opt/cni/bin tar zxvf cni-plugins-linux-amd64-v0.8.6.tgz -C /opt/cni/bin 【master】 (3)上传 kube-flannel.yml 文件到 /opt/k8s 目录中,部署 CNI 网络 cd /opt/k8s kubectl apply -f kube-flannel.yml kubectl get pods -n kube-system kubectl get nodes 查看node1节点 查看node2节点 方式2:calico 【master】 (1)上传 calico.yaml 文件到 /opt/k8s 目录中,部署 CNI 网络 cd /opt/k8s vim calico.yaml #修改里面定义 Pod 的网络(CALICO_IPV4POOL_CIDR),需与前面 kube-controller-manager 配置文件指定的 cluster-cidr 网段一样 - name: CALICO_IPV4POOL_CIDR value: "10.244.0.0/16" #Calico 默认使用的网段为 192.168.0.0/16 kubectl apply -f calico.yaml kubectl get pods -n kube-system 等 Calico Pod 都 Running,节点也会准备就绪 kubectl get nodes 查看node节点 创建一个pod kubectl create deployment nginx1 --image=nginx --replicas=3 每创建一个pod,就会生成一个cali网卡 每创建一个容器会生成一个路由表,路由表会越来越多,降低转发效率,需要定期维护 删除pod节点,会自动删除相应的网卡和路由表 10、部署多节点 【所有节点】 (1)主机映射 vim /etc/hosts 【slave】 (2)安装时间同步 yum install ntpdate -y ntpdate ntp.aliyun.com (3)清空所有策略、关闭swap交换分区 iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X swapoff -a sed -ri 's/.*swap.*/#&/' /etc/fstab (4)调整内核参数 sysctl --system 【master】 (5)从 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://20.0.0.17:2379,https://20.0.0.37:2379,https://20.0.0.47:2379 \ --bind-address=20.0.0.27 \ #修改 --secure-port=6443 \ --advertise-address=20.0.0.27 \ #修改 (6)在 slave节点上启动各服务并设置开机自启 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 (7)查看node节点状态 ln -s /opt/kubernetes/bin/* /usr/local/bin/ kubectl get nodes kubectl get nodes -o wide #-o=wide:输出额外信息;对于Pod,将输出Pod所在的Node名 此时在slave节点查到的node节点状态仅是从etcd查询到的信息, 而此时node节点实际上并未与master02节点建立通信连接,因此需要使用一个VIP把node节点与master节点都关联起来 11、负载均衡部署 【所有nginx节点】 不能用epel源下载nginx,用官方源或者编译安装1.22.0下载,支持四层代理 【nginx1】 (1)配置nginx的官方在线yum源,配置本地nginx的yum源 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 (2)修改nginx配置文件,配置四层反向代理负载均衡,指定k8s群集2台master的节点ip和6443端口 vim /etc/nginx/nginx.conf events { worker_connections 1024; } #添加 stream { log_format main '$remote_addr $upstream_addr - [$time_local] $status $upstream_bytes_sent'; #日志记录格式 #$remote_addr: 客户端的 IP 地址。 #$upstream_addr: 上游服务器的地址。 #[$time_local]: 访问时间,使用本地时间。 #$status: HTTP 响应状态码。 #$upstream_bytes_sent: 从上游服务器发送到客户端的字节数。 access_log /var/log/nginx/k8s-access.log main; upstream k8s-apiserver { server 192.168.233.91:6443; server 192.168.233.92:6443; } server { listen 6443; proxy_pass k8s-apiserver; } } http { ...... (3)检查配置文件语法 nginx -t (4)启动nginx服务,查看已监听6443端口 systemctl start nginx systemctl enable nginx netstat -natp | grep nginx 【nginx2】 (5)配置nginx的官方在线yum源,配置本地nginx的yum源 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 (6)修改nginx配置文件,配置四层反向代理负载均衡,指定k8s群集2台master的节点ip和6443端口 vim /etc/nginx/nginx.conf events { worker_connections 1024; } #添加 stream { log_format main '$remote_addr $upstream_addr - [$time_local] $status $upstream_bytes_sent'; #日志记录格式 #$remote_addr: 客户端的 IP 地址。 #$upstream_addr: 上游服务器的地址。 #[$time_local]: 访问时间,使用本地时间。 #$status: HTTP 响应状态码。 #$upstream_bytes_sent: 从上游服务器发送到客户端的字节数。 access_log /var/log/nginx/k8s-access.log main; upstream k8s-apiserver { server 192.168.233.91:6443; server 192.168.233.92:6443; } server { listen 6443; proxy_pass k8s-apiserver; } } http { ...... (7)检查配置文件语法 nginx -t (8)启动nginx服务,查看已监听6443端口 systemctl start nginx systemctl enable nginx netstat -natp | grep nginx 12、部署keepalived服务 【所有nginx节点】 yum install keepalived -y (1)修改keepalived配置文件 vim /etc/keepalived/keepalived.conf (2)创建nginx状态检查脚本 【nginx1】 vim /etc/nginx/check_nginx.sh #!/bin/bash /usr/bin/curl -I http://localhost &>/dev/null if [ $? -ne 0 ];then # /etc/init.d/keepalived stop systemctl stop keepalived fi chmod +x /etc/nginx/check_nginx.sh (3)启动keepalived服务(一定要先启动了nginx服务,再启动keepalived服务) systemctl start keepalived systemctl enable keepalived ip a #查看VIP是否生成 关闭nginx、keepalived测试vip地址是否能漂移到备服务器 停止主服务器的nginx 查看vip地址是否漂移到备服务器上 ip addr 结论:keepalived高可用正常 【所有node节点】 (4)修改node节点上的bootstrap.kubeconfig,kubelet.kubeconfig配置文件为VIP cd /opt/kubernetes/cfg/ vim bootstrap.kubeconfig server: https://20.0.0.100:6443 vim kubelet.kubeconfig server: https://20.0.0.100:6443 vim kube-proxy.kubeconfig server: https://20.0.0.100:6443 【node1】 【node2】 (5)重启kubelet和kube-proxy服务 systemctl restart kubelet.service systemctl restart kube-proxy.service (6)在主服务器 nginx1上查看 nginx 和 node 、 master 节点的连接状态 netstat -natp | grep nginx 搭建完成 13、部署 Dashboard 【master】 Dashboard仪表盘,k8s的可视化界面,在这个可视化界面,可以对k8s进行可视化管理 (1)上传 recommended.yaml 文件到 /opt/k8s 目录中 cd /opt/k8s vim recommended.yaml kubectl apply -f recommended.yaml (2)创建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 (3)获取token值 kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}') (4)使用输出的token登录Dashboard【node节点访问火狐浏览器,谷歌】 https://20.0.0.37:30001 集群中的node节点出现故障,怎么解决? kubectl get cs 查看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://20.0.0.17:2379,https://20.0.0.37:2379,https://20.0.0.47:2379" --write-out=table member list 检查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://20.0.0.17:2379,https://20.0.0.37:2379,https://20.0.0.47:2379" endpoint health --write-out=table 将有故障的etcd节点remove出集群 /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://20.0.0.17:2379,https://20.0.0.37:2379,https://20.0.0.47:2379" member remove 故障节点的id 来到故障节点 rm -rf /var/lib/etcd/default.etcd/member/ 修改etcd配置文件,将下面new修改为: vim /opt/etcd/cfg/etcd 修改前: ETCD_INITIAL_CLUSTER_STATE="new" 修改后: ETCD_INITIAL_CLUSTER_STATE="existing" 重新加入etcd集群 /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://20.0.0.17:2379,https://20.0.0.37:2379,https://20.0.0.47:2379" member add etcd03 --peer-urls=https://20.0.0.47:2380 重启etcd故障节点 在master节点查看