012、基于kubeadm部署K8S集群
本文最后更新于 68 天前,其中的信息可能已经过时,如有错误请发送邮件到wuxianglongblog@163.com

基于kubeadm部署K8S集群

一.部署K8S集群的环境准备

1.虚拟机准备环境

(1)一台兼容的Linux主机。Kubernetes项目为基于Debian和Red Hat的Linux发行版以及一些不提供包管理器的发行版提供通用的指令;
(2)每台机器2GB或更多的RAM(如果少于这个数字将会影响你应用的运行内存),2个CPU核或更多;
(3)集群中的所有机器的网络彼此均能相互连接(公网和内网都可以);

推荐阅读:
    https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/#before-you-begin

温馨提示:
    如下图所示,强烈建议将集群的所有主机名在host文件中进行解析。

2.关闭交换分区

临时禁用swap分区:
    swapoff -a

永久禁用swap分区:
    修改"/etc/fstab"配置文件即可。

1637286254299

3.确保每个节点上 MAC 地址和 product_uuid 的唯一性

(1)你可以使用命令"ip link"或"ifconfig -a"来获取网络接口的MAC地址;

(2)使用 "cat /sys/class/dmi/id/product_uuid"命令对product_uuid校验

温馨提示:
    一般来讲,硬件设备会拥有唯一的地址,但是有些虚拟机的地址可能会重复。 
    Kubernetes使用这些值来唯一确定集群中的节点。 如果这些值在每个节点上不唯一,可能会导致安装失败。

4.检查网络适配器

简而言之,就是检查你的K8S集群各个节点是否互通!如果各节点并不互通,请不要继续下面的步骤啦!

温馨提示:
    可以使用ping命令进行测试哟~

5.允许iptables检查桥接流量

(1)确保"br_netfilter"模块被加载。这一操作可以通过运行"lsmod | grep br_netfilter"来完成。

(2)若要显式加载该模块,可执行"modprobe br_netfilter"

详细操作如下:
lsmod | grep br_netfilter

modprobe br_netfilter

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF

cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF

sudo sysctl --system

image-20210926212129260

6.检查所需端口是否被占用

如下图所示,对应master和node节点其需要占用的端口范围,如果防火墙已开,请检查这些端口是否已被放行!

推荐阅读:
    https://kubernetes.io/docs/reference/ports-and-protocols/
    https://kubernetes.io/zh/docs/concepts/services-networking/service/

image-20210926212514750

7.安装容器运行时

为了在Pod中运行容器,Kubernetes使用容器运行时(Container Runtime)。

默认情况下,Kubernetes使用容器运行时接口(Container Runtime Interface,CRI)来与你所选择的容器运行时交互。如果你不指定运行时,则kubeadm会自动尝试检测到系统上已经安装的运行时, 方法是扫描一组众所周知的Unix 域套接字。

下面的表格列举了一些容器运行时及其对应的套接字路径:
    Docker:
        /var/run/dockershim.sock
    containerd:
        /run/containerd/containerd.sock
    CRI-O:
        /var/run/crio/crio.sock

如果同时检测到Docker和containerd,则优先选择Docker,因为Docker 18.09附带了containerd并且两者都是可以检测到的。如果检测到其他两个或多个运行时,kubeadm输出错误信息并退出。

kubelet通过内置的dockershim CRI实现与Docker集成。

#所有节点
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
curl -o /etc/yum.repos.d/docker-ce.repo https://download.docker.com/linux/centos/docker-ce.repo
sed -i 's+download.docker.com+mirrors.tuna.tsinghua.edu.cn/docker-ce+' /etc/yum.repos.d/docker-ce.repo
yum list docker-ce --showduplicates

#安装指定版本的docker,如下图所示,对于K8S 1.15版本最高支持的docker版本为18.09哟~
yum -y install docker-ce-18.09.9 docker-ce-cli-18.09.9
yum -y install bash-completion
source /usr/share/bash-completion/bash_completion

