3.Kubernetes学前基础了解

Kubernetes快速学习笔记

说明:如果你能有耐心看完官方文档,那建议不要去看我写的这个东西了。因为学习任何技术,最简单最权威的方法就是去学习官方文档,如果连官方文档都看不下去,那就没必要去看什么书、视频或资料了。其次学习任何东西,先掌握专业名词,搞懂专业名词的意思后再去了解宏观的构建,最后庖丁解牛细化实践,当细化到一定程度后再去反过来宏观理解,自己动手归纳总结,再去看一些高级深入的书籍才有用,不然看到的都是千篇一律的东西浪费时间和精力毫无意义。

1.Kubernetes是什么?

Kubernetes 是一个可移植的、可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化。 Kubernetes 拥有一个庞大且快速增长的生态系统。Kubernetes 的服务、支持和工具广泛可用。

1.1 一张图对比传统部署、虚拟化部署和容器部署方式的差距

特点:

  • 敏捷应用程序的创建和部署:与使用 VM 镜像相比,提高了容器镜像创建的简便性和效率。
  • 持续开发、集成和部署:通过快速简单的回滚(由于镜像不可变性),支持可靠且频繁的 容器镜像构建和部署。
  • 关注开发与运维的分离:在构建/发布时而不是在部署时创建应用程序容器镜像, 从而将应用程序与基础架构分离。
  • 可观察性:不仅可以显示操作系统级别的信息和指标,还可以显示应用程序的运行状况和其他指标信号。
  • 跨开发、测试和生产的环境一致性:在便携式计算机上与在云中相同地运行。
  • 跨云和操作系统发行版本的可移植性:可在 Ubuntu、RHEL、CoreOS、本地、 Google Kubernetes Engine 和其他任何地方运行。
  • 以应用程序为中心的管理:提高抽象级别,从在虚拟硬件上运行 OS 到使用逻辑资源在 OS 上运行应用程序。
  • 松散耦合、分布式、弹性、解放的微服务:应用程序被分解成较小的独立部分, 并且可以动态部署和管理 - 而不是在一台大型单机上整体运行。
  • 资源隔离:可预测的应用程序性能。
  • 资源利用:高效率和高密度

image-20210926091154137

1.2 容器部署为啥需要Kubernetes?解决什么问题?

容器是打包和运行应用程序的好方式。在生产环境中,你需要管理运行应用程序的容器,并确保不会停机。那这里就牵扯到了服务发现、负载均衡、存储编排、自动部署和回滚、资源分配、自我修复、安全管理。

Kubernetes 为你提供:

  • 服务发现和负载均衡

    Kubernetes 可以使用 DNS 名称或自己的 IP 地址公开容器,如果进入容器的流量很大, Kubernetes 可以负载均衡并分配网络流量,从而使部署稳定。

  • 存储编排

    Kubernetes 允许你自动挂载你选择的存储系统,例如本地存储、公共云提供商等。

  • 自动部署和回滚

    你可以使用 Kubernetes 描述已部署容器的所需状态,它可以以受控的速率将实际状态 更改为期望状态。例如,你可以自动化 Kubernetes 来为你的部署创建新容器, 删除现有容器并将它们的所有资源用于新容器。

  • 资源分配

    Kubernetes 允许你指定每个容器所需 CPU 和内存(RAM)。 当容器指定了资源请求时,Kubernetes 可以做出更好的决策来管理容器的资源。

  • 自我修复

    Kubernetes 重新启动失败的容器、替换容器、杀死不响应用户定义的 运行状况检查的容器,并且在准备好服务之前不将其通告给客户端。

  • 密钥与配置管理

    Kubernetes 允许你存储和管理敏感信息,例如密码、OAuth 令牌和 ssh 密钥。 你可以在不重建容器镜像的情况下部署和更新密钥和应用程序配置,也无需在堆栈配置中暴露密钥。

1.3 Kubernetes长啥样子?

image-20210926092841090

一个 Kubernetes 集群由一组被称作节点的机器组成。这些节点上运行 Kubernetes 所管理的容器化应用。集群具有至少一个工作节点。也就是说Node至少有一个,Node上装了容器来提供服务。这些Node一般分布在多个不同的物理主机上或者虚拟机上,也就是说由Control Plane(控制平面)控制了很多机器。

1.4 分解控制平面组件,这些东西都是什么?都起到什么作用?

首先了解Pod是什么?POD这个单词在英语中指夹,类似豌豆夹的意思。我们暂且理解为壳,壳能包裹了容器。

​ Pod是Kubernetes中能够创建和部署的最小单元,是Kubernetes集群中的一个应用实例,总是部署在同一个节点Node上 .Pod中包含了一个或多个容器,还包括了存储、网络等各个容器共享的资源.

image-20210926094711485

