本文以 青云平台 作为演示。 k8s 的版本是 1.21.1 。 本文所使用到的资源都在这里附件.zip。 做实验,最好还是选择云服务器为企业型,基础型带宽实在太低了,本文使用的是基础型,感觉性能和网速等都不是很好。

第一章:前言

1.1 安装方式

  • kubeadm:一个用于快速搭建 Kubernetes 集群的工具(可以用于生产环境);但是,启动慢,集群恢复的速度慢。
  • 二进制:核心组件是 Linux 服务(建议生产环境使用),启动快,集群恢复的速度快,维护方便。

本次使用二进制方式安装。

1.2 集群类型

  • Kubernetes 集群大致分为两类:一主多从和多主多从。
    • 一主多从(单 master ):一个 Master 节点和多台 Node 节点,搭建简单,但是有单机故障风险,适合用于测试环境。
    • 多主多从(高可用):多台 Master 节点和多台 Node 节点,搭建麻烦,安全性高,适合用于生产环境。
  • 单 master 的架构图:

1.png

  • 高可用集群的架构图:

2.png

3.png

第二章:开通服务器

2.1 VPC 网络划分示意图

1.jpg

2.2 创建 VPC 网络

2.png

3.png

4.png

5.png

2.3 创建云服务器

2.3.1 创建 master 机器

  • 创建三台 master 机器,下面只会给出一台机器的创建过程,依次类推即可。

6.png

7.png

8.png

9.png

  • 根据上面的步骤,依次创建 k8s-master2、k8s-master3 机器,其配置如下: | 机器 | IP | 配置 | | —- | —- | —- | | k8s-master1 | 192.168.0.10 | 2核4G | | k8s-master2 | 192.168.0.11 | 2核4G | | k8s-master3 | 192.168.0.12 | 2核4G |
  • 最终创建完的结果如下:

10.png

2.3.2 创建 node 机器

  • 创建三台 node 机器,步骤参考《创建 master 机器》
  • k8s-node1、k8s-node2、k8s-node3 机器的配置如下: | 机器 | IP | 配置 | | —- | —- | —- | | k8s-node1 | 192.168.0.13 | 4核8G | | k8s-node2 | 192.168.0.14 | 4核8G | | k8s-node3 | 192.168.0.15 | 4核8G |
  • 最终创建完的结果如下:

11.png

2.3.3 设置安全组的组内互信

12.png

13.png

2.3.4 添加 VPC 的端口转发规则

  • 因为只有 VPC 有公网 IP 地址,所以为了能够远程连接 VPC 下的子网的云服务器,我们需要配置端口转发规则。

14.png

15.png

16.png

17.png

2.3.5 安全组开放 VPC 转发的端口

18.png

19.png

20.png

21.png

  • 除此之外,还需要开放 http 的 80 端口以及 https 的 443 端口。

22.png

  • 但是,因为 VPC 网络和云服务器都是使用的一个安全组,而安全组我有禁止 22 端口,那么一定会出现虽然我配置了 VPC 的端口转发规则,但是远程就是连接不上,怎么办?
    • ① 重新创建新的服务器,但是不配置安全组。
    • ② 重新创建新的服务器,选择新的安全组。
    • ③ 将安全组从云服务器上解绑(其实,使用的是默认的安全组)。
  • 以上的两种方案都是可以的,我选择第三种方案(将安全组从云服务器上解绑)。
  • 因为我是边操作边写的,如果选择方案一和二,那么我还需要重新做一遍,太麻烦了。^_^
  • 生产环境中,建议 VPC 和云服务器的安全组分开比较好,方便管理。

23.png

24.png

2.4 xshell 连接

  • xshell 连接到远程云服务器上。

25.png

  • 依次配置即可。

26.png

第三章:升级内核

3.1 查看内核

  • 默认的 Centos 7.9 的内核是 3.10 ,在大规模集群中不稳定,所以需要升级内核。

  • 命令:

  1. uname -sr

27.gif

3.2 升级软件包,不升级内核

  • 命令:
  1. yum update -y --exclude=kernel*

28.gif

3.3 在 CentOS 7.x 上启用 ELRepo 仓库

  • 命令:
  1. rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
  1. rpm -Uvh https://www.elrepo.org/elrepo-release-7.0-4.el7.elrepo.noarch.rpm

29.gif

3.4 安装镜像加速

  • 命令:
  1. yum install -y yum-plugin-fastestmirror

30.gif

3.5 列出可用的内核相关包(选做)

  • 命令:
  1. yum --disablerepo="*" --enablerepo="elrepo-kernel" list available

注意:

  • kernel-lt: long term support:长期支持版。
  • kernel-ml: mainline stable: 主线稳定版。

31.gif

3.6 安装内核

  • 命令:
  1. yum -y --enablerepo=elrepo-kernel install kernel-ml

我选择的是主线稳定版,你也可以选择长期支持版。

32.gif

3.7 查看内核(选做)

  • 命令:
  1. uname -sr

33.gif

仅仅安装了内核是没用的,因为此时还没启用最新的内核。

3.8 查看内核的位置(选做)

  • 命令:
  1. awk -F\' '$1=="menuentry " {print $2}' /etc/grub2.cfg

34.gif

  1. CentOS Linux 7 Rescue 6e7213ddfcb53de7a920d7c702595fc8 (5.17.1-1.el7.elrepo.x86_64) # 第0个
  2. CentOS Linux (5.17.1-1.el7.elrepo.x86_64) 7 (Core)# 我们自己安装的在第1
  3. CentOS Linux (3.10.0-1160.el7.x86_64) 7 (Core)
  4. CentOS Linux (0-rescue-cc2c86fe566741e6a2ff6d399c5d5daa) 7 (Core)

3.9 重新创建内核配置

  • 命令:
  1. grub2-mkconfig -o /boot/grub2/grub.cfg

35.gif

3.10 查看内核的位置(选做)

  • 命令:
  1. awk -F\' '$1=="menuentry " {print $2}' /etc/grub2.cfg

36.gif

  1. CentOS Linux (5.17.1-1.el7.elrepo.x86_64) 7 (Core)
  2. CentOS Linux (3.10.0-1160.el7.x86_64) 7 (Core)
  3. CentOS Linux (0-rescue-57dd577c800933a5a43274612b265d43) 7 (Core)
  4. CentOS Linux (0-rescue-cc2c86fe566741e6a2ff6d399c5d5daa) 7 (Core)

3.11 修改使用默认内核

  • 命令:
  1. vi /etc/default/grub
  1. GRUB_TIMEOUT=5
  2. GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
  3. GRUB_DEFAULT=0 # 修改此处,原来是 saved
  4. GRUB_DISABLE_SUBMENU=true
  5. GRUB_TERMINAL_OUTPUT="console"
  6. GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet"
  7. GRUB_DISABLE_RECOVERY="true"
  1. # 重新整理下内核
  2. grub2-mkconfig -o /boot/grub2/grub.cfg

37.gif

3.12 重启系统

  • 命令:
  1. reboot

38.gif

3.13 查看内核(选做)

  • 命令:
  1. uname -sr

39.gif

第四章:Kubernetes 高可用架构图

4.1 高可用

  • 业务代码高可用(无状态,比如:用 Java 写的商城微服务,各个微服务都是无状态的),只需要负载均衡+多副本即可。
  • 数据存储中间件的高可用(有状态),不同产品有不同的方式(如:MySQL 采取的是主从复制,日志同步;Redis 采取的是槽),不管方式怎么变,只需要做到数据分片、数据副本同步即可。
  • Kubernetes 中除了 etcd 都是无状态应用。

4.2 Kubernetes 高可用架构图

40.png

第五章:证书

5.1 Kubernetes 中的证书体系

41.jpg

5.2 CFSSL 的介绍和安装

5.2.1 介绍

  • CFSSL 是 CloudFlare 开源的一款 PKI/TLS 工具。 CFSSL 包含一个命令行工具和一个用于签名,验证并且捆绑 TLS 证书的 HTTP API 服务。 使用 Go 语言编写。
  • Github 地址

5.2.2 安装

  • 如果 wget 命令没有,使用如下的命令安装:
  1. yum -y install wget
  • 去官网下载 cfssl-certinfo_linux-amd64 cfssljson_linux-amd64 cfssl_linux-amd64 这三个组件:
  1. # 注意:只需要在一台机器下载即可
  2. wget https://github.com/cloudflare/cfssl/releases/download/v1.5.0/cfssl-certinfo_1.5.0_linux_amd64
  3. wget https://github.com/cloudflare/cfssl/releases/download/v1.5.0/cfssl_1.5.0_linux_amd64
  4. wget https://github.com/cloudflare/cfssl/releases/download/v1.5.0/cfssljson_1.5.0_linux_amd64

42.gif

  • 授权执行权限:
  1. chmod +x cfssl*

43.gif

  • 批量重命名:
  1. for name in `ls cfssl*`; do mv $name ${name%_1.5.0_linux_amd64}; done

44.gif

  • 移动文件:
  1. mv cfssl* /usr/bin

45.gif

5.3 证书是如何产生的?

  • 使用浏览器和服务器之间的传输来模拟证书是如何产生的?
  • ① 如果浏览器和服务器之间采取的是明文传输,那么后果不堪设想。

46.png

  • ② 如果采用一对密钥将至少保证单方的安全性。

47.png

  • ③ 如果浏览器和服务器端都采取一对密钥,那么浏览器端和服务器端的数据传输将会非常安全,但是黑客不拦截请求和响应,直接做一个钓鱼网站。

48.png

需要注意的是,在 Kubernetes 中,私钥就是证书的 key ,公钥就是证书,当然也会存在 CA 机构的。

5.4 证书制作步骤

  • 证书制作的步骤:
    • ① 证书颁发机构,如:CA 机构等。
    • ② 提交证书申请,根据申请 CA 机构颁发证书给我们。
  • 同理,使用 cfssl 自签证书的步骤如下:
    • ① 自己的证书机构(初始化一个证书颁发机构)。
    • ② 使用之前的证书颁发机构,颁发证书给别人。

第六章:集群搭建

6.1 准备工作

6.1.1 升级内核

  • 略(已完成)。

6.1.2 设置主机名

  • 命令:
  1. hostnamectl set-hostname <hostname>
  • 由于,我在开通云服务器的时候,已经设置过了,此处就不再设置了。

6.1.3 主机名解析

  • 为了方便后面集群节点间的直接调用,需要配置一下主机名解析,企业中推荐使用内部的 DNS 服务器。
  1. cat >> /etc/hosts << EOF
  2. 192.168.0.10 k8s-master1
  3. 192.168.0.11 k8s-master2
  4. 192.168.0.12 k8s-master3
  5. 192.168.0.13 k8s-node1
  6. 192.168.0.14 k8s-node2
  7. 192.168.0.15 k8s-node3
  8. 192.168.0.250 k8s-master-lb # master 负载均衡器的 ip,这个使用 keepalive 配置
  9. EOF

