在写这篇文章的时候使用的 k8s 版本为 1.27.1
基础知识 Kubernetes 集群资源类型 一个 Kubernetes 集群包含两种类型的资源:
Master: 负责管理整个集群。 Master 协调集群中的所有活动,例如调度应用、维护应用的所需状态、应用扩容以及推出新的更新。
Node: 是一个虚拟机或者物理机,它在 Kubernetes 集群中充当工作机器的角色 每个Node都有 Kubelet , 它管理 Node 而且是 Node 与 Master 通信的代理。
基础工具
kubectl : kubectl是Kubernetes的命令行工具,用于管理Kubernetes集群中的应用程序、服务、部署、状态等。
kubelet 负责管理每个节点上的容器,监视运行在节点上的容器的状态,以及与master节点上的其它组件进行通信,如kube-apiserver和kube-proxy,以确保节点上的容器处于期望的状态,kubelet还会从etcd中获取Pod的信息,并执行Pod的调度和容器的启动、停止、重启等操作。需要运行在每个节点上
kubeadm : 用于创建和部署 Kubernetes 集群。
kubeadm 可以用于安装 Kubernetes 集群的主节点(master)和工作节点(worker)。它可以执行以下任务:
初始化 Kubernetes 主节点并生成必要的证书和密钥。
部署 Kubernetes 控制平面组件,如 API Server、Controller Manager、Scheduler 等。
添加工作节点到 Kubernetes 集群中。
部署网络插件、存储插件等 Kubernetes 插件。
使用 kubeadm 创建的 Kubernetes 集群与手动安装的集群相比具有以下优势:
它是快速且一致的,因为所有的组件都是通过相同的工具和流程安装的。
它是可重复的,因为在不同环境中使用相同的命令和配置文件可以创建相同的集群。
它可以方便地进行升级和维护。
cgroup 驱动 在 Linux 上,控制组(CGroup) 用于限制分配给进程的资源。
kubelet 和 容器运行时 都需要对接 CGroup 来强制执行 为 Pod 和容器管理资源 并为诸如 CPU、内存这类资源设置请求和限制。若要对接控制组,kubelet 和容器运行时需要使用一个 cgroup 驱动 。 关键的一点是 kubelet 和容器运行时需使用相同的 cgroup 驱动并且采用相同的配置。
kubelet 和底层容器运行时需要与控制组对接,以强制执行 Pod 和容器的资源管理,并设置诸如 CPU/内存请求和限制资源等。为了与控制组对接,kubelet 和容器运行时需要使用 cgroup 驱动。关键的一点是 kubelet 和容器运行时需要使用相同的 cgroup 驱动。
可用的 cgroup 驱动有两个:
cgroupfs 驱动 略
systemd cgroup 驱动 大部分的 Linux 发行版(Debian系 ReaHat系)都默认使用 systemd cgroup 驱动,当使用 systemd 作为其初始化系统时,初始化进程会生成并使用一个 root 控制组(cgroup),并充当 cgroup 管理器。
systemd 与 cgroup 集成紧密,并将为每个 systemd 单元分配一个 cgroup。 如果 systemd 用作初始化系统,同时使用 cgroupfs 驱动,则系统中会存在两个不同的 cgroup 管理器,这样就会产生一些问题,所以最好使用一个 cgroup 驱动。
安装 k8s 并使用 kubeadm 引导创建集群 安装 k8s 基础工具 1. 更新软件列表,安装需要的依赖包
1 2 sudo apt-get update sudo apt-get install -y ca-certificates curl
2. 安装 kubeadm
在这里我们使用k8s清华源 来进行安装
1 2 3 4 5 # 信任 k8s 的 GPG 公钥 sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg # 添加 Kubernetes apt 仓库 echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://mirrors.tuna.tsinghua.edu.cn/kubernetes/apt kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
3. 再次更新软件列表,安装 kubelet kubeadm kubectl
1 2 3 4 sudo apt-get update sudo apt-get install -y kubelet kubeadm kubectl # 锁定版本 sudo apt-mark hold kubelet kubeadm kubectl
安装容器运行时 k8s 需要一款容器运行时作为其运行的基础,从 1.24 版本起 k8s 将不再在项目包含 Dockershim ,因此我们在此使用的是 containerd
安装 containerd 我所使用的Linux发行版为 Ubuntu,安装方式使用 apt 进行安装,其他安装方式参考
containerd 的 DEB 包是由 Docker 进行分发的,所以我们需要添加 Docker 源,在国内因为网络隐私直接访问可能会无法正常进行,所以我们使用清华源 来进行安装
1.清理掉旧的 docker 相关包,如果从未安装过可以跳过此步
1 sudo apt-get remove docker docker-engine docker.io containerd runc
2.安装依赖项
1 sudo apt-get install ca-certificates curl gnupg
3.信任 Docker 的 GPG 公钥并添加仓库
1 2 3 4 5 sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu \ "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
4.更新软件列表并安装
1 2 sudo apt-get update sudo apt-get install containerd.io
containerd 的基础配置 1.首先我们先初始化配置文件
1 containerd config default | sudo tee /etc/containerd/config.toml
2.启用 CRI 集成插件
使用apt安装 containerd,可能会默认禁用了 CRI 集成插件。需要启用 CRI 支持才能在 Kubernetes 集群中使用 containerd。 查看 CRI 没有出现在 /etc/containerd/config.toml 文件中 disabled_plugins 列表内。如果存在的话将其移除.
1 2 3 4 5 6 7 8 # 使用任意工具编辑配置文件 sudo vim /etc/containerd/config.toml # 找到 disabled_plugins 项,只将 cri 从列表中移除即可,如下 disabled_plugins = [] # 重启 containerd sudo systemctl restart containerd.service
3.容器运行时配置 cgroup 驱动
1 2 3 4 5 6 7 8 9 10 11 # 使用任意工具编辑配置文件 sudo vim /etc/containerd/config.toml # 找到 SystemdCgroup 配置,将其值改为 true [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] ... [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] SystemdCgroup = true # 重启 containerd sudo systemctl restart containerd
系统基础配置 1.转发 IPv4 并让 iptables 看到桥接流量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf overlay br_netfilter EOF sudo modprobe overlay sudo modprobe br_netfilter # 设置所需的 sysctl 参数,参数在重新启动后保持不变 cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.ipv4.ip_forward = 1 EOF # 应用 sysctl 参数而不重新启动 sudo sysctl --system
通过命令确认 br_netfilter 和 overlay 模块被加载
1 2 lsmod | grep br_netfilter lsmod | grep overlay
通过运行以下命令确认 net.bridge.bridge-nf-call-iptables、net.bridge.bridge-nf-call-ip6tables 和 net.ipv4.ip_forward 系统变量在你的 sysctl 配置中被设置为 1
1 2 3 4 sysctl \ net.bridge.bridge-nf-call-iptables \ net.bridge.bridge-nf-call-ip6tables \ net.ipv4.ip_forward
2.禁用 swap 交换分区
1 2 3 4 5 6 7 8 # 临时禁用 sudo swapoff -a # 在配置文件中禁用,防止重启机器需再次配置 sudo vim /etc/fstab # 将 swap 行配置注释掉, /swap.img none swap sw 0 0
引导集群启动 1.使用 kubeadm 创建一个默认配置文件
1 kubeadm config print init-defaults > kubeadm.yaml
内容如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 apiVersion: kubeadm.k8s.io/v1beta3 bootstrapTokens: - groups: - system:bootstrappers:kubeadm:default-node-token token: abcdef.0123456789abcdee ttl: 24h0m0s usages: - signing - authentication kind: InitConfiguration localAPIEndpoint: advertiseAddress: 0.0 .0 .0 bindPort: 9001 nodeRegistration: criSocket: unix:///run/containerd/containerd.sock imagePullPolicy: IfNotPresent name: k8s-master taints: null --- apiServer: timeoutForControlPlane: 4m0s apiVersion: kubeadm.k8s.io/v1beta3 certificatesDir: /etc/kubernetes/pki clusterName: kubernetes controllerManager: {}imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers kind: ClusterConfiguration kubernetesVersion: 1.27 .0 networking: dnsDomain: cluster.local serviceSubnet: 10.96 .0 .0 /12 podSubnet: 10.244 .0 .0 /16 scheduler: {}
我们只需要更改如下几项
1 2 3 4 5 6 7 8 9 10 11 12 13 14 localAPIEndpoint: advertiseAddress: 192.168 .100 .12 bindPort: 9001 ... nodeRegistration: criSocket: unix:///run/containerd/containerd.sock imagePullPolicy: IfNotPresent name: k8s-master ... imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers
一些其他的gcr源
1 2 3 registry.aliyuncs.com/google_containers registry.cn-hangzhou.aliyuncs.com/google_containers gcr.azk8s.cn/google_containers
2.使用 kubeadm init 命令引导集群
1 2 3 4 sudo kubeadm init --config=kubeadm.yaml # 集群已经初始化,您也可以使用以下命令将新的配置文件应用到集群中: kubeadm config upload from-file=kubeadm.yaml
初始化成功之后会提示 Your Kubernetes control-plane has initialized successfully! 就像下面这样
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 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.100.12:9001 --token abcdef.0123456789abcdee \ --discovery-token-ca-cert-hash sha256:7880dc1eb6a43857d81d2871326cd0616e9be6e52404ad02d29fab436fc08a02
开始使用集群前需要进行以下操作:
普通用户:
1 2 3 mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config
root 用户:
1 export KUBECONFIG=/etc/kubernetes/admin.conf
我们可以使用下列命令来查看集群状态
1 kubectl get pods --all-namespaces
我们需要部署一个基于 Pod 网络插件的 容器网络接口 (CNI),使得 Pod 可以相互通信。 如果没有安装,集群 DNS (CoreDNS) 将不会启动。
集群中部署一个pod网络 在集群初始化完成之后我们可以看到下面的提示,让我们安装一个pod网络插件
1 2 3 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/
在这里我们安装 flannel
1 2 3 4 5 6 # 可以使用下面命令直接获取 yml 文件进行安装 kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml # 也可以先下载下来,然后再进行安装 wget https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml kubectl apply -f kube-flannel.yml
安装好之后我们在看集群状态都为 Running
1 2 3 4 5 6 7 8 9 10 11 kubectl get pods --all-namespaces NAMESPACE NAME READY STATUS kube-flannel kube-flannel-ds-czhsp 1/1 Running 0 kube-system coredns-65dcc469f7-hjznr 1/1 Running 0 kube-system coredns-65dcc469f7-wn4m4 1/1 Running 0 kube-system etcd-k8s-master 1/1 Running 0 kube-system kube-apiserver-k8s-master 1/1 Running 0 kube-system kube-controller-manager-k8s-master 1/1 Running 0 kube-system kube-proxy-jq2rb 1/1 Running 0 kube-system kube-scheduler-k8s-master 1/1 Running 0
到这里我们的k8s集群已经成功搭建好了,目前我们只搭建了 master 节点,node 节点之后再配。