​ Pod并不提供保证正常运行的能力,因为可能遭受Node节点的物理故障、网络分区等等的影响,整体的高可用是Kubernetes集群通过在集群内调度Node来实现的。通常情况下我们不要直接创建Pod,一般都是通过Controller来进行管理。

特点:

  • 一般建议一个pod包含一个容器。一个pod包含多个容器的情况,一个Pod内的容器共享IP地址和端口范围,容器之间可以通过 localhost 互相访问。
  • Pod做为一个可以独立运行的服务单元,简化了应用部署的难度,以更高的抽象层次为应用部署管提供了极大的方便。
  • Pod做为最小的应用实例可以独立运行,因此可以方便的进行部署、水平扩展和收缩、方便进行调度管理与资源的分配。
  • Pod中的容器共享相同的数据和网络地址空间,Pod之间也进行了统一的资源管理与分配。

分解Control Plane控制平面组件

image-20210926100330421

控制平面组件可以在集群中的任何节点上运行。 然而,为了简单起见,设置脚本通常会在同一个计算机上启动所有控制平面组件, 并且不会在此计算机上运行用户容器。也就是说控制平面虽然可以在任何节点上运行,但是一般建议放在一个单独的机器节点上做总控。

Kube-apiserver(API服务)

API 服务器是 Kubernetes 控制面的前端, kube-apiserver 设计上考虑了水平伸缩,也就是说,它可通过部署多个实例进行伸缩。 你可以运行 kube-apiserver 的多个实例,并在这些实例之间平衡流量。

etcd(数据库)

etcd 是键值数据库,可以作为保存 Kubernetes 所有集群数据的后台数据库,常需要有个备份计划 。如果要深入了解这个数据库请看ETCD文档

kube-scheduler(负责监视、新建POD,选择NODE让POD运行其上)

负责监视新创建的、未指定运行节点(node)Pods,选择节点让 Pod 在上面运行。

调度决策考虑的因素包括单个 Pod 和 Pod 集合的资源需求、硬件/软件/策略约束、亲和性和反亲和性规范、数据位置、工作负载间的干扰和最后时限。

kube-controller-manager(节点控制器、任务控制器、端点控制器、服务帐户和令牌控制器)

从逻辑上讲,每个控制器都是一个单独的进程, 但是为了降低复杂性,它们都被编译到同一个可执行文件,并在一个进程中运行。

这些控制器包括:

  • 节点控制器(Node Controller): 负责在节点出现故障时进行通知和响应
  • 任务控制器(Job controller): 监测代表一次性任务的 Job 对象,然后创建 Pods 来运行这些任务直至完成
  • 端点控制器(Endpoints Controller): 填充端点(Endpoints)对象(即加入 Service 与 Pod)
  • 服务帐户和令牌控制器(Service Account & Token Controllers): 为新的命名空间创建默认帐户和 API 访问令牌

cloud-controller-manager(云控制器指嵌入特定云的控制逻辑的 控制平面组件)

cloud-controller-manager 仅运行特定于云平台的控制回路,也就说你买个阿里云的K8S集群,可以通过云控制器来控制不同容器间的工作。如果是本地部署,不连接互联网,那就不需要这个控制器。

它和kube-controller-manager基本类似,也有一些控制器,但是依赖于云平台驱动:

  • 节点控制器(Node Controller): 用于在节点终止响应后检查云提供商以确定节点是否已被删除
  • 路由控制器(Route Controller): 用于在底层云基础架构中设置路由
  • 服务控制器(Service Controller): 用于创建、更新和删除云提供商负载均衡器

1.5分解节点Node上的组件

image-20210926103558143

Node是在每个节点上运行,用来维护POD运行,并提供基础的K8S运行环境。

kubelet(在每个节点上运行的代理,它来保证容器都运行在POD中,也就是说它最接近docker本身)

  • kubelet 接收一组通过各类机制提供给它的 PodSpecs,确保这些 PodSpecs 中描述的容器处于运行状态且健康。

  • kubelet 不会管理不是由 Kubernetes 创建的容器,例如自己用docker单独挂的容器是不受kubelet管理的,它只认识自己PodSpecs定义的东西。

另外说一下,PodSpecs咋理解,最简单直观的理解它就是由Pod+Spec两个单词组成。Pod已经说过了,是壳或者夹的意思,Spec是规则的意思。组合一起就不难理解了,是Pod规则列表的意思。

kube-proxy(集群中每个节点上运行的网络代理)

它是做节点上的网络规则。允许从集群内部或外部的网络会话与 Pod 进行网络通信。详情请看官方文档

Container Runtime(容器运行环境)

负责运行容器的软件。这是个概念,它指Docker、containerd、rkt等容器运行环境。它还有一个和CRI接口,来和docker等联通,运行时为容器提供资源使用统计信息。

1.6 插件

插件被用于Kubernetes中实现集群功能。这些插件并非都需要,但有些常见的要了解。具体的插件列表请看插件列表

DNS插件

