• kubeadm安装kubernetes


    k8s集群搭建

    背景

    实验环境准备

    部署docker

          设置使用国内Yum源

          安装指定的Docker版本

          安装Docker20.10.3

          设置cgorup驱动使用systemd

          启动后台进程

          查看docker版本

          部署kubeadm和kubelet

                设置k8s YUM仓库

                安装软件包

                配置kubelet

                设置内核参数

                启动kubelet并设置开机启动

                使用ipvs进行负载均衡

          初始化集群部署master

                导出所有默认的配置

                修改集群创建参数

                执行初始化操作

                为kubectl准备kubeconfig文件

                使⽤kubectl命令查看组件状态

                处理unhealth的组件

                使用kubectl获取node信息

          部署网络插件

                部署node节点

          测试k8s集群

    k8s集群搭建

    背景

    想要快速的体验Kubernetes的功能,官方提供了非常多的部署方案,可以使用官方提供的kubeadm以容器的方式运行Kubernetes集群,也可以使用二进制方式部署更有利于理解 Kubernetes的架构,我们先使用kubeadm快速的部署一个Kubernetes集群后。

    注意:由于云平台的存在当前部署已经是k8s学习的初期阶段了,建议尽快开始k8s课程的深入学习。k8sv1.13版本发布后,kubeadm才正式进入GA,可以生产使用。目前k8s的对应镜像仓库,在国内阿里云也有了镜像站点,使用kubeadm部署k8s集群变得简单并且容易了很多,我们使用kubeadm带领大家快速部署k8sv1.21.14版本。

    实验环境准备

    在上一节实验环境的基础上,我们如下来分配⻆色:

    主机名Ip地址描述
    linux-node1.example.cometh0:192.168.56.11k8s master/etcd节点
    linux-node2.example.cometh0:192.168.56.12k8s node节点
    linux-node3.example.cometh0:192.168.56.13k8s node节点
    service网段10.1.0.0/16
    Pod网段10.2.0.0/16

    部署docker

    首先需要在所有Kubernetes集群的节点中安装Docker和kubeadm。

    设置使用国内Yum源

    [root@linux-node1 ~]# cd /etc/yum.repos.d/
    [root@linux-node1 yum.repos.d]# wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

    安装指定的Docker版本

    由于kubeadm对Docker的版本是有要求的,需要安装与Kubernetes匹配的版本,这个对应关系⼀般在每次发布的Changlog中可以找到。例如1.21.14的CHANGELOG中docker需求是 20版本;当前docker的版本可以通过下面的命令查看:

    [root@linux-node1 ~]# yum list docker-ce.x86_64 --showduplicates |sort-r 已加载插件:fastestmirror 已安装的软件包 可安装的软件包 * updates: m

    安装Docker20.10.3

    [root@linux-node1 ~]# yum -y install docker-ce-20.10.3-3.el7  docker-ce-cli-20.10.3-3.el7

    设置cgorup驱动使⽤systemd

    [root@linux-node1 ~]# mkdir /etc/docker[root@linux-node1 ~]# cat > /etc/docker/daemon.json <<EOF{"registry-mirrors": ["https://dx5z2hy7.mirror.aliyuncs.com"],"exec-opts": ["native.cgroupdriver=systemd"],"log-driver": "json-file","log-opts": {"max-size": "100m"},"storage-driver": "overlay2","storage-opts": ["overlay2.override_kernel_check=true"]}EOF

    启动后台进程

    [root@linux-node1 ~]# systemctl enable docker && systemctl start docker

    查看docker版本

    [root@linux-node1 ~]# docker --versionDocker version 19.03.8, build afacb8b

    部署kubeadm和kubelet

    在k8s集群的所有节点上部署完毕docker后,还需要全部部署kubeadm和kubelet,其中kubeadm是管理⼯具,kubelet是⼀个服务,⽤于启动k8s对应的服务。

    设置k8s YUM仓库

    这⾥在官⽅⽂档的基础上修改为了国内阿⾥云的yum仓库

    [root@linux-node1 ~]# vim /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://mirrors.aliyun.com/kubernetes/yu

    安装软件包

    由于版本更新频繁,请指定对应的版本号,本⽂采⽤ 1.21.14版本,其它版本未经测试,如果不指定版本默认安装最新版本。

    [root@linux-node1 yum.repos.d]# yum -y install kubelet-1.21.14 kubeadm-1.21.14 kubectl-1.21.14 ipvsadm

    配置kubelet

    默认情况下, Kubelet不允许所在的主机存在交换分区,后期规划的时候,可以考虑在系统安装的时候不创建交换分区,针对已经存在交换分区的可以设置忽略禁⽌使⽤Swap的限 制,不然⽆法启动Kubelet。

    [root@linux-node1 ~]# vim /etc/sysconfig/kubelet KUBELET_CGROUP_ARGS="--cgroup-driver=systemd" KUBELET_EXTRA_ARGS="--fail-swap-on=false"

    在所有节点上关闭SWAP​​​​​​​

    [root@linux-node1 ~]# swapoff -a[root@linux-node1 ~]# cat <<EOF >  /etc/sysctl.d/k8s.confnet.bridge.bridge-nf-call-ip6tables = 1net.bridge.bridge-nf-call-iptables = 1net.ipv4.ip_forward = 1EOF

    使配置⽣效   [root@linux-node1 ~]# sysctl --system

    启动kubelet并设置开机启动

    注意,此时kubelet是⽆法正常启动的,可以查看/var/log/messages有报错信息,等待执⾏初始化之后即可正常,为正常现象;

    [root@linux-node1 ~]# systemctl enable kubelet && systemctl start kubelet

    使⽤ipvs进⾏负载均衡

    在Kubernetes集群中Kube-Proxy组件负载均衡的功能,默认使⽤iptables,⽣产环境建议使⽤ipvs进⾏负载均衡。在所有节点启⽤ipvs模块​​​​​​​

    [root@linux-node1 ~]# vim /etc/sysconfig/modules/ipvs.modules#!/bin/bashmodprobe -- ip_vsmodprobe -- ip_vs_rrmodprobe -- ip_vs_wrrmodprobe -- ip_vs_shmodprobe -- nf_conntrack_ipv4[root@linux-node1 ~]# chmod +x /etc/sysconfig/modules/ipvs.modules[root@linux-node1 ~]# source /etc/sysconfig/modules/ipvs.modules

    以上步骤请在Kubernetes的所有节点上执⾏,本实验环境是需要在linux-node1 、linux-node2 、linux-node3这三台机器上均安装Docker 、kubeadm 、kubelet.

    初始化集群部署master

    在所有节点上安装完毕后,在linux-node1这台Master节点上进⾏集群的初始化⼯作。

    导出所有默认的配置

    [root@linux-node1 ~]#kubeadm config print init-defaults > kubeadm.yaml

    上⾯的命令会⽣成⼀个默认配置的kubeadm配置⽂件,然后在此基础上进⾏修改即可。

    修改集群创建参数​​​​​​​

    apiVersion: kubeadm.k8s.io/v1beta2
    bootstrapTokens:
    - groups:
    - system:bootstrappers:kubeadm:default-node-token
    token: abcdef.0123456789abcdef
    ttl: 24h0m0susages:- signing- authenticationkind: InitConfigurationlocalAPIEndpoint:advertiseAddress: 192.168.56.11 #修改为API Server的地址bindPort: 6443nodeRegistration:criSocket: /var/run/dockershim.sockname: linux-node1.example.comtaints: null---apiServer:timeoutForControlPlane: 4m0sapiVersion: kubeadm.k8s.io/v1beta2certificatesDir: /etc/kubernetes/pkiclusterName: kubernetescontrollerManager: {}dns:type: CoreDNSetcd:local:dataDir: /var/lib/etcdimageRepository: registry.aliyuncs.com/google_containers #修改为阿⾥云镜像仓库kind: ClusterConfigurationkubernetesVersion: v1.21.14 #修改为具体的版本networking:dnsDomain: cluster.localserviceSubnet: 10.1.0.0/16 #修改service的⽹络podSubnet: 10.2.0.0/16 #新增Pod的⽹络scheduler: {}---   #下⾯有增加的三⾏配置,⽤于设置Kubeproxy使⽤LVSapiVersion: kubeproxy.config.k8s.io/v1alpha1kind: KubeProxyConfigurationmode: ipvs

    执行初始化操作

    [root@linux-node1 ~]# kubeadm init --config kubeadm.yaml[init] Using Kubernetes version: v1.21.14[preflight] Running pre-flight checkserror execution phase preflight: [preflight] Some fatal errors occurred:[ERROR NumCPU]: the number of available CPUs 1 is less than the required 2[ERROR Mem]: the system RAM (972 MB) is less than the minimum 1700 MB[preflight] If you know what you are doing, you can make a check non-fatal with `--ignore-preflight-errors=...`To see the stack trace of this error execute with --v=5 or higher

    如果遇到上⾯这样的报错,是因为在实验环境开启了交换分区,以及CPU的核数⼩于2造成的,可以使⽤ --ignore-preflight-errors=进⾏忽略。   --ignore-preflight-errors= :忽略运⾏时 的错误,例如上⾯⽬前存在[ERROR NumCPU]和[ERROR Swap],忽略这两个报错就是增加 --ignore-preflight-errors=NumCPU 和--ignore-preflight-errors=Swap的配置即可。   再次 执⾏初始化操作: ``` [root@linux-node1 ~]# swapoff -a [root@linux-node1 ~]# kubeadm init --config kubeadm.yaml --ignore-preflight-errors=NumCPU,Mem,Swap [init] Using            Kubernetes version: v1.21.14 [preflight] Running pre-flight checks [WARNING NumCPU]: the number of available CPUs 1 is less than the required 2 [WARNING Mem]: the system RAM (972 MB) is less than the minimum 1700 MB [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​​​​​​​

    执⾏完毕后,会在当前输出下停留,等待下载Kubernetes组件的Docker镜像。根据你的⽹络情况,可以持续 1-5分钟,你也可以使⽤docker images查看下载的镜像。镜像下载完毕之后 ,就会进⾏初始操作:这⾥省略了所有输出,初始化操作主要经历了下⾯ 15个步骤,每个阶段均输出均使⽤[步骤名称]作为开头:* [init]:指定版本进⾏初始化操作* [preflight] :初始化前的检查和下载所需要的 Docker镜像⽂件。* [kubelet-start]:⽣成kubelet的配置⽂件”/var/lib/kubelet/config.yaml”,没有这个⽂件kubelet⽆法启动,所以初始化之前的kubelet实际上启动失败。* [certificates]:⽣成Kubernetes使⽤的证书,存放在/etc/kubernetes/pki⽬录中。* [kubeconfig] :⽣成  KubeConfig⽂件,存放在/etc/kubernetes⽬录中,组件之间通信需要使⽤对应⽂件。* [control-plane]:使⽤/etc/kubernetes/manifest⽬录下的YAML⽂件,安装  Master组件。* [etcd]:使⽤/etc/kubernetes/manifest/etcd.yaml安装Etcd服务。* [wait-control-plane]:等待control-plan部署的Master组件启动。* [apiclient]:检查Master组件服务状态。* [uploadconfig]:更新配置* [kubelet]:使⽤configMap配置kubelet* [patchnode]:更新CNI信息到Node上,通过注释的⽅式记录。* [mark-control-plane]:为当前节点打标签,打了⻆⾊Master,和不可调度标签,这样默认就不会使⽤ Master节点来运⾏ Pod* [bootstrap-token]:⽣成token记录下来,后边使⽤kubeadm join往集群中添加节点时会⽤到* [addons]:安装附加组件CoreDNSkube-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/

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

    kubeadm join 192.168.56.11:6443 --token abcdef.0123456789abcdef \ --discovery-token-ca-cert-hash

    sha256:a0272d589f79d9568bb79cf829493676156351f96237438b85ce32da3724b109 ```

    如果执⾏失败,那意味着之前的操作存在问题,检查顺序如下:   * 基础环境 * 主机名是否可以解析,  SELinux,  iptables是否关闭。   * 交换分区是否存在free -m查看 * 内核参数是否修 改、  IPVS是否修改(⽬前阶段不会造成失败)

    • 基础软件

    • Docker是否安装并启动

    • Kubelet是否安装并启动

    • 执⾏kubeadm是否有别的报错是否忽略

    • systemctl status kubelet查看kubelet是否启动

    • 如果kubelet⽆法启动,查看⽇志有什么报错,并解决报错。

    以上都解决完毕,需要重新初始化

    kubeadm reset 进⾏重置(⽣产千万不要执⾏,会直接删除集群)   根据kubeadm reset 提升,清楚iptables和LVS 。   请根据上⾯输出的要求配置kubectl命令来访问集群。

    为kubectl准备kubeconfig⽂件

    kubectl默认会在执⾏的⽤户家⽬录下⾯的.kube⽬录下寻找config⽂件。这⾥是将在初始化时[kubeconfig]步骤⽣成的admin.conf拷⻉到.kube/config。​​​​​​​

    [root@linux-node1 ~]# mkdir -p $HOME/.kube [root@linux-node1 ~]# cp -i /etc/kubernetes/admin.conf $HOME/.kube/config [root@linux-node1 ~

    在该配置⽂件中,记录了API Server的访问地址,所以后⾯直接执⾏kubectl命令就可以正常连接到API Server中。

    使⽤kubectl命令查看组件状态​​​​​​​

    [root@linux-node1 ~]# kubectl get csWarning: v1 ComponentStatus is deprecated in v1.19+NAME                 STATUS       MESSAGE                               ERRORcontroller-manager   Unhealthy    Get "http://127.0.0.1:10252/healthz": dial tcp 127.0.0.1:10252: connect: connection refusedscheduler            Unhealthy    Get "http://127.0.0.1:10251/healthz": dial tcp 127.0.0.1:10251: connect: connection refusedetcd-0               Healthy      {"health":"true"}

    k8s集群状态提示Gethttp://127.0.0.1:10251/healthz:dial tcp 127.0.0.1:10251:connect: connection refused,这种情况是因为kube-controller-manager.yaml和kube-scheduler.yaml ⾥ ⾯配置了默认端⼝0。检查kube-controller-manager.yaml和kube-scheduler.yaml​​​​​​​

    [root@linux-node1 manifests]# cd /etc/kubernetes/manifests/[root@linux-node1 manifests]# lsetcd.yaml  kube-apiserver.yaml  kube-controller-manager.yaml  kube-scheduler.yaml#对这两个⽂件进⾏备份 ,创建备份⽬录[root@linux-node1 manifests]# mkdir /backup# 对⽂件进⾏备份操作[root@linux-node1 manifests]# cp kube-controller-manager.yaml /backup/[root@linux-node1 manifests]# cp kube-scheduler.yaml /backup/

    处理unhealth的组件

    编辑kube-controller-manager.yaml和kube-scheduler.yaml的配置⽂件,注视掉port=0的⾏,保存退出即可。

    使⽤kubectl命令查看组件状态

    [root@linux-node1 manifests]# kubectl get cs Warning: v1 ComponentStatus is deprecated in v1.19+ NAME STATUS MESSAGE ERROR controller-ma

    知识说明:为什么上⾯的输出没有显示API Server组件的状态

    因为API Server是Kubernetes集群的⼊⼝,所有和Kubernetes集群的交互都必须经过APIServer,  kubectl命令也是连接到API Server上进⾏交互,所以如果能够正常使⽤kubectl执⾏ 命令,意味着API Server运⾏正常。

    使⽤kubectl获取node信息

    ⽬前只有⼀个节点,⻆⾊是Master,状态是NotReady。

    [root@linux-node1 ~]# kubectl get node NAME STATUS ROLES AGE VERSION linux-node1.example.com NotReady control-plane,master 19m v1.21.14

    部署⽹络插件

    Master节点NotReady的原因就是因为没有使⽤任何的⽹络插件,此时Node和Master的连接还不正常。⽬前最流⾏的Kubernetes⽹络插件有Flannel 、Calico 、Canal,这⾥分别列举  了Canal和Flannel,你可以选择其中之⼀进⾏部署。   因为基础的Kubernetes集群已经配置完毕,后⾯的增加组件等操作,⼏乎都可以使⽤kubectl和⼀个YAML配置⽂件来完成。     【部 署Flannel⽹络插件】(推荐)   部署Flannel⽹络插件需要修改Pod的IP地址段,修改为和你初始化⼀直的⽹段,可以先下载Flannel的YAML⽂件修改后,再执⾏。​​​​​​​

    [root@linux-node1 ~]# git clone --depth 1 https://github.com/coreos/flannel.git[root@linux-node1 ~]# cd flannel/Documentation/[root@linux-node1 Documentation]# vim kube-flannel.yml# 修改 "Network": "10.244.0.0/16""Network": "10.2.0.0/16",net-conf.json: |{"Network": "10.2.0.0/16","Backend": {"Type": "vxlan"
    }}

    部署Flannel

    [root@linux-node1 Documentation]# kubectl create -f kube-flannel.yml

    查看Pod状态,注意如果有出于pending状态的pod待flanel安装完成后就会变成running;​​​​​​​

    [root@linux-node1 Documentation]# kubectl get pod --all-namespacesNAMESPACE      NAME                                              READY   STATUS    RESTARTS   AGEkube-flannel   kube-flannel-ds-zp4mf                               1/1     Running   0           3m1skube-system    coredns-59d64cd4d4-wxzjw                            1/1     Running   0           31mkube-system    coredns-59d64cd4d4-zppgw                            1/1     Running   0           31mkube-system    etcd-linux-node1.example.com                        1/1     Running   1           31mkube-system    kube-apiserver-linux-node1.example.com             1/1     Running   1           31mkube-system    kube-controller-manager-linux-node1.example.com   1/1     Running   6          29mkube-system    kube-proxy-d4tsw                                     1/1     Running   1           31mkube-system    kube-scheduler-linux-node1.example.com             1/1     Running   5          28m[root@linux-node1 Documentation]

    所有Pod的状态都变成Running之后,这个时候再次获取Node,会发现节点变成了Ready状态。​​​​​​​

    [root@linux-node1 Documemtation]# kubectl get nodeNAME                     STATUS  ROLES                 AGE   VERSIONlinux-node1.example.com  Ready   control-plane,master  35m   v1.21.1

    kubeadm其实使⽤Kubernetes部署Kubernetes,这样就存在先有鸡还是先有蛋的问题,所以,我们⾸先⼿动部署了Docker和kubelet,然后kubeadm调⽤kubelet以静态Pod的⽅式部 署了Kubernetes集群中的其它组件。静态Pod在后⾯的章节会讲到。

    部署node节点

    Master节点部署完毕之后,就可以部署Node节点,⾸先请遵循部署Docker和kubeadm章节为Node节点部署安装好docker 、kubeadm和kubelet,此过程这⾥不再重复列出。

    • Master节点输出增加节点的命令

      [root@linux-node1 Documentation]# kubeadm token create --print-join-commandkubeadm join 192.168.56.11:6443 --token 352g01.c3r8gvzog5i545hi --discovery-token-ca-cert-hash sha256:a0272d589f79d9568bb79cf829493676156351f96237438b85ce32da3724b109[root@linux-node1 Documentation]#​​​​​​​
    • 在node节点执⾏注意如果节点有交换分区,需要增加--ignore-preflight-errors=Swap 。   部署linux-node2

    [root@linux-node2 ~]# kubeadm join 192.168.56.11:6443 --token 61tumq.rnrs79270u4a2ofj --discovery-token-ca-cert-hash sha256:a0272d58

    部署linux-node3

    [root@linux-node3 ~]# kubeadm join 192.168.56.11:6443 --token 61tumq.rnrs79270u4a2ofj --discovery-token-ca-cert-hash sha256:a0272d58

    这个时候kubernetes会使⽤DaemonSet在所有节点上都部署flannel和kube-proxy 。部署完毕之后节点即部署完毕。  DaemonSet的内容后⾯会讲解。

    测试k8s集群

    • 创建⼀个Pod的nginx应⽤

    [root@linux-node1 ~]# kubectl create deployment nginx --image=nginx:alpine
    deployment.apps/nginx created
    [root@linux-node1 ~]# kubectl get pod
    NAME READY STATUS RESTARTS AGE
    nginx-54458cd494-9j7ql 0/1 ContainerCreating 0 10s
    • 查看Pod详细信息 待Pod的状态为Running后,可以获取Pod的IP地址,这个IP地址是从Master节点初始化的--pod-network-cidr=10.2.0.0/16地址段中分配的。

    • 测试nginx访问

    [root@linux-node1 Documentation]# curl --head http://10.2.2.2HTTP/1.1 200 OKServer: nginx/1.21.5Date: Fri, 14 Oct 2022 05:56:27 GMTContent-Type: text/htmlContent-Length: 615Last-Modified: Tue, 28 Dec 2021 18:48:00 GMTConnection: keep-aliveETag: "61cb5be0-267"Accept-Ranges: bytes
    • 测试扩容

    [root@linux-node1 ~]# kubectl scale deployment nginx --replicas=2deployment.extensions/nginx scaled[root@linux-node1 Documentation]# kubectl get podSTATUSRunningRunning[root@linux-node1 ~]# kubectl expose deployment nginx --port=80--type=NodePortservice/nginx exposed[root@linux-node1 Documentation]# kubectl get serviceCLUSTER-IPClusterIPNodePort
    • 测试service的ip

    [root@linux-node1 Documentation]# curl --head http://10.1.200.119HTTP/1.1 200 OKServer: nginx/1.21.5Date: Fri, 14 Oct 2022 06:00:18 GMTContent-Type: text/htmlContent-Length: 615Last-Modified: Tue, 28 Dec 2021 18:48:00 GMTConnection: keep-aliveETag: "61cb5be0-267"Accept-Ranges: bytes[root@linux-node1 Documentation]#
    • 测试Nodeport,外部访问

    这样看起来已经拥有了第⼀个k8s集群,接下来我们将开始k8s探索之旅。

  • 相关阅读:
    小程序中如何核销订单和优惠券
    设计模式--责任链模式
    【Vue全家桶】Vuex状态管理
    技术学习:Python(21)|爬虫篇|selenium自动化操作浏览器
    森林安全新保障:智能高压应急消防泵的应用
    MySQL介绍及CRUD操作。
    【老板要我啥都会】前端升全栈系列 项目安全
    软件测试/测试开发丨Selenium Web自动化测试 高级控件交互方法
    mmsegmentation 训练自己的数据集
    arm cortex-a9的qemu仿真与启动文件解释
  • 原文地址:https://blog.csdn.net/dajiangtai007/article/details/127765798