# 配置Docker守护程序,尤其是使用systemd来管理容器的cgroup,否则会导致kubelet无法正常启动哟~
mkdir /etc/docker
cat <<EOF | sudo tee /etc/docker/daemon.json
{
  "insecure-registries": ["k8s221.oldboyedu.com:5000"],
  "registry-mirrors": ["https://tuv7rqqq.mirror.aliyuncs.com"],
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2"
}
EOF

# 重新启动Docker并在启动时启用
systemctl enable docker
systemctl daemon-reload
systemctl restart docker

推荐阅读:
    https://kubernetes.io/zh/docs/setup/production-environment/container-runtimes/
    https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.15.md#unchanged

温馨提示:
    如下图所示,如果你安装的是K8S1.15版本,则最高支持"18.09"的docker版本哟~

image-20211110114528215

8.禁用selinux服务

setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

温馨提示:
     (1)SELinux设置为permissive模式相当于将其禁用;
     (2)禁用selinux这是允许容器访问主机文件系统所必需的,而这些操作时为了Pod网络工作正常。你必须这么做,直到kubelet做出对SELinux的支持进行升级为止;
     (3)如果你知道如何配置 SELinux则可以将其保持启用状态,但可能需要设定kubeadm不支持的部分配置;

9.推荐阅读

https://kubernetes.io/zh/docs/setup/production-environment/container-runtimes/

https://kubernetes.io/zh/docs/tasks/administer-cluster/kubeadm/configure-cgroup-driver/

https://kubernetes.io/zh/docs/setup/production-environment/tools/kubeadm/troubleshooting-kubeadm/

https://kubernetes.io/zh/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/

二.安装 kubeadm、kubelet 和 kubectl

1.待安装软件包作用说明

你需要在每台机器上安装以下的软件包:
    kubeadm:
        用来初始化集群的指令。
    kubelet:
        在集群中的每个节点上用来启动Pod和容器等。
    kubectl:
        用来与集群通信的命令行工具。

kubeadm不能帮你安装或者管理kubelet或kubectl,所以你需要确保它们与通过kubeadm安装的控制平面(master)的版本相匹配。 如果不这样做,则存在发生版本偏差的风险,可能会导致一些预料之外的错误和问题。 

然而,控制平面与kubelet间的相差一个次要版本不一致是支持的,但kubelet的版本不可以超过"API SERVER"的版本。 例如,1.7.0版本的kubelet可以完全兼容1.8.0版本的"API SERVER",反之则不可以。

推荐阅读:
    https://kubernetes.io/zh/docs/tasks/tools/

2.所有节点安装kubeadm软件包

(1)配置软件源
cat  > /etc/yum.repos.d/kubernetes.repo <<EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

(2)安装指定的kubeadm版本
yum -y install kubelet-1.15.12-0 kubeadm-1.15.12-0 kubectl-1.15.12-0 
systemctl enable kubelet && systemctl start kubelet

(3)查看kubeadm的版本(将来你要安装的K8S时请所有组件版本均保持一致!)
yum list kubeadm --showduplicates | sort -r

温馨提示:
    如下图所示,kubelet服务会启动失败,很可能是缺少"/var/lib/kubelet/config.yaml"文件,但不用着急,因为后面我们将node节点加入到集群后,你就会发现kubelet服务可以启动成功啦!

image-20211112104642439

3.使用kubeadm工具初始化一套k8s集群

kubeadm init --kubernetes-version=v1.15.12 --image-repository registry.aliyuncs.com/google_containers  --pod-network-cidr=10.244.0.0/16 --service-cidr=10.254.0.0/16

使用kubeadm初始化集群时,存在以下几个优点:
[init] 
    使用初始化的K8S版本。

[preflight] 
    主要是做安装K8S集群的前置工作,比如下载镜像,这个时间取决于你的网速。

[certs] 
    生成证书文件,默认存储在"/etc/kubernetes/pki"目录哟。

[kubeconfig]
    生成K8S集群的默认配置文件,默认存储在"/etc/kubernetes"目录哟。

