云原生|K8s系列第1篇:K8s的基础概念组件架构及实战安装

Posted 洲的学习笔记

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了云原生|K8s系列第1篇:K8s的基础概念组件架构及实战安装相关的知识,希望对你有一定的参考价值。

云原生|K8s系列第1篇目录

1、先从K8s不是什么讲起

首先,K8s并不是一个传统意义上的 PaaS平台即服务的工具,它充分给使用者提供了很多很多选择的空间。

  • 不限制支持的应用程序类型,K8s并不插手应用程序框架, 也不限制支持的语言 (如 Java, Python, Ruby 等),只要应用符合 12 因素即可。也就是说,只需要应用可以在容器中运行,那么它就可以很好的在 Kubernetes 上运行。
  • 不提供内置的中间件 (如消息中间件)、数据处理框架 (如 Spark)、数据库 (如 mysql) 或集群存储系统 (如 Ceph) 等。这些应用直接运行在 Kubernetes 之上。
  • 不直接部署代码,也不会构建您的应用程序,但是可以在 Kubernetes 之上构建需 要的持续集成 (CI) 工作流。
  • 不提供机器配置、维护、管理或自愈系统。
  • 不提供应用程序配置语言或系统。
  • 不提供点击即部署的服务市场。

K8s 不仅仅是一个 “编排系统”,它消除了编排的需要。K8s通过声明式的 API 和一系列独立、可组合的控制器保证了应用总是在期望的状态,用户并不需要关心中间状态是如何转换的。

2、K8s是什么及核心基础概念

K8s 是谷歌开源的容器集群管理系统,即一个大规模容器编排系统,是 Google 多年大规模容器管理技术 Borg 的开源版本。

可以用来完成以下一些主要功能:

  • 基于容器的应用部署、维护和滚动升级。
  • 负载均衡和服务发现:
  • 跨机器和跨地区的集群调度。
  • 自动伸缩。
  • 广泛的 Volume 支持。
  • 插件机制保证扩展性。

用户可以使用 Label 以自己的方式组织管理资源,还可以使用 Annotation 来自定义资源的描述信息,比如为管理工具提供状态检查等。控制器也是构建在跟开发人员和用户使用的相同的 API 之上。用户 还可以编写自己的控制器和调度器,也可以通过各种插件机制扩展系统的功能。这使得可以方便地在 K8s 之上构建各种应用系统。

2.1 Container容器

  • Container(容器)是一种便携式、轻量级的操作系统级虚拟化技术。

它使用 namespace 隔离不同的软件运行环境,并通过镜像自包含软件的运行环境,从而使得容器可以很方便的在任何地方运行。

容器体积小且启动快,可以在每个容器镜像中打包一个应用程序。这种一对一 的应用镜像关系拥有很多好处。使用容器,不需要与外部的基础架构环境绑定, 因为每一个应用程序都不需要外部依赖,不需要与外部的基础架构环境依赖,从而完美解决了开发到生产环境的一致性问题。

容器同样比虚拟机更加透明,这有助于监测和管理。容器进程的生命周期由基础设施管理,而不是被进程管理器隐藏在容器内部。每个应用程序用容器封装,管理容器部署就等同于管理应用程序部署。

2.2 Pod

  • Kubernetes 使用 Pod 来管理容器,每个 Pod 可以包含一个或多个紧密关联的容器。

Pod 是一组紧密关联的容器集合,它们共享 PID、IPC、Network 和 UTS namespace, 是 K8s调度的基本单位。Pod 内的多个容器共享网络和文件系统,可以通过进程间通信和文件共享这种简单高效的方式组合完成服务。

在 Kubernetes 中,所有对象都使用 manifest(yaml 或 json)来定义,比如一个简单的 nginx 服务可以定义为 nginx.yaml,它包含一个镜像为 nginx 的容器:

apiVersion: v1 
kind: Pod 
metadata: 
	name: nginx 
	labels: app: nginx 
spec: 
	containers: 
	- name: nginx 
	  image: nginx 
	  ports: 
	  - containerPort: 80

2.3 Node

  • Node 是 Pod 真正运行的主机,可以是物理机,也可以是虚拟机。每个 Node 节点上至少要运行 container
    runtime(比如 docker 或者 rkt)、 kubelet 和 kube-proxy 服务。

