当前位置:   article > 正文

云原生学习

云原生学习

1. 高可用架构

1.1 架构图

Kubernetes是属于主从设备模型(Master-Slave架构),即有Master节点负责核心的调度、管理和运维,Slave节点则执行用户的程序。在Kubernetes中,主节点一般被称为Master Node 或者 Head Node,而从节点则被称为Worker Node 或者 Node。

Tips:Master节点通常包括API Server、Scheduler、Controller Manager等组件,Node节点通常包括Kubelet、Kube-Proxy等组件!

看到蓝色框内的Control Plane,这个是整个集群的控制平面,相当于是master进程的加强版。k8s中的Control Plane一般都会运行在Master节点上面。在默认情况下,Master节点并不会运行应用工作负载,所有的应用工作负载都交由Node节点负责。

控制平面中的Master节点主要运行控制平面的各种组件,它们主要的作用就是维持整个k8s集群的正常工作、存储集群的相关信息,同时为集群提供故障转移、负载均衡、任务调度和高可用等功能。对于Master节点一般有多个用于保证高可用,而控制平面中的各个组件均以容器的Pod形式运行在Master节点中,大部分的组件需要在每个Master节点上都运行,少数如DNS服务等组件则只需要保证足够数量的高可用即可。

1.1.1 etcd

ETCD:它是兼具一致性和高可用性的键值key-value数据库,可以作为保存 Kubernetes 所有集群数据的后台数据库,负责保存Kubernetes Cluster的配置信息和各种资源的状态信息,当数据发生变化时,etcd 会快速地通知Kubernetes相关组件。

Kubernetes 集群的 etcd 数据库通常需要有个备份计划。此外还有一种k8s集群部署的高可用方案是将etcd数据库从容器中抽离出来,单独作为一个高可用数据库部署,从而为k8s提供稳定可靠的高可用数据库存储。

Tips:生成环境如果机器配置够高,安装etcd与master安装在一起也OK,也可以单独分离。

1.1.2 kube-apiserver

k8s集群的控制平面的核心是API服务器,而API服务器主要就是由kube-apiserver组件实现的,它被设计为可水平扩展,即通过部署不同数量的实例来进行缩放从而适应不同的流量。API服务器作为整个k8s控制平面的前端,负责提供 HTTP API,以供用户、集群中的不同部分组件和集群外部组件相互通信。(可以通过kubeadm或者kubectl这类的CLI工具来操控API从而控制整个k8s集群,也可以通过其他的Web UI来进行操控)

Tips:工具在背后也是调用 API,包括Web操作。

1.1.3 kube-scheduler

主节点上的组件,该组件监视那些新创建的未指定运行节点的 Pod,并选择节点让 Pod 在上面运行。

调度决策考虑的因素包括单个 Pod 和 Pod 集合的资源需求、硬件/软件/策略约束、亲和性和反亲和性规范、数据位置、工作负载间的干扰和最后时限。

1.1.4 kube-controller-manager

K8S所有Worker Node的监控器。Controller Manager作为集群内部的管理控制中心,运行在Master节点上,是一个永不休止的循环。它实质上是群内的Node、Pod、服务(Server)、端点(Endpoint)、命名空间(Namespace)、服务账号(ServiceAccount)、资源定额(ResourceQuota)的监视与守护进程的合集,每个资源的Controller通过API Server提供的接口实时监控每个资源对象的当前状态,当某个Node意外宕机时,Controller Manager会及时发现并执行自动化修复流程,确保集群始终处于预期的工作状态。

其中控制器包括:

  • 节点控制器(Node Controller): 负责在节点出现故障时进行通知和响应。
  • 副本控制器(Replication Controller): 负责为系统中的每个副本控制器对象维护正确数量的 Pod。
  • 端点控制器(Endpoints Controller): 填充端点(Endpoints)对象(即加入 Service 与 Pod)。
  • 服务帐户和令牌控制器(Service Account & Token Controllers): 为新的命名空间创建默认帐户和 API 访问令牌。

1.1.5 kubelet

K8S中Master节点在每个Worker Node节点上运行的主要“节点代理”,也可以说是Master 的“眼线”。它会定期向Master Node汇报自己Node上运行服务的状态,并接受来自Master Node的指示采取调整措施。负责控制由 K8S 创建的容器的启动停止,保证节点工作正常。

1.1.6 kube-proxy

kube-proxy是集群中每个节点上运行的网络代理,负责Node在K8S的网络通讯、以及对外网络流量的负载均衡。 kube-proxy通过维护主机上的网络规则并执行连接转发,实现了Kubernetes服务抽象。

service在逻辑上代表了后端的多个Pod,外界通过service访问Pod。service接收到的请求就是通过kube-proxy转发到Pod上的,kube-proxy服务负责将访问service的TCP/UDP数据流转发到后端的容器。如果有多个副本,kube-proxy会实现负载均衡。

由于性能问题,目前大部分企业用K8S进行实际生产时,都不会直接使用Kube-proxy作为服务代理,而是通过Ingress Controller来集成HAProxy, Nginx来代替Kube-proxy。

1.2 高可用分析

