• 搭建K8S集群(kubeadm篇)


    搭建K8S集群(kubeadm篇)

    一、K8S概述

    K8S是当下最火热的容器运行时编排工具,不仅仅提供了用户应用的容器镜像运行解决方案,还提供了路由网关、水平扩展、多副本容灾等能力。在Kubernetes项目中,master节点由负责api服务的kube-apiserver、负责调度的kube-scheduler、负责编排的kebu-controller-manager三者组成。node节点上,最核心的部分是kubelet组件。kubelet主要负责同容器运行时(比如Docker项目)交互,而交互依赖的是CRI(Container Runtime Interface)的远程调用接口。这个接口定义了容器运行时的各项核心操作。具体的容器运行时,则通过OCI这个容器标准,把CRI请求翻译成对Linux系统的底层调用。
    话不多说,我们用最简单的方式,即kubeadm来搭建一个K8S集群吧。

    二、如何使用kubeadm搭建集群

    2.1 机器准备

    我们需要准备3台机器,配置是4核8G,提前做好部署规划和网络规划。考虑到云上机器的网络条件较好,我这里用的是腾讯云的机器,读者们也可以使用3台2核4G的机器来完成搭建。
    每台机器都需要关闭防火墙,配置好DNS域名解析,并且时间上已配置同步。

    • master节点
    • node1节点
    • node2节点

    2.2 准备程序包

    由于我们本次使用的是kubeadm工具搭建集群,我们先要下载相关的程序包。但是!由于大中华网络等原因,部分包下载会有问题。那怎么办呢,我们找一台海外的机器来下载这部分程序包即可。
    安装kubeadm所需的程序包有以下几个

    • kubelet
    • kubeadm
    • kubectl
    • kubernetes-cni
    • cri-tools
    # 安装yum-utils工具,这样我们就可以将包下载到本地
    yum install -y yum-utils
    
    # 配置yum源,让我们能够下载相关程序包
    cat >> /etc/yum.repos.d/kubernetes.repo << EOF
    [kubernetes]
    name=Kubernetes
    baseurl=http://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
    enabled=1
    gpgcheck=1
    repo_gpgcheck=1
    gpgkey=http://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
    EOF
    
    # 将相关程序包下载 kubelet kubeadm kubectl kubernetes-cni cri-tools
    yumdownloader kubelet kubeadm kubectl kubernetes-cni cri-tools
    
    # 打包这几个rpm程序包,上传到我们的集群机器上去
    tar zcf k8s-deploy.tgz *.rpm
    

    备注: 作者知道有些同学可能还没有海外的服务器,这几个服务的包我已经打包好放在网盘上,大家可以直接下载使用。https://share.weiyun.com/g8sbwcWA

    2.3 安装kubeadm

    我们已经有了相关软件包了,安装就很简单了

    # 解压软件包
    tar xf k8s-deploy.tgz
    
    # 执行安装
    yum localinstall -y *.rpm
    

    2.4 下载镜像

    最早期的时候,K8S集群是直接部署在裸金属服务器上面的,这个部署过程有一系列繁琐的操作(如手动生成配置证书等操作),非常的不友好。后面呢大家考虑,既然K8S能力这么强大,那为何不把kube-apiserver、kube-controller-manager、kube-scheduler这些都做成容器镜像,然后通过K8S直接管理起来呢。事实上,kubeadm就是这样做的。但是这里有一点需要注意的是,并不是每个组件都事宜做成容器镜像的,比方说像kubelet。因为kubelet需要与宿主机打交道,比方说配置宿主机网络、存储系统等。假如kubelet是一个容器,那么其运行在自己的Namespace中,是很难对宿主机进行操作的。因此,kubelet是需要手动在宿主机上安装的。
    我们开始下载K8S组件的容器镜像,糟糕这里似乎有被大中华的网络拦截了。这里我们就需要依赖阿里云镜像仓库,这里有我们所需的全部镜像,我们可以从阿里云镜像仓库下载镜像,然后打tag将镜像改成kubeadm所需的即可。

    # 查看kubeadm部署集群所需的镜像
    kubeadm config images list
    #k8s.gcr.io/kube-apiserver:v1.23.1
    #k8s.gcr.io/kube-controller-manager:v1.23.1
    #k8s.gcr.io/kube-scheduler:v1.23.1
    #k8s.gcr.io/kube-proxy:v1.23.1
    #k8s.gcr.io/pause:3.6
    #k8s.gcr.io/etcd:3.5.1-0
    #k8s.gcr.io/coredns/coredns:v1.8.6
    
    # 下载所需镜像并修改tag,这里的coredns我们稍后单独处理
    for item in `kubeadm config images list | egrep -v "coredns|grep"` ; do image=` echo $item | sed -e "s@k8s.gcr.io@registry.aliyuncs.com/google_containers@g"`; docker pull $image ; docker tag $image `echo $image | sed -e "s@registry.aliyuncs.com/google_containers@k8s.gcr.io@g"` ; docker rmi $image ; done ; 
    
    # 下载coredns镜像
    for item in `kubeadm config images list | egrep "coredns" | grep -v grep ` ; do image=` echo $item | sed -e "s@k8s.gcr.io/coredns@registry.aliyuncs.com/google_containers@g"` ; docker pull $image ; docker tag $image `echo $image | sed -e "s@registry.aliyuncs.com/google_containers@k8s.gcr.io/coredns@g"` ; docker rmi $image ; done ; 
    
    # 查看我们下载的所有镜像,此时看看是不是和我们通过kubeadm config images list查询出来的一样啦
    docker images
    

    2.5 部署master节点

    到了这里,我们就可以使用kubeadm来部署master节点。部署命令非常简单,只需要执行kubeadm init即可。部署完成之后,出现如下提示就说明kubeadm执行完成了。

    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 IP:6443 --token ltfaw0.yci1z7zqdrll2ixp \
            --discovery-token-ca-cert-hash sha256:145415d491d67daeb13910ffb49e5a8608863225a13cfdc794b85cc5aca46972 
    

    在这里可能有些同学会碰到kubelet相关的异常,通过执行journalctl -xeu kubelet可以看到,最常见的就是kubelet提示“kubelet cgroup driver: "systemd" is different from docker cgroup driver: "cgroupfs"”,这是什么意思呢?
    意思就是说docker使用的cgroup驱动和kubelet使用的驱动不一致,我们知道cgroup全称为Linux Control Group,是用来控制一个进程组使用系统资源的上限。kubelet是通过CRI这个远程调用接口来操作容器运行时(即Docker),驱动不一致会导致相关限制能力无法执行。所以,我们需要修改Docker(建议,当然也可以修改kubelet)的cgroup驱动。具体如下:

    # 修改docker的配置文件
    cat /etc/docker/daemon.json 
    {
      "exec-opts": ["native.cgroupdriver=systemd"]
    }
    
    # 内核重新加载进程配置
    systemctl daemon-reload
    
    # 重启docker进程
    systemctl restart docker
    
    # 检查docker的cgroup驱动
    docker info
    

    2.6 部署网络插件

    此时我们部署好了K8S集群的master节点,根据输出提示export KUBECONFIG=/etc/kubernetes/admin.conf在机器上执行,然后我们通过kubectl get po -n kube-system检查各个Pod的运行情况。突然发现咋不对劲呢,怎么有些Pod始终处于Pending状态呢?

    [root@VM-62-206-centos ~]# kubectl get po -n kube-system
    NAME                                       READY   STATUS    RESTARTS   AGE
    coredns-64897985d-9nrqf                    0/1     Pending   0          31s
    coredns-64897985d-ms4jr                    0/1     Pending   0          31s
    etcd-vm-62-206-centos                      1/1     Running   0          35s
    kube-apiserver-vm-62-206-centos            1/1     Running   0          35s
    kube-controller-manager-vm-62-206-centos   1/1     Running   0          37s
    kube-proxy-zkxln                           1/1     Running   0          31s
    kube-scheduler-vm-62-206-centos            1/1     Running   0          35s
    

    其实这是正常的,DNS和什么相关,和网络相关对吧。我们现在都还没有网络插件,肯定是有问题啊。话不多说,我们立马把网络插件部署上去,在这里我们使用的网络插件是weave

    # 部署网络插件,非常简单一条命令就可以搞定
    # 执行完之后需要等一段时间,因为在下载镜像
    kubectl apply -n kube-system -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"
    

    这里可能有些同学在部署过程中会碰到,网络插件weave在启动的过程在提示“CrashLoopBackOff”,我们打开日志检查

    kubectl logs weave-net-k966t -c weave -n kube-system
    # Network 10.32.0.0/12 overlaps with existing route 10.0.0.0/8 on host
    

    我们从这里看到了啥,是不是说weave需要配置10.32.0.0/12这个网段的路由表,但是和现有机器上面的路由表冲突了。怎么办呢,其实比较简单的解决办法是把现有冲突的网段调整一下。调整完之后,我们再打印下Pod运行情况,可以看到Pod全部都正常运行了。

    kubectl get po -n kube-system
    NAME                                       READY   STATUS    RESTARTS       AGE
    coredns-64897985d-9nrqf                    1/1     Running   0              92m
    coredns-64897985d-ms4jr                    1/1     Running   0              92m
    etcd-vm-62-206-centos                      1/1     Running   0              92m
    kube-apiserver-vm-62-206-centos            1/1     Running   0              92m
    kube-controller-manager-vm-62-206-centos   1/1     Running   0              92m
    kube-proxy-zkxln                           1/1     Running   0              92m
    kube-scheduler-vm-62-206-centos            1/1     Running   0              92m
    weave-net-k966t                            2/2     Running   11 (21m ago)   59m
    

    2.7 部署node节点

    部署node节点比较简单,我们在node节点上面安装好docker-ce、kubeadm、上传相关镜像后,只需要将部署master节点系统提示的命令复制过去即可。

    # 执行部署node节点命令
    kubeadm join IP:6443 --token ltfaw0.yci1z7zqdrll2ixp --discovery-token-ca-cert-hash sha256:145415d491d67daeb13910ffb49e5a8608863225a13cfdc794b85cc5aca46972 
    

    此时我们等一段时间,等待weave插件在node节点上面安装完成,就可以看到整个集群Pod均运行情况。

    kubectl get po -n kube-system
    NAME                                       READY   STATUS    RESTARTS       AGE
    coredns-64897985d-9nrqf                    1/1     Running   0              130m
    coredns-64897985d-ms4jr                    1/1     Running   0              130m
    etcd-vm-62-206-centos                      1/1     Running   0              130m
    kube-apiserver-vm-62-206-centos            1/1     Running   0              130m
    kube-controller-manager-vm-62-206-centos   1/1     Running   0              130m
    kube-proxy-ftr7m                           1/1     Running   0              30m
    kube-proxy-mcxt5                           1/1     Running   0              29m
    kube-proxy-zkxln                           1/1     Running   0              130m
    kube-scheduler-vm-62-206-centos            1/1     Running   0              130m
    weave-net-9rpsv                            2/2     Running   0              30m
    weave-net-dd9nr                            2/2     Running   0              29m
    weave-net-k966t                            2/2     Running   11 (58m ago)   97m
    

    2.8 一些收尾工作

    到目前为止,我们已经部署好一个非生产环境的K8S集群,做做实验还是绰绰有余的。不过,大家有没有发现,kubectl命令只有在master节点上管用,在其他的node节点似乎不起作用,始终提示“The connection to the server localhost:8080 was refused - did you specify the right host or port?”。这个如何修复呢,其实很简单,我们只需要把master节点的/etc/kubernetes/admin.conf拷贝到node节点的对应位置,在执行export命令即可。

    scp /etc/kubernetes/admin.conf root@node_ip:/etc/kubernetes/admin.conf
    export KUBECONFIG=/etc/kubernetes/admin.conf
    

    三、控制器模式下运行Pod实例

    现在我们已经有了完整可用的K8S集群,我们就开始部署一个简答的Nginx服务吧。

    3.1 编写YAML文件

    我已经编写好一个最简单的案例文件

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
    spec:
      selector:
        matchLabels:
          app: nginx
      replicas: 2
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:1.7.9
            ports:
            - containerPort: 80
    

    3.2 运行应用

    我们执行kubectl apply -f nginx.yaml来将我们编写好的YAML提交到K8S,使用apply操作的好处在于,K8S可以自动识别到文件的变化,并根据对象的变化自动执行响应的操作(增加或者减少副本数量、修改应用镜像等)。
    过了几分钟,我们可以看到应用顺利运行起来了。

    kubectl get po
    NAME                                READY   STATUS    RESTARTS   AGE
    nginx-deployment-5fcc5d8c6d-6fr2b   1/1     Running   0          12m
    nginx-deployment-5fcc5d8c6d-79r2w   1/1     Running   0          11m
    
  • 相关阅读:
    Linux 下判断磁盘是ssd还是hdd
    Ceph rgw COR测试
    nfs 挂载选项
    【Linux命令】dmsetup--device mapper 管理工具(更底层的管理工具)
    Device Mapper 存储介绍
    easyui combotree 默认 初始化时就选中
    EasyUI 添加tab页(iframe方式)(转)
    EasyUI DataGrid 配置参数
    EasyUI 后台接受DataGrid传来的参数
    (转)combogrid的代码实例
  • 原文地址:https://www.cnblogs.com/zimskyzeng/p/15708037.html
Copyright © 2020-2023  润新知