几乎所有 Kubernetes 集群都应该 有集群 DNS。具体怎么去配置,配置规则是什么可以看官方连接。这里先忽略,后面详细分解,只需要知道就是做解析的就完事。

哪些对象会获得 DNS 记录呢?

  1. Services
  2. Pods

web仪表盘

Dashboard 是 Kubernetes 集群的通用的、基于 Web 的用户界面。 它使用户可以管理集群中运行的应用程序以及集群本身并进行故障排除。怎样安装调试看连接文件,这里先不了解,后面再去看。

容器资源监控

容器资源监控 将关于容器的一些常见的时间序列度量值保存到一个集中的数据库中,并提供用于浏览这些数据的界面。建议采用Prometheus来做监控。

集群日志

负责将容器的日志数据 保存到一个集中的日志存储中,该存储能够提供搜索和浏览接口。要了解日志架构请看连接。

2.初步学习安装K8S

2.1 学习环境安装minikube(不需要的话请直接跳过到2.2)

下载安装包

下载地址在这里,选定好操作系统类型和K8S版本后就出现了下图.

我们进行分步骤安装,安装前为了简单,先把selinux和防火墙关闭。

image-20210926114510263

1.在Centos上安装Kubectl命令行工具组件

可以采用三种方式:

  • curl在线安装
  • 下载二进制文件安装
  • 使用包管理器安装

我们采用二进制文件安装,如果要知道具体的其他安装方式请查看官方安装文档

[root@localhost ~]# sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

无root权限安装,可以将 kubectl 安装到~/.local/bin目录:

chmod +x kubectl
mkdir -p ~/.local/bin/kubectl
mv ./kubectl ~/.local/bin/kubectl
# and then add ~/.local/bin/kubectl to $PATH

安装完后检查

[root@localhost ~]# kubectl version --client
Client Version: version.Info{Major:"1", Minor:"22", GitVersion:"v1.22.2", GitCommit:"8b5a19147530eaac9476b0ab82980b4088bbc1b2", GitTreeState:"clean", BuildDate:"2021-09-15T21:38:50Z", GoVersion:"go1.16.8", Compiler:"gc", Platform:"linux/amd64"}

如果使用kubectl cluster-info会报错

The connection to the server <server-name:port> was refused - did you specify the right host or port?

如果您打算在笔记本电脑上(本地)运行 Kubernetes 集群,则需要先安装 Minikube 之类的工具,然后重新运行上述命令.

如果已经有了配置文件,无法连接到指定的集群,则使用如下命令检查:

[root@localhost ~]# kubectl cluster-info dump
The connection to the server localhost:8080 was refused - did you specify the right host or port?

先别急,我们只安装了一个kubectl,没有实际意义,他只是Node上一个客户端命令。所以如果要它能连接上集群首先要有集群存在,然后要有个配置文件kubeconfig文件,kubectl 配置位于~/.kube/config

安装命令补全

yum install bash-completion  #安装bash的补全
kubectl completion bash >/etc/bash_completion.d/kubectl #安装kubectl的补全命令

安装kubectl convert

这个组件是用来帮助kubectl命令行工具转换配置文件为不同的API版本,该命令将配置文件名,目录或URL作为输入,并将其转换为指定的版本格式,如果目标版本未指定或不支持,则转换为最新版本。

[root@localhost ~]# sudo install -o root -g root -m 0755 kubectl-convert /usr/local/bin/kubectl-convert

验证:

kubectl convert --help 或者 kubectl-convert --help

安装minikube(本地学习环境可以用这个快速创建一个K8S集群,如不需要可以直接跳过)

minikube 是本地 Kubernetes,专注于让 Kubernetes 易于学习和开发。docker安装文档请看官方文档,这里给出centos7.9的包地址

image-20210926124305806

您所需要的只是 Docker(或类似兼容的)容器或虚拟机环境,而 Kubernetes 只需一个命令: minikube start

#先安装docker.
sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
#使用在线安装吧
sudo yum install -y yum-utils  #安装yum配置管理工具
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo #加官方在线源
sudo yum install docker-ce docker-ce-cli containerd.io  #安装docker
sudo systemctl start docker #启动docker

再安装minikube:

curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube

启动 minikube

[root@localhost ~]# minikube start
* minikube v1.23.2 on Centos 7.9.2009
* Automatically selected the docker driver. Other choices: none, ssh
* The "docker" driver should not be used with root privileges.
* If you are running minikube within a VM, consider using --driver=none:
*   https://minikube.sigs.k8s.io/docs/reference/drivers/none/

X Exiting due to DRV_AS_ROOT: The "docker" driver should not be used with root privileges.

这里报错,因为docker不允许使用root:

sudo groupadd docker  #以root身份创建docker组
sudo usermod -aG docker $USER 
sudo usermod -aG docker zhangsan #把张三加进超级组内
service docker restart #重启docker
su zhangsan  #切换用户

以zhangsan用户进入后启动minikube:

