一、前置知识点

1.1 生产环境可部署Kubernetes集群的两种方式

目前生产部署Kubernetes集群主要有两种方式:
•kubeadm
Kubeadm是一个K8s部署工具,提供kubeadm init和kubeadm join,用于快速部署Kubernetes集群。
•二进制包
从github下载发行版的二进制包,手动部署每个组件,组成Kubernetes集群。
这里采用kubeadm搭建集群。
kubeadm工具功能:
•kubeadm init:初始化一个Master节点
•kubeadm join:将工作节点加入集群
•kubeadm upgrade:升级K8s版本
•kubeadm token:管理 kubeadm join 使用的令牌
•kubeadm reset:清空 kubeadm init 或者 kubeadm join 对主机所做的任何更改
•kubeadm version:打印 kubeadm 版本
•kubeadm alpha:预览可用的新功能

1.2 准备环境

服务器要求:
•建议最小硬件配置:2核CPU、2G内存、30G硬盘
•服务器最好可以访问外网,会有从网上拉取镜像需求,如果服务器不能上网,需要提前下载对应镜像并导入节点
软件环境:
image.png

软件 版本
操作系统 CentOS7.8_x64 (mini)
Docker 19-ce
Kubernetes 1.20

服务器整体规划:

角色 IP 其他单装组件
k8s-master1 192.168.31.61 docker,etcd,nginx,keepalived
k8s-master2 192.168.31.62 docker,etcd,nginx,keepalived
k8s-node1 192.168.31.63 docker,etcd
负载均衡器对外IP 192.168.31.88 (VIP)

架构图:

1.3 操作系统初始化配置

  1. # 关闭防火墙
  2. systemctl stop firewalld
  3. systemctl disable firewalld
  4. # 关闭selinux
  5. sed -i 's/enforcing/disabled/' /etc/selinux/config # 永久
  6. setenforce 0 # 临时
  7. # 关闭swap
  8. swapoff -a # 临时
  9. sed -ri 's/.*swap.*/#&/' /etc/fstab # 永久
  10. # 根据规划设置主机名
  11. hostnamectl set-hostname <hostname>
  12. # 在master添加hosts
  13. cat >> /etc/hosts << EOF
  14. 192.168.31.61 k8s-master1
  15. 192.168.31.62 k8s-master2
  16. 192.168.31.63 k8s-node1
  17. EOF
  18. # 将桥接的IPv4流量传递到iptables的链
  19. cat > /etc/sysctl.d/k8s.conf << EOF
  20. net.bridge.bridge-nf-call-ip6tables = 1
  21. net.bridge.bridge-nf-call-iptables = 1
  22. EOF
  23. sysctl --system # 生效
  24. # 时间同步
  25. yum install ntpdate -y
  26. ntpdate time.windows.com

二、部署Nginx+Keepalived高可用负载均衡器

Kubernetes作为容器集群系统,通过健康检查+重启策略实现了Pod故障自我修复能力,通过调度算法实现将Pod分布式部署,并保持预期副本数,根据Node失效状态自动在其他Node拉起Pod,实现了应用层的高可用性。
针对Kubernetes集群,高可用性还应包含以下两个层面的考虑:Etcd数据库的高可用性和Kubernetes Master组件的高可用性。 而kubeadm搭建的K8s集群,Etcd只起了一个,存在单点,所以我们这里会独立搭建一个Etcd集群。
Master节点扮演着总控中心的角色,通过不断与工作节点上的Kubelet和kube-proxy进行通信来维护整个集群的健康工作状态。如果Master节点故障,将无法使用kubectl工具或者API做任何集群管理。
Master节点主要有三个服务kube-apiserver、kube-controller-manager和kube-scheduler,其中kube-controller-manager和kube-scheduler组件自身通过选择机制已经实现了高可用,所以Master高可用主要针对kube-apiserver组件,而该组件是以HTTP API提供服务,因此对他高可用与Web服务器类似,增加负载均衡器对其负载均衡即可,并且可水平扩容。
kube-apiserver高可用架构图:
image.png
•Nginx是一个主流Web服务和反向代理服务器,这里用四层实现对apiserver实现负载均衡。
•Keepalived是一个主流高可用软件,基于VIP绑定实现服务器双机热备,在上述拓扑中,Keepalived主要根据Nginx运行状态判断是否需要故障转移(偏移VIP),例如当Nginx主节点挂掉,VIP会自动绑定在Nginx备节点,从而保证VIP一直可用,实现Nginx高可用。
注:为了节省机器,这里与K8s master节点机器复用。也可以独立于k8s集群之外部署,只要nginx与apiserver能通信就行。

