Kubernetes小试牛刀

1、Kubernetes简介

Kubernetes,是一个全新的基于容器技术的分布式架构领先方案,是Google严格保密十几年的秘密武器--Borg系统的一个开源版本,于2014年9月发布第一个版本,2015年7月发布第一个正式版本。

Kubernetes的本质是一组服务器集群,它可以在集群的每个节点上运行特定的程序,来对节点中的容器进行管理。它的目的就是实现资源管理的自动化,主要提供了如下的功能:

  • 自我修复:一旦某一个容器崩溃,能够在1秒左右迅速启动新的容器。

  • 弹性伸缩:可以根据需要,自动对集群中正在运行的容器数量进行调整。

  • 服务发现:服务可以通过自动发现的形式找到它所依赖的服务。

  • 负载均衡:如果一个服务启动了多个容器,能够自动实现请求的负载均衡。

  • 版本回退:如果发现新发布的程序版本有问题,可以立即回退到原来的版本。

  • 存储编排:可以根据容器自身的需求自动创建存储卷。

2、Kubernetes组件

2.1、组件介绍

一个Kubernetes集群主要由控制节点(master)、工作节点(node)构成,每个节点上都会安装不同的组件。

  • 控制节点(master):集群的控制平面,负责集群的决策。

    • API Server:集群操作的唯一入口,接收用户输入的命令,提供认证、授权、API注册和发现等机制。

    • Scheduler:负责集群资源调度,按照预定的调度策略将Pod调度到相应的node节点上。

    • ControllerManager:负责维护集群的状态,比如程序部署安排、故障检测、自动扩展和滚动更新等。

    • Etcd:负责存储集群中各种资源对象的信息。

  • 工作节点(node):集群的数据平面,负责为容器提供运行环境。

    • Kubelet:负责维护容器的生命周期,即通过控制Docker,来创建、更新、销毁容器。
    • KubeProxy:负责提供集群内部的服务发现和负载均衡。
    • Docker:负责节点上容器的各种操作。

Kubernetes小试牛刀

2.3、组件概念

  • Master:集群控制节点,每个集群要求至少有一个Master接地那来负责集群的管控。
  • Node:工作负载节点,由Master分配容器到这些Node工作节点上,然后Node节点上的Docker负责容器的运行。
  • Pod:Kubernetes的最小控制单元,容器都是运行在Pod中,一个Pod可以有一个或多个容器。
  • Controller:控制器,通过它来实现对Pod的管理,比如启动Pod,停止Pod,伸缩Pod的数量等等。
  • Label:标签,用于对Pod进行分类,同一类Pod会拥有相同的标签。
  • NameSpace:命令空间,用来隔离Pod的运行环境。

2.3、Kubernetes组件调用关系的应用示例

以部署一个Nginx服务器来说明Kubernetes系统各个组件间的调用关系。

? ①首先需要明确,一旦Kubernetes环境启动之后,master和node都会将自身的信息存储到ETCD数据库中。

? ②一个Nginx服务的安装请求首先会被发送到master节点上的API Server组件。

? ③API Server组件会调用Scheduler组件来决定到底应该把这个服务安装到那个node节点上。此时,它会从ETCD中读取各个node节点的信息,然后按照一定的算法进行选择,并将结果告知API Server。

? ④API Server调用Controller-Manager去调用Node节点安装Nginx服务。

? ⑤Kubelet接收到指令后,会通知Docker,然后由Docker来启动一个Nginx的Pod。Pod是Kubernetes的最小操作单元,容器必须跑在Pod中。

? ⑥一个Nginx服务就运行了,如果需要访问Nginx,就需要通过kube-proxy来对Pod产生访问的代理,这样,外界用户就可以访问集群中的Nginx服务了。

3、集群环境的搭建

3.1、环境规划

3.1.1、集群类型

Kubernetes集群大致分为两类:一主多从和多主多从。

  • 一主多从:一个Master节点和多个Node节点,搭建简单,但是有单机故障风险,适合用于测试环境。
  • 多主多从:多个Master节点和多个Node节点,搭建麻烦,安全性高,适用于生产环境。

Kubernetes小试牛刀

3.1.2、安装方式

Kubernetes有多种部署方式,目前主流的方式有kubeadm、minikube、二进制包。

  • minikube:一个用于快速搭建单节点的Kubernetes工具。
  • kubeadm:一个用于快速搭建Kubernetes集群的工具。
  • 二进制包:从官网上下载每个组件的二进制包,依次去安装,此方式对于理解Kubernetes组件更加有效。

3.1.3、主机规划

角色 IP地址 操作系统 配置
Master 192.168.114.129 Centos7.8+,基础设施服务器 2核CPU,2G内存,50G硬盘
Node1 192.168.114.130 Centos7.8+,基础设施服务器 2核CPU,2G内存,50G硬盘
Node2 192.168.114.131 Centos7.8+,基础设施服务器 2核CPU,2G内存,50G硬盘

3.2、集群搭建(一主多从)

注:无特别说明,三台机器一直执行相应的命令