2.4 Label

  • Label 是识别 Kubernetes 对象的标签,以 key/value 的方式附加到对象上(key 最长不能超过 63 字节,value 可以为空,也可以是不超过 253 字节的字符串)。

Label 不提供唯一性,实际上经常是很多对象(如 Pods)都使用相同的 label 来标 志具体的应用。

Label 定义好后其他对象可以使用 Label Selector 来选择一组相同 label 的对象(比如 ReplicaSet 和 Service 用 label 来选择一组 Pod)

2.5 Annotations

Annotations 是 key/value 形式附加于对象的注解。不同于 Labels 用于标志和选择对象,Annotations 用来记录一些附加信息,用来辅助应用部署、安全策略以及调度策略等。

2.6 Service

Service 是应用服务的抽象,通过 labels 为应用提供负载均衡和服务发现。匹配 labels 的 Pod IP 和端口列表组成 endpoints,由 kube-proxy 负责将服务 IP 负载均衡到这些 endpoints 上。

每个 Service 都会自动分配一个 cluster IP(仅在集群内部可访问的虚拟地址)和 DNS 名,其他容器可以通过该地址或 DNS 来访问服务,不需要了解后端容器的运行。


3、K8s架构

3.1 K8s的工作方式

  • Kubernetes Cluster = N Master Node + N Worker Node:N主节点+N工作节点; N>=1

3.2 K8s的组件架构

3.2.1 控制平面组件

  • 控制平面组件-Control Plane Components:

控制平面的组件对集群做出全局决策(如调度等),以及检测和响应集群事件(例如,当不满足部署的 replicas 字段时,启动新的 pod)。控制平面组件可以在集群中的任何节点上运行。但为了简单起见,设置脚本通常会在同一个计算机上启动所有控制平面组件,并且不会在此计算机上运行用户容器。

kube-apiserver

  • API 服务器是 K8s 控制面的组件, 该组件公开了 Kubernetes API。 API 服务器是 Kubernetes 控制面的前端。Kubernetes API 服务器的主要实现是 kube-apiserver。 kube-apiserver 设计上考虑了水平伸缩,即它可通过部署多个实例进行伸缩。 可以运行 kube-apiserver 的多个实例,并且在这些实例之间平衡流量。

etcd

  • etcd 是兼具一致性和高可用性的键值数据库,可以作为保存 K8s 所有集群数据的后台数据库。通常etcd需要有备份计划。

kube-scheduler

  • kube-scheduler是控制平面组件,负责监视新创建的、未指定运行节点(node)的 Pods,选择节点让 Pod 在上面运行。

kube-controller-manager

  • kube-controller-manager是在主节点上运行 控制器 的组件。

从逻辑上讲,每个控制器都是一个单独的进程, 为了降低复杂性,它们都被编译到同一个可执行文件,并在一个进程中运行。这些控制器有:

节点控制器(Node Controller): 负责在节点出现故障时进行通知和响应。
任务控制器(Job controller): 监测代表一次性任务的 Job 对象,然后创建 Pods 来运行这些任务直至完成
端点控制器(Endpoints Controller): 填充端点(Endpoints)对象(即加入 Service 与 Pod)
服务帐户和令牌控制器(Service Account & Token Controllers): 为新的命名空间创建默认帐户和 API 访问令牌

cloud-controller-manager

  • 云控制器管理器是指嵌入特定云的控制逻辑的控制平面组件。 云控制器管理器允许链接集群到云提供商的应用编程接口中,并把和该云平台交互的组件与只和用户集群交互的组件分离开。

3.2.2 Node组件

节点组件在每个节点上运行,维护运行的 Pod 并提供 Kubernetes 运行环境

kubelet

  • 一个在集群中每个节点(node)上运行的代理。 它保证容器(containers)都 运行在 Pod 中。kubelet 接收一组通过各类机制提供给它的 PodSpecs,确保这些 PodSpecs 中描述的容器处于运行状态且健康。 kubelet 不会管理不是由 Kubernetes 创建的容器。

kube-proxy

  • kube-proxy 是集群中每个节点上运行的网络代理, 实现 Kubernetes 服务(Service) 概念的一部分。kube-proxy 维护节点上的网络规则。这些网络规则允许从集群内部或外部的网络会话与 Pod 进行网络通信。如果操作系统提供了数据包过滤层并可用的话,kube-proxy 会通过它来实现网络规则。否则, kube-proxy 仅转发流量本身。