所有从集群(或所运行的 Pods)发出的 API 调用都终止于 API server,而API Server直接与ETCD数据库通讯。若仅部署单一的API server ,当API server所在的 VM 关机或者 API 服务器崩溃将导致不能停止、更新或者启动新的 Pod、服务或副本控制器;而ETCD存储若发生丢失,API 服务器将不能启动。

所以如下几个方面需要做到:

  1. 集群状态维持:K8S集群状态信息存储在ETCD集群中,该集群非常可靠,且可以分布在多个节点上。需要注意的是,在ETCD群集中至少应该有3个节点,且为了防止2网络分裂,节点的数量必须为奇数。
  2. API服务器冗余灾备:K8S的API server服务器是无状态的,从ETCD集群中能获取所有必要的数据。这意味着K8S集群中可以轻松地运行多个API服务器,而无需要进行协调,因此我们可以把负载均衡器(LB)放在这些服务器之前,使其对用户、Worker Node均透明。
  3. Master选举:一些主组件(Scheduler和Controller Manager)不能同时具有多个实例,可以想象多个Scheduler同时进行节点调度会导致多大的混乱。由于Controller Manager等组件通常扮演着一个守护进程的角色,当它自己失败时,K8S将没有更多的手段重新启动它自己,因此必须准备已经启动的组件随时准备取代它。高度可扩展的Kubernetes集群可以让这些组件在领导者选举模式下运行。这意味着虽然多个实例在运行,但是每次只有一个实例是活动的,如果它失败,则另一个实例被选为领导者并代替它。
  4. K8S高可用:只要K8S集群关键结点均高可用,则部署在K8S集群中的Pod、Service的高可用性就可以由K8S自行保证。

负载均衡节点设计

负载均衡节点承担着Worker Node集群和Master集群通讯的职责,同时Load Balance没有部署在K8S集群中,不受Controller Manager的监控,倘若Load Balance发生故障,将导致Node与Master的通讯全部中断,因此需要对负载均衡做高可用配置。Load Balance同样不能同时有多个实例在服务,因此使用Keepalived对部署了Load Balance的服务器进行监控,当发生失败时将虚拟IP(VIP)飘移至备份节点,确保集群继续可用。

2. 前期规划及准备

2.1 高可用Kubernetes集群规划

主机规划

主机名

IP地址

说明

k8s-master01 ~ 03

10.0.0.104 ~ 106

master节点 * 3

k8s-master-lb

10.0.0.236

keepalived虚拟IP(不占用机器)

k8s-node01 ~ 02

10.0.0.107 ~ 108

worker节点 * 2

网络规划及版本说明

配置信息

备注

系统版本

CentOS 7.9

Docker版本 (containerd)

20.10.x

Pod网段

172.16.0.0/16

Service网段

192.168.0.0/16

Tips:宿主机网段、K8s Service网段、Pod网段不能重复!

本方案负载均衡(VIP)在Master上,没有单独做负载均衡双机热备。

IP

角色

Hostname

说明

10.0.0.104

Master

k8s-master01

keepalived、haproxy、kube-apiserver、kube-scheduler、kube-controller-manager

10.0.0.105

Master

k8s-master02

keepalived、haproxy、kube-apiserver、kube-scheduler、kube-controller-manager

10.0.0.106

Master

k8s-master03

keepalived、haproxy、kube-apiserver、kube-scheduler、kube-controller-manager

10.0.0.107

Node

k8s-node01

kubelet、kube-proxy

10.0.0.108

Node

k8s-node02

kubelet、kube-proxy

10.0.0.236

Virtual IP(VIP)

k8s-master-lb

各主机hosts解析需要对应加上这一条10.0.0.36 k8s-master-lb

2.2 基本环境配置

centos通过单独安装,非克隆。安装完后进行基本环境的配置,配置一下几个方面:

  1. 设置主机名
  2. 关闭NetworkManager、firewalld、dnsmasq、selinux
  3. 设置eth0
  4. 优化ssh
  5. 设置时区为Asia/Shanghai
  6. 备份并新增清华yum源、epel源、docker-ce源、k8s源
  7. 更新yum源软件包缓存
  8. 修改history格式及记录数
  9. 添加hosts解析
  10. 关闭swap分区
  11. 安装ntpdate服务,并同步时间
  12. 配置limits.conf
  13. 安装必备工具
  14. 升级系统并重启

在/root目录下创建k8s_system_init.sh,复制以下内容。然后sh /root/k8s_system_init.sh进行基本环境的配置。

