K8S

为什么要容器化

  1. 节省服务器资源
  2. 自动伸缩扩容
  3. 环境一致性
  4. 方便迁移,一次构建到处部署

什么是Docker

  1. Docker并不等于容器,Docker只是基于容器技术的一个产品。相比于其他容器产品,Docker最大的优势和创新是镜像(image)。
  2. 通过docker run启动一个容器,是通过Linux Namespace、Linux Cgroups 和 rootfs 三种技术构建出来的进程的隔离环境,实际它只是运行在主机上的一个特殊的进程。

什么是K8S,为什么需要K8S

  1. 如果说Docker只是安装应用的另外一种形式,那么k8s就是管理容器应用的操作系统,为Docker化的应用提供路由网关、水平扩展、监控、备份、灾难恢复等一系列运维能力。认识了k8s才能真正走入容器化的世界
  2. k8s最重要的概念是Pod,Pod是k8s项目的原子调度单位,一个Pod可以包含一个或多个容器应用(通常只放一个)。所以你可以将一个pod看成我们传统的一台虚拟机。

K8S的架构

  1. 全局架构

    • ApiServer: K8S访问入口,所有通过kubectl执行的命令都是调用ApiServer实现的,提供认证、授权、访问控制、API 注册和发现等机制。
    • Scheduler: 调度室,决定一个Pod应该运行在哪个Node。(Pod运行的节点一般通过Node的label指定)。
    • Controller Manager: 总控室,监控集群状态,管理集群资源。例如:例如某一个应用设置的副本是2,其中一个意外停止,则Controller Manager负责重新创建一个Pod,保证应用副本个数是2。
    • Etcd: key-value的数据库,负责持久化集群中各资源对象的信息。
    • kubelet: 主要负责和Docker交互。
    • kube-proxy: 负责为Service提供cluster内部的服务发现和负载均衡,处理外部请求应该访问到那个pod。
      k8s-cluster
  2. 集群对象关系

    • Pod: 一个或多个紧密协作的容器应用组成的逻辑对象,每个Pod会分配一个虚拟的PodIP(主机模式用的是主机IP),一个Pod内的容器共享Pod的IP和网络配置,用于同外界通信。
    • Replication Controller: Pod的子类,简称RC。一个RC可以管理多个Pod。
    • Replica Set: RS是新一代 RC。
    • Deployment: 管理RS的对象,提供了更丰富管理Pod的功能,例如:健康检查,滚动升级等。
    • Ingress: 需要结合Ingress Controller和Service一起使用,可以看成Nginx的另一种形式,只要Ingress更新了,对应的访问入口就更新了,相当于Nginx自动更新了。
    • Service: 一组Pod的访问入口,并负责pod的负载均衡。一个Service会分配一个Cluster IP,并指定与主机和Pod的通信端口。
    • ConfigMap/Secret: 都属于一种特殊的volume,负责存放一些环境相关的配置,方便多环境配置调整,只是Secret是加密的。
    • DaemonSet: 会在每个或指定范围内的Node都运行一个Pod,且新增节点后会自动部署。例如:网络插件flannel
    • StatefulSet: 有状态的应用。一般用来部署中间件,例如:redis,elasticsearch
    • Job: 一次性任务
    • CronJob: 定时任务
    • Horizontal PodAutoscaler: 水平自动伸缩控制器
      k8s-pod

k8s的网络原理

k8s网络实则是帮助Docker实现跨主机通信

docker容器怎么和主机通信

宿主机安装完docker后,会创建一个docker0网桥,执行ifconfig会看到有如下信息:(其中192.168.5.1可以通过/etc/docker/daemon.json中bip配置项自行指定)

docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.5.1  netmask 255.255.255.0  broadcast 192.168.5.255
        inet6 fe80::42:ecff:fee9:1ed3  prefixlen 64  scopeid 0x20<link>
        ether 02:42:ec:e9:1e:d3  txqueuelen 0  (Ethernet)
        RX packets 47074  bytes 14036792 (13.3 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 47814  bytes 12944523 (12.3 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
.
.
.
vetha0087a6: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::ccf2:faff:fed1:cf71  prefixlen 64  scopeid 0x20<link>
        ether ce:f2:fa:d1:cf:71  txqueuelen 0  (Ethernet)
        RX packets 47074  bytes 14695828 (14.0 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 47822  bytes 12945171 (12.3 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

在docker0网桥上有一个Veth Pair的虚拟网卡设备,正是通过这个虚拟设备容器可以和docker0通信,然后docker0则可以和主机直接通信。至于docker0怎么和主机通信,我想应该和iptables技术有关

A主机的容器怎么和B主机的容器通信

两个主机网络是连通的,但是两台主机上的docker0是不互通的,所以我们要通过软件的方式为两台主机构建一个虚拟网络Overlay Network。有了这个虚拟网络,两台主机上的容器通信就和单机类似了。这就是为什么k8s集群必须安装网络插件的原因,执行ifconfig会看到如下信息

flannel.1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1450
        inet 100.244.0.0  netmask 255.255.255.255  broadcast 0.0.0.0
        inet6 fe80::b07b:70ff:feae:1fe8  prefixlen 64  scopeid 0x20<link>
        ether b2:7b:70:ae:1f:e8  txqueuelen 0  (Ethernet)
        RX packets 21112  bytes 10048496 (9.5 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 23197  bytes 2119926 (2.0 MiB)
        TX errors 0  dropped 8 overruns 0  carrier 0  collisions 0

集群外访问集群内服务的几种模式

  • Host模式: Browser->Nginx->Pod
  • NodePort模式: Browser->Nginx->Service->Pod
  • Ingress模式: Browser->Ingress->Service->Pod

二进制安装(单机)

关闭防火墙

systemctl disable firewalld  
systemctl stop firewalld

安装etcd和kubernetes(会自动安装docker)

yum install -y etcd kubernetes

修改配置

  1. 修改Docker配置文件/etc/sysconfig/docker,OPTIONS='--selinux-enabled=false --insecure-registry gcr.io'
  2. 修改配置文件/etc/kubernetes/apiserver,把–admission_control参数中的ServiceAccount删除

按顺序启动所有服务

systemctl start etcd  
systemctl start docker  
systemctl start kube-apiserver  
systemctl start kube-controller-manager  
systemctl start kube-scheduler  
systemctl start kubelet  
systemctl start kube-proxy

查看版本

kubectl version

FAQ

  1. 删除pod后,pod会自动重启,因为rc还存在,应删除rc

    kubectl get rc
    kubectl delete rc rcname
    
  2. 拉取不到最新的镜像 因为当你的版本和上次一样时,可能拉取的镜像不是最新的,在app_deploy_rc.yaml镜像拉取策略有3种

    • imagePullPolicy: Always:总是从镜像库中拉取
    • imagePullPolicy: IfNotPresent: 如果本地不存在才从镜像库中拉取
    • imagePullPolicy: Nerver: 只从本地拉取镜像
  3. The maximum number of pending replies per connection has been reached 随着worker node上的pod不断增长,到了一定时间后,调度到该节点的pod会出现异常:The maximum number of pending replies per connection has been reached.

    • 出现这个提示是 Linux 为了防止程序占用过多系统资源导致拒绝服务而做的限制,所以根本解决办法是追加系统资源,或者在安装 k8s 节时是为其设置合理的资源预留
    • 临时解决方案,调整系统参数 max_replies_per_connection。
      vim /usr/share/dbus-1/session.conf
      systemctl restart dbus.service
      systemctl daemon-reload
      
  4. PLEG is not healthy
    节点状态一直是 NotReady , 查看 kubelet 日志 ( systemctl status kubelet ) 出现如下错误:

     kubelet[21928]: E0829 13:50:48.305712   21928 kubelet.go:1845] skipping pod synchronization - PLEG is not   healthy: pleg was last seen active 10m52.160098484s ago; threshold is 3m0s
    

    解决办法:来源于 https://cloud.tencent.com/developer/article/1884333

     systemctl daemon-reexec
    

参考文献

results matching ""

    No results matching ""