说明:如果你能有耐心看完官方文档,那建议不要去看我写的这个东西了。因为学习任何技术,最简单最权威的方法就是去学习官方文档,如果连官方文档都看不下去,那就没必要去看什么书、视频或资料了。其次学习任何东西,先掌握专业名词,搞懂专业名词的意思后再去了解宏观的构建,最后庖丁解牛细化实践,当细化到一定程度后再去反过来宏观理解,自己动手归纳总结,再去看一些高级深入的书籍才有用,不然看到的都是千篇一律的东西浪费时间和精力毫无意义。
1.Kubernetes是什么?
Kubernetes 是一个可移植的、可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化。 Kubernetes 拥有一个庞大且快速增长的生态系统。Kubernetes 的服务、支持和工具广泛可用。
1.1 一张图对比传统部署、虚拟化部署和容器部署方式的差距
特点:
- 敏捷应用程序的创建和部署:与使用 VM 镜像相比,提高了容器镜像创建的简便性和效率。
- 持续开发、集成和部署:通过快速简单的回滚(由于镜像不可变性),支持可靠且频繁的 容器镜像构建和部署。
- 关注开发与运维的分离:在构建/发布时而不是在部署时创建应用程序容器镜像, 从而将应用程序与基础架构分离。
- 可观察性:不仅可以显示操作系统级别的信息和指标,还可以显示应用程序的运行状况和其他指标信号。
- 跨开发、测试和生产的环境一致性:在便携式计算机上与在云中相同地运行。
- 跨云和操作系统发行版本的可移植性:可在 Ubuntu、RHEL、CoreOS、本地、 Google Kubernetes Engine 和其他任何地方运行。
- 以应用程序为中心的管理:提高抽象级别,从在虚拟硬件上运行 OS 到使用逻辑资源在 OS 上运行应用程序。
- 松散耦合、分布式、弹性、解放的微服务:应用程序被分解成较小的独立部分, 并且可以动态部署和管理 - 而不是在一台大型单机上整体运行。
- 资源隔离:可预测的应用程序性能。
- 资源利用:高效率和高密度
1.2 容器部署为啥需要Kubernetes?解决什么问题?
容器是打包和运行应用程序的好方式。在生产环境中,你需要管理运行应用程序的容器,并确保不会停机。那这里就牵扯到了服务发现、负载均衡、存储编排、自动部署和回滚、资源分配、自我修复、安全管理。
Kubernetes 为你提供:
- 服务发现和负载均衡
Kubernetes 可以使用 DNS 名称或自己的 IP 地址公开容器,如果进入容器的流量很大, Kubernetes 可以负载均衡并分配网络流量,从而使部署稳定。 - 存储编排
Kubernetes 允许你自动挂载你选择的存储系统,例如本地存储、公共云提供商等。 - 自动部署和回滚
你可以使用 Kubernetes 描述已部署容器的所需状态,它可以以受控的速率将实际状态 更改为期望状态。例如,你可以自动化 Kubernetes 来为你的部署创建新容器, 删除现有容器并将它们的所有资源用于新容器。 - 资源分配
Kubernetes 允许你指定每个容器所需 CPU 和内存(RAM)。 当容器指定了资源请求时,Kubernetes 可以做出更好的决策来管理容器的资源。 - 自我修复
Kubernetes 重新启动失败的容器、替换容器、杀死不响应用户定义的 运行状况检查的容器,并且在准备好服务之前不将其通告给客户端。 - 密钥与配置管理
Kubernetes 允许你存储和管理敏感信息,例如密码、OAuth 令牌和 ssh 密钥。 你可以在不重建容器镜像的情况下部署和更新密钥和应用程序配置,也无需在堆栈配置中暴露密钥。
1.3 Kubernetes长啥样子?
一个 Kubernetes 集群由一组被称作节点的机器组成。这些节点上运行 Kubernetes 所管理的容器化应用。集群具有至少一个工作节点。也就是说Node至少有一个,Node上装了容器来提供服务。这些Node一般分布在多个不同的物理主机上或者虚拟机上,也就是说由Control Plane(控制平面)控制了很多机器。
1.4 分解控制平面组件,这些东西都是什么?都起到什么作用?
首先了解Pod是什么?POD这个单词在英语中指夹,类似豌豆夹的意思。我们暂且理解为壳,壳能包裹了容器。
Pod是Kubernetes中能够创建和部署的最小单元,是Kubernetes集群中的一个应用实例,总是部署在同一个节点Node上 .Pod中包含了一个或多个容器,还包括了存储、网络等各个容器共享的资源.
Pod并不提供保证正常运行的能力,因为可能遭受Node节点的物理故障、网络分区等等的影响,整体的高可用是Kubernetes集群通过在集群内调度Node来实现的。通常情况下我们不要直接创建Pod,一般都是通过Controller来进行管理。
特点:
- 一般建议一个pod包含一个容器。一个pod包含多个容器的情况,一个Pod内的容器共享IP地址和端口范围,容器之间可以通过 localhost 互相访问。
- Pod做为一个可以独立运行的服务单元,简化了应用部署的难度,以更高的抽象层次为应用部署管提供了极大的方便。
- Pod做为最小的应用实例可以独立运行,因此可以方便的进行部署、水平扩展和收缩、方便进行调度管理与资源的分配。
- Pod中的容器共享相同的数据和网络地址空间,Pod之间也进行了统一的资源管理与分配。
分解Control Plane控制平面组件
控制平面组件可以在集群中的任何节点上运行。 然而,为了简单起见,设置脚本通常会在同一个计算机上启动所有控制平面组件, 并且不会在此计算机上运行用户容器。也就是说控制平面虽然可以在任何节点上运行,但是一般建议放在一个单独的机器节点上做总控。
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上的组件
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 记录呢?
- Services
- Pods
web仪表盘
Dashboard 是 Kubernetes 集群的通用的、基于 Web 的用户界面。 它使用户可以管理集群中运行的应用程序以及集群本身并进行故障排除。怎样安装调试看连接文件,这里先不了解,后面再去看。
容器资源监控
容器资源监控 将关于容器的一些常见的时间序列度量值保存到一个集中的数据库中,并提供用于浏览这些数据的界面。建议采用Prometheus来做监控。
集群日志
负责将容器的日志数据 保存到一个集中的日志存储中,该存储能够提供搜索和浏览接口。要了解日志架构请看连接。
2.初步学习安装K8S
2.1 学习环境安装minikube(不需要的话请直接跳过到2.2)
下载安装包
下载地址在这里,选定好操作系统类型和K8S版本后就出现了下图.
我们进行分步骤安装,安装前为了简单,先把selinux和防火墙关闭。
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的包地址
您所需要的只是 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/
部署服务
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
控制平面节点
- 工作节点
先处理几个点(每个机器都处理):
- 处理普通用户加入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.
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