此步骤Master及Node节点都需进行!

  1. #!/bin/bash
  2. if [ $# -eq 2 ];then
  3. echo "设置主机名为:$1"
  4. echo "eth0设置IP地址为:10.0.0.$2"
  5. else
  6. echo "使用方法:sh $0 主机名 主机位"
  7. exit 2
  8. fi
  9. echo "--------------------------------------"
  10. echo "1.正在设置主机名:$1"
  11. hostnamectl set-hostname $1
  12. echo "2.正在关闭NetworkManager、firewalld、dnsmasq、selinux"
  13. systemctl disable firewalld &> /dev/null
  14. systemctl disable NetworkManager &> /dev/null
  15. systemctl disable dnsmasq &> /dev/null
  16. systemctl stop firewalld
  17. systemctl stop NetworkManager
  18. systemctl stop dnsmasq
  19. sed -i "s#SELINUX=enforcing#SELINUX=disabled#g" /etc/selinux/config
  20. setenforce 0
  21. echo "3.正在设置eth0:10.0.0.$2"
  22. cat > /etc/sysconfig/network-scripts/ifcfg-eth0 <<EOF
  23. TYPE=Ethernet
  24. BOOTPROTO=static
  25. DEFROUTE=yes
  26. NAME=eth0
  27. DEVICE=eth0
  28. ONBOOT=yes
  29. IPADDR=10.0.0.$2
  30. NETMASK=255.255.255.0
  31. GATEWAY=10.0.0.2
  32. DNS1=114.114.114.114
  33. EOF
  34. systemctl restart network
  35. echo "4.优化ssh"
  36. sed -i "s#\#UseDNS yes#UseDNS no#g" /etc/ssh/sshd_config
  37. sed -i "s#GSSAPIAuthentication yes#GSSAPIAuthentication no#g" /etc/ssh/sshd_config
  38. systemctl restart sshd
  39. echo "5.设置时区为Asia/Shanghai"
  40. timedatectl set-timezone Asia/Shanghai
  41. echo "6.备份并新增清华yum源、epel源、docker-ce源、k8s源"
  42. cd /etc/yum.repos.d/
  43. mkdir bak ; mv *.repo bak
  44. cat > /etc/yum.repos.d/Centos-Base.repo <<EOF
  45. [base]
  46. name=CentOS-$releasever - Base
  47. baseurl=https://mirrors.tuna.tsinghua.edu.cn/centos/\$releasever/os/\$basearch/
  48. gpgcheck=1
  49. gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
  50. [updates]
  51. name=CentOS-$releasever - Updates
  52. baseurl=https://mirrors.tuna.tsinghua.edu.cn/centos/\$releasever/updates/\$basearch/
  53. gpgcheck=1
  54. gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
  55. [extras]
  56. name=CentOS-$releasever - Extras
  57. baseurl=https://mirrors.tuna.tsinghua.edu.cn/centos/\$releasever/extras/\$basearch/
  58. gpgcheck=1
  59. gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
  60. [centosplus]
  61. name=CentOS-$releasever - Plus
  62. baseurl=https://mirrors.tuna.tsinghua.edu.cn/centos/\$releasever/centosplus/\$basearch/
  63. gpgcheck=1
  64. enabled=0
  65. gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
  66. EOF
  67. cat > /etc/yum.repos.d/epel.repo <<EOF
  68. [epel]
  69. name=Extra Packages for Enterprise Linux 7 - \$basearch
  70. baseurl=https://mirrors.tuna.tsinghua.edu.cn/epel/7/\$basearch
  71. failovermethod=priority
  72. enabled=1
  73. gpgcheck=1
  74. gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
  75. [epel-debuginfo]
  76. name=Extra Packages for Enterprise Linux 7 - \$basearch - Debug
  77. baseurl=https://mirrors.tuna.tsinghua.edu.cn/epel/7/\$basearch/debug
  78. failovermethod=priority
  79. enabled=0
  80. gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
  81. gpgcheck=1
  82. [epel-source]
  83. name=Extra Packages for Enterprise Linux 7 - \$basearch - Source
  84. baseurl=https://mirrors.tuna.tsinghua.edu.cn/epel/7/SRPMS
  85. failovermethod=priority
  86. enabled=0
  87. gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
  88. gpgcheck=1
  89. EOF
  90. cat > /etc/yum.repos.d/kubernetes.repo <<EOF
  91. [kubernetes]
  92. name=Kubernetes
  93. baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
  94. enabled=1
  95. gpgcheck=1
  96. repo_gpgcheck=1
  97. gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
  98. EOF
  99. yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo &> /dev/null
  100. sed -i 's+https://download.docker.com+https://mirrors.tuna.tsinghua.edu.cn/docker-ce+' /etc/yum.repos.d/docker-ce.repo
  101. echo "7.更新yum源软件包缓存"
  102. yum makecache
  103. echo "8.修改history格式及记录数"
  104. sed -i "s#HISTSIZE=1000##g" /etc/profile
  105. cat >> /etc/profile <<EOF
  106. shopt -s histappend
  107. USER_IP=`who -u am i 2>/dev/null| awk '{print $NF}'|sed -e 's/[()]//g'`
  108. export HISTFILE=~/.commandline_warrior
  109. export HISTTIMEFORMAT="%Y-%m-%d %H:%M:%S `whoami`@${USER_IP}: "
  110. export HISTSIZE=200000
  111. export HISTFILESIZE=1000000
  112. export PROMPT_COMMAND="history -a"
  113. EOF
  114. source /etc/profile
  115. echo "9.添加hosts解析"
  116. cat >> /etc/hosts <<EOF
  117. 10.0.0.104 k8s-master01
  118. 10.0.0.105 k8s-master02
  119. 10.0.0.106 k8s-master03
  120. 10.0.0.236 k8s-master-lb
  121. 10.0.0.107 k8s-node01
  122. 10.0.0.108 k8s-node02
  123. EOF
  124. echo "10.关闭swap分区"
  125. swapoff -a && sysctl -w vm.swappiness=0 &> /dev/null
  126. sed -ri '/^[^#]*swap/s@^@#@' /etc/fstab
  127. echo "11.安装ntpdate服务,并同步时间"
  128. yum install ntpdate -y &> /dev/null
  129. systemctl enabled ntpdate &> /dev/null
  130. systemctl start ntpdate
  131. echo "*/10 * * * * root /usr/sbin/ntpdate ntp1.aliyun.com >/dev/null 2>&1" > /etc/cron.d/ntp_sync
  132. echo "12.配置limits.conf"
  133. ulimit -SHn 65535
  134. cat >> /etc/security/limits.conf <<EOF
  135. * soft nofile 65536
  136. * hard nofile 131072
  137. * soft nproc 65535
  138. * hard nproc 655350
  139. * soft memlock unlimited
  140. * hard memlock unlimited
  141. EOF
  142. echo "13.必备工具安装"
  143. yum install wget jq psmisc vim net-tools telnet yum-utils device-mapper-persistent-data lvm2 git -y &> /dev/null
  144. echo "14.升级系统并重启"
  145. yum update -y --exclude=kernel* && reboot

2.3 内核及ipvs模块配置

此步骤是升级内核、配置ipvs模块,开启一些k8s集群中必须的内核参数。配置一下几个方面:

  1. 下载安装包到/server/soft
  2. 安装kernel
  3. 更改内核启动顺序
  4. 安装ipvsadm
  5. 配置ipvs模块
  6. 开启k8s集群必须的内核参数
  7. 配置完内核,重启服务器

在/root目录下创建kernel_update.sh,复制以下内容。然后sh /root/kernel_update.sh进行基本环境的配置。

此步骤Master及Node节点都需进行!

  1. #!/bin/bash
  2. echo "1.下载安装包到/server/soft"
  3. mkdir -p /server/soft ; cd /server/soft
  4. wget http://193.49.22.109/elrepo/kernel/el7/x86_64/RPMS/kernel-ml-devel-4.19.12-1.el7.elrepo.x86_64.rpm
  5. wget http://193.49.22.109/elrepo/kernel/el7/x86_64/RPMS/kernel-ml-4.19.12-1.el7.elrepo.x86_64.rpm
  6. echo "2.正在安装kernel"
  7. yum localinstall -y kernel-ml*
  8. echo "3.更改内核启动顺序"
  9. grub2-set-default 0 && grub2-mkconfig -o /etc/grub2.cfg
  10. grubby --args="user_namespace.enable=1" --update-kernel="$(grubby --default-kernel)"
  11. echo "4.输出现在内核版本信息"
  12. grubby --default-kernel
  13. echo "5.安装ipvsadm"
  14. yum install ipvsadm ipset sysstat conntrack libseccomp -y &> /dev/null
  15. echo "6.配置ipvs模块"
  16. modprobe -- ip_vs
  17. modprobe -- ip_vs_rr
  18. modprobe -- ip_vs_wrr
  19. modprobe -- ip_vs_sh
  20. modprobe -- nf_conntrack
  21. cat >> /etc/modules-load.d/ipvs.conf <<EOF
  22. ip_vs
  23. ip_vs_lc
  24. ip_vs_wlc
  25. ip_vs_rr
  26. ip_vs_wrr
  27. ip_vs_lblc
  28. ip_vs_lblcr
  29. ip_vs_dh
  30. ip_vs_sh
  31. ip_vs_fo
  32. ip_vs_nq
  33. ip_vs_sed
  34. ip_vs_ftp
  35. ip_vs_sh
  36. nf_conntrack
  37. ip_tables
  38. ip_set
  39. xt_set
  40. ipt_set
  41. ipt_rpfilter
  42. ipt_REJECT
  43. ipip
  44. EOF
  45. systemctl enable --now systemd-modules-load.service &> /dev/null
  46. echo "7.开启k8s集群必须的内核参数"
  47. cat <<EOF > /etc/sysctl.d/k8s.conf
  48. net.ipv4.ip_forward = 1
  49. net.bridge.bridge-nf-call-iptables = 1
  50. net.bridge.bridge-nf-call-ip6tables = 1
  51. fs.may_detach_mounts = 1
  52. net.ipv4.conf.all.route_localnet = 1
  53. vm.overcommit_memory=1
  54. vm.panic_on_oom=0
  55. fs.inotify.max_user_watches=89100
  56. fs.file-max=52706963
  57. fs.nr_open=52706963
  58. net.netfilter.nf_conntrack_max=2310720
  59. net.ipv4.tcp_keepalive_time = 600
  60. net.ipv4.tcp_keepalive_probes = 3
  61. net.ipv4.tcp_keepalive_intvl =15
  62. net.ipv4.tcp_max_tw_buckets = 36000
  63. net.ipv4.tcp_tw_reuse = 1
  64. net.ipv4.tcp_max_orphans = 327680
  65. net.ipv4.tcp_orphan_retries = 3
  66. net.ipv4.tcp_syncookies = 1
  67. net.ipv4.tcp_max_syn_backlog = 16384
  68. net.ipv4.ip_conntrack_max = 65536
  69. net.ipv4.tcp_max_syn_backlog = 16384
  70. net.ipv4.tcp_timestamps = 0
  71. net.core.somaxconn = 16384
  72. EOF
  73. sysctl --system
  74. echo "8.配置完内核,重启服务器!"
  75. reboot

2.4 检查ipvs加载、内核版本验证

lsmod | grep --color=auto -e ip_vs -e nf_conntrack

uname -a

2.5 高可用组件安装
2.5.1 HAproxy配置

所有Master节点安装Keepalived、HAproxy

yum install keepalived haproxy -y

所有Master节点配置HAProxy,所有Master节点的HAProxy配置相同。

  1. # cat /etc/haproxy/haproxy.cfg
  2. global
  3. maxconn 2000
  4. ulimit-n 16384
  5. log 127.0.0.1 local0 err
  6. stats timeout 30s
  7. defaults
  8. log global
  9. mode http
  10. option httplog
  11. timeout connect 5000
  12. timeout client 50000
  13. timeout server 50000
  14. timeout http-request 15s
  15. timeout http-keep-alive 15s
  16. frontend monitor-in
  17. bind *:33305
  18. mode http
  19. option httplog
  20. monitor-uri /monitor
  21. frontend k8s-master
  22. bind 0.0.0.0:16443
  23. bind 127.0.0.1:16443
  24. mode tcp
  25. option tcplog
  26. tcp-request inspect-delay 5s
  27. default_backend k8s-master
  28. backend k8s-master
  29. mode tcp
  30. option tcplog
  31. option tcp-check
  32. balance roundrobin
  33. default-server inter 10s downinter 5s rise 2 fall 2 slowstart 60s maxconn 250 maxqueue 256 weight 100
  34. server k8s-master01 10.0.0.104:6443 check
  35. server k8s-master02 10.0.0.105:6443 check
  36. server k8s-master03 10.0.0.106:6443 check

2.5.2 Keepalived配置

所有Master节点配置Keepalived,以下三个Master节点配置注意ip和网卡。

Master01配置

  1. [root@k8s-master01 ~]# vim /etc/keepalived/keepalived.conf
  2. ! Configuration File for keepalived
  3. global_defs {
  4. router_id LVS_DEVEL
  5. script_user root
  6. enable_script_security
  7. }
  8. vrrp_script chk_apiserver {
  9. script "/etc/keepalived/check_apiserver.sh"
  10. interval 5
  11. weight -5
  12. fall 2
  13. rise 1
  14. }
  15. vrrp_instance VI_1 {
  16. state MASTER
  17. interface eth0
  18. mcast_src_ip 10.0.0.104
  19. virtual_router_id 51
  20. priority 101
  21. advert_int 2
  22. authentication {
  23. auth_type PASS
  24. auth_pass K8SHA_KA_AUTH
  25. }
  26. virtual_ipaddress {
  27. 10.0.0.236
  28. }
  29. track_script {
  30. chk_apiserver
  31. }
  32. }

Master02配置

  1. [root@k8s-master02 ~]# cat /etc/keepalived/keepalived.conf
  2. ! Configuration File for keepalived
  3. global_defs {
  4. router_id LVS_DEVEL
  5. script_user root
  6. enable_script_security
  7. }
  8. vrrp_script chk_apiserver {
  9. script "/etc/keepalived/check_apiserver.sh"
  10. interval 5
  11. weight -5
  12. fall 2
  13. rise 1
  14. }
  15. vrrp_instance VI_1 {
  16. state BACKUP
  17. interface eth0
  18. mcast_src_ip 10.0.0.105
  19. virtual_router_id 51
  20. priority 100
  21. advert_int 2
  22. authentication {
  23. auth_type PASS
  24. auth_pass K8SHA_KA_AUTH
  25. }
  26. virtual_ipaddress {
  27. 10.0.0.236
  28. }
  29. track_script {
  30. chk_apiserver
  31. }
  32. }

Master03配置

  1. [root@k8s-master03 ~]# cat /etc/keepalived/keepalived.conf
  2. ! Configuration File for keepalived
  3. global_defs {
  4. router_id LVS_DEVEL
  5. script_user root
  6. enable_script_security
  7. }
  8. vrrp_script chk_apiserver {
  9. script "/etc/keepalived/check_apiserver.sh"
  10. interval 5
  11. weight -5
  12. fall 2
  13. rise 1
  14. }
  15. vrrp_instance VI_1 {
  16. state BACKUP
  17. interface eth0
  18. mcast_src_ip 10.0.0.106
  19. virtual_router_id 51
  20. priority 100
  21. advert_int 2
  22. authentication {
  23. auth_type PASS
  24. auth_pass K8SHA_KA_AUTH
  25. }
  26. virtual_ipaddress {
  27. 10.0.0.236
  28. }
  29. track_script {
  30. chk_apiserver
  31. }
  32. }

所有Master节点配置Keepalived健康检查文件

  1. #cat /etc/keepalived/check_apiserver.sh
  2. #!/bin/bash
  3. err=0
  4. for k in $(seq 1 3)
  5. do
  6. check_code=$(pgrep haproxy)
  7. if [[ $check_code == "" ]]; then
  8. err=$(expr $err + 1)
  9. sleep 1
  10. continue
  11. else
  12. err=0
  13. break
  14. fi
  15. done
  16. if [[ $err != "0" ]]; then
  17. echo "systemctl stop keepalived"
  18. /usr/bin/systemctl stop keepalived
  19. exit 1
  20. else
  21. exit 0
  22. fi

赋予执行权限

chmod +x /etc/keepalived/check_apiserver.sh

所有Master节点启动haproxy和keepalived,并设置开机自启动。

  1. systemctl daemon-reload
  2. systemctl enable --now haproxy
  3. systemctl enable --now keepalived

2.5.3 测试VIP及HAproxy端口

所有节点测试VIP

  1. #ping 10.0.0.236 -c 2
  2. PING 10.0.0.236 (10.0.0.236) 56(84) bytes of data.
  3. 64 bytes from 10.0.0.236: icmp_seq=1 ttl=64 time=0.067 ms
  4. 64 bytes from 10.0.0.236: icmp_seq=2 ttl=64 time=0.061 ms

随便一台telnet VIP 16443端口,显示^]就说明端口开放的。

  1. [root@k8s-master01 ~]# telnet 10.0.0.236 16443
  2. Trying 10.0.0.236...
  3. Connected to 10.0.0.236.
  4. Escape character is '^]'.
  5. Connection closed by foreign host.

