通过kubeadm安装K8s集群

kubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具。这个工具能通过两条指令快速完成一个kubernetes集群的部署。

本例子中使用centos7系统安装k8s集群

一、系统初始化设置:

参考k8s二进制部署章节:系统初始化

二、docker安装:

参考k8s二进制部署:docker安装

三、机器IP信息:

主机名 IP 节点类型 最低配置
k8s-master1 192.168.15.215 master1节点 1G2CPU
k8s-master2 192.168.15.216 master2节点 1G2CPU
k8s-master3 192.168.15.217 master3节点 1G2CPU
k8s-worker1 192.168.15.218 worker1节点 1G2CPU
k8s-worker2 192.168.15.219 worker2节点 1G2CPU
k8s-worker3 192.168.15.221 worker3节点 1G2CPU
VIP 192.168.15.253 部署在master节点  
#注意:master节点至少要2个cpu,否则报错
error execution phase preflight: [preflight] Some fatal errors occurred:
[ERROR NumCPU]: the number of available CPUs 1 is less than the required 2

四、安装keepalived和nginx:

keepalived直接yum即可,keepalived配置文件可参考二进制安装一篇,nginx需要编译安装,因为需要stream模块,Nginx编译安装参考:Nginx编译安装

nginx配置文件内容如下:

events {
    worker_connections  1024;
}

stream {
    log_format  main  '$remote_addr $upstream_addr - [$time_local] $status $upstream_bytes_sent';

    access_log  /var/log/nginx/k8s-access.log  main;

    upstream k8s-apiserver {
       server 192.168.15.215:6443;   # Master1 APISERVER IP:PORT
       server 192.168.15.216:6443;   # Master2 APISERVER IP:PORT
       server 192.168.15.217:6443;    # Master3 APISEVER  IP:PORT
    }

    server {
       listen 16443;  # 由于nginx与master节点复用,这个监听端口不能是6443,否则会冲突
       proxy_pass k8s-apiserver;
    }
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    
    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';
    
    #access_log  logs/access.log  main;
    
    sendfile        on;
    #tcp_nopush     on;
    
    #keepalive_timeout  0;
    keepalive_timeout  65;
    
    #gzip  on;
    
    server {
        listen       80;
        server_name  localhost;
        
        #charset koi8-r;
        
        #access_log  logs/host.access.log  main;
        
        location / {
            root   html;
            index  index.html index.htm;
        }
        
        #error_page  404              /404.html;
        
        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    
    }

}

keepalived中配置nginx健康状态检测脚本,如下:

! Configuration File for keepalived

global_defs {
   notification_email {
     acassen@firewall.loc
     failover@firewall.loc
     sysadmin@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 192.168.200.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
   vrrp_skip_check_adv_addr
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}
vrrp_script check_nginx {
     script "/etc/keepalived/check_nginx.sh"
     interval 2
     weight -20                         #脚本返回状态码为1,那么权重下降20,实现VIP飘逸
   }
vrrp_instance VI_1 {
    state MASTER
    interface ens33
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.15.253/24
    }
    track_script {
      check_nginx
    }
}

check_nginx脚本内容如下:

#!/bin/bash
count=$(ss -antp |grep 16443 |egrep -cv "grep|$$")

if [ "$count" -eq 0 ];then
    exit 1
else
    exit 0
fi

注意:如果是单master,那么就不需要安装 keepalived和nginx

五、安装etcd:

本教程中etcd采用单独安装的方式,安装方法参考二进制部署章节https://www.ywdevops.cn/index.php/2021/06/29/k8s-2/

六、安装k8s组件:

1、下载k8s组件:

我们需要安装kubeadm, kubelet, kubectl,版本需要一致。在可以连外网的机器上下载组件。

添加kubernetes yum源:

cat > /etc/yum.repos.d/kubernetes.repo <<EOF
[kubernetes]
name=Kubernetes Repo
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
enabled=1
EOF

查看kubeadm版本

yum list kubeadm --showduplicates

我们下载1.20.8版本(也可根据需要下载任何版本)

yum install --downloadonly --downloaddir ~/k8s/kubernetes kubeadm-1.20.8-0

在根据上述方式查找kubelet、kubectl版本,以及依赖包,并下载

yum install --downloadonly --downloaddir ~/k8s/kubernetes kubelet-1.20.8-0
yum install --downloadonly --downloaddir ~/k8s/kubernetes kubectl-1.20.8-0
yum install --downloadonly --downloaddir ~/k8s/kubernetes kubernetes-cni-0.8.7-0
yum install --downloadonly --downloaddir ~/k8s/kubernetes cri-tools-1.13.0-0

