K8S高可用集群部署

K8S高可用集群部署

一、服务器规划

主机名操作系统IPCPU内存
K8S-master01Centos7.9172.31.0.48C16G
K8S-master02Centos7.9172.31.0.58C16G
K8S-master03Centos7.9172.31.0.68C16G
K8S-node01Centos7.9172.31.0.78C16G
K8S-node02Centos7.9172.31.0.88C16G
vip172.31.0.99

二、初始化基础资源

所有机器执行以下操作

  • step 1:各个机器设置自己的主机名

hostnamectl set-hostname xxxx
  • step 2:时间同步

yum -y install ntpdate
ntpdate cn.pool.ntp.org
  • step 3:将 SELinux 设置为 permissive 模式(相当于将其禁用)

sudo setenforce 0.
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
  • step 4:关闭swap

swapoff -a  
sed -ri 's/.*swap.*/#&/' /etc/fstab
  • step 5:允许 iptables 检查桥接流量

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF

cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sudo sysctl --system
  • step 6:设置资源配置文件

echo "* soft nofile 65536" >> /etc/security/limits.conf
echo "* hard nofile 65536" >> /etc/security/limits.conf
echo "* soft nproc 65536"  >> /etc/security/limits.conf
echo "* hard nproc 65536"  >> /etc/security/limits.conf
echo "* soft  memlock  unlimited"  >> /etc/security/limits.conf
echo "* hard memlock  unlimited"  >> /etc/security/limits.conf
  • step 7:编辑hosts文件

cat <<EOF >>/etc/hosts
172.31.0.99 master.k8s.io k8s-vip
172.31.0.4 master01.k8s.io k8s-master01
172.31.0.5 master02.k8s.io k8s-master02
172.31.0.6 master03.k8s.io k8s-master03
172.31.0.7 node01.k8s.io k8s-node01
172.31.0.8 node02.k8s.io k8s-node02
EOF
  • step 8:安装相关包

yum install -y conntrack-tools libseccomp libtool-ltdl

三、部署keepalived(在3台master机器操作)

  • step 1:安装keepalived(在3台master操作)

yum install -y conntrack-tools libseccomp libtool-ltdl keepalived
  • step 2:编写检测脚本一会会在keepalived配置文件中用到(在3台master操作)

cat > /etc/keepalived/check_haproxy.sh <<EOF
#!/bin/bash
if [ $(ps -C haproxy --no-header | wc -l) -eq 0 ]; then    #这行代码检查是否没有正在运行的haproxy进程。ps命令列出所有正在运行的进程,-C haproxy过滤只有haproxy进程,--no-header从输出中移除标题,wc -l计算行数(进程)。如果没有haproxy进程,则执行if块内的代码。
   systemctl start haproxy        #这行代码使用systemd systemctl命令启动haproxy服务
   sleep 3                        #这行代码暂停脚本3秒钟,然后继续执行

   if [ $(ps -C haproxy --no-header | wc -l) -eq 0 ]; then  #这行代码再次检查haproxy进程是否仍未运行。如果没有haproxy进程,则执行嵌套在if块内的代码。
          systemctl stop keepalived
   fi
fi
EOF
chmod +x /etc/keepalived/check_haproxy.sh
  • step 3:配置(另外的两台master配置和上面类似,只需要修改对应的state配置为BACKUP,priority权重值不同即可)

  • k8s-master01配置

cat > /etc/keepalived/keepalived.conf <<EOF 
! Configuration File for keepalived

global_defs {
   router_id k8s
}

vrrp_script check_haproxy {
    #script "killall -0 haproxy"
    script "/etc/keepalived/check_haproxy.sh"   #刚刚配置的检测脚本
    interval 3  #此脚本每3秒执行一次
    weight -2   #权重
    fall 10     #如果脚本连续失败10次(fall),则keepalived将认为服务器已停止
    rise 2      #当脚本在失败后连续成功两次(rise)时,keepalived将再次将服务器视为已启动。
}

vrrp_instance VI_1 {
    state MASTER     #如果是主节点 则为MASTER ,其他则为 BACKUP
    interface ens33  #网卡名称
    virtual_router_id 51
    priority 250  #优先级高于另外两台即可
    nopreempt   #设置非抢占模式
    preempt_delay 10  #抢占延时10分钟
    advert_int 1      #检查间隔默认1s
    authentication {
        auth_type PASS    #  设置验证类型,主要有PASS和AH两种
        auth_pass ceb1b3ec013d66163d6ab11     #  设置验证密码,同一个vrrp_instance下,MASTER和BACKUP的密码必须一致才能正常通信
    }
    virtual_ipaddress {
        172.31.0.99    #VIP地址
    }
    track_script {
        check_haproxy
    }

}
EOF
  • k8s-master02配置

cat > /etc/keepalived/keepalived.conf <<EOF
! Configuration File for keepalived

global_defs {
   router_id k8s
}

vrrp_script check_haproxy {
    #script "killall -0 haproxy"
    script "/etc/keepalived/check_haproxy.sh"   #刚刚配置的检测脚本
    interval 3  #此脚本每3秒执行一次
    weight -2   #权重
    fall 10     #如果脚本连续失败10次(fall),则keepalived将认为服务器已停止
    rise 2      #当脚本在失败后连续成功两次(rise)时,keepalived将再次将服务器视为已启动。
}

vrrp_instance VI_1 {
    state BACKUP     #如果是主节点 则为MASTER ,其他则为 BACKUP
    interface ens33  #网卡名称
    virtual_router_id 51
    priority 200 #优先级
    nopreempt   #设置非抢占模式
    preempt_delay 10  #抢占延时10分钟
    advert_int 1      #检查间隔默认1s
    authentication {
        auth_type PASS
        auth_pass ceb1b3ec013d66163d6ab11
    }
    virtual_ipaddress {
        172.31.0.99    #VIP地址
    }
    track_script {
        check_haproxy
    }

}
EOF
  • k8s-master03配置

cat > /etc/keepalived/keepalived.conf <<EOF
! Configuration File for keepalived

global_defs {
   router_id k8s
}

vrrp_script check_haproxy {
    #script "killall -0 haproxy"
    script "/etc/keepalived/check_haproxy.sh"   #刚刚配置的检测脚本
    interval 3  #此脚本每3秒执行一次
    weight -2   #权重
    fall 10     #如果脚本连续失败10次(fall),则keepalived将认为服务器已停止
    rise 2      #当脚本在失败后连续成功两次(rise)时,keepalived将再次将服务器视为已启动。
}

vrrp_instance VI_1 {
    state BACKUP     #如果是主节点 则为MASTER ,其他则为 BACKUP
    interface ens33  #网卡名称
    virtual_router_id 51
    priority 150 #优先级
    nopreempt   #设置非抢占模式
    preempt_delay 10  #抢占延时10分钟
    advert_int 1      #检查间隔默认1s
    authentication {
        auth_type PASS
        auth_pass ceb1b3ec013d66163d6ab11
    }
    virtual_ipaddress {
        172.31.0.99    #VIP地址
    }
    track_script {
        check_haproxy
    }

}
EOF
  • step 4:启动检查

#开启并设置开机自启
systemctl enable --now keepalived   
#查看启动状态
systemctl status keepalived.service
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:d8:17:39 brd ff:ff:ff:ff:ff:ff
    inet 172.31.0.4/24 brd 172.31.0.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
    inet 172.31.0.99/32 scope global ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fed8:1739/64 scope link 
       valid_lft forever preferred_lft forever

