K8s Docker的Good选择

引子:在现代开发当中,整体式的应用早已成为过去时,如今的应用由数十乃至数百个松散结合的容器式组件构成,而这些组件需要通过相互间的协同合作,才能使既定的应用按照设计运作。容器编排是指对单独组件和应用层的工作进行组织的流程。

而容器编排会遇到如下的问题:

  • 一个容器故障停机了,怎么让另外一个容器立刻启动去替补停机的容器
  • 当并发访问量变大的时候,怎么样做到横向扩展的容器数量

为解决这些容器编排问题,,产生了伊西俄容器编排的软件。K8S就是google开源的容器编排工具。

K8S简介:

kubernetes,是一个全新的基于容器技术的分布式架构领先方法,其本质是一组服务器集群,可以在集群的每个节点上运行特定的程序,来对节点中的容器进行管理。

k8s的功能:

  • 自我修复: 一旦某个docker崩溃,会在1s之内启动新docker顶替崩溃的docker
  • 弹性伸缩: 根据需要,自动对集群中的容器数量进行调整
  • 服务发现:服务可以通过自动发现的形式找到它所依赖的服务
  • 负载均衡:如果一个服务器启动了多个容器,能自动实现请求的负载均衡
  • 版本回退:如果发现新发布的程序版本有问题,立即回退到原来的版本
  • 存储编排:根据容器自身的需求自动创建存储卷

K8s组件:

一个k8s集群主要是由控制节点与工作节点构成,每个节点上安装不同的组件。

  • 控制节点:又叫做master节点,主要负责集群的决策:

    APIServer: 资源操作的唯一入口,接受用户输入的命令,进行认证与访问控制等
    Scheduler: 负责集群资源调度, 按照预定的调度策略将Pod调度到相应的node节点上
    ControllerManager: 负责维护集群的状态,比如程序部署安排,故障检测,自动扩展,滚动更新等
    Etcd: 负责存储集群中各种资源对象的信息,主要是存储相应功能的容器的地址啥的方便发命令
    