49.gif

6.1.4 时间同步(可以不做)

因为云服务器默认就是时间同步的,所以可以不做此步骤。

  • Kubernetes 要求集群中的节点时间必须精确一致,所以在每个节点上添加时间同步:
  1. yum install ntpdate -y
  1. ntpdate time.windows.com

50.gif

6.1.5 关闭 selinux

  • 命令:
  1. # 查看 SELinux 是否开启
  2. getenforce
  3. # 永久关闭 SELinux ,需要重启:
  4. sed -i 's#SELINUX=enforcing#SELINUX=disabled#g' /etc/sysconfig/selinux
  5. sed -i 's#SELINUX=enforcing#SELINUX=disabled#g' /etc/selinux/config
  6. # 关闭当前会话的 SELinux ,重启之后无效:
  7. setenforce 0

51.gif

6.1.6 关闭 swap 分区

  • 命令:
  1. # 关闭当前会话的 swap
  2. swapoff -a && sysctl -w vm.swappiness=0
  3. # 永久关闭 swap ,需要重启
  4. sed -ri 's/.*swap.*/#&/' /etc/fstab

52.gif

6.1.7 修改 limit

  • 命令:
  1. ulimit -SHn 65535
  1. vi /etc/security/limits.conf
  1. # 末尾添加如下内容
  2. * soft nofile 655360
  3. * hard nofile 131072
  4. * soft nproc 655350
  5. * hard nproc 655350
  6. * soft memlock unlimited
  7. * hard memlock unlimited

53.gif

6.1.8 配置 ssh 免密连接

  • 命令:
  1. ssh-keygen -t rsa
  1. for i in k8s-master1 k8s-master2 k8s-master3 k8s-node1 k8s-node2 k8s-node3;do ssh-copy-id -i .ssh/id_rsa.pub $i;done

54.gif

6.1.9 安装一些工具

  • 命令:
  1. yum -y install wget git jq psmisc net-tools yum-utils device-mapper-persistent-data lvm2

55.gif

6.1.10 安装 ipvs

  • 在 Kubernetes 中 service 有两种代理模型,一种是基于 iptables ,另一种是基于 ipvs 的。ipvs 的性能要高于 iptables 的,但是如果要使用它,需要手动载入 ipvs 模块。
  • 命令:
  1. # 安装ipvs工具,方便以后操作ipvs,ipset,conntrack等
  2. yum install ipvsadm ipset sysstat conntrack libseccomp -y
  1. # 所有节点配置ipvs模块,执行以下命令,在内核4.19+版本改为nf_conntrack, 4.18下改为nf_conntrack_ipv4
  2. modprobe -- ip_vs
  3. modprobe -- ip_vs_rr
  4. modprobe -- ip_vs_wrr
  5. modprobe -- ip_vs_sh
  6. modprobe -- nf_conntrack
  1. # 修改ipvs配置,加入以下内容
  2. cat >> /etc/modules-load.d/ipvs.conf << EOF
  3. ip_vs
  4. ip_vs_lc
  5. ip_vs_wlc
  6. ip_vs_rr
  7. ip_vs_wrr
  8. ip_vs_lblc
  9. ip_vs_lblcr
  10. ip_vs_dh
  11. ip_vs_sh
  12. ip_vs_fo
  13. ip_vs_nq
  14. ip_vs_sed
  15. ip_vs_ftp
  16. ip_vs_sh
  17. nf_conntrack
  18. ip_tables
  19. ip_set
  20. xt_set
  21. ipt_set
  22. ipt_rpfilter
  23. ipt_REJECT
  24. ipip
  25. EOF
  1. # 执行命令
  2. systemctl enable --now systemd-modules-load.service #--now = enable+start
  1. #检测是否加载
  2. lsmod | grep -e ip_vs -e nf_conntrack

56.gif

6.1.11 将桥接的 IPv4 流量传递到 iptables 的链

  • 命令:
  1. ## 所有节点
  2. cat <<EOF > /etc/sysctl.d/k8s.conf
  3. net.ipv4.ip_forward = 1
  4. net.bridge.bridge-nf-call-iptables = 1
  5. net.bridge.bridge-nf-call-ip6tables = 1
  6. fs.may_detach_mounts = 1
  7. vm.overcommit_memory=1
  8. net.ipv4.conf.all.route_localnet = 1
  9. vm.panic_on_oom=0
  10. fs.inotify.max_user_watches=89100
  11. fs.file-max=52706963
  12. fs.nr_open=52706963
  13. net.netfilter.nf_conntrack_max=2310720
  14. net.ipv4.tcp_keepalive_time = 600
  15. net.ipv4.tcp_keepalive_probes = 3
  16. net.ipv4.tcp_keepalive_intvl =15
  17. net.ipv4.tcp_max_tw_buckets = 36000
  18. net.ipv4.tcp_tw_reuse = 1
  19. net.ipv4.tcp_max_orphans = 327680
  20. net.ipv4.tcp_orphan_retries = 3
  21. net.ipv4.tcp_syncookies = 1
  22. net.ipv4.tcp_max_syn_backlog = 16768
  23. net.ipv4.ip_conntrack_max = 65536
  24. net.ipv4.tcp_timestamps = 0
  25. net.core.somaxconn = 16768
  26. EOF
  1. sysctl --system

57.gif

6.1.2 重启机器

  • 命令:
  1. reboot

58.gif

6.2 安装 Docker

  • 卸载旧版本:
  1. sudo yum remove docker \
  2. docker-client \
  3. docker-client-latest \
  4. docker-common \
  5. docker-latest \
  6. docker-latest-logrotate \
  7. docker-logrotate \
  8. docker-engine

59.gif

  • yum 安装 gcc 相关:
  1. yum -y install gcc
  1. yum -y install gcc-c++

60.gif

  • 安装所需要的软件包:
  1. yum -y install yum-utils

61.gif

  • 设置 stable 镜像仓库:
  1. yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

62.gif

  • 更新 yum 软件包索引:
  1. yum makecache fast

63.gif

  • 安装指定版本的 Docker(v20.10) :
  1. yum -y install docker-ce-3:20.10.8-3.el7.x86_64 docker-ce-cli-3:20.10.8-3.el7.x86_64 containerd.io

64.gif

  • 启动 Docker :
  1. # 启动 Docker
  2. systemctl start docker
  1. # 开启自动启动
  2. systemctl enable docker

65.gif

  • 阿里云镜像加速:
  1. sudo mkdir -p /etc/docker
  1. sudo tee /etc/docker/daemon.json <<-'EOF'
  2. {
  3. "exec-opts": ["native.cgroupdriver=systemd"],
  4. "registry-mirrors": [
  5. "https://du3ia00u.mirror.aliyuncs.com",
  6. "https://hub-mirror.c.163.com",
  7. "https://mirror.baidubce.com"
  8. ],
  9. "live-restore": true,
  10. "log-driver":"json-file",
  11. "log-opts": {"max-size":"500m", "max-file":"3"},
  12. "max-concurrent-downloads": 10,
  13. "max-concurrent-uploads": 5,
  14. "storage-driver": "overlay2"
  15. }
  16. EOF
  1. sudo systemctl daemon-reload
  1. sudo systemctl restart docker

66.gif

6.3 etcd 高可用搭建

6.3.1 etcd 集群规划

  • 小型 k8s 集群(50 个 node 节点): | Provider | Type | vCPUs | Memory (GB) | Max concurrent IOPS | Disk bandwidth (MB/s) | | —- | —- | —- | —- | —- | —- | | AWS | m4.large | 2 | 8 | 3600 | 56.25 | | GCE | n1-standard-2 + 50GB PD SSD | 2 | 7.5 | 1500 | 25 |
  • 中型 k8s 集群(250 个 node 节点): | Provider | Type | vCPUs | Memory (GB) | Max concurrent IOPS | Disk bandwidth (MB/s) | | —- | —- | —- | —- | —- | —- | | AWS | m4.xlarge | 4 | 16 | 6000 | 93.75 | | GCE | n1-standard-4 + 150GB PD SSD | 4 | 15 | 4500 | 75 |
  • 大型 k8s 集群(1000 个 node 节点): | Provider | Type | vCPUs | Memory (GB) | Max concurrent IOPS | Disk bandwidth (MB/s) | | —- | —- | —- | —- | —- | —- | | AWS | m4.2xlarge | 8 | 32 | 8000 | 125 | | GCE | n1-standard-8 + 250GB PD SSD | 8 | 30 | 7500 | 125 |
  • 超大型 k8s 集群(3000 个 node 节点): | Provider | Type | vCPUs | Memory (GB) | Max concurrent IOPS | Disk bandwidth (MB/s) | | —- | —- | —- | —- | —- | —- | | AWS | m4.4xlarge | 16 | 64 | 16,000 | 250 | | GCE | n1-standard-16 + 500GB PD SSD | 16 | 60 | 15,000 | 250 |

6.3.2 下载和解压 etcd

  • 给所有 master 节点,发送 etcd 包,以便部署 etcd 高可用:
  • 下载 etcd (k8s-master1):
  1. wget https://github.com/etcd-io/etcd/releases/download/v3.4.16/etcd-v3.4.16-linux-amd64.tar.gz

67.gif

  • 将 etcd 包复制到其他节点(k8s-master1):
  1. for i in k8s-master1 k8s-master2 k8s-master3;do scp etcd-* root@$i:/root/;done

68.gif

  • 解压 etcd 包到 /usr/local/bin(所有 master 节点):
  1. tar -zxvf etcd-v3.4.16-linux-amd64.tar.gz --strip-components=1 -C /usr/local/bin etcd-v3.4.16-linux-amd64/etcd{,ctl}

69.gif

  • 验证:
  1. etcdctl

70.gif

6.3.3 etcd 证书

  • 创建目录(k8s-master1):
  1. mkdir -pv /etc/kubernetes/pki/etcd

71.gif

  • 创建 etcd 根配置(k8s-master1):
  1. sudo tee /etc/kubernetes/pki/etcd-ca-csr.json <<-'EOF'
  2. {
  3. "CN": "etcd",
  4. "key": {
  5. "algo": "rsa",
  6. "size": 2048
  7. },
  8. "names": [
  9. {
  10. "C": "CN",
  11. "ST": "Beijing",
  12. "L": "Beijing",
  13. "O": "etcd",
  14. "OU": "etcd"
  15. }
  16. ],
  17. "ca": {
  18. "expiry": "87600h"
  19. }
  20. }
  21. EOF