尝试停掉k8s-master01的keepalived服务,查看vip是否能漂移到其他的master,并且重新启动k8s-master01的keepalived服务,查看vip是否能正常漂移回来,证明配置没有问题。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

四、haproxy搭建(三台master上操作)

  • step 1:安装haproxy(三台master执行)

yum install -y haproxy
cat > /etc/haproxy/haproxy.cfg << EOF
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
    # to have these messages end up in /var/log/haproxy.log you will
    # need to:
    # 1) configure syslog to accept network log events.  This is done
    #    by adding the '-r' option to the SYSLOGD_OPTIONS in
    #    /etc/sysconfig/syslog
    # 2) configure local2 events to go to the /var/log/haproxy.log
    #   file. A line like the following can be added to
    #   /etc/sysconfig/syslog
    #
    #    local2.*                       /var/log/haproxy.log
    #
    log         127.0.0.1 local2
    
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon 
       
    # turn on stats unix socket
    stats socket /var/lib/haproxy/stats
#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------  
defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 3000
#---------------------------------------------------------------------
# kubernetes apiserver frontend which proxys to the backends
#--------------------------------------------------------------------- 
frontend kubernetes-apiserver
    mode                 tcp
    bind                 *:16443
    option               tcplog
    default_backend      kubernetes-apiserver    
#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend kubernetes-apiserver
    mode        tcp
    balance     roundrobin
    server      master01.k8s.io   172.31.0.4:6443 check
    server      master02.k8s.io   172.31.0.5:6443 check
    server      master03.k8s.io   172.31.0.6:6443 check
#---------------------------------------------------------------------
# collection haproxy statistics message
#---------------------------------------------------------------------
listen stats
    bind                 *:1080
    stats auth           admin:awesomePassword
    stats refresh        5s
    stats realm          HAProxy\ Statistics
    stats uri            /admin?stats
EOF
#开启并且设置开机自启
systemctl enable haproxy --now
#检查服务端口是否启动
[root@k8s-master01 haproxy]# netstat -anpt |grep haproxy
tcp        0      0 0.0.0.0:1080            0.0.0.0:*               LISTEN      13084/haproxy       
tcp        0      0 0.0.0.0:16443           0.0.0.0:*               LISTEN      13084/haproxy

五、安装docker(所有节点)

  • step 1: 安装必要的一些系统工具

yum install -y yum-utils device-mapper-persistent-data lvm2
  • step 2: 配置yum源

sudo yum install -y yum-utils
sudo yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
  • step 3: 安装docker

yum install -y docker-ce-20.10.7 docker-ce-cli-20.10.7  containerd.io-1.4.6
  • step 4: 启动并设置开机自启

systemctl enable docker --now
  • step 5: 配置加速

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://82m9ar63.mirror.aliyuncs.com"],
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2"
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

六.安装kubeadm,kubelet,和kubectl(所有节点操作)

  • step 1:配置kubernetes源(所有主机操作)

cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
   http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
exclude=kubelet kubeadm kubectl
EOF
  • step 2:安装

sudo yum install -y kubelet-1.20.9 kubeadm-1.20.9 kubectl-1.20.9 --disableexcludes=kubernetes
  • step 3:启动并设置开机自启

sudo systemctl enable --now kubelet
  • step 4:配置kubectl自动补全功能

安装 bash-completion 包

sudo yum -y install bash-completion

下载 kubectl 补全脚本

curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin/kubectl
echo "source <(kubectl completion bash)" >> ~/.bashrc
source ~/.bashrc
  • step 5:安装k8s集群(在具有vip的k8s-master01上操作)

  • 1.创建配置文件:

mkdir /usr/local/kubernetes/manifests -p

cd /usr/local/kubernetes/manifests/

cat > kubeadm-config.yaml <<EOF
apiVersion: kubeadm.k8s.io/v1beta2    # 集群主版本,根据集群版本号决定
bootstrapTokens:
- groups:
  - system:bootstrappers:kubeadm:default-node-token
  token: abcdef.0123456789abcdef
  ttl: 24h0m0s
  usages:
  - signing
  - authentication
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: 172.31.0.4    #本机ip
  bindPort: 6443              #apiserver集群端口号
nodeRegistration:
  criSocket: /var/run/dockershim.sock
  name: k8s-master01           #本机hostname
  taints:
  - effect: NoSchedule
    key: node-role.kubernetes.io/master
apiServer:
  certSANs:
    - k8s-master01
    - k8s-master02
    - k8s-master03
    - master.k8s.io
    - 172.31.0.4
    - 172.31.0.5
    - 172.31.0.6
    - 172.31.0.7
    - 127.0.0.1
  extraArgs:
    authorization-mode: Node,RBAC
  timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta1
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controlPlaneEndpoint: "master.k8s.io:16443"     #虚拟vip地址+haproxy绑定的端口号
controllerManager: {}
dns: 
  type: CoreDNS
etcd:
  local:    
    dataDir: /var/lib/etcd
imageRepository: registry.aliyuncs.com/google_containers
kind: ClusterConfiguration
kubernetesVersion: v1.16.3         #这里注意要和kubeadmin的版本一样
networking: 
  dnsDomain: cluster.local  
  podSubnet: 10.244.0.0/16             #所有网络范围不重叠
  serviceSubnet: 10.1.0.0/16
scheduler: {}
EOF
  • 2、初始化k8s-master01节点

[root@k8s-master01 manifests]# kubeadm init --config kubeadm-config.yaml 
W0510 09:30:06.966439  127276 common.go:77] your configuration file uses a deprecated API spec: "kubeadm.k8s.io/v1beta1". Please use 'kubeadm config migrate --old-config old.yaml --new-config new.yaml', which will write the new, similar spec using a newer API version.
[init] Using Kubernetes version: v1.20.9
[preflight] Running pre-flight checks
        [WARNING SystemVerification]: this Docker version is not on the list of validated versions: 20.10.7. Latest validated version: 19.03
