Kubernetes/K8S快速入门-基本概念

前言

官方文档:https://kubernetes.io/zh/docs/setup/

image-20210302173424496

在之前的文章中我们经历了上面的一系列变化,这里就说一下这些技术本身都解决了什么问题,从而帮助我们在实际环境中应该使用什么技术。

Docker的出现解决了之前每次部署一个新环境都要重新配置的问题,但是如果项目有多个服务以及我们要做多个负载就要分别配置启动

Docker Compose的出现就解决了上面的问题,但是我们的多个负载依旧要通过Nginx做反向代理

Traefik就解决了这个问题,我们可以轻松的配置反向代理及多个负载,但是如果我们的负载挂了,就只能人工重启,并且它只能在一台服务器上,如果有多个服务器,它就无能为力了

K8S就解决了这个问题,但是相应的配置的难度也提高了。

使用 Docker Compose 可以轻松、高效的管理容器,它是一个用于定义和运行多容器 Docker 的应用程序工具。

但是他无法同时管理多台计算机,而Kubernetes 可以管理大规模的集群,使集群中的每一个节点彼此连接,能够像控制一台单一的计算机一样控制整个集群。

Kubernetes名称优点长,所以用K8S代替,中间的8代表名称中间的8个字母。

Kubernetes 得益于 Docker 的特性,服务的创建和销毁变得非常快速、简单,实现了集群规模的管理、编排方案,使应用的发布、重启、扩缩容能够自动化。

image-20220221141449505

相关概念

image-20210302170431262

Kubernetes主要由以下几个核心组件组成:

  • etcd保存了整个集群的状态;
  • apiserver提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;
  • controller manager负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
  • scheduler负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上;
  • kubelet负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理;
  • Container runtime负责镜像管理以及Pod和容器的真正运行(CRI);
  • kube-proxy负责为Service提供cluster内部的服务发现和负载均衡;

除了核心组件,还有一些推荐的Add-ons:

  • kube-dns负责为整个集群提供DNS服务
  • Ingress Controller为服务提供外网入口
  • Heapster提供资源监控
  • Dashboard提供GUI
  • Federation提供跨可用区的集群
  • Fluentd-elasticsearch提供集群日志采集、存储与查询

Kubernetes基于集群的设计,它有两种角色一种是 master ,一种是 Node(也叫worker)。

  • master 是集群的大脑,负责管理整个集群:像应用的调度、更新、扩缩容等。
  • Node 就是具体干活的,一个Node一般是一个虚拟机或物理机,它上面事先运行着 docker 服务和 kubelet 服务( Kubernetes 的一个组件),当接收到 master 下发的”任务”后,Node 就要去完成任务(用 docker 运行一个指定的应用)

avatar

Deployment - 应用管理者

当我们拥有一个 Kubernetes 集群后,就可以在上面跑我们的应用了,前提是我们的应用必须支持在 docker 中运行,也就是我们要事先准备好docker镜像。

有了镜像之后,一般我们会通过Kubernetes的 Deployment 的配置文件去描述应用,比如应用叫什么名字、使用的镜像名字、要运行几个实例、需要多少的内存资源、cpu 资源等等。

有了配置文件就可以通过Kubernetes提供的命令行客户端 - kubectl 去管理这个应用了。kubectl 会跟 Kubernetes 的 master 通过RestAPI通信,最终完成应用的管理。
比如我们刚才配置好的 Deployment 配置文件叫 app.yaml,我们就可以通过

1
kubectl create -f app.yaml

来创建这个应用啦,之后就由 Kubernetes 来保证我们的应用处于运行状态,当某个实例运行失败了或者运行着应用的 Node 突然宕机了,Kubernetes 会自动发现并在新的 Node 上调度一个新的实例,保证我们的应用始终达到我们预期的结果。

avatar

Pod - Kubernetes最小调度单位

其实在上一步创建完 Deployment 之后,Kubernetes 的 Node 做的事情并不是简单的docker run 一个容器。出于像易用性、灵活性、稳定性等的考虑,Kubernetes 提出了一个叫做 Pod 的东西,作为 Kubernetes 的最小调度单位。所以我们的应用在每个 Node 上运行的其实是一个 Pod。Pod 也只能运行在 Node 上。

如下图:
avatar

那么什么是 Pod 呢?Pod 是一组容器(当然也可以只有一个)。容器本身就是一个小盒子了,Pod 相当于在容器上又包了一层小盒子。这个盒子里面的容器有什么特点呢?

  • 可以直接通过 volume 共享存储。
  • 有相同的网络空间,通俗点说就是有一样的ip地址,有一样的网卡和网络设置。
  • 多个容器之间可以“了解”对方,比如知道其他人的镜像,知道别人定义的端口等。

