使用 Kubernetes 对容器进行编排成为微服务时代的技术风向标。
更新记录
2023-05
- (05-22)「新增」时间同步部分说明;
2022-07
- (07-30)「新增」CRI 部分说明;
- (07-30)「补充」Kubernetes 1.24 相关内容;
- (07-30)「更新」CentOS 部署 Docker 相关内容;
2020-07
- (07-26)「初始」版本;
环境检查
要求
- 兼容的 Linux 主机。Kubernetes 为基于 Debian 和 Red Hat 的系列发行版以及那些没有包管理的发行版提供了说明;
- 每个节点都具有 2 GB 及以上 RAM
- 2 CPUs 双核及以上
- 集群内各节点网络互通(公网、私网皆可)
- 每个节点都有唯一的
hostname
、MAC address
和product_uuid
- 部分端口处于可用状态
- 禁用 Swap 分区,必须禁用交换分区以便
kubelet
服务正常工作
确认节点唯一
确保 MAC 地址和设备识别码在集群内唯一
- MAC 地址可以通过
ip link
或ifconfig -a
命令查看 - 设备识别码可以通过
sudo cat /sys/class/dmi/id/product_uuid
查看
部分虚拟机可能具有相同的值,Kubernetes 使用这些值进行唯一识别,如果这些值相同可能导致服务无法正常工作。
检查所需端口
全新机器可以跳过本步骤,主要是为了防止端口冲突导致。
控制节点
Protocol Direction Port Range Purpose Used By TCP Inbound 6443* Kubernetes API server All TCP Inbound 2379-2380 etcd server client API kube-apiserver, etcd TCP Inbound 10250 Kubelet API Self, Control plane TCP Inbound 10251 kube-scheduler Self TCP Inbound 10252 kube-controller-manager Self 工作节点
Protocol Direction Port Range Purpose Used By TCP Inbound 10250 Kubelet API Self, Control plane TCP Inbound 30000-32767 NodePort Services† All
禁用交换分区
Kubernetes 的 kubelet 使用需要禁用 Swap 交换分区,否则可能产生无法预料的错误。
sudo swapoff -a
小贴士:推荐在服务器安装时手动配置分区表,将 swap 分区删除,否则可能导致开机后自动挂载 swap 分区,也需要记得注释掉 fstab 中的 swap 分区,防止机器重启后自动挂载。
一键删除交换分区
grep swap /etc/fstab && sudo sed -i.bak '/swap/d' /etc/fstab
配置时间同步服务
Kubernetes 集群内的时间同步很重要,可以防止出现因时间不同步导致的流量包异常问题。
sudo apt install -y chrony
主节点添加中国国家授时中心同步源
echo 'server ntp.ntsc.ac.cn iburst' | sudo tee /etc/chrony/sources.d/ntsc.sources
其他节点添加主节点为同步源
## 替换 192.0.2.1 为主节点IP
echo 'server 192.0.2.1 iburst' | sudo tee /etc/chrony/sources.d/local-ntp-server.sources
修改主节点的配置
cat <<EOF | sudo tee /etc/chrony/conf.d/k8s.conf
makestep 0.1 3
local stratum 8
manual
allow 192.0.2.0/24 ## 这里改成实际的K8S节点子网
smoothtime 400 0.01
EOF
重新载入同步源,提示 200 OK 即为载入成功
sudo chronyc reload sources
关于 CR 和 CRI
Kubernetes 作为一个容器编排工具,管理的只是“容器”,至于容器由什么服务提供,这不重要,实际上 Kubernetes 管控的是 CRI(Container Runtime Interface,容器运行时接口),CRI 可以对接多种 CR(Container Runtime,容器运行时),CR 有多种,比如 Docker 、containerd、CRI-O 等。
逻辑关系:
Kubernetes ==> CRI ==> CR
containerd 和 Docker 之前的渊源:实际上 containerd 是 Docker 内的一个组件,谷歌想削弱 Docker 公司在容器方面的影响,于是开源了 Kubernetes,然后 Docker 开发了 Docker Swarm 与之竞争,但不幸在这场竞争中失利。而 Kubernetes 一直想剥离对于 Docker 引擎的依赖,于是 Docker 公司将 Docker 的核心组件剥离出来并开源为 containerd 捐赠给了 CNCF(Cloud Native Computing Foundation,云原生计算基金会),想以此继续占据 Kubernetes 核心组件的位置。
特别注意的是,从 Kubernetes 1.24 版本开始,不再内置 docker 的 CRI 组件 docker-shim
,因此直接安装后是无法直接管控 Docker 容器的,需要额外安装 CRI 组件,并且从旧版本升级到 1.24 及其之后版本需要提前修改容器环境。
因此后续将分为两个部分:Kubernetes 1.24 之前的版本、Kubernetes 1.24 及其之后的版本。
流量转发
安装 CRI 前需要配置接管 Kubernetes 流量,在默认情况下 Kubernetes 会使用 iptables 进行流量转发。
iptables Mode
检查 br_netfilter
模块是否加载。
lsmod | grep br_netfilter
执行以下命令加载内核模块并配置系统参数
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
模块是否已经正常加载。
lsmod | grep br_netfilter
lsmod | grep overlay
IPVS Mode
如果想使用 ipvs
模式,则还需要额外进行配置。
先安装所需的模块和配置工具
sudo apt install -y ipset ipvsadm
需要加载的内核模块可参考其官方博客内容。
小贴士:需要注意的是,在 Kernel 4.18+ 中,模块nf_conntrack_ipv4
更名为nf_conntrack
。
cat <<EOF | sudo tee /etc/modules-load.d/ipvs.conf
ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
nf_conntrack
EOF
# 手动加载下模块
sudo modprobe ip_vs
sudo modprobe ip_vs_rr
sudo modprobe ip_vs_wrr
sudo modprobe ip_vs_sh
sudo modprobe nf_conntrack
没有报错即表示加载成功。
安装 Container Runtime
常见的 CRI 接口地址
Runtime | Unix 套接字默认地址 |
---|---|
containerd | unix:///var/run/containerd/containerd.sock |
CRI-O | unix:///var/run/crio/crio.sock |
Docker Engine (using cri-dockerd) | unix:///var/run/cri-dockerd.sock |
使用 Docker 作为 CR
从 Kubernetes 1.24 版本开始已经移除了 Docker 的官方支持,但通过 dockerd cri 插件依旧可以使用,但并不推荐。
原因是实际上 Docker CE 从 19.x 版本后也拆分为了 containerd + docker,所以如果在 kubernetes 中使用 docker,实际控制逻辑为:
kubernetes -> dockerd(cri) -> docker(ce) -> containerd
在使用 containerd 作为 CR 时,控制逻辑为:
kubernetes -> containerd(cri) -> containerd
可以看到实际上这个可以省略,并且引入的东西越多,产生问题的可能性就越大。
安装 Docker
安装方法可以参考官网文档,或者参考基于 Debian 系列发行版部署 Docker CE。
CentOS
系统要求
安装 Docker 需要使用 CentOS 7,CentOS 8, CentOS 8 (stream),CentOS 9 (stream) 的主线版本,对于已存档的版本不被支持。
必须启用
centos-extras
仓库,这个仓库默认是启用的,但是如果被禁用,需要在安装前启动此仓库。推荐使用
overlay2
存储驱动。注意:目前 Docker 官方构建仓库仅支持 CentOS 7 ,最新的 CentOS 8 暂时不支持,可以通过某神奇方法安装,但是不保证其稳定性,切勿用于生产环境。卸载旧版本
旧版本的 Docker 包名为
docker
或docker-engine
,如果已经安装,则需要卸载它们和相关的依赖。sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine
如果提示没有找到这些软件包,那么也没关系,直接进行下面的步骤即可。
目录
/var/lib/docker/
(存放镜像、容器、数据卷、网络配置等)会被默认保留,Docker Engine 包现在已经改名为docker-ce
。使用仓库安装
配置仓库
需要使用
yum-utils
才能使用yum-config-manager
仓库配置工具sudo yum install -y yum-utils
非中国大陆地区请使用官方地址进行安装
sudo yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo
中国大陆推荐使用国内镜像站(阿里开源镜像)
sudo yum-config-manager \ --add-repo \ https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
国内镜像站(清华开源镜像)
sudo yum-config-manager \ --add-repo \ https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo
国内镜像站(网易开源镜像)
sudo yum-config-manager \ --add-repo \ https://mirrors.163.com/docker-ce/linux/centos/docker-ce.repo
安装
安装最新版本的 Docker Engine,containerd 和 Docker Compose
sudo yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin
如果提示接受 GPG 密钥,请确认是否为
060A 61C5 1B55 8A7F 742B 77AA C52F EB6B 621E 9F35
,如果匹配则可以接受。这个命令仅安装 Docker ,并不会启动。并且会自动创建docker
用户组,在默认情况下请不要将任何用户添加只此用户组中。如果需要安装指定版本的 Docker Engine,请列出所有可用版本,然后进行选择和安装:
a. 检索所有在仓库中可用的版本,可以使用命令进行检索并按版本从高到低进行排序:
yum list docker-ce --showduplicates | sort -r
返回的版本字符串中会包含系统版本,比如
.el7
或.el8
等。b. 安装指定版本需要使用完整的包含版本号的包名进行安装,比如
docker-ce-18.09.1
。sudo yum install docker-ce-<版本号> docker-ce-cli-<版本号> containerd.io docker-compose-plugin
需要注意的是
docker-ce
和docker-ce-cli
必须版本匹配,其他组件可以使用新版本。启动 Docker
sudo systemctl start docker
可以通过运行
hello-world
镜像来验证是否成功安装sudo docker run hello-world
这个命令会下载镜像并在容器中运行,运行后会打印一个消息后退出。
配置优化
非 root 用户管理 docker
Docker 守护程序绑定在 Unix 套接字,而非 TCP 端口。默认情况下 Unix 套接字只被 root
用户管理,其他用户使用需要添加 sudo
,Docker 守护进程必须运行在 root
用户下。
如果希望不使用 sudo
即可对其进行管理,可以将用户添加至 docker
组中即可不使用 sudo
进行管理操作。
sudo usermod -aG docker $USER
然后需要重新登陆终端才能生效。
cgroup 驱动切换
在使用基于 SystemD 的机器上部署 Kubernetes 和 Docker 时,为了让更好的工作
注意:在 Kubernetes v1.22 及之后版本中,如果用户没有在KubeletConfiguration
下设置cgroupDriver
字段,kubeadm
将默认使用systemd
,无需进行下面的操作。
Debian/Ubuntu
cat <<EOF | sudo tee /etc/docker/daemon.json { "exec-opts": ["native.cgroupdriver=systemd"], "log-driver": "json-file", "log-opts": { "max-size": "100m" }, "storage-driver": "overlay2" } EOF
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo systemctl daemon-reload sudo systemctl restart docker
CentOS/RadHat
cat <<EOF | sudo tee /etc/docker/daemon.json { "exec-opts": ["native.cgroupdriver=systemd"], "log-driver": "json-file", "log-opts": { "max-size": "100m" }, "storage-driver": "overlay2", "storage-opts": [ "overlay2.override_kernel_check=true" ] } EOF
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo systemctl daemon-reload sudo systemctl restart docker
Hub 镜像仓库加速
上述配置文件使用的是网易的镜像仓库,也可以使用 DaoCloud 镜像。
curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.io
其他详细方式请详见其官网链接。
部署 CRI (dockerd)
如果依旧选择使用 Docker 作为后端,则需要手动安装 cri-dockerd,才能让 Kubernetes 对接 Docker Engine。根据系统直接安装 deb 或者 rpm 包即可。
其他的 CRI 引擎在 kubernetes 中已经自带,无需手动进行安装部署。到项目 Release 中下载安装包并进行安装。
# CentOS 8
sudo rpm -ivh cri-dockerd-0.x.x-0.el8.x86_64.rpm
# Debian 11
sudo dpkg -i cri-dockerd_0.x.x-0.debian-bullseye_amd64.deb
如果所使用的发行版未提供安装包,可以手动下载二进制包 cri-dockerd-0.x.x.amd64.tgz
,解压后移动至相应目录即可。
tar xf cri-dockerd-0.x.x.amd64.tgz
mv cri-dockerd/cri-dockerd /usr/bin/
安装完毕后,Kubernetes 即可使用 docker 作为后端。
附录
相关链接
- 从零开始的 Kubernetes 学习笔记(二) - VVavE
- 从零开始的 Kubernetes 学习笔记(三) - VVavE
- 从零开始的 Kubernetes 学习笔记(四) - VVavE
- 从零开始的 Kubernetes 学习笔记(五) - VVavE
参考链接
- Install Docker Engine - docker docs
- Kubernetes Container runtimes | cgroup-drivers - kubernetes.io
- Kubernetes Container runtimes | Docker - kubernetes.io
- modprobe: FATAL: Module nf_conntrack_ipv4 not found in directory - serverfault
本文由 柒 创作,采用 知识共享署名4.0
国际许可协议进行许可。
转载本站文章前请注明出处,文章作者保留所有权限。
最后编辑时间: 2024-12-12 22:03 PM