[kubelet-start] 
    启动kubelet,
    环境变量默认写入:"/var/lib/kubelet/kubeadm-flags.env"
    配置文件默认写入:"/var/lib/kubelet/config.yaml"

[control-plane]
    使用静态的目录,默认的资源清单存放在:"/etc/kubernetes/manifests"。
    此过程会创建静态Pod,包括"kube-apiserver","kube-controller-manager"和"kube-scheduler"

[etcd] 
    创建etcd的静态Pod,默认的资源清单存放在:""/etc/kubernetes/manifests"

[wait-control-plane] 
    等待kubelet从资源清单目录"/etc/kubernetes/manifests"启动静态Pod。

[apiclient]
    等待所有的master组件正常运行。

[upload-config] 
    创建名为"kubeadm-config"的ConfigMap在"kube-system"名称空间中。

[kubelet] 
    创建名为"kubelet-config-1.22"的ConfigMap在"kube-system"名称空间中,其中包含集群中kubelet的配置

[upload-certs] 
    跳过此节点,详情请参考”--upload-certs"

[mark-control-plane]
    标记控制面板,包括打标签和污点,目的是为了标记master节点。

[bootstrap-token] 
    创建token口令,例如:"kbkgsa.fc97518diw8bdqid"。
    如下图所示,这个口令将来在加入集群节点时很有用,而且对于RBAC控制也很有用处哟。

[kubelet-finalize] 
    更新kubelet的证书文件信息

[addons] 
    添加附加组件,例如:"CoreDNS"和"kube-proxy”

image-20211112110212003

4.创建管理员证书文件

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

温馨提示:
    如下图所示,当我们执行上述3条命令后,就可以正常管理集群啦!

image-20211112110703521

5.部署Pod附加组件(可以先跳过)

推荐阅读:
    https://kubernetes.io/docs/concepts/cluster-administration/addons/

温馨提示:
    (1)我们可以直接先暂时性跳过此步骤,先继续下一个步骤即可!因为后面会有专门的章节部署网络组件哟~
    (2)此处我们故意不部署网络插件,一会集群部署成功后,节点状态会一致处于"NotReady"哟~

image-20211112111054508

6.node节点加入到现有集群

image-20211112112329740

kubeadm join 10.0.0.151:6443 --token kbkgsa.fc97518diw8bdqid \
    --discovery-token-ca-cert-hash sha256:e7a83697658c085f68618edaa61a17798b4ce635eb97d05f515f3a9d5354c377 

温馨提示:
    如下图所示,我们成功的加入到咱们部署的集群啦。

image-20211112115356986

7.移除node节点案例:star:(面试题)

image-20211112123218917

(1)驱逐这个node节点上的pod
kubectl drain k8s155.oldboyedu.com  --delete-local-data --force --ignore-daemonsets

也可以通过打污点的方式驱赶Pod资源:
kubectl taint node k8s204.oldboyedu.com school=oldboyedu:NoExecute 

(2)删除这个node节点
kubectl delete node k8s155.oldboyedu.com

(3)在node节点执行如下命令
kubeadm reset -f

温馨提示:
    运行"kubeadm reset -f"可还原“kubeadm init”或“kubeadm join”对此主机所做的任何更改;

三.kubeadm有关token的管理,有效防止token过期的场景

1.查看集群现有的token

通过上面的案例想必大家都已经清楚了token的作用,那一但token挂掉后,由该如何解决呢?

我们可以使用"kubeadm token --help"指令来查看有关token声明周期的管理。

2.查看现有的token信息

kubeadm token list

image-20211005143317400

3.删除指定的token

kubeadm token delete [token-value]

温馨提示:
    如下图所示,我们可以直接删除指定的token,详细信息请参考“kubeadm token delete --help”

image-20211005143555551

4.创建topken

kubeadm token create --print-join-command
    默认设置一个24h的token,并打印node节点加入集群的命令.

kubeadm token create --ttl 8760h 
    设置一个一年的token.

kubeadm token create --ttl 0
    设置一个永久的token.