至于这样设计的好处呢,还是要大家深入学习后慢慢体会啦~
avatar

Service - 服务发现 - 找到每个Pod

上面的 Deployment 创建了,Pod 也运行起来了。如何才能访问到我们的应用呢?

最直接想到的方法就是直接通过 Pod-ip+port 去访问,但如果实例数很多呢?好,拿到所有的 Pod-ip 列表,配置到负载均衡器中,轮询访问。但上面我们说过,Pod 可能会死掉,甚至 Pod 所在的 Node 也可能宕机,Kubernetes 会自动帮我们重新创建新的Pod。再者每次更新服务的时候也会重建 Pod。而每个 Pod 都有自己的 ip。所以 Pod 的ip 是不稳定的,会经常变化的。

面对这种变化我们就要借助另一个概念:Service。它就是来专门解决这个问题的。不管Deployment的Pod有多少个,不管它是更新、销毁还是重建,Service总是能发现并维护好它的ip列表。

Service对外也提供了多种入口:

  1. ClusterIP:Service 在集群内的唯一 ip 地址,我们可以通过这个 ip,均衡的访问到后端的 Pod,而无须关心具体的 Pod。
  2. NodePort:Service 会在集群的每个 Node 上都启动一个端口,我们可以通过任意Node 的这个端口来访问到 Pod。
  3. LoadBalancer:在 NodePort 的基础上,借助公有云环境创建一个外部的负载均衡器,并将请求转发到 NodeIP:NodePort。
  4. ExternalName:将服务通过 DNS CNAME 记录方式转发到指定的域名(通过 spec.externlName 设定)。
    avatar

好,看似服务访问的问题解决了。

但大家有没有想过,Service是如何知道它负责哪些 Pod 呢?是如何跟踪这些 Pod 变化的?

最容易想到的方法是使用 Deployment 的名字。一个 Service 对应一个 Deployment 。当然这样确实可以实现。

但Kubernetes 使用了一个更加灵活、通用的设计 - Label 标签,通过给 Pod 打标签,Service 可以只负责一个 Deployment 的 Pod 也可以负责多个 Deployment 的 Pod 了。

Deployment 和 Service 就可以通过 Label 解耦了。
avatar

RollingUpdate - 滚动升级

滚动升级是Kubernetes中最典型的服务升级方案,主要思路是一边增加新版本应用的实例数,一边减少旧版本应用的实例数,直到新版本的实例数达到预期,旧版本的实例数减少为0,滚动升级结束。在整个升级过程中,服务一直处于可用状态。并且可以在任意时刻回滚到旧版本。

43

安装Docker

K8S是基于Docker的,所以我们要先安装Docker

https://www.psvmc.cn/article/2018-12-13-docker-install.html

安装K8S

  1. 配置/etc/hosts文件,将所有机器配置成通过主机名可以访问。
  2. 如果环境中有代理,请一定要在环境变量中将no_proxy配置正确。
  3. master还需要执行下面的命令

k8s.conf

1
2
3
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF

k8s.conf

1
2
3
4
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF

配置生效

1
sudo sysctl --system

Ubuntu

1
2
3
4
5
6
7
8
9
apt-get update && apt-get install -y apt-transport-https
curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF

sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

CentOS

kubernetes.repo

1
2
3
4
5
6
7
8
9
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

selinux

1
2
3
# 将 SELinux 设置为 permissive 模式(相当于将其禁用)
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

安装

1
2
yum install -y kubelet-1.20.4 kubeadm-1.20.4 kubectl-1.20.4
systemctl enable kubelet && systemctl start kubelet

查看

1
kubectl version --client

你需要在每台机器上安装以下的软件包:

  • kubelet:在集群中的每个节点上用来启动 Pod 和容器等。
  • kubectl:用来与集群通信的命令行工具。
  • kubeadm:用来初始化集群的指令。

部署方式

kubernetes 官方提供的三种部署方式

https://kubernetes.io/zh/docs/tasks/tools/

kind

kind 让你能够在本地计算机上运行 Kubernetes。 kind 要求你安装并配置好 Docker

部署文档:

minikube

Minikube是一个工具,可以在本地快速运行一个单点的Kubernetes,仅用于尝试Kubernetes或日常开发的用户使用。

部署文档:

kubeadm

Kubeadm也是一个工具,提供kubeadm init和kubeadm join,用于快速部署Kubernetes集群

部署文档:

总之

学习测试环境用kindminikube

生产环境用kubeadm