2.5.4 故障解决

  1. 所有节点查看防火墙状态必须为disable和inactive:systemctl status firewalld
  2. 所有节点查看selinux状态,必须为disable:getenforce
  3. 如果ping不通且telnet没有出现 ] ,VIP没起来,不可在继续往下执行,需要排查keepalived的问题,比如防火墙和selinux,haproxy和keepalived的状态,监听端口等。

master节点查看haproxy和keepalived状态:systemctl status keepalived haproxy

master节点查看监听端口:netstat -lntp

3. k8s集群安装

3.1 安装Docker作为Runtime

如果选择Docker作为Runtime,安装步骤较Containerd较为简单,只需要安装并启动即可。

所有节点安装docker-ce 20.10:

yum install docker-ce-20.10.* docker-ce-cli-20.10.* -y

由于新版Kubelet建议使用systemd,所以把Docker的CgroupDriver也改成systemd:

  1. mkdir /etc/docker
  2. cat > /etc/docker/daemon.json <<EOF
  3. {
  4. "exec-opts": ["native.cgroupdriver=systemd"]
  5. }
  6. EOF

所有节点设置开机自启动Docker

systemctl daemon-reload && systemctl enable --now docker

3.2 安装Kubenetes组件

在Master01节点查看最新的Kubernetes版本是多少,列出 kubeadm软件包的可用版本,并显示重复的版本,最后再进行一个最新版本优先顺序显示。

