- 集群组件
- 核心概念
- 集群安装
1 集群组件
- 集群 cluster : 将同一个软件服务多个节点组织到一起共同为系统提供服务过程称之为该软件的集群。redis 集群、es集群、mongo 等。
- k8s 集群: 多个节点: 3 个节点 角色: 1.master 节点/control plane 控制节点 2. work node: 工作节点(pod 容器:应用程序容器)
当部署完 Kubernetes,便拥有了一个完整的集群。一组工作机器,称为节点, 会运行容器化应用程序。每个集群至少有一个工作节点
。工作节点会托管 Pod
,而 Pod 就是作为应用负载的组件。 控制平面管理集群中的工作节点和 Pod
。
1.1 控制平面组件(Control Plane Components)
控制平面组件会为集群做出全局决策,比如资源的调度。 以及检测和响应集群事件,例如当不满足部署的 replicas 字段时, 要启动新的 pod
)。
控制平面组件可以在集群中的任何节点上运行。 然而,为了简单起见,设置脚本通常会在同一个计算机上启动所有控制平面组件, 并且不会在此计算机上运行用户容器。
- kube-apiserver
API server是 Kubernetes 控制平面的组件,该组件负责公开了 Kubernetes API,负责处理接受请求的工作
。 API server 是 Kubernetes 控制平面的前端。Kubernetes API 服务器的主要实现是 kube-apiserver。kube-apiserver
设计上考虑了水平扩缩,也就是说,它可通过部署多个实例来进行扩缩。 你可以运行kube-apiserver
的多个实例,并在这些实例之间平衡流量。 - etcd
一致且高度可用的键值存储,用作 Kubernetes 的所有集群数据的后台数据库
。 - kube-scheduler
kube-scheduler
是控制平面的组件, 负责监视新创建的、未指定运行节点 node 的 Pods, 并选择节点来让 Pod 在上面运行。调度决策考虑的因素包括单个 Pod 及 Pods 集合的资源需求、软硬件及策略约束、 亲和性及反亲和性规范、数据位置、工作负载间的干扰及最后时限。 - kube-controller-managerkube-controller-manager 是控制平面的组件, 负责运行控制器进程。从逻辑上讲, 每个控制器都是一个单独的进程, 但是为了降低复杂性,它们都被编译到同一个可执行文件,并在同一个进程中运行。这些控制器包括:
- 节点控制器(Node Controller):负责在节点出现故障时进行通知和响应
- 任务控制器(Job Controller):监测代表一次性任务的 Job 对象,然后创建 Pods 来运行这些任务直至完成
- 端点分片控制器(EndpointSlice controller):填充端点分片(EndpointSlice)对象(以提供 Service 和 Pod 之间的链接)。
- 服务账号控制器(ServiceAccount controller):为新的命名空间创建默认的服务账号(ServiceAccount)。
- cloud-controller-manager(optional 可选)一个 Kubernetes 控制平面组件, 嵌入了特定于云平台的控制逻辑。 云控制器管理器(Cloud Controller Manager)允许你将你的集群连接到云提供商的 API 之上, 并将与该云平台交互的组件同与你的集群交互的组件分离开来。
cloud-controller-manager
仅运行特定于云平台的控制器。 因此如果你在自己的环境中运行 Kubernetes,或者在本地计算机中运行学习环境, 所部署的集群不需要有云控制器管理器。与kube-controller-manager
类似,cloud-controller-manager
将若干逻辑上独立的控制回路组合到同一个可执行文件中, 供你以同一进程的方式运行。 你可以对其执行水平扩容(运行不止一个副本)以提升性能或者增强容错能力。下面的控制器都包含对云平台驱动的依赖:
- 节点控制器(Node Controller):用于在节点终止响应后检查云提供商以确定节点是否已被删除
- 路由控制器(Route Controller):用于在底层云基础架构中设置路由
- 服务控制器(Service Controller):用于创建、更新和删除云提供商负载均衡器
1.2 Node 组件
节点组件会在每个节点上运行,负责维护运行的 Pod 并提供 Kubernetes 运行环境。
- kubelet
kubelet 会在集群中每个节点(node)上运行。 它保证容器(containers)都运行在 Pods 中。
kubelet 接收一组通过各类机制提供给它的 PodSpecs, 确保这些 PodSpecs 中描述的容器处于运行状态且健康。 kubelet 不会管理不是由 Kubernetes 创建的容器。 - kube-proxy
kube-proxy是集群中每个节点(node)上所运行的网络代理, 实现 Kubernetes 服务(Service)概念的一部分。
kube-proxy 维护节点上的一些网络规则, 这些网络规则会允许从集群内部或外部的网络会话与 Pod 进行网络通信。
如果操作系统提供了可用的数据包过滤层,则 kube-proxy 会通过它来实现网络规则。 否则,kube-proxy 仅做流量转发。 - 容器运行时(Container Runtime)
容器运行环境是负责运行容器的软件。
Kubernetes 支持许多容器运行环境,例如 containerd、 CRI-0、Docker 以及 Kubernetes CRI 的其他任何实现。
1.3 插件 (Addons)
- DNS
尽管其他插件都并非严格意义上的必需组件,但几乎所有 Kubernetes 集群都应该有集群 DNS因为很多示例都需要 DNS 服务。 - Web 界面(仪表盘)
Dashboard 是 Kubernetes 集群的通用的、基于 Web 的用户界面。 它使用户可以管理集群中运行的应用程序以及集群本身, 并进行故障排除。 - 容器资源监控
容器资源监控将关于容器的一些常见的时间序列度量值保存到一个集中的数据库中, 并提供浏览这些数据的界面。 - 集群层面日志
集群层面日志机制负责将容器的日志数据保存到一个集中的日志存储中, 这种集中日志存储提供搜索和浏览接口。
2 集群架构详细
- 总结
- Kubernetes 集群由多个节点组成,节点分为两类:一类是属于管理平面的主节点/控制节点(Master Node);一类是属于运行平面的工作节点(Worker Node)。显然,复杂的工作肯定都交给控制节点去做了,工作节点负责提供稳定的操作接口和能力抽象即可。
3 集群搭建[重点]
- minikube 只是一个 K8S 集群模拟器,只有一个节点的集群,只为测试用,master 和 worker 都在一起。
- 裸机安装 至少需要两台机器(主节点、工作节点个一台),需要自己安装 Kubernetes 组件,配置会稍微麻烦点。 缺点:配置麻烦,缺少生态支持,例如负载均衡器、云存储。
- 直接用云平台 Kubernetes 可视化搭建,只需简单几步就可以创建好一个集群。 优点:安装简单,生态齐全,负载均衡器、存储等都给你配套好,简单操作就搞定
- k3s
安装简单,脚本自动完成。
优点:轻量级,配置要求低,安装简单,生态齐全。
3.1 minikube
3.2 裸机安装
0 环境准备
- 节点数量: 3 台虚拟机 centos7
- 硬件配置: 2G或更多的RAM,2个CPU或更多的CPU,硬盘至少30G 以上
- 网络要求: 多个节点之间网络互通,每个节点能访问外网
1 集群规划
- k8s-node1:10.15.0.5
- k8s-node2:10.15.0.6
- k8s-node3:10.15.0.7
2 设置主机名
$ hostnamectl set-hostname k8s-node1 $ hostnamectl set-hostname k8s-node2 $ hostnamectl set-hostname k8s-node3
3 同步 hosts 文件
如果 DNS 不支持主机名称解析,还需要在每台机器的
/etc/hosts
文件中添加主机名和 IP 的对应关系:
cat >> /etc/hosts <<EOF 192.168.2.4 k8s-node1 192.168.2.5 k8s-node2 192.168.2.6 k8s-node3 EOF
4 关闭防火墙
$ systemctl stop firewalld && systemctl disable firewalld
5 关闭 SELINUX
注意: ARM 架构请勿执行,执行会出现 ip 无法获取问题!
$ setenforce 0 && sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
6 关闭 swap 分区
$ swapoff -a && sed -ri 's/.*swap.*/#&/' /etc/fstab
7 同步时间
$ yum install ntpdate -y $ ntpdate time.windows.com
8 安装 containerd
# 安装 yum-config-manager 相关依赖 $ yum install -y yum-utils device-mapper-persistent-data lvm2 # 添加 containerd yum 源 $ yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # 安装 containerd $ yum install -y containerd.io cri-tools # 配置 containerd $ cat > /etc/containerd/config.toml <<EOF disabled_plugins = ["restart"] [plugins.linux] shim_debug = true [plugins.cri.registry.mirrors."docker.io"] endpoint = ["https://frz7i079.mirror.aliyuncs.com"] [plugins.cri] sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.2" EOF # 启动 containerd 服务 并 开机配置自启动 $ systemctl enable containerd && systemctl start containerd && systemctl status containerd # 配置 containerd 配置 $ cat > /etc/modules-load.d/containerd.conf <<EOF overlay br_netfilter EOF # 配置 k8s 网络配置 $ cat > /etc/sysctl.d/k8s.conf <<EOF net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 net.ipv4.ip_forward = 1 EOF # 加载 overlay br_netfilter 模块 modprobe overlay modprobe br_netfilter # 查看当前配置是否生效 $ sysctl -p /etc/sysctl.d/k8s.conf
9 添加源
- 查看源
$ yum repolist
- 添加源 x86
$ cat <<EOF > kubernetes.repo [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 $ mv kubernetes.repo /etc/yum.repos.d/
- 添加源 ARM
$ cat << EOF > kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-aarch64 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 $ mv kubernetes.repo /etc/yum.repos.d/
11 安装 k8s
# 安装最新版本 $ yum install -y kubelet kubeadm kubectl # 指定版本安装 # yum install -y kubelet-1.26.0 kubectl-1.26.0 kubeadm-1.26.0 # 启动 kubelet $ sudo systemctl enable kubelet && sudo systemctl start kubelet && sudo systemctl status kubelet
12 初始化集群
注意: 初始化 k8s 集群仅仅需要再在 master 节点进行集群初始化!
$ kubeadm init \ --apiserver-advertise-address=本机masterIP地址 \ --pod-network-cidr=10.244.0.0/16 \ --image-repository registry.aliyuncs.com/google_containers \ --cri-socket=unix:///var/run/containerd/containerd.sock # 添加新节点 $ kubeadm token create --print-join-command --ttl=0 $ kubeadm join 10.15.0.21:6443 --token xjm7ts.gu3ojvta6se26q8i --discovery-token-ca-cert-hash sha256:14c8ac5c04ff9dda389e7c6c505728ac1293c6aed5978c3ea9c6953d4a79ed34
13 配置集群网络
创建配置: kube-flannel.yml ,执行 kubectl apply -f kube-flannel.yml
注意: 只在主节点执行即可!
--- kind: Namespace apiVersion: v1 metadata: name: kube-flannel labels: pod-security.kubernetes.io/enforce: privileged --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: flannel rules: - apiGroups: - "" resources: - pods verbs: - get - apiGroups: - "" resources: - nodes verbs: - get - list - watch - apiGroups: - "" resources: - nodes/status verbs: - patch --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: flannel roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: flannel subjects: - kind: ServiceAccount name: flannel namespace: kube-flannel --- apiVersion: v1 kind: ServiceAccount metadata: name: flannel namespace: kube-flannel --- kind: ConfigMap apiVersion: v1 metadata: name: kube-flannel-cfg namespace: kube-flannel labels: tier: node app: flannel data: cni-conf.json: | { "name": "cbr0", "cniVersion": "0.3.1", "plugins": [ { "type": "flannel", "delegate": { "hairpinMode": true, "isDefaultGateway": true } }, { "type": "portmap", "capabilities": { "portMappings": true } } ] } net-conf.json: | { "Network": "10.244.0.0/16", "Backend": { "Type": "vxlan" } } --- apiVersion: apps/v1 kind: DaemonSet metadata: name: kube-flannel-ds namespace: kube-flannel labels: tier: node app: flannel spec: selector: matchLabels: app: flannel template: metadata: labels: tier: node app: flannel spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/os operator: In values: - linux hostNetwork: true priorityClassName: system-node-critical tolerations: - operator: Exists effect: NoSchedule serviceAccountName: flannel initContainers: - name: install-cni-plugin #image: flannelcni/flannel-cni-plugin:v1.1.0 for ppc64le and mips64le (dockerhub limitations may apply) image: docker.io/rancher/mirrored-flannelcni-flannel-cni-plugin:v1.1.0 command: - cp args: - -f - /flannel - /opt/cni/bin/flannel volumeMounts: - name: cni-plugin mountPath: /opt/cni/bin - name: install-cni #image: flannelcni/flannel:v0.20.2 for ppc64le and mips64le (dockerhub limitations may apply) image: docker.io/rancher/mirrored-flannelcni-flannel:v0.20.2 command: - cp args: - -f - /etc/kube-flannel/cni-conf.json - /etc/cni/net.d/10-flannel.conflist volumeMounts: - name: cni mountPath: /etc/cni/net.d - name: flannel-cfg mountPath: /etc/kube-flannel/ containers: - name: kube-flannel #image: flannelcni/flannel:v0.20.2 for ppc64le and mips64le (dockerhub limitations may apply) image: docker.io/rancher/mirrored-flannelcni-flannel:v0.20.2 command: - /opt/bin/flanneld args: - --ip-masq - --kube-subnet-mgr resources: requests: cpu: "100m" memory: "50Mi" limits: cpu: "100m" memory: "50Mi" securityContext: privileged: false capabilities: add: ["NET_ADMIN", "NET_RAW"] env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: EVENT_QUEUE_DEPTH value: "5000" volumeMounts: - name: run mountPath: /run/flannel - name: flannel-cfg mountPath: /etc/kube-flannel/ - name: xtables-lock mountPath: /run/xtables.lock volumes: - name: run hostPath: path: /run/flannel - name: cni-plugin hostPath: path: /opt/cni/bin - name: cni hostPath: path: /etc/cni/net.d - name: flannel-cfg configMap: name: kube-flannel-cfg - name: xtables-lock hostPath: path: /run/xtables.lock type: FileOrCreate
14 查看集群状态
# 查看集群节点状态 全部为 Ready 代表集群搭建成功
$ kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-node1 Ready control-plane 21h v1.26.0 k8s-node2 Ready <none> 21h v1.26.0 k8s-node3 Ready <none> 21h v1.26.0
# 查看集群系统 pod 运行情况,下面所有 pod 状态为 Running 代表集群可用
$ kubectl get pod -A NAMESPACE NAME READY STATUS RESTARTS AGE default nginx 1/1 Running 0 21h kube-flannel kube-flannel-ds-gtq49 1/1 Running 0 21h kube-flannel kube-flannel-ds-qpdl6 1/1 Running 0 21h kube-flannel kube-flannel-ds-ttxjb 1/1 Running 0 21h kube-system coredns-5bbd96d687-p7q2x 1/1 Running 0 21h kube-system coredns-5bbd96d687-rzcnz 1/1 Running 0 21h kube-system etcd-k8s-node1 1/1 Running 0 21h kube-system kube-apiserver-k8s-node1 1/1 Running 0 21h kube-system kube-controller-manager-k8s-node1 1/1 Running 0 21h kube-system kube-proxy-mtsbp 1/1 Running 0 21h kube-system kube-proxy-v2jfs 1/1 Running 0 21h kube-system kube-proxy-x6vhn 1/1 Running 0 21h kube-system kube-scheduler-k8s-node1 1/1 Running 0 21h