[zhangsan@localhost root]$ minikube start 
* minikube v1.23.2 on Centos 7.9.2009
* Automatically selected the docker driver

X The requested memory allocation of 2200MiB does not leave room for system overhead (total system memory: 2827MiB). You may face stability issues.
* Suggestion: Start minikube with less memory allocated: 'minikube start --memory=2200mb'

* Starting control plane node minikube in cluster minikube
* Pulling base image ...
* Downloading Kubernetes v1.22.2 preload ...
    > preloaded-images-k8s-v13-v1...: 511.84 MiB / 511.84 MiB  100.00% 7.65 MiB

    > index.docker.io/kicbase/sta...: 355.40 MiB / 355.40 MiB  100.00% 6.32 MiB
! minikube was unable to download gcr.io/k8s-minikube/kicbase:v0.0.27, but successfully downloaded docker.io/kicbase/stable:v0.0.27 as a fallback image
* Creating docker container (CPUs=2, Memory=2200MB) ...
! This container is having trouble accessing https://k8s.gcr.io
* To pull new external images, you may need to configure a proxy: https://minikube.sigs.k8s.io/docs/reference/networking/proxy/
* Preparing Kubernetes v1.22.2 on Docker 20.10.8 ...
  - Generating certificates and keys ...
  - Booting up control plane ...
  - Configuring RBAC rules ...
* Verifying Kubernetes components...
  - Using image gcr.io/k8s-minikube/storage-provisioner:v5
* Enabled addons: storage-provisioner, default-storageclass
* Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default
[zhangsan@localhost root]$ kubectl get pods -A   #获取NODE上的POD资源,可以看到pod上跑了一套完整的K8S简易集群
NAMESPACE              NAME                                         READY   STATUS    RESTARTS        AGE
kube-system            coredns-78fcd69978-s8pr9                     1/1     Running   1 (6m39s ago)   11m
kube-system            etcd-minikube                                1/1     Running   1 (6m44s ago)   11m
kube-system            kube-apiserver-minikube                      1/1     Running   1 (3m3s ago)    12m
kube-system            kube-controller-manager-minikube             1/1     Running   1 (6m44s ago)   12m
kube-system            kube-proxy-bqq27                             1/1     Running   1 (6m44s ago)   11m
kube-system            kube-scheduler-minikube                      1/1     Running   1 (3m3s ago)    11m
kube-system            storage-provisioner                          1/1     Running   3 (99s ago)     11m
kubernetes-dashboard   dashboard-metrics-scraper-5594458c94-j8nmp   1/1     Running   1 (6m44s ago)   10m
kubernetes-dashboard   kubernetes-dashboard-654cf69797-hcwsp        1/1     Running   2 (95s ago)     10m

minikube dashboard访问:

# 启动dashboard,输出url
minikube dashboard --url
# 使用kubectl proxy监听所有地址
minikube kubectl -- proxy --address=0.0.0.0 --accept-hosts='.*'
# 返回代理地址为[::]:8001
# 可远程访问的url:
# http://192.168.1.18:8001/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/

image-20210926135552137

部署服务

kubectl create deployment hello-minikube --image=k8s.gcr.io/echoserver:1.4 #这一步会报错,因为k8s.gcr.io被墙,所以要自行配置docker的源为国内源,然后自行拉取,改tag后删原来的tag
kubectl expose deployment hello-minikube --type=NodePort --port=8080

处理上步错误:

vim /etc/docker/daemon.json
{
        "registry-mirrors":["这里写你自己的阿里加速地址"]
}
#然后重启docker
systemctl restart docker  
minikube start
#然后用kubectl重新创建部署服务
kubectl create deployment hello-minikube --image=registry.aliyuncs.com/google_containers/echoserver:1.4
kubectl expose deployment hello-minikube --type=NodePort --port=8080
[zhangsan@localhost ~]$ kubectl get service hello-minikube 
NAME             TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
hello-minikube   NodePort   10.106.2.120   <none>        8080:32448/TCP   80m

2.2生产环境使用kubeadm

0.准备工作(使用普通用户bt)

安装条件:

  • 每台机器 2 GB +

  • 2 CPU 核以上

  • 集群中的所有机器的网络彼此均能相互连接

  • 节点之中不可以有重复的主机名、MAC 地址或 product_uuid (查看uuid:sudo cat /sys/class/dmi/id/product_uuid 查看ip: ip addr )

  • 要开启一些端口(见下表)

  • 禁用交换分区(临时:swapoff -a 永久:注释 /etc/fstab 中的/dev/mapper/centos-swap然后重启操作系统)

  • 三台机器,一个master 192.168.1.18 节点node1 192.168.1.19 节点node2 192.168.1.20

    控制平面节点

    协议 方向 端口范围 作用 使用者
    TCP 入站 6443 Kubernetes API 服务器 所有组件
    TCP 入站 2379-2380 etcd 服务器客户端 API kube-apiserver, etcd
    TCP 入站 10250 Kubelet API kubelet 自身、控制平面组件
    TCP 入站 10251 kube-scheduler kube-scheduler 自身
    TCP 入站 10252 kube-controller-manager kube-controller-manager 自身

    工作节点

    协议 方向 端口范围 作用 使用者
    TCP 入站 10250 Kubelet API kubelet 自身、控制平面组件
    TCP 入站 30000-32767 NodePort 服务† 所有组件

