概述
Kubernetes 是一个可移植、可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化。 Kubernetes 拥有一个庞大且快速增长的生态,其服务、支持和工具的使用范围相当广泛。
应用部署方式演变
传统部署 :互联网早期,会直接将应用程序部署在物理机上优点:简单,不需要其它技术的参与缺点:不能为应用程序定义资源使用边界,很难合理地分配计算资源,而且程序 之间 容易产 生影响虚拟化部署 :可以在一台物理机上运行多个虚拟机,每个虚拟机都是独立的一个环境优点:程序环境不会相互产生影响,提供了一定程度的安全性缺点:增加了操作系统,浪费了部分资源容器化部署 :与虚拟化类似,但是共享了操作系统优点: 可以保证每个容器拥有自己的文件系统、CPU 、内存、进程空间等运行应用程序所需要的资源都被容器包装,并和底层基础架构解耦容器化的应用程序可以跨云服务商、跨 Linux 操作系统发行版进行部署
- 一个容器故障停机了,怎么样让另外一个容器立刻启动去替补停机的容器
- 当并发访问量变大的时候,怎么样做到横向扩展容器数量
- Swarm:Docker自己的容器编排工具
- Mesos:Apache的一个资源统一管控的工具,需要和Marathon结合使用
- Kubernetes:Google开源的的容器编排工具
k8s的作用
Kubernetes 为你提供:
-
服务发现和负载均衡
Kubernetes 可以使用 DNS 名称或自己的 IP 地址来暴露容器。 如果进入容器的流量很大, Kubernetes 可以负载均衡并分配网络流量,从而使部署稳定。
-
存储编排
Kubernetes 允许你自动挂载你选择的存储系统,例如本地存储、公共云提供商等。
-
自动部署和回滚
你可以使用 Kubernetes 描述已部署容器的所需状态, 它可以以受控的速率将实际状态更改为期望状态。 例如,你可以自动化 Kubernetes 来为你的部署创建新容器, 删除现有容器并将它们的所有资源用于新容器。
-
自动完成装箱计算
你为 Kubernetes 提供许多节点组成的集群,在这个集群上运行容器化的任务。 你告诉 Kubernetes 每个容器需要多少 CPU 和内存 (RAM)。 Kubernetes 可以将这些容器按实际情况调度到你的节点上,以最佳方式利用你的资源。
-
自我修复
Kubernetes 将重新启动失败的容器、替换容器、杀死不响应用户定义的运行状况检查的容器, 并且在准备好服务之前不将其通告给客户端。
-
密钥与配置管理
Kubernetes 允许你存储和管理敏感信息,例如密码、OAuth 令牌和 SSH 密钥。 你可以在不重建容器镜像的情况下部署和更新密钥和应用程序配置,也无需在堆栈配置中暴露密钥。
- 批处理执行 除了服务外,Kubernetes 还可以管理你的批处理和 CI(持续集成)工作负载,如有需要,可以替换失败的容器。
- 水平扩缩 使用简单的命令、用户界面或根据 CPU 使用率自动对你的应用进行扩缩。
- IPv4/IPv6 双栈 为 Pod(容器组)和 Service(服务)分配 IPv4 和 IPv6 地址。
- 为可扩展性设计 在不改变上游源代码的情况下为你的 Kubernetes 集群添加功能。
k8s对象
理解 Kubernetes 对象
在 Kubernetes 系统中,Kubernetes 对象是持久化的实体。 Kubernetes 使用这些实体去表示整个集群的状态。 具体而言,它们描述了如下信息:
- 哪些容器化应用正在运行(以及在哪些节点上运行)
- 可以被应用使用的资源
- 关于应用运行时行为的策略,比如重启策略、升级策略以及容错策
Kubernetes 对象是一种“意向表达(Record of Intent)”。一旦创建该对象, Kubernetes 系统将不断工作以确保该对象存在。通过创建对象,你本质上是在告知 Kubernetes 系统,你想要的集群工作负载状态看起来应是什么样子的, 这就是 Kubernetes 集群所谓的期望状态(Desired State)。
kubernetes的对象是一种意图(期望)的记录,kubernetes会始终保持预期创建的对象存在和集群运行在预期的状态下。
几乎每个 Kubernetes 对象包含两个嵌套的对象字段,它们负责管理对象的配置:
- 对象
spec
(规约)
对于具有
spec
的对象,你必须在创建对象时设置其内容,描述你希望对象所具有的特征: 期望状态(Desired State)。
- 对象
status
(状态)
status
描述了对象的当前状态(Current State),它是由 Kubernetes 系统和组件设置并更新的。在任何时刻,Kubernetes 控制平面 都一直在积极地管理着对象的实际状态,以使之达成期望状态。
描述 Kubernetes 对象
创建 Kubernetes 对象时,必须提供对象的 spec
,用来描述该对象的期望状态, 以及关于对象的一些基本信息(例如名称)。 当使用 Kubernetes API 创建对象时(直接创建或经由 kubectl
创建), API 请求必须在请求主体中包含 JSON 格式的信息。 大多数情况下,你会通过 清单(Manifest) 文件为 kubectl
提供这些信息。 按照惯例,清单是 YAML 格式的(你也可以使用 JSON 格式)。 像 kubectl
这样的工具在通过 HTTP 进行 API 请求时, 会将清单中的信息转换为 JSON 或其他受支持的序列化格式。
这里有一个清单示例文件,展示了 Kubernetes Deployment 的必需字段和对象 spec
:
[root@k8s-master-1 ~]# vim deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2 # 告知 Deployment 运行 2 个与该模板匹配的 Pod
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
使用 kubectl
命令行接口(CLI)的 kubectl apply 命令, 将 .yaml
文件作为参数。下面是一个示例:
[root@k8s-master-1 ~]# kubectl apply -f deployment.yaml
输出类似下面这样:
[root@k8s-master-1 ~]# kubectl apply -f deployment.yaml
deployment.apps/nginx-deployment created
[root@k8s-master-1 ~]#
必需字段
在想要创建的 Kubernetes 对象所对应的清单(YAML 或 JSON 文件)中,需要配置的字段如下:
apiVersion
- 创建该对象所使用的 Kubernetes API 的版本kind
- 想要创建的对象的类别metadata
- 帮助唯一标识对象的一些数据,包括一个name
字符串、UID
和可选的namespace
spec
- 你所期望的该对象的状态
对每个 Kubernetes 对象而言,其 spec
之精确格式都是不同的,包含了特定于该对象的嵌套字段。
服务器端字段验证
从 Kubernetes v1.25 开始,API 服务器提供了服务器端字段验证, 可以检测对象中未被识别或重复的字段。它在服务器端提供了 kubectl --validate
的所有功能。
kubectl
工具使用 --validate
标志来设置字段验证级别。它接受值 ignore
、warn
和 strict
,同时还接受值 true
(等同于 strict
)和 false
(等同于 ignore
)。kubectl
的默认验证设置为 --validate=true
。
Strict
严格的字段验证,验证失败时会报错
Warn
执行字段验证,但错误会以警告形式提供而不是拒绝请求
Ignore
不执行服务器端字段验证
当 kubectl
无法连接到支持字段验证的 API 服务器时,它将回退为使用客户端验证。 Kubernetes 1.27 及更高版本始终提供字段验证;较早的 Kubernetes 版本可能没有此功能。 如果你的集群版本低于 v1.27,可以查阅适用于你的 Kubernetes 版本的文档。
Kubernetes 组件
当你部署完 Kubernetes,便拥有了一个完整的集群。
一组工作机器,称为节点, 会运行容器化应用程序。每个集群至少有一个工作节点。
工作节点会托管 Pod,而 Pod 就是作为应用负载的组件。 控制平面管理集群中的工作节点和 Pod。 在生产环境中,控制平面通常跨多台计算机运行, 一个集群通常运行多个节点,提供容错性和高可用性。
Kubernetes 集群的组件
控制平面组件(Control Plane Components)
控制平面组件会为集群做出全局决策,比如资源的调度。 以及检测和响应集群事件,例如当不满足部署的 replicas
字段时,要启动新的 Pod)。
控制平面组件可以在集群中的任何节点上运行。 然而,为了简单起见,设置脚本通常会在同一个计算机上启动所有控制平面组件, 并且不会在此计算机上运行用户容器。 请参阅使用 kubeadm 构建高可用性集群 中关于跨多机器控制平面设置的示例。
kube-apiserver
API 服务器是 Kubernetes 控制平面的组件, 该组件负责公开了 Kubernetes API,负责处理接受请求的工作。 API 服务器是 Kubernetes 控制平面的前端。
Kubernetes API 服务器的主要实现是 kube-apiserver。
kube-apiserver
设计上考虑了水平扩缩,也就是说,它可通过部署多个实例来进行扩缩。 你可以运行kube-apiserver
的多个实例,并在这些实例之间平衡流量。
etcd
一致且高可用的键值存储,用作 Kubernetes 所有集群数据的后台数据库。
如果你的 Kubernetes 集群使用 etcd 作为其后台数据库, 请确保你针对这些数据有一份 备份计划。你可以在官方文档中找到有关 etcd 的深入知识。
kube-scheduler
kube-scheduler
是控制平面的组件, 负责监视新创建的、未指定运行节点(node)的 Pods, 并选择节点来让 Pod 在上面运行。调度决策考虑的因素包括单个 Pod 及 Pods 集合的资源需求、软硬件及策略约束、 亲和性及反亲和性规范、数据位置、工作负载间的干扰及最后时限。
kube-controller-manager
kube-controller-manager 是控制平面的组件, 负责运行控制器进程。
从逻辑上讲, 每个控制器都是一个单独的进程, 但是为了降低复杂性,它们都被编译到同一个可执行文件,并在同一个进程中运行。
有许多不同类型的控制器。以下是一些例子:
- 节点控制器(Node Controller):负责在节点出现故障时进行通知和响应
- 任务控制器(Job Controller):监测代表一次性任务的 Job 对象,然后创建 Pod 来运行这些任务直至完成
- 端点分片控制器(EndpointSlice controller):填充端点分片(EndpointSlice)对象(以提供 Service 和 Pod 之间的链接)。
- 服务账号控制器(ServiceAccount controller):为新的命名空间创建默认的服务账号(ServiceAccount)。
以上并不是一个详尽的列表。
cloud-controller-manager
一个 Kubernetes 控制平面组件, 嵌入了特定于云平台的控制逻辑。 云控制器管理器(Cloud Controller Manager)允许将你的集群连接到云提供商的 API 之上, 并将与该云平台交互的组件同与你的集群交互的组件分离开来。
cloud-controller-manager
仅运行特定于云平台的控制器。 因此如果你在自己的环境中运行 Kubernetes,或者在本地计算机中运行学习环境, 所部署的集群不需要有云控制器管理器。
与 kube-controller-manager
类似,cloud-controller-manager
将若干逻辑上独立的控制回路组合到同一个可执行文件中, 供你以同一进程的方式运行。 你可以对其执行水平扩容(运行不止一个副本)以提升性能或者增强容错能力。
下面的控制器都包含对云平台驱动的依赖:
- 节点控制器(Node Controller):用于在节点终止响应后检查云提供商以确定节点是否已被删除
- 路由控制器(Route Controller):用于在底层云基础架构中设置路由
- 服务控制器(Service Controller):用于创建、更新和删除云提供商负载均衡器
Node 组件
节点组件会在每个节点上运行,负责维护运行的 Pod 并提供 Kubernetes 运行环境。
kubelet
kubelet
会在集群中每个节点(node)上运行。 它保证容器(containers)都运行在 Pod 中。kubelet 接收一组通过各类机制提供给它的 PodSpec,确保这些 PodSpec 中描述的容器处于运行状态且健康。 kubelet 不会管理不是由 Kubernetes 创建的容器。
kube-proxy
kube-proxy 是集群中每个节点(node)上所运行的网络代理, 实现 Kubernetes 服务(Service) 概念的一部分。
kube-proxy 维护节点上的一些网络规则, 这些网络规则会允许从集群内部或外部的网络会话与 Pod 进行网络通信。
如果操作系统提供了可用的数据包过滤层,则 kube-proxy 会通过它来实现网络规则。 否则,kube-proxy 仅做流量转发。
容器运行时(Container Runtime)
这个基础组件使 Kubernetes 能够有效运行容器。 它负责管理 Kubernetes 环境中容器的执行和生命周期。
Kubernetes 支持许多容器运行环境,例如 containerd、docker、 CRI-O 以及 Kubernetes CRI (容器运行环境接口) 的其他任何实现。
插件(Addons)
插件使用 Kubernetes 资源(DaemonSet、 Deployment 等)实现集群功能。 因为这些插件提供集群级别的功能,插件中命名空间域的资源属于 kube-system
命名空间。
下面描述众多插件中的几种。
DNS
尽管其他插件都并非严格意义上的必需组件,但几乎所有 Kubernetes 集群都应该有集群 DNS, 因为很多示例都需要 DNS 服务。
集群 DNS 是一个 DNS 服务器,和环境中的其他 DNS 服务器一起工作,它为 Kubernetes 服务提供 DNS 记录。
Kubernetes 启动的容器自动将此 DNS 服务器包含在其 DNS 搜索列表中。
Web 界面(仪表盘)
Dashboard 是 Kubernetes 集群的通用的、基于 Web 的用户界面。 它使用户可以管理集群中运行的应用程序以及集群本身, 并进行故障排除。
容器资源监控
容器资源监控 将关于容器的一些常见的时间序列度量值保存到一个集中的数据库中, 并提供浏览这些数据的界面。
集群层面日志
集群层面日志机制负责将容器的日志数据保存到一个集中的日志存储中, 这种集中日志存储提供搜索和浏览接口。
网络插件
网络插件 是实现容器网络接口(CNI)规范的软件组件。它们负责为 Pod 分配 IP 地址,并使这些 Pod 能在集群内部相互通信
理解
ApiServer : 资源操作的唯一入口,接收用户输入的命令,提供认证、授权、API注册和发现等机制Scheduler : 负责集群资源调度,按照预定的调度策略将Pod调度到相应的node节点上ControllerManager : 负责维护集群的状态,比如程序部署安排、故障检测、自动扩展、滚动更新等Etcd :负责存储集群中各种资源对象的信息
Kubelet : 负责维护容器的生命周期,即通过控制docker,来创建、更新、销毁容器KubeProxy : 负责提供集群内部的服务发现和负载均衡Docker : 负责节点上容器的各种操作下面,以部署一个nginx服务来说明kubernetes系统各个组件调用关系:
k8s架构
k8s集群环境搭建
一主多从:一台 Master 节点和多台 Node 节点,搭建简单,但是有单机故障风险,适合用于测试环境多主多从:多台 Master 节点和多台 Node 节点,搭建麻烦,安全性高,适合用于生产环境
说明:为了测试简单,本次搭建的是 一主两从 类型的集群
- minikube:一个用于快速搭建单节点kubernetes的工具
- kubeadm:一个用于快速搭建kubernetes集群的工具
- 二进制包 :从官网下载每个组件的二进制包,依次去安装,此方式对于理解kubernetes组件更加有效
主机规划
作用 | IP地址 | 操作系统 |
master | 192.168.244.208 | Centos7.9 |
node1 | 192.168.244.209 | Centos7.9 |
node2 | 192.168.244.210 | Centos7.9 |
# 将 SELinux 设置为 permissive 模式(相当于将其禁用)
sudo setenforce 0
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
添加 Kubernetes 的 yum
仓库。在仓库定义中的 exclude
参数确保了与 Kubernetes 相关的软件包在运行 yum update
时不会升级,因为升级 Kubernetes 需要遵循特定的过程。
# 此操作会覆盖 /etc/yum.repos.d/kubernetes.repo 中现存的所有配置
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.30/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.30/rpm/repodata/repomd.xml.key
exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni
EOF
安装 kubelet、kubeadm 和 kubectl,并启用 kubelet 以确保它在启动时自动启动:
sudo yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
sudo systemctl enable --now kubelet
环境初始化
1) 检查操作系统的版本
[root@k8s-master-1 ~]# cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)
[root@k8s-master-1 ~]#
[root@k8s-master-1 ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
# 主机名成解析 编辑三台服务器的/etc/hosts文件,添加下面内容
192.168.244.208 k8s-master-1
192.168.244.209 k8s-node-1
192.168.244.210 k8s-node-2
[root@k8s-master-1 ~]#
3) 时间同步
kubernetes要求集群中的节点时间必须精确一致,这里直接使用chronyd服务从网络同步时间。企业中建议配置内部的时间同步服务器
# 启动chronyd服务
[root@k8s-master-1 ~]# systemctl start chronyd
# 设置chronyd服务开机自启
[root@k8s-master-1 ~]# systemctl enable chronyd
# chronyd服务启动稍等几秒钟,就可以使用date命令验证时间了
[root@k8s-master-1 ~]# date
# 1 关闭firewalld服务
[root@k8s-master-1 ~]# systemctl stop firewalld
[root@k8s-master-1 ~]# systemctl disable firewalld
# 2 关闭iptables服务
[root@k8s-master-1 ~]# systemctl stop iptables
[root@k8s-master-1 ~]# systemctl disable iptables
# 编辑 /etc/selinux/config 文件,修改SELINUX的值为disabled
# 注意修改完毕之后需要重启linux服务
SELINUX=disabled
# 临时关闭
swapoff -a
# 永久关闭
sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
# 修改linux的内核参数,添加网桥过滤和地址转发功能,转发IPv4并让iptables看到桥接流量
cat <<EOF | tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
# 加载网桥过滤模块
modprobe overlay
modprobe br_netfilter
# 编辑/etc/sysctl.d/kubernetes.conf文件,主要是对容器虚拟网络的支持,添加如下配置:
cat << EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
# 应用sysctl参数而不重新启动
sysctl -p
# 查看br_netfilter和 overlay模块是否加载成功
[root@k8s-master-1 ~]# lsmod | egrep "br_netfilter|overlay"
br_netfilter 22256 0
overlay 91659 0
bridge 151336 1 br_netfilter
[root@k8s-master-1 ~]#
8)更新和配置软件源
[root@k8s-master-1 ~]# cd /etc/yum.repos.d/
[root@k8s-master-1 yum.repos.d]# rm -rf *
[root@k8s-master-1 yum.repos.d]# curl -O http://mirrors.aliyun.com/repo/Centos-7.repo
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 2523 100 2523 0 0 23563 0 --:--:-- --:--:-- --:--:-- 23801
[root@k8s-master-1 yum.repos.d]# ls
Centos-7.repo
yum clean all && yum makecache fast
yum install -y yum-utils
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
9)配置ipvs功能
# 安装ipset和ipvsadm,主要是对ipvs进行传递参数的或者管理的
yum install ipset ipvsadm -y
# 添加需要加载的模块写入脚本文件
#modprobo 作用是加载模块到内核里
cat <<EOF > /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
# 为脚本文件添加执行权限
chmod +x /etc/sysconfig/modules/ipvs.modules
# 执行脚本文件
/bin/bash /etc/sysconfig/modules/ipvs.modules
# 重启
reboot
# 查看对应的模块是否加载成功
[root@k8s-master-1 ~]# lsmod | egrep "br_netfilter|overlay"
br_netfilter 22256 0
bridge 151336 1 br_netfilter
overlay 91659 24
[root@k8s-master-1 ~]# lsmod | grep -e ip_vs -e nf_conntrack_ipv4
nf_conntrack_ipv4 15053 32
nf_defrag_ipv4 12729 1 nf_conntrack_ipv4
ip_vs_sh 12688 0
ip_vs_wrr 12697 0
ip_vs_rr 12600 22
ip_vs 145458 28 ip_vs_rr,ip_vs_sh,ip_vs_wrr
nf_conntrack 139264 10 ip_vs,nf_nat,nf_nat_ipv4,nf_nat_ipv6,xt_conntrack,nf_nat_masquerade_ipv4,nf_nat_masquerade_ipv6,nf_conntrack_netlink,nf_conntrack_ipv4,nf_conntrack_ipv6
libcrc32c 12644 4 xfs,ip_vs,nf_nat,nf_conntrack
[root@k8s-master-1 ~]#
安装docker
# 查看所有版本
yum list docker-ce --showduplicates
#安装指定版本20.10.24的docker
yum install -y docker-ce-20.10.24-3.el7 docker-ce-cli-20.10.24-3.el7
#下面命令会安装最新版本的docker软件
yum install -y docker-ce docker-ce-cli
配置docker的国内源
mkdir /etc/docker -p
yum install vim -y
cat > /etc/docker/daemon.json <<EOF
{
"registry-mirrors": ["https://hub.docker-alhk.dkdun.com/"],
"exec-opts": ["native.cgroupdriver=systemd"]
}
EOF
[root@k8s-master-1 docker]# cat daemon.json
{
"registry-mirrors": ["https://hub.docker-alhk.dkdun.com/"],
"exec-opts": ["native.cgroupdriver=systemd"]
}
#重新加载docker的配置文件和重启docker服务
[root@k8s-master-1 docker]# systemctl daemon-reload
[root@k8s-master-1 docker]# systemctl restart docker
配置docker服务自启动
# 启动docker并设置开机自启
systemctl enable --now docker
# 验证
systemctl status docker
集群初始化
kubeadm init
仅在master节点执行
kubeadm init \
--kubernetes-version=v1.23.17 \
--pod-network-cidr=10.224.0.0/16 \
--service-cidr=10.96.0.0/12 \
--apiserver-advertise-address=192.168.244.208 \ # 集群master的IP
--image-repository=registry.aliyuncs.com/google_containers
成功后会提示以下信息:
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 172.18.212.47:6443 --token nyjc81.tvhtt2h67snpkf48 \
--discovery-token-ca-cert-hash sha256:cf8458e93e3510cf77dd96a73d39acd3f6284034177f8bad4d8452bb7f5f6e62 # 暂存这条命令
然后在master节点上继续执行
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
#查看master接口监听6443端口的进程,是kube-apiserver
[root@k8s-master-1 ~]# ss -anplut|grep 6443
tcp LISTEN 0 128 [::]:6443 [::]:* users:(("kube-apiserver",pid=2809,fd=7))
[root@k8s-master-1 ~]#
node节点加入集群
# 上面得到的命令
kubeadm join 172.18.212.47:6443 --token nyjc81.tvhtt2h67snpkf48 \
--discovery-token-ca-cert-hash sha256:cf8458e93e3510cf77dd96a73d39acd3f6284034177f8bad4d8452bb7f5f6e62
#执行下面的命令也可以得到join集群的命令,如果忘记了或者没有提前复制保存
[root@k8s-master-1 ~]# kubeadm token create --print-join-command
kubeadm join 192.168.205.140:6443 --token yvq3xz.x0xfu68vz4rqldvw --discovery-token-ca-cert-hash sha256:1afc3cdd9442dfb8e1d6420c2cdb551a994e3972dbad5468193735b9ea18c086
[root@k8s-master-1 ~]#
如果成功,检查集群节点状态
# 在master上执行
kubectl get nodes
# NAME STATUS ROLES AGE VERSION
# k8s-master NotReady control-plane,master 53m v1.23.17
# k8s-node-1 NotReady <none> 1m v1.23.17
# k8s-node-2 NotReady <none> 1m v1.23.17
分配worker role
# 在master上执行
kubectl label node k8s-node-1 node-role.kubernetes.io/worker=worker
kubectl label node k8s-node-2 node-role.kubernetes.io/worker=worker
在node节点上也可以执行kubectl命令
[root@k8s-node-1 ~]# mkdir -p $HOME/.kube
[root@k8s-node-1 ~]# scp k8s-master-1:/etc/kubernetes/admin.conf /root/.kube/config
[root@k8s-node-1 ~]# chown $(id -u):$(id -g) $HOME/.kube/config
[root@k8s-node-1 ~]# kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master-1 Ready control-plane,master 75m v1.23.17
k8s-node-1 Ready worker 63m v1.23.17
k8s-node-2 Ready worker 63m v1.23.17
[root@k8s-node-1 ~]#
安装Calico网络插件
calico是k8s集群里网络通信的一个组件(软件),实现集群内部不同的机器之间的容器的通信(大的网络规模)。k8s集群节点可以到5000节点,1亿个容器
flannel 也是一个网络插件(适合小规模的集群,节点服务器的数量比较小,例如:10台左右)
terway 是阿里云自己研发的一个网络插件
# master执行
kubectl apply -f https://docs.projectcalico.org/archive/v3.25/manifests/calico.yaml
# k8s 1.23适用此版本
# 验证 节点状态 NotReady => Ready
kubectl get nodes
# NAME STATUS ROLES AGE VERSION
# k8s-master Ready control-plane 2h v1.23.17
# k8s-node-1 Ready worker 1h v1.23.17
# k8s-node-2 Ready worker 1h v1.23.172
安装calico网络插件的时候,因为需要下载镜像文件,同时镜像文件比较大,网速不好需要等很长时间。
[root@k8s-master-1 ~]# kubectl get pod -n kube-system #calico镜像全部完成后的效果
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-64cc74d646-rgbbs 1/1 Running 0 27m
calico-node-6pxcb 1/1 Running 0 27m
calico-node-bb5d4 1/1 Running 0 27m
calico-node-r7dxg 1/1 Running 0 27m
coredns-6d8c4cb4d-267tv 1/1 Running 0 48m
coredns-6d8c4cb4d-nvqfv 1/1 Running 0 48m
etcd-k8s-master-1 1/1 Running 0 49m
kube-apiserver-k8s-master-1 1/1 Running 0 49m
kube-controller-manager-k8s-master-1 1/1 Running 0 49m
kube-proxy-2tg79 1/1 Running 0 8m51s
kube-proxy-bx9cs 1/1 Running 0 8m50s
kube-proxy-lzjkx 1/1 Running 0 8m51s
kube-scheduler-k8s-master-1 1/1 Running 0 49m
[root@k8s-master-1 ~]#
[root@k8s-master-1 ~]# kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master-1 Ready control-plane,master 50m v1.23.17
k8s-node-1 Ready worker 38m v1.23.17
k8s-node-2 Ready worker 38m v1.23.17
[root@k8s-master-1 ~]#
k8s配置ipvs
ipvs 是linux里的一个负载均衡软件,默认在linux内核里就安装了,修改k8s里的一个配置,负载均衡的时候使用ipvs做为默认的负载均衡软件,如果不修改默认是iptables
kubectl edit configmap kube-proxy -n kube-system
# 修改配置
mode: "ipvs"
# 删除所有kube-proxy pod使之重启
kubectl delete pods -n kube-system -l k8s-app=kube-proxy
常用软件
安装kubectl命令自动补全
yum install -y bash-completion
# 临时设置自动补全
source <(kubectl completion bash)
# 永久设置自动补全
echo "source <(kubectl completion bash)" >> ~/.bashrc && bash
安装Dashboard
以下命令均只在master节点上执行
下载安装
wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml\
# 修改Service部分,改为NodePort对外暴露端口
查看
[root@k8s-master-1 nginx]# kubectl get pods,svc -n kubernetes-dashboard
NAME READY STATUS RESTARTS AGE
pod/dashboard-metrics-scraper-6f669b9c9b-pp8mz 1/1 Running 6 (6h50m ago) 7d5h
pod/kubernetes-dashboard-57dd8bd998-wvzcr 1/1 Running 9 (6h48m ago) 7d1h
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/dashboard-metrics-scraper ClusterIP 10.103.145.248 <none> 8000/TCP 7d5h
service/kubernetes-dashboard NodePort 10.111.19.31 <none> 443:30088/TCP 7d5h
[root@k8s-master-1 nginx]#
创建账号
创建dashboard-access-token.yaml文件
[root@k8s-master-1 nginx]# cat dashboard-access-token.yaml
# Creating a Service Account
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kubernetes-dashboard
---
# Creating a ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kubernetes-dashboard
---
# Getting a long-lived Bearer Token for ServiceAccount
apiVersion: v1
kind: Secret
metadata:
name: admin-user
namespace: kubernetes-dashboard
annotations:
kubernetes.io/service-account.name: "admin-user"
type: kubernetes.io/service-account-token
# Clean up and next steps
# kubectl -n kubernetes-dashboard delete serviceaccount admin-user
# kubectl -n kubernetes-dashboard delete clusterrolebinding admin-user
[root@k8s-master-1 nginx]#
执行
kubectl apply -f dashboard-access-token.yaml
# 获取token
kubectl get secret admin-user -n kubernetes-dashboard -o jsonpath={".data.token"} | base64 -d
访问dashboard
#获取端口
[root@k8s-master-1 nginx]# kubectl get svc -n kubernetes-dashboard
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
dashboard-metrics-scraper ClusterIP 10.103.145.248 <none> 8000/TCP 7d5h
kubernetes-dashboard NodePort 10.111.19.31 <none> 443:30088/TCP 7d5h
# 端口为30088
[root@k8s-master-1 nginx]#
安装Kuborad
任意节点执行,推荐master
sudo docker run -d \
--restart=unless-stopped \
--name=kuboard \
-p 80:80/tcp \ # 可根据需要修改第一个暴露的port
-p 10081:10081/tcp \ # 无特殊需要不建议修改
-e KUBOARD_ENDPOINT="http://IP:PORT" \ # 部署在哪台机器就用什么IP:PORT
-e KUBOARD_AGENT_SERVER_TCP_PORT="10081" \
-v /root/kuboard-data:/data \ # 可根据需要修改第一个数据挂载路径
swr.cn-east-2.myhuaweicloud.com/kuboard/kuboard:v3
复制时,请把注释删除后,改好后,再粘贴,运行。
浏览器访问 http://IP:PORT(本人master节点IP为192.168.244.208,port:10081)
用户名:
admin
密 码:
Kuboard123
部署metric-server
使用Kuboard可一键集成,无需手动部署
下载
wget https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.6.2/components.yaml
修改
vim
修改140行左右
原来
containers:
- args:
...
image: k8s.gcr.io/metrics-server/metrics-server:v0.6.2
修改后:
containers:
- args:
...
- --kubelet-insecure-tls # 添加这一行
image: registry.cn-hangzhou.aliyuncs.com/google_containers/metrics-server:v0.6.2 # 修改镜像仓库地址
应用
kubectl apply -f components.yaml
查看
[root@k8s-master-1 nginx]# kubectl top nodes
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
k8s-master-1 227m 11% 1070Mi 62%
k8s-node-1 128m 12% 628Mi 72%
k8s-node-2 212m 21% 589Mi 67%
[root@k8s-master-1 nginx]# kubectl top pods
NAME CPU(cores) MEMORY(bytes)
configmap-demo-pod 0m 0Mi
[root@k8s-master-1 nginx]#
安装Krew 和Kube-Capacity
安装插件管理器Krew
# 下载压缩包
[root@k8s-master-1 ~]# wget https://mirror.ghproxy.com/https://github.com/kubernetes-sigs/krew/releases/latest/download/krew-linux_amd64.tar.gz
# 解压
[root@k8s-master-1 ~]# tar -zxvf krew-linux_amd64.tar.gz
./LICENSE
./krew-linux_amd64
# 配置环境变量
[root@k8s-master-1 ~]# vim ~/.bashrc
....
export PATH="${PATH}:${HOME}/.krew/bin"
.....
# 重新bash
[root@k8s-master-1 ~]# bash
# 验证
[root@k8s-master-1 ~]# ./krew-linux_amd64 version
OPTION VALUE
GitTag v0.4.4
GitCommit 343e657
IndexURI https://github.com/kubernetes-sigs/krew-index.git
BasePath /root/.krew
IndexPath /root/.krew/index/default
InstallPath /root/.krew/store
BinPath /root/.krew/bin
DetectedPlatform linux/amd64
# 安装
[root@k8s-master-1 ~]# mv ./krew-linux_amd64 ./kubectl-krew
[root@k8s-master-1 ~]# mv ./kubectl-krew /usr/local/bin/
# 验证
[root@k8s-master-1 ~]# kubectl krew version
OPTION VALUE
GitTag v0.4.4
GitCommit 343e657
IndexURI https://github.com/kubernetes-sigs/krew-index.git
BasePath /root/.krew
IndexPath /root/.krew/index/default
InstallPath /root/.krew/store
BinPath /root/.krew/bin
DetectedPlatform linux/amd64
# 更新索引
[root@k8s-master-1 ~]# kubectl krew update
Adding "default" plugin index from https://github.com/kubernetes-sigs/krew-index.git.
Updated the local copy of plugin index.
[root@k8s-master-1 ~]# kubectl krew info
accepts 1 arg(s), received 0
# 使用
[root@k8s-master-1 ~]# kubectl krew search
安装资源使用量终端管理工具resource-capacity
[root@k8s-master-1 ~]# kubectl krew install resource-capacity
Updated the local copy of plugin index.
Installing plugin: resource-capacity
Installed plugin: resource-capacity
\
| Use this plugin:
| kubectl resource-capacity
| Documentation:
| https://github.com/robscott/kube-capacity
/
WARNING: You installed plugin "resource-capacity" from the krew-index plugin repository.
These plugins are not audited for security by the Krew maintainers.
Run them at your own risk.
# 使用resource-capacity
# 查看节点情况
[root@k8s-master-1 ~]# kubectl resource-capacity
NODE CPU REQUESTS CPU LIMITS MEMORY REQUESTS MEMORY LIMITS
* 1700m (42%) 0m (0%) 540Mi (15%) 540Mi (15%)
k8s-master-1 1200m (60%) 0m (0%) 440Mi (25%) 340Mi (19%)
k8s-node-1 250m (25%) 0m (0%) 0Mi (0%) 0Mi (0%)
k8s-node-2 250m (25%) 0m (0%) 100Mi (11%) 200Mi (22%)
[root@k8s-master-1 ~]#
# 查看POD
[root@k8s-master-1 ~]# kubectl resource-capacity --pods
NODE NAMESPACE POD CPU REQUESTS CPU LIMITS MEMORY REQUESTS MEMORY LIMITS
* * * 1700m (42%) 0m (0%) 540Mi (15%) 540Mi (15%)
k8s-master-1 * * 1200m (60%) 0m (0%) 440Mi (25%) 340Mi (19%)
k8s-master-1 kube-system calico-node-m77cd 250m (12%) 0m (0%) 0Mi (0%) 0Mi (0%)
k8s-master-1 kube-system coredns-6d8c4cb4d-xkqx9 100m (5%) 0m (0%) 70Mi (4%) 170Mi (9%)
k8s-master-1 kube-system coredns-6d8c4cb4d-zqkvr 100m (5%) 0m (0%) 70Mi (4%) 170Mi (9%)
k8s-master-1 kubernetes-dashboard dashboard-metrics-scraper-6f669b9c9b-pp8mz 0m (0%) 0m (0%) 0Mi (0%) 0Mi (0%)
k8s-master-1 kube-system etcd-k8s-master-1 100m (5%) 0m (0%) 100Mi (5%) 0Mi (0%)
k8s-master-1 kube-system kube-apiserver-k8s-master-1 250m (12%) 0m (0%) 0Mi (0%) 0Mi (0%)
k8s-master-1 kube-system kube-controller-manager-k8s-master-1 200m (10%) 0m (0%) 0Mi (0%) 0Mi (0%)
k8s-master-1 kube-system kube-proxy-lp5qw 0m (0%) 0m (0%) 0Mi (0%) 0Mi (0%)
k8s-master-1 kube-system kube-scheduler-k8s-master-1 100m (5%) 0m (0%) 0Mi (0%) 0Mi (0%)
k8s-master-1 kuboard metrics-scraper-b9df464c7-pzjnt 0m (0%) 0m (0%) 0Mi (0%) 0Mi (0%)
k8s-master-1 kube-system metrics-server-77f66557c9-vb5fp 100m (5%) 0m (0%) 200Mi (11%) 0Mi (0%)
k8s-node-1 * * 250m (25%) 0m (0%) 0Mi (0%) 0Mi (0%)
k8s-node-1 kube-system calico-node-n9vdd 250m (25%) 0m (0%) 0Mi (0%) 0Mi (0%)
k8s-node-1 default configmap-demo-pod 0m (0%) 0m (0%) 0Mi (0%) 0Mi (0%)
k8s-node-1 kube-system kube-proxy-tf9h2 0m (0%) 0m (0%) 0Mi (0%) 0Mi (0%)
k8s-node-1 hengyang sa-luo 0m (0%) 0m (0%) 0Mi (0%) 0Mi (0%)
k8s-node-1 sanchuang sa-ross 0m (0%) 0m (0%) 0Mi (0%) 0Mi (0%)
k8s-node-1 default task-pv-pod 0m (0%) 0m (0%) 0Mi (0%) 0Mi (0%)
k8s-node-2 * * 250m (25%) 0m (0%) 100Mi (11%) 200Mi (22%)
k8s-node-2 kube-system calico-kube-controllers-64cc74d646-dntx8 0m (0%) 0m (0%) 0Mi (0%) 0Mi (0%)
k8s-node-2 kube-system calico-node-62qxx 250m (25%) 0m (0%) 0Mi (0%) 0Mi (0%)
k8s-node-2 kube-system kube-proxy-nl9p9 0m (0%) 0m (0%) 0Mi (0%) 0Mi (0%)
k8s-node-2 kubernetes-dashboard kubernetes-dashboard-57dd8bd998-wvzcr 0m (0%) 0m (0%) 0Mi (0%) 0Mi (0%)
[root@k8s-master-1 ~]#
# 宽输出
[root@k8s-master-1 ~]# kubectl resource-capacity --pods --util
NODE NAMESPACE POD CPU REQUESTS CPU LIMITS CPU UTIL MEMORY REQUESTS MEMORY LIMITS MEMORY UTIL
* * * 1700m (42%) 0m (0%) 606m (15%) 540Mi (15%) 540Mi (15%) 2342Mi (67%)
k8s-master-1 * * 1200m (60%) 0m (0%) 183m (9%) 440Mi (25%) 340Mi (19%) 1157Mi (67%)
k8s-master-1 kube-system calico-node-m77cd 250m (12%) 0m (0%) 32m (1%) 0Mi (0%) 0Mi (0%) 84Mi (4%)
k8s-master-1 kube-system coredns-6d8c4cb4d-xkqx9 100m (5%) 0m (0%) 2m (0%) 70Mi (4%) 170Mi (9%) 19Mi (1%)
k8s-master-1 kube-system coredns-6d8c4cb4d-zqkvr 100m (5%) 0m (0%) 2m (0%) 70Mi (4%) 170Mi (9%) 18Mi (1%)
k8s-master-1 kubernetes-dashboard dashboard-metrics-scraper-6f669b9c9b-pp8mz 0m (0%) 0m (0%) 1m (0%) 0Mi (0%) 0Mi (0%) 14Mi (0%)
k8s-master-1 kube-system etcd-k8s-master-1 100m (5%) 0m (0%) 18m (0%) 100Mi (5%) 0Mi (0%) 73Mi (4%)
k8s-master-1 kube-system kube-apiserver-k8s-master-1 250m (12%) 0m (0%) 51m (2%) 0Mi (0%) 0Mi (0%) 274Mi (15%)
k8s-master-1 kube-system kube-controller-manager-k8s-master-1 200m (10%) 0m (0%) 21m (1%) 0Mi (0%) 0Mi (0%) 83Mi (4%)
k8s-master-1 kube-system kube-proxy-lp5qw 0m (0%) 0m (0%) 4m (0%) 0Mi (0%) 0Mi (0%) 25Mi (1%)
k8s-master-1 kube-system kube-scheduler-k8s-master-1 100m (5%) 0m (0%) 4m (0%) 0Mi (0%) 0Mi (0%) 38Mi (2%)
k8s-master-1 kuboard metrics-scraper-b9df464c7-pzjnt 0m (0%) 0m (0%) 1m (0%) 0Mi (0%) 0Mi (0%) 16Mi (0%)
k8s-master-1 kube-system metrics-server-77f66557c9-vb5fp 100m (5%) 0m (0%) 3m (0%) 200Mi (11%) 0Mi (0%) 31Mi (1%)
k8s-node-1 * * 250m (25%) 0m (0%) 213m (21%) 0Mi (0%) 0Mi (0%) 609Mi (69%)
k8s-node-1 kube-system calico-node-n9vdd 250m (25%) 0m (0%) 53m (5%) 0Mi (0%) 0Mi (0%) 98Mi (11%)
k8s-node-1 default configmap-demo-pod 0m (0%) 0m (0%) 0m (0%) 0Mi (0%) 0Mi (0%) 1Mi (0%)
k8s-node-1 kube-system kube-proxy-tf9h2 0m (0%) 0m (0%) 14m (1%) 0Mi (0%) 0Mi (0%) 16Mi (1%)
k8s-node-1 hengyang sa-luo 0m (0%) 0m (0%) 0m (0%) 0Mi (0%) 0Mi (0%) 2Mi (0%)
k8s-node-1 sanchuang sa-ross 0m (0%) 0m (0%) 0m (0%) 0Mi (0%) 0Mi (0%) 2Mi (0%)
k8s-node-1 default task-pv-pod 0m (0%) 0m (0%) 0m (0%) 0Mi (0%) 0Mi (0%) 2Mi (0%)
k8s-node-2 * * 250m (25%) 0m (0%) 211m (21%) 100Mi (11%) 200Mi (22%) 578Mi (66%)
k8s-node-2 kube-system calico-kube-controllers-64cc74d646-dntx8 0m (0%) 0m (0%) 6m (0%) 0Mi (0%) 0Mi (0%) 25Mi (2%)
k8s-node-2 kube-system calico-node-62qxx 250m (25%) 0m (0%) 38m (3%) 0Mi (0%) 0Mi (0%) 99Mi (11%)
k8s-node-2 kube-system kube-proxy-nl9p9 0m (0%) 0m (0%) 8m (0%) 0Mi (0%) 0Mi (0%) 21Mi (2%)
k8s-node-2 kubernetes-dashboard kubernetes-dashboard-57dd8bd998-wvzcr 0m (0%) 0m (0%) 2m (0%) 0Mi (0%) 0Mi (0%) 10Mi (1%)
[root@k8s-master-1 ~]#
来自 pod 的利用率数字可能不会与总节点利用率相加。 与节点和集群级别数字代表 pod 值总和的请求和限制数字不同,节点指标直接来自指标服务器,并且可能包括其他形式的资源利用率。
# 排序
[root@k8s-master-1 ~]# kubectl resource-capacity --util --sort cpu.util
NODE CPU REQUESTS CPU LIMITS CPU UTIL MEMORY REQUESTS MEMORY LIMITS MEMORY UTIL
* 1700m (42%) 0m (0%) 616m (15%) 540Mi (15%) 540Mi (15%) 2340Mi (67%)
k8s-node-1 250m (25%) 0m (0%) 221m (22%) 0Mi (0%) 0Mi (0%) 608Mi (69%)
k8s-master-1 1200m (60%) 0m (0%) 198m (9%) 440Mi (25%) 340Mi (19%) 1157Mi (67%)
k8s-node-2 250m (25%) 0m (0%) 198m (19%) 100Mi (11%) 200Mi (22%) 577Mi (66%)
# 显示 Pod 计数
[root@k8s-master-1 ~]# kubectl resource-capacity --pod-count
NODE CPU REQUESTS CPU LIMITS MEMORY REQUESTS MEMORY LIMITS POD COUNT
* 1700m (42%) 0m (0%) 540Mi (15%) 540Mi (15%) 24/330
k8s-master-1 1200m (60%) 0m (0%) 440Mi (25%) 340Mi (19%) 11/110
k8s-node-1 250m (25%) 0m (0%) 0Mi (0%) 0Mi (0%) 6/110
k8s-node-2 250m (25%) 0m (0%) 100Mi (11%) 200Mi (22%) 7/110
# 标签过滤
kube-capacity --pod-labels app=nginx
kube-capacity --namespace 默认
kube-capacity --namespace-labels team=api
kube-capacity --node-labels kubernetes.io/role=node
服务部署
# 部署nginx
[root@k8s-master-1 ~]# kubectl create deployment nginx --image=nginx:latest
deployment.apps/nginx created
# 暴露端口
[root@k8s-master-1 ~]# kubectl expose deployment nginx --port=80 --type=NodePort
service/nginx exposed
# 查看服务状态
[root@k8s-master-1 ~]# kubectl get pods,service
NAME READY STATUS RESTARTS AGE
pod/nginx-7c658794b9-rqzn4 0/1 ContainerCreating 0 28s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 13d
service/nginx NodePort 10.96.117.244 <none> 80:30383/TCP 9s
[root@k8s-master-1 ~]#
搭建nginx负载均衡
准备两台虚拟机,用作负载均衡。
建立本地nginx官方源
cat > /etc/yum.repos.d/nginx.repo << 'EOF'
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
EOF
yum install nginx -y
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
# 添加这个
stream {
# 日志格式
log_format main '$remote_addr $upstream_addr - [$time_local] $status $upstream_bytes_sent';
# 日志存放路径
access_log /var/log/nginx/k8s-access.log main;
# master 调度资源池
upstream k8s-apiserver {
server 192.168.244.200:6443;
server 192.168.244.201:6443;
}
server {
listen 6443;
proxy_pass k8s-apiserver;# 做反向代理到资源池
}
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
检查配置文件语法,启动nginx服务,查看已监听6443端口
[root@nginx-keepalived ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@nginx-keepalived ~]# netstat -anplut | grep nginx
tcp 0 0 0.0.0.0:6443 0.0.0.0:* LISTEN 1662/nginx: master
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1662/nginx: master
[root@nginx-keepalived ~]#
搭建 keepalived 高可用服务
在两台负载均衡服务器上都要做
yum install keepalived -y
选择一台作为master,一台作为backup
修改/etc/keepalived/keepalived.conf配置文件
! Configuration File for keepalived
global_defs {
# 接收邮件地址
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
# 邮件发送地址
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id NGINX_MASTER #lb01节点的为 NGINX_MASTER,lb02节点的为 NGINX_BACKUP
}
#添加一个周期性执行的脚本
vrrp_script check_nginx {
script "/etc/nginx/check_nginx.sh" #指定检查nginx存活的脚本路径
}
vrrp_instance VI_1 {
state MASTER #lb01节点的为 MASTER,lb02节点的为 BACKUP
interface ens33 #指定网卡名称 ens33
virtual_router_id 51 #指定vrid,两个节点要一致
priority 100 #指定 k8s-nginx01 节点的为 100,k8s-nginx02 节点的为 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.205.100/24 #指定 VIP
}
track_script {
check_nginx #指定vrrp_script配置的脚本
}
}
#vrrp_strict 注释掉,遵守最严格的vrrp协议
#这是实现高可用的配置
vrrp_instance VI_1 { 启动一个vrrp的实例 VI_1 实例名,可以自定义,一个实例背后就是一个keepalived相关的进程
state MASTER --》角色是master backup
interface ens33 --》在哪个接口上监听vrrp协议,同时绑定vip到那个接口
virtual_router_id 105 --》虚拟路由id(帮派) 0~255范围
priority 120 ---》优先级 0~255
advert_int 1 --》advert interval 宣告消息 时间间隔 1秒
authentication { 认证
auth_type PASS 认证的类型是密码认证
auth_pass 11112222 具体的密码,可以自己修改
}
virtual_ipaddress { --》vip的配置,vip可以是多个ip,也可以是一个vip
192.168.200.16
192.168.200.17
192.168.200.18
}
}
另一台的配置
! Configuration File for keepalived
global_defs {
# 接收邮件地址
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
# 邮件发送地址
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id NGINX_MASTER #lb01节点的为 NGINX_MASTER,lb02节点的为 NGINX_BACKUP
}
#添加一个周期性执行的脚本
vrrp_script check_nginx {
script "/etc/nginx/check_nginx.sh" #指定检查nginx存活的脚本路径
}
vrrp_instance VI_1 {
state BACKUP #k8s-nginx01 节点的为 MASTER,k8s-nginx02节点的为 BACKUP
interface ens33 #指定网卡名称 ens33
virtual_router_id 51 #指定vrid,两个节点要一致
priority 90 #指定 k8s-nginx01 节点的为 100,k8s-nginx02 节点的为 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.205.100/24 #指定 VIP
}
track_script {
check_nginx #指定vrrp_script配置的脚本
}
}
创建 nginx 状态检查脚本
vim /etc/nginx/check_nginx.sh
#!/bin/bash
#egrep -cv "grep|$$" 用于过滤掉包含grep 或者 $$ 表示的当前Shell进程ID
count=$(ps -ef | grep nginx | egrep -cv "grep|$$")
if [ "$count" -eq 0 ];then
systemctl stop keepalived
fi
授权
chmod +x /etc/nginx/check_nginx.sh
先启动nginx,再启动keepalived
systemctl start keepalived
双vip架构
修改/etc/keepalived/keepalived.conf配置文件
在nginx-1
vrrp_instance VI_1 {
state MASTER #lb01节点的为 MASTER,lb02节点的为 BACKUP
interface ens33 #指定网卡名称 ens33
virtual_router_id 51 #指定vrid,两个节点要一致
priority 100 #指定 k8s-nginx01 节点的为 100,k8s-nginx02 节点的为 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.205.100/24 #指定 VIP
}
track_script {
check_nginx #指定vrrp_script配置的脚本
}
}
vrrp_instance VI_2 {
state BACKUP
interface ens33
virtual_router_id 52
priority 80
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.205.101/24 #指定 VIP
}
track_script {
check_nginx #指定vrrp_script配置的脚本
}
}
在nginx-2
vrrp_instance VI_1 {
state BACKUP #k8s-nginx01 节点的为 MASTER,k8s-nginx02节点的为 BACKUP
interface ens33 #指定网卡名称 ens33
virtual_router_id 51 #指定vrid,两个节点要一致
priority 80 #指定 k8s-nginx01 节点的为 100,k8s-nginx02 节点的为 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.205.100/24 #指定 VIP
}
track_script {
check_nginx #指定vrrp_script配置的脚本
}
}
vrrp_instance VI_2 {
state MASTER
interface ens33
virtual_router_id 52
priority 100 #指定 k8s-nginx01 节点的为 100,k8s-nginx02 节点的为 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.205.101/24 #指定 VIP
}
track_script {
check_nginx #指定vrrp_script配置的脚本
}
}
验证
脑裂
脑裂: 就是2台或者多台LB上都有vip地址
原因:
脑裂现象:
1.vrid(虚拟路由id)不一样
2.网络通信有问题:中间有防火墙阻止了网络之间的选举的过程,vrrp报文的通信
3.认证密码不一样也会出现脑裂
脑裂有没有危害?是否对业务有危害或者对业务有什么影响?
答案:
没有危害,能正常访问,反而还有负载均衡的作用
脑裂恢复的时候,还是有影响的,会短暂的中断,影响业务的
部署自动化运维工具ansible
ansible就是让什么主机,使用什么工具,做什么事情 --》自动化运维工具,批量部署,批量操作运维。
安装ansible软件,需要先安装epel源
[root@ansible-nfs-prome ~]# yum install epel-release -y
[root@ansible-nfs-prome ~]# yum install ansible -y
添加主机清单,新增控制的服务器
生成免密通道
上传公钥k8s集群服务器
ssh-copy-id -i id_rsa.pub root@192.168.244.200
ssh-copy-id -i id_rsa.pub root@192.168.244.201
ssh-copy-id -i id_rsa.pub root@192.168.244.202
ssh-copy-id -i id_rsa.pub root@192.168.244.203
验证,出现黄色字体表示成功。
ansible架构图
Ansible
:Ansible核心程序。HostInventory
:记录由Ansible管理的主机信息,包括端口、密码、ip等,可以控制的其他的电脑的名单。Playbooks
:“剧本”YAML格式文件,多个任务定义在一个文件中,定义主机需要调用哪些模块来完成的功能。让主机清单里的主机去批量完成的任务 -->脚本CoreModules
:核心模块,主要操作是通过调用核心模块来完成管理任务。CustomModules
:自定义模块,完成核心模块无法完成的功能,支持多种语言。ConnectionPlugins
:连接插件,Ansible和Host通信使用
部署Prometheus监控软件
Prometheus是一个开源的监控和报警系统。
架构图
核心组件:
- Prometheus server :存储数据(TSDB)、提供访问数据的接口的(HTTP)
- exporter 收集数据的
- altermanager ---》--》设置阈值 cpu 80%--》报警
- 数据可视化工具: web UI ---》user interface 用户界面
- pushgateway: 是一个中间件(代理程序)---》分布式
二进制源码安装
https://prometheus.io/download/
下载Linux64位的
新建目录/prometheeus,将下载好的压缩包放到改目录。安装过程如下
[root@ansible-nfs-prome ~]# mkdir /prome
[root@ansible-nfs-prome ~]# cd /prome/
[root@ansible-nfs-prome prome]# ls
node_exporter-1.8.2.linux-amd64.tar.gz prometheus-2.54.0.linux-amd64.tar.gz
#修改名字
[root@ansible-nfs-prome prome]# mv prometheus-2.54.0.linux-amd64 prometheus
[root@ansible-nfs-prome prome]# ls
node_exporter-1.8.2.linux-amd64.tar.gz prometheus prometheus-2.54.0.linux-amd64.tar.gz
#临时和永久配置环境变量
[root@ansible-nfs-prome prome]# PATH=/prome/prometheus:$PATH
[root@ansible-nfs-prome prome]# which prometheus
/prome/prometheus/prometheus
[root@ansible-nfs-prome prome]# echo 'PATH=/prome/prometheus:$PATH' >>/etc/profile
[root@ansible-nfs-prome prome]# which prometheus
/prome/prometheus/prometheus
#把prometheus做成一个服务来进行管理,非常方便日后维护和使用
[root@ansible-nfs-prome prome]# vim /usr/lib/systemd/system/prometheus.service
[Unit]
Description=prometheus
[Service]
ExecStart=/prome/prometheus/prometheus --config.file=/prome/prometheus/prometheus.yml
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
[Install]
WantedBy=multi-user.target
#重新加载systemd相关的服务,识别Prometheus服务的配置文件
[root@ansible-nfs-prome prome]# systemctl daemon-reload
#启动Prometheus服务
[root@ansible-nfs-prome prome]# systemctl start prometheus
[root@ansible-nfs-prome prome]# ps aux| grep prome
root 112573 5.9 4.1 1325992 41548 ? Ssl 12:53 0:00 /prome/prometheus/prometheus --config.file=/prome/prometheus/prometheus.yml
root 112670 0.0 0.0 112824 976 pts/1 R+ 12:53 0:00 grep --color=auto prome
#设置开机启动
[root@ansible-nfs-prome prome]# systemctl enable prometheus
Created symlink from /etc/systemd/system/multi-user.target.wants/prometheus.service to /usr/lib/systemd/system/prometheus.service.
[root@ansible-nfs-prome prome]#
查看本机的ip地址
[root@ansible-nfs-prome prome]# ip add
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:38:ac:f3 brd ff:ff:ff:ff:ff:ff
inet 192.168.244.204/24 brd 192.168.244.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet 192.168.205.101/24 scope global ens33
valid_lft forever preferred_lft forever
[root@ansible-nfs-prome prome]#
ip地址位192.168.244.204
访问Prometheus 的web server
http://192.168.244.204:9090
安装exporter
exporter 是Prometheus的客户端的数据采集工具--》go语言编写的
node-exporter 是专门用来采集节点服务器的通用性能指标(cpu、内存、磁盘、网速等)
vim一个安装脚本
[root@ansible-nfs-prome prome]# cat install_node_exporter.sh
#!/bin/bash
tar xf /root/node_exporter-1.8.2.linux-amd64.tar.gz -C /
cd /
mv node_exporter-1.8.2.linux-amd64/ node_exporter
cd /node_exporter/
echo 'PATH=/node_exporter/:$PATH' >>/etc/profile
#生成nodeexporter.service文件
cat >/usr/lib/systemd/system/node_exporter.service <<EOF
[Unit]
Description=node_exporter
[Service]
ExecStart=/node_exporter/node_exporter --web.listen-address 0.0.0.0:9090
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
#让systemd进程识别node_exporter服务
systemctl daemon-reload
#设置开机启动
systemctl enable node_exporter
#启动node_exporter
systemctl start node_exporter
执行脚本
[root@ansible-nfs-prome prome]# ansible all -m script -a "/prome/install_node_exporter.sh"
在其他服务器查看是由安装成功
添加被监控的服务器
在prometheus服务器上添加抓取数据的配置,添加node节点服务器,将抓取的数据存储到时序数据库里。
[root@ansible-nfs-prome prometheus]# pwd
/prome/prometheus
[root@ansible-nfs-prome prometheus]# vim prometheus.yml
添加以下配置
重启Prometheus服务
[root@ansible-nfs-prome prometheus]# systemctl restart prometheus
查看是否成功
安装grafana出图展示
[root@ansible-nfs-prome prome]# ls
grafana-enterprise-9.1.2-1.x86_64.rpm install_node_exporter.sh node_exporter-1.8.2.linux-amd64.tar.gz prometheus prometheus-2.54.0.linux-amd64.tar.gz
[root@ansible-nfs-prome prome]#
[root@ansible-nfs-prome prome]# yum install grafana-enterprise-9.1.2-1.x86_64.rpm -y
#启动grafana
[root@ansible-nfs-prome prome]# systemctl start grafana-server
#设置开机启动
[root@ansible-nfs-prome prome]# systemctl enable grafana-server
Created symlink from /etc/systemd/system/multi-user.target.wants/grafana-server.service to /usr/lib/systemd/system/grafana-server.service.
#查看grafana是否启动
[root@ansible-nfs-prome prome]# ps aux|grep grafana
grafana 1587 0.6 6.6 1277776 66064 ? Ssl 13:46 0:01 /usr/sbin/grafana-server --config=/etc/grafana/grafana.ini --pidfile=/var/run/grafana/grafana-server.pid --packaging=rpm cfg:default.paths.logs=/var/log/grafana cfg:default.paths.data=/var/lib/grafana cfg:default.paths.plugins=/var/lib/grafana/plugins cfg:default.paths.provisioning=/etc/grafana/provisioning
root 2745 0.0 0.0 112824 972 pts/1 R+ 13:49 0:00 grep --color=auto grafana
[root@ansible-nfs-prome prome]#
#查看监听端口号
[root@ansible-nfs-prome prome]# netstat -anplut | grep grafana
tcp6 0 0 :::3000 :::* LISTEN 1587/grafana-server
[root@ansible-nfs-prome prome]#
访问http://192.168.244.204:3000
默认的用户名和密码是
用户名admin
密码admin
登陆进来的界面
先配置prometheus的数据源
管理--》数据源--》add new data source-->prometheus
点击添加数据源(add data source)
选择Prometheus数据库
填写好配置
点击测试是否能成功连接到Prometheus 时序数据库
导入grafana的模板
点击Dashboards 进入仪表盘设置
点击import直接导入模板
输入8919模板,点击load
给模板起一个名字,然后选择Prometheus数据库,最后点击import
进入dashboard界面,看到非常漂亮的监控效果图
这2个模板ID非常好用,推荐使用
- 1860
- 8919 -->推荐使用,因为是中文版的字符
部署nfs+pv+pvc服务器
pod–>volume–>pvc–>pv–>nfs
卷(Volume)当容器崩溃或停止时会出现一个问题。此时容器状态未保存, 因此在容器生命周期内创建或修改的所有文件都将丢失。 在崩溃期间,kubelet 会以干净的状态重新启动容器。 当多个容器在一个 Pod 中运行并且需要共享文件时,会出现另一个问题。 跨所有容器设置和访问共享文件系统具有一定的挑战性。
持久卷(PersistentVolume,PV) 是集群中的一块存储,可以由管理员事先制备, 或者使用存储类(Storage Class)来动态制备。 持久卷是集群资源,就像节点也是集群资源一样。PV 持久卷和普通的 Volume 一样, 也是使用卷插件来实现的,只是它们拥有独立于任何使用 PV 的 Pod 的生命周期。 此 API 对象中记述了存储的实现细节,无论其背后是 NFS、iSCSI 还是特定于云平台的存储系统。
持久卷申领(PersistentVolumeClaim,PVC) 表达的是用户对存储的请求。概念上与 Pod 类似。 Pod 会耗用节点资源,而 PVC 申领会耗用 PV 资源。Pod 可以请求特定数量的资源(CPU 和内存)。同样 PVC 申领也可以请求特定的大小和访问模式 (例如,可以挂载为 ReadWriteOnce、ReadOnlyMany、ReadWriteMany 或 ReadWriteOncePod等)。
存储类(StorageClass)尽管 PersistentVolumeClaim 允许用户消耗抽象的存储资源, 常见的情况是针对不同的问题用户需要的是具有不同属性(如,性能)的 PersistentVolume 卷。 集群管理员需要能够提供不同性质的 PersistentVolume, 并且这些 PV 卷之间的差别不仅限于卷大小和访问模式,同时又不能将卷是如何实现的这些细节暴露给用户。
PV代表的是k8s中的存储;PVC就像许可证,赋予Pod访问PV的权限;StorageClass则使分配过程是动态的
1.搭建好nfs服务器
# 在nfs服务器和k8s集群上安装nfs
[root@ansible-nfs-prome ~]# yum install nfs-utils -y
[root@k8s-master-1 ~]# yum install nfs-utils -y
[root@k8s-node-1 ~]# yum install nfs-utils -y
[root@k8s-node-2 ~]# yum install nfs-utils -y
2.设置共享目录
[root@ansible-nfs-prome ~]# vim /etc/exports
[root@ansible-nfs-prome ~]# cat /etc/exports
/nfs/share 192.168.244.*(rw,no_root_squash,sync)
[root@ansible-nfs-prome ~]#
[root@ansible-nfs-prome ~]# mkdir /nfs/share
[root@ansible-nfs-prome ~]# cd /nfs/share/
[root@ansible-nfs-prome share]# echo "ross" >index.html
[root@ansible-nfs-prome share]# ls
index.html
[root@ansible-nfs-prome share]# cat index.html
ross
[root@ansible-nfs-prome share]#
[root@ansible-nfs-prome share]# exportfs -rv #刷新nfs服务
exporting 192.168.244.*:/nfs/share
#重启服务并且设置开机启动
[root@ansible-nfs-prome share]# systemctl restart nfs && systemctl enable nfs
3.创建pv使用nfs服务器上的共享目录
[root@k8s-master-1 mysql]# cd /nfs
[root@k8s-master-1 nfs]# ls
nfs-pvc.yaml nfs-pv.yaml nginx.deployment.yaml
[root@k8s-master-1 nfs]#
[root@k8s-master-1 nfs]# cat nfs-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: nginx-pv
labels:
type: nginx-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteMany
storageClassName: nfs #pv对应的名字
nfs:
path: "/nfs/share" #nfs共享的目录
server: 192.168.244.204 #nfs服务器的ip地址
readOnly: false #访问模式
[root@k8s-master-1 nfs]# kubectl apply -f nfs-pv.yaml
persistentvolume/nginx-pv created
[root@k8s-master-1 nfs]#
[root@k8s-master-1 nfs]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
nginx-pv 10Gi RWX Retain Bound default/nginx-pvc nfs 92m
[root@k8s-master-1 nfs]#
# 创建pvc使用pv
[root@k8s-master-1 nfs]# vim nfs-pvc.yml
[root@k8s-master-1 nfs]# cat nfs-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nginx-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
storageClassName: nfs #使用nfs类型的pv
[root@k8s-master-1 nfs]#
[root@k8s-master-1 nfs]# kubectl apply -f nfs-pvc.yaml
persistentvolumeclaim/nginx-pvc created
[root@k8s-master-1 nfs]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
nginx-pvc Bound nginx-pv 10Gi RWX nfs 94m
[root@k8s-master-1 nfs]#
#创建pod使用pvc
[root@k8s-master-1 nfs]# vim nginx-deployment.yaml
[root@k8s-master-1 nfs]# cat nginx.deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment-nfs
labels:
app: nginx-nfs
spec:
replicas: 3
selector:
matchLabels:
app: nginx-nfs
template:
metadata:
labels:
app: nginx-nfs
spec:
#定义卷
volumes:
- name: pv-storage-nfs
persistentVolumeClaim:
claimName: nginx-pvc
containers:
- name: nginx
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
#容器里调用卷
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: pv-storage-nfs
[root@k8s-master-1 nfs]# kubectl apply -f nginx.deployment.yaml
[root@k8s-master-1 nfs]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-nfs-d89bc5845-4zsrk 1/1 Running 0 14s 10.224.140.69 k8s-node-2 <none> <none>
nginx-deployment-nfs-d89bc5845-dm56n 1/1 Running 0 14s 10.224.109.80 k8s-node-1 <none> <none>
nginx-deployment-nfs-d89bc5845-vdd2h 1/1 Running 0 14s 10.224.109.79 k8s-node-1 <none> <none>
[root@k8s-master-1 nfs]#
测试
[root@k8s-master-1 nfs]# curl 10.224.140.69
ross
[root@k8s-master-1 nfs]#
#修改下nfs服务器上的index.html的内容
[root@ansible-nfs-prome share]# vim index.html
[root@ansible-nfs-prome share]# cat index.html
welcome to changsha ross!
[root@k8s-master-1 nfs]# curl 10.224.140.69
welcome to changsha ross! #访问也变了,表示已经成功!
[root@k8s-master-1 nfs]#
使用ingress给web业务做基于域名的负载均衡,基于url的负载均衡的实现
ingress 和ingress controller 的关系
ingress controller 本质上是一个nginx软件,用来做负载均衡
ingress 是k8s内部管理nginx配置(nginx.conf)的组件,用来给ingress controller传参
建议参考安装部署文档
- 入口控制器( Ingress Controller )是 Kubernetes 中的一个关键组件,用于管理入口资源对象。
- Ingress 资源对象用于定义来自外网的 HTTP 和 HTTPS 规则,以控制进入集群内服务的流量。而 Ingress Controller 则是真正实现 Ingress 规则的组件。
- 节点(Node): Kubernetes 集群中的一台工作机器,是集群的一部分。
- 集群(Cluster): 一组运行容器化应用程序的 Node,这些应用由 Kubernetes 管理。 在此示例和在大多数常见的 Kubernetes 部署环境中,集群中的节点都不在公共网络中。
- 边缘路由器(Edge Router): 在集群中强制执行防火墙策略的路由器。 可以是由云提供商管理的网关,也可以是物理硬件。
- 集群网络(Cluster Network): 一组逻辑的或物理的连接,基于 Kubernetes 网络模型实现集群内的通信。
- 服务(Service):Kubernetes 服务(Service), 使用标签选择算符(Selectors) 来选择一组 Pod。除非另作说明,否则假定 Service 具有只能在集群网络内路由的虚拟 IP。
下面是 Ingress 的一个简单示例,可将所有流量都发送到同一 Service:
通过配置,Ingress 可为 Service 提供外部可访问的 URL、对其流量作负载均衡、 终止 SSL/TLS,以及基于名称的虚拟托管等能力。 Ingress 控制器 负责完成 Ingress 的工作,具体实现上通常会使用某个负载均衡器, 不过也可以配置边缘路由器或其他前端来帮助处理流量。
Ingress 不会随意公开端口或协议。 将 HTTP 和 HTTPS 以外的服务开放到 Internet 时,通常使用 Service.Type=NodePort 或 Service.Type=LoadBalancer 类型的 Service。
[root@k8s-master-1 ~]# mkdir /ingress
[root@k8s-master-1 ~]# cd /ingress
[root@k8s-master-1 ingress]# ls
ingress-controller-deploy.yaml kube-webhook-certgen-v1.1.0.tar.gz nfs-pv.yaml sc-ingress-url.yaml sc-nginx-svc-1.yaml sc-nginx-svc-4.yaml
ingress-nginx-controllerv1.1.0.tar.gz nfs-pvc.yaml nginx-deployment-nginx-svc-2.yaml sc-ingress.yaml sc-nginx-svc-3.yaml
ingress-controller-deploy.yaml 是部署ingress controller使用的yaml文件
ingress-nginx-controllerv1.1.0.tar.gz ingress-nginx-controller镜像
kube-webhook-certgen-v1.1.0.tar.gz kube-webhook-certgen镜像
#kube-webhook-certgen镜像主要用于生成Kubernetes集群中用于Webhook的证书。
#kube-webhook-certgen镜像生成的证书,可以确保Webhook服务在Kubernetes集群中的安全通信和身份验证
ingress.yaml 创建ingress的配置文件
sc-nginx-svc-1.yaml 启动sc-nginx-svc服务和相关pod的yaml
nginx-deployment-nginx-svc-2.yaml 启动sc-nginx-svc-2服务和相关pod的yaml
nginx-svc-3.yaml 创建service3 和相关pod
nginx-svc-4.yaml 创建service4 和相关pod
第1大步骤: 安装ingress controller
1.将镜像scp到所有的node节点服务器上
[root@k8s-master-1 ingress]# scp ingress-nginx-controllerv1.1.0.tar.gz k8s-node-1:/root
[root@k8s-master-1 ingress]# scp ingress-nginx-controllerv1.1.0.tar.gz k8s-node-2:/root
[root@k8s-master-1 ingress]#
[root@k8s-master-1 ingress]# scp kube-webhook-certgen-v1.1.0.tar.gz k8s-node-1:/root
[root@k8s-master-1 ingress]# scp kube-webhook-certgen-v1.1.0.tar.gz k8s-node-2:/root
2.导入镜像,在所有的节点服务器(node-1和node-2)上进行
[root@k8s-node-1 ~]# docker load -i ingress-nginx-controllerv1.1.0.tar.gz
[root@k8s-node-2 ~]# docker load -i ingress-nginx-controllerv1.1.0.tar.gz
3.使用ingress-controller-deploy.yaml 文件去启动ingress controller
[root@k8s-master-1 ingress]# kubectl apply -f ingress-controller-deploy.yaml
#查看ingress controller的相关命名空间
[root@k8s-master-1 ingress]# kubectl get ns
NAME STATUS AGE
default Active 6h17m
ingress-nginx Active 54s
kube-node-lease Active 6h17m
kube-public Active 6h17m
kube-system Active 6h17m
kubernetes-dashboard Active 4h54m
kuboard Active 101m
[root@k8s-master-1 ingress]#
#查看ingress controller的相关service
[root@k8s-master-1 ingress]# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller NodePort 10.105.167.67 <none> 80:30382/TCP,443:30759/TCP 84s
ingress-nginx-controller-admission ClusterIP 10.108.85.20 <none> 443/TCP 87s
[root@k8s-master-1 ingress]#
#查看ingress controller的相关pod
[root@k8s-master-1 ingress]# kubectl get pod -n ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-bns7g 0/1 Completed 0 117s
ingress-nginx-admission-patch-kmkdp 0/1 Completed 0 117s
ingress-nginx-controller-7cd558c647-x29mc 1/1 Running 0 117s
ingress-nginx-controller-7cd558c647-zv4rh 1/1 Running 0 117s
[root@k8s-master-1 ingress]#
第2大步骤: 创建pod和暴露pod的服务
[root@k8s-master-1 ingress]# cat sc-nginx-svc-1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: sc-nginx-deploy
labels:
app: sc-nginx-feng
spec:
replicas: 3
selector:
matchLabels:
app: sc-nginx-feng
template:
metadata:
labels:
app: sc-nginx-feng
spec:
containers:
- name: sc-nginx-feng
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: sc-nginx-svc
labels:
app: sc-nginx-svc
spec:
selector:
app: sc-nginx-feng
ports:
- name: name-of-service-port
protocol: TCP
port: 80
targetPort: 80
[root@k8s-master-1 ingress]# kubectl apply -f sc-nginx-svc-1.yaml
deployment.apps/sc-nginx-deploy created
service/sc-nginx-svc created
[root@k8s-master-1 ingress]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ab-nginx-svc NodePort 10.108.100.140 <none> 80:31000/TCP 4h50m
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 6h21m
sc-nginx-svc ClusterIP 10.99.124.194 <none> 80/TCP 56s
[root@k8s-master-1 ingress]#
#查看服务器的详细信息,查看Endpoints对应的pod的ip和端口是否正常
[root@k8s-master-1 ingress]# kubectl describe svc sc-nginx-svc
Name: sc-nginx-svc
Namespace: default
Labels: app=sc-nginx-svc
Annotations: <none>
Selector: app=sc-nginx-feng
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.99.124.194
IPs: 10.99.124.194
Port: name-of-service-port 80/TCP
TargetPort: 80/TCP
Endpoints: 10.224.109.87:80,10.224.109.88:80,10.224.140.74:80
Session Affinity: None
Events: <none>
[root@k8s-master-1 ingress]#
#访问服务暴露的ip
[root@k8s-master-1 ingress]# curl 10.99.124.194
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@k8s-master-1 ingress]#
第3大步骤: 启用ingress 关联ingress controller 和service
[root@k8s-master-1 ingress]# cat sc-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: sc-ingress
annotations:
kubernets.io/ingress.class: nginx
spec:
ingressClassName: nginx
rules:
- host: www.feng.com
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: sc-nginx-svc
port:
number: 80
- host: www.zhang.com
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: sc-nginx-svc-2
port:
number: 80
[root@k8s-master-1 ingress]# kubectl apply -f sc-ingress.yaml
ingress.networking.k8s.io/sc-ingress created
[root@k8s-master-1 ingress]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
sc-ingress nginx www.feng.com,www.zhang.com 192.168.244.202,192.168.244.203 80 40s
[root@k8s-master-1 ingress]#
第4步: 查看ingress controller 里的nginx.conf 文件里是否有ingress对应的规则
[root@k8s-master-1 ingress]# kubectl get pod -n ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-bns7g 0/1 Completed 0 10m
ingress-nginx-admission-patch-kmkdp 0/1 Completed 0 10m
ingress-nginx-controller-7cd558c647-x29mc 1/1 Running 0 10m
ingress-nginx-controller-7cd558c647-zv4rh 1/1 Running 0 10m
[root@k8s-master-1 ingress]#
#进入ingress controller对应的pod里查看nginx.conf的配置
[root@k8s-master-1 ingress]#kubectl exec -n ingress-nginx -it ingress-nginx-controller-7cd558c647-x29mc -- bash
bash-5.1$ cat nginx.conf|grep zhang.com
## start server www.zhang.com
server_name www.zhang.com ;
## end server www.zhang.com
bash-5.1$ cat nginx.conf|grep feng.com
## start server www.feng.com
server_name www.feng.com ;
## end server www.feng.com
bash-5.1$ cat nginx.conf|grep -C3 upstream_balancer
proxy_ssl_session_reuse on;
upstream upstream_balancer {
### Attention!!!
#
# We no longer create "upstream" section for every backend.
--
proxy_next_upstream_timeout 0;
proxy_next_upstream_tries 3;
proxy_pass http://upstream_balancer;
proxy_redirect off;
--
proxy_next_upstream_timeout 0;
proxy_next_upstream_tries 3;
proxy_pass http://upstream_balancer;
proxy_redirect off;
--
proxy_next_upstream_timeout 0;
proxy_next_upstream_tries 3;
proxy_pass http://upstream_balancer;
proxy_redirect off;
--
error_log /var/log/nginx/error.log notice;
upstream upstream_balancer {
server 0.0.0.1:1234; # placeholder
balancer_by_lua_block {
bash-5.1$
#获取ingress controller对应的service暴露宿主机的端口,访问宿主机和相关端口,就可以验证ingress controller是否能进行负载均衡
[root@k8s-master-1 ingress]# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller NodePort 10.105.167.67 <none> 80:30382/TCP,443:30759/TCP 17m
ingress-nginx-controller-admission ClusterIP 10.108.85.20 <none> 443/TCP 17m
[root@k8s-master-1 ingress]#
#在其他的宿主机(nfs服务器上)或者windows机器上使用域名进行访问
[root@ansible-nfs-prome ~]# vim /etc/hosts
[root@ansible-nfs-prome ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.244.202 www.feng.com
192.168.244.203 www.zhang.com
[root@ansible-nfs-prome ~]#
因为我们是基于域名做的负载均衡的配置,所有必须要在浏览器里使用域名去访问,不能使用ip地址
同时ingress controller做负载均衡的时候是基于http协议的,7层负载均衡
[root@ansible-nfs-prome ~]# curl www.feng.com
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@ansible-nfs-prome ~]#
[root@ansible-nfs-prome ~]# curl www.zhang.com
<html>
<head><title>503 Service Temporarily Unavailable</title></head>
<body>
<center><h1>503 Service Temporarily Unavailable</h1></center>
<hr><center>nginx</center>
</body>
</html>
[root@ansible-nfs-prome ~]#
第5步:启动第2个服务和pod,使用了pv+pvc+nfs
需要提前准备好nfs服务器+创建pv和pvc
[root@k8s-master-1 ingress]# cat nginx-deployment-nginx-svc-2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: sc-nginx-feng-2
template:
metadata:
labels:
app: sc-nginx-feng-2
spec:
volumes:
- name: sc-pv-storage-nfs
persistentVolumeClaim:
claimName: nginx-pvc
containers:
- name: sc-pv-container-nfs
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
name: "http-server"
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: sc-pv-storage-nfs
---
apiVersion: v1
kind: Service
metadata:
name: sc-nginx-svc-2
labels:
app: sc-nginx-svc-2
spec:
selector:
app: sc-nginx-feng-2
ports:
- name: name-of-service-port
protocol: TCP
port: 80
targetPort: 80
[root@k8s-master-1 ingress]# kubectl apply -f nginx-deployment-nginx-svc-2.yaml
deployment.apps/nginx-deployment created
service/sc-nginx-svc-2 created
[root@k8s-master-1 ingress]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ab-nginx-svc NodePort 10.108.100.140 <none> 80:31000/TCP 22h
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 23h
sc-nginx-svc ClusterIP 10.99.124.194 <none> 80/TCP 17h
sc-nginx-svc-2 ClusterIP 10.99.206.179 <none> 80/TCP 23s
[root@k8s-master-1 ingress]#
[root@k8s-master-1 ingress]# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller NodePort 10.105.167.67 <none> 80:30382/TCP,443:30759/TCP 17h
ingress-nginx-controller-admission ClusterIP 10.108.85.20 <none> 443/TCP 17h
[root@k8s-master-1 ingress]#
[root@k8s-master-1 ingress]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
sc-ingress nginx www.feng.com,www.zhang.com 192.168.244.202,192.168.244.203 80 17h
[root@k8s-master-1 ingress]#
访问宿主机暴露的端口号30092或者80都可以
使用ingress controller暴露服务,感觉不需要使用30000以上的端口访问,可以直接访问80或者443
比使用service 暴露服务还是有点优势
基于url的负载均衡的实现
sc-ingress-url.yaml --》是创建一个基于URL做负载均衡的ingress
sc-nginx-svc-3.yaml 创建service3 和相关pod
sc-nginx-svc-4.yaml 创建service4 和相关pod
[root@k8s-master-1 ingress]# ls
ingress-controller-deploy.yaml kube-webhook-certgen-v1.1.0.tar.gz nfs-pv.yaml sc-ingress-url.yaml sc-nginx-svc-1.yaml sc-nginx-svc-4.yaml
ingress-nginx-controllerv1.1.0.tar.gz nfs-pvc.yaml nginx-deployment-nginx-svc-2.yaml sc-ingress.yaml sc-nginx-svc-3.yaml
[root@k8s-master-1 ingress]#
#查看目前已经存在的ingress ,是基于域名的负载均衡
[root@k8s-master-1 ingress]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
sc-ingress nginx www.feng.com,www.zhang.com 192.168.244.202,192.168.244.203 80 18h
[root@k8s-master-1 ingress]#
#下面我们去创建另外一个基于url的负载均衡的ingress
[root@k8s-master-1 ingress]# cat sc-ingress-url.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: simple-fanout-example
annotations:
kubernets.io/ingress.class: nginx
spec:
ingressClassName: nginx
rules:
- host: www.wen.com
http:
paths:
- path: /foo
pathType: Prefix
backend:
service:
name: sc-nginx-svc-3
port:
number: 80
- path: /bar
pathType: Prefix
backend:
service:
name: sc-nginx-svc-4
port:
number: 80
[root@k8s-master-1 ingress]#
[root@k8s-master-1 ingress]# kubectl apply -f sc-ingress-url.yaml
ingress.networking.k8s.io/simple-fanout-example created
[root@k8s-master-1 ingress]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
sc-ingress nginx www.feng.com,www.zhang.com 192.168.244.202,192.168.244.203 80 18h
simple-fanout-example nginx www.wen.com 80 14s
[root@k8s-master-1 ingress]#
[root@k8s-master-1 ingress]# cat sc-nginx-svc-3.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: sc-nginx-deploy-3
labels:
app: sc-nginx-feng-3
spec:
replicas: 3
selector:
matchLabels:
app: sc-nginx-feng-3
template:
metadata:
labels:
app: sc-nginx-feng-3
spec:
containers:
- name: sc-nginx-feng-3
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: sc-nginx-svc-3
labels:
app: sc-nginx-svc-3
spec:
selector:
app: sc-nginx-feng-3
ports:
- name: name-of-service-port
protocol: TCP
port: 80
targetPort: 80
[root@k8s-master-1 ingress]#
[root@k8s-master-1 ingress]# cat sc-nginx-svc-4.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: sc-nginx-deploy-4
labels:
app: sc-nginx-feng-4
spec:
replicas: 3
selector:
matchLabels:
app: sc-nginx-feng-4
template:
metadata:
labels:
app: sc-nginx-feng-4
spec:
containers:
- name: sc-nginx-feng-4
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: sc-nginx-svc-4
labels:
app: sc-nginx-svc-4
spec:
selector:
app: sc-nginx-feng-4
ports:
- name: name-of-service-port
protocol: TCP
port: 80
targetPort: 80
[root@k8s-master-1 ingress]#
[root@k8s-master-1 ingress]# kubectl apply -f sc-nginx-svc-3.yaml
deployment.apps/sc-nginx-deploy-3 created
service/sc-nginx-svc-3 created
[root@k8s-master-1 ingress]#
[root@k8s-master-1 ingress]# kubectl apply -f sc-nginx-svc-4.yaml
deployment.apps/sc-nginx-deploy-4 created
service/sc-nginx-svc-4 created
[root@k8s-master-1 ingress]#
[root@k8s-master-1 ingress]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
sc-ingress nginx www.feng.com,www.zhang.com 192.168.244.202,192.168.244.203 80 18h
simple-fanout-example nginx www.wen.com 192.168.244.202,192.168.244.203 80 2m44s
[root@k8s-master-1 ingress]#
#在nfs服务器上进行测试,需要在/etc/hosts文件里添加域名解析记录
[root@ansible-nfs-prome nfs]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.244.202 www.feng.com
192.168.244.203 www.wen.com
192.168.244.202 www.wen.com
192.168.244.203 www.zhang.com
[root@ansible-nfs-prome nfs]#
[root@ansible-nfs-prome nfs]# curl www.wen.com/foo
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.27.1</center>
</body>
</html>
[root@ansible-nfs-prome nfs]#
#测试发现不能找到页面,到底是ingress controller的问题还是我们后端的pod的问题
思路:
1.进入ingress控制器的内部查看是否加载基于URL的负载均衡的配置
[root@k8s-master-1 ingress]# kubectl get pod -n ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-bns7g 0/1 Completed 0 18h
ingress-nginx-admission-patch-kmkdp 0/1 Completed 0 18h
ingress-nginx-controller-7cd558c647-x29mc 1/1 Running 0 18h
ingress-nginx-controller-7cd558c647-zv4rh 1/1 Running 0 18h
[root@k8s-master-1 ingress]# kubectl exec -it -n ingress-nginx ingress-nginx-controller-7cd558c647-x29mc -- bash
bash-5.1$ cat nginx.conf|grep www.wen.com
## start server www.wen.com
server_name www.wen.com ;
## end server www.wen.com
bash-5.1$
2.看pod的日志和详细信息
[root@k8s-master-1 ingress]# kubectl logs -n ingress-nginx ingress-nginx-controller-7cd558c647-x29mc
3.查看最后提供web服务器的pod的日志
[root@k8s-master-1 ingress]# kubectl get pod
NAME READY STATUS RESTARTS AGE
sc-nginx-deploy-3-5c4b975ffc-cf4wz 1/1 Running 0 13m
sc-nginx-deploy-3-5c4b975ffc-lbtmk 1/1 Running 0 13m
sc-nginx-deploy-3-5c4b975ffc-pzndq 1/1 Running 0 13m
sc-nginx-deploy-4-7d4b5c487f-g552b 1/1 Running 0 13m
sc-nginx-deploy-4-7d4b5c487f-kscnv 1/1 Running 0 13m
sc-nginx-deploy-4-7d4b5c487f-szq5l 1/1 Running 0 13m
[root@k8s-master-1 ingress]# kubectl logs sc-nginx-deploy-3-5c4b975ffc-pzndq -f
2024/09/01 08:44:37 [error] 29#29: *1 open() "/usr/share/nginx/html/foo" failed (2: No such file or directory), client: 192.168.244.203, server: localhost, request: "GET /foo HTTP/1.1", host: "www.wen.com"
192.168.244.203 - - [01/Sep/2024:08:44:37 +0000] "GET /foo HTTP/1.1" 404 153 "-" "curl/7.29.0" "192.168.244.204"
2024/09/01 08:53:57 [error] 29#29: *2 open() "/usr/share/nginx/html/foo" failed (2: No such file or directory), client: 192.168.244.203, server: localhost, request: "GET /foo HTTP/1.1", host: "www.wen.com"
192.168.244.203 - - [01/Sep/2024:08:53:57 +0000] "GET /foo HTTP/1.1" 404 153 "-" "curl/7.29.0" "192.168.244.204"
2024/09/01 08:55:07 [error] 29#29: *3 open() "/usr/share/nginx/html/foo" failed (2: No such file or directory), client: 192.168.244.203, server: localhost, request: "GET /foo HTTP/1.1", host: "www.wen.com"
192.168.244.203 - - [01/Sep/2024:08:55:07 +0000] "GET /foo HTTP/1.1" 404 153 "-" "curl/7.29.0" "192.168.244.204"
#/usr/share/nginx/html/bar 文件夹不存在,导致404错误
#进入service4 对应的一个pod里,新建bar和foo文件夹以及index.html网页文件
[root@k8s-master-1 ingress]# kubectl exec -it sc-nginx-deploy-3-5c4b975ffc-pzndq -- bash
root@sc-nginx-deploy-3-5c4b975ffc-pzndq:/# cd /usr/share/nginx/html/
root@sc-nginx-deploy-3-5c4b975ffc-pzndq:/usr/share/nginx/html# ls
50x.html index.html
root@sc-nginx-deploy-3-5c4b975ffc-pzndq:/usr/share/nginx/html# mkdir bar
root@sc-nginx-deploy-3-5c4b975ffc-pzndq:/usr/share/nginx/html# echo "hello,bar" >bar/index.html
root@sc-nginx-deploy-3-5c4b975ffc-pzndq:/usr/share/nginx/html# ls
50x.html bar index.html
root@sc-nginx-deploy-3-5c4b975ffc-pzndq:/usr/share/nginx/html# cd bar
root@sc-nginx-deploy-3-5c4b975ffc-pzndq:/usr/share/nginx/html/bar# ls
index.html
root@sc-nginx-deploy-3-5c4b975ffc-pzndq:/usr/share/nginx/html/bar# cat index.html
hello,bar
root@sc-nginx-deploy-3-5c4b975ffc-pzndq:/usr/share/nginx/html/bar#
#再次在nfs服务器上测试,多测试几次,因为service 背后的ipvs的调度算法是轮询的
[root@ansible-nfs-prome nfs]# curl www.wen.com/bar/index.html
hello,bar
[root@ansible-nfs-prome nfs]#
需要在后端的pod里/usr/share/nginx/html里新建bar和foo文件夹,里面新建index.html页面
在nfs服务器上测试的时候访问路径如下:
curl www.wen.com/bar/index.html
curl www.wen.com/foo/index.html
验证和排错
#查看配置的负载均衡策略
[root@k8s-master-1 ingress]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
sc-ingress nginx www.feng.com,www.zhang.com 192.168.244.202,192.168.244.203 80 18h
simple-fanout-example nginx www.wen.com 192.168.244.202,192.168.244.203 80 27m
[root@k8s-master-1 ingress]# kubectl describe ingress simple-fanout-example
Name: simple-fanout-example
Labels: <none>
Namespace: default
Address: 192.168.244.202,192.168.244.203
Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
Host Path Backends
---- ---- --------
www.wen.com
/foo sc-nginx-svc-3:80 (10.224.109.89:80,10.224.109.90:80,10.224.140.75:80)
/bar sc-nginx-svc-4:80 (10.224.109.91:80,10.224.140.76:80,10.224.140.77:80)
Annotations: kubernets.io/ingress.class: nginx
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Sync 27m (x2 over 28m) nginx-ingress-controller Scheduled for sync
Normal Sync 27m (x2 over 28m) nginx-ingress-controller Scheduled for sync
[root@k8s-master-1 ingress]#
#在ingress-controller上查看负载均衡的情况
[root@k8s-master-1 ingress]# kubectl get pod -n ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-bns7g 0/1 Completed 0 18h
ingress-nginx-admission-patch-kmkdp 0/1 Completed 0 18h
ingress-nginx-controller-7cd558c647-x29mc 1/1 Running 0 18h
ingress-nginx-controller-7cd558c647-zv4rh 1/1 Running 0 18h
[root@k8s-master-1 ingress]# kubectl logs -n ingress-nginx ingress-nginx-controller-7cd558c647-x29mc -f
#查看service对应的endpoint 是否存在,就可以指定service是否有问题
[root@k8s-master-1 ingress]# kubectl get ep
NAME ENDPOINTS AGE
ab-nginx-svc <none> 23h
kubernetes 192.168.244.200:6443 25h
sc-nginx-svc <none> 18h
sc-nginx-svc-3 10.224.109.89:80,10.224.109.90:80,10.224.140.75:80 29m
sc-nginx-svc-4 10.224.109.91:80,10.224.140.76:80,10.224.140.77:80 29m
[root@k8s-master-1 ingress]#
数据的流程
数据的流程
ingress-controller--》ingress--》service-->pod
资源管理
资源管理介绍
kubernetes 的本质上就是一个集群系统,用户可以在集群中部署各种服务,所谓的部署服务,其实就是在 kubernetes 集群中运行一个个的容器,并将指定的程序跑在容器中。kubernetes 的最小管理单元是 pod 而不是容器,所以只能将容器放在 Pod 中,而 kubernetes 一般也不会直接管理 Pod ,而是通过 Pod控制器 来管理 Pod 的。Pod 可以提供服务之后,就要考虑如何访问 Pod 中服务, kubernetes 提供了 Service 资源实现这个功能。当然,如果 Pod 中程序的数据需要持久化, kubernetes 还提供了各种 存储 系统。
学习 kubernetes 的核心,就是学习如何对集群上的 Pod、Pod控制器、Service、存储 等各种资源进行操作
查看k8s里的所有的资源的名字以及简称
YAML语言介绍
- 大小写敏感
- 使用缩进表示层级关系
- 缩进不允许使用tab,只允许空格( 低版本限制 )
- 缩进的空格数不重要,只要相同层级的元素左对齐即可
- '#'表示注释
YAML支持以下几种数据类型:
- 纯量:单个的、不可再分的值
- 对象:键值对的集合,又称为映射(mapping)/ 哈希(hash) / 字典(dictionary)
- 数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)
提示:1 书写 yaml 切记 : 后面要加一个空格2 如果需要将多段 yaml 配置放在一个文件中,中间要使用 --- 分隔
资源管理方式
- 命令式对象管理:直接使用命令去操作kubernetes资源 kubectl run nginx-pod --image=nginx:latest --port=80
- 命令式对象配置:通过命令配置和配置文件去操作kubernetes资源 kubectl create/patch -f nginx-pod.yaml
- 声明式对象配置:通过apply命令和配置文件去操作kubernetes资源 kubectl apply -f nginx-pod.yaml
类型 |
操作对
象
|
适用环
境
|
优点
|
缺点
|
---|---|---|---|---|
命令式对象管理
|
对象
|
测试
|
简单
|
只能操作活动对象,无法审计、 跟踪
|
命令式对象配 置
|
文件
|
开发
|
可以审计、跟踪
|
项目大时,配置文件多,操作麻烦
|
声明式对象配置
|
目录
|
开发
|
支持目录操作
|
意外情况下难以调试
|
命令式对象管理
kubectl命令
kubectl是kubernetes集群的命令行工具,通过它能够对集群本身进行管理,并能够在集群上进行容器化应用的安装部署。kubectl命令的语法如下:
kubectl [command] [type] [name] [flags]
- comand:指定要对资源执行的操作,例如create、get、delete
- type:指定资源类型,比如deployment、pod、service
- name:指定资源的名称,名称大小写敏感
- flags:指定额外的可选参数
# 查看所有pod
kubectl get pod
# 查看某个pod
kubectl get pod pod_name
# 查看某个pod,以yaml格式展示结果
kubectl get pod pod_name -o yaml
资源类型
kubectl api-resources
经常使用的资源有下面这些:
操作
kubernetes允许对资源进行多种操作,可以通过--help查看详细的操作命令
kubectl --help
经常使用的操作有下面这些:
下面以一个namespace / pod的创建和删除简单演示下命令的使用:
# 创建一个namespace
[root@k8s-master-1 ~]# kubectl create namespace dev
namespace/dev created
# 获取namespace
[root@k8s-master-1 ~]# kubectl get ns
NAME STATUS AGE
default Active 13d
dev Active 7s
kube-node-lease Active 13d
kube-public Active 13d
kube-system Active 13d
kubernetes-dashboard Active 9d
kuboard Active 9d
# 在此namespace下创建并运行一个nginx的Pod
[root@k8s-master-1 ~]# kubectl run pod --image=nginx -n dev
pod/pod created
# 查看新创建的pod
[root@k8s-master-1 ~]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
pod 1/1 Running 0 28s
# 删除指定的pod
[root@k8s-master-1 ~]# kubectl delete pod pod -n dev
pod "pod" deleted
# 删除指定的namespace
[root@k8s-master-1 ~]# kubectl delete ns dev
namespace "dev" deleted
命令式对象配置
[root@k8s-master-1 ~]# vim nginxpod.yaml
apiVersion: v1
kind: Namespace
metadata:
name: dev
---
apiVersion: v1
kind: Pod
metadata:
name: nginxpod
namespace: dev
spec:
containers:
- name: nginx-containers
image: nginx:latest
[root@k8s-master-1 ~]# kubectl apply -f nginxpod.yaml
namespace/dev created
pod/nginxpod created
[root@k8s-master-1 ~]#
[root@k8s-master-1 ~]# kubectl get -f nginxpod.yaml
NAME STATUS AGE
namespace/dev Active 68s
NAME READY STATUS RESTARTS AGE
pod/nginxpod 1/1 Running 0 68s
[root@k8s-master-1 ~]#
[root@k8s-master-1 ~]# kubectl delete -f nginxpod.yaml
namespace "dev" deleted
pod "nginxpod" deleted
总结 :命令式对象配置的方式操作资源,可以简单的认为:命令 + yaml 配置文件(里面是命令需要的各种参数)
声明式对象配置
声明式对象配置跟命令式对象配置很相似,但是它只有一个命令apply。
# 首先执行一次kubectl apply -f yaml文件,发现创建了资源
[root@k8s-master-1 ~]# kubectl apply -f nginxpod.yaml
namespace/dev created
pod/nginxpod created
# 再次执行一次kubectl apply -f yaml文件,发现说资源没有变动
[root@k8s-master-1 ~]# kubectl apply -f nginxpod.yaml
namespace/dev unchanged
pod/nginxpod unchanged
总结 :
- 其实声明式对象配置就是使用apply描述一个资源最终的状态(在yaml中定义状态)
- 使用apply操作资源:
- 如果资源不存在,就创建,相当于 kubectl create
- 如果资源已存在,就更新,相当于 kubectl patch
kubectl也可以在node节点上运行
scp -r HOME/.kube k8s-node-1: HOME/
创建 / 更新资源 使用声明式对象配置 kubectl apply -f XXX.yaml删除资源 使用命令式对象配置 kubectl delete -f XXX.yaml查询资源 使用命令式对象管理 kubectl get(describe) 资源名称
Namespace
Namespace 是 kubernetes 系统中的一种非常重要资源,它的主要作用是用来实现 多套环境的资源隔离 或者 多租户的资源隔离 。默认情况下, kubernetes 集群中的所有的 Pod 都是可以相互访问的。但是在实际中,可能不想让两个 Pod之间进行互相的访问,那此时就可以将两个 Pod 划分到不同的 namespace 下。 kubernetes 通过将集群内部的资源分配到不同的 Namespace 中,可以形成逻辑上的 " 组 " ,以方便不同的组的资源进行隔离使用和管理。可以通过 kubernetes 的授权机制,将不同的 namespace 交给不同租户进行管理,这样就实现了多租户的资源隔离。此时还能结合 kubernetes 的资源配额机制,限定不同租户能占用的资源,例如 CPU 使用量、内存使用量等等,来实现租户可用资源的管理。
kubernetes在集群启动之后,会默认创建几个namespace
[root@k8s-master-1 ~]# kubectl get ns #namespace的简写
NAME STATUS AGE
default Active 4d23h # 所有未指定Namespace的对象都会被分配在default命名空间
kube-node-lease Active 4d23h # 集群节点之间的心跳维护,v1.13开始引入
kube-public Active 4d23h # 此命名空间下的资源可以被所有人访问(包括未认证用户
kube-system Active 4d23h # 所有由Kubernetes系统创建的资源都处于这个命名空间
# 1 查看所有的ns 命令:kubectl get ns
[root@k8s-master-1 ~]# kubectl get ns
NAME STATUS AGE
default Active 4d23h
kube-node-lease Active 4d23h
kube-public Active 4d23h
kube-system Active 4d23h
kubernetes-dashboard Active 2d18h
kuboard Active 2d18h
[root@k8s-master-1 ~]#
# 2 查看指定的ns 命令:kubectl get ns ns名称
[root@k8s-master-1 ~]# kubectl get ns default
NAME STATUS AGE
default Active 4d23h
[root@k8s-master-1 ~]#
# 3 指定输出格式 命令:kubectl get ns ns名称 -o 格式参数
# kubernetes支持的格式有很多,比较常见的是wide、json、yaml
[root@k8s-master-1 ~]# kubectl get ns default -o yaml
apiVersion: v1
kind: Namespace
metadata:
creationTimestamp: "2024-08-17T04:45:39Z"
labels:
kubernetes.io/metadata.name: default
name: default
resourceVersion: "206"
uid: 0d20d166-4353-4fd8-8b8d-bee1b589c336
spec:
finalizers:
- kubernetes
status:
phase: Active
[root@k8s-master-1 ~]#
更多命令的使用可以查看kubectl帮助文档来看
[root@k8s-master-1 ~]# kubectl --help
Pod
Pod 是 kubernetes 集群进行管理的最小单元,程序要运行必须部署在容器中,而容器必须存在于 Pod 中。Pod 可以认为是容器的封装,一个 Pod 中可以存在一个或者多个容器。
部署nginx-pod实例
deployment部署控制器
一旦运行了 Kubernetes 集群, 就可以在其上部署容器化应用。为此,你需要创建 Kubernetes Deployment。 Deployment 指挥 Kubernetes 如何创建和更新应用的实例。 创建 Deployment 后,Kubernetes 控制平面将 Deployment 中包含的应用实例调度到集群中的各个节点上。
[root@k8s-master-1 ~]# kubectl create deployment k8s-nginx --image=nginx -r 2
deployment.apps/k8s-nginx created
[root@k8s-master-1 ~]# kubectl get deploy -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
k8s-nginx 2/2 2 2 46s nginx nginx app=k8s-nginx
[root@k8s-master-1 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
k8s-nginx-6d779d947c-5n669 1/1 Running 0 66s
k8s-nginx-6d779d947c-m8s4v 1/1 Running 0 66s
部署mysql-pod实例
[root@k8s-master-1 nfs]# mkdir /mysql
[root@k8s-master-1 nfs]# cd /mysql
[root@k8s-master-1 mysql]# ls
mysql.yaml
[root@k8s-master-1 mysql]# cat mysql.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: mysql
name: mysql
spec:
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- image: mysql:latest
name: mysql
imagePullPolicy: IfNotPresent
env:
- name: MYSQL_ROOT_PASSWORD
value: "123456" #mysql的密码
ports:
- containerPort: 3306
---
apiVersion: v1
kind: Service
metadata:
labels:
app: svc-mysql
name: svc-mysql
spec:
selector:
app: mysql
type: NodePort
ports:
- port: 3306
protocol: TCP
targetPort: 3306
nodePort: 30007
[root@k8s-master-1 mysql]# kubectl apply -f mysql.yaml
deployment.apps/mysql created
service/svc-mysql created
[root@k8s-master-1 mysql]# kubectl get pod
NAME READY STATUS RESTARTS AGE
mysql-597ff9595d-9bjsn 1/1 Running 0 18s
[root@k8s-master-1 mysql]# kubectl exec -it mysql-597ff9595d-9bjsn -- bash
bash-5.1# mysql -uroot -p123456
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 9.0.1 MySQL Community Server - GPL
Copyright (c) 2000, 2024, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.01 sec)
启动开启了HPA功能的nginx的部署控制器,启动nginx-pod
HorizontalPodAutoscaler(简称 HPA ) 自动更新工作负载资源(例如 Deployment 或者 StatefulSet), 目的是自动扩缩工作负载以满足需求。
水平扩缩意味着对增加的负载的响应是部署更多的 Pod。 这与“垂直(Vertical)”扩缩不同,对于 Kubernetes, 垂直扩缩意味着将更多资源(例如:内存或 CPU)分配给已经为工作负载运行的 Pod。
如果负载减少,并且 Pod 的数量高于配置的最小值, HorizontalPodAutoscaler 会指示工作负载资源(Deployment、StatefulSet 或其他类似资源)缩减。
[root@k8s-master-1 /]# mkdir hpa
[root@k8s-master-1 /]# cd hpa/
[root@k8s-master-1 hpa]# vim nginx-hpa.yaml
[root@k8s-master-1 hpa]# cat nginx-hpa.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: ab-nginx
spec:
selector:
matchLabels:
run: ab-nginx
template:
metadata:
labels:
run: ab-nginx
spec:
containers:
- name: ab-nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
resources:
limits:
cpu: 100m
requests:
cpu: 50m
---
apiVersion: v1
kind: Service
metadata:
name: ab-nginx-svc
labels:
run: ab-nginx-svc
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
nodePort: 31000
selector:
run: ab-nginx
---
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: ab-nginx
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: ab-nginx
minReplicas: 1
maxReplicas: 10
targetCPUUtilizationPercentage: 50
[root@k8s-master-1 hpa]#
#查看启动hpa和pod、deployment、service的情况
[root@k8s-master-1 hpa]# kubectl get pod
NAME READY STATUS RESTARTS AGE
ab-nginx-794dd6d597-jvgxk 1/1 Running 0 38m
[root@k8s-master-1 hpa]# kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
ab-nginx Deployment/ab-nginx <unknown>/50% 1 10 1 38m
[root@k8s-master-1 hpa]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ab-nginx-svc NodePort 10.108.100.140 <none> 80:31000/TCP 39m
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 130m
[root@k8s-master-1 hpa]#
访问
访问宿主机的31000端口
http://192.168.244.200:31000
测试nginx pod是否启动成功
ab工具测试
[root@ansible-nfs-prome ~]# ab -n 20000 -c 400 http://192.168.244.200:31000/index.html
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 192.168.244.200 (be patient)
Completed 2000 requests
Completed 4000 requests
Completed 6000 requests
Completed 8000 requests
Completed 10000 requests
Completed 12000 requests
Completed 14000 requests
Completed 16000 requests
Completed 18000 requests
Completed 20000 requests
Finished 20000 requests
Server Software: nginx/1.27.1
Server Hostname: 192.168.244.200
Server Port: 31000
Document Path: /index.html
Document Length: 615 bytes
Concurrency Level: 400
Time taken for tests: 34.004 seconds
Complete requests: 20000
Failed requests: 0
Write errors: 0
Total transferred: 16960000 bytes
HTML transferred: 12300000 bytes
Requests per second: 588.16 [#/sec] (mean)
Time per request: 680.086 [ms] (mean)
Time per request: 1.700 [ms] (mean, across all concurrent requests)
Transfer rate: 487.07 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 609 485.7 1002 3008
Processing: 0 61 95.0 4 1852
Waiting: 0 60 94.6 4 1852
Total: 1 670 426.2 1004 3016
Percentage of the requests served within a certain time (ms)
50% 1004
66% 1004
75% 1005
80% 1005
90% 1009
95% 1021
98% 1050
99% 1128
100% 3016 (longest request)
[root@ansible-nfs-prome ~]#
[root@k8s-master-1 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
ab-nginx-794dd6d597-447qr 1/1 Running 0 2m19s
ab-nginx-794dd6d597-cdnxv 1/1 Running 0 3m50s
ab-nginx-794dd6d597-jvgxk 1/1 Running 0 3h21m
ab-nginx-794dd6d597-rwxsp 1/1 Running 0 3m50s
ab-nginx-794dd6d597-v8zsh 1/1 Running 0 3m50s
ab-nginx-794dd6d597-x5cvf 1/1 Running 0 2m19s
[root@k8s-master-1 ~]#
使用探针对web业务pod进行监控, 一旦出现问题马上重启, 增强业务pod的可靠性。
优先级顺序: startupProbe--》readinessProbe--》livenessProbe
[root@k8s-master-1 probe]# cat my-web.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: myweb
name: myweb
spec:
replicas: 3
selector:
matchLabels:
app: myweb
template:
metadata:
labels:
app: myweb
spec:
containers:
- name: myweb
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8000
resources:
limits:
cpu: 300m
requests:
cpu: 100m
livenessProbe:
exec:
command:
- ls
- /tmp
initialDelaySeconds: 5
periodSeconds: 5
readinessProbe:
exec:
command:
- ls
- /tmp
initialDelaySeconds: 5
periodSeconds: 5
startupProbe:
httpGet:
path: /
port: 8000
failureThreshold: 30
periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
labels:
app: myweb-svc
name: myweb-svc
spec:
selector:
app: myweb
type: NodePort
ports:
- port: 8000
protocol: TCP
targetPort: 8000
nodePort: 30000
[root@k8s-master-1 probe]# [root@k8s-master-1 probe]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myweb-7df8f89d75-7drdl 0/1 Running 0 66s 10.224.109.95 k8s-node-1 <none> <none>
myweb-7df8f89d75-cbtwk 0/1 Running 0 66s 10.224.140.82 k8s-node-2 <none> <none>
myweb-7df8f89d75-jqk9l 0/1 Running 0 67s 10.224.109.96 k8s-node-1 <none> <none>
[root@k8s-master-1 probe]# kubectl describe pod myweb-7df8f89d75-7drdl
...
Liveness: exec [ls /tmp] delay=5s timeout=1s period=5s #success=1 #failure=3
Readiness: exec [ls /tmp] delay=5s timeout=1s period=5s #success=1 #failure=3
Startup: http-get http://:8000/ delay=0s timeout=1s period=10s #success=1 #failure=30
...
构建CI/CD环境, k8smaster上安装部署Jenkins,一台机器上安装部署harbor仓库。
# 前提是安装好 docker 和 docker compose
# 1.配置阿里云的repo源
yum install -y yum-utils
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 2.安装docker服务
yum install docker-ce-20.10.6 -y
# 启动docker,设置开机自启
systemctl start docker && systemctl enable docker.service
# 3.查看docker版本,docker compose版本
[root@k8s-node-1 ~]# docker version
[root@k8s-node-1 ~]# docker compose version
# 5.安装 harbor,到 harbor 官网或者 github 下载harbor源码包,上传到本地。
wget https://github.com/goharbor/harbor/releases/download/v2.8.3/harbor-offline-installer-v2.8.3.tgz
[root@k8s-node-1 ~]# ls
anaconda-ks.cfg harbor-offline-installer-v2.8.3.tgz
# 6.解压
[root@k8s-node-1 ~]# tar xf harbor-offline-installer-v2.8.3.tgz
[root@k8s-node-1 ~]# ls
harbor harbor-offline-installer-v2.8.3.tgz
[root@k8s-node-1 ~]# cd harbor/
[root@k8s-node-1 harbor]# ls
common common.sh docker-compose.yml harbor.v2.8.3.tar.gz harbor.yml install.sh LICENSE prepare
[root@k8s-node-1 harbor]#
[root@k8s-node-1 harbor]# mv harbor.yml.tmpl harbor.yml
[root@k8s-node-1 harbor]# vim harbor.yml
# 7.修改配置文件
[root@harbor harbor]# vim harbor.yml.tmpl
# Configuration file of Harbor
# The IP address or hostname to access admin UI and registry service.
# DO NOT use localhost or 127.0.0.1, because Harbor needs to be accessed by external clients.
hostname: 192.168.244.202 #修改为主机ip地址
# http related config
http:
# port for http, default is 80. If https enabled, this port will redirect to https port
port: 20001 #可以进行修改端口
# https related config
#https: #记得注释掉,没有用到https
# https port for harbor, default is 443
# port: 443
# The path of cert and key files for nginx
#certificate: /your/certificate/path
#private_key: /your/private/key/path
# # Uncomment following will enable tls communication between all harbor components
# internal_tls:
# # set enabled to true means internal tls is enabled
# enabled: true
# # put your cert and key files on dir
# dir: /etc/harbor/tls/internal
# Uncomment external_url if you want to enable external proxy
# And when it enabled the hostname will no longer used
# external_url: https://reg.mydomain.com:8433
# The initial password of Harbor admin
# It only works in first time to install harbor
# Remember Change the admin password from UI after launching Harbor.
harbor_admin_password: Harbor12345 #登录密码
# Uncomment external_url if you want to enable external proxy
# And when it enabled the hostname will no longer used
# external_url: https://reg.mydomain.com:8433
# The initial password of Harbor admin
# It only works in first time to install harbor
# Remember Change the admin password from UI after launching Harbor.
harbor_admin_password: Harbor12345 #登录密码,可以修改
# Harbor DB configuration
database:
# The password for the root user of Harbor DB. Change this before any production use.
password: root123 #这是 Harbor 数据库的 root 用户的密码
# The maximum number of connections in the idle connection pool. If it <=0, no idle connections are retained.
max_idle_conns: 100 #这是空闲连接池中的最大连接数。
# The maximum number of open connections to the database. If it <= 0, then there is no limit on the number of open connections.
# Note: the default number of connections is 1024 for postgres of harbor.
max_open_conns: 900 #这是到数据库的最大打开连接数。
测试登录
http://192.168.244.202:20001/
- # 账号:admin
- # 密码:Harbor12345
- 登录后:
- 在harbor里创建一个项目k8s-harbor
- 并且新建一个用户 ross 密码是Ross1234
- 授权k8s-harbor这个项目允许guan这个用户去访问,授予项目管理员权限
[root@k8s-master-1 ~]# vim /etc/docker/daemon.json
[root@k8s-master-1 ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://hub.docker-alhk.dkdun.com/"],
"exec-opts": ["native.cgroupdriver=systemd"],
"insecure-registries" : ["192.168.244.202:20001"]
}
#然后重启docker
[root@k8s-master-1 ~]# systemctl daemon-reload
[root@k8s-master-1 ~]# systemctl restart docker
[root@k8s-master-1 ~]# journalctl -xe
在原来安装harbor的宿主机上,重新启动harbor相关的容器
[root@k8s-node-1 ~]# cd harbor
[root@k8s-node-1 harbor]# docker compose up -d
pod集群机器上拉取一个镜像或者dockerfile制作一个镜像,修改镜像的名字
[root@k8s-master-1 ~]# docker tag nginx:latest 192.168.244.202:20001/k8s-harbor/nginx:latest
本机上传
首先登陆私有仓库
登录使用ross这个用户,密码是Ross1234
[root@k8s-master-1 ~]# docker login 192.168.244.202:20001
Username: ross
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
上传到仓库
[root@k8s-master-1 ~]# docker push 192.168.244.202:20001/k8s-harbor/nginx:latest
上传成功
持续集成CI-持续交付-CD
Jenkins中文网站教程概览 (jenkins.io)
Jenkins是开源CI&CD软件领导者, 提供超过1000个插件来支持构建、部署、自动化, 满足任何项目的需要。
CICD解决方案的好处
- 快速部署
- 减少人为失误
- 节约成本,减少人力资源