2.1 安装软件包(主/备)

  1. yum install epel-release -y
  2. yum install nginx keepalived -y

2.2 Nginx配置文件(主/备一样)

  1. cat > /etc/nginx/nginx.conf << "EOF"
  2. user nginx;
  3. worker_processes auto;
  4. error_log /var/log/nginx/error.log;
  5. pid /run/nginx.pid;
  6. include /usr/share/nginx/modules/*.conf;
  7. events {
  8. worker_connections 1024;
  9. }
  10. # 四层负载均衡,为两台Master apiserver组件提供负载均衡
  11. stream {
  12. log_format main '$remote_addr $upstream_addr - [$time_local] $status $upstream_bytes_sent';
  13. access_log /var/log/nginx/k8s-access.log main;
  14. upstream k8s-apiserver {
  15. server 192.168.31.61:6443; # Master1 APISERVER IP:PORT
  16. server 192.168.31.62:6443; # Master2 APISERVER IP:PORT
  17. }
  18. server {
  19. listen 16443; # 由于nginx与master节点复用,这个监听端口不能是6443,否则会冲突
  20. proxy_pass k8s-apiserver;
  21. }
  22. }
  23. http {
  24. log_format main '$remote_addr - $remote_user [$time_local] "$request" '
  25. '$status $body_bytes_sent "$http_referer" '
  26. '"$http_user_agent" "$http_x_forwarded_for"';
  27. access_log /var/log/nginx/access.log main;
  28. sendfile on;
  29. tcp_nopush on;
  30. tcp_nodelay on;
  31. keepalive_timeout 65;
  32. types_hash_max_size 2048;
  33. include /etc/nginx/mime.types;
  34. default_type application/octet-stream;
  35. server {
  36. listen 80 default_server;
  37. server_name _;
  38. location / {
  39. }
  40. }
  41. }
  42. EOF

2.3 keepalived配置文件(Nginx Master)

  1. cat > /etc/keepalived/keepalived.conf << EOF
  2. global_defs {
  3. notification_email {
  4. acassen@firewall.loc
  5. failover@firewall.loc
  6. sysadmin@firewall.loc
  7. }
  8. notification_email_from Alexandre.Cassen@firewall.loc
  9. smtp_server 127.0.0.1
  10. smtp_connect_timeout 30
  11. router_id NGINX_MASTER
  12. }
  13. vrrp_script check_nginx {
  14. script "/etc/keepalived/check_nginx.sh"
  15. }
  16. vrrp_instance VI_1 {
  17. state MASTER
  18. interface ens33 # 修改为实际网卡名
  19. virtual_router_id 51 # VRRP 路由 ID实例,每个实例是唯一的
  20. priority 100 # 优先级,备服务器设置 90
  21. advert_int 1 # 指定VRRP 心跳包通告间隔时间,默认1秒
  22. authentication {
  23. auth_type PASS
  24. auth_pass 1111
  25. }
  26. # 虚拟IP
  27. virtual_ipaddress {
  28. 192.168.31.88/24
  29. }
  30. track_script {
  31. check_nginx
  32. }
  33. }
  34. EOF

•vrrp_script:指定检查nginx工作状态脚本(根据nginx状态判断是否故障转移)
•virtual_ipaddress:虚拟IP(VIP)
准备上述配置文件中检查nginx运行状态的脚本:

  1. cat > /etc/keepalived/check_nginx.sh << "EOF"
  2. #!/bin/bash
  3. count=$(ss -antp |grep 16443 |egrep -cv "grep|$$")
  4. if [ "$count" -eq 0 ];then
  5. exit 1
  6. else
  7. exit 0
  8. fi
  9. EOF
  10. chmod +x /etc/keepalived/check_nginx.sh

2.4 keepalived配置文件(Nginx Backup)

  1. cat > /etc/keepalived/keepalived.conf << EOF
  2. global_defs {
  3. notification_email {
  4. acassen@firewall.loc
  5. failover@firewall.loc
  6. sysadmin@firewall.loc
  7. }
  8. notification_email_from Alexandre.Cassen@firewall.loc
  9. smtp_server 127.0.0.1
  10. smtp_connect_timeout 30
  11. router_id NGINX_BACKUP
  12. }
  13. vrrp_script check_nginx {
  14. script "/etc/keepalived/check_nginx.sh"
  15. }
  16. vrrp_instance VI_1 {
  17. state BACKUP
  18. interface ens33
  19. virtual_router_id 51 # VRRP 路由 ID实例,每个实例是唯一的
  20. priority 90
  21. advert_int 1
  22. authentication {
  23. auth_type PASS
  24. auth_pass 1111
  25. }
  26. virtual_ipaddress {
  27. 192.168.31.88/24
  28. }
  29. track_script {
  30. check_nginx
  31. }
  32. }
  33. EOF

准备上述配置文件中检查nginx运行状态的脚本:

  1. cat > /etc/keepalived/check_nginx.sh << "EOF"
  2. #!/bin/bash
  3. count=$(ss -antp |grep 16443 |egrep -cv "grep|$$")
  4. if [ "$count" -eq 0 ];then
  5. exit 1
  6. else
  7. exit 0
  8. fi
  9. EOF
  10. chmod +x /etc/keepalived/check_nginx.sh

注:keepalived根据脚本返回状态码(0为工作正常,非0不正常)判断是否故障转移。

2.5 启动并设置开机启动

  1. systemctl daemon-reload
  2. systemctl start nginx
  3. systemctl start keepalived
  4. systemctl enable nginx
  5. systemctl enable keepalived

2.6 查看keepalived工作状态

  1. ip addr
  2. 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
  3. link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  4. inet 127.0.0.1/8 scope host lo
  5. valid_lft forever preferred_lft forever
  6. inet6 ::1/128 scope host
  7. valid_lft forever preferred_lft forever
  8. 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
  9. link/ether 00:0c:29:04:f7:2c brd ff:ff:ff:ff:ff:ff
  10. inet 192.168.31.80/24 brd 192.168.31.255 scope global noprefixroute ens33
  11. valid_lft forever preferred_lft forever
  12. inet 192.168.31.88/24 scope global secondary ens33
  13. valid_lft forever preferred_lft forever
  14. inet6 fe80::20c:29ff:fe04:f72c/64 scope link
  15. valid_lft forever preferred_lft forever

er
可以看到,在ens33网卡绑定了192.168.31.88 虚拟IP,说明工作正常。

2.7 Nginx+Keepalived高可用测试

关闭主节点Nginx,测试VIP是否漂移到备节点服务器。
在Nginx Master执行 pkill nginx在Nginx Backup,ip addr命令查看已成功绑定VIP。

三、部署Etcd集群

如果你在学习中遇到问题或者文档有误可联系阿良~ 微信: xyz12366699
Etcd 是一个分布式键值存储系统,Kubernetes使用Etcd进行数据存储,kubeadm搭建默认情况下只启动一个Etcd Pod,存在单点故障,生产环境强烈不建议,所以我们这里使用3台服务器组建集群,可容忍1台机器故障,当然,你也可以使用5台组建集群,可容忍2台机器故障。

节点名称 IP
etcd-1 192.168.31.61
etcd-2 192.168.31.62
etcd-3 192.168.31.63

注:为了节省机器,这里与K8s节点机器复用。也可以独立于k8s集群之外部署,只要apiserver能连接到就行。

3.1 准备cfssl证书生成工具

cfssl是一个开源的证书管理工具,使用json文件生成证书,相比openssl更方便使用。
找任意一台服务器操作,这里用Master节点。

  1. wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
  2. wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
  3. wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
  4. chmod +x cfssl_linux-amd64 cfssljson_linux-amd64 cfssl-certinfo_linux-amd64
  5. mv cfssl_linux-amd64 /usr/local/bin/cfssl
  6. mv cfssljson_linux-amd64 /usr/local/bin/cfssljson
  7. mv cfssl-certinfo_linux-amd64 /usr/bin/cfssl-certinfo

3.2 生成Etcd证书

1. 自签证书颁发机构(CA)

创建工作目录:

  1. mkdir -p ~/etcd_tls
  2. cd ~/etcd_tls

自签CA:

  1. cat > ca-config.json << EOF
  2. {
  3. "signing": {
  4. "default": {
  5. "expiry": "87600h"
  6. },
  7. "profiles": {
  8. "www": {
  9. "expiry": "87600h",
  10. "usages": [
  11. "signing",
  12. "key encipherment",
  13. "server auth",
  14. "client auth"
  15. ]
  16. }
  17. }
  18. }
  19. }
  20. EOF
  21. cat > ca-csr.json << EOF
  22. {
  23. "CN": "etcd CA",
  24. "key": {
  25. "algo": "rsa",
  26. "size": 2048
  27. },
  28. "names": [
  29. {
  30. "C": "CN",
  31. "L": "Beijing",
  32. "ST": "Beijing"
  33. }
  34. ]
  35. }
  36. EOF

生成证书:

  1. cfssl gencert -initca ca-csr.json | cfssljson -bare ca -

会生成ca.pem和ca-key.pem文件。

2. 使用自签CA签发Etcd HTTPS证书

创建证书申请文件:

  1. cat > server-csr.json << EOF
  2. {
  3. "CN": "etcd",
  4. "hosts": [
  5. "192.168.31.61",
  6. "192.168.31.62",
  7. "192.168.31.63"
  8. ],
  9. "key": {
  10. "algo": "rsa",
  11. "size": 2048
  12. },
  13. "names": [
  14. {
  15. "C": "CN",
  16. "L": "BeiJing",
  17. "ST": "BeiJing"
  18. }
  19. ]
  20. }
  21. EOF

注:上述文件hosts字段中IP为所有etcd节点的集群内部通信IP,一个都不能少!为了方便后期扩容可以多写几个预留的IP。
生成证书:

  1. cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=www server-csr.json | cfssljson -bare server

会生成server.pem和server-key.pem文件。

3.3 从Github下载二进制文件

下载地址:https://github.com/etcd-io/etcd/releases/download/v3.4.9/etcd-v3.4.9-linux-amd64.tar.gz

3.4 部署Etcd集群

以下在节点1上操作,为简化操作,待会将节点1生成的所有文件拷贝到节点2和节点3。

1. 创建工作目录并解压二进制包

  1. mkdir /opt/etcd/{bin,cfg,ssl} -p
  2. tar zxvf etcd-v3.4.9-linux-amd64.tar.gz
  3. mv etcd-v3.4.9-linux-amd64/{etcd,etcdctl} /opt/etcd/bin/

2. 创建etcd配置文件

  1. cat > /opt/etcd/cfg/etcd.conf << EOF
  2. #[Member]
  3. ETCD_NAME="etcd-1"
  4. ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
  5. ETCD_LISTEN_PEER_URLS="https://192.168.31.61:2380"
  6. ETCD_LISTEN_CLIENT_URLS="https://192.168.31.61:2379"
  7. #[Clustering]
  8. ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.31.61:2380"
  9. ETCD_ADVERTISE_CLIENT_URLS="https://192.168.31.61:2379"
  10. ETCD_INITIAL_CLUSTER="etcd-1=https://192.168.31.61:2380,etcd-2=https://192.168.31.62:2380,etcd-3=https://192.168.31.63:2380"
  11. ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
  12. ETCD_INITIAL_CLUSTER_STATE="new"
  13. EOF

•ETCD_NAME:节点名称,集群中唯一
•ETCDDATADIR:数据目录
•ETCDLISTENPEER_URLS:集群通信监听地址
•ETCDLISTENCLIENT_URLS:客户端访问监听地址
•ETCDINITIALADVERTISEPEERURLS:集群通告地址
•ETCDADVERTISECLIENT_URLS:客户端通告地址
•ETCDINITIALCLUSTER:集群节点地址
•ETCDINITIALCLUSTER_TOKEN:集群Token
•ETCDINITIALCLUSTER_STATE:加入集群的当前状态,new是新集群,existing表示加入已有集群

3. systemd管理etcd

  1. cat > /usr/lib/systemd/system/etcd.service << EOF
  2. [Unit]
  3. Description=Etcd Server
  4. After=network.target
  5. After=network-online.target
  6. Wants=network-online.target
  7. [Service]
  8. Type=notify
  9. EnvironmentFile=/opt/etcd/cfg/etcd.conf
  10. ExecStart=/opt/etcd/bin/etcd \
  11. --cert-file=/opt/etcd/ssl/server.pem \
  12. --key-file=/opt/etcd/ssl/server-key.pem \
  13. --peer-cert-file=/opt/etcd/ssl/server.pem \
  14. --peer-key-file=/opt/etcd/ssl/server-key.pem \
  15. --trusted-ca-file=/opt/etcd/ssl/ca.pem \
  16. --peer-trusted-ca-file=/opt/etcd/ssl/ca.pem \
  17. --logger=zap
  18. Restart=on-failure
  19. LimitNOFILE=65536
  20. [Install]
  21. WantedBy=multi-user.target
  22. EOF

4. 拷贝刚才生成的证书

把刚才生成的证书拷贝到配置文件中的路径:

  1. cp ~/etcd_tls/ca*pem ~/etcd_tls/server*pem /opt/etcd/ssl/

5. 启动并设置开机启动

  1. systemctl daemon-reload
  2. systemctl start etcd
  3. systemctl enable etcd

6. 将上面节点1所有生成的文件拷贝到节点2和节点3

  1. scp -r /opt/etcd/ root@192.168.31.62:/opt/
  2. scp /usr/lib/systemd/system/etcd.service root@192.168.31.62:/usr/lib/systemd/system/
  3. scp -r /opt/etcd/ root@192.168.31.63:/opt/
  4. scp /usr/lib/systemd/system/etcd.service root@192.168.31.63:/usr/lib/systemd/system/

然后在节点2和节点3分别修改etcd.conf配置文件中的节点名称和当前服务器IP:

  1. vi /opt/etcd/cfg/etcd.conf
  2. #[Member]
  3. ETCD_NAME="etcd-1" # 修改此处,节点2改为etcd-2,节点3改为etcd-3
  4. ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
  5. ETCD_LISTEN_PEER_URLS="https://192.168.31.71:2380" # 修改此处为当前服务器IP
  6. ETCD_LISTEN_CLIENT_URLS="https://192.168.31.71:2379" # 修改此处为当前服务器IP
  7. #[Clustering]
  8. ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.31.71:2380" # 修改此处为当前服务器IP
  9. ETCD_ADVERTISE_CLIENT_URLS="https://192.168.31.71:2379" # 修改此处为当前服务器IP
  10. ETCD_INITIAL_CLUSTER="etcd-1=https://192.168.31.71:2380,etcd-2=https://192.168.31.72:2380,etcd-3=https://192.168.31.73:2380"
  11. ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
  12. ETCD_INITIAL_CLUSTER_STATE="new"

最后启动etcd并设置开机启动,同上。

7. 查看集群状态

  1. ETCDCTL_API=3 /opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://192.168.31.61:2379,https://192.168.31.62:2379,https://192.168.31.63:2379" endpoint health --write-out=table
  2. +----------------------------+--------+-------------+-------+
  3. | ENDPOINT | HEALTH | TOOK | ERROR |
  4. +----------------------------+--------+-------------+-------+
  5. | https://192.168.31.61:2379 | true | 10.301506ms | |
  6. | https://192.168.31.63:2379 | true | 12.87467ms | |
  7. | https://192.168.31.62:2379 | true | 13.225954ms | |
  8. +----------------------------+--------+-------------+-------+

如果输出上面信息,就说明集群部署成功。
如果有问题第一步先看日志:/var/log/message 或 journalctl -u etcd

四、安装Docker/kubeadm/kubelet【所有节点】

这里使用Docker作为容器引擎,也可以换成别的,例如containerd

4.1 安装Docker

  1. wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
  2. yum -y install docker-ce
  3. systemctl enable docker && systemctl start docker

配置镜像下载加速器:

  1. cat > /etc/docker/daemon.json << EOF
  2. {
  3. "registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"]
  4. }
  5. EOF
  6. systemctl restart docker
  7. docker info

4.2 添加阿里云YUM软件源

  1. cat > /etc/yum.repos.d/kubernetes.repo << EOF
  2. [kubernetes]
  3. name=Kubernetes
  4. baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
  5. enabled=1
  6. gpgcheck=0
  7. repo_gpgcheck=0
  8. gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
  9. EOF

4.3 安装kubeadm,kubelet和kubectl

由于版本更新频繁,这里指定版本号部署:

  1. yum install -y kubelet-1.20.0 kubeadm-1.20.0 kubectl-1.20.0
  2. systemctl enable kubelet

五、部署Kubernetes Master

如果你在学习中遇到问题或者文档有误可联系阿良~ 微信: xyz12366699

5.1 初始化Master1

生成初始化配置文件:

  1. cat > kubeadm-config.yaml << EOF
  2. apiVersion: kubeadm.k8s.io/v1beta2
  3. bootstrapTokens:
  4. - groups:
  5. - system:bootstrappers:kubeadm:default-node-token
  6. token: 9037x2.tcaqnpaqkra9vsbw
  7. ttl: 24h0m0s
  8. usages:
  9. - signing
  10. - authentication
  11. kind: InitConfiguration
  12. localAPIEndpoint:
  13. advertiseAddress: 192.168.31.61
  14. bindPort: 6443
  15. nodeRegistration:
  16. criSocket: /var/run/dockershim.sock
  17. name: k8s-master1
  18. taints:
  19. - effect: NoSchedule
  20. key: node-role.kubernetes.io/master
  21. ---
  22. apiServer:
  23. certSANs: # 包含所有Master/LB/VIP IP,一个都不能少!为了方便后期扩容可以多写几个预留的IP。
  24. - k8s-master1
  25. - k8s-master2
  26. - 192.168.31.61
  27. - 192.168.31.62
  28. - 192.168.31.63
  29. - 127.0.0.1
  30. extraArgs:
  31. authorization-mode: Node,RBAC
  32. timeoutForControlPlane: 4m0s
  33. apiVersion: kubeadm.k8s.io/v1beta2
  34. certificatesDir: /etc/kubernetes/pki
  35. clusterName: kubernetes
  36. controlPlaneEndpoint: 192.168.31.88:16443 # 负载均衡虚拟IP(VIP)和端口
  37. controllerManager: {}
  38. dns:
  39. type: CoreDNS
  40. etcd:
  41. external: # 使用外部etcd
  42. endpoints:
  43. - https://192.168.31.61:2379 # etcd集群3个节点
  44. - https://192.168.31.62:2379
  45. - https://192.168.31.63:2379
  46. caFile: /opt/etcd/ssl/ca.pem # 连接etcd所需证书
  47. certFile: /opt/etcd/ssl/server.pem
  48. keyFile: /opt/etcd/ssl/server-key.pem
  49. imageRepository: registry.aliyuncs.com/google_containers # 由于默认拉取镜像地址k8s.gcr.io国内无法访问,这里指定阿里云镜像仓库地址
  50. kind: ClusterConfiguration
  51. kubernetesVersion: v1.20.0 # K8s版本,与上面安装的一致
  52. networking:
  53. dnsDomain: cluster.local
  54. podSubnet: 10.244.0.0/16 # Pod网络,与下面部署的CNI网络组件yaml中保持一致
  55. serviceSubnet: 10.96.0.0/12 # 集群内部虚拟网络,Pod统一访问入口
  56. scheduler: {}
  57. EOF

或者使用配置文件引导:

  1. kubeadm init --config kubeadm-config.yaml
  2. ...
  3. Your Kubernetes control-plane has initialized successfully!
  4. To start using your cluster, you need to run the following as a regular user:
  5. mkdir -p $HOME/.kube
  6. sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  7. sudo chown $(id -u):$(id -g) $HOME/.kube/config
  8. Alternatively, if you are the root user, you can run:
  9. export KUBECONFIG=/etc/kubernetes/admin.conf
  10. You should now deploy a pod network to the cluster.
  11. Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  12. https://kubernetes.io/docs/concepts/cluster-administration/addons/
  13. You can now join any number of control-plane nodes by copying certificate authorities
  14. and service account keys on each node and then running the following as root:
  15. kubeadm join 192.168.31.88:16443 --token 9037x2.tcaqnpaqkra9vsbw \
  16. --discovery-token-ca-cert-hash sha256:b1e726042cdd5df3ce62e60a2f86168cd2e64bff856e061e465df10cd36295b8 \
  17. --control-plane
  18. Then you can join any number of worker nodes by running the following on each as root:
  19. kubeadm join 192.168.31.88:16443 --token 9037x2.tcaqnpaqkra9vsbw \
  20. --discovery-token-ca-cert-hash sha256:b1e726042cdd5df3ce62e60a2f86168cd2e64bff856e061e465df10cd36295b8

初始化完成后,会有两个join的命令,带有 —control-plane 是用于加入组建多master集群的,不带的是加入节点的。
拷贝kubectl使用的连接k8s认证文件到默认路径:

  1. mkdir -p $HOME/.kube
  2. sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  3. sudo chown $(id -u):$(id -g) $HOME/.kube/config
  4. kubectl get node
  5. NAME STATUS ROLES AGE VERSION
  6. k8s-master1 NotReady control-plane,master 6m42s v1.20.0

5.2 初始化Master2

将Master1节点生成的证书拷贝到Master2:

  1. scp -r /etc/kubernetes/pki/ 192.168.31.62:/etc/kubernetes/

复制加入master join命令在master2执行:

  1. kubeadm join 192.168.31.88:16443 --token 9037x2.tcaqnpaqkra9vsbw \
  2. --discovery-token-ca-cert-hash sha256:b1e726042cdd5df3ce62e60a2f86168cd2e64bff856e061e465df10cd36295b8 \
  3. --control-plane

拷贝kubectl使用的连接k8s认证文件到默认路径:

  1. mkdir -p $HOME/.kube
  2. sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  3. sudo chown $(id -u):$(id -g) $HOME/.kube/config
  4. kubectl get node
  5. NAME STATUS ROLES AGE VERSION
  6. k8s-master1 NotReady control-plane,master 28m v1.20.0
  7. k8s-master2 NotReady control-plane,master 2m12s v1.20.0

注:由于网络插件还没有部署,还没有准备就绪 NotReady

5.3 访问负载均衡器测试

找K8s集群中任意一个节点,使用curl查看K8s版本测试,使用VIP访问:

  1. curl -k https://192.168.31.88:16443/version
  2. {
  3. "major": "1",
  4. "minor": "20",
  5. "gitVersion": "v1.20.0",
  6. "gitCommit": "e87da0bd6e03ec3fea7933c4b5263d151aafd07c",
  7. "gitTreeState": "clean",
  8. "buildDate": "2021-02-18T16:03:00Z",
  9. "goVersion": "go1.15.8",
  10. "compiler": "gc",
  11. "platform": "linux/amd64"
  12. }

可以正确获取到K8s版本信息,说明负载均衡器搭建正常。该请求数据流程:curl -> vip(nginx) -> apiserver
通过查看Nginx日志也可以看到转发apiserver IP:

  1. tail /var/log/nginx/k8s-access.log -f
  2. 192.168.31.71 192.168.31.71:6443 - [02/Apr/2021:19:17:57 +0800] 200 423
  3. 192.168.31.71 192.168.31.72:6443 - [02/Apr/2021:19:18:50 +0800] 200 423

六、加入Kubernetes Node

在192.168.31.63(Node)执行。
向集群添加新节点,执行在kubeadm init输出的kubeadm join命令:

  1. kubeadm join 192.168.31.88:16443 --token 9037x2.tcaqnpaqkra9vsbw \
  2. --discovery-token-ca-cert-hash sha256:e6a724bb7ef8bb363762fbaa088f6eb5975e0c654db038560199a7063735a697

后续其他节点也是这样加入。
注:默认token有效期为24小时,当过期之后,该token就不可用了。这时就需要重新创建token,可以直接使用命令快捷生成:kubeadm token create —print-join-command

七、部署网络组件

Calico是一个纯三层的数据中心网络方案,是目前Kubernetes主流的网络方案。
部署Calico:

  1. kubectl apply -f calico.yaml
  2. kubectl get pods -n kube-system

等Calico Pod都Running,节点也会准备就绪:

  1. kubectl get node
  2. NAME STATUS ROLES AGE VERSION
  3. k8s-master1 Ready control-plane,master 50m v1.20.0
  4. k8s-master2 Ready control-plane,master 24m v1.20.0
  5. k8s-node1 Ready <none> 20m v1.20.0

八、部署 Dashboard

Dashboard是官方提供的一个UI,可用于基本管理K8s资源。

  1. kubectl apply -f kubernetes-dashboard.yaml
  2. # 查看部署
  3. kubectl get pods -n kubernetes-dashboard

访问地址:https://NodeIP:30001
创建service account并绑定默认cluster-admin管理员集群角色:

  1. kubectl create serviceaccount dashboard-admin -n kube-system
  2. kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin
  3. kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')

使用输出的token登录Dashboard。
image.png
image.png