Kubernetes 最初源于谷歌内部的Borg,Kubernetes 是一个全新的基于容器技术的分布式架构解决方案。
包含几个基本功能:
1.将应用水平扩容到多个集群
2.为扩容的实例提供负载均衡策略
3.提供基本的健康检查和自愈能力
4.实现任务的统一调度
- 2014年6月 谷歌云计算专家Eric Brewer在旧金山的发布会为这款新的开源工具揭牌。
- 2015年7月22日K8S迭代到 v 1.0并在OSCON大会上正式对外公布。
- 为了建立容器编排领域的标准和规范,Google、RedHat 等开源基础设施领域玩家们,在 2015 年共同牵头发起了名为 CNCF(Cloud Native Computing Foundation)的基金会。Kubernetes 成为 CNCF 最核心的项目。发起成员:AT&T, Box, Cisco, Cloud Foundry Foundation, CoreOS, Cycle Computing, Docker, eBay, Goldman Sachs, Google, Huawei, IBM, Intel, Joyent, Kismatic, Mesosphere, Red Hat, Switch SUPERNAP, Twitter, Univa, VMware and Weaveworks。
- 2018年,超过 1700 开发者成为 Kubernetes 项目社区贡献者,全球有 500 多场沙龙。国内出现大量基于 Kubernetes 的创业公司。
- 2020 年,Kubernetes 项目已经成为贡献者仅次于 Linux 项目的第二大开源项目。成为了业界容器编排的事实标准,各大厂商纷纷宣布支持 Kubernetes 作为容器编排的方案。
容器技术虽然解决了应用和基础设施异构的问题,让应用可以做到一次构建,多次部署,但在复杂的微服务场景,单靠 Docker 技术还不够,它仍然有以下问题没有解决:
- 集成和编排微服务模块
- 提供按需自动扩容,缩容能力
- 故障自愈
- 集群内的通信
- 按需的垂直扩容,新的服务器(node)能够轻易的增加或删除
- 按需的水平扩容,容器实例能够轻松扩容,缩容
- 副本控制器,你不用担心副本的状态
- 服务发现和路由
- 自动部署和回滚,如果应用状态错误,可以实现自动回滚
- 当你的应用是微服务架构
- 开发者需要快速部署自己的新功能到测试环境进行验证
- 降低硬件资源成本,提高使用率
- 应用是轻量级的单体应用,没有高并发的需求
- 团队文化不适应变革
主控制节点组件对集群做出全局决策(比如调度),以及检测和响应集群事件(例如,当不满足部署的 replicas 字段时,启动新的 pod)。
主控制节点组件可以在集群中的任何节点上运行。 然而,为了简单起见,设置脚本通常会在同一个计算机上启动所有主控制节点组件,并且不会在此计算机上运行用户容器。
主节点上负责提供 Kubernetes API 服务的组件;它是 Kubernetes 控制面的前端组件。
etcd 是兼具一致性和高可用性的键值数据库,可以作为保存 Kubernetes 所有集群数据的后台数据库。
主节点上的组件,该组件监视那些新创建的未指定运行节点的 Pod,并选择节点让 Pod 在上面运行。
调度决策考虑的因素包括单个 Pod 和 Pod 集合的资源需求、硬件/软件/策略约束、亲和性和反亲和性规范、数据位置、工作负载间的干扰和最后时限。
在主节点上运行控制器的组件。
从逻辑上讲,每个控制器都是一个单独的进程,但是为了降低复杂性,它们都被编译到同一个可执行文件,并在一个进程中运行。这些控制器包括:
1. 节点控制器(Node Controller): 负责在节点出现故障时进行通知和响应。
3. 副本控制器(Replication Controller): 负责为系统中的每个副本控制器对象维护正确数量的 Pod。
3. 终端控制器(Endpoints Controller): 填充终端(Endpoints)对象(即加入 Service 与 Pod)。
4. 服务帐户和令牌控制器(Service Account & Token Controllers),为新的命名空间创建默认帐户和 API 访问令牌.
从节点组件在每个节点上运行,维护运行的 Pod 并提供 Kubernetes 运行环境。
在集群中每个节点上运行的代理。它保证容器都运行在 Pod 中。
kubelet 接收一组通过各类机制提供给它的 PodSpecs,确保这些 PodSpecs 中描述的容器处于运行状态且健康。kubelet 不会管理不是由 Kubernetes 创建的容器。
kube-proxy 是集群中每个节点上运行的网络代理,实现 Kubernetes Service 概念的一部分。
kube-proxy 维护节点上的网络规则。这些网络规则允许从集群内部或外部的网络会话与 Pod 进行网络通信。
容器运行环境是负责运行容器的软件。
Kubernetes 支持多个容器运行环境: Docker、 containerd、cri-o、 rktlet 以及任何实现 Kubernetes CRI (容器运行环境接口)。
尽管其他插件都并非严格意义上的必需组件,但几乎所有 Kubernetes 集群都应该有集群 DNS, 因为很多示例都需要 DNS 服务。
Dashboard 是K ubernetes 集群的通用的、基于 Web 的用户界面。 它使用户可以管理集群中运行的应用程序以及集群本身并进行故障排除。
容器资源监控 将关于容器的一些常见的时间序列度量值保存到一个集中的数据库中,并提供用于浏览这些数据的界面。
集群层面日志 机制负责将容器的日志数据 保存到一个集中的日志存储中,该存储能够提供搜索和浏览接口。
1、Pod
Pod 是 K8S 中最重要也是最基本的概念,Pod 是最小的部署单元,是一组容器的集合。每个 Pod 都由一个特殊的根容器 Pause 容器,以及一个或多个紧密相关的用户业务容器组成。
Pause 容器作为 Pod 的根容器,以它的状态代表整个容器组的状态。K8S 为每个 Pod 都分配了唯一的 IP 地址,称之为 Pod IP。Pod 里的多个业务容器共享 Pause 容器的IP,共享 Pause 容器挂载的 Volume。
2、Label
标签,附加到某个资源上,用于关联对象、查询和筛选。一个 Label 是一个 key=value 的键值对,key 与 value 由用户自己指定。Label 可以附加到各种资源上,一个资源对象可以定义任意数量的 Label,同一个 Label 也可以被添加到任意数量的资源上。
我们可以通过给指定的资源对象捆绑一个或多个不同的 Label 来实现多维度的资源分组管理功能,以便于灵活、方便地进行资源分配、调度、配置、部署等工作。
K8S 通过 Label Selector(标签选择器)来查询和筛选拥有某些 Label 的资源对象。Label Selector 有基于等式( name=label1 )和基于集合( name in (label1, label2) )的两种方式。
3、ReplicaSet(RC)
ReplicaSet 用来确保预期的 Pod 副本数量,如果有过多的 Pod 副本在运行,系统就会停掉一些 Pod,否则系统就会再自动创建一些 Pod。
我们很少单独使用 ReplicaSet,它主要被 Deployment 这个更高层的资源对象使用,从而形成一整套 Pod 创建、删除、更新的编排机制。
4、Deployment
Deployment 用于部署无状态应用,Deployment 为 Pod 和 ReplicaSet 提供声明式更新,只需要在 Deployment 描述想要的目标状态,Deployment 就会将 Pod 和 ReplicaSet 的实际状态改变到目标状态。
5、Horizontal Pod Autoscaler(HPA)
HPA 为 Pod 横向自动扩容,也是 K8S 的一种资源对象。HPA 通过追踪分析 RC 的所有目标 Pod 的负载变化情况,来确定是否需要针对性调整目标 Pod 的副本数量。
6、Service
Service 定义了一个服务的访问入口,通过 Label Selector 与 Pod 副本集群之间“无缝对接”,定义了一组 Pod 的访问策略,防止 Pod 失联。
创建 Service 时,K8S会自动为它分配一个全局唯一的虚拟 IP 地址,即 Cluster IP。服务发现就是通过 Service 的 Name 和 Service 的 ClusterIP 地址做一个 DNS 域名映射来解决的。
7、Namespace
命名空间,Namespace 多用于实现多租户的资源隔离。Namespace 通过将集群内部的资源对象“分配”到不同的Namespace中,形成逻辑上分组的不同项目、小组或用户组。
K8S 集群在启动后,会创建一个名为 default 的 Namespace,如果不特别指明 Namespace,创建的 Pod、RC、Service 都将被创建到 default 下。
当我们给每个租户创建一个 Namespace 来实现多租户的资源隔离时,还可以结合 K8S 的资源配额管理,限定不同租户能占用的资源,例如 CPU 使用量、内存使用量等。
ip | 域名 | 备注 | 安装软件 |
192.168.70.80 | master | 主节点 | Docker Kubeadm kubelet kubectl flannel |
192.168.70.81 | node1 | 从节点1 | Docker Kubeadm kubelet kubectl |
192.168.70.82 | node2 | 从节点2 | Docker Kubeadm kubelet kubectl |
操作系统设置
- #配置内核参数,将桥接的IPv4流量传递到iptables的链
- [root@master01 ~]# cat > /etc/sysctl.d/k8s.conf <
- net.bridge.bridge-nf-call-ip6tables = 1
- net.bridge.bridge-nf-call-iptables = 1
- EOF
-
- #将桥接的ipv4流量传递到iptables的链
- modprobe br_netfilter
- echo "1" >/proc/sys/net/bridge/bridge-nf-call-iptables
- vi /etc/sysctl.d/k8s.conf
- net.bridge.bridge-nf-call-iptables = 1
- net.bridge.bridge-nf-call-ip6tables = 1
-
- #关闭防火墙
- systemctl stop firewalld
- systemctl disable firewalld
-
- #关闭 selinux
- #临时生效
- setenforce 0
- #永久生效
- sed -i 's/enforcing/disabled/' /etc/selinux/config
-
- #关闭 swap
- #临时关闭
- swapoff -a
- # 永久生效
- vim /etc/fstab
- #将 [UUID=5b59fd54-eaad-41d6-90b2-ce28ac65dd81 swap swap defaults 0 0] 这一行注释掉
-
- #配置 Master 和 work 节点的域名
- vim /etc/hosts
- 192.168.70.80 master
- 192.168.70.81 node1
- 192.168.70.82 node2
-
- #同步系统时间
- ntpdate 0.asia.pool.ntp.org
-
阿里云yum源
- rm -f /etc/yum.repos.d/*
- wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
安装Docker
- 1. 添加依赖
- yum install -y yum-utils device-mapper-persistent-data lvm2
-
- 2. 设置yum源
- yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
-
- 3. 查看仓库中所有Docker版本
- yum list docker-ce --showduplicates | sort -r
-
- 4. 安装Docker
- yum -y install docker-ce
-
- 5. 启动并加入开机启动
- systemctl start docker
- systemctl enable docker
-
- 6.配置docker仓库源
- cat > /etc/docker/daemon.json << EOF
- {
- "exec-opts": ["native.cgroupdriver=systemd"],
- "log-driver": "json-file",
- "log-opts": {
- "max-size": "100m"
- },
- "storage-driver": "overlay2"
- }
- EOF
-
- systemctl restart docker
配置Docker, K8S的阿里云yum源
- 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
-
-
- systemctl daemon-reload
- systemctl enable docker
- systemctl restart docker
安装kubelet、kubeadm、kubectl
yum install -y kubelet-1.23.1 kubeadm-1.23.1 kubectl-1.23.1 --disableexcludes=kubernetes
重启 docker,并启动 kubelet
systemctl enable kubelet && systemctl start kubelet
- kubeadm init \
- --apiserver-advertise-address=179.220.56.230 \
- --image-repository registry.aliyuncs.com/google_containers \
- --kubernetes-version v1.23.1 \
- --service-cidr=10.96.0.0/12 \
- --pod-network-cidr=10.244.0.0/16 \
- --ignore-preflight-errors=all
master节点打印token信息
- [root@master kubernetes]# kubeadm token create --print-join-command
- kubeadm join 171.210.51.235:6443 --token 2lwlhg.p1af6oxfeppnfa1i --discovery-token-ca-cert-hash sha256:76e69800d4b85fbc6166d3c0e2724e5f03e83eae2458fe29a18e846a9f385b5e
新节点加入k8s集群
- [root@node2 ~]# kubeadm join 119.221.51.231:6443 --token 2lwlhg.p1af6oxfeppnfa1i --discovery-token-ca-cert-hash sha256:76e69800d4b85fbc6166d3c0e2724e5f03e83eae2458fe29a18e846a9f385b5e
- [preflight] Running pre-flight checks
- [preflight] Reading configuration from the cluster...
- [preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
- [kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
- [kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
- [kubelet-start] Starting the kubelet
- [kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...
-
- This node has joined the cluster:
- * Certificate signing request was sent to apiserver and a response was received.
- * The Kubelet was informed of the new secure connection details.
-
- Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
查看节点状态
- [root@master kubernetes]# kubectl get node
- NAME STATUS ROLES AGE VERSION
- master Ready control-plane,master 32m v1.23.1
- node1 Ready <none> 24m v1.23.1
- node2 Ready <none> 41s v1.23.1
- [root@master kubernetes]#