72.gif

  • 生成 etcd 根 ca 证书(k8s-master1):
  1. cfssl gencert -initca \
  2. /etc/kubernetes/pki/etcd-ca-csr.json | cfssljson -bare /etc/kubernetes/pki/etcd/ca -

73.gif

  • 创建 etcd-cluster 配置(k8s-master1):
  1. sudo tee /etc/kubernetes/pki/etcd-cluster-csr.json <<-'EOF'
  2. {
  3. "CN": "etcd-cluster",
  4. "key": {
  5. "algo": "rsa",
  6. "size": 2048
  7. },
  8. "hosts": [
  9. "127.0.0.1",
  10. "k8s-master1",
  11. "k8s-master2",
  12. "k8s-master3",
  13. "192.168.0.10",
  14. "192.168.0.11",
  15. "192.168.0.12"
  16. ],
  17. "names": [
  18. {
  19. "C": "CN",
  20. "L": "beijing",
  21. "O": "etcd",
  22. "ST": "beijing",
  23. "OU": "System"
  24. }
  25. ]
  26. }
  27. EOF

注意:hosts 中配置的是 etcd 所在机器的主机名和 IP 地址,表示只能在这些机器受信。

74.gif

  • 创建 ca-config.json 文件(k8s-master1):
  1. sudo tee /etc/kubernetes/pki/ca-config.json <<-'EOF'
  2. {
  3. "signing": {
  4. "default": {
  5. "expiry": "87600h"
  6. },
  7. "profiles": {
  8. "server": {
  9. "expiry": "87600h",
  10. "usages": [
  11. "signing",
  12. "key encipherment",
  13. "server auth"
  14. ]
  15. },
  16. "client": {
  17. "expiry": "87600h",
  18. "usages": [
  19. "signing",
  20. "key encipherment",
  21. "client auth"
  22. ]
  23. },
  24. "peer": {
  25. "expiry": "87600h",
  26. "usages": [
  27. "signing",
  28. "key encipherment",
  29. "server auth",
  30. "client auth"
  31. ]
  32. },
  33. "kubernetes": {
  34. "expiry": "87600h",
  35. "usages": [
  36. "signing",
  37. "key encipherment",
  38. "server auth",
  39. "client auth"
  40. ]
  41. },
  42. "etcd": {
  43. "expiry": "87600h",
  44. "usages": [
  45. "signing",
  46. "key encipherment",
  47. "server auth",
  48. "client auth"
  49. ]
  50. }
  51. }
  52. }
  53. }
  54. EOF

75.gif

  • 签发 cluster 的 etcd 证书(k8s-master1):
  1. cfssl gencert \
  2. -ca=/etc/kubernetes/pki/etcd/ca.pem \
  3. -ca-key=/etc/kubernetes/pki/etcd/ca-key.pem \
  4. -config=/etc/kubernetes/pki/ca-config.json \
  5. -profile=etcd \
  6. /etc/kubernetes/pki/etcd-cluster-csr.json | cfssljson -bare /etc/kubernetes/pki/etcd/etcd

76.gif

  • 给 k8s-master2 和 k8s-master3 创建目录:
  1. mkdir -pv /etc/kubernetes/pki

77.gif

  • 将生成的 etcd 证书复制到其他 master 机器(k8s-master1):
  1. for i in k8s-master2 k8s-master3;do scp -r /etc/kubernetes/pki/etcd root@$i:/etc/kubernetes/pki;done

78.gif

6.3.4 etcd 高可用安装

  • 为了保证启动配置一致性,我们编写 etcd 配置文件,并将 etcd 做成 service 启动。
  • 三台 master 机器创建 /etc/etcd 目录:
  1. mkdir -pv /etc/etcd

79.gif

  • k8s-master1 的 etcd 配置文件:
  1. sudo tee /etc/etcd/etcd.yaml <<-'EOF'
  2. name: 'etcd-master1' #每个机器可以写自己的域名,不能重复
  3. data-dir: /var/lib/etcd
  4. wal-dir: /var/lib/etcd/wal
  5. snapshot-count: 5000
  6. heartbeat-interval: 100
  7. election-timeout: 1000
  8. quota-backend-bytes: 0
  9. listen-peer-urls: 'https://192.168.0.10:2380' # 本机ip+2380端口,代表和集群通信
  10. listen-client-urls: 'https://192.168.0.10:2379,http://127.0.0.1:2379' #改为自己的
  11. max-snapshots: 3
  12. max-wals: 5
  13. cors:
  14. initial-advertise-peer-urls: 'https://192.168.0.10:2380' #自己的ip
  15. advertise-client-urls: 'https://192.168.0.10:2379' #自己的ip
  16. discovery:
  17. discovery-fallback: 'proxy'
  18. discovery-proxy:
  19. discovery-srv:
  20. initial-cluster: 'etcd-master1=https://192.168.0.10:2380,etcd-master2=https://192.168.0.11:2380,etcd-master3=https://192.168.0.12:2380' #这里不一样
  21. initial-cluster-token: 'etcd-k8s-cluster'
  22. initial-cluster-state: 'new'
  23. strict-reconfig-check: false
  24. enable-v2: true
  25. enable-pprof: true
  26. proxy: 'off'
  27. proxy-failure-wait: 5000
  28. proxy-refresh-interval: 30000
  29. proxy-dial-timeout: 1000
  30. proxy-write-timeout: 5000
  31. proxy-read-timeout: 0
  32. client-transport-security:
  33. cert-file: '/etc/kubernetes/pki/etcd/etcd.pem'
  34. key-file: '/etc/kubernetes/pki/etcd/etcd-key.pem'
  35. client-cert-auth: true
  36. trusted-ca-file: '/etc/kubernetes/pki/etcd/ca.pem'
  37. auto-tls: true
  38. peer-transport-security:
  39. cert-file: '/etc/kubernetes/pki/etcd/etcd.pem'
  40. key-file: '/etc/kubernetes/pki/etcd/etcd-key.pem'
  41. peer-client-cert-auth: true
  42. trusted-ca-file: '/etc/kubernetes/pki/etcd/ca.pem'
  43. auto-tls: true
  44. debug: false
  45. log-package-levels:
  46. log-outputs: [default]
  47. force-new-cluster: false
  48. EOF

80.gif

  • k8s-master2 的 etcd 配置文件:
  1. sudo tee /etc/etcd/etcd.yaml <<-'EOF'
  2. name: 'etcd-master2' #每个机器可以写自己的域名,不能重复
  3. data-dir: /var/lib/etcd
  4. wal-dir: /var/lib/etcd/wal
  5. snapshot-count: 5000
  6. heartbeat-interval: 100
  7. election-timeout: 1000
  8. quota-backend-bytes: 0
  9. listen-peer-urls: 'https://192.168.0.11:2380' # 本机ip+2380端口,代表和集群通信
  10. listen-client-urls: 'https://192.168.0.11:2379,http://127.0.0.1:2379' #改为自己的
  11. max-snapshots: 3
  12. max-wals: 5
  13. cors:
  14. initial-advertise-peer-urls: 'https://192.168.0.11:2380' #自己的ip
  15. advertise-client-urls: 'https://192.168.0.11:2379' #自己的ip
  16. discovery:
  17. discovery-fallback: 'proxy'
  18. discovery-proxy:
  19. discovery-srv:
  20. initial-cluster: 'etcd-master1=https://192.168.0.10:2380,etcd-master2=https://192.168.0.11:2380,etcd-master3=https://192.168.0.12:2380' #这里不一样
  21. initial-cluster-token: 'etcd-k8s-cluster'
  22. initial-cluster-state: 'new'
  23. strict-reconfig-check: false
  24. enable-v2: true
  25. enable-pprof: true
  26. proxy: 'off'
  27. proxy-failure-wait: 5000
  28. proxy-refresh-interval: 30000
  29. proxy-dial-timeout: 1000
  30. proxy-write-timeout: 5000
  31. proxy-read-timeout: 0
  32. client-transport-security:
  33. cert-file: '/etc/kubernetes/pki/etcd/etcd.pem'
  34. key-file: '/etc/kubernetes/pki/etcd/etcd-key.pem'
  35. client-cert-auth: true
  36. trusted-ca-file: '/etc/kubernetes/pki/etcd/ca.pem'
  37. auto-tls: true
  38. peer-transport-security:
  39. cert-file: '/etc/kubernetes/pki/etcd/etcd.pem'
  40. key-file: '/etc/kubernetes/pki/etcd/etcd-key.pem'
  41. peer-client-cert-auth: true
  42. trusted-ca-file: '/etc/kubernetes/pki/etcd/ca.pem'
  43. auto-tls: true
  44. debug: false
  45. log-package-levels:
  46. log-outputs: [default]
  47. force-new-cluster: false
  48. EOF

81.gif

  • k8s-master3 的 etcd 配置文件:
  1. sudo tee /etc/etcd/etcd.yaml <<-'EOF'
  2. name: 'etcd-master3' #每个机器可以写自己的域名,不能重复
  3. data-dir: /var/lib/etcd
  4. wal-dir: /var/lib/etcd/wal
  5. snapshot-count: 5000
  6. heartbeat-interval: 100
  7. election-timeout: 1000
  8. quota-backend-bytes: 0
  9. listen-peer-urls: 'https://192.168.0.12:2380' # 本机ip+2380端口,代表和集群通信
  10. listen-client-urls: 'https://192.168.0.12:2379,http://127.0.0.1:2379' #改为自己的
  11. max-snapshots: 3
  12. max-wals: 5
  13. cors:
  14. initial-advertise-peer-urls: 'https://192.168.0.12:2380' #自己的ip
  15. advertise-client-urls: 'https://192.168.0.12:2379' #自己的ip
  16. discovery:
  17. discovery-fallback: 'proxy'
  18. discovery-proxy:
  19. discovery-srv:
  20. initial-cluster: 'etcd-master1=https://192.168.0.10:2380,etcd-master2=https://192.168.0.11:2380,etcd-master3=https://192.168.0.12:2380' #这里不一样
  21. initial-cluster-token: 'etcd-k8s-cluster'
  22. initial-cluster-state: 'new'
  23. strict-reconfig-check: false
  24. enable-v2: true
  25. enable-pprof: true
  26. proxy: 'off'
  27. proxy-failure-wait: 5000
  28. proxy-refresh-interval: 30000
  29. proxy-dial-timeout: 1000
  30. proxy-write-timeout: 5000
  31. proxy-read-timeout: 0
  32. client-transport-security:
  33. cert-file: '/etc/kubernetes/pki/etcd/etcd.pem'
  34. key-file: '/etc/kubernetes/pki/etcd/etcd-key.pem'
  35. client-cert-auth: true
  36. trusted-ca-file: '/etc/kubernetes/pki/etcd/ca.pem'
  37. auto-tls: true
  38. peer-transport-security:
  39. cert-file: '/etc/kubernetes/pki/etcd/etcd.pem'
  40. key-file: '/etc/kubernetes/pki/etcd/etcd-key.pem'
  41. peer-client-cert-auth: true
  42. trusted-ca-file: '/etc/kubernetes/pki/etcd/ca.pem'
  43. auto-tls: true
  44. debug: false
  45. log-package-levels:
  46. log-outputs: [default]
  47. force-new-cluster: false
  48. EOF