yum list kubeadm.x86_64 --showduplicates | sort -r

安装1.23最新版本kubeadm、kubelet和kubectl(所有节点均需安装)

yum install kubeadm-1.23* kubelet-1.23* kubectl-1.23* -y
  • kubeadm:用来初始化集群的指令。
  • kubelet:在集群中的每个节点上用来启动 Pod 和容器等。
  • kubectl:用来与集群通信的命令行工具。

设置Kubelet开机自启动(由于还未初始化,没有kubelet的配置文件,此时kubelet无法启动,无需管理)

  1. systemctl daemon-reload
  2. systemctl enable --now kubelet

3.3 集群初始化

以下操作在master01vim kubeadm-config.yaml

  1. apiVersion: kubeadm.k8s.io/v1beta2
  2. bootstrapTokens:
  3. - groups:
  4. - system:bootstrappers:kubeadm:default-node-token
  5. token: 7t2weq.bjbawausm0jaxury
  6. ttl: 24h0m0s
  7. usages:
  8. - signing
  9. - authentication
  10. kind: InitConfiguration
  11. localAPIEndpoint:
  12. advertiseAddress: 10.0.0.104
  13. bindPort: 6443
  14. nodeRegistration:
  15. criSocket: /var/run/dockershim.sock
  16. name: k8s-master01
  17. taints:
  18. - effect: NoSchedule
  19. key: node-role.kubernetes.io/master
  20. ---
  21. apiServer:
  22. certSANs:
  23. - 10.0.0.236
  24. timeoutForControlPlane: 4m0s
  25. apiVersion: kubeadm.k8s.io/v1beta2
  26. certificatesDir: /etc/kubernetes/pki
  27. clusterName: kubernetes
  28. controlPlaneEndpoint: 10.0.0.236:16443
  29. controllerManager: {}
  30. dns:
  31. type: CoreDNS
  32. etcd:
  33. local:
  34. dataDir: /var/lib/etcd
  35. imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers
  36. kind: ClusterConfiguration
  37. kubernetesVersion: v1.23.17 # 更改此处的版本号和kubeadm version一致
  38. networking:
  39. dnsDomain: cluster.local
  40. podSubnet: 172.16.0.0/16
  41. serviceSubnet: 192.168.0.0/16
  42. scheduler: {}