[preflight] Pulling images required for setting up a Kubernetes cluster
[preflight] This might take a minute or two, depending on the speed of your internet connection
[preflight] You can also perform this action in beforehand using 'kubeadm config images pull'
[certs] Using certificateDir folder "/etc/kubernetes/pki"
[certs] Generating "ca" certificate and key
[certs] Generating "apiserver" certificate and key
[certs] apiserver serving cert is signed for DNS names [k8s-master01 k8s-master02 k8s-master03 kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local master.k8s.io] and IPs [10.1.0.1 192.168.65.132 172.31.0.4 172.31.0.5 172.31.0.6 172.31.0.99 127.0.0.1]
[certs] Generating "apiserver-kubelet-client" certificate and key
[certs] Generating "front-proxy-ca" certificate and key
[certs] Generating "front-proxy-client" certificate and key
[certs] Generating "etcd/ca" certificate and key
[certs] Generating "etcd/server" certificate and key
[certs] etcd/server serving cert is signed for DNS names [k8s-master01 localhost] and IPs [192.168.65.132 127.0.0.1 ::1]
[certs] Generating "etcd/peer" certificate and key
[certs] etcd/peer serving cert is signed for DNS names [k8s-master01 localhost] and IPs [192.168.65.132 127.0.0.1 ::1]
[certs] Generating "etcd/healthcheck-client" certificate and key
[certs] Generating "apiserver-etcd-client" certificate and key
[certs] Generating "sa" key and public key
[kubeconfig] Using kubeconfig folder "/etc/kubernetes"
[endpoint] WARNING: port specified in controlPlaneEndpoint overrides bindPort in the controlplane address
[kubeconfig] Writing "admin.conf" kubeconfig file
[endpoint] WARNING: port specified in controlPlaneEndpoint overrides bindPort in the controlplane address
[kubeconfig] Writing "kubelet.conf" kubeconfig file
[endpoint] WARNING: port specified in controlPlaneEndpoint overrides bindPort in the controlplane address
[kubeconfig] Writing "controller-manager.conf" kubeconfig file
[endpoint] WARNING: port specified in controlPlaneEndpoint overrides bindPort in the controlplane address
[kubeconfig] Writing "scheduler.conf" kubeconfig file
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Starting the kubelet
[control-plane] Using manifest folder "/etc/kubernetes/manifests"
[control-plane] Creating static Pod manifest for "kube-apiserver"
[control-plane] Creating static Pod manifest for "kube-controller-manager"
[control-plane] Creating static Pod manifest for "kube-scheduler"
[etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests"
[wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests". This can take up to 4m0s
[apiclient] All control plane components are healthy after 7.641464 seconds
[upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[kubelet] Creating a ConfigMap "kubelet-config-1.20" in namespace kube-system with the configuration for the kubelets in the cluster
[upload-certs] Skipping phase. Please see --upload-certs
[mark-control-plane] Marking the node k8s-master01 as control-plane by adding the labels "node-role.kubernetes.io/master=''" and "node-role.kubernetes.io/control-plane='' (deprecated)"
[mark-control-plane] Marking the node k8s-master01 as control-plane by adding the taints [node-role.kubernetes.io/master:NoSchedule]
[bootstrap-token] Using token: k5j27i.bo0clckst09xkb6t
[bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles
[bootstrap-token] configured RBAC rules to allow Node Bootstrap tokens to get nodes
[bootstrap-token] configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
[bootstrap-token] configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
[bootstrap-token] configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
[bootstrap-token] Creating the "cluster-info" ConfigMap in the "kube-public" namespace
[kubelet-finalize] Updating "/etc/kubernetes/kubelet.conf" to point to a rotatable kubelet client certificate and key
[addons] Applied essential addon: CoreDNS
[endpoint] WARNING: port specified in controlPlaneEndpoint overrides bindPort in the controlplane address
[addons] Applied essential addon: kube-proxy

Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

Alternatively, if you are the root user, you can run:

  export KUBECONFIG=/etc/kubernetes/admin.conf

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

You can now join any number of control-plane nodes by copying certificate authorities
and service account keys on each node and then running the following as root:

  kubeadm join master.k8s.io:16443 --token k5j27i.bo0clckst09xkb6t \
    --discovery-token-ca-cert-hash sha256:0a0e6689586e6c6529484ed947689f5aa292f268e9eae03377ac2bc0bc85a530 \
    --control-plane 

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join master.k8s.io:16443 --token k5j27i.bo0clckst09xkb6t \
    --discovery-token-ca-cert-hash sha256:0a0e6689586e6c6529484ed947689f5aa292f268e9eae03377ac2bc0bc85a530
  • 3.按照提示配置环境变量

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config
  

  创建一个名为 .kube 的目录,该目录位于当前用户的主目录下(即 $HOME 目录)。
  使用 sudo 命令将位于 /etc/kubernetes/admin.conf 路径下的 Kubernetes 集群配置文件复制到 .kube/config 文件中。
  使用 chown 命令将 .kube/config 文件的所有权赋予当前用户,以便该用户可以对其进行读写操作。

  • 4.查看集群状态

[root@k8s-master01 ~]# kubectl get nodes
NAME           STATUS     ROLES                  AGE     VERSION
k8s-master01   NotReady   control-plane,master   8m14s   v1.20.9
[root@k8s-master01 ~]# kubectl get pod -n kube-system
NAME                                   READY   STATUS    RESTARTS   AGE
coredns-7f89b7bc75-mmpj9               0/1     Pending   0          8m3s
coredns-7f89b7bc75-rzt8b               0/1     Pending   0          8m3s
etcd-k8s-master01                      1/1     Running   0          8m17s
kube-apiserver-k8s-master01            1/1     Running   0          8m17s
kube-controller-manager-k8s-master01   1/1     Running   0          8m17s
kube-proxy-4rmbb                       1/1     Running   0          8m3s
kube-scheduler-k8s-master01            1/1     Running   0          8m17s
#这里处于pending状态的原因是因为还没有安装网络组件
  • 5. 安装集群网络

从官方地址获取到flannel的yaml,在k8s-master01上执行
# 创建文件夹
mkdir flannel
cd flannel
# 下载yaml文件
wget -c https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

可能因为网络原因拉不下来所以这里留一份yml文件

---
kind: Namespace
apiVersion: v1
metadata:
  name: kube-flannel
  labels:
    k8s-app: flannel
    pod-security.kubernetes.io/enforce: privileged
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  labels:
    k8s-app: flannel
  name: flannel
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
- apiGroups:
  - ""
  resources:
  - nodes
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - nodes/status
  verbs:
  - patch
- apiGroups:
  - networking.k8s.io
  resources:
  - clustercidrs
  verbs:
  - list
  - watch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  labels:
    k8s-app: flannel
  name: flannel
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: flannel
subjects:
- kind: ServiceAccount
  name: flannel
  namespace: kube-flannel
---
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    k8s-app: flannel
  name: flannel
  namespace: kube-flannel
---
kind: ConfigMap
apiVersion: v1
metadata:
  name: kube-flannel-cfg
  namespace: kube-flannel
  labels:
    tier: node
    k8s-app: flannel
    app: flannel
data:
  cni-conf.json: |
    {
      "name": "cbr0",
      "cniVersion": "0.3.1",
      "plugins": [
        {
          "type": "flannel",
          "delegate": {
            "hairpinMode": true,
            "isDefaultGateway": true
          }
        },
        {
          "type": "portmap",
          "capabilities": {
            "portMappings": true
          }
        }
      ]
    }
  net-conf.json: |
    {
      "Network": "10.244.0.0/16",
      "Backend": {
        "Type": "vxlan"
      }
    }
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: kube-flannel-ds
  namespace: kube-flannel
  labels:
    tier: node
    app: flannel
    k8s-app: flannel
spec:
  selector:
    matchLabels:
      app: flannel
  template:
    metadata:
      labels:
        tier: node
        app: flannel
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: kubernetes.io/os
                operator: In
                values:
                - linux
      hostNetwork: true
      priorityClassName: system-node-critical
      tolerations:
      - operator: Exists
        effect: NoSchedule
      serviceAccountName: flannel
      initContainers:
      - name: install-cni-plugin
        image: docker.io/flannel/flannel-cni-plugin:v1.1.2
       #image: docker.io/rancher/mirrored-flannelcni-flannel-cni-plugin:v1.1.2
        command:
        - cp
        args:
        - -f
        - /flannel
        - /opt/cni/bin/flannel
        volumeMounts:
        - name: cni-plugin
          mountPath: /opt/cni/bin
      - name: install-cni
        image: docker.io/flannel/flannel:v0.21.5
       #image: docker.io/rancher/mirrored-flannelcni-flannel:v0.21.5
        command:
        - cp
        args:
        - -f
        - /etc/kube-flannel/cni-conf.json
        - /etc/cni/net.d/10-flannel.conflist
        volumeMounts:
        - name: cni
          mountPath: /etc/cni/net.d
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      containers:
      - name: kube-flannel
        image: docker.io/flannel/flannel:v0.21.5
       #image: docker.io/rancher/mirrored-flannelcni-flannel:v0.21.5
        command:
        - /opt/bin/flanneld
        args:
        - --ip-masq
        - --kube-subnet-mgr
        resources:
          requests:
            cpu: "100m"
            memory: "50Mi"
        securityContext:
          privileged: false
          capabilities:
            add: ["NET_ADMIN", "NET_RAW"]
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: EVENT_QUEUE_DEPTH
          value: "5000"
        volumeMounts:
        - name: run
          mountPath: /run/flannel
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
        - name: xtables-lock
          mountPath: /run/xtables.lock
      volumes:
      - name: run
        hostPath:
          path: /run/flannel
      - name: cni-plugin
        hostPath:
          path: /opt/cni/bin
      - name: cni
        hostPath:
          path: /etc/cni/net.d
      - name: flannel-cfg
        configMap:
          name: kube-flannel-cfg
      - name: xtables-lock
        hostPath:
          path: /run/xtables.lock
          type: FileOrCreate

安装flannel网络,执行完apply之后需要等待一会,pending状态才会变成running。

kubectl apply -f kube-flannel.yml 

检查,都已经running,且k8s-master01已经ready。

[root@k8s-master01 flannel]# kubectl get nodes
NAME           STATUS   ROLES                  AGE   VERSION
k8s-master01   Ready    control-plane,master   16m   v1.20.9
[root@k8s-master01 flannel]# kubectl get pod -A
NAMESPACE      NAME                                   READY   STATUS    RESTARTS   AGE
kube-flannel   kube-flannel-ds-z5nwb                  1/1     Running   0          2m41s
kube-system    coredns-7f89b7bc75-mmpj9               1/1     Running   0          16m
kube-system    coredns-7f89b7bc75-rzt8b               1/1     Running   0          16m
kube-system    etcd-k8s-master01                      1/1     Running   0          16m
kube-system    kube-apiserver-k8s-master01            1/1     Running   0          16m
kube-system    kube-controller-manager-k8s-master01   1/1     Running   0          16m
kube-system    kube-proxy-4rmbb                       1/1     Running   0          16m
kube-system    kube-scheduler-k8s-master01            1/1     Running   0          16m
  • 6.其他节点加入集群(master,node都需要加入)

  • master加入集群
  • 复制密钥和相关文件(k8s-master01执行)
#建立免登录
#创建 SSH 密钥对
ssh-keygen -t rsa
#进入到.ssh目录
cd /root/.ssh/
ssh-copy-id -i id_rsa.pub 172.31.0.5
ssh-copy-id -i id_rsa.pub 172.31.0.6

复制文件到k8s-master02

ssh root@172.31.0.5 mkdir -p /etc/kubernetes/pki/etcd
scp /etc/kubernetes/admin.conf root@172.31.0.5:/etc/kubernetes
scp /etc/kubernetes/pki/{ca.*,sa.*,front-proxy-ca.*} root@172.31.0.5:/etc/kubernetes/pki
scp /etc/kubernetes/pki/etcd/ca.* root@172.31.0.5:/etc/kubernetes/pki/etcd

复制文件到k8s-master03

ssh root@172.31.0.6 mkdir -p /etc/kubernetes/pki/etcd
scp /etc/kubernetes/admin.conf root@172.31.0.6:/etc/kubernetes
scp /etc/kubernetes/pki/{ca.*,sa.*,front-proxy-ca.*} root@172.31.0.6:/etc/kubernetes/pki
scp /etc/kubernetes/pki/etcd/ca.* root@172.31.0.6:/etc/kubernetes/pki/etcd
  • master加入集群

分别在其他两个master ,k8s-master02,k8s-master03上执行k8s-master01 init后输出的join命令,如果找不到可以在k8s-master01执行会重新生成 kubeadm token create --print-join-command

注意第一次生成的token有效期只有俩小时,如果服务器有多网卡的情况下 加入集群命令需要加一条 不然他可能会使用其他IP加入

在k8s-master02上执行操作,需要带上参数–control-plane表示把master控制节点加入到集群
apiserver-advertise-address 需要指定自己本机IP 这个不加的话如果遇到多网卡的情况可能会随机添加一个网卡的IP

 kubeadm join master.k8s.io:16443 --token k5j27i.bo0clckst09xkb6t \
 --discovery-token-ca-cert-hash sha256:0a0e6689586e6c6529484ed947689f5aa292f268e9eae03377ac2bc0bc85a530 \
 --apiserver-advertise-address=172.31.0.5   \
 --control-plane 
    
 mkdir -p $HOME/.kube
 sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
 sudo chown $(id -u):$(id -g) $HOME/.kube/config

在k8s-master-03上执行join命令

 kubeadm join master.k8s.io:16443 --token k5j27i.bo0clckst09xkb6t \
 --discovery-token-ca-cert-hash sha256:0a0e6689586e6c6529484ed947689f5aa292f268e9eae03377ac2bc0bc85a530 \
  --apiserver-advertise-address=172.31.0.6    \ 
 --control-plane 
    
 mkdir -p $HOME/.kube
 sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
 sudo chown $(id -u):$(id -g) $HOME/.kube/config

检查master是否加入成功

[root@k8s-master01 ~]# kubectl get nodes
NAME           STATUS   ROLES                  AGE     VERSION
k8s-master01   Ready    control-plane,master   60m     v1.20.9
k8s-master02   Ready    control-plane,master   14m     v1.20.9
k8s-master03   Ready    control-plane,master   11m     v1.20.9
k8s-node01     Ready    <none>                 9m42s   v1.20.9
k8s-node02     Ready    <none>                 115s    v1.20.9
[root@k8s-master01 ~]# kubectl get pod -A
NAMESPACE      NAME                                   READY   STATUS    RESTARTS   AGE
kube-flannel   kube-flannel-ds-bf56s                  1/1     Running   0          2m3s
kube-flannel   kube-flannel-ds-jwtfz                  1/1     Running   0          14m
kube-flannel   kube-flannel-ds-vrmwn                  1/1     Running   0          9m50s
kube-flannel   kube-flannel-ds-wm5vn                  1/1     Running   0          11m
kube-flannel   kube-flannel-ds-z5nwb                  1/1     Running   0          46m
kube-system    coredns-7f89b7bc75-mmpj9               1/1     Running   0          60m
kube-system    coredns-7f89b7bc75-rzt8b               1/1     Running   0          60m
kube-system    etcd-k8s-master01                      1/1     Running   0          60m
kube-system    etcd-k8s-master02                      1/1     Running   0          14m
kube-system    etcd-k8s-master03                      1/1     Running   0          11m
kube-system    kube-apiserver-k8s-master01            1/1     Running   0          60m
kube-system    kube-apiserver-k8s-master02            1/1     Running   0          14m
kube-system    kube-apiserver-k8s-master03            1/1     Running   0          11m
kube-system    kube-controller-manager-k8s-master01   1/1     Running   1          60m
kube-system    kube-controller-manager-k8s-master02   1/1     Running   0          14m
kube-system    kube-controller-manager-k8s-master03   1/1     Running   0          11m
kube-system    kube-proxy-4rmbb                       1/1     Running   0          60m
kube-system    kube-proxy-7c9mm                       1/1     Running   0          2m3s
kube-system    kube-proxy-9g2r4                       1/1     Running   0          9m50s
kube-system    kube-proxy-b4l7f                       1/1     Running   0          14m
kube-system    kube-proxy-qdntb                       1/1     Running   0          11m
kube-system    kube-scheduler-k8s-master01            1/1     Running   1          60m
kube-system    kube-scheduler-k8s-master02            1/1     Running   0          14m
kube-system    kube-scheduler-k8s-master03            1/1     Running   0          11m
  • node加入到集群(分别在两个node上执行)

在k8s-node01上执行join命令

kubeadm join master.k8s.io:16443 --token k5j27i.bo0clckst09xkb6t \
--discovery-token-ca-cert-hash sha256:0a0e6689586e6c6529484ed947689f5aa292f268e9eae03377ac2bc0bc85a530

检查node是否加入成功

[root@k8s-master01 ~]# kubectl get nodes
NAME           STATUS   ROLES                  AGE     VERSION
k8s-master01   Ready    control-plane,master   60m     v1.20.9
k8s-master02   Ready    control-plane,master   14m     v1.20.9
k8s-master03   Ready    control-plane,master   11m     v1.20.9
k8s-node01     Ready    <none>                 9m42s   v1.20.9
k8s-node02     Ready    <none>                 115s    v1.20.9
[root@k8s-master01 ~]# kubectl get pod -A
NAMESPACE      NAME                                   READY   STATUS    RESTARTS   AGE
kube-flannel   kube-flannel-ds-bf56s                  1/1     Running   0          2m3s
kube-flannel   kube-flannel-ds-jwtfz                  1/1     Running   0          14m
kube-flannel   kube-flannel-ds-vrmwn                  1/1     Running   0          9m50s
kube-flannel   kube-flannel-ds-wm5vn                  1/1     Running   0          11m
kube-flannel   kube-flannel-ds-z5nwb                  1/1     Running   0          46m
kube-system    coredns-7f89b7bc75-mmpj9               1/1     Running   0          60m
kube-system    coredns-7f89b7bc75-rzt8b               1/1     Running   0          60m
kube-system    etcd-k8s-master01                      1/1     Running   0          60m
kube-system    etcd-k8s-master02                      1/1     Running   0          14m
kube-system    etcd-k8s-master03                      1/1     Running   0          11m
kube-system    kube-apiserver-k8s-master01            1/1     Running   0          60m
kube-system    kube-apiserver-k8s-master02            1/1     Running   0          14m
kube-system    kube-apiserver-k8s-master03            1/1     Running   0          11m
kube-system    kube-controller-manager-k8s-master01   1/1     Running   1          60m
kube-system    kube-controller-manager-k8s-master02   1/1     Running   0          14m
kube-system    kube-controller-manager-k8s-master03   1/1     Running   0          11m
kube-system    kube-proxy-4rmbb                       1/1     Running   0          60m
kube-system    kube-proxy-7c9mm                       1/1     Running   0          2m3s
kube-system    kube-proxy-9g2r4                       1/1     Running   0          9m50s
kube-system    kube-proxy-b4l7f                       1/1     Running   0          14m
kube-system    kube-proxy-qdntb                       1/1     Running   0          11m
kube-system    kube-scheduler-k8s-master01            1/1     Running   1          60m
kube-system    kube-scheduler-k8s-master02            1/1     Running   0          14m
kube-system    kube-scheduler-k8s-master03            1/1     Running   0          11m

七、设置允许POD调度到master上面

默认配置下Kubernetes不会将Pod调度到Master节点。如果希望将k8s-master也当作Node使用,可以执行如下命令:

#查看默认配置的污点
[root@k8s-master01 ~]#  kubectl describe node k8s-master01 |grep Taints
Taints:             node-role.kubernetes.io/master:NoSchedule
[root@k8s-master01 ~]#  kubectl describe node k8s-master02 |grep Taints
Taints:             node-role.kubernetes.io/master:NoSchedule
[root@k8s-master01 ~]#  kubectl describe node k8s-master03 |grep Taints
Taints:             node-role.kubernetes.io/master:NoSchedule
#去除污点
[root@k8s-master01 ~]# kubectl taint node k8s-master02 node-role.kubernetes.io/master-
node/k8s-master02 untainted
[root@k8s-master01 ~]# kubectl taint node k8s-master03 node-role.kubernetes.io/master-
node/k8s-master03 untainted
#再次查询
[root@k8s-master01 ~]#  kubectl describe node k8s-master02 |grep Taints
Taints:             <none>
[root@k8s-master01 ~]#  kubectl describe node k8s-master03 |grep Taints
Taints:             <none>
#这样POD就可以调度到master02和master03上面了
测试kubernetes集群

在Kubernetes集群中创建一个pod,验证是否可以正常调度到master02和master03上:

# 创建nginx deployment
kubectl create deployment nginx --image=nginx --replicas=20
# 暴露端口
kubectl expose deployment nginx --port=80 --target-port=80 --type=NodePort
# 查看状态
kubectl get pod,svc
#
[root@k8s-master01 ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.1.0.1      <none>        443/TCP        5h3m
nginx        NodePort    10.1.89.205   <none>        80:31658/TCP   2m38s
#可以看到已经有pod已经调度到master02和master03上面了
[root@k8s-master01 ~]# kubectl get pod -owide
NAME                     READY   STATUS             RESTARTS   AGE     IP            NODE           NOMINATED NODE   READINESS GATES
nginx-6799fc88d8-22qvj   1/1     Running            0          101s    10.244.1.2    k8s-master02   <none>           <none>
nginx-6799fc88d8-26n7d   1/1     Running            0          101s    10.244.3.17   k8s-node01     <none>           <none>
nginx-6799fc88d8-26ptq   1/1     Running            0          2m3s    10.244.3.13   k8s-node01     <none>           <none>
nginx-6799fc88d8-5dl2z   1/1     Running            0          101s    10.244.2.2    k8s-master03   <none>           <none>
nginx-6799fc88d8-5f99h   1/1     Running            0          3m44s   10.244.3.9    k8s-node01     <none>           <none>
nginx-6799fc88d8-72dst   1/1     Running            0          101s    10.244.4.11   k8s-node02     <none>           <none>
nginx-6799fc88d8-bbn5d   1/1     Running            0          2m3s    10.244.4.9    k8s-node02     <none>           <none>
nginx-6799fc88d8-cnz9z   1/1     Running            0          101s    10.244.3.15   k8s-node01     <none>           <none>
nginx-6799fc88d8-f69w5   1/1     Running            0          2m3s    10.244.4.7    k8s-node02     <none>           <none>
nginx-6799fc88d8-g7b98   1/1     Running            0          43m     10.244.4.3    k8s-node02     <none>           <none>
nginx-6799fc88d8-j66bk   1/1     Running            0          3m44s   10.244.3.11   k8s-node01     <none>           <none>
nginx-6799fc88d8-j9vg2   1/1     Running            0          3m44s   10.244.3.10   k8s-node01     <none>           <none>
nginx-6799fc88d8-kbhc8   1/1     Running            0          101s    10.244.4.13   k8s-node02     <none>           <none>
nginx-6799fc88d8-m52dm   1/1     Running            0          2m3s    10.244.3.12   k8s-node01     <none>           <none>
nginx-6799fc88d8-mk8lw   1/1     Running            0          101s    10.244.3.16   k8s-node01     <none>           <none>
nginx-6799fc88d8-n6tkg   1/1     Running            0          101s    10.244.3.14   k8s-node01     <none>           <none>
nginx-6799fc88d8-rtxrg   1/1     Running            0          2m3s    10.244.4.8    k8s-node02     <none>           <none>
nginx-6799fc88d8-rxkjt   1/1     Running            0          43m     10.244.4.4    k8s-node02     <none>           <none>
nginx-6799fc88d8-t8fdl   1/1     Running            0          101s    10.244.4.12   k8s-node02     <none>           <none>
nginx-6799fc88d8-zwrwp   1/1     Running            0          101s    10.244.4.10   k8s-node02     <none>           <none>

八、集群的扩容,缩容

1.集群扩容

默认情况下加入集群的token是24小时过期,24小时后如果是想要新的node加入到集群,需要重新生成一个token,命令如下

# 显示获取token列表

$ kubeadm token list

# 生成新的token

$ kubeadm token create

除token外,join命令还需要一个sha256的值,通过以下方法计算

openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'

用上面输出的token和sha256的值或者是利用kubeadm token create --print-join-command拼接join命令即可

2.集群的缩容

kubectl cordon <node name> #设置为不可调度

kubectl drain <node name> --delete-local-data --force --ignore-daemonsets 驱逐节点上的pod

kubectl delete node <node name>

3.初始化重新加入

需要把原来的配置清空

kubeadm reset

systemctl stop kubelet

systemctl stop docker

rm -rf /var/lib/cni/

rm -rf /var/lib/kubelet/*

rm -rf /etc/cni/

ifconfig cni0 down

ifconfig flannel.1 down

ifconfig docker0 down

ip link delete cni0

ip link delete flannel.1

systemctl start docker

九、模拟

我们现在有3个master节点,2个node节点,经过上述测试,发现集群可以正常访问nginx服务,因为三台master在正常运行,我们现在模拟挂掉一台master,让另外2台master正常运行,看一下会有什么效果:

#首先查询一下节点运行状态
[root@k8s-master01 ~]# kubectl get nodes
NAME           STATUS   ROLES                  AGE     VERSION
k8s-master01   Ready    control-plane,master   5h10m   v1.20.9
k8s-master02   Ready    control-plane,master   4h25m   v1.20.9
k8s-master03   Ready    control-plane,master   4h22m   v1.20.9
k8s-node01     Ready    <none>                 4h20m   v1.20.9
k8s-node02     Ready    <none>                 4h12m   v1.20.9
#我们现在把master01这台服务器关掉,再看集群状态,关掉一会之后,发现master01节点状态变成了NotReady
[root@k8s-master02 ~]# kubectl get nodes
NAME           STATUS     ROLES                  AGE     VERSION
k8s-master01   NotReady   control-plane,master   5h14m   v1.20.9
k8s-master02   Ready      control-plane,master   4h28m   v1.20.9
k8s-master03   Ready      control-plane,master   4h25m   v1.20.9
k8s-node01     Ready      <none>                 4h23m   v1.20.9
k8s-node02     Ready      <none>                 4h15m   v1.20.9
#可以看到vip地址成功转移到master02节点上
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:e0:53:6e brd ff:ff:ff:ff:ff:ff
    inet 172.31.0.5/24 brd 172.31.0.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
    inet 172.31.0.99/32 scope global ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fee0:536e/64 scope link 
       valid_lft forever preferred_lft forever
#修改一下刚刚创建的deployment的副本数验证一下功能是否正常
kubectl scale --replicas=5 deployment/nginx
[root@k8s-master02 ~]# kubectl get pod 
NAME                     READY   STATUS    RESTARTS   AGE
nginx-6799fc88d8-5dl2z   1/1     Running   0          16m
nginx-6799fc88d8-bbn5d   1/1     Running   0          16m
nginx-6799fc88d8-f69w5   1/1     Running   0          16m
nginx-6799fc88d8-g7b98   1/1     Running   0          58m
nginx-6799fc88d8-rxkjt   1/1     Running   0          58m
[root@k8s-master02 ~]# kubectl scale --replicas=10 deployment/nginx
deployment.apps/nginx scaled
[root@k8s-master02 ~]# kubectl get pod 
NAME                     READY   STATUS              RESTARTS   AGE
nginx-6799fc88d8-5dl2z   1/1     Running             0          17m
nginx-6799fc88d8-b5tmh   0/1     ContainerCreating   0          2s
nginx-6799fc88d8-bbn5d   1/1     Running             0          18m
nginx-6799fc88d8-ck4nn   1/1     Running             0          2s
nginx-6799fc88d8-f69w5   1/1     Running             0          18m
nginx-6799fc88d8-g7b98   1/1     Running             0          59m
nginx-6799fc88d8-l6j59   1/1     Running             0          2s
nginx-6799fc88d8-n6lrr   0/1     ContainerCreating   0          2s
nginx-6799fc88d8-pwwgp   0/1     ContainerCreating   0          2s
nginx-6799fc88d8-rxkjt   1/1     Running             0          59m
#可以看到挂掉一台master还是可以正常跑的

我们再使用其他节点的IP加上端口号访问nginx试一下,发现可以正常访问;如果使用master01节点的IP加端口号就无法访问nginx,是因为master01服务器已经关闭。
在这里插入图片描述到现在为止,我们有2台正在运行的master,现在我们再关闭一台master,把master02也关掉,只留一台master,试一下会怎么样?
关闭前的状态:
在这里插入图片描述
关闭后再次执行kubectl get nodes命令,发现报错了,显示无法连接到服务器。
在这里插入图片描述
虽然这时候在访问nginx还是可以正常访问,但是此时的集群已经坏掉了。
所以,如果有3个master节点,必须要保证2个正常运行;如果有5个master,必须保证3个正常运行。假设有N个master节点,必须保证有(N+1)/2个节点正常运行,才能保证集群正常。
在这里插入图片描述
可以看到master01节点一启动vip地址就回来了
在这里插入图片描述

[root@k8s-master01 ~]# kubectl get nodes
NAME           STATUS     ROLES                  AGE     VERSION
k8s-master01   Ready      control-plane,master   5h26m   v1.20.9
k8s-master02   NotReady   control-plane,master   4h40m   v1.20.9
k8s-master03   Ready      control-plane,master   4h37m   v1.20.9
k8s-node01     Ready      <none>                 4h36m   v1.20.9
k8s-node02     Ready      <none>                 4h28m   v1.20.9

十、离线安装

在安装的时候可能会遇到客户环境没网的情况这时候就需要打包好离线包进行离线安装了
下面是我编写的一个一键执行脚本,主节点执行,其余节点需要删除部分内容之后再执行
脚本里面没写去除污点操作有需要的可以看上面

离线包下载地址:
链接:https://pan.baidu.com/s/1moe7MRKPqAtiIuY5R1uiAA?pwd=08sq
提取码:08sq

#!/bin/bash
echo ---设置hosts文件主机名---
read -p "输入k8s-vip地址:"  k8svip
echo "$k8svip master.k8s.io k8s-vip" >> /etc/hosts
read -p "输入k8s-master01,ip:"  master01
echo "$master01  master01.k8s.io  k8s-master01" >> /etc/hosts
read -p "输入k8s-master02,ip:"  master02
echo "$master02  master02.k8s.io  k8s-master02" >> /etc/hosts
read -p "输入k8s-master03,ip:"  master03
echo "$master03  master03.k8s.io  k8s-master03" >> /etc/hosts
read -p "输入k8s-node01,ip:"  node01
echo "$node01  node01.k8s.io  k8s-node01" >> /etc/hosts
read -p "输入k8s-node02,ip:"  node02
echo "$node02  node02.k8s.io  k8s-node02" >> /etc/hosts
echo ---更改主机名-----
read -p  "输入主机名:" name


if [ ! -n "$name" ];then
echo "请输入节点名称"
exit 1
else
echo $name
fi
hostnamectl set-hostname $name
echo ---关闭防火墙---
systemctl stop firewalld 
systemctl disable firewalld

echo ---关闭selinux----
sed -i 's/enforcing/disabled/' /etc/selinux/config
setenforce 0

echo ---关闭swap---
swapoff -a
sed -i 's/.*swap.*/#&/' /etc/fstab

echo ---将桥接的IPv4流量传递到iptables的链---
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF

sysctl --system

echo --------------同步时间-----------------
#yum -y install ntpdate
#ntpdate cn.pool.ntp.org


echo  --------安装keepalived-----------
cd /root/k8s-master
tar xf pack.tar.gz
cd /root/k8s-master/pack
rpm -ivh  keepalived/*.rpm --nodeps --force



echo ------------------编写检测脚本一会会在keepalived配置文件中用到在3台master操作-----------------


cat > /etc/keepalived/check_haproxy.sh <<EOF
#!/bin/bash
if [ $(ps -C haproxy --no-header | wc -l) -eq 0 ]; then    #这行代码检查是否没有正在运行的haproxy进程。ps命令列出所有正在运行的进程,-C haproxy过滤只有haproxy进程,--no-header从输出中移除标题,wc -l计算行数(进程)。如果没有haproxy进程,则执行if块内的代码。
   systemctl start haproxy        #这行代码使用systemd systemctl命令启动haproxy服务
   sleep 3                        #这行代码暂停脚本3秒钟,然后继续执行

   if [ $(ps -C haproxy --no-header | wc -l) -eq 0 ]; then  #这行代码再次检查haproxy进程是否仍未运行。如果没有haproxy进程,则执行嵌套在if块内的代码。
          systemctl stop keepalived
   fi
fi
EOF
chmod +x /etc/keepalived/check_haproxy.sh



echo -------------------修改配置文件中----------------

read -p "输入网卡名称:"  NIC
read -p "输入keepalived优先级:" priority
read -p "输入选择如果是主节点 则为MASTER ,其他则为 BACKUP:" state

cat > /etc/keepalived/keepalived.conf <<EOF 
! Configuration File for keepalived

global_defs {
   router_id k8s
}

vrrp_script check_haproxy {
    #script "killall -0 haproxy"
    script "/etc/keepalived/check_haproxy.sh"   #刚刚配置的检测脚本
    interval 3  #此脚本每3秒执行一次
    weight -2   #权重
    fall 10     #如果脚本连续失败10次(fall),则keepalived将认为服务器已停止
    rise 2      #当脚本在失败后连续成功两次(rise)时,keepalived将再次将服务器视为已启动。
}

vrrp_instance VI_1 {
    state MASTER     #如果是主节点 则为MASTER ,其他则为 BACKUP
    interface NIC  #网卡名称
    virtual_router_id 51
    priority 250  #优先级高于另外两台即可
    nopreempt   #设置非抢占模式
    preempt_delay 10  #抢占延时10分钟
    advert_int 1      #检查间隔默认1s
    authentication {
        auth_type PASS    #  设置验证类型,主要有PASS和AH两种
        auth_pass ceb1b3ec013d66163d6ab11     #  设置验证密码,同一个vrrp_instance下,MASTER和BACKUP的密码必须一致才能正常通信
    }
    virtual_ipaddress {
        172.31.0.99    #VIP地址
    }
    track_script {
        check_haproxy
    }

}
EOF

sed -i "s/NIC/$NIC/g"  /etc/keepalived/keepalived.conf
sed -i "s/250/$priority/g"  /etc/keepalived/keepalived.conf
sed -i "s/172.31.0.99/$k8svip/g"  /etc/keepalived/keepalived.conf
sed -i "s/MASTER/$state/g"  /etc/keepalived/keepalived.conf


echo ------设置开机并且设置开机自启---------
systemctl start keepalived && systemctl enable keepalived



echo -----------安装haproxy------------------

cd /root/k8s-master/pack
rpm -ivh  haproxy/*.rpm --nodeps --force

cat > /etc/haproxy/haproxy.cfg << EOF
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
    # to have these messages end up in /var/log/haproxy.log you will
    # need to:
    # 1) configure syslog to accept network log events.  This is done
    #    by adding the '-r' option to the SYSLOGD_OPTIONS in
    #    /etc/sysconfig/syslog
    # 2) configure local2 events to go to the /var/log/haproxy.log
    #   file. A line like the following can be added to
    #   /etc/sysconfig/syslog
    #
    #    local2.*                       /var/log/haproxy.log
    #
    log         127.0.0.1 local2
    
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon 
       
    # turn on stats unix socket
    stats socket /var/lib/haproxy/stats
#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------  
defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 3000
#---------------------------------------------------------------------
# kubernetes apiserver frontend which proxys to the backends
#--------------------------------------------------------------------- 
frontend kubernetes-apiserver
    mode                 tcp
    bind                 *:16443
    option               tcplog
    default_backend      kubernetes-apiserver    
#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend kubernetes-apiserver
    mode        tcp
    balance     roundrobin
    server      master01.k8s.io   172.31.0.4:6443 check
    server      master02.k8s.io   172.31.0.5:6443 check
    server      master03.k8s.io   172.31.0.6:6443 check
#---------------------------------------------------------------------
# collection haproxy statistics message
#---------------------------------------------------------------------
listen stats
    bind                 *:1080
    stats auth           admin:awesomePassword
    stats refresh        5s
    stats realm          HAProxy\ Statistics
    stats uri            /admin?stats
EOF

sed -i "s/172.31.0.4/$master01/g" /etc/haproxy/haproxy.cfg
sed -i "s/172.31.0.5/$master02/g" /etc/haproxy/haproxy.cfg
sed -i "s/172.31.0.6/$master03/g" /etc/haproxy/haproxy.cfg

# 启动 haproxy
systemctl start haproxy
# 设置开启自启
systemctl enable haproxy
# 查看启动状态
systemctl status haproxy

netstat -tunlp | grep haproxy

echo -----------------安装docker--------------
cd /root/k8s-master/pack
rpm -ivh  docker/*.rpm --nodeps --force

systemctl enable docker --now


sudo mkdir -p /etc/docker

cat > /etc/docker/daemon.json <<EOF
{
  "exec-opts": ["native.cgroupdriver=cgroupfs"],
  "insecure-registries": ["192.168.31.121:5000"],
  "registry-mirrors": ["http://hub-mirror.c.163.com"]
}
EOF
sed -i "s/192.168.31.121/$node02/g" /etc/docker/daemon.json

sudo systemctl daemon-reload
sudo systemctl restart docker


echo ------------安装k8s----------------
cd /root/k8s-master/pack
rpm -ivh  kubelet/*.rpm --nodeps --force



sudo systemctl enable --now kubelet


#安装 bash-completion 包

cd /root/k8s-master/pack
rpm -ivh  bash-completion/*.rpm --nodeps --force

#下载 kubectl 补全脚本
cd ./bash-completion
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin/kubectl
echo "source <(kubectl completion bash)" >> ~/.bashrc
source ~/.bashrc


#导入镜像
cd /root/k8s-master
unzip images.zip
cd /root/k8s-master/images
for i in `ls`;do docker load -i $i ;done


echo ----------初始化主节点--------------------
mkdir /usr/local/kubernetes/manifests -p

cd /usr/local/kubernetes/manifests/

cat > kubeadm-config.yaml <<EOF
apiVersion: kubeadm.k8s.io/v1beta2    # 集群主版本,根据集群版本号决定
bootstrapTokens:
- groups:
  - system:bootstrappers:kubeadm:default-node-token
  token: abcdef.0123456789abcdef
  ttl: 24h0m0s
  usages:
  - signing
  - authentication
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: 192.168.2.200    #本机ip
  bindPort: 6443              #apiserver集群端口号
nodeRegistration:
  criSocket: /var/run/dockershim.sock
  name: k8s-master01           #本机hostname
  taints:
  - effect: NoSchedule
    key: node-role.kubernetes.io/master
---
apiServer:
  certSANs:
    - k8s-master01
    - k8s-master02
    - k8s-master03
    - master.k8s.io
    - 172.31.0.4
    - 172.31.0.5
    - 172.31.0.6
    - 172.31.0.99
    - 127.0.0.1
  extraArgs:
    authorization-mode: Node,RBAC
  timeoutForControlPlane: 2m0s      # 注册时间2分钟
apiVersion: kubeadm.k8s.io/v1beta2
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes      # 集群名字
controlPlaneEndpoint: "master.k8s.io:16443"              # 虚拟ip + haproxy绑定的端口号
controllerManager: {}
dns:
  type: CoreDNS
etcd:
  local:
    dataDir: /var/lib/etcd
imageRepository: registry.aliyuncs.com/google_containers
kind: ClusterConfiguration
kubernetesVersion: v1.18.0               # 集群版本,需要与kubeadm版本一致
networking:
  dnsDomain: cluster.local
  podSubnet: 10.244.0.0/16                 # pod 内网ip网段
  serviceSubnet: 10.96.0.0/12               # svc 内网ip网段
scheduler: {}
EOF



version=$(kubeadm version -o short)
sed -i "s/172.31.0.4/$master01/g" kubeadm-config.yaml 
sed -i "s/172.31.0.5/$master02/g" kubeadm-config.yaml 
sed -i "s/172.31.0.6/$master03/g" kubeadm-config.yaml 
sed -i "s/172.31.0.99/$k8svip/g" kubeadm-config.yaml
sed -i "s/v1.18.0/$version/g" kubeadm-config.yaml
sed -i "s/192.168.2.200/$master01/g" kubeadm-config.yaml


kubeadm init --config kubeadm-config.yaml

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config


echo ------------安装集群网络---------------
mkdir -p /root/flannel
cd /root/flannel

cat > kube-flannel.yml <<EOF
kind: Namespace
apiVersion: v1
metadata:
  name: kube-flannel
  labels:
    k8s-app: flannel
    pod-security.kubernetes.io/enforce: privileged
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  labels:
    k8s-app: flannel
  name: flannel
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
- apiGroups:
  - ""
  resources:
  - nodes
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - nodes/status
  verbs:
  - patch
- apiGroups:
  - networking.k8s.io
  resources:
  - clustercidrs
  verbs:
  - list
  - watch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  labels:
    k8s-app: flannel
  name: flannel
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: flannel
subjects:
- kind: ServiceAccount
  name: flannel
  namespace: kube-flannel
---
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    k8s-app: flannel
  name: flannel
  namespace: kube-flannel
---
kind: ConfigMap
apiVersion: v1
metadata:
  name: kube-flannel-cfg
  namespace: kube-flannel
  labels:
    tier: node
    k8s-app: flannel
    app: flannel
data:
  cni-conf.json: |
    {
      "name": "cbr0",
      "cniVersion": "0.3.1",
      "plugins": [
        {
          "type": "flannel",
          "delegate": {
            "hairpinMode": true,
            "isDefaultGateway": true
          }
        },
        {
          "type": "portmap",
          "capabilities": {
            "portMappings": true
          }
        }
      ]
    }
  net-conf.json: |
    {
      "Network": "10.244.0.0/16",
      "Backend": {
        "Type": "vxlan"
      }
    }
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: kube-flannel-ds
  namespace: kube-flannel
  labels:
    tier: node
    app: flannel
    k8s-app: flannel
spec:
  selector:
    matchLabels:
      app: flannel
  template:
    metadata:
      labels:
        tier: node
        app: flannel
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: kubernetes.io/os
                operator: In
                values:
                - linux
      hostNetwork: true
      priorityClassName: system-node-critical
      tolerations:
      - operator: Exists
        effect: NoSchedule
      serviceAccountName: flannel
      initContainers:
      - name: install-cni-plugin
        image: docker.io/flannel/flannel-cni-plugin:v1.1.2
       #image: docker.io/rancher/mirrored-flannelcni-flannel-cni-plugin:v1.1.2
        command:
        - cp
        args:
        - -f
        - /flannel
        - /opt/cni/bin/flannel
        volumeMounts:
        - name: cni-plugin
          mountPath: /opt/cni/bin
      - name: install-cni
        image: docker.io/flannel/flannel:v0.21.5
       #image: docker.io/rancher/mirrored-flannelcni-flannel:v0.21.5
        command:
        - cp
        args:
        - -f
        - /etc/kube-flannel/cni-conf.json
        - /etc/cni/net.d/10-flannel.conflist
        volumeMounts:
        - name: cni
          mountPath: /etc/cni/net.d
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      containers:
      - name: kube-flannel
        image: docker.io/flannel/flannel:v0.21.5
       #image: docker.io/rancher/mirrored-flannelcni-flannel:v0.21.5
        command:
        - /opt/bin/flanneld
        args:
        - --ip-masq
        - --kube-subnet-mgr
        resources:
          requests:
            cpu: "100m"
            memory: "50Mi"
        securityContext:
          privileged: false
          capabilities:
            add: ["NET_ADMIN", "NET_RAW"]
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: EVENT_QUEUE_DEPTH
          value: "5000"
        volumeMounts:
        - name: run
          mountPath: /run/flannel
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
        - name: xtables-lock
          mountPath: /run/xtables.lock
      volumes:
      - name: run
        hostPath:
          path: /run/flannel
      - name: cni-plugin
        hostPath:
          path: /opt/cni/bin
      - name: cni
        hostPath:
          path: /etc/cni/net.d
      - name: flannel-cfg
        configMap:
          name: kube-flannel-cfg
      - name: xtables-lock
        hostPath:
          path: /run/xtables.lock
          type: FileOrCreate
EOF

kubectl apply -f kube-flannel.yml



cd /root
#建立免登录
#创建 SSH 密钥对
ssh-keygen -t rsa
#进入到.ssh目录
cd /root/.ssh/
ssh-copy-id -i id_rsa.pub $master02
ssh-copy-id -i id_rsa.pub $master03



#复制文件到k8s-master02

ssh root@$master02 mkdir -p /etc/kubernetes/pki/etcd
scp /etc/kubernetes/admin.conf root@$master02:/etc/kubernetes
scp /etc/kubernetes/pki/{ca.*,sa.*,front-proxy-ca.*} root@$master02:/etc/kubernetes/pki
scp /etc/kubernetes/pki/etcd/ca.* root@$master02:/etc/kubernetes/pki/etcd

#复制文件到k8s-master03

ssh root@$master03 mkdir -p /etc/kubernetes/pki/etcd
scp /etc/kubernetes/admin.conf root@$master03:/etc/kubernetes
scp /etc/kubernetes/pki/{ca.*,sa.*,front-proxy-ca.*} root@$master03:/etc/kubernetes/pki
scp /etc/kubernetes/pki/etcd/ca.* root@$master03:/etc/kubernetes/pki/etcd

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值