2、安装k8s组件:

将上图中的rpm包拷贝到每一个节点,执行如下命令安装

yum install ~/k8s/kubernetes/*.rpm

执行完成后, kubeadm, kubectl, kubelet就已经安装好了

3、 设置kubelet的开机启动。我们并不需要启动kubelet,就算启动,也是不能成功的。执行kubeadm命令,会生成一些配置文件 ,这时才会让kubelet启动成功的。

systemctl enable kubelet

4、拉取镜像:

执行kubeadm时,需要用到一些镜像,我们需要提前准备

查看需要依赖哪些镜像:

由于国内访问不了k8s.gcr.io地址,因此需要通过国内镜像地址,或者直接通过docker hub地址拉取镜像也可以,本例子已经从docker hub上拉取了镜像,并tag成k8s.gcr.io的地址类型,如图:

七、部署k8s集群:

1、 获取默认配置文件 :

kubeadm config print init-defaults > kubeadm-config.yaml

kubeadm-config.yaml文件的内容如下:

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.15.215
  bindPort: 6443
nodeRegistration:
  criSocket: /var/run/dockershim.sock
  name: k8s-master1
  taints:
  - effect: NoSchedule
    key: node-role.kubernetes.io/master
---
apiServer:
  certSANs:
  - k8s-master1
  - k8s-master2
  - k8s-master3
  - 192.168.15.215
  - 192.168.15.216
  - 192.168.15.217
  - 192.168.15.253
  - 127.0.0.1
  extraArgs:
    authorization-mode: Node,RBAC
  timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta2
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controlPlaneEndpoint: "192.168.15.253:16443"     #vip
controllerManager: {}
dns:
  type: CoreDNS
etcd:
  external:
   endpoints:
   - https://192.168.15.215:2379   
   - https://192.168.15.216:2379   
   - https://192.168.15.217:2379
   caFile: /opt/etcd/ssl/etcd-ca.pem
   certFile: /opt/etcd/ssl/server.pem
   keyFile: /opt/etcd/ssl/server-key.pem 
imageRepository: registry.aliyuncs.com/google_containers      #阿里云仓库
kind: ClusterConfiguration
kubernetesVersion: v1.20.8
networking:
  dnsDomain: cluster.local
  podSubnet: 10.244.0.0/16                      #pod网段
  serviceSubnet: 10.96.0.0/12                   #server网段
scheduler: {}
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs                                      #开启ipvs模式
---
#注意:在初始化集群之前,需要确保当前机器可以登录镜像仓库,否则拉取镜像失败

也可以使用命令将旧的kubeadm-config.yaml转换为新的文件,执行命令如下:

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

2、将从外网下载镜像导入到机器中,执行命令如下:

dokcer load -i  镜像名

#注意:如果上面初始化文件中配置了镜像仓库地址,就不用再次load了

3、 初始化集群:

kubeadm init --config kubeadm-config.yaml

#如果集群初始化失败需要重置集群,可执行下面命令
kubeadm reset -f
iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X

如果初始化成功,可以看到内容如下:

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 192.168.15.253:16443 --token abcdef.0123456789abcdef \
    --discovery-token-ca-cert-hash sha256:9363682fcdbfedd6e059d7428d859d5b0ae5388641dcd098b6876d89461b0625 \
    --control-plane 

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

kubeadm join 192.168.15.253:16443 --token abcdef.0123456789abcdef \
    --discovery-token-ca-cert-hash sha256:9363682fcdbfedd6e059d7428d859d5b0ae5388641dcd098b6876d89461b0625 

注意:master节点加入命令和Node节点加入命令的唯一区别就是master节点加入命令多了一个参数 --control-plane,其余都是一摸一样的

注意:如果初始化卡在这个位置:[kubelet-check] Initial timeout of 40s passed., 则说明是初始化配置文件中的controlPlaneEndpoint不通,可排查下

4、 在其它两个master节点创建以下目录 :

mkdir -p /etc/kubernetes/pki/

5、 把主master节点证书分别复制到其余master节点 :

scp -r /etc/kubernetes/pki/ca.* root@192.168.15.216:/etc/kubernetes/pki/
scp -r /etc/kubernetes/pki/sa.* root@192.168.15.216:/etc/kubernetes/pki/
scp -r /etc/kubernetes/pki/front-proxy-ca.* root@192.168.15.216:/etc/kubernetes/pki
scp -r /etc/kubernetes/pki/etcd/ca.* root@192.168.15.216:/etc/kubernetes/pki/etcd
scp -r /etc/kubernetes/admin.conf root@192.168.15.216:/etc/kubernetes/

6、 其他master节点加入集群执行以下命令 :

kubeadm join 10.88.15.253:8443 --token abcdef.0123456789abcdef --discovery-token-ca-cert-hash sha256:9363682fcdbfedd6e059d7428d859d5b0ae5388641dcd098b6876d89461b0625 --control-plane

7、 所有master节点执行以下命令(管理集群,查看集群等),node节点随意 :

#root用户执行以下命令:
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
source .bash_profile

#非root用户可以执行以下命令:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

8、 node节点加入集群执行以下命令(要安装kubeadm、kubelet、kubectl) :

kubeadm join 10.88.15.253:8443 --token abcdef.0123456789abcdef --discovery-token-ca-cert-hash sha256:9363682fcdbfedd6e059d7428d859d5b0ae5388641dcd098b6876d89461b0625

注意:如果加入时卡在了这个命令位置,[preflight] Running pre-flight checks,说明token已经过期,此时可以执行下面命令重新生成token和hash的值

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

生成后使用新的token和hash值再次执行命令加入集群即可

如果加入node节点,出现如下错误: error execution phase kubelet-start: error uploading crisocket: timed out waiting for the condition
To see the stack trace of this error execute with –v=5 or higher,此时可以按照如下步骤执行,如下:

swapoff -a
kubeadm reset
systemctl daemon-reload
systemctl restart kubelet
iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X
#执行完成后重新加入集群即可

9、加入完成后,在master节点执行命令查看集群资源,如下:

从上图可以看出,STATUS显示NotReady,因为还没有安装网络组件

执行命令kubectl get cs 查看集群状态可以看出显示如下:

出现这种情况,是/etc/kubernetes/manifests/下的kube-controller-manager.yaml和kube-scheduler.yaml设置的默认端口是0导致的,解决方式是注释掉对应的port即可,操作如下:

执行命令kubectl get po -n kube-system可以看到coredns处于pending状态,因为没有安装calico

10、安装calico网络插件:下载文件,执行命令如下:

#注意:此calico是针对50个节点之内的
curl https://docs.projectcalico.org/manifests/calico.yaml -O

修改pod CIDR地址,默认是192.168.0.0/16,需要修改成我们自己的,先打开注释,修改自定义的pod网段地址,如图:

里面的镜像地址修改为自己的仓库地址,本例子中用的阿里云镜像仓库(不需要secret认证),如图:

如果是个人仓库还需要在镜像拉取策略位置要设置仓库认证名称(Deployment和DaemonSet位置都要设置)和拉取策略(也可以不设置默认是Always),如图:

注意:需要创建仓库认证文件secret.yml,然后配置在calico中,这样才可以顺利将镜像拉去下来,参考二进制部署中的配置说明https://www.ywdevops.cn/index.php/2021/06/29/k8s-2/

最后执行命令kubectl apply -f calico.yaml即可,执行完成后可以看到coredns也恢复正常了,如图:

各个节点状态都变成了Ready,如图:

注意:如果出现如下错误calico/node is not ready: BIRD is not ready: BGP not established,表示calico没有 发现实际真正的网卡 ,可用如下方式解决,如图:

如果calico的控制器pod calico-kube-controllers提示错误如下:

Failed to create pod sandbox: rpc error: code = Unknown desc = [failed to set up sandbox container “70a2175a467ba631594c6f661ff612e15eed9d5f31332061ef7d2b399d5cacdb” network for pod “calico-kube-controllers-dbc86d6cc-7cbs9”: networkPlugin cni failed to set up pod “calico-kube-controllers-dbc86d6cc-7cbs9_kube-system” network: error getting ClusterInformation: connection is unauthorized: Unauthorized, failed to clean up sandbox container “70a2175a467ba631594c6f661ff612e15eed9d5f31332061ef7d2b399d5cacdb” network for pod “calico-kube-controllers-dbc86d6cc-7cbs9”: networkPlugin cni failed to teardown pod “calico-kube-controllers-dbc86d6cc-7cbs9_kube-system” network: error getting ClusterInformation: connection is unauthorized: Unauthorized

解决方法:

  • kubelet delete -f calico.yaml #卸载calico
  • rm -rf /etc/cni/net.d/* #删除全部节点的calico残留配置文件
  • modprobe -r ipip #删除tun10网卡
  • reboot 或者systemctl restart kubelet
  • kubectl apply -f calico.yaml #最后在重新部署calico

注:k8s 1.20.8版本可使用calico的3.19.1 ,k8s 1.23.5版本可用calico的3.25.0版本

metrics部署:

在新版的k8s中,资源采集均使用Metirc-server,可以通过Metirc采集节点和Pod的内存、磁盘、cpu和网络使用率

首先将mastere1节点的front-proxy-ca.crt拷贝到所有Node节点

scp /etc/kubernetes/pki/front-proxy-ca.crt root192.168.15.218:/etc/kubernetes/pki

github.com下载metrics的yaml文件,地址如下:

https://github.com/kubernetes-sigs/metrics-server/releases/tag/v0.4.4
#名称为:components.yaml

修改文件components.yaml,内部的镜像地址改为自己的仓库地址(需要提前把镜像下载回来传入仓库),然后加入指定证书的参数,如图:

注:不加证书参数可能获取不到度量指标

执行命令kubectl create -f components.yaml创建Pod即可,如图:

注意:如果镜像拉取不成功,那就手动将镜像拉取到每个节点上即可,注意看镜像拉取策略imagePullPolicy,如果是IfNotPresent,那么如果从仓库拉取不成功就会寻找本地镜像

运行成功后,执行命令kubectl top node 可以查看所有节点的资源情况,如图:

执行命令kubectl top po -A 可以查看所有pod的资源情况,如图:

注:-A 表示所有命名空间

至此:k8s集群已经部署完成,下面的dashboard可根据需要进行部署

dashboard部署

将文件下载回来,一共两个文件,dashboard-user.yaml和dashboard.yaml,修改dashboard.yaml中的镜像地址为本地地址,一共两个,如图:

执行命令创建pod,如下:

kubectl create -f dashborad-user.yaml dashboard.yaml

注意:如果镜像拉取不成功,可检查下拉取策略是否为IfNotPresent,建议采用此策略

部署完成后,需要修改谷歌浏览器的配置,然后才可以访问自签名的https页面,在启动文件后面添加参数–test-type –ignore-certificate-errors,如图:

然后更改kubernetes-dashboard的svc为NodePort,否则访问不了,执行命令如下:

#首先查看下svc
kubectl get svc -n kubernetes-dashboard
#编辑svc
kubectl edit svc kubernetes-dashboard -n kubernetes-dashboard
#编辑后,修改最下方的type:ClusterIP 为type:NodePort

再次查看svc可以看到已经变成NodePort类型,映射到宿主的端口为30500,如图:

此时通过vip地址加端口即可访问dashboard,https://192.168.15.253:30500如图:

注意:通过https来访问

查看登录token,命令如下:

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

将此token输入后,点击登录即可,如图:

修改proxy模式为ipvs

首先查看下默认的模式,执行命令如下:

curl 127.0.0.1:10249/proxyMode

输入命令编辑kube-proxy,修改模式为ipvs,如下:

#查看comfigmap情况
kubectl get cm -n kube-system
#编辑kube-proxy,修改模式
kubectl edit cm kube-proxy -n kube-system

执行命令滚动更新,如下:

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

再次查看模式,已经变成ipvs,如图:

七、集群可用性验证:

1、首先通过命令kubectl get po –all-namespace(或者-A参数)查看所有容器都已启动,如图:

2、验证下网络情况,首先查看k8s的service ip情况,执行命令如下:

kubectl get svc
#k8s的IP地址一般为cluster ip的第一个IP地址

验证每台机器到此IP的443端口是否通,如图:

查询coredns的serviceip 地址,执行命令如下:

kubectl get svc -n kube-system
#coredns的IP地址一般为clusterip 的第10个IP地址

验证每台机器到此IP的53端口是否通,如图:

3、验证其余机器到某台机器的pod 是否通(跨服务器访问),首先查看pod地址,如图:

kubctl get po -A -o wide //查询详细信息

从上图可以看出,在master2机器上有一个Pod ,地址为172.169.115.66,然后在其他所有节点上ping此IP地址,看是否通,如图:

经过测试,所有节点都通,说明跨服务器访问没问题

4、接下来验证pod和pod之间是否通,选择其他任意一台机器,进入pod中,然后ping master节点的172.169.115.66,执行命令如下:

通过如下组件可实现固定pod的ip/mac地址:

https://github.com/google-fabric
posted @ 2023-02-22 15:53  技术颜良  阅读(891)  评论(0编辑  收藏  举报