更新kubeadm文件

kubeadm config migrate --old-config kubeadm-config.yaml --new-config new.yaml

将new.yaml文件复制到其他master节点

  1. scp /root/new.yaml root@10.0.0.105:/root
  2. scp /root/new.yaml root@10.0.0.106:/root

之后所有Master节点提前下载镜像,可以节省初始化时间(其他节点不需要更改任何配置,包括IP地址也不需要更改)

kubeadm config images pull --config /root/new.yaml

三台Master拉取镜像结束如下:

Master01节点初始化,初始化以后会在/etc/kubernetes目录下生成对应的证书和配置文件,之后其他Master节点加入Master01即可。

kubeadm init --config /root/new.yaml  --upload-certs

初始化成功以后,会产生Token值,用于其他节点加入时使用,因此要记录下初始化成功生成的token值(令牌值),有效期24小时,后续需要操作可以重新生成Token

此时通过kubectl操作,会出现失败,因为还没有将集群的"钥匙"交给root用户。/etc/kubernetes/admin.conf 文件是 Kubernetes(K8s)集群中的管理员配置文件,它包含了用于管理集群的身份验证和访问信息。所以下面进行配置环境变量,用于访问Kubernetes集群:

  1. cat <<EOF >> /root/.bashrc
  2. export KUBECONFIG=/etc/kubernetes/admin.conf
  3. EOF
  4. source /root/.bashrc