先处理几个点(每个机器都处理)

  • 处理普通用户加入sudoer中(visudo 后 在最后加入 your_user_name ALL=(ALL) ALL)

    • 防火墙关了( systemctl stop ufw && systemctl disable firewalld.service)
    • selinux关闭(sudo setenforce 0 如果要永久关闭去改配置 sudo vi /etc/sysconfig/selinux 改SELINUX=disabled)
  • 主机名处理好(每个机器都处理)

    #每个机器自行处理一下内容
    hostnamectl set-hostname node2  #本机主机名
    [root@node2 bt]# cat /etc/hosts   #加解析
    127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
    ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
    192.168.1.18 master
    192.168.1.19 node1
    192.168.1.20 node2
    
  • 禁用交换分区(临时:swapoff -a 永久:注释 /etc/fstab 中的/dev/mapper/centos-swap然后重启操作系统)

  • 确定各个机器可以互ping

  • 加载ipvs相关模块(三个机器都做,保证在节点重启后能自动加载所需模块)

    sudo yum install ipset ipvsadm -y
    cat << EOF |sudo tee  /etc/sysconfig/modules/ipvs.modules 
    #!/bin/bash
    modprobe -- ip_vs
    modprobe -- ip_vs_rr
    modprobe -- ip_vs_wrr
    modprobe -- ip_vs_sh
    modprobe -- nf_conntrack_ipv4
    EOF
    sudo chmod 755 /etc/sysconfig/modules/ipvs.modules && sudo bash /etc/sysconfig/modules/ipvs.modules && sudo lsmod | grep -e ip_vs -e nf_conntrack_ipv4
    
  • 确保 br_netfilter 模块被加载(每个机器都处理)

    #确保 br_netfilter 模块被加载  需要超管用户来处理
    [root@node2 ~]# sudo modprobe br_netfilter
    [root@node2 ~]# lsmod | grep br_netfilter
    br_netfilter           22256  0 
    bridge                151336  1 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
    
  • 安装docker

    docker安装文档请看官方文档,这里给出centos7.9的包地址

    #先卸载已有docker.
    sudo yum remove docker \
                      docker-client \
                      docker-client-latest \
                      docker-common \
                      docker-latest \
                      docker-latest-logrotate \
                      docker-logrotate \
                      docker-engine
    #使用在线安装吧
    sudo yum install -y yum-utils  #安装yum配置管理工具
    sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo #加官方在线源
    sudo yum install docker-ce docker-ce-cli containerd.io  #安装docker
    sudo systemctl start docker #启动docker
    
  • 普通用户加入docker组内

    sudo groupadd docker  #以root身份创建docker组
    sudo usermod -aG docker $USER 
    sudo usermod -aG docker bt #把张三加进超级组内
    service docker restart #重启docker
    su bt  #切换用户
    
  • 处理docker的源,改成国内源

    [bt@master ~]$ cat /etc/docker/daemon.json 
    {
    		"exec-opts": ["native.cgroupdriver=systemd"],    #这注意,一定要写systemd,不然kubelet启动不起来
            "log-driver": "json-file",
            "log-opts": {"max-size": "100m"},
            "storage-driver": "overlay2",
            "registry-mirrors":["https://xxxxx.mirror.aliyuncs.com"]   #注意,这里的地址是你自己的私有加速地址,可以去阿里自己申请
    }
    [bt@master ~]$ sudo systemctl restart docker
    
  • 主机做时间服务器

    #在主机上做以下内容
    #安装chrony:
    sudo yum install -y chrony
    #注释默认ntp服务器
    sudo sed -i 's/^server/#&/' /etc/chrony.conf
    #指定上游公共 ntp 服务器,并允许其他节点同步时间
    cat << EOF | sudo tee  /etc/chrony.conf
    server 0.asia.pool.ntp.org iburst
    server 1.asia.pool.ntp.org iburst
    server 2.asia.pool.ntp.org iburst
    server 3.asia.pool.ntp.org iburst
    allow all
    EOF
    #重启chronyd服务并设为开机启动:
    sudo systemctl enable chronyd && sudo systemctl restart chronyd
    #开启网络时间同步功能
    sudo timedatectl set-ntp true
    
    #在节点node1和node2做以下动作
    sudo yum install -y chrony
    sudo sed -i 's/^server/#&/' /etc/chrony.conf
    cat << EOF | sudo tee  /etc/chrony.conf
    server 192.168.1.18 iburst
    allow all
    EOF
    sudo systemctl enable chronyd && sudo systemctl restart chronyd
    chronyc sources
    

