文章转载自: https://www.skynemo.cn/archives/01-k8s-install-with-kubeadm
本文中所有操作均以 Kubernetes 1.23.5 为基准
Kubeadm 简介
官网简介: Kubeadm | Kubernetes
Kubeadm 是快速创建 Kubernetes 集群的官方工具。它不仅提供了 kubeadm init
和 kubeadm join
命令用于创建、加入集群,还可以用于在线升级、管理证书等应用
kubeadm 通过执行必要的操作来启动和运行最小可用集群。 按照设计,它只关注启动引导,而非配置机器。同样的, 安装其他的扩展,例如 Kubernetes Dashboard、 监控方案、以及特定云平台的扩展,都不在 kubeadm 使用范围内
理想情况下,使用 kubeadm 作为所有部署工作的基准将会更加易于创建一致性集群
安装 Kubeadm
Kubeadm 官方安装参考: 安装 kubeadm | Kubernetes
Kubernetes 版本选择
Kubernetes 最近发布版本列表:Releases | Kubernetes
Kubernetes 所有发布版本列表:Releases · kubernetes/kubernetes (github.com)
本文选择安装 Kubernetes 1.23.5
注意事项
- 一台兼容的 Linux 主机。Kubernetes 项目为基于 Debian 和 Red Hat 的 Linux 发行版以及一些不提供包管理器的发行版提供通用的指令
- 每台机器 2 GB 或更多的 RAM(如果少于这个数字将会影响你应用的运行内存)
- 2 CPU 核或更多
- 集群中的所有机器的网络彼此均能相互连接(公网和内网都可以)
- 节点之中不可以有重复的主机名、MAC 地址或 product_uuid
- 允许 iptables 检查桥接流量
- 禁用交换分区。为了保证 kubelet 正常工作,你 必须 禁用交换分区
- 启用一些必要的端口,详见 附录-端口与协议,测试环境可以直接关闭防火墙以放行端口
主机设置
检查 MAC 与 product_uuid
- 使用命令
ip link
或ifconfig -a
来获取网络接口的 MAC 地址 - 使用
sudo cat /sys/class/dmi/id/product_uuid
命令对 product_uuid 校验
一般来讲,硬件设备会拥有唯一的地址,但是有些虚拟机的地址可能会重复。 Kubernetes 使用这些值来唯一确定集群中的节点。 如果这些值在每个节点上不唯一,可能会导致安装失败
允许 iptables 检查桥接流量
确保 br_netfilter
模块被加载。这一操作可以通过运行 lsmod | grep br_netfilter
来完成。若要显式加载该模块,可执行 sudo modprobe br_netfilter
。
为了让你的 Linux 节点上的 iptables 能够正确地查看桥接流量,你需要确保在你的 sysctl
配置中将 net.bridge.bridge-nf-call-iptables
设置为 1。例如:
# 加载 br_netfilter 模块
root@kube-master:~# cat > /etc/modules-load.d/k8s.conf <<EOF
br_netfilter
EOF
# 配置允许 iptables 检查桥接流量
root@kube-master:~# cat > /etc/sysctl.d/k8s.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
# 应用配置
root@kube-master:~# sudo sysctl --system
禁用交换分区
临时禁止
# 临时禁止,重启后恢复,适用于不能重启的主机
root@kube-master:~# swapoff -a
永久禁止
# 永久禁止,注释 /etc/fstab 中与 swap 相关的行,重启依旧有效
root@kube-master:~# vi /etc/fstab
...
# /swap.img none swap sw 0 0
...
优化参数
优化内核参数及资源限制参数,详见 附录-参数优化
安装容器运行时
kubernetes 集群的每个节点均需要安装容器运行时
容器运行时官方详解:容器运行时 | Kubernetes
注:在 Kubernetes 1.24 版本往后,Kubernetes 不再包含 Dockershim
选择容器运行时
目前 Kubernetes 支持几种通用容器运行时
本文使用 Docker 20.10.6 作为容器运行时,其他容器运行时并无太大区别
Docker 版本选择需要参考 Kubernetes 的版本兼容情况,可以在 Kubernetes 最近版本列表页面 或 Kubernetes 所有版本列表页面 点击对应的版本的 Changelog 进行查看(如果没有找到 Docker 版本信息则表示与上一版本支持情况相同)。下表列出最近 Kubernetes 对 Docker 版本的兼容情况
Kubernetes 版本 | Docker版本兼容情况 |
---|---|
1.21.x | v20.10.2版本以上不兼容 |
1.22.x | v20.10.2版本以上不兼容 |
1.23.x | v20.10.7版本以上不兼容 |
安装容器运行时
操作系统以 ubuntu 20.04.x 为例
清理原有的 docker
如果你过去安装过 docker,需要先卸载
root@kube-master:~# sudo apt remove -y docker-ce docker-ce-cli containerd.io
安装依赖
root@kube-master:~# sudo apt -y install apt-transport-https ca-certificates software-properties-common gnupg2
配置仓库
此处使用了阿里云的镜像源
信任 Docker 的 GPG 公钥
root@kube-master:~# curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
| sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
添加软件源
root@kube-master:~# echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
更新缓存
root@kube-master:~# apt update
安装指定 Docker 版本
# 查找docker版本
root@kube-master:~# apt-cache madison docker-ce
......
docker-ce | 5:20.10.9~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
docker-ce | 5:20.10.8~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
docker-ce | 5:20.10.7~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
docker-ce | 5:20.10.6~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
......
# 安装指定版本的 docker-ce
root@kube-master:~# sudo apt install -y containerd.io \
docker-ce=5:20.10.6~3-0~ubuntu-focal \
docker-ce-cli=5:20.10.6~3-0~ubuntu-focal
检查 docker 版本
root@kube-master:~# docker --version
Docker version 20.10.6, build 370c289
配置开机自启
root@kube-master:~# sudo systemctl enable --now docker
其他配置(可选)
配置 Docker 镜像加速(推荐配置)、默认路径(可选,必须在初始化集群前配置)、存储驱动(可选,必须在初始化集群前配置)等参数
root@kube-master:~# mkdir -p /data/docker
root@kube-master:~# vim /etc/docker/daemon.json
{
"data-root": "/data/docker",
"registry-mirrors": ["https://sqr9a2ic.mirror.aliyuncs.com"],
"storage-driver": "overlay2"
}
安装 kubeadm、kubelet 和 kubectl
操作系统以 ubantu 20.04.x 为例
建议三个工具版本一致,如果工具版本不能够一致,参考版本差异文档进行选择:Version Skew Policy | Kubernetes
Kubernetes 集群的每个节点均需要安装 kubeadm、kubelet、kubectl
-
kubelet 原则上不需要在控制面节点上运行。但是 kubeadm 构建集群时,apiserver、controller-manager、scheduler、etcd等服务是运行在容器上的,需要由 kubelet 进行调度,所以需要在控制面节点安装 kubelet
-
kubectl 原则上可以只在需要与集群通信的节点(一般为控制面节点)安装,但 kubeadm 依赖于 kubectl,故所有节点均需安装
软件作用
-
kubeadm
:用于初始化集群的管理指令 -
kubelet
:用于在集群中的每个节点上用来启动 Pod 和容器等 -
kubectl
:用来与集群通信的命令行工具
安装
由于官网镜像在国内下载较慢,此处使用阿里云镜像站,安装方法参考:kubernetes安装教程-阿里巴巴开源镜像站 (aliyun.com)
安装依赖
# 更新 apt 包索引
root@kube-master:~# sudo apt-get update
# 安装 Kubernetes apt 仓库所需的依赖
root@kube-master:~# sudo apt-get install -y apt-transport-https ca-certificates curl
下载公钥
由于默认公钥在外网无法访问,此处使用的是阿里云的公钥文件
root@kube-master:~# curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg \
https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg
添加仓库
添加阿里云的 Kubernetes apt
仓库
root@kube-master:~# cat > /etc/apt/sources.list.d/kubernetes.list <<EOF
deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF
安装
# 更新 apt 包索引
root@kube-master:~# sudo apt update
# 查看版本
root@kube-master:~# apt-cache madison kubeadm
kubeadm | 1.23.6-00 | https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages
kubeadm | 1.23.5-00 | https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages
# 安装 kubelet kubeadm kubectl 指定版本( node 节点可以不安装 kubectl )
root@kube-master:~# sudo apt install -y \
kubelet=1.23.5-00 \
kubeadm=1.23.5-00 \
kubectl=1.23.5-00
# 由于 kubernetes 官网未开放同步方式, 可能会有索引 gpg 检查失败的情况,可以在安装时忽略 gpg 检查
# root@kube-master:~# sudo apt --allow-unauthenticated install -y ......
# 锁定版本,防止误更新
root@kube-master:~# sudo apt-mark hold kubelet kubeadm kubectl
检查版本
root@kube-master:~# kubeadm version
kubeadm version: &version.Info{Major:"1", Minor:"23", GitVersion:"v1.23.5", GitCommit:"c285e781331a3785a7f436042c65c5641ce8a9e9", GitTreeState:"clean", BuildDate:"2022-03-16T15:57:37Z", GoVersion:"go1.17.8", Compiler:"gc", Platform:"linux/amd64"}
安装完成后,kubelet 每隔几秒就会重启,因为它陷入了一个等待 kubeadm 指令的死循环
配置驱动(重要)
由于 kubeadm 把 kubelet 视为一个系统服务来管理,所以对基于 kubeadm 的安装 k8s 时, 官方推荐使用 systemd
作为 cgroup 的驱动,不推荐 cgroupfs
。但是容器运行时(此处为 docker)默认的 cgroup 的驱动一般都是 cgroupfs
。两者的 cgroup 驱动不一致时,会出现如下错误,导致 kubelet 运行异常
kubelet cgroup driver: “systemd” is different from docker cgroup driver: “cgroupfs”
需要修改容器运行时与 kubelet 的 cgroup 驱动保持一致,推荐修改容器运行时的 cgroup 驱动为 systemd
配置容器运行时的 cgroup 驱动
其他容器运行时配置的方法,请参考官方文档:容器运行时 | Kubernetes
在 docker 的配置文件中配置 cgroup 驱动
root@kube-master:~# sudo mkdir /etc/docker
root@kube-master:~# vim /etc/docker/daemon.json
{
"data-root": "/data/docker",
"registry-mirrors": ["https://sqr9a2ic.mirror.aliyuncs.com"],
"storage-driver": "overlay2",
"exec-opts": ["native.cgroupdriver=systemd"]
}
重启 docker 使配置生效
root@kube-master:~# sudo systemctl daemon-reload
root@kube-master:~# sudo systemctl restart docker
配置 kubelet 的 cgroup 驱动
参考官方文档:配置 cgroup 驱动 | Kubernetes
kubelet 默认cgroup 的驱动为 systemd ,不推荐修改
使用配置文件初始化时,可以在配置文件中进行设置
# kubeadm-config.yaml
kind: ClusterConfiguration
apiVersion: kubeadm.k8s.io/v1beta3
kubernetesVersion: v1.21.0
---
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
cgroupDriver: systemd
使用配置文件初始化
kubeadm init --config kubeadm-config.yaml
kubeadm
命令介绍
kubeadm
常用命令
[kubeadm init](https://kubernetes.io/zh/docs/reference/setup-tools/kubeadm/kubeadm-init)kubeadm init
用于搭建控制平面节点[kubeadm join](https://kubernetes.io/zh/docs/reference/setup-tools/kubeadm/kubeadm-join)
用于搭建工作节点并将其加入到集群中[kubeadm upgrade](https://kubernetes.io/zh/docs/reference/setup-tools/kubeadm/kubeadm-upgrade)
用于升级 Kubernetes 集群到新版本[kubeadm config](https://kubernetes.io/zh/docs/reference/setup-tools/kubeadm/kubeadm-config)
如果你使用了 v1.7.x 或更低版本的 kubeadm 版本初始化你的集群,则使用kubeadm upgrade
来配置你的集群[kubeadm token](https://kubernetes.io/zh/docs/reference/setup-tools/kubeadm/kubeadm-token)
用于管理kubeadm join
使用的令牌[kubeadm reset](https://kubernetes.io/zh/docs/reference/setup-tools/kubeadm/kubeadm-reset)
用于恢复通过kubeadm init
或者kubeadm join
命令对节点进行的任何变更[kubeadm certs](https://kubernetes.io/zh/docs/reference/setup-tools/kubeadm/kubeadm-certs)
用于管理 Kubernetes 证书[kubeadm kubeconfig](https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm-kubeconfig)
用于管理 kubeconfig 文件[kubeadm version](https://kubernetes.io/zh/docs/reference/setup-tools/kubeadm/kubeadm-version)
用于打印 kubeadm 的版本信息[kubeadm alpha](https://kubernetes.io/zh/docs/reference/setup-tools/kubeadm/kubeadm-alpha)
用于预览一组可用于收集社区反馈的特性
全局选项
全局选项适用于 kubeadm
的所有命令,多为日志相关选项
--add-dir-header # 如果为 true,将在日志头部添加日志目录
--log-file string # 指定输出的日志文件
--log-file-max-size uint # 定义日志文件的最大大小,单位 MB,如果设置为 0,则不限制。默认为 1800
--one-output # 如果为 true,则只写入严重级别的日志
--rootfs string # 指定宿主机路径作为根路径
--skip-headers # 如果为 true,则日志里不显示标题前缀
--skip-log-headers # 如果为 true,则日志里不显示标题
-v, --v Level # 指定日志级别,0 ~ 5
kubeadm init
命令简介
查看帮助
root@kube-master:~# kubeadm init --help
常用选项
# 选项较多,此处仅列出较常用的选项
--apiserver-advertise-address string # (重要)API Server 监听的 IP 地址
--apiserver-bind-port int32 # (重要)API Server 绑定的端口,默认为 6443
--apiserver-cert-extra-sans strings # 用于 API Server 服务 SANs 扩展的证书。可以是 IP 地址和 DNS 名称
--cert-dir string # 指定证书存放路径,默认为 "/etc/kubernetes/pki"
--certificate-key string # 指定一个用于加密 kubeadm certs Secret 中的控制平面证书的密钥
--config string # 指定 kubeadm 配置文件路径
--control-plane-endpoint string # (重要)为控制平面指定一个稳定的 IP 地址或 DNS 名称。常用于多 master 时指定统一的 VIP 地址
--cri-socket string # 要连接的 CRI socket 路径。如果为空,kubeadm 将自动检测;仅当安装了多个 CRI 或非标准 CRI socket 时,才会使用此选项
--dry-run # 测试运行,不会应用任何的更改
--feature-gates string # 一组 key=value 键值对,用于开关一些当前版本特有的功能,支持选项如下
PublicKeysECDSA=true|false (ALPHA - default=false)
RootlessControlPlane=true|false (ALPHA - default=false)
UnversionedKubeletConfigMap=true|false (ALPHA - default=false)
--ignore-preflight-errors strings # (重要)是否忽略检查过程中出现的错误信息,例如: 'IsPrivilegedUser'、'Swap'。如果设置为 'all',则忽略所有错误信息
--image-repository string # (重要)指定容器镜像仓库,用于拉取控制面镜像,默认为 "k8s.gcr.io"
--kubernetes-version string # (重要)指定安装的 Kubernetes 版本,默认为 "stable-1"
--node-name string # 指定 node 节点名称
--pod-network-cidr string # (重要)指定 pod 网络的 IP 地址范围。如果设置,控制平面将自动为每个节点分配 CIDR,注意不要与主机网络重叠
--service-cidr string # (重要)指定 service 网络的 IP 地址范围,默认为 "10.96.0.0/12",注意不要与主机网络重叠
--service-dns-domain string # (重要)为服务指定替代域名( k8s 的内部域名),默认为 "cluster.local",会由相应的 DNS 服务(kube-dns/coredns)解析生成的域名记录
--skip-certificate-key-print # 不打印用于加密控制平面证书的密钥信息
--skip-phases strings # 要跳过哪些阶段
--skip-token-print # 跳过打印 'kubeadm init' 生成的默认 token 信息
--token string # 指定用于 node 节点和控制平面节点之间建立双向信任的 token
--token-ttl duration # token 过期时间,例如:1s、2m、3h。如果设置为“0”,令牌将永远不会过期。默认为 24h0m0s
--upload-certs # 将控制平面证书加载到 kubeadm certs Secret,更新证书
创建单节点集群
kubeadm 命令选项和帮助:Kubeadm | Kubernetes
主机列表
主机名 | IP | 角色 | 安装服务 |
---|---|---|---|
kube-master.skynemo.cn | 192.168.1.201 | 控制面节点、工作节点 | docker: 20.10.6 kubeadm: 1.23.5 kubelet: 1.23.5 kubectl: 1.23.5 |
安装过程省略,详见:安装 Kubeadm
主机需要关闭防火墙
下载镜像
kubeadm 在初始化节点时会从镜像仓库下载镜像,默认镜像仓库由 google 提供(地址为:k8s.gcr.io),国内无法访问。需要使用科学上网方式,提前下载好所需的镜像,防止在构建过程中因镜像下载异常而导致部署失败。如果选定的版本将作为生产环境使用,可以将这些镜像保存到国内的镜像仓库,方便后续多次下载
查看所需镜像
root@kube-master:~# kubeadm config images list --kubernetes-version=1.23.5
k8s.gcr.io/kube-apiserver:v1.23.5
k8s.gcr.io/kube-controller-manager:v1.23.5
k8s.gcr.io/kube-scheduler:v1.23.5
k8s.gcr.io/kube-proxy:v1.23.5
k8s.gcr.io/pause:3.6
k8s.gcr.io/etcd:3.5.1-0
k8s.gcr.io/coredns/coredns:v1.8.6
下载镜像(需科学上网)
docker pull k8s.gcr.io/kube-apiserver:v1.23.5
docker pull k8s.gcr.io/kube-controller-manager:v1.23.5
docker pull k8s.gcr.io/kube-scheduler:v1.23.5
docker pull k8s.gcr.io/kube-proxy:v1.23.5
docker pull k8s.gcr.io/pause:3.6
docker pull k8s.gcr.io/etcd:3.5.1-0
docker pull k8s.gcr.io/coredns/coredns:v1.8.6
下载镜像(使用私人仓库)
可以使用本人在阿里云仓库保存的镜像
root@kube-master:~# docker pull registry.cn-shanghai.aliyuncs.com/sync-k8s-images/kube-apiserver:v1.23.5
root@kube-master:~# docker pull registry.cn-shanghai.aliyuncs.com/sync-k8s-images/kube-controller-manager:v1.23.5
root@kube-master:~# docker pull registry.cn-shanghai.aliyuncs.com/sync-k8s-images/kube-scheduler:v1.23.5
root@kube-master:~# docker pull registry.cn-shanghai.aliyuncs.com/sync-k8s-images/kube-proxy:v1.23.5
root@kube-master:~# docker pull registry.cn-shanghai.aliyuncs.com/sync-k8s-images/pause:3.6
root@kube-master:~# docker pull registry.cn-shanghai.aliyuncs.com/sync-k8s-images/etcd:3.5.1-0
root@kube-master:~# docker pull registry.cn-shanghai.aliyuncs.com/sync-k8s-images/coredns:v1.8.6
查看下载的镜像
root@kube-master:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry.cn-shanghai.aliyuncs.com/sync-k8s-images/kube-apiserver v1.23.5 3fc1d62d6587 6 weeks ago 135MB
registry.cn-shanghai.aliyuncs.com/sync-k8s-images/kube-proxy v1.23.5 3c53fa8541f9 6 weeks ago 112MB
registry.cn-shanghai.aliyuncs.com/sync-k8s-images/kube-controller-manager v1.23.5 b0c9e5e4dbb1 6 weeks ago 125MB
registry.cn-shanghai.aliyuncs.com/sync-k8s-images/kube-scheduler v1.23.5 884d49d6d8c9 6 weeks ago 53.5MB
registry.cn-shanghai.aliyuncs.com/sync-k8s-images/etcd 3.5.1-0 25f8c7f3da61 6 months ago 293MB
registry.cn-shanghai.aliyuncs.com/sync-k8s-images/coredns v1.8.6 a4ca41631cc7 6 months ago 46.8MB
registry.cn-shanghai.aliyuncs.com/sync-k8s-images/pause 3.6 6270bb605e12 8 months ago 683kB
初始化节点
使用命令进行控制面节点初始化
root@kube-master:~# kubeadm init \
--apiserver-advertise-address=192.168.1.201 \
--apiserver-bind-port=6443 \
--kubernetes-version=v1.23.5 \
--pod-network-cidr=10.100.0.0/16 \
--service-cidr=10.200.0.0/16 \
--service-dns-domain=nemo.local \
--image-repository=registry.cn-shanghai.aliyuncs.com/sync-k8s-images \
--ignore-preflight-errors=swap
初始化完成后会输出一些配置指导信息
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.1.201:6443 --token pahk98.bwimpfz46v82rva3 \
--discovery-token-ca-cert-hash sha256:1f3e810d21e68b12c88ae4cf778e7d91c9df3195b8e7acd524b7efc32fe56677
配置使用 kubectl
若要使非 root 用户可以运行 kubectl
,请运行以下命令, 它们是 kubeadm init
输出的一部分配置,包含了请求的证书、密钥等信息
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
如果你是 root
用户,则可以配置环境变量 KUBECONFIG=/etc/kubernetes/admin.conf
# 配置永久环境变量
root@kube-master:~# cat > /etc/profile.d/kubeconfig.sh << EOF
export KUBECONFIG=/etc/kubernetes/admin.conf
EOF
# 加载环境变量
root@kube-master:~# source /etc/profile
允许在控制平面节点上调度 Pod
默认情况下,出于安全原因,集群不会在控制平面节点上调度 Pod。 如果希望能够在控制平面节点上调度 Pod, 例如用于开发的单机 Kubernetes 集群,请运行
root@kube-master:~# kubectl taint nodes --all node-role.kubernetes.io/master-
node/kube-master untainted
这将从任何拥有 node-role.kubernetes.io/master
taint 标记的节点中移除该标记, 包括控制平面节点,这意味着调度程序将能够在任何地方调度 Pods
部署网络插件
支持的网络插件列表: 集群网络系统 | Kubernetes
常用的网络插件有: Calico flannel
在安装网络之前,集群 DNS (CoreDNS) 不会启动
# 查看当前的 pod 状态,会发现 coredns 没有启动
root@kube-master:~# kubectl get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-bc5b69cd6-bqr4g 0/1 Pending 0 18m
kube-system coredns-bc5b69cd6-n7qg9 0/1 Pending 0 18m
kube-system etcd-kube-master 1/1 Running 1 18m
kube-system kube-apiserver-kube-master 1/1 Running 1 18m
kube-system kube-controller-manager-kube-master 1/1 Running 1 18m
kube-system kube-proxy-vrnq7 1/1 Running 0 18m
kube-system kube-scheduler-kube-master 1/1 Running 1 18m
部署网络插件
# 下载配置文件
root@kube-master:~# curl -o kube-flannel-v0.17.0-release.yml \
https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
# 如果无法访问外网,可以使用作者的配置备份
# curl -O https://resource-1258540788.file.myqcloud.com/99-external-resource/01-kubernetes/01-flannel/kube-flannel-v0.17.0-release.yml
# 修改网络与 kubeadm init 配置的 pod 网络(由初始化选项 pod-network-cidr 指定)一致
root@kube-master:~# vim kube-flannel-v0.17.0-release.yml
......
net-conf.json: |
{
"Network": "10.100.0.0/16",
"Backend": {
"Type": "vxlan"
}
}
......
# 直接使用 kubectl 应用部署
root@kube-master:~# kubectl apply -f kube-flannel-v0.17.0-release.yml
检验集群 DNS (CoreDNS) 是否启动
root@kube-master:~# kubectl get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-bc5b69cd6-bqr4g 1/1 Running 0 39m
kube-system coredns-bc5b69cd6-n7qg9 1/1 Running 0 39m
kube-system etcd-kube-master 1/1 Running 1 39m
kube-system kube-apiserver-kube-master 1/1 Running 1 39m
kube-system kube-controller-manager-kube-master 1/1 Running 1 39m
kube-system kube-flannel-ds-k476z 1/1 Running 0 41s
kube-system kube-proxy-vrnq7 1/1 Running 0 39m
kube-system kube-scheduler-kube-master 1/1 Running 1 39m
测试 Pod 的使用
查看节点状态
root@kube-master:~# kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
kube-master Ready control-plane,master 42m v1.23.5 192.168.1.201 <none> Ubuntu 20.04.4 LTS 5.4.0-100-generic docker://20.10.6
创建 Pod 并暴露端口
root@kube-master:~# kubectl create deployment nginx --image=nginx
deployment.apps/nginx created
root@kube-master:~# kubectl expose deployment nginx --port=80 --type=NodePort
service/nginx exposed
查看 Pod 和 service 状态
root@kube-master:~# kubectl get pod,svc
NAME READY STATUS RESTARTS AGE
pod/nginx-85b98978db-4nlx9 1/1 Running 0 66s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.200.0.1 <none> 443/TCP 76m
service/nginx NodePort 10.200.202.133 <none> 80:30528/TCP 31m
测试访问,返回 nginx 页面信息
root@kube-master:~# curl 192.168.1.201:30528
高可用集群拓扑
参考文档:高可用拓扑选项 | Kubernetes
高可用(HA) Kubernetes 集群拓扑通常可以分成两个选项
- 使用堆叠(stacked)控制平面节点,其中 etcd 节点与控制平面节点共存
- 使用外部 etcd 节点,其中 etcd 在与控制平面不同的节点上运行
堆叠(Stacked) etcd 拓扑
拓扑图
堆叠(Stacked) HA 集群最主要的特点:etcd 分布式数据存储集群堆叠在 kubeadm 管理的控制平面节点上,作为控制平面的一个组件运行
每个控制平面节点运行 kube-apiserver
,kube-scheduler
和 kube-controller-manager
实例。其中,kube-apiserver
使用负载均衡器暴露给工作节点
此外,每个控制平面节点会创建一个本地 etcd 成员(member),这个 etcd 成员只与该节点的 kube-apiserver
通信。这同样适用于本地 kube-controller-manager
和 kube-scheduler
实例
这是 kubeadm 中的默认拓扑。当使用 kubeadm init
和 kubeadm join --control-plane
时,在控制平面节点上会自动创建本地 etcd 成员
优缺点
-
优点:这种拓扑将控制平面和 etcd 成员耦合在同一节点上。相对使用外部 etcd 集群,设置起来更简单,而且更易于副本管理。
-
缺点:堆叠集群存在耦合失败的风险。如果一个节点发生故障,则 etcd 成员和控制平面实例都将丢失,并且冗余会受到影响。您可以通过添加更多控制平面节点来降低此风险
因此,如果使用堆叠(Stacked) etcd 拓扑,则至少应该为 HA 集群运行三个堆叠的控制平面节点
外部 etcd 拓扑
拓扑图
外部 etcd 的 HA 集群最主要的特点: etcd 分布式数据存储集群在独立于控制平面节点的其他节点上运行
每个控制平面节点都运行 kube-apiserver
,kube-scheduler
和 kube-controller-manager
实例。同样, kube-apiserver
使用负载均衡器暴露给工作节点。
与堆叠(Stacked) etcd 拓扑不同的是,在外部 etcd 拓扑中,etcd 成员在非控制平面节点主机上运行,每个 etcd 主机与每个控制平面节点的 kube-apiserver
通信
优缺点
- 优点:这种拓扑结构解耦了控制平面和 etcd 成员。在失去控制平面实例或者 etcd 成员时,产生影响较小,并且不会像堆叠的 HA 拓扑那样影响整个集群冗余
- 缺点:此拓扑需要两倍于堆叠 HA 拓扑的主机数量
因此,如果使用外部 etcd 拓扑,则 HA 集群至少需要三个用于控制平面节点的主机和三个用于 etcd 节点的主机
创建高可用集群
堆叠(Stacked) etcd 拓扑的高可用集群构建可以参考:利用 kubeadm 创建高可用集群 | Kubernetes
外部 etcd 拓扑的高可用集群构建可以参考:利用 kubeadm 创建高可用集群 | Kubernetes
本文选用堆叠(Stacked) etcd 拓扑的高可用集群
准备
使用 5 台主机,其中 3 台作为控制面节点,2 台作为工作节点
拓扑结构
主机列表
主机 | IP | 角色 | 安装服务 |
---|---|---|---|
kube-master-1.skynemo.cn | 192.168.1.201 | 控制面节点-1 | docker: 20.10.6 kubeadm: 1.23.5 kubelet: 1.23.5 kubectl: 1.23.5 |
kube-master-2.skynemo.cn | 192.168.1.202 | 控制面节点-2 | docker: 20.10.6 kubeadm: 1.23.5 kubelet: 1.23.5 kubectl: 1.23.5 |
kube-master-3.skynemo.cn | 192.168.1.203 | 控制面节点-3 | docker: 20.10.6 kubeadm: 1.23.5 kubelet: 1.23.5 kubectl: 1.23.5 |
kube-worker-1.skynemo.cn | 192.168.1.204 | 工作节点-1 | docker: 20.10.6 kubeadm: 1.23.5 kubelet: 1.23.5 kubectl: 1.23.5 |
kube-worker-2.skynemo.cn | 192.168.1.205 | 工作节点-2 | docker: 20.10.6 kubeadm: 1.23.5 kubelet: 1.23.5 kubectl: 1.23.5 |
haproxy.skynemo.cn | 192.168.1.206 | 负载均衡 | HAProxy 2.4 |
Kubeadm 相关安装过程省略,详见:安装 Kubeadm
HAProxy 安装过程省略,详见:HAProxy 安装
下载镜像
默认镜像仓库由 google 提供(地址为:k8s.gcr.io),国内无法访问,可以使用本人在阿里云仓库保存的镜像
提前下载好所需的镜像,防止在构建过程中因镜像下载异常而导致部署失败
控制面节点下载镜像
所有控制面节点下载如下镜像
root@kube-master:~# docker pull registry.cn-shanghai.aliyuncs.com/sync-k8s-images/kube-apiserver:v1.23.5
root@kube-master:~# docker pull registry.cn-shanghai.aliyuncs.com/sync-k8s-images/kube-controller-manager:v1.23.5
root@kube-master:~# docker pull registry.cn-shanghai.aliyuncs.com/sync-k8s-images/kube-scheduler:v1.23.5
root@kube-master:~# docker pull registry.cn-shanghai.aliyuncs.com/sync-k8s-images/pause:3.6
root@kube-master:~# docker pull registry.cn-shanghai.aliyuncs.com/sync-k8s-images/etcd:3.5.1-0
root@kube-master:~# docker pull registry.cn-shanghai.aliyuncs.com/sync-k8s-images/coredns:v1.8.6
工作节点下载镜像
工作节点下载如下镜像
root@kube-master:~# docker pull registry.cn-shanghai.aliyuncs.com/sync-k8s-images/kube-proxy:v1.23.5
配置 HAProxy
配置
代理三个控制面节点
root@haproxy:~# vim /etc/haproxy/haproxy.cfg
global
maxconn 100000
chroot /apps/haproxy/empty
stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin
user haproxy
group haproxy
daemon
pidfile /var/lib/haproxy/haproxy.pid
log 127.0.0.1 local2 info
defaults
option http-keep-alive
option forwardfor
maxconn 100000
mode http
timeout connect 300000ms
timeout client 300000ms
timeout server 300000ms
# 配置状态页面,方便查看代理情况
listen stats
mode http
bind 0.0.0.0:9999
stats enable
log global
stats uri /haproxy-status # haproxy 状态页 URL
stats auth haadmin:520123 # Haproxy 状态页用户名/密码
# 配置控制面节点的代理
listen kube-apiserver
bind 192.168.1.206:6443
mode tcp
log global
balance source
server kube-master-1 192.168.1.201:6443 check inter 3000 fall 2 rise 5
server kube-master-2 192.168.1.202:6443 check inter 3000 fall 2 rise 5
server kube-master-3 192.168.1.203:6443 check inter 3000 fall 2 rise 5
重启 HAProxy
重启使配置生效
root@haproxy:~# systemctl restart haproxy
查看 HAProxy 状态页面
在 初始化或加入控制面节点后 ,可以检查 HAProxy 状态页面,看代理是否正常,未初始化时显示红色
初始化第一个控制面节点
可以使用命令或者配置文件初始化节点,选一即可
需要注意以下参数的设置:
apiserver-advertise-address
:设置为当前节点的 IPapiserver-bind-port
:设置为当前节点 apiserver 绑定的端口control-plane-endpoint
:设置为负载均衡器(此处为 HAProxy)的 VIP-upload-certs
:将在所有控制平面实例之间的共享证书上传到集群
方式一:基于命令初始化(推荐)
root@kube-master-1:~# kubeadm init \
--apiserver-advertise-address=192.168.1.201 \
--apiserver-bind-port=6443 \
--control-plane-endpoint=192.168.1.206 \
--kubernetes-version=v1.23.5 \
--pod-network-cidr=10.100.0.0/16 \
--service-cidr=10.200.0.0/16 \
--service-dns-domain=skynemo.cn \
--image-repository=registry.cn-shanghai.aliyuncs.com/sync-k8s-images \
--upload-certs
方式二:基于配置文件初始化(不推荐)
构建配置文件
# 将默认的初始化设置输出到文件
root@kube-master-1:~# kubeadm config print init-defaults > kubeadm-init.yaml
# 修改配置文件
# 主要修改绑定的 IP、端口、代理 IP、k8s 版本、网络等等
root@kube-master-1:~# vim kubeadm-init.yaml
基于文件执行初始化
root@kube-master-1:~# kubeadm init --config kubeadm-init.yaml
初始化信息
需要记录初始化时的输出信息,这些信息可以用来将控制平面节点和工作节点加入集群
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/
You can now join any number of the control-plane node running the following command on each as root:
kubeadm join 192.168.1.206:6443 --token ch3ac2.4mvbqy7yxglj61r5 \
--discovery-token-ca-cert-hash sha256:e61f9d225786478692201f31dc96620303e1d246d2b9bd9c934ced8c3c5e0a7c \
--control-plane --certificate-key 515d5f0ac58789a8db3a4bce4d6c8a34386fa43eba9b8e6ff8c4176b34f154d1
Please note that the certificate-key gives access to cluster sensitive data, keep it secret!
As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use
"kubeadm init phase upload-certs --upload-certs" to reload certs afterward.
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.1.206:6443 --token ch3ac2.4mvbqy7yxglj61r5 \
--discovery-token-ca-cert-hash sha256:e61f9d225786478692201f31dc96620303e1d246d2b9bd9c934ced8c3c5e0a7c
证书操作
查看证书有效期
root@kube-master-1:~# kubeadm certs check-expiration
[check-expiration] Reading configuration from the cluster...
[check-expiration] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
W0508 01:51:50.729401 5228 utils.go:69] The recommended value for "resolvConf" in "KubeletConfiguration" is: /run/systemd/resolve/resolv.conf; the provided value is: /run/systemd/resolve/resolv.conf
CERTIFICATE EXPIRES RESIDUAL TIME CERTIFICATE AUTHORITY EXTERNALLY MANAGED
admin.conf May 06, 2023 19:41 UTC 364d ca no
apiserver May 06, 2023 19:41 UTC 364d ca no
apiserver-etcd-client May 06, 2023 19:41 UTC 364d etcd-ca no
apiserver-kubelet-client May 06, 2023 19:41 UTC 364d ca no
controller-manager.conf May 06, 2023 19:41 UTC 364d ca no
etcd-healthcheck-client May 06, 2023 19:41 UTC 364d etcd-ca no
etcd-peer May 06, 2023 19:41 UTC 364d etcd-ca no
etcd-server May 06, 2023 19:41 UTC 364d etcd-ca no
front-proxy-client May 06, 2023 19:41 UTC 364d front-proxy-ca no
scheduler.conf May 06, 2023 19:41 UTC 364d ca no
CERTIFICATE AUTHORITY EXPIRES RESIDUAL TIME EXTERNALLY MANAGED
ca May 03, 2032 19:41 UTC 9y no
etcd-ca May 03, 2032 19:41 UTC 9y no
front-proxy-ca May 03, 2032 19:41 UTC 9y no
更新证书有效期
需要重启 kube-apiserver
、 kube-controller-manager
、 kube-scheduler
、etcd
后才会生效,kubeadm 管理的集群可以选择 重启 kubelet
在所有控制面节点依次执行以下命令
# 更新证书
root@kube-master-1:~# kubeadm certs renew all
# 重启使证书生效
root@kube-master-1:~# systemctl restart kubelet
Token 操作
当使用 --upload-certs
调用 kubeadm init
时,主控制平面的证书被加密并上传到 kubeadm-certs
Secret 中,生成 Token。其他节点加入集群时,需要提供 Token 和密钥(由 --certificate-key
选项指定)
查看 Token有效期
root@kube-master-1:~# kubeadm token list
TOKEN TTL EXPIRES USAGES DESCRIPTION EXTRA GROUPS
a2ib8m.ss02ch6lvlt98jxf 53m 2022-05-06T21:41:52Z <none> Proxy for managing TTL for the kubeadm-certs secret <none>
ch3ac2.4mvbqy7yxglj61r5 22h 2022-05-07T19:41:52Z authentication,signing The default bootstrap token generated by 'kubeadm init'. system:bootstrappers:kubeadm:default-node-token
可以看到有两个 token
- 第一个 Token 用来管理
kubeadm-certs
Secret 中的证书有效时间,默认有效期为 2 小时 - 第二个 Token 用于其他节点加入集群,默认有效期为 24 小时
重新上传证书
如果 kubeadm-certs
Secret 中的证书已过期,可以重新上传证书并生成新的解密密钥,需要在已加入集群的控制平面节点上运行命令
kubeadm init phase upload-certs --upload-certs
# 输出信息包含 certificate key
重新生成 Token
默认 Token 有效期为24小时,当过期之后,该 Token 就不可用了。这时就需要重新创建 Token
方式一
# 生成 token
root@kube-master-1:~# kubeadm token create
p28vsh.p9jsja0q4pncwbtn
# 获取CA 证书的 hash 值
root@kube-master-1:~# openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt \
| openssl rsa -pubin -outform der 2>/dev/null \
| openssl dgst -sha256 -hex | sed 's/^.* //'
e61f9d225786478692201f31dc96620303e1d246d2b9bd9c934ced8c3c5e0a7c
# 工作节点加入集群
kubeadm join 192.168.1.206:6443 --token p28vsh.p9jsja0q4pncwbtn \
--discovery-token-ca-cert-hash sha256:e61f9d225786478692201f31dc96620303e1d246d2b9bd9c934ced8c3c5e0a7c
方式二
# 直接生成工作节点加入集群的命令(包含 token 和 hash 值)
root@kube-master-1:~# kubeadm token create --print-join-command
kubeadm join 192.168.1.206:6443 --token 3uemx2.g4x8m8cbe2gjrxkg \
--discovery-token-ca-cert-hash sha256:e61f9d225786478692201f31dc96620303e1d246d2b9bd9c934ced8c3c5e0a7c
配置使用 kubectl
若要使非 root 用户可以运行 kubectl
,请运行以下命令, 它们是 kubeadm init
输出的一部分配置,包含了请求的证书、密钥等信息
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
如果你是 root
用户,则可以配置环境变量 KUBECONFIG=/etc/kubernetes/admin.conf
# 配置永久环境变量
root@kube-master-1:~# cat > /etc/profile.d/kubeconfig.sh << EOF
export KUBECONFIG=/etc/kubernetes/admin.conf
EOF
# 加载环境变量
root@kube-master-1:~# source /etc/profile
部署网络插件
支持的网络插件列表: 集群网络系统 | Kubernetes
常用的网络插件有: Calico、flannel
flannel 镜像地址: rancher/mirrored-flannelcni-flannel Tags | Docker Hub
在安装网络之前,集群 DNS (CoreDNS) 不会启动
# 查看当前的 pod 状态,会发现 coredns 没有启动
root@kube-master-1:~# kubectl get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-bc5b69cd6-qnxmz 0/1 Pending 0 7m51s
kube-system coredns-bc5b69cd6-sctmz 0/1 Pending 0 7m51s
kube-system etcd-kube-master-1.skynemo.cn 1/1 Running 0 7m50s
kube-system kube-apiserver-kube-master-1.skynemo.cn 1/1 Running 0 7m50s
kube-system kube-controller-manager-kube-master-1.skynemo.cn 1/1 Running 2 7m50s
kube-system kube-proxy-gg7m5 1/1 Running 0 7m51s
kube-system kube-scheduler-kube-master-1.skynemo.cn 1/1 Running 2 7m50s
部署网络插件
注: 每个集群只能安装一个Pod网络,此处一flannel为例,Calico部署方式类似
# 下载配置文件
root@kube-master-1:~# curl -o kube-flannel-v0.17.0-release.yml \
https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
# 如果无法访问外网,可以使用作者的配置备份
# curl -O https://resource-1258540788.file.myqcloud.com/99-external-resource/01-kubernetes/01-flannel/kube-flannel-v0.17.0-release.yml
# 修改网络与 kubeadm init 配置的 pod 网络(由初始化选项 pod-network-cidr 指定)一致
root@kube-master-1:~# vim kube-flannel-v0.17.0-release.yml
......
net-conf.json: |
{
"Network": "10.100.0.0/16",
"Backend": {
"Type": "vxlan"
}
}
......
# 直接使用 kubectl 应用部署
root@kube-master-1:~# kubectl apply -f kube-flannel-v0.17.0-release.yml
检验集群 DNS (CoreDNS) 是否启动
root@kube-master-1:~# kubectl get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-bc5b69cd6-qnxmz 1/1 Running 0 59m
kube-system coredns-bc5b69cd6-sctmz 1/1 Running 0 59m
kube-system etcd-kube-master-1.skynemo.cn 1/1 Running 0 59m
kube-system kube-apiserver-kube-master-1.skynemo.cn 1/1 Running 0 59m
kube-system kube-controller-manager-kube-master-1.skynemo.cn 1/1 Running 2 59m
kube-system kube-flannel-ds-xpq4g 1/1 Running 0 2m38s
kube-system kube-proxy-gg7m5 1/1 Running 0 59m
kube-system kube-scheduler-kube-master-1.skynemo.cn 1/1 Running 2 59m
加入其他控制面节点
其余两个控制面节点均操作
从 kubeadm 1.15 版本开始,你可以并行加入多个控制平面节点。 在此版本之前,你必须在第一个节点初始化后才能依序的增加新的控制平面节点
执行先前由第一个节点上的 kubeadm init
命令初始化时输出信息的 join 命令
# 如果重新加载过证书,则使用新的 token 和 certificate-key
root@kube-master-2:~# kubeadm join 192.168.1.206:6443 --token ch3ac2.4mvbqy7yxglj61r5 \
--discovery-token-ca-cert-hash sha256:e61f9d225786478692201f31dc96620303e1d246d2b9bd9c934ced8c3c5e0a7c \
--control-plane --certificate-key 515d5f0ac58789a8db3a4bce4d6c8a34386fa43eba9b8e6ff8c4176b34f154d1
# 加入成功提示信息
This node has joined the cluster and a new control plane instance was created:
* Certificate signing request was sent to apiserver and approval was received.
* The Kubelet was informed of the new secure connection details.
* Control plane (master) label and taint were applied to the new node.
* The Kubernetes control plane instances scaled up.
* A new etcd member was added to the local/stacked etcd cluster.
To start administering your cluster from this node, 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
Run 'kubectl get nodes' to see this node join the cluster.
- 这个
-control-plane
标志通知kubeadm join
创建一个新的控制平面。 -certificate-key ...
将从集群中的kubeadm-certs
Secret 下载控制平面证书并使用给定的密钥进行解密
加入工作节点
在工作节点上操作
使用之前保存的 kubeadm init
命令初始化时输出信息的 join 命令,将工作节点加入集群中:
# 加入集群
root@kube-worker-1:~# kubeadm join 192.168.1.206:6443 --token ch3ac2.4mvbqy7yxglj61r5 \
--discovery-token-ca-cert-hash sha256:e61f9d225786478692201f31dc96620303e1d246d2b9bd9c934ced8c3c5e0a7c
# 加入成功时输出信息
This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.
Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
验证
查看当前 Node 状态
root@kube-master-1:~# kubectl get node
NAME STATUS ROLES AGE VERSION
kube-master-1.skynemo.cn Ready control-plane,master 25h v1.23.5
kube-master-2.skynemo.cn Ready control-plane,master 49m v1.23.5
kube-master-3.skynemo.cn Ready control-plane,master 38m v1.23.5
kube-worker-1.skynemo.cn Ready <none> 2m21s v1.23.5
kube-worker-2.skynemo.cn Ready <none> 2m7s v1.23.5
查看当前证书状态
root@kube-master-1:~# kubectl get csr
NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION
csr-6bzs7 50m kubernetes.io/kube-apiserver-client-kubelet system:bootstrap:3uemx2 <none> Approved,Issued
csr-cwqn5 6m53s kubernetes.io/kube-apiserver-client-kubelet system:bootstrap:3uemx2 <none> Approved,Issued
csr-gdsdc 39m kubernetes.io/kube-apiserver-client-kubelet system:bootstrap:3uemx2 <none> Approved,Issued
csr-kpw8s 2m22s kubernetes.io/kube-apiserver-client-kubelet system:bootstrap:3uemx2 <none> Approved,Issued
csr-nfphs 2m26s kubernetes.io/kube-apiserver-client-kubelet system:bootstrap:3uemx2 <none> Approved,Issued
csr-rjtg5 6m58s kubernetes.io/kube-apiserver-client-kubelet system:bootstrap:3uemx2 <none> Approved,Issued
测试 Pod 的可用性
编写配置文件
# 创建配置文件
root@kube-master-1:~# vim busybox.yaml
apiVersion: v1
kind: Pod
metadata:
name: busybox1
labels:
app: busybox1
spec:
containers:
- image: busybox
command:
- sleep
- "3600"
imagePullPolicy: IfNotPresent
name: busybox
restartPolicy: Always
创建容器
# 创建容器
root@kube-master-1:~# kubectl create -f busybox.yaml
pod/busybox1 created
查看容器
root@kube-master-1:~# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
busybox1 1/1 Running 0 3m25s 10.100.3.2 kube-worker-1.skynemo.cn <none> <none>
测试网络
# 进入容器并 ping 测试对外网络
root@kube-master-1:~# kubectl exec -it busybox1 -- /bin/sh
/ # ping www.baidu.com
PING www.baidu.com (112.80.248.76): 56 data bytes
64 bytes from 112.80.248.76: seq=0 ttl=127 time=11.764 ms
64 bytes from 112.80.248.76: seq=1 ttl=127 time=13.045 ms
^C
--- www.baidu.com ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 11.764/12.404/13.045 ms
/ #
删除并清理节点
标识即将删除
使用适当的凭证与控制平面节点通信,运行以下命令
kubectl drain <node name> --delete-emptydir-data --force --ignore-daemonsets
清理节点配置
然后在要清理的节点上重置 kubeadm
安装的状态
kubeadm reset
重置过程不会重置或清除 iptables 规则或 IPVS 表。如果你希望重置 iptables,则必须手动进行
iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X
如果要重置 IPVS 表,则必须运行以下命令
ipvsadm -C
删除节点
kubectl delete node <node name>
附录
端口与协议
当你在一个有严格网络边界的环境里运行 Kubernetes,例如拥有物理网络防火墙或者拥有公有云中虚拟网络的自有数据中心,了解 Kubernetes 组件使用了哪些端口和协议是非常有用的。
控制面
协议 | 方向 | 端口范围 | 目的 | 使用者 |
---|---|---|---|---|
TCP | 入站 | 6443 | Kubernetes API server | 所有 |
TCP | 入站 | 2379-2380 | etcd server client API | kube-apiserver, etcd |
TCP | 入站 | 10250 | Kubelet API | 自身,控制面 |
TCP | 入站 | 10259 | kube-scheduler | 自身 |
TCP | 入站 | 10257 | kube-controller-manager | 自身 |
尽管 etcd 的端口也列举在控制面的部分,但你也可以在外部自己托管 etcd 集群或者自定义端口。
工作节点
协议 | 方向 | 端口范围 | 目的 | 使用者 |
---|---|---|---|---|
TCP | 入站 | 10250 | Kubelet API | 自身,控制面 |
TCP | 入站 | 30000-32767 | NodePort Services | 所有 |
所有默认端口都可以重新配置。当使用自定义的端口时,你需要打开这些端口来代替这里提到的默认端口。
一个常见的例子是 API 服务器的端口有时会配置为443。或者你也可以使用默认端口,把 API 服务器放到一个监听443 端口的负载均衡器后面,并且路由所有请求到 API 服务器的默认端口。
参数优化
Kubernetes 与 Docker 运行时需要各种系统底层配置支持,推荐按以下参数设置系统
pam_limits.so 限制 limits.conf
root@docker:~# vi /etc/security/limits.conf
# 配置单个用户 core 文件(程序崩溃时的内存镜像)大小,,单位 KB
* soft core unlimited
* hard core unlimited
# 配置单个用户的最大运行线程数
* soft nproc 1000000
* hard nproc 1000000
# 配置单个用户能打开的最大文件数
* soft nofile 1000000
* hard nofile 1000000
# 配置单个用户最大内存锁定地址空间大小,单位 KB
* soft memlock 32000
* hard memlock 32000
# POSIX 消息队列使用的最大内存,单位 bytes
* soft msgqueue 8192000
* hard msgqueue 8192000
系统参数 sysctl.conf
root@docker:~# vi /etc/sysctl.conf
# 开启路由转发
net.ipv4.ip_forward=1
# 配置系统单个进程可以拥有的 VMA (虚拟内存区域)的数量,ES的最低要求为 262144
vm.max_map_count=262144
# Linux 的最大进程数
kernel.pid_max=4194303
# 系统能够打开的文件句柄的数量(整个系统的限制),注意与 ulimit 的区别
fs.file-max=1000000
# timewait 的数量,默认 180000
net.ipv4.tcp_max_tw_buckets=6000
# 防火墙表大小,默认65536
net.netfilter.nf_conntrack_max=2097152
# 二层的网桥在转发包时是否被 iptables 的 FORWARD 规则所过滤
# 部分 K8S 网络插件依赖于 iptables,所以需要开启
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
# 尽量不使用 swap
vm.swappiness=0
应用参数
root@docker:~# sysctl -p
评论区