此时root用户可以使用 Kubernetes 的命令行工具(例如 kubectl)或其他库来与集群进行交互,执行管理操作,例如创建、更新和删除资源,监视集群状态等。

Master01节点查看节点状态:(显示NotReady不影响)

采用kubeadm初始化安装方式,所有的系统组件均以容器的方式运行并且在kube-system命名空间内,此时可以查看Pod状态(Pending不用管,后续装好Node节点再回来看)

3.4 添加Master实现高可用

其他Master加入集群,master02和master03分别执行刚从上面获得的kubeadm join的命令参数。

如果Master01、02节点要操作集群就添加环境变量

  1. cat <<EOF >> /root/.bashrc
  2. export KUBECONFIG=/etc/kubernetes/admin.conf
  3. EOF
  4. source /root/.bashrc

查看当前node,三个master节点已在集群中。

3.5 模拟Token过期重新生成并加入Node节点

如果集群在运行过一段时间后需要新增Node或者Master节点,此时之前生成的Token会失效,需要重新生成Token。

Token过期后生成新的token:

kubeadm token create --print-join-command

Master需要生成--certificate-key:

kubeadm init phase upload-certs --upload-certs

生成新的Token用于集群添加新Node节点

复制到Node节点执行

查看当前node,两个Node节点已添加在集群中。

如果是新增Mster节点则拼接Token

  1. [root@k8s-master01 ~]# kubeadm token create --print-join-command
  2. kubeadm join 10.0.0.236:16443 --token t3esfj.wvv6a5b7661cbkp1 --discovery-token-ca-cert-hash sha256:163ab3f59152d1684bd0cba8a5b7347b248bb07aca8d420058d0f1ce0480b9bc
  3. [root@k8s-master01 ~]# kubeadm init phase upload-certs --upload-certs
  4. I0716 23:29:53.752376 58857 version.go:256] remote version is much newer: v1.27.3; falling back to: stable-1.23
  5. [upload-certs] Storing the certificates in Secret "kubeadm-certs" in the "kube-system" Namespace
  6. [upload-certs] Using certificate key:
  7. 49b6262e2eda9115c2f426374b72aac2590ebd86161e4c0fcf53f0e690eb59aa
  8. #拼接如下:
  9. kubeadm join 10.0.0.236:16443 --token t3esfj.wvv6a5b7661cbkp1 --discovery-token-ca-cert-hash sha256:163ab3f59152d1684bd0cba8a5b7347b248bb07aca8d420058d0f1ce0480b9bc --control-plane --certificate-key 49b6262e2eda9115c2f426374b72aac2590ebd86161e4c0fcf53f0e690eb59aa

3.6 安装Calico网络插件

git拉取下来k8s-ha-install的仓库

cd /root/ ; git clone https://gitee.com/dukuan/k8s-ha-install.git

以下步骤只在master01执行(.x不需要更改)

cd /root/k8s-ha-install && git checkout manual-installation-v1.23.x && cd calico/

vim calico.yml 配置文件修改Pod网段,并保存。(大约在配置文件的4365行)

如果不手动在配置文件修改,也可以使用以下命令直接替换。

  1. POD_SUBNET=`cat /etc/kubernetes/manifests/kube-controller-manager.yaml | grep cluster-cidr= | awk -F= '{print $NF}'`
  2. sed -i "s#POD_CIDR#${POD_SUBNET}#g" calico.yaml

然后进行安装calico

kubectl apply -f calico.yaml

