1 K8s
中文文档地址:https://kubernetes.io/zh-cn/docs/concepts/overview/components/
Kubernetes 也称为 K8s,是用于自动部署、扩缩和管理容器化应用程序的开源系统。
A Kubernetes cluster consists of 一组工作机器,称为 节点, 会运行容器化应用程序。每个集群至少有一个工作节点。
工作节点会托管 Pod ,而 Pod 就是作为应用负载的组件。 控制平面管理集群中的工作节点和 Pod。 在生产环境中,控制平面通常跨多台计算机运行, 一个集群通常运行多个节点,提供容错性和高可用性。
当你部署完 Kubernetes,便拥有了一个完整的集群。
一组工作机器,称为 节点, 会运行容器化应用程序。每个集群至少有一个工作节点。
工作节点会托管 Pod ,而 Pod 就是作为应用负载的组件。 控制平面管理集群中的工作节点和 Pod。 在生产环境中,控制平面通常跨多台计算机运行, 一个集群通常运行多个节点,提供容错性和高可用性。
本文档概述了一个正常运行的 Kubernetes 集群所需的各种组件。
2 控制平面组件(Control Plane Components)
控制平面组件会为集群做出全局决策,比如资源的调度。 以及检测和响应集群事件,例如当不满足部署的 replicas
字段时, 要启动新的 pod)。
控制平面组件可以在集群中的任何节点上运行。 然而,为了简单起见,设置脚本通常会在同一个计算机上启动所有控制平面组件, 并且不会在此计算机上运行用户容器。 请参阅使用 kubeadm 构建高可用性集群 中关于跨多机器控制平面设置的示例。
kube-apiserver 所有调度的总入口
API 服务器是 Kubernetes 控制平面的组件, 该组件负责公开了 Kubernetes API,负责处理接受请求的工作。 API 服务器是 Kubernetes 控制平面的前端。 类似于管理员中转站
Kubernetes API 服务器的主要实现是 kube-apiserver。 kube-apiserver
设计上考虑了水平扩缩,也就是说,它可通过部署多个实例来进行扩缩。 你可以运行 kube-apiserver
的多个实例,并在这些实例之间平衡流量。
etcd 数据存储
一致且高可用的键值存储,用作 Kubernetes 所有集群数据的后台数据库。类似于redis数据库
l如果你的 Kubernetes 集群使用 etcd 作为其后台数据库, 请确保你针对这些数据有一份 备份计划。
你可以在官方文档中找到有关 etcd 的深入知识。
kube-scheduler 监视节点
kube-scheduler
是控制平面的组件, 负责监视新创建的、未指定运行节点(node)的 Pods, 并选择节点来让 Pod 在上面运行。
调度决策考虑的因素包括单个 Pod 及 Pods 集合的资源需求、软硬件及策略约束、 亲和性及反亲和性规范、数据位置、工作负载间的干扰及最后时限。
kube-controller-manager 调度节点的控制进程
kube-controller-manager 是控制平面的组件, 负责运行控制器进程。
从逻辑上讲, 每个控制器都是一个单独的进程, 但是为了降低复杂性,它们都被编译到同一个可执行文件,并在同一个进程中运行。
这些控制器包括:
- 节点控制器(Node Controller):负责在节点出现故障时进行通知和响应
- 任务控制器(Job Controller):监测代表一次性任务的 Job 对象,然后创建 Pods 来运行这些任务直至完成
- 端点分片控制器(EndpointSlice controller):填充端点分片(EndpointSlice)对象(以提供 Service 和 Pod 之间的链接)。
- 服务账号控制器(ServiceAccount controller):为新的命名空间创建默认的服务账号(ServiceAccount)。
cloud-controller-manager 云平台的调度管理器
一个 Kubernetes 控制平面组件, 嵌入了特定于云平台的控制逻辑。 云控制器管理器(Cloud Controller Manager)允许你将你的集群连接到云提供商的 API 之上, 并将与该云平台交互的组件同与你的集群交互的组件分离开来。
cloud-controller-manager
仅运行特定于云平台的控制器。 因此如果你在自己的环境中运行 Kubernetes,或者在本地计算机中运行学习环境, 所部署的集群不需要有云控制器管理器。
与 kube-controller-manager
类似,cloud-controller-manager
将若干逻辑上独立的控制回路组合到同一个可执行文件中, 供你以同一进程的方式运行。 你可以对其执行水平扩容(运行不止一个副本)以提升性能或者增强容错能力。
下面的控制器都包含对云平台驱动的依赖:
- 节点控制器(Node Controller):用于在节点终止响应后检查云提供商以确定节点是否已被删除
- 路由控制器(Route Controller):用于在底层云基础架构中设置路由
- 服务控制器(Service Controller):用于创建、更新和删除云提供商负载均衡器
2 Node 组件
节点组件会在每个节点上运行,负责维护运行的 Pod 并提供 Kubernetes 运行环境。
kubelet 管理pod
kubelet
会在集群中每个节点(node)上运行。 它保证容器(containers)都运行在 Pod 中。
kubelet 接收一组通过各类机制提供给它的 PodSpecs, 确保这些 PodSpecs 中描述的容器处于运行状态且健康。 kubelet 不会管理不是由 Kubernetes 创建的容器。
kube-proxy 实现内外部网络的通讯
kube-proxy 是集群中每个节点(node)上所运行的网络代理, 实现 Kubernetes 服务(Service) 概念的一部分。
kube-proxy 维护节点上的一些网络规则, 这些网络规则会允许从集群内部或外部的网络会话与 Pod 进行网络通信。
如果操作系统提供了可用的数据包过滤层,则 kube-proxy 会通过它来实现网络规则。 否则,kube-proxy 仅做流量转发。
容器运行时(Container Runtime)
容器运行环境是负责运行容器的软件。
Kubernetes 支持许多容器运行环境,例如 containerd、 CRI-O 以及 Kubernetes CRI (容器运行环境接口) 的其他任何实现。
3 插件(Addons)
插件使用 Kubernetes 资源(DaemonSet、 Deployment 等)实现集群功能。 因为这些插件提供集群级别的功能,插件中命名空间域的资源属于 kube-system
命名空间。
下面描述众多插件中的几种。有关可用插件的完整列表,请参见 插件(Addons)。
DNS
尽管其他插件都并非严格意义上的必需组件,但几乎所有 Kubernetes 集群都应该有集群 DNS, 因为很多示例都需要 DNS 服务。
集群 DNS 是一个 DNS 服务器,和环境中的其他 DNS 服务器一起工作,它为 Kubernetes 服务提供 DNS 记录。
Kubernetes 启动的容器自动将此 DNS 服务器包含在其 DNS 搜索列表中。
Web 界面(仪表盘)
Dashboard 是 Kubernetes 集群的通用的、基于 Web 的用户界面。 它使用户可以管理集群中运行的应用程序以及集群本身, 并进行故障排除。
容器资源监控
容器资源监控 将关于容器的一些常见的时间序列度量值保存到一个集中的数据库中, 并提供浏览这些数据的界面。
集群层面日志
集群层面日志机制负责将容器的日志数据保存到一个集中的日志存储中, 这种集中日志存储提供搜索和浏览接口。
4 架构图
kubernets集群由多个节点组成,节点分为2类,
一类属于管理平面的主节点/控制节点(masterNode)
一类属于运行平面的工作节点(worker Node)
显然复杂的工作肯定交给控制节点来做,工作节点负责提供稳定的操作接口和能力抽象即可
5集群搭建
1 minikube
只是一个k8s的集群模拟器,只有一个节点的集群,只为测试用 master和worker 都在一起
2裸机安装
至少两台机器,(主节点和工作节点各一台),需要自动安装kubernetes组件,配置稍微麻烦点
缺点:配置复杂,缺少生态支持,例如负载均衡器,云存储
3直接使用云平台kubernetes
可视化搭建,只需几步就可以创建好一个集群
优点:安装简单,生态齐全,负载均衡器,存储等都配置好,简单操作即可搞定
5.1 minikube 搭建步骤
1使用docker 开启minikube
安装完成 在命令行中执行 kubectl get pods -A
5.2 裸机安装
1 环境准备
节点数量 3台虚拟机 使用contos7 下载地址:http://mirrors.163.com/centos/7.9.2009/isos/x86_64/
使用这个是正常使用:http://mirrors.163.com/centos/7.9.2009/isos/x86_64/CentOS-7-x86_64-DVD-2009.iso
硬件要求 2GRam 2核CPU 硬盘30G以上
网络要求 多个节点间网络互通 每个节点可以访问外网
vi /etc/sysconfig/network-scripts/ifcfg-ens33
TYPE="Ethernet"
PROXY_METHOD="none"
BROWSER_ONLY="no"
BOOTPROTO="static" #标记使用静态地址
DEFROUTE="yes"
IPV4_FAILURE_FATAL="no"
IPV6INIT="yes"
IPV6_AUTOCONF="yes"
IPV6_DEFROUTE="yes"
IPV6_FAILURE_FATAL="no"
IPV6_ADDR_GEN_MODE="stable-privacy"
NAME="ens33"
UUID="53a9629f-77f6-46cf-980f-791e80095a65"
DEVICE="ens33"
ONBOOT="yes"
IPADDR=192.168.107.135 #ip地址
NETMASK=255.255.255.0
GATEWAY=192.168.107.2
DNS1=8.8.8.8
DNS2=114.114.114.114
DNS3=192.168.107.2
PREFIX=24
2 集群规划
k8s-node1:192.168.107.129
k8s-node2:192.168.107.130
k8s-node3:192.168.107.131
3设置主机名
hostnamectl set-hostname k8s-node1
hostnamectl set-hostname k8s-node2
hostnamectl set-hostname k8s-node3
4同步hosts文件
如果DNS不支持主机名解析 需要每台机器的 /etc/host 文件中添加主机名和ip的对应关系
cat >> /etc/hosts <<EOF
192.168.107.129 k8s-node1
192.168.107.130 k8s-node2
192.168.107.131 k8s-node3
EOF
4关闭防火墙
systemctl stop firewalld && systemctl disable firewalld
5 更改时间同步
命令
yum install ntpdate -y
ntpdate time.windows.com
6 关闭swap分区
swapoff -a && sed -ri 's/.swap./#&/' /etc/fstab
7安装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
8 添加源
查看源
yum repolist
添加源 x86 不同的系统使用不同的源 我用的是CentOS-7-x86_64-DVD-2009 使用的是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/
9安装k8s
安装最新版本
yum install -y kubelet kubeadm kubectl
指定版本安装
yun install -y kubelet-1.26.0 kubectl-1..26.0 kubeadm-1.26.0
启动kubelet
sudo sysctmctl enable kubelet && sudo systemctl start kubelet && sudo systemctl status kubelet
如果启动失败使用以下命令试试
systemctl enable kubelet.service
10 初始化集
注意 初始化k8s集群 仅仅需要在master节点进行集群初始化
指定129地址的服务器为apiserver的服务器 pod的网络地址范围
kubeadm init \
--apiserver-advertise-address=192.168.107.129 \
--pod-network-cidr=192.168.0.0/16 \
--image-repository registry.aliyuncs.com/google_containers
执行成功结果显示
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy
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/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.107.129:6443 --token jyu6h9.qcsat7zv4i5zpd16 \
--discovery-token-ca-cert-hash sha256:1a8788dce63f4b8dae3256983d1ae300a7da9ac4b5188b1837a0b9bf17c5d943
安装成功后执行一下命令
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
将其他两个服务器加载到master上 分别在两个服务器上执行以下命令
kubeadm join 192.168.107.129:6443 --token jyu6h9.qcsat7zv4i5zpd16 \
--discovery-token-ca-cert-hash sha256:1a8788dce63f4b8dae3256983d1ae300a7da9ac4b5188b1837a0b9bf17c5d943
查看master是否加载成功
安装之后发现staus状态为notready pod节点有内容为pending状态
是因为网络没有互通需要配置集群网络
11 配置集群网络 网络组件部署 Calico
使用
wget https://docs.projectcalico.org/v3.19/manifests/calico.yaml
calico 要根据k8s版本下载
#### 2.5.10.2 修改文件
~~~powershell 将注释去掉
3683行 - name: CALICO_IPV4POOL_CIDR
3684行 value: "10.244.0.0/16"
~~~
~~~执行命令
kubectl apply -f calico.yaml
~~~
12 安装完成后显示结果为
---
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
- apiGroups:
- "networking.k8s.io"
resources:
- clustercidrs
verbs:
- list
- watch
---
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.2 #for ppc64le and mips64le (dockerhub limitations may apply)
image: docker.io/rancher/mirrored-flannelcni-flannel-cni-plugin:v1.1.2
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"
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
执行后查看安装状态
watch -n 1 -d kubectl get nodes
watch -n 1 -d kubectl get pods -A
安装网络失败时卸载
kubectl delete -f kube-flannel.yml