1.在线安装 kubelet kubeadm kubectl 三个机器都装

  • kubeadm:用来初始化集群的指令。
  • kubelet:在集群中的每个节点上用来启动 Pod 和容器等。
  • kubectl:用来与集群通信的命令行工具。
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-\$basearch
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
exclude=kubelet kubeadm kubectl
EOF

sudo yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
sudo systemctl enable --now kubelet

2.主机的配置

sudo kubeadm init --apiserver-advertise-address=192.168.1.18 --image-repository=registry.aliyuncs.com/google_containers --kubernetes-version=v1.22.0 --pod-network-cidr=10.95.0.0/12 --node-name=master

#照做一下内容:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
#root用户:export KUBECONFIG=/etc/kubernetes/admin.conf
#做flannel网络
kubectl apply -f kube-flannel.yml #这个文件在下面

#这是节点加入的命令,记下来后面有用
kubeadm join 192.168.1.18:6443 --token gxwo7x.xa0iqazrhke06cx2 --discovery-token-ca-cert-hash sha256:0e25bc328b9a4ae3362967aac81103200b2b2c0f6a7b6a112cea20daab4978c1 

kube-flannel.yml

---
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: psp.flannel.unprivileged
  annotations:
    seccomp.security.alpha.kubernetes.io/allowedProfileNames: docker/default
    seccomp.security.alpha.kubernetes.io/defaultProfileName: docker/default
    apparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/default
    apparmor.security.beta.kubernetes.io/defaultProfileName: runtime/default
spec:
  privileged: false
  volumes:
    - configMap
    - secret
    - emptyDir
    - hostPath
  allowedHostPaths:
    - pathPrefix: "/etc/cni/net.d"
    - pathPrefix: "/etc/kube-flannel"
    - pathPrefix: "/run/flannel"
  readOnlyRootFilesystem: false
  # Users and groups
  runAsUser:
    rule: RunAsAny
  supplementalGroups:
    rule: RunAsAny
  fsGroup:
    rule: RunAsAny
  # Privilege Escalation
  allowPrivilegeEscalation: false
  defaultAllowPrivilegeEscalation: false
  # Capabilities
  allowedCapabilities: ['NET_ADMIN']
  defaultAddCapabilities: []
  requiredDropCapabilities: []
  # Host namespaces
  hostPID: false
  hostIPC: false
  hostNetwork: true
  hostPorts:
  - min: 0
    max: 65535
  # SELinux
  seLinux:
    # SELinux is unused in CaaSP
    rule: 'RunAsAny'
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: flannel
rules:
  - apiGroups: ['extensions']
    resources: ['podsecuritypolicies']
    verbs: ['use']
    resourceNames: ['psp.flannel.unprivileged']
  - apiGroups:
      - ""
    resources:
      - pods
    verbs:
      - get
  - apiGroups:
      - ""
    resources:
      - nodes
    verbs:
      - list
      - watch
  - apiGroups:
      - ""
    resources:
      - nodes/status
    verbs:
      - patch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: flannel
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: flannel
subjects:
- kind: ServiceAccount
  name: flannel
  namespace: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: flannel
  namespace: kube-system
---
kind: ConfigMap
apiVersion: v1
metadata:
  name: kube-flannel-cfg
  namespace: kube-system
  labels:
    tier: node
    app: flannel
data:
  cni-conf.json: |
    {
      "name": "cbr0",
      "cniVersion": "0.3.1",
      "plugins": [
        {
          "type": "flannel",
          "delegate": {
            "hairpinMode": true,
            "isDefaultGateway": true
          }
        },
        {
          "type": "portmap",
          "capabilities": {
            "portMappings": true
          }
        }
      ]
    }
  net-conf.json: |
    {
      "Network": "10.244.0.0/16",
      "Backend": {
        "Type": "vxlan"
      }
    }
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: kube-flannel-ds-amd64
  namespace: kube-system
  labels:
    tier: node
    app: flannel