在这里插入图片描述

  • node: 集群的数据平面, 负责为容器提供运行环境

    Kubelet: 负责维护容器的生命周期,来更新,创建,销毁docker
    KubeProxy: 负责提供集群内部的服务发现于负载均衡
    Docker: 负责节点上的容器操作
    

    一个部署nginx的例子:

    1. k8s环境启动之后, master和node都将自身的信息存放到etcd
    2. 一个nginx服务的安装请求首先发送到master节点和apiServer组件
    3. apiServer组件会调用Scheduler组件决定到底把服务安排在哪个node节点上
    4. apiServer在调用controller-manager去调度node节点安装nginx服务
    5. kublet接收到指令之后,通知docker, 由docker来启动一个nginx的pod(pod是k8s的最小操作单元,容器必须在pod中)
    6. nginx安装完成了,访问nginx经过kube-pro的负载均衡产生对pod中的container的代理,这样外界就可以访问集群中的nginx服务了
    K8S集群环境

    K8S的集群大体上分为两类:一主多从与多主多从。

    • 一主多从: 存在单机故障风险,搭建简单,适用于测试环境
    • 多主多从: 搭建麻烦,安全性高,适用于生产环境

    安装: 有三种安装方式:minkube(快速单间单节点k8s的工具), kubeadm快速搭建k8s集群的工具, 二进制包(从官网一个一个下,比较麻烦但是理解的更深刻)

    本教程本来是打算跟着kubeadm安装的,但是导致自己踩坑的时候报废了两个Ubuntu20.04 系统。真的无语住了,

    咱就是说坑踩多了就老老实实的跟着教程走:

    1. 关闭swap, 关闭防火墙(ufw), 写入主机名, 设置时戳:

      (Tips: swap 指允许我们使用虚存, 必须禁用放置性能抖动。主要是k8s这么要求的)

      sudo nano /etc/hosts    	# 设置主机名
      sudo ufw disable			# 关闭防火墙
      sudo nano /etc/fstab		# 关闭swap
      sudo timedatectl set-timezone Asia/Shanghai 	# 设置时间戳保持相同
      
      # 关于为什么centos需要关闭selinux而ubuntu不需要,,兄弟你确定你装selinux了么
      
    2. 安装docker, 按照官方文档来就行,或者https://docs.docker.com/engine/install/ubuntu/

    3. 安装kubeadm, kubectl, kubelet:

      # 更新并与允许 curl HTTPs的访问,没装过的装一下
      # sudo apt-get update && sudo apt-get install -y apt-transport-https
      
      # 去阿里云去搞一个密钥。 注,这句话只能由root运行,不也能使用sudo。畏怯一般来说都要运行这句话的
      curl -fsSL https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
      
      #新增源
      sudo tee /etc/apt/sources.list.d/kubernetes.list <<EOF 
      deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
      EOF
      
      # 更新并安装三组件: kubelet,  kubeadm,  kubectl
      sudo apt-get install -y kubelet kubeadm kubectl
      
      # 遇到的问题1:缺少依赖,缺少啥咱就安啥
      The following packages have unmet dependencies:
       kubelet : Depends: ebtables but it is not going to be installed
      E: Unable to correct problems, you have held broken packages.
      sudo apt-get install ebtables
      
      # 遇到问题二,版本不兼容
      kubelet : Depends: iptables (>= 1.4.21)
      E: Unable to correct problems, you have held broken packages.
      
      # 升级, 核心包版本不兼容
      apt-get upgrade iptables
      iptables : Depends: libip4tc0 (= 1.6.1-2ubuntu2) but it is not going to be installed
                 Depends: libip6tc0 (= 1.6.1-2ubuntu2) but it is not going to be installed
                 Depends: libiptc0 (= 1.6.1-2ubuntu2) but it is not going to be installed
                 Depends: libxtables12 (= 1.6.1-2ubuntu2) but 1.8.4-3ubuntu2 is to be installed
      # 这里报错更高版本的包已经装过了,坑点,不要卸载这个更高版本的包(笔者的一时手欠加忘拍快照直接报废了一个系统),直接安装需要的版本的包即可,不然系统直接挂了
      apt-get install libxtables12=1.6.1-2ubuntu2
      # 之后递归向上更新即可
      apt-get upgrade iptables
      sudo apt-get install -y kubelet kubeadm kubectl
      
    4. 初始化:

      sudo kubeadm init
      root@ubuntu:~# kubeadm init
      [init] Using Kubernetes version: v1.23.5
      [preflight] Running pre-flight checks
      [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'
      
      #等个两三分钟,报错,原因是连不到google家的仓库超时了。明明放了镜像却一定会去Google找
      # 解决方法也很简单,科学上网或者将版本找网上国内有仓库的下载, 镜像地址咱就是说直接找这个人的https://registry.hub.docker.com/r/v5cn/kube-apiserver/tags
      #(这是教程https://blog.csdn.net/m0_44982764/article/details/118753414)
      
      看版本号:kubeadm config images list
      以我的1.23.5 版本为例,拖过来这个v5cn大佬的镜像
      set -o errexit
      set -o nounset
      set -o pipefail
       
      ##这里定义版本,按照上面得到的列表自己改一下版本号
       
      KUBE_VERSION=v1.23.5
      KUBE_PAUSE_VERSION=3.6
      ETCD_VERSION=3.5.1-0
      DNS_VERSION=v1.8.6
       
      ##这是原始仓库名,最后需要改名成这个
      GCR_URL=k8s.gcr.io
       
      ##这里就是写你要使用的仓库
      DOCKERHUB_URL=v5cn
       
      ##这里是镜像列表,新版本要把coredns改成coredns/coredns
      images=(
      kube-proxy:${KUBE_VERSION}
      kube-scheduler:${KUBE_VERSION}
      kube-controller-manager:${KUBE_VERSION}
      kube-apiserver:${KUBE_VERSION}
      pause:${KUBE_PAUSE_VERSION}
      etcd:${ETCD_VERSION}
      coredns/coredns:${DNS_VERSION}
      )
       
      ##这里是拉取和改名的循环语句
      for imageName in ${images[@]} ; do
        docker pull $DOCKERHUB_URL/$imageName
        docker tag $DOCKERHUB_URL/$imageName $GCR_URL/$imageName
        docker rmi $DOCKERHUB_URL/$imageName
        echo $DOCKERHUB_URL/$imageName Done
      done
      
      # 但是不知道为什么,我装了这些包之后在初始化的时候还是要先访问google的那个网站,然后就还是超时。没办法,只能science online。关键点在于全局proxy (求求审核给过吧): https://v2xtls.org/v2raya%EF%BC%9A%E6%94%AF%E6%8C%81%E5%85%A8%E5%B1%80%E9%80%8F%E6%98%8E%E4%BB%A3%E7%90%86%E7%9A%84v2ray-linux%E5%AE%A2%E6%88%B7%E7%AB%AF/
      
      
      # 坑2, 
      curl -sSL http://localhost:10248/healthz
      curl: (7) Failed to connect to localhost port 10248: Connection refused
      #查看报错原因: journalctl -xeu kubelet / journalctl -xeu kubelet -l (参考https://blog.51cto.com/8999a/5005591)
      [302] "Failed to run kubelet" err="failed to run Kubelet: misconfiguration: ku>
      exited, status=1/FAILURE
      报错原因:是因为 k8s 和docker 的 cgroup driver 不一致导致的。k8s 的是 systemd ,而 docker 是cgroupfs。
      
      尝试:在docker daemon首选项加入:
      {
      "exec-opts": ["native.cgroupdriver=systemd"]
      }
      
      解决
      # 坑点3, 10250端口占用
      [ERROR Port-10250]: Port 10250 is in use
      sudo netstat -tunlp    # 查看端口信息
      tcp6       0      0 :::10250                :::*                    LISTEN      890/kubelet
      # 我这边是kubelet占用了,应该都是雷希德相关程序占用, kill就好了
      sudo kill 890  
      
      安装成功的标志:
      Your Kubernetes control-plane has initialized successfully!
      
      接下来就可以安装其他组件了
      
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