82.gif

  • 三台机器的 etcd 做成 Service ,开机启动:
  1. sudo tee /usr/lib/systemd/system/etcd.service <<-'EOF'
  2. [Unit]
  3. Description=Etcd Service
  4. Documentation=https://etcd.io/docs/v3.4/op-guide/clustering/
  5. After=network.target
  6. [Service]
  7. Type=notify
  8. ExecStart=/usr/local/bin/etcd --config-file=/etc/etcd/etcd.yaml
  9. Restart=on-failure
  10. RestartSec=10
  11. LimitNOFILE=65536
  12. [Install]
  13. WantedBy=multi-user.target
  14. Alias=etcd3.service
  15. EOF

83.gif

  • 加载并开机启动:
  1. systemctl daemon-reload
  1. systemctl enable --now etcd
  1. systemctl status etcd

84.gif

6.3.5 测试 etcd 是否可用

  • 命令行方式测试:
  1. # 查看 etcd 集群状态
  2. etcdctl --endpoints="192.168.0.10:2379,192.168.0.11:2379,192.168.0.12:2379" --cacert=/etc/kubernetes/pki/etcd/ca.pem --cert=/etc/kubernetes/pki/etcd/etcd.pem --key=/etc/kubernetes/pki/etcd/etcd-key.pem endpoint status --write-out=table

85.gif

  • 导出环境变量的方式测试:
  1. export ETCDCTL_API=3
  2. HOST_1=192.168.0.10
  3. HOST_2=192.168.0.11
  4. HOST_3=192.168.0.12
  5. ENDPOINTS=$HOST_1:2379,$HOST_2:2379,$HOST_3:2379
  6. export ETCDCTL_DIAL_TIMEOUT=3s
  7. export ETCDCTL_CACERT=/etc/kubernetes/pki/etcd/ca.pem
  8. export ETCDCTL_CERT=/etc/kubernetes/pki/etcd/etcd.pem
  9. export ETCDCTL_KEY=/etc/kubernetes/pki/etcd/etcd-key.pem
  10. export ETCDCTL_ENDPOINTS=$HOST_1:2379,$HOST_2:2379,$HOST_3:2379
  11. etcdctl member list --write-out=table

86.gif

两种测试方式,任选一种即可。

6.4 Kubernetes 组件和证书

6.4.1 Kubernetes 离线安装包

87.png

  • 下载 Kubernetes 离线安装包(k8s-master1):
  1. wget https://dl.k8s.io/v1.21.1/kubernetes-server-linux-amd64.tar.gz

88.gif

  • 将 Kubernetes 离线安装包发送到所有节点(k8s-master1):
  1. for i in k8s-master1 k8s-master2 k8s-master3 k8s-node1 k8s-node2 k8s-node3;do scp kubernetes-server-* root@$i:/root/;done

89.gif

  • master 节点(k8s-master1、k8s-master2、k8s-master3)解压 kubelet,kubectl 等到 /usr/local/bin
  1. tar -xvf kubernetes-server-linux-amd64.tar.gz --strip-components=3 -C /usr/local/bin kubernetes/server/bin/kube{let,ctl,-apiserver,-controller-manager,-scheduler,-proxy}

90.gif

  • node 节点(k8s-node1、k8s-node2、k8s-node3)解压 kubelet,kube-proxy 等到 /usr/local/bin
  1. tar -xvf kubernetes-server-linux-amd64.tar.gz --strip-components=3 -C /usr/local/bin kubernetes/server/bin/kube{let,-proxy}

91.gif

6.4.2 api-server 证书生成

  • 新建 apiserver-csr.json 文件(k8s-master1):
  1. sudo tee /etc/kubernetes/pki/apiserver-csr.json <<-'EOF'
  2. {
  3. "CN": "kube-apiserver",
  4. "hosts": [
  5. "10.96.0.1",
  6. "127.0.0.1",
  7. "192.168.0.250",
  8. "192.168.0.10",
  9. "192.168.0.11",
  10. "192.168.0.12",
  11. "192.168.0.13",
  12. "192.168.0.14",
  13. "192.168.0.15",
  14. "192.168.0.16",
  15. "kubernetes",
  16. "kubernetes.default",
  17. "kubernetes.default.svc",
  18. "kubernetes.default.svc.cluster",
  19. "kubernetes.default.svc.cluster.local"
  20. ],
  21. "key": {
  22. "algo": "rsa",
  23. "size": 2048
  24. },
  25. "names": [
  26. {
  27. "C": "CN",
  28. "L": "BeiJing",
  29. "ST": "BeiJing",
  30. "O": "Kubernetes",
  31. "OU": "Kubernetes"
  32. }
  33. ]
  34. }
  35. EOF

hosts 中配置的是各个节点的 ip 地址(192.168.0.250 是负载均衡器的地址,负载均衡器可以自己创建,也可以使用云厂商提供的 LB),以及 Service 的地址,其中 10.96.0.x 为 Service 的网段,当然,你也可以自定义。

92.gif

  • 生成 Kubernetes 的 CA 机构(k8s-master1):
  1. sudo tee /etc/kubernetes/pki/ca-csr.json <<-'EOF'
  2. {
  3. "CN": "kubernetes",
  4. "key": {
  5. "algo": "rsa",
  6. "size": 2048
  7. },
  8. "names": [
  9. {
  10. "C": "CN",
  11. "ST": "Beijing",
  12. "L": "Beijing",
  13. "O": "Kubernetes",
  14. "OU": "Kubernetes"
  15. }
  16. ],
  17. "ca": {
  18. "expiry": "87600h"
  19. }
  20. }
  21. EOF
  1. cfssl gencert -initca /etc/kubernetes/pki/ca-csr.json | cfssljson -bare /etc/kubernetes/pki/ca -

94.gif

  • 生成 api-server 证书:
  1. cfssl gencert \
  2. -ca=/etc/kubernetes/pki/ca.pem \
  3. -ca-key=/etc/kubernetes/pki/ca-key.pem \
  4. -config=/etc/kubernetes/pki/ca-config.json \
  5. -profile=kubernetes \
  6. /etc/kubernetes/pki/apiserver-csr.json | cfssljson -bare /etc/kubernetes/pki/apiserver

95.gif

6.4.3 front-proxy 证书生成

  • front-proxy 是 api-server 的聚合层,后来支持 CRD。

注意:

  • front-proxy 不建议用新的 CA 机构签发证书,可能导致通过他代理的组件如 metrics-server 权限不可用。
  • 如果用新的,api-server 配置添加 —requestheader-allowed-names=front-proxy-client。
  • 新建 front-proxy-ca-csr.json 文件(k8s-master1):
  1. sudo tee /etc/kubernetes/pki/front-proxy-ca-csr.json <<-'EOF'
  2. {
  3. "CN": "kubernetes",
  4. "key": {
  5. "algo": "rsa",
  6. "size": 2048
  7. }
  8. }
  9. EOF

96.gif

  • 生成 front-proxy 的 CA 机构(k8s-master1):
  1. cfssl gencert -initca /etc/kubernetes/pki/front-proxy-ca-csr.json | cfssljson -bare /etc/kubernetes/pki/front-proxy-ca

97.gif

  • 新建 front-proxy-client-csr.json 文件(k8s-master1):
  1. sudo tee /etc/kubernetes/pki/front-proxy-client-csr.json <<-'EOF'
  2. {
  3. "CN": "front-proxy-client",
  4. "key": {
  5. "algo": "rsa",
  6. "size": 2048
  7. }
  8. }
  9. EOF

98.gif

  • 生成 front-proxy 证书(k8s-master1):
  1. cfssl gencert \
  2. -ca=/etc/kubernetes/pki/front-proxy-ca.pem \
  3. -ca-key=/etc/kubernetes/pki/front-proxy-ca-key.pem \
  4. -config=/etc/kubernetes/pki/ca-config.json \
  5. -profile=kubernetes \
  6. /etc/kubernetes/pki/front-proxy-client-csr.json | cfssljson -bare /etc/kubernetes/pki/front-proxy-client

99.gif

6.4.4 controller-manager 证书生成和配置

  • 新建 controller-manager-csr.json 文件(k8s-master1):
  1. sudo tee /etc/kubernetes/pki/controller-manager-csr.json <<-'EOF'
  2. {
  3. "CN": "system:kube-controller-manager",
  4. "key": {
  5. "algo": "rsa",
  6. "size": 2048
  7. },
  8. "names": [
  9. {
  10. "C": "CN",
  11. "ST": "Beijing",
  12. "L": "Beijing",
  13. "O": "system:kube-controller-manager",
  14. "OU": "Kubernetes"
  15. }
  16. ]
  17. }
  18. EOF

100.gif

  • 生成证书(k8s-master1):
  1. cfssl gencert \
  2. -ca=/etc/kubernetes/pki/ca.pem \
  3. -ca-key=/etc/kubernetes/pki/ca-key.pem \
  4. -config=/etc/kubernetes/pki/ca-config.json \
  5. -profile=kubernetes \
  6. /etc/kubernetes/pki/controller-manager-csr.json | cfssljson -bare /etc/kubernetes/pki/controller-manager

101.gif

  • 生成配置(k8s-master1):
  1. # set-cluster:设置一个集群项,
  2. kubectl config set-cluster kubernetes \
  3. --certificate-authority=/etc/kubernetes/pki/ca.pem \
  4. --embed-certs=true \
  5. --server=https://192.168.0.250:6443 \
  6. --kubeconfig=/etc/kubernetes/controller-manager.conf

注意,如果不是高可用集群,192.168.0.250:6443 改为 master01 的地址,6443 为 apiserver 的默认端口。

  1. # 设置一个环境项,一个上下文
  2. kubectl config set-context system:kube-controller-manager@kubernetes \
  3. --cluster=kubernetes \
  4. --user=system:kube-controller-manager \
  5. --kubeconfig=/etc/kubernetes/controller-manager.conf
  1. # set-credentials 设置一个用户项
  2. kubectl config set-credentials system:kube-controller-manager \
  3. --client-certificate=/etc/kubernetes/pki/controller-manager.pem \
  4. --client-key=/etc/kubernetes/pki/controller-manager-key.pem \
  5. --embed-certs=true \
  6. --kubeconfig=/etc/kubernetes/controller-manager.conf
  1. # 使用某个环境当做默认环境
  2. kubectl config use-context system:kube-controller-manager@kubernetes \
  3. --kubeconfig=/etc/kubernetes/controller-manager.conf

