Kubenetes 安装

在写这篇文章的时候使用的 k8s 版本为 1.27.1

基础知识

Kubernetes 集群资源类型

一个 Kubernetes 集群包含两种类型的资源:

  1. Master: 负责管理整个集群。 Master 协调集群中的所有活动,例如调度应用、维护应用的所需状态、应用扩容以及推出新的更新。
  2. Node: 是一个虚拟机或者物理机,它在 Kubernetes 集群中充当工作机器的角色 每个Node都有 Kubelet , 它管理 Node 而且是 Node 与 Master 通信的代理。

基础工具

  1. kubectl: kubectl是Kubernetes的命令行工具,用于管理Kubernetes集群中的应用程序、服务、部署、状态等。

    kubelet 负责管理每个节点上的容器,监视运行在节点上的容器的状态,以及与master节点上的其它组件进行通信,如kube-apiserver和kube-proxy,以确保节点上的容器处于期望的状态,kubelet还会从etcd中获取Pod的信息,并执行Pod的调度和容器的启动、停止、重启等操作。需要运行在每个节点上

  2. 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

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_netfilteroverlay 模块被加载

1
2
lsmod | grep br_netfilter
lsmod | grep overlay

通过运行以下命令确认 net.bridge.bridge-nf-call-iptablesnet.bridge.bridge-nf-call-ip6tablesnet.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
# k8s 本地接口
localAPIEndpoint:
# 此处为本机地址,只允许配置为ip地址
advertiseAddress: 192.168.100.12
bindPort: 9001
...
nodeRegistration:
criSocket: unix:///run/containerd/containerd.sock
imagePullPolicy: IfNotPresent
# 集群名称
name: k8s-master
...
# gcr 官方源国内可能不可访问,可以更改为国内源
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 节点之后再配。