K8s架构示意图

4、K8s创建集群

准备工作及注意事项:

  • 集群中的所有机器的网络彼此均能相互连接,公网和内网都可以。
  • 节点之中不可以有重复的主机名、MAC 地址或 product_uuid
  • 禁用交换分区。为了保证 kubelet 正常工作,需要禁用交换分区。

4.1 基础环境准备

#各个机器设置自己的域名
hostnamectl set-hostname xxxx

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

#关闭swap
swapoff -a  
sed -ri 's/.*swap.*/#&/' /etc/fstab

#允许 iptables 检查桥接流量
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF

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

4.2 安装kubelet、kubeadm、kubectl

cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
   http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
exclude=kubelet kubeadm kubectl
EOF

sudo yum install -y kubelet-1.20.9 kubeadm-1.20.9 kubectl-1.20.9 --disableexcludes=kubernetes

sudo systemctl enable --now kubelet

4.3 下载每个机器所需要的镜像

sudo tee ./images.sh <<-'EOF'
#!/bin/bash
images=(
kube-apiserver:v1.20.9
kube-proxy:v1.20.9
kube-controller-manager:v1.20.9
kube-scheduler:v1.20.9
coredns:1.7.0
etcd:3.4.13-0
pause:3.2
)
for imageName in $images[@] ; do
docker pull registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images/$imageName
done
EOF
   
chmod +x ./images.sh && ./images.sh

4.4 初始主节点

#所有机器添加master域名映射,以下需要修改为自己的域名映射
echo "172.xx.xx.xx  cluster-endpoint" >> /etc/hosts

#主节点初始化
kubeadm init \\
--apiserver-advertise-address=172.xx.xx.xx \\
--control-plane-endpoint=cluster-endpoint \\
--image-repository registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images \\
--kubernetes-version v1.20.9 \\
--service-cidr=10.96.0.0/16 \\
--pod-network-cidr=192.168.0.0/16

#所有网络范围不重叠
#查看集群所有节点
kubectl get nodes

#根据配置文件,给集群创建资源
kubectl apply -f xxxx.yaml

#查看集群部署了哪些应用?
docker ps   ===   kubectl get pods -A
# 运行中的应用在docker里面叫容器,在k8s里面叫Pod
kubectl get pods -A

master成功之后提示:

Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

Alternatively, if you are the root user, you can run:

  export KUBECONFIG=/etc/kubernetes/admin.conf

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

You can now join any number of control-plane nodes by copying certificate authorities
and service account keys on each node and then running the following as root:

  kubeadm join cluster-endpoint:6443 --token hums8f.vyx71prsg74ofce7 \\
    --discovery-token-ca-cert-hash sha256:a394d059dd51d68bb007a532a037d0a477131480ae95f75840c461e85e2c6ae3 \\
    --control-plane 

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join cluster-endpoint:6443 --token hums8f.vyx71prsg74ofce7 \\
    --discovery-token-ca-cert-hash sha256:a394d059dd51d68bb007a532a037d0a477131480ae95f75840c461e85e2c6ae3

接下来就通过上述命令,配置设置.kube/config。

4.5 安装网络组件

curl https://docs.projectcalico.org/manifests/calico.yaml -O

kubectl apply -f calico.yaml

4.6 加入node节点

kubeadm join cluster-endpoint:6443 --token x5g4uy.wpjjdbgra92s25pp \\
	--discovery-token-ca-cert-hash sha256:6255797916eaee52bf9dda9429db616fcd828436708345a308f4b917d3457a22

4.7 验证集群节点状态

  kubectl get nodes

以上是关于云原生|K8s系列第1篇:K8s的基础概念组件架构及实战安装的主要内容,如果未能解决你的问题,请参考以下文章

云原生 | Kubernetes篇深入Kubernetes(k8s)概念

云原生|K8s系列第3篇:实战Kubectl创建Deployment部署应用

云原生&k8s的架构及基本组件原理

[云原生专题-23]:K8S - Kubernetes(K8S)整体概述与组件架构通俗讲解

云原生Kubernetes系列第三篇二进制部署单节点Kubernetes(k8s)v1.20(不要因为别人都在交卷,自己就乱写答案)

云原生Kubernetes系列第五篇kubeadm v1.20 部署K8S 集群架构(人生这道选择题,总会有遗憾)