102.gif

6.4.5 scheduler 证书生成与配置

  • 新建 scheduler-csr.json 文件(k8s-master1):
  1. sudo tee /etc/kubernetes/pki/scheduler-csr.json <<-'EOF'
  2. {
  3. "CN": "system:kube-scheduler",
  4. "key": {
  5. "algo": "rsa",
  6. "size": 2048
  7. },
  8. "names": [
  9. {
  10. "C": "CN",
  11. "ST": "Beijing",
  12. "L": "Beijing",
  13. "O": "system:kube-scheduler",
  14. "OU": "Kubernetes"
  15. }
  16. ]
  17. }
  18. EOF

103.gif

  • 生成证书(k8s-master1):
  1. cfssl gencert \
  2. -ca=/etc/kubernetes/pki/ca.pem \
  3. -ca-key=/etc/kubernetes/pki/ca-key.pem \
  4. -config=/etc/kubernetes/pki/ca-config.json \
  5. -profile=kubernetes \
  6. /etc/kubernetes/pki/scheduler-csr.json | cfssljson -bare /etc/kubernetes/pki/scheduler

104.gif

  • 生成配置(k8s-master1):
  1. kubectl config set-cluster kubernetes \
  2. --certificate-authority=/etc/kubernetes/pki/ca.pem \
  3. --embed-certs=true \
  4. --server=https://192.168.0.250:6443 \
  5. --kubeconfig=/etc/kubernetes/scheduler.conf

注意,如果不是高可用集群,192.168.0.250:6443 改为 master01 的地址,6443 是 api-server 默认端口。

  1. kubectl config set-credentials system:kube-scheduler \
  2. --client-certificate=/etc/kubernetes/pki/scheduler.pem \
  3. --client-key=/etc/kubernetes/pki/scheduler-key.pem \
  4. --embed-certs=true \
  5. --kubeconfig=/etc/kubernetes/scheduler.conf
  1. kubectl config set-context system:kube-scheduler@kubernetes \
  2. --cluster=kubernetes \
  3. --user=system:kube-scheduler \
  4. --kubeconfig=/etc/kubernetes/scheduler.conf
  1. kubectl config use-context system:kube-scheduler@kubernetes \
  2. --kubeconfig=/etc/kubernetes/scheduler.conf

105.gif

6.4.6 admin 证书生成与配置

  • 新建 admin-csr.json 文件(k8s-master1):
  1. sudo tee /etc/kubernetes/pki/admin-csr.json <<-'EOF'
  2. {
  3. "CN": "admin",
  4. "key": {
  5. "algo": "rsa",
  6. "size": 2048
  7. },
  8. "names": [
  9. {
  10. "C": "CN",
  11. "ST": "Beijing",
  12. "L": "Beijing",
  13. "O": "system:masters",
  14. "OU": "Kubernetes"
  15. }
  16. ]
  17. }
  18. EOF

106.gif

  • 生成证书(k8s-master1):
  1. cfssl gencert \
  2. -ca=/etc/kubernetes/pki/ca.pem \
  3. -ca-key=/etc/kubernetes/pki/ca-key.pem \
  4. -config=/etc/kubernetes/pki/ca-config.json \
  5. -profile=kubernetes \
  6. /etc/kubernetes/pki/admin-csr.json | cfssljson -bare /etc/kubernetes/pki/admin

107.gif

  • 生成配置(k8s-master1):
  1. kubectl config set-cluster kubernetes \
  2. --certificate-authority=/etc/kubernetes/pki/ca.pem \
  3. --embed-certs=true \
  4. --server=https://192.168.0.250:6443 \
  5. --kubeconfig=/etc/kubernetes/admin.conf

注意,如果不是高可用集群,192.168.0.250:6443 改为 master01 的地址,6443 为 apiserver 的默认端口。

  1. kubectl config set-credentials kubernetes-admin \
  2. --client-certificate=/etc/kubernetes/pki/admin.pem \
  3. --client-key=/etc/kubernetes/pki/admin-key.pem \
  4. --embed-certs=true \
  5. --kubeconfig=/etc/kubernetes/admin.conf
  1. kubectl config set-context kubernetes-admin@kubernetes \
  2. --cluster=kubernetes \
  3. --user=kubernetes-admin \
  4. --kubeconfig=/etc/kubernetes/admin.conf
  1. kubectl config use-context kubernetes-admin@kubernetes \
  2. --kubeconfig=/etc/kubernetes/admin.conf

108.gif

注意:kubelet 将使用 bootstrap 引导机制,自动颁发证书,所以我们不需要配置。否则,一万台机器,一万个 kubelet ,就需要配置一万次证书,太麻烦了。

6.4.7 ServiceAccount Key 生成

  • Kubernetes 底层,每创建一个 ServiceAccount ,都会分配一个 Secret,而 Secret 里面有秘钥,秘钥就是由我们接下来的 sa 生成的,所以我们提前创建出 sa 信息:
  • 命令(k8s-master1):
  1. openssl genrsa -out /etc/kubernetes/pki/sa.key 2048
  1. openssl rsa -in /etc/kubernetes/pki/sa.key -pubout -out /etc/kubernetes/pki/sa.pub

109.gif

6.4.8 发送证书到其他节点

  • 命令(k8s-master1):
  1. for NODE in k8s-master2 k8s-master3
  2. do
  3. for FILE in admin.conf controller-manager.conf scheduler.conf
  4. do
  5. scp /etc/kubernetes/${FILE} $NODE:/etc/kubernetes/${FILE}
  6. done
  7. done

110.gif

6.5 高可用配置

  • 高可用配置有很多可选方案:
    • ① nginx。
    • ② haproxy。
    • ③ keepalived。
    • ④ 云厂商提供的负载均衡产品。
  • 如果不是在创建高可用集群,则无需配置 haproxy 和 keepalived 。
  • 云上安装注意实现:
    • 云上安装可以直接使用云上的 lb ,如:阿里云 slb ,腾讯云 elb 等。
    • 公有云要用公有云自带的负载均衡,比如阿里云的 SLB,腾讯云的 ELB,用来替代 haproxy 和 keepalived ,因为公有云大部分都是不支持 keepalived 的。
    • 阿里云的话,kubectl 控制端不能放在 master 节点,推荐使用腾讯云,因为阿里云的 slb 有回环的问题,也就是 slb 代理的服务器不能反向访问 SLB ,但是腾讯云修复了这个问题。

注意:本次使用青云。

  • 创建负载均衡器,指定 IP 地址为我们之前预留的地址 192.168.0.250

111.PNG

112.PNG

113.PNG

  • 进入负载均衡器,创建监听器。

114.PNG

115.PNG

  • 选择 TCP 的 6443 端口。

116.PNG

  • 添加后端服务器地址和端口。

117.PNG

118.PNG

6.6 组件启动

6.6.1 创建目录

  • 创建目录(k8s-master1、k8s-master2、k8s-master3):
  1. mkdir -pv /etc/kubernetes/manifests/ /etc/systemd/system/kubelet.service.d /var/lib/kubelet /var/log/kubernetes

119.gif