3.2.1、环境初始化

  • 检查操作系统的版本

    cat /etc/redhat-release
    CentOS Linux release 7.9.2009 (Core)
    
    # 推荐使用7.5及以上版本
    
  • 关闭防火墙和禁止防火墙开机启动

    systemctl stop firewalld
    systemctl disable firewalld
    
  • 禁用iptables

    systemctl stop iptables
    systemctl disable iptables
    
  • 禁用selinux

    selinux时Linux系统的一个安全服务,在集群的安装过程中可能会遇到各种奇葩问题,所以选择关闭它 。

    vim /etc/selinux/config
    
    SELINUX=disabled
    
  • 禁用swap分区

    Swap分区在系统的物理内存不够用的时候,把硬盘内存中的一部分空间释放出来,以供当前运行的程序使用。那些被释放的空间可能来自一些很长时间没有什么操作的程序,这些被释放的空间被临时保存到Swap分区中,等到那些程序要运行时,再从Swap分区中恢复保存的数据到内存中。但是这样非常影响性能。

    vim /etc/fstab
    
    # 只需注释掉最后一句
    #/dev/mapper/centos-swap swap   swap    defaults  0 0
    
  • 配置域名解析

    cat >> /etc/hosts << EOF
    192.168.114.129 master
    192.168.114.130 node1
    192.168.114.131 node2
    EOF
    
    # 配置完成后,可以在三台机器上互相验证
    ping master 
    ping node1
    ping node2
    
  • 时间同步

    Kubernetes要求集群中的节点时间必须精确一致,所以在每个节点上添加时间同步 。(此处必须保证三台服务器的时间不然,不然会出现node连接不上master的情况)

    yum install ntpdate -y
    ntpdate time.windows.com
    
  • 添加网桥过滤和地址转发

    vim /etc/sysctl.d/kubernetes.conf
    
    net.bridge.bridge-nf-call-ip6tables = 1
    net.bridge.bridge-nf-call-iptables = 1
    net.ipv4.ip_forward = 1
    
    # 加载使生效
    sysctl -p
    
  • 加载网桥过滤模块

    modprobe br_netfilter
    
    # 查看是否加载
    lsmod | grep br_netfilter
    > br_netfilter           22256  0 
    > bridge                151336  1 br_netfilter
    
  • 配置ipvs功能

    在Kubernetes中service有两种代理模型,一种是基于iptables的,一种是基于ipvs的两者比较的话,ipvs的性能明显要高一些,但是如果要使用它,需要手动载入ipvs模块。

    # 安装ipset和ipvsadm
    yum -y install ipset ipvsadm
    
    # 添加需要加载的模块写入脚本文件
    cat <<EOF>  /etc/sysconfig/modules/ipvs.modules
    modprobe -- ip_vs
    modprobe -- ip_vs_rr
    modprobe -- ip_vs_wrr
    modprobe -- ip_vs_sh
    modprobe -- nf_conntrack_ipv4
    EOF
    
    # 为脚本文件添加执行权限
    chmod +x /etc/sysconfig/modules/ipvs.modules
    
    # 执行
    /bin/bash /etc/sysconfig/modules/ipvs.modules
    
    # 查看对应模块是否加载成功
    lsmod | grep -e ip_vs -e nf_conntrack_ipv4
    
    > nf_conntrack_ipv4      15053  9 
    > nf_defrag_ipv4         12729  1 nf_conntrack_ipv4
    > ip_vs_sh               12688  0 
    > ip_vs_wrr              12697  0 
    > ip_vs_rr               12600  0 
    > ip_vs                 145458  6 ip_vs_rr,ip_vs_sh,ip_vs_wrr
    > nf_conntrack          139264  7 
    >ip_vs,nf_nat,nf_nat_ipv4,xt_conntrack,nf_nat_masquerade_ipv4,nf_conntrack_netlink,nf_conntra> ck_ipv4
    > libcrc32c              12644  4 xfs,ip_vs,nf_nat,nf_conntrack
    
  • 重启时配置生效

    reboot
    
  • 检查selinux和swap是否生效

    gentenforce  # 检查selinux 
    > disable
    
    free -m  # 检查swap
    
      total   used   free  shared  buff/cache  available
    Mem:3502  453    2180  11         869       2812
    Swap:0     0       0
    