calico.yaml 是 Calico 的配置清单文件,其中包含了部署 Calico 所需的各种 Kubernetes 资源和配置选项。这个文件定义了 Calico 控制器、网络策略、路由配置等参数。

通过执行 kubectl apply -f calico.yaml 命令,Kubernetes 集群会根据 calico.yaml 文件中的定义创建或更新相关的资源。apply 命令会检查已存在的资源并更新其配置,或者创建新资源。这样,Calico 的组件和配置将被应用到集群中,以实现 Calico 网络和网络策略。

查看集群中 kube-system命名空间下的所有 Pod 的状态信息,已经Running状态。

获取 Kubernetes 集群中所有的节点(Node)的状态信息,已经全部Ready状态。

3.7 Metrics部署

在新版(1.8版本开始)的Kubernetes中系统资源的采集均使用Metrics-server,可以通过Metrics采集节点和Pod的内存、磁盘、CPU和网络的使用率。

将Master01节点的front-proxy-ca.crt复制到所有Node节点

  1. scp /etc/kubernetes/pki/front-proxy-ca.crt 10.0.0.107:/etc/kubernetes/pki/front-proxy-ca.crt
  2. scp /etc/kubernetes/pki/front-proxy-ca.crt 10.0.0.108:/etc/kubernetes/pki/front-proxy-ca.crt

以下操作均在master01节点执行

  1. cd /root/k8s-ha-install/kubeadm-metrics-server
  2. kubectl create -f comp.yaml

查看这个Pod是否起来了,kubectl get po -n kube-system -l k8s-app=metrics-server,OK,已经Running。

此时可以查看集群中所有节点的资源使用情况,命令:kubectl top node

查看所有命名空间底下的Pod资源使用情况,命令:kubectl top pod -A

3.8 Dashboard部署

Dashboard用于展示集群中的各类资源,同时也可以通过Dashboard实时查看Pod的日志和在容器中执行一些命令等。

在Master01下执行

  1. cd /root/k8s-ha-install/dashboard/
  2. kubectl create -f .

kubectl get all -n kubernetes-dashboard 用于获取在 kubernetes-dashboard 命名空间中的所有资源的详细信息。

查看端口号kubectl get svc kubernetes-dashboard -n kubernetes-dashboard

根据自己的实例端口号,通过任意安装了kube-proxy的宿主机的IP+端口即可访问到dashboard,或者直接VIP+端口也可访问到dashboard。

创建登录Token

kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk '{print $1}')

将token值输入到令牌后,单击登录即可访问Dashboard。

3.9 必须的配置更改

将kube-proxy改为ipvs模式,因为在初始化集群的时候注释了ipvs配置,所以需要自行修改一下:

  1. #在master01节点执行
  2. kubectl edit cm kube-proxy -n kube-system
  3. #找到mode那一行修改成ipvs
  4. mode: ipvs

更新kube-proxy的Pod

kubectl patch daemonset kube-proxy -p "{\"spec\":{\"template\":{\"metadata\":{\"annotations\":{\"date\":\"`date +'%s'`\"}}}}}" -n kube-system

验证Kube-Proxy模式

  1. [root@k8s-master01 ~]# curl 127.0.0.1:10249/proxyMode
  2. ipvs

4. 集群可用性验证

节点均需正常

kubectl get node

Pod均需正常

kubectl get pod -A

检查集群网段无任何冲突

  1. kubectl get svc
  2. kubectl get pod -A -owide

能够正常创建资源

kubectl create deploy cluster-test --image=registry.cn-beijing.aliyuncs.com/dotbalo/debug-tools -- sleep 3600

Pod 必须能够解析 Service(同 namespace 和跨 namespace)

  1. #取上面的NAME进入pod
  2. kubectl exec -it cluster-test-8b47d69f5-dbvvf -- bash
  3. #解析两个域名,能够对应到.1和.10即可
  4. nslookup kubernetes
  5. nslookup kube-dns.kube-system

每个节点都必须要能访问 Kubernetes 的 kubernetes svc 443 和 kube-dns 的 service 53

  1. curl https://192.168.0.1:443
  2. curl 192.168.0.10:53

每个节点均需出现以下返回信息说明已通

Pod 和 Pod 之间要能够正常通讯(同 namespace 和跨 namespace)

  1. #刚刚创建的一个测试Pod,看看IP也放在哪个节点上
  2. [root@k8s-master01 ~]# kubectl get pod -owide
  3. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  4. cluster-test-8b47d69f5-dbvvf 1/1 Running 0 6m34s 172.16.58.194 k8s-node02 <none> <none>
  5. #找出不在node02上的Pod IP,然后两个Pod之间不在同一机器上进ping
  6. kubectl get pod -n kube-system -owide

Pod 和 Pod 之间要能够正常通讯(同机器和跨机器)

  1. #找刚从创建的测试Pod IP,全主机进行ping测试,都ping通即可。
  2. [root@k8s-master01 ~]# kubectl get pod -owide
  3. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  4. cluster-test-8b47d69f5-dbvvf 1/1 Running 0 9m23s 172.16.58.194 k8s-node02 <none> <none>

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号