6.6.2 将证书复制到其他 Master 节点

  • 命令(k8s-master1):
  1. for NODE in k8s-master2 k8s-master3
  2. do
  3. scp -r /etc/kubernetes/* root@$NODE:/etc/kubernetes/
  4. done

120.gif

6.6.3 配置 api-server 服务

  • k8s-master1 节点创建 kube-apiserver.service ,命令如下:
  1. # --advertise-address: 需要改为本master节点的ip
  2. # --service-cluster-ip-range=10.96.0.0/16: 需要改为自己规划的service网段
  3. # --etcd-servers: 改为自己etcd-server的所有地址
  4. sudo tee /usr/lib/systemd/system/kube-apiserver.service <<-'EOF'
  5. [Unit]
  6. Description=Kubernetes API Server
  7. Documentation=https://github.com/kubernetes/kubernetes
  8. After=network.target
  9. [Service]
  10. ExecStart=/usr/local/bin/kube-apiserver \
  11. --v=2 \
  12. --logtostderr=true \
  13. --allow-privileged=true \
  14. --bind-address=0.0.0.0 \
  15. --secure-port=6443 \
  16. --insecure-port=0 \
  17. --advertise-address=192.168.0.10 \
  18. --service-cluster-ip-range=10.96.0.0/16 \
  19. --service-node-port-range=30000-32767 \
  20. --etcd-servers=https://192.168.0.10:2379,https://192.168.0.11:2379,https://192.168.0.12:2379 \
  21. --etcd-cafile=/etc/kubernetes/pki/etcd/ca.pem \
  22. --etcd-certfile=/etc/kubernetes/pki/etcd/etcd.pem \
  23. --etcd-keyfile=/etc/kubernetes/pki/etcd/etcd-key.pem \
  24. --client-ca-file=/etc/kubernetes/pki/ca.pem \
  25. --tls-cert-file=/etc/kubernetes/pki/apiserver.pem \
  26. --tls-private-key-file=/etc/kubernetes/pki/apiserver-key.pem \
  27. --kubelet-client-certificate=/etc/kubernetes/pki/apiserver.pem \
  28. --kubelet-client-key=/etc/kubernetes/pki/apiserver-key.pem \
  29. --service-account-key-file=/etc/kubernetes/pki/sa.pub \
  30. --service-account-signing-key-file=/etc/kubernetes/pki/sa.key \
  31. --service-account-issuer=https://kubernetes.default.svc.cluster.local \
  32. --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname \
  33. --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,ResourceQuota \
  34. --authorization-mode=Node,RBAC \
  35. --enable-bootstrap-token-auth=true \
  36. --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.pem \
  37. --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.pem \
  38. --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client-key.pem \
  39. --requestheader-allowed-names=aggregator,front-proxy-client \
  40. --requestheader-group-headers=X-Remote-Group \
  41. --requestheader-extra-headers-prefix=X-Remote-Extra- \
  42. --requestheader-username-headers=X-Remote-User
  43. # --token-auth-file=/etc/kubernetes/token.csv
  44. Restart=on-failure
  45. RestartSec=10s
  46. LimitNOFILE=65535
  47. [Install]
  48. WantedBy=multi-user.target
  49. EOF

注意:

  • 如果不是高可用集群,192.168.0.250 改为 master1 的地址。
  • 使用的 k8s service 网段为 10.96.0.0/16,该网段不能和宿主机的网段、Pod 网段的重复。
  • 需要注意,docker 的网桥默认为 172.17.0.1/16。不要使用这个网段。

121.gif

  • k8s-master2 节点创建 kube-apiserver.service ,命令如下:
  1. # --advertise-address: 需要改为本master节点的ip
  2. # --service-cluster-ip-range=10.96.0.0/16: 需要改为自己规划的service网段
  3. # --etcd-servers: 改为自己etcd-server的所有地址
  4. sudo tee /usr/lib/systemd/system/kube-apiserver.service <<-'EOF'
  5. [Unit]
  6. Description=Kubernetes API Server
  7. Documentation=https://github.com/kubernetes/kubernetes
  8. After=network.target
  9. [Service]
  10. ExecStart=/usr/local/bin/kube-apiserver \
  11. --v=2 \
  12. --logtostderr=true \
  13. --allow-privileged=true \
  14. --bind-address=0.0.0.0 \
  15. --secure-port=6443 \
  16. --insecure-port=0 \
  17. --advertise-address=192.168.0.11 \
  18. --service-cluster-ip-range=10.96.0.0/16 \
  19. --service-node-port-range=30000-32767 \
  20. --etcd-servers=https://192.168.0.10:2379,https://192.168.0.11:2379,https://192.168.0.12:2379 \
  21. --etcd-cafile=/etc/kubernetes/pki/etcd/ca.pem \
  22. --etcd-certfile=/etc/kubernetes/pki/etcd/etcd.pem \
  23. --etcd-keyfile=/etc/kubernetes/pki/etcd/etcd-key.pem \
  24. --client-ca-file=/etc/kubernetes/pki/ca.pem \
  25. --tls-cert-file=/etc/kubernetes/pki/apiserver.pem \
  26. --tls-private-key-file=/etc/kubernetes/pki/apiserver-key.pem \
  27. --kubelet-client-certificate=/etc/kubernetes/pki/apiserver.pem \
  28. --kubelet-client-key=/etc/kubernetes/pki/apiserver-key.pem \
  29. --service-account-key-file=/etc/kubernetes/pki/sa.pub \
  30. --service-account-signing-key-file=/etc/kubernetes/pki/sa.key \
  31. --service-account-issuer=https://kubernetes.default.svc.cluster.local \
  32. --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname \
  33. --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,ResourceQuota \
  34. --authorization-mode=Node,RBAC \
  35. --enable-bootstrap-token-auth=true \
  36. --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.pem \
  37. --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.pem \
  38. --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client-key.pem \
  39. --requestheader-allowed-names=aggregator,front-proxy-client \
  40. --requestheader-group-headers=X-Remote-Group \
  41. --requestheader-extra-headers-prefix=X-Remote-Extra- \
  42. --requestheader-username-headers=X-Remote-User
  43. # --token-auth-file=/etc/kubernetes/token.csv
  44. Restart=on-failure
  45. RestartSec=10s
  46. LimitNOFILE=65535
  47. [Install]
  48. WantedBy=multi-user.target
  49. EOF

122.gif

  • k8s-master3 节点创建 kube-apiserver.service ,命令如下:
  1. # --advertise-address: 需要改为本master节点的ip
  2. # --service-cluster-ip-range=10.96.0.0/16: 需要改为自己规划的service网段
  3. # --etcd-servers: 改为自己etcd-server的所有地址
  4. sudo tee /usr/lib/systemd/system/kube-apiserver.service <<-'EOF'
  5. [Unit]
  6. Description=Kubernetes API Server
  7. Documentation=https://github.com/kubernetes/kubernetes
  8. After=network.target
  9. [Service]
  10. ExecStart=/usr/local/bin/kube-apiserver \
  11. --v=2 \
  12. --logtostderr=true \
  13. --allow-privileged=true \
  14. --bind-address=0.0.0.0 \
  15. --secure-port=6443 \
  16. --insecure-port=0 \
  17. --advertise-address=192.168.0.12 \
  18. --service-cluster-ip-range=10.96.0.0/16 \
  19. --service-node-port-range=30000-32767 \
  20. --etcd-servers=https://192.168.0.10:2379,https://192.168.0.11:2379,https://192.168.0.12:2379 \
  21. --etcd-cafile=/etc/kubernetes/pki/etcd/ca.pem \
  22. --etcd-certfile=/etc/kubernetes/pki/etcd/etcd.pem \
  23. --etcd-keyfile=/etc/kubernetes/pki/etcd/etcd-key.pem \
  24. --client-ca-file=/etc/kubernetes/pki/ca.pem \
  25. --tls-cert-file=/etc/kubernetes/pki/apiserver.pem \
  26. --tls-private-key-file=/etc/kubernetes/pki/apiserver-key.pem \
  27. --kubelet-client-certificate=/etc/kubernetes/pki/apiserver.pem \
  28. --kubelet-client-key=/etc/kubernetes/pki/apiserver-key.pem \
  29. --service-account-key-file=/etc/kubernetes/pki/sa.pub \
  30. --service-account-signing-key-file=/etc/kubernetes/pki/sa.key \
  31. --service-account-issuer=https://kubernetes.default.svc.cluster.local \
  32. --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname \
  33. --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,ResourceQuota \
  34. --authorization-mode=Node,RBAC \
  35. --enable-bootstrap-token-auth=true \
  36. --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.pem \
  37. --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.pem \
  38. --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client-key.pem \
  39. --requestheader-allowed-names=aggregator,front-proxy-client \
  40. --requestheader-group-headers=X-Remote-Group \
  41. --requestheader-extra-headers-prefix=X-Remote-Extra- \
  42. --requestheader-username-headers=X-Remote-User
  43. # --token-auth-file=/etc/kubernetes/token.csv
  44. Restart=on-failure
  45. RestartSec=10s
  46. LimitNOFILE=65535
  47. [Install]
  48. WantedBy=multi-user.target
  49. EOF

123.gif

6.6.4 启动 api-server 服务

  • 启动 api-server 服务(k8s-master1、k8s-master2、k8s-master3):
  1. systemctl daemon-reload && systemctl enable --now kube-apiserver

124.gif

  • 查看状态:
  1. systemctl status kube-apiserver

125.gif

  • 此时,负载均衡器的状态将变为活跃状态。

126.PNG

6.6.5 配置 controller-manager 服务

  • k8s-master1 、k8s-master2 、k8s-master3 节点创建 kube-controller-manager.service ,命令如下:
  1. ## --cluster-cidr=196.16.0.0/16 : 为Pod的网段。修改成自己想规划的网段
  2. sudo tee /usr/lib/systemd/system/kube-controller-manager.service <<-'EOF'
  3. [Unit]
  4. Description=Kubernetes Controller Manager
  5. Documentation=https://github.com/kubernetes/kubernetes
  6. After=network.target
  7. [Service]
  8. ExecStart=/usr/local/bin/kube-controller-manager \
  9. --v=2 \
  10. --logtostderr=true \
  11. --address=127.0.0.1 \
  12. --root-ca-file=/etc/kubernetes/pki/ca.pem \
  13. --cluster-signing-cert-file=/etc/kubernetes/pki/ca.pem \
  14. --cluster-signing-key-file=/etc/kubernetes/pki/ca-key.pem \
  15. --service-account-private-key-file=/etc/kubernetes/pki/sa.key \
  16. --kubeconfig=/etc/kubernetes/controller-manager.conf \
  17. --leader-elect=true \
  18. --use-service-account-credentials=true \
  19. --node-monitor-grace-period=40s \
  20. --node-monitor-period=5s \
  21. --pod-eviction-timeout=2m0s \
  22. --controllers=*,bootstrapsigner,tokencleaner \
  23. --allocate-node-cidrs=true \
  24. --cluster-cidr=196.16.0.0/16 \
  25. --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.pem \
  26. --node-cidr-mask-size=24
  27. Restart=always
  28. RestartSec=10s
  29. [Install]
  30. WantedBy=multi-user.target
  31. EOF

注意:

  • k8s Pod 网段为196.16.0.0/16,该网段不能和宿主机的网段、k8s Service 网段的重复,请按需修改;
  • 特别注意:docker的网桥默认为 172.17.0.1/16。不要使用这个网段。

127.gif

6.6.6 启动 controller-manager 服务

  • 启动 controller-manager 服务(k8s-master1、k8s-master2、k8s-master3):
  1. systemctl daemon-reload && systemctl enable --now kube-controller-manager

128.gif

  • 查看状态:
  1. systemctl status kube-controller-manager

129.gif

6.6.7 配置 scheduler

  • k8s-master1 、k8s-master2 、k8s-master3 节点创建 kube-scheduler.service ,命令如下:
  1. sudo tee /usr/lib/systemd/system/kube-scheduler.service <<-'EOF'
  2. [Unit]
  3. Description=Kubernetes Scheduler
  4. Documentation=https://github.com/kubernetes/kubernetes
  5. After=network.target
  6. [Service]
  7. ExecStart=/usr/local/bin/kube-scheduler \
  8. --v=2 \
  9. --logtostderr=true \
  10. --address=127.0.0.1 \
  11. --leader-elect=true \
  12. --kubeconfig=/etc/kubernetes/scheduler.conf
  13. Restart=always
  14. RestartSec=10s
  15. [Install]
  16. WantedBy=multi-user.target
  17. EOF

130.gif

6.6.8 启动 scheduler

  • 启动 scheduler 服务(k8s-master1、k8s-master2、k8s-master3):
  1. systemctl daemon-reload && systemctl enable --now kube-scheduler

131.gif

  • 查看状态:
  1. systemctl status kube-scheduler

132.gif

6.6.9 配置 kubelet

  • 生成 bootstrap-kubelet.conf 文件(k8s-master1):
  1. #设置集群
  2. kubectl config set-cluster kubernetes \
  3. --certificate-authority=/etc/kubernetes/pki/ca.pem \
  4. --embed-certs=true \
  5. --server=https://192.168.0.250:6443 \
  6. --kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf

注意:如果不是高可用集群,192.168.0.250:6443改为 master1 的地址,6443 为apiserver的默认端口。

  1. #设置秘钥
  2. kubectl config set-credentials tls-bootstrap-token-user \
  3. --token=l6fy8c.d683399b7a553977 \
  4. --kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf
  1. #设置上下文
  2. kubectl config set-context tls-bootstrap-token-user@kubernetes \
  3. --cluster=kubernetes \
  4. --user=tls-bootstrap-token-user \
  5. --kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf
  1. #使用设置
  2. kubectl config use-context tls-bootstrap-token-user@kubernetes \
  3. --kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf

133.gif

6.6.10 配置 kubectl

  • kubectl 能不能操作集群是看 /root/.kube 下有没有 config 文件,而 config 就是我们之前生成的 admin.conf,admin.conf 是具有操作权限的(k8s-master1,当然也可以在所有 master 节点执行如下的命令):
  1. # 只在 master1 生成,因为生产集群,我们只能让一台机器具有操作集群的权限,这样好控制
  2. mkdir -pv /root/.kube
  3. cp /etc/kubernetes/admin.conf /root/.kube/config

134.gif

  • 需要将负载均衡器所在的安全组开放 6443 端口,以便 api-server 能访问:

136.PNG

  • 验证 kubectl 是否可用:
  1. kubectl get pod

137.gif

注意:

  • 如果输入 kubectl get nodes 命令返回 No resources found ,说明已经可以连接 apiserver 并获取资源了。

6.6.11 创建并应用权限引导文件

  • 创建权限引导文件(k8s-master1):
  1. sudo tee /etc/kubernetes/bootstrap.secret.yaml <<-'EOF'
  2. apiVersion: v1
  3. kind: Secret
  4. metadata:
  5. name: bootstrap-token-l6fy8c
  6. namespace: kube-system
  7. type: bootstrap.kubernetes.io/token
  8. stringData:
  9. description: "The default bootstrap token generated by 'kubelet '."
  10. token-id: l6fy8c
  11. token-secret: d683399b7a553977
  12. usage-bootstrap-authentication: "true"
  13. usage-bootstrap-signing: "true"
  14. auth-extra-groups: system:bootstrappers:default-node-token,system:bootstrappers:worker,system:bootstrappers:ingress
  15. ---
  16. apiVersion: rbac.authorization.k8s.io/v1
  17. kind: ClusterRoleBinding
  18. metadata:
  19. name: kubelet-bootstrap
  20. roleRef:
  21. apiGroup: rbac.authorization.k8s.io
  22. kind: ClusterRole
  23. name: system:node-bootstrapper
  24. subjects:
  25. - apiGroup: rbac.authorization.k8s.io
  26. kind: Group
  27. name: system:bootstrappers:default-node-token
  28. ---
  29. apiVersion: rbac.authorization.k8s.io/v1
  30. kind: ClusterRoleBinding
  31. metadata:
  32. name: node-autoapprove-bootstrap
  33. roleRef:
  34. apiGroup: rbac.authorization.k8s.io
  35. kind: ClusterRole
  36. name: system:certificates.k8s.io:certificatesigningrequests:nodeclient
  37. subjects:
  38. - apiGroup: rbac.authorization.k8s.io
  39. kind: Group
  40. name: system:bootstrappers:default-node-token
  41. ---
  42. apiVersion: rbac.authorization.k8s.io/v1
  43. kind: ClusterRoleBinding
  44. metadata:
  45. name: node-autoapprove-certificate-rotation
  46. roleRef:
  47. apiGroup: rbac.authorization.k8s.io
  48. kind: ClusterRole
  49. name: system:certificates.k8s.io:certificatesigningrequests:selfnodeclient
  50. subjects:
  51. - apiGroup: rbac.authorization.k8s.io
  52. kind: Group
  53. name: system:nodes
  54. ---
  55. apiVersion: rbac.authorization.k8s.io/v1
  56. kind: ClusterRole
  57. metadata:
  58. annotations:
  59. rbac.authorization.kubernetes.io/autoupdate: "true"
  60. labels:
  61. kubernetes.io/bootstrapping: rbac-defaults
  62. name: system:kube-apiserver-to-kubelet
  63. rules:
  64. - apiGroups:
  65. - ""
  66. resources:
  67. - nodes/proxy
  68. - nodes/stats
  69. - nodes/log
  70. - nodes/spec
  71. - nodes/metrics
  72. verbs:
  73. - "*"
  74. ---
  75. apiVersion: rbac.authorization.k8s.io/v1
  76. kind: ClusterRoleBinding
  77. metadata:
  78. name: system:kube-apiserver
  79. namespace: ""
  80. roleRef:
  81. apiGroup: rbac.authorization.k8s.io
  82. kind: ClusterRole
  83. name: system:kube-apiserver-to-kubelet
  84. subjects:
  85. - apiGroup: rbac.authorization.k8s.io
  86. kind: User
  87. name: kube-apiserver
  88. EOF

138.gif

  • 应用权限引导文件(k8s-master1):
  1. kubectl create -f /etc/kubernetes/bootstrap.secret.yaml

139.gif

6.7 引导 Node 节点启动

6.7.1 创建相关目录

  • 所有节点创建相关目录(k8s-master1、k8s-master2、k8s-master3、k8s-node1、k8s-node2、k8s-node3):
  1. mkdir -pv /var/lib/kubelet /var/log/kubernetes /etc/systemd/system/kubelet.service.d /etc/kubernetes/manifests/

140.gif

6.7.2 发送证书到其他节点

  • k8s-master1 发送证书到其他节点:
  1. for NODE in k8s-master2 k8s-master3 k8s-node3 k8s-node1 k8s-node2; do
  2. scp -r /etc/kubernetes/* root@$NODE:/etc/kubernetes/
  3. done

141.gif

6.7.3 所有节点配置 kubelet

  • 所有节点创建 kubelet.service 文件(k8s-master1、k8s-master2、k8s-master3、k8s-node1、k8s-node2、k8s-node3):
  1. sudo tee /usr/lib/systemd/system/kubelet.service <<-'EOF'
  2. [Unit]
  3. Description=Kubernetes Kubelet
  4. Documentation=https://github.com/kubernetes/kubernetes
  5. After=docker.service
  6. Requires=docker.service
  7. [Service]
  8. ExecStart=/usr/local/bin/kubelet
  9. Restart=always
  10. StartLimitInterval=0
  11. RestartSec=10
  12. [Install]
  13. WantedBy=multi-user.target
  14. EOF

142.gif

  • 所有节点配置 kubelet service 配置文件(k8s-master1、k8s-master2、k8s-master3、k8s-node1、k8s-node2、k8s-node3):
  1. sudo tee /etc/systemd/system/kubelet.service.d/10-kubelet.conf <<-'EOF'
  2. [Service]
  3. Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf"
  4. Environment="KUBELET_SYSTEM_ARGS=--network-plugin=cni --cni-conf-dir=/etc/cni/net.d --cni-bin-dir=/opt/cni/bin"
  5. Environment="KUBELET_CONFIG_ARGS=--config=/etc/kubernetes/kubelet-conf.yml --pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.4.1"
  6. Environment="KUBELET_EXTRA_ARGS=--node-labels=node.kubernetes.io/node='' "
  7. ExecStart=
  8. ExecStart=/usr/local/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_SYSTEM_ARGS $KUBELET_EXTRA_ARGS
  9. EOF

143.gif

  • 所有节点配置 kubelet-conf.yml 文件(k8s-master1、k8s-master2、k8s-master3、k8s-node1、k8s-node2、k8s-node3):
  1. sudo tee /etc/kubernetes/kubelet-conf.yml <<-'EOF'
  2. apiVersion: kubelet.config.k8s.io/v1beta1
  3. kind: KubeletConfiguration
  4. address: 0.0.0.0
  5. port: 10250
  6. readOnlyPort: 10255
  7. authentication:
  8. anonymous:
  9. enabled: false
  10. webhook:
  11. cacheTTL: 2m0s
  12. enabled: true
  13. x509:
  14. clientCAFile: /etc/kubernetes/pki/ca.pem
  15. authorization:
  16. mode: Webhook
  17. webhook:
  18. cacheAuthorizedTTL: 5m0s
  19. cacheUnauthorizedTTL: 30s
  20. cgroupDriver: systemd
  21. cgroupsPerQOS: true
  22. clusterDNS:
  23. - 10.96.0.10 # clusterDNS 为service网络的第10个ip值,改成自己的。如:10.96.0.10
  24. clusterDomain: cluster.local
  25. containerLogMaxFiles: 5
  26. containerLogMaxSize: 10Mi
  27. contentType: application/vnd.kubernetes.protobuf
  28. cpuCFSQuota: true
  29. cpuManagerPolicy: none
  30. cpuManagerReconcilePeriod: 10s
  31. enableControllerAttachDetach: true
  32. enableDebuggingHandlers: true
  33. enforceNodeAllocatable:
  34. - pods
  35. eventBurst: 10
  36. eventRecordQPS: 5
  37. evictionHard:
  38. imagefs.available: 15%
  39. memory.available: 100Mi
  40. nodefs.available: 10%
  41. nodefs.inodesFree: 5%
  42. evictionPressureTransitionPeriod: 5m0s #缩小相应的配置
  43. failSwapOn: true
  44. fileCheckFrequency: 20s
  45. hairpinMode: promiscuous-bridge
  46. healthzBindAddress: 127.0.0.1
  47. healthzPort: 10248
  48. httpCheckFrequency: 20s
  49. imageGCHighThresholdPercent: 85
  50. imageGCLowThresholdPercent: 80
  51. imageMinimumGCAge: 2m0s
  52. iptablesDropBit: 15
  53. iptablesMasqueradeBit: 14
  54. kubeAPIBurst: 10
  55. kubeAPIQPS: 5
  56. makeIPTablesUtilChains: true
  57. maxOpenFiles: 1000000
  58. maxPods: 110
  59. nodeStatusUpdateFrequency: 10s
  60. oomScoreAdj: -999
  61. podPidsLimit: -1
  62. registryBurst: 10
  63. registryPullQPS: 5
  64. resolvConf: /etc/resolv.conf
  65. rotateCertificates: true
  66. runtimeRequestTimeout: 2m0s
  67. serializeImagePulls: true
  68. staticPodPath: /etc/kubernetes/manifests
  69. streamingConnectionIdleTimeout: 4h0m0s
  70. syncFrequency: 1m0s
  71. volumeStatsAggPeriod: 1m0s
  72. EOF

144.gif

  • 所有节点启动 kubelet :
  1. systemctl daemon-reload && systemctl enable --now kubelet

145.gif

  • 查看状态:
  1. systemctl status kubelet

146.gif

如果提示 Unable to update cni config ,说明还需要部署 CNI 网络插件。

6.7.4 kube-proxy 配置

  • 生成 kube-proxy.conf 文件(k8s-master1):
  1. # 创建 kube-proxy 的 sa
  2. kubectl -n kube-system create serviceaccount kube-proxy
  1. # 创建角色绑定
  2. kubectl create clusterrolebinding system:kube-proxy \
  3. --clusterrole system:node-proxier \
  4. --serviceaccount kube-system:kube-proxy
  1. # 导出变量,方便后面使用
  2. SECRET=$(kubectl -n kube-system get sa/kube-proxy --output=jsonpath='{.secrets[0].name}')
  3. JWT_TOKEN=$(kubectl -n kube-system get secret/$SECRET --output=jsonpath='{.data.token}' | base64 -d)
  4. PKI_DIR=/etc/kubernetes/pki
  5. K8S_DIR=/etc/kubernetes
  1. # 生成kube-proxy配置
  2. # --server: 指定自己的apiserver地址或者lb地址
  3. kubectl config set-cluster kubernetes \
  4. --certificate-authority=/etc/kubernetes/pki/ca.pem \
  5. --embed-certs=true \
  6. --server=https://192.168.0.250:6443 \
  7. --kubeconfig=${K8S_DIR}/kube-proxy.conf

注意,如果不是高可用集群,192.168.0.250:6443改为master1的地址,6443 改为 apiserver 的默认端口

  1. # kube-proxy秘钥设置
  2. kubectl config set-credentials kubernetes \
  3. --token=${JWT_TOKEN} \
  4. --kubeconfig=/etc/kubernetes/kube-proxy.conf
  1. kubectl config set-context kubernetes \
  2. --cluster=kubernetes \
  3. --user=kubernetes \
  4. --kubeconfig=/etc/kubernetes/kube-proxy.conf
  1. kubectl config use-context kubernetes \
  2. --kubeconfig=/etc/kubernetes/kube-proxy.conf

147.gif

  • k8s-master1 发送证书到其他节点:
  1. for NODE in k8s-master2 k8s-master3 k8s-node1 k8s-node2 k8s-node3; do
  2. scp /etc/kubernetes/kube-proxy.conf $NODE:/etc/kubernetes/
  3. done

148.gif

  • 所有节点配置 kube-proxy.service 文件(k8s-master1、k8s-master2、k8s-master3、k8s-node1、k8s-node2、k8s-node3):
  1. sudo tee /usr/lib/systemd/system/kube-proxy.service <<-'EOF'
  2. [Unit]
  3. Description=Kubernetes Kube Proxy
  4. Documentation=https://github.com/kubernetes/kubernetes
  5. After=network.target
  6. [Service]
  7. ExecStart=/usr/local/bin/kube-proxy \
  8. --config=/etc/kubernetes/kube-proxy.yaml \
  9. --v=2
  10. Restart=always
  11. RestartSec=10s
  12. [Install]
  13. WantedBy=multi-user.target
  14. EOF

149.gif

  • 所有节点创建 kube-proxy.yaml 文件(k8s-master1、k8s-master2、k8s-master3、k8s-node1、k8s-node2、k8s-node3):
  1. sudo tee /etc/kubernetes/kube-proxy.yaml <<-'EOF'
  2. apiVersion: kubeproxy.config.k8s.io/v1alpha1
  3. bindAddress: 0.0.0.0
  4. clientConnection:
  5. acceptContentTypes: ""
  6. burst: 10
  7. contentType: application/vnd.kubernetes.protobuf
  8. kubeconfig: /etc/kubernetes/kube-proxy.conf #kube-proxy引导文件
  9. qps: 5
  10. clusterCIDR: 196.16.0.0/16 #修改为自己的Pod-CIDR
  11. configSyncPeriod: 15m0s
  12. conntrack:
  13. max: null
  14. maxPerCore: 32768
  15. min: 131072
  16. tcpCloseWaitTimeout: 1h0m0s
  17. tcpEstablishedTimeout: 24h0m0s
  18. enableProfiling: false
  19. healthzBindAddress: 0.0.0.0:10256
  20. hostnameOverride: ""
  21. iptables:
  22. masqueradeAll: false
  23. masqueradeBit: 14
  24. minSyncPeriod: 0s
  25. syncPeriod: 30s
  26. ipvs:
  27. masqueradeAll: true
  28. minSyncPeriod: 5s
  29. scheduler: "rr"
  30. syncPeriod: 30s
  31. kind: KubeProxyConfiguration
  32. metricsBindAddress: 127.0.0.1:10249
  33. mode: "ipvs"
  34. nodePortAddresses: null
  35. oomScoreAdj: -999
  36. portRange: ""
  37. udpIdleTimeout: 250ms
  38. EOF

150.gif

  • 所有节点启动 kube-proxy (k8s-master1、k8s-master2、k8s-master3、k8s-node1、k8s-node2、k8s-node3):
  1. systemctl daemon-reload && systemctl enable --now kube-proxy

151.gif

  • 查看状态:
  1. systemctl status kube-proxy

152.gif

6.8 部署 calico

  • 下载 calico(k8s-master1):
  1. curl https://docs.projectcalico.org/v3.19/manifests/calico-etcd.yaml -o calico.yaml

153.gif

  • 修改 etcd 集群地址(k8s-master1):
  1. sed -i 's#etcd_endpoints: "http://<ETCD_IP>:<ETCD_PORT>"#etcd_endpoints: "https://192.168.0.10:2379,https://192.168.0.11:2379,https://192.168.0.12:2379"#g' calico.yaml

154.gif

  • etcd 的证书内容,需要 base64 编码设置到 yaml 中(k8s-master1):
  1. ETCD_CA=`cat /etc/kubernetes/pki/etcd/ca.pem | base64 -w 0 `
  2. ETCD_CERT=`cat /etc/kubernetes/pki/etcd/etcd.pem | base64 -w 0 `
  3. ETCD_KEY=`cat /etc/kubernetes/pki/etcd/etcd-key.pem | base64 -w 0 `

155.gif

  • 替换 etcd 中的证书 base64 编码后的内容(k8s-master1):
  1. sed -i "s@# etcd-key: null@etcd-key: ${ETCD_KEY}@g; s@# etcd-cert: null@etcd-cert: ${ETCD_CERT}@g; s@# etcd-ca: null@etcd-ca: ${ETCD_CA}@g" calico.yaml

156.gif

  • 打开 etcd_ca 等默认设置(calico启动后自己生成,k8s-master1):
  1. sed -i 's#etcd_ca: ""#etcd_ca: "/calico-secrets/etcd-ca"#g; s#etcd_cert: ""#etcd_cert: "/calico-secrets/etcd-cert"#g; s#etcd_key: "" #etcd_key: "/calico-secrets/etcd-key" #g' calico.yaml

157.gif

  • 修改自己的 Pod 网段(196.16.0.0/16,k8s-master1):
  1. POD_SUBNET="196.16.0.0/16"
  2. sed -i 's@# - name: CALICO_IPV4POOL_CIDR@- name: CALICO_IPV4POOL_CIDR@g; s@# value: "192.168.0.0/16"@ value: '"${POD_SUBNET}"'@g' calico.yaml

158.gif

  • 确认 calico 是否修改好(k8s-master1):
  1. grep "CALICO_IPV4POOL_CIDR" calico.yaml -A 1

159.gif

  • 应用 calico 配置(k8s-master1):
  1. kubectl apply -f calico.yaml

160.gif

  • 镜像下载比较慢,可以提前下载镜像(所有节点):
  1. docker pull calico/cni:v3.22.1
  2. docker pull calico/pod2daemon-flexvol:v3.22.1
  3. docker pull calico/node:v3.22.1
  4. docker pull calico/kube-controllers:v3.22.1

可能还会超时,那么可以使用我给的压缩包中的 calico组件.zip ,将其解压,然后使用 docker load -i xxx.tar 即可。

  • 查看 Calico 是否安装完毕(k8s-master1):
  1. kubectl get pod -A

161.png

6.9 部署 coreDNS

  • 命令(k8s-master1):
  1. git clone https://github.com/coredns/deployment.git
  2. cd deployment/kubernetes
  3. #10.96.0.10 改为 service 网段的 第 10 个ip
  4. ./deploy.sh -s -i 10.96.0.10 | kubectl apply -f -

162.gif

  • 查看是否安装成功(k8s-master1):
  1. kubectl get pod -A

163.png

6.10 给机器打上 role 标签

  • 命令(k8s-master1):
  1. kubectl label node k8s-master1 node-role.kubernetes.io/master=''
  2. kubectl label node k8s-master2 node-role.kubernetes.io/master=''
  3. kubectl label node k8s-master3 node-role.kubernetes.io/master=''
  4. kubectl label node k8s-node1 node-role.kubernetes.io/worker=''
  5. kubectl label node k8s-node2 node-role.kubernetes.io/worker=''
  6. kubectl label node k8s-node3 node-role.kubernetes.io/worker=''
  1. kubectl taint nodes k8s-master1 node-role.kubernetes.io/master=:NoSchedule
  2. kubectl taint nodes k8s-master2 node-role.kubernetes.io/master=:NoSchedule
  1. # 查看所有节点的污点
  2. kubectl describe node | grep -i taints

164.gif

6.11 集群验证

  • 部署以下的内容进行测试:
  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. name: nginx-01
  5. namespace: default
  6. labels:
  7. app: nginx-01
  8. spec:
  9. selector:
  10. matchLabels:
  11. app: nginx-01
  12. replicas: 1
  13. template:
  14. metadata:
  15. labels:
  16. app: nginx-01
  17. spec:
  18. containers:
  19. - name: nginx-01
  20. image: nginx
  21. ---
  22. apiVersion: v1
  23. kind: Service
  24. metadata:
  25. name: nginx-svc
  26. namespace: default
  27. spec:
  28. selector:
  29. app: nginx-01
  30. type: ClusterIP
  31. ports:
  32. - name: nginx-svc
  33. port: 80
  34. targetPort: 80
  35. protocol: TCP
  36. ---
  37. apiVersion: v1
  38. kind: Namespace
  39. metadata:
  40. name: hello
  41. spec: {}
  42. ---
  43. apiVersion: apps/v1
  44. kind: Deployment
  45. metadata:
  46. name: nginx-hello
  47. namespace: hello
  48. labels:
  49. app: nginx-hello
  50. spec:
  51. selector:
  52. matchLabels:
  53. app: nginx-hello
  54. replicas: 1
  55. template:
  56. metadata:
  57. labels:
  58. app: nginx-hello
  59. spec:
  60. containers:
  61. - name: nginx-hello
  62. image: nginx
  63. ---
  64. apiVersion: v1
  65. kind: Service
  66. metadata:
  67. name: nginx-svc-hello
  68. namespace: hello
  69. spec:
  70. selector:
  71. app: nginx-hello
  72. type: ClusterIP
  73. ports:
  74. - name: nginx-svc-hello
  75. port: 80
  76. targetPort: 80
  77. protocol: TCP

7 集群优化

7.1 优化 kubelet

  1. vi /etc/kubernetes/kubelet-conf.yml
  1. # 其余略
  2. # kubeReserved: kubelet预留资源
  3. kubeReserved:
  4. cpu: "500m"
  5. memory: 300m
  6. ephemeral-storage: 3Gi
  7. systemReserved:
  8. cpu: "200m"
  9. memory: 500m
  10. ephemeral-storage: 3Gi
  • 验证集群 kube-proxy 使用 ipvs 模式工作; 10249 是每个节点 kube-proxy 的 metrics 信息端口,可以访问 /proxyMode 或者 /metrics 等。
  1. curl 127.0.0.1:10249/proxyMode