详情请参考"kubeadm token create --help"

image-20211005144414125

5.node节点使用新创建的token重新将加入K8S集群

kubeadm join 10.0.0.101:6443 --token vfojxf.i17e7y35p7815nho --discovery-token-ca-cert-hash sha256:f37c6ed0b13719c6de8f730ef821bf16ee7e2561cd7716d7a08dfa46437a56de

温馨提示:
    建议使用还未加入集群的节点测试哟,这样效果更加明显!

四.部署网络插件

1.K8S集群的网络插件概述

如下图所示,网络插件也是附加组件,集群如果想要正常通信,我们就必须任选其一进行部署。

其中flannel和calico这两款网络插件都是企业应用较为广泛的插件,此处我们以部署flannel网络插件进行展示!

像Kubernetes这样的平台假设每个容器 (pod) 在集群内都有一个唯一的、可路由的IP。该模型的优势在于它消除了共享单个主机IP所带来的端口映射复杂性。

Flannel负责在集群中的多个节点之间提供第3层IPv4网络。Flannel不控制容器如何与主机联网,只控制如何在主机之间传输流量。但是,flannel确实为Kubernetes提供了CNI插件以及与Docker集成的指南。

Flannel专注于网络。对于网络策略,可以使用Calico等其他项目。

推荐阅读:
    https://kubernetes.io/docs/concepts/cluster-administration/addons
    https://github.com/flannel-io/flannel#deploying-flannel-manually
    https://docs.projectcalico.org/getting-started/kubernetes/quickstart

image-20211005154115908

2.部署flannel网络插件

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

温馨提示:
    (1)如果网络不是特别好的小伙伴,可以考虑先把配置文件下载到本地哟;
    (2)如果Pod始终处于"Pending"状态,请检查目标节点的docker和kubelet组件是否正常工作哟;

image-20211112124907732

3.验证集群节点是否正常工作

任意找两个工作节点启动一个测试Pod并能相互连接即可。

五.小彩蛋

1.有关docker的自动补全功能

很明显,如果你安装咱们的笔记来部署K8S集群时,你可以很容易的发现其本身就是支持自动补全的。

如果你并不是安装上面的笔记来的也没有关系,参考以下内容即可:
yum -y install bash-completion
source /usr/share/bash-completion/bash_completion

2.有关kubelet的自动补全功能

(1)安装bash-completion
yum -y install bash-completion 
source /usr/share/bash-completion/bash_completion  # 此步骤也可以省略哈!

(2)应用kubectl的completion到系统环境
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc

image-20211005174617398

3.创建docker私有镜像仓库

下面的案例是快速启动一个私有的镜像仓库:
docker container run -itdp 5000:5000  --name oldboyedu-registry --restart always registry

温馨提示:
    此处考虑到学员的虚拟机使用上可能会存在问题,我可以在讲师机上harbor镜像仓库配置一块桥接网卡,这样一来方便让大家和我一起共享镜像哟~

4.kubeadm快速部署的原理

vim /var/lib/kubelet/config.yaml 
...

staticPodPath: /etc/kubernetes/manifests

image-20211112130517656

5.课后作业-部署K8S 1.22集群

如下图所示,使用kubeadm工具部署最新版本的K8S集群。

image-20211112125607142

六.可能会遇到的错误

1. failed to create kubelet: misconfiguration: kubelet cgroup driver: "cgroupfs" is different from docker cgroup driver: "systemd"

问题原因:
    如下图所示,cgroup driver不一致导致,咱们集群默认的是"native.cgroupdriver=systemd"。

解决方案:
    修改驱动,如下所示:
cat /etc/docker/daemon.json 
{
  "insecure-registries": ["k8s201.oldboyedu.com:5000"],
  "registry-mirrors": ["https://tuv7rqqq.mirror.aliyuncs.com"],
  "exec-opts": ["native.cgroupdriver=cgroupfs"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2"
}

1637309747379

谨此笔记,记录过往。凭君阅览,如能收益,莫大奢望。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