3.2.2、Kubernetes安装

  • docker 安装

    # 替换阿里源
    yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    
    # 安装指定版本,必须指定--setopt=obsoletes=0,否则会自动安装更高版本
     yum install --setopt=obsoletes=0 docker-ce-18.06.3.ce-3.el7 -y
     
    # 设置docker加速器
    sudo mkdir -p /etc/docker
    
    # docker在默认情况下使用的Cgroup Driver为cgroupfs,而Kubernetes推荐使用systemd来代替cgroupfs
    sudo tee /etc/docker/daemon.json <<-‘EOF‘
    {
      "exec-opts": ["native.cgroupdriver=systemd"], 
      "registry-mirrors": ["https://isch1uhg.mirror.aliyuncs.com"]
    }
    EOF
    
    # 启动docker 
    ststemctl start docker
    # 开机启动
    systemctl enable docker
    
  • 安装Kubernetes组件

    # 由于Kubernetes的镜像在国外,速度比较慢,这里换成国内镜像源。
    cat > /etc/yum.repos.d/kubernetes.repo << EOF
    [kubernetes]
    name=Kubernetes
    baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
    enabled=1
    gpgcheck=0
    repo_gpgcheck=0
    gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
    EOF
    
    # 由于版本更新频繁,这里指定版本号部署(1.18.0)
    yum install -y kubelet-1.18.0 kubeadm-1.18.0 kubectl-1.18.0
    
    # 为了实现Docker使用的cgroup drvier和kubelet使用的cgroup drver一致,建议修改"/etc/sysconfig/kubelet"文件的内容
    vim /etc/sysconfig/kubelet
    
    KUBELET_EXTRA_ARGS="--cgroup-driver=systemd"
    KUBE_PROXY_MODE="ipvs"
    
    # 设置为开机自启动即可,由于没有生成配置文件,集群初始化后自动启动
    systemctl enable kubelet
    
  • 部署Master节点(192.168.114.129)

    此操作只需要在Master节点上操作。

    # 由于默认拉取镜像地址k8s.gcr.io国内无法访问,这里需要指定阿里云镜像仓库地址
    
    kubeadm init   --apiserver-advertise-address=192.168.114.129   --image-repository registry.aliyuncs.com/google_containers   --kubernetes-version v1.18.0   --service-cidr=10.96.0.0/12   --pod-network-cidr=10.244.0.0/16
      
    # 看到Success等字样,以及提示加入master节点命令,说明master启动成功。
    
    # 根据提示信息,在Master节点上使用Kubectl工具
    mkdir -p $HOME/.kube
    sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
    sudo chown $(id -u):$(id -g) $HOME/.kube/config
    
    ## 补充
    # 如要需要重启,则需要删除 $HOME/.kube/config
    rm -rf $HOME/.kube/config
    kubeadm reset 
    kubeadm init   --apiserver-advertise-address=192.168.114.129   --image-repository registry.aliyuncs.com/google_containers   --kubernetes-version v1.18.0   --service-cidr=10.96.0.0/12   --pod-network-cidr=10.244.0.0/16
    
  • 部署Node节点

    此处操作需要在两个Node上操作

    # 根据Master节点提示信息,将Node加入Master
    kubeadm join 192.168.37.128:6443 --token j068mm.zzc2tg40yrdh3dw9 --discovery-token-ca-cert-hash sha256:fda934d79defaca0416c232022ba1ad7057648ceeb173744faacd4e7555efcee
    
  • 在Master上查看节点信息

    kubectl get nodes 
    
    # 执行命令后,会发现STATUS显示NotReady,这是我们没有配置网络。节点间不能通信。
    

3.3.3、部署CNI网路插件

此处只需在Master上操作

Kubernetes支持多种网络插件,比如flannel、calico、canal等,任选一种即可,本次选择flannel 。

# 注意此处可能需要KX上网
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

# 查看部署CNO网络插件进度
kubectl get pods -n kube-system

NAME                             READY   STATUS    RESTARTS   AGE
coredns-7ff77c879f-8cjh4         1/1     Running   0          4h30m
coredns-7ff77c879f-96dh4         1/1     Running   0          4h30m
etcd-master                      1/1     Running   0          4h30m
kube-apiserver-master            1/1     Running   0          4h30m
kube-controller-manager-master   1/1     Running   0          4h30m
kube-flannel-ds-4mj76            1/1     Running   0          3h22m
kube-flannel-ds-7tz4s            1/1     Running   0          3h22m
kube-flannel-ds-mnv66            1/1     Running   0          3h22m
kube-proxy-7pv69                 1/1     Running   0          4h30m
kube-proxy-shv6g                 1/1     Running   0          4h29m
kube-proxy-xhfj7                 1/1     Running   0          4h29m
kube-scheduler-master            1/1     Running   0          4h30m

# 查看节点状态
kubectl get nodes

NAME     STATUS   ROLES    AGE     VERSION
master   Ready    master   4h31m   v1.18.0
node1    Ready    <none>   4h30m   v1.18.0
node2    Ready    <none>   4h30m   v1.18.0

# 查看集群健康状态
kubectl get cs

NAME                 STATUS    MESSAGE             ERROR
scheduler            Healthy   ok                  
controller-manager   Healthy   ok                  
etcd-0               Healthy   {"health":"true"}   

3.3.4、服务部署

在Kubernetes集群中部署一个Nginx服务,测试集群是否正常工作。

# 创建Nginx
kubectl create deployment nginx --image=nginx:1.14-alpine

# 暴露端口
kubectl expose deploy nginx --port=80 --target-port=80 --type=NodePort

# 查看服务
kubectl get svc

NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP        4h35m
nginx        NodePort    10.107.20.43   <none>        80:30073/TCP   3h21m

# 访问测试(集群中任意一个地址都可以访问)
curl http://192.168.114.131:30073

Kubernetes小试牛刀

上一篇:.net 知新:【3】.net 5 项目结构说明和发布部署


下一篇:netty系列之:netty初探