spec:
  selector:
    matchLabels:
      app: flannel
  template:
    metadata:
      labels:
        tier: node
        app: flannel
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: kubernetes.io/os
                    operator: In
                    values:
                      - linux
                  - key: kubernetes.io/arch
                    operator: In
                    values:
                      - amd64
      hostNetwork: true
      tolerations:
      - operator: Exists
        effect: NoSchedule
      serviceAccountName: flannel
      initContainers:
      - name: install-cni
        image: quay.io/coreos/flannel:v0.12.0-amd64
        command:
        - cp
        args:
        - -f
        - /etc/kube-flannel/cni-conf.json
        - /etc/cni/net.d/10-flannel.conflist
        volumeMounts:
        - name: cni
          mountPath: /etc/cni/net.d
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      containers:
      - name: kube-flannel
        image: quay.io/coreos/flannel:v0.12.0-amd64
        command:
        - /opt/bin/flanneld
        args:
        - --ip-masq
        - --kube-subnet-mgr
        resources:
          requests:
            cpu: "100m"
            memory: "50Mi"
          limits:
            cpu: "100m"
            memory: "50Mi"
        securityContext:
          privileged: false
          capabilities:
            add: ["NET_ADMIN"]
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        volumeMounts:
        - name: run
          mountPath: /run/flannel
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      volumes:
        - name: run
          hostPath:
            path: /run/flannel
        - name: cni
          hostPath:
            path: /etc/cni/net.d
        - name: flannel-cfg
          configMap:
            name: kube-flannel-cfg
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: kube-flannel-ds-arm64
  namespace: kube-system
  labels:
    tier: node
    app: flannel
spec:
  selector:
    matchLabels:
      app: flannel
  template:
    metadata:
      labels:
        tier: node
        app: flannel
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: kubernetes.io/os
                    operator: In
                    values:
                      - linux
                  - key: kubernetes.io/arch
                    operator: In
                    values:
                      - arm64
      hostNetwork: true
      tolerations:
      - operator: Exists
        effect: NoSchedule
      serviceAccountName: flannel
      initContainers:
      - name: install-cni
        image: quay.io/coreos/flannel:v0.12.0-arm64
        command:
        - cp
        args:
        - -f
        - /etc/kube-flannel/cni-conf.json
        - /etc/cni/net.d/10-flannel.conflist
        volumeMounts:
        - name: cni
          mountPath: /etc/cni/net.d
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      containers:
      - name: kube-flannel
        image: quay.io/coreos/flannel:v0.12.0-arm64
        command:
        - /opt/bin/flanneld
        args:
        - --ip-masq
        - --kube-subnet-mgr
        resources:
          requests:
            cpu: "100m"
            memory: "50Mi"
          limits:
            cpu: "100m"
            memory: "50Mi"
        securityContext:
          privileged: false
          capabilities:
             add: ["NET_ADMIN"]
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        volumeMounts:
        - name: run
          mountPath: /run/flannel
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      volumes:
        - name: run
          hostPath:
            path: /run/flannel
        - name: cni
          hostPath:
            path: /etc/cni/net.d
        - name: flannel-cfg
          configMap:
            name: kube-flannel-cfg
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: kube-flannel-ds-arm
  namespace: kube-system
  labels:
    tier: node
    app: flannel
spec:
  selector:
    matchLabels:
      app: flannel
  template:
    metadata:
      labels:
        tier: node
        app: flannel
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: kubernetes.io/os
                    operator: In
                    values:
                      - linux
                  - key: kubernetes.io/arch
                    operator: In
                    values:
                      - arm
      hostNetwork: true
      tolerations:
      - operator: Exists
        effect: NoSchedule
      serviceAccountName: flannel
      initContainers:
      - name: install-cni
        image: quay.io/coreos/flannel:v0.12.0-arm
        command:
        - cp
        args:
        - -f
        - /etc/kube-flannel/cni-conf.json
        - /etc/cni/net.d/10-flannel.conflist
        volumeMounts:
        - name: cni
          mountPath: /etc/cni/net.d
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      containers:
      - name: kube-flannel
        image: quay.io/coreos/flannel:v0.12.0-arm
        command:
        - /opt/bin/flanneld
        args:
        - --ip-masq
        - --kube-subnet-mgr
        resources:
          requests:
            cpu: "100m"
            memory: "50Mi"
          limits:
            cpu: "100m"
            memory: "50Mi"
        securityContext:
          privileged: false
          capabilities:
             add: ["NET_ADMIN"]
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        volumeMounts:
        - name: run
          mountPath: /run/flannel
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      volumes:
        - name: run
          hostPath:
            path: /run/flannel
        - name: cni
          hostPath:
            path: /etc/cni/net.d
        - name: flannel-cfg
          configMap:
            name: kube-flannel-cfg
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: kube-flannel-ds-ppc64le
  namespace: kube-system
  labels:
    tier: node
    app: flannel
spec:
  selector:
    matchLabels:
      app: flannel
  template:
    metadata:
      labels:
        tier: node
        app: flannel
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: kubernetes.io/os
                    operator: In
                    values:
                      - linux
                  - key: kubernetes.io/arch
                    operator: In
                    values:
                      - ppc64le
      hostNetwork: true
      tolerations:
      - operator: Exists
        effect: NoSchedule
      serviceAccountName: flannel
      initContainers:
      - name: install-cni
        image: quay.io/coreos/flannel:v0.12.0-ppc64le
        command:
        - cp
        args:
        - -f
        - /etc/kube-flannel/cni-conf.json
        - /etc/cni/net.d/10-flannel.conflist
        volumeMounts:
        - name: cni
          mountPath: /etc/cni/net.d
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      containers:
      - name: kube-flannel
        image: quay.io/coreos/flannel:v0.12.0-ppc64le
        command:
        - /opt/bin/flanneld
        args:
        - --ip-masq
        - --kube-subnet-mgr
        resources:
          requests:
            cpu: "100m"
            memory: "50Mi"
          limits:
            cpu: "100m"
            memory: "50Mi"
        securityContext:
          privileged: false
          capabilities:
             add: ["NET_ADMIN"]
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        volumeMounts:
        - name: run
          mountPath: /run/flannel
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      volumes:
        - name: run
          hostPath:
            path: /run/flannel
        - name: cni
          hostPath:
            path: /etc/cni/net.d
        - name: flannel-cfg
          configMap:
            name: kube-flannel-cfg
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: kube-flannel-ds-s390x
  namespace: kube-system
  labels:
    tier: node
    app: flannel
spec:
  selector:
    matchLabels:
      app: flannel
  template:
    metadata:
      labels:
        tier: node
        app: flannel
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: kubernetes.io/os
                    operator: In
                    values:
                      - linux
                  - key: kubernetes.io/arch
                    operator: In
                    values:
                      - s390x
      hostNetwork: true
      tolerations:
      - operator: Exists
        effect: NoSchedule
      serviceAccountName: flannel
      initContainers:
      - name: install-cni
        image: quay.io/coreos/flannel:v0.12.0-s390x
        command:
        - cp
        args:
        - -f
        - /etc/kube-flannel/cni-conf.json
        - /etc/cni/net.d/10-flannel.conflist
        volumeMounts:
        - name: cni
          mountPath: /etc/cni/net.d
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      containers:
      - name: kube-flannel
        image: quay.io/coreos/flannel:v0.12.0-s390x
        command:
        - /opt/bin/flanneld
        args:
        - --ip-masq
        - --kube-subnet-mgr
        resources:
          requests:
            cpu: "100m"
            memory: "50Mi"
          limits:
            cpu: "100m"
            memory: "50Mi"
        securityContext:
          privileged: false
          capabilities:
             add: ["NET_ADMIN"]
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        volumeMounts:
        - name: run
          mountPath: /run/flannel
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      volumes:
        - name: run
          hostPath:
            path: /run/flannel
        - name: cni
          hostPath:
            path: /etc/cni/net.d
        - name: flannel-cfg
          configMap:
            name: kube-flannel-cfg

查看状态

[bt@master ~]$ kubectl get pod -n kube-system -o wide
NAME                             READY   STATUS              RESTARTS      AGE     IP             NODE     NOMINATED NODE   READINESS GATES
coredns-7f6cbbb7b8-pq2j4         0/1     ContainerCreating   0             18m     <none>         master   <none>           <none>
coredns-7f6cbbb7b8-vjctk         0/1     ContainerCreating   0             18m     <none>         master   <none>           <none>
etcd-master                      1/1     Running             0             19m     192.168.1.18   master   <none>           <none>
kube-apiserver-master            1/1     Running             0             19m     192.168.1.18   master   <none>           <none>
kube-controller-manager-master   1/1     Running             0             19m     192.168.1.18   master   <none>           <none>
kube-flannel-ds-amd64-xfjcc      0/1     CrashLoopBackOff    4 (80s ago)   3m19s   192.168.1.18   master   <none>           <none>
kube-proxy-fgxvz                 1/1     Running             0             18m     192.168.1.18   master   <none>           <none>
kube-scheduler-master            1/1     Running             0             19m     192.168.1.18   master   <none>           <none>

查看主机的节点是否ready

[bt@master ~]$ kubectl get node -o wide
NAME     STATUS   ROLES                  AGE   VERSION   INTERNAL-IP    EXTERNAL-IP   OS-IMAGE                KERNEL-VERSION                CONTAINER-RUNTIME
master   Ready    control-plane,master   20m   v1.22.2   192.168.1.18   <none>        CentOS Linux 7 (Core)   3.10.0-1160.42.2.el7.x86_64   docker://20.10.8

部署node1和node2

在node1和node2上执行

#执行以下命令将节点接入集群
kubeadm join 192.168.1.18:6443 --token gxwo7x.xa0iqazrhke06cx2 --discovery-token-ca-cert-hash sha256:0e25bc328b9a4ae3362967aac81103200b2b2c0f6a7b6a112cea20daab4978c1 
#如果执行kubeadm init时没有记录下加入集群的命令,可以在主机通过以下命令重新创建
kubeadm token create --print-join-command

在主机查看状态

[bt@master ~]$ kubectl get nodes
NAME     STATUS   ROLES                  AGE     VERSION
master   Ready    control-plane,master   30m     v1.22.2
node1    Ready    <none>                 4m34s   v1.22.2
node2    Ready    <none>                 72s     v1.22.2
posted @ 2021-10-08 10:57  石头墩子  阅读(286)  评论(0)    收藏  举报