当前位置: 首页 > news >正文

Kubernetes基础使用

Kubernetes是一个开源的容器编排引擎,可以用来管理容器化的应用,包括容器的自动化的部署、扩容、缩容、升级、回滚等等,它是Google在2014年开源的一个项目,它的前身是Google内部的Borg系统。

在Kubernetes出现之前, 我们一般都是使用Docker来管理容器化的应用, 但是Docker只是一个单机的容器管理工具, 它只能管理单个节点上的容器, 当我们的应用程序需要运行在多个节点上的时候, 就需要使用一些其他的工具来管理这些节点, 比如Docker Swarm、Mesos、Kubernetes等等, 这些工具都是容器编排引擎, 它们可以用来管理多个节点上的容器, 但是它们之间也有一些区别, 比如Docker Swarm是Docker官方提供的一个容器编排引擎, 它的功能比较简单, 适合于一些小型的、简单的场景, 而Mesos和Kubernetes则是比较复杂的容器编排引擎, Mesos是Apache基金会的一个开源项目, 而Kubernetes是Google在2014年开源的, 目前已经成为了CNCF(Cloud Native Computing Foundation)的一个顶级项目, 基本上已经成为了容器编排引擎的事实标准了。

1.Kubernetes核心组件

1.1 Node:

Node:节点,一个物理机或者一台虚拟机。

1.2 Pod:

Pod 是 Kubernetes 的最小调度单元,可以理解为容器的抽象。一个Node中运行多个Pod,一个 Pod 就是一个或者多个应用容器的组合。它创建了一个容器的运行环境,在这个环境中容器可以共享一些资源,比如网络、存储和运行时的一些配置等等。

假设我们系统包括一个应用程序和一个数据库,就可以将应用程序和数据库分别放到两个不同的 Pod 中,一般情况下一个 Pod 中只运行一个容器,这样可以更好地实现应用程序的解耦和扩展。

一个 Pod 中也是可以运行多个容器的,一般仅限于这些容器是高度耦合的情况,它们之间为了共享一些配置或者资源,不得不将它们放到一个容器。

应用程序要访问数据库的话,只需要知道数据库的 IP 地址,这里的 IP 地址是 Pod 在创建的时候自动创建的,是一个集群内部的 IP 地址(也就是无法从集群外部访问),Pod 之间通过这些 IP 地址进行通信。

Pod IP 不稳定问题:

Pod 并不是稳定的实体,它们非常容易被创建或者销毁,比如发生故障的时候,Kubernetes会自动将发生故障的 Pod 销毁掉然后创建一个新的 Pod 替代它,这时候 IP 也会重新分配,如果应用程序还用原来的 IP 来访问的话就找不到。

1.3 Service

为了解决Pod IP 不稳定问题,Kubernetes 提供了一个名为 Service 的资源对象,它可以将一组 Pod 封装成一个服务,这个服务通过一个统一的入口来访问。

就比如上面的场景,我们分别将应用程序和数据库两组 Pod 封装成两个 Service,这样应用程序就可以通过 Service 的 IP 地址访问数据库(有点像路由器和反向代理),即使 Pod 的 IP 地址发生了变化,Service 的 IP 地址也不会发生变化,Service 会自动将请求转发到其它健康的 Pod 上。

正向代理:代理的是 C 端(客户端),S 端不知道 C 端的 IP。C 端发送请求给代理服务器,再由代理服务器向 S 端(服务端)发送请求,S 端就会将数据响应给代理服务器,再由代理服务器将数据传输给 C 端。(科学上网使用的就是正向代理)

反向代理:代理的是 S 端,C 端不知道 S 端的 IP。S 端可能有多台服务器,C 端向代理服务器发送请求,代理服务器向 S 端的其中一台服务器发送请求,服务器将数据响应给代理服务器,再由代理服务器将数据传输给 C 端。(比如 Nginx 的负载均衡)

使用代理模式的好处:

  1. 隐藏真实 IP,隐私
  2. 在代理服务器上设置缓存可以加快访问
  3. 突破网络限制,有些网站会限制某些地区的 IP 访问,使用化茧成蝶可以突破限制。(还是科学上网)

坏处:

  1. C 端和 S 端的 IP 对彼此隐藏了,但会将 IP 暴露给代理服务器
  2. 网络链路多了代理服务器的节点,降低访问速度

内部服务和外部服务:

内部服务:不能暴露或者不需要暴露给外部的服务,比如数据库、缓存、消息队列等,这些服务只需要在集群内部访问就可以了。

外部服务:后端的 API 接口或者前端界面等等,这些就是需要暴露给用户的服务。

外部服务常见的类型有 ExternalName、LoadBalancer、NodePort、ClusterIP,其中 NodePort 是我们常用的类型,它会在节点上开放一个端口,然后将这个端口映射到 Service 的 IP 地址和端口上,这样就可以通过节点的 IP 地址和端口来访问 Service 了。是不是感觉有点熟悉?http://localhost:8080,想起来了吗?

在开发和测试阶段使用 IP 和端口号的方式是没有问题的,但在生产环境中通常是用域名来访问服务的,这时就用到了另一个资源对象 Ingress。

1.4 Ingress

Ingress 是用于管理从集群外部访问集群内部服务的入口和方式,可以通过 Ingress 配置不同的转发规则,从而根据不同的规则来访问不同的 Service 以及 Service 所对应的 Pod。还可以通过 Ingress 来配置域名,这样就可以从集群外部使用域名和访问 Service。

Ingress 也可以用来配置 SSL 证书或者负载均衡。

1.5 ConfigMap

原来我们的应用程序需要访问数据库的话,一般的做法是将数据库的地址和端口等连接信息写到配置文件或者环境变量中,然后在应用程序中读取这些配置信息,这样配置信息就和应用程序耦合在一起了,当数据库的地址或者端口发生变化,我们就得修改应用程序的配置信息然后重新编译部署,这样不仅麻烦,而且对于一些需要不间断运行的服务来说是不能接受的(比如你深夜肚子饿了想点外卖而服务器却在重新编译部署)。

为了解决这个问题,Kubernetes 提供了一个 ConfigMap 组件,它可以将配置信息封装起来,然后就可以在应用程序中读取和使用。将配置信息和应用程序的镜像内容分离开,当数据库的地址和端口发生变化的时候,只需要修改 ConfigMap对象中的配置信息,然后重新加载 Pod,不需要重新编译和部署应用程序。

可以理解为给数据库加了个反向代理

1.6 Secret

但 ConfigMap 有个问题,就是它的配置信息是明文的,如果用户名和密码存在 ConfigMap 中是有风险的,于是 Kubernetes 提供了 Secret 组件,用于封装敏感信息,会将配置信息 Base64 编码,但 Base64 编码很容易解码,浏览器随便搜个解码器就能得到原文,所以还需要配合其它手段来确保安全性。

1.7 Volume

Pod 被销毁或重启时数据也跟着消失,这对于需要持久化存储的应用程序比如数据库肯定是不行的,Kubernetes 提供了 Volume 组件,它可以将一些持久化存储的资源挂载到集群中的本地磁盘上,或者挂载到集群外部的远程存储上(比如 OSS)。

1.8 Deployment

如果服务端只有一个节点的话,这个节点发生故障就会导致服务宕机(即单点故障),无法实现高可用性。这个好解决,既然一个不够,那就多复制几个,当一个节点发生故障的时候,Service 就会自动将请求转发到另一个节点。(这里的 Service 指的是上面的 Service 组件)

Deployment 就是用来定义和管理应用程序的副本数量以及应用程序的更新策略,将一个或者多个 Pod 组合在一起,简化应用程序的部署和更新操作,还可以副本控制、滚动更新、自动扩缩容等。

副本控制:定义和管理应用程序的副本数量,比如定义一个应用程序副本数量为 3,当其中一个发生故障时,就会生成一个新的副本来替换坏副本,始终保持有 3 个副本在集群中运行。

滚动更新:定义和管理应用程序的更新策略,使用新版本替换旧版本,确保应用程序的平滑升级。

平滑升级:不对用户的使用造成中断或不便的升级

1.9 StatefulSet

除了应用程序,数据库也有故障、升级和更新维护的时候,数据库停了服务也停了,所以数据库也需要采取多副本的方式来保证高可用性,但一般不使用 Deployment 来实现数据库的多副本,因为数据库的多副本之间是有状态的,就是每个副本的数据存在差异(状态不同),需要确保数据的一致性,可以把数据写到一个共享的存储中或者同步不同副本之间的数据。

对于这一类有状态的应用程序,Kubernetes 提供了 StatefulSet 组件来管理,StatefulSet 跟 Deployment 非常类似,也提供了定义和管理应用程序副本数量和动态扩缩容等功能,此外它还保证了每个副本都有自己稳定的网络标识符和持久化存储,数据库、缓存、消息队列等这些有状态的应用以及保留了会话状态的应用一般都需要使用 StatefulSet 而不是 Deployment。

但 StatefulSet 部署的过程比较复杂和繁琐,而且并不是所有的有状态应用都适合用 StatefulSet 来部署,比如Redis,当 Redis 实例需要使用内存进行数据存储,并且数据存储在实例的内存中而不是持久性存储中时,如果这时候实例重启,Redis 数据丢失,这时候 StatefulSet 就无法保证数据的持久性(还是有点不理解)。更加通用和简单的方式是把有状态的应用程序从 Kubernetes 中剥离出来,在集群外单独部署。(ToLearn:集群外单独部署有状态应用的方法)

2. Kubernetes 架构

Kubernetes 是典型的 Master-Worker 架构, Master Node 负责管理整个集群,Worker Node 负责运行应用程序和服务。

官方定义:Kubernetes 通过将容器放入在节点上运行的 Pod 中来执行工作负载。

2.1 Worker Node

下面这个 Node 就运行了两个 Pod,这里的 Node 就是集群中实际完成工作的节点,也就是 Worker-Node。

为了对外提供服务,每个 Node 上都会包含三个组件,kubelet、kube-proxy 和 container runtime。

container runtime:

翻译为“运行环境”,可以理解为一个运行容器的实例,负责拉取容器镜像、创建容器、启动或者停止容器等等,所有的容器都需要通过 container runtime 来运行,所以每个节点上都需要安装 container runtime。

kubelet:

负责管理和维护每个节点上的 Pod 并确保它们按照预期运行,它也会定期从 apiserver 组件接收新的或者修改后的 Pod 规范,同时会监控工作节点的运行情况,然后将信息汇报给 apiserver。

kube-proxy:

负责为 Pod 对象提供网络代理和负载均衡服务。

一般 Kubernetes 集群包含多个节点,节点之间通过 Service 通信,这就需要一个负载均衡器来接收请求,然后再将请求发送到不同节点上。kube-proxy 就是负责这个功能的组件,它在每个 Node 上启动一个网络代理,使发往 Service 的流量路由到正确的后端 Pod,比如 Node A 的应用程序要访问数据库,应用程序对数据库的访问请求并不会被随机路由到别的节点的数据库中,kube-proxy 会把请求路由到与应用程序同一个节点(也就是 Node A)的数据库 Pod 中。

2.2 Master Node

kube-apiserver

负责提供 Kubernetes 集群的 API 接口服务,所有的组件通过 apiserver 通信,用户在集群中部署应用时也需要使用客户端与 apiserver 进行交互。apiserver 就像一个集群的网关,是整个系统的入口,所有的请求都会先经过它,再由它分发给不同的组件进行处理。

除了提供 API 接口之外,apiserver 还负责对所有对象的增删改查等操作进行认证、授权和访问控制。apiserver 接收到请求时会先验证请求的合法性,验证通过之后才会将请求转发给 Scheduler 处理。

Scheduler 调度器

负责监控集群中所有节点的资源使用情况,然后根据调度策略将 Pod 调度到合适的节点上运行。

调度策略:比如新增一个新 Pod 时,将 Pod 调度到空闲资源最多的节点上

Controller Manager 控制器管理器

负责管理集群中各种资源对象(比如 Node、Pod、Service)的状态,然后根据状态做出相应的响应。比如集群中有一个节点发生故障时,得有一个机制来监控和检测这个故障然后处理故障,比如重启 Pod 或者使用新 Pod 替代,这就是 Controller Manager 要做的事。

etcd

高可用键-值存储系统,类似 Redis,用于存储集群中所有资源对象的状态信息,每新增或者崩掉一个 Pod,这些信息都会被记录到 etcd 中,使用命令行查询集群状态时就是通过 etcd 来获取的。

etcd 一般只存储集群中应用程序的状态信息,不存储应用程序的数据

Cloud Controller Manager

一个云平台相关的控制器,负责与云平台(例如 Google GKE、Microsoft AKS、Amazon EKS)的 API 进行交互,并且对不同平台都提供一致的管理接口。

3. K8S环境搭建

3.1 minikube 搭建环境

minikube是一个轻量级的kubernetes集群环境, 可以用来在本地快速搭建一个单节点的kubernetes集群。

kubectl 是一个命令行工具,可以通过在命令行输入各种命令与 Master Node 的 apiserver 交互,从而与 Kubernetes 集群进行交互。

  1. 命令行输入choco install minikube安装 minikube
  2. minikube version查看版本信息验证是否安装成功

安装minikube:

# macOS
brew install minikube# Windows
choco install minikube# Linux
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube

也可以到官网直接下载安装包来安装:https://minikube.sigs.k8s.io/docs/start/

启动minikube:

# 启动minikube
minikube start

下面这条命令先不加参数,直接启动如果很慢的话,试试指定镜像源为 cn,还是慢的话加上后面的版本参数,初步学习就不用追求最新版了。

minikube start --image-mirror-country='cn' --kubernetes-version=v1.23.9

成功 start 之后就可以sudo kubectl get nodes查看集群中的节点信息了。

3.2 Multipass和K3S搭建K8S集群环境

minikube只能用来在本地搭建一个单节点的kubernetes集群环境, 下面介绍如何使用Multipass和k3s来搭建一个多节点的kubernetes集群环境。

3.2.1 Multipass介绍

Multipass是一个轻量级的虚拟机管理工具, 可以用来在本地快速创建和管理虚拟机, 相比于VirtualBox或者VMware这样的虚拟机管理工具, Multipass更加轻量快速, 而且它还提供了一些命令行工具来方便我们管理虚拟机。 官方网址: https://Multipass.run/

3.2.2 安装Multipass

# macOS
brew install multipass# Windows
choco install multipass# Linux
sudo snap install multipass

3.2.3 Multipass常用命令

关于Multipass的一些常用命令我们可以通过multipass help来查看

# 查看帮助
multipass help
multipass help <command># 创建一个名字叫做k3s的虚拟机
multipass launch --name k3s# 在虚拟机中执行命令
multipass exec k3s -- ls -l# 进入虚拟机并执行shell
multipass shell k3s# 查看虚拟机的信息
multipass info k3s# 停止虚拟机
multipass stop k3s# 启动虚拟机
multipass start k3s# 删除虚拟机
multipass delete k3s# 清理虚拟机
multipass purge# 查看虚拟机列表
multipass list# 挂载目录(将本地的~/kubernetes/master目录挂载到虚拟机中的~/master目录)

3.2.4 K3S介绍

k3s 是一个轻量级的Kubernetes发行版,它是 Rancher Labs 推出的一个开源项目, 旨在简化Kubernetes的安装和维护,同时它还是CNCF认证的Kubernetes发行版。

3.2.5 创建和配置master节点

首先我们需要使用multipass创建一个名字叫做k3s的虚拟机,

multipass launch --name k3s --cpus 2 --memory 8G --disk 10G

虚拟机创建完成之后, 可以配置SSH密钥登录, 不过这一步并不是必须的, 即使不配置也可以通过multipass exec或者multipass shell命令来进入虚拟机, 然后我们需要在master节点上安装k3s,使用k3s搭建kubernetes集群非常简单, 只需要执行一条命令就可以在当前节点上安装k3s, 打开刚刚创建的k3s虚拟机, 执行下面的命令就可以安装一个k3s的master节点,

# 安装k3s的master节点
curl -sfL https://get.k3s.io | sh -

国内用户可以换成下面的命令,使用ranher的镜像源来安装:

curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn sh -

安装完成之后,可以通过kubectl命令来查看集群的状态

sudo kubectl get nodes

3.2.6 创建和配置worker节点

接下来需要在这个master节点上获取一个token, 用来作为创建worker节点时的一个认证凭证, 它保存在/var/lib/rancher/k3s/server/node-token这个文件里面, 我们可以使用sudo cat命令来查看一下这个文件中的内容,

sudo cat /var/lib/rancher/k3s/server/node-token

将TOKEN保存到一个环境变量中

TOKEN=$(multipass exec k3s sudo cat /var/lib/rancher/k3s/server/node-token)

保存master节点的IP地址

MASTER_IP=$(multipass info k3s | grep IPv4 | awk '{print $2}')

确认:

echo $MASTER_IP

使用刚刚的TOKENMASTER_IP来创建两个worker节点 并把它们加入到集群中

# 创建两个worker节点的虚拟机
multipass launch --name worker1 --cpus 2 --memory 8G --disk 10G
multipass launch --name worker2 --cpus 2 --memory 8G --disk 10G
​
# 在worker节点虚拟机上安装k3sfor f in 1 2; domultipass exec worker$f -- bash -c "curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn K3S_URL=\"https://$MASTER_IP:6443\" K3S_TOKEN=\"$TOKEN\" sh -"done

这样就完成了一个多节点的kubernetes集群的搭建。

3.3 在线实验环境

Killercoda

Play-With-K8s

4.Kubectl常用命令

基础使用:

# 查看帮助
kubectl --help# 查看API版本
kubectl api-versions# 查看集群信息
kubectl cluster-info

资源创建和运行:

# 创建并运行一个指定的镜像
kubectl run NAME --image=image [params...]
# e.g. 创建并运行一个名字为nginx的Pod
kubectl run nginx --image=nginx# 根据YAML配置文件或者标准输入创建资源
kubectl create RESOURCE
# e.g.
# 根据nginx.yaml配置文件创建资源
kubectl create -f nginx.yaml
# 根据URL创建资源
kubectl create -f https://k8s.io/examples/application/deployment.yaml
# 根据目录下的所有配置文件创建资源
kubectl create -f ./dir# 通过文件名或标准输入配置资源
kubectl apply -f (-k DIRECTORY | -f FILENAME | stdin)
# e.g.
# 根据nginx.yaml配置文件创建资源
kubectl apply -f nginx.yaml

查看资源信息:

# 查看集群中某一类型的资源
kubectl get RESOURCE
# 其中,RESOURCE可以是以下类型:
kubectl get pods / po         # 查看Pod
kubectl get svc               # 查看Service
kubectl get deploy            # 查看Deployment
kubectl get rs                # 查看ReplicaSet
kubectl get cm                # 查看ConfigMap
kubectl get secret            # 查看Secret
kubectl get ing               # 查看Ingress
kubectl get pv                # 查看PersistentVolume
kubectl get pvc               # 查看PersistentVolumeClaim
kubectl get ns                # 查看Namespace
kubectl get node              # 查看Node
kubectl get all               # 查看所有资源# 后面还可以加上 -o wide 参数来查看更多信息
kubectl get pods -o wide# 查看某一类型资源的详细信息
kubectl describe RESOURCE NAME
# e.g. 查看名字为nginx的Pod的详细信息
kubectl describe pod nginx

资源的修改,删除,清理:

# 更新某个资源的标签
kubectl label RESOURCE NAME KEY_1=VALUE_1 ... KEY_N=VALUE_N
# e.g. 更新名字为nginx的Pod的标签
kubectl label pod nginx app=nginx# 删除某个资源
kubectl delete RESOURCE NAME
# e.g. 删除名字为nginx的Pod
kubectl delete pod nginx# 删除某个资源的所有实例
kubectl delete RESOURCE --all
# e.g. 删除所有Pod
kubectl delete pod --all# 根据YAML配置文件删除资源
kubectl delete -f FILENAME
# e.g. 根据nginx.yaml配置文件删除资源
kubectl delete -f nginx.yaml# 设置某个资源的副本数
kubectl scale --replicas=COUNT RESOURCE NAME
# e.g. 设置名字为nginx的Deployment的副本数为3
kubectl scale --replicas=3 deployment/nginx# 根据配置文件或者标准输入替换某个资源
kubectl replace -f FILENAME
# e.g. 根据nginx.yaml配置文件替换名字为nginx的Deployment
kubectl replace -f nginx.yaml

调试和交互:
 

# 进入某个Pod的容器中
kubectl exec [-it] POD [-c CONTAINER] -- COMMAND [args...]
# e.g. 进入名字为nginx的Pod的容器中,并执行/bin/bash命令
kubectl exec -it nginx -- /bin/bash# 查看某个Pod的日志
kubectl logs [-f] [-p] [-c CONTAINER] POD [-n NAMESPACE]
# e.g. 查看名字为nginx的Pod的日志
kubectl logs nginx# 将某个Pod的端口转发到本地
kubectl port-forward POD [LOCAL_PORT:]REMOTE_PORT [...[LOCAL_PORT_N:]REMOTE_PORT_N]
# e.g. 将名字为nginx的Pod的80端口转发到本地的8080端口
kubectl port-forward nginx 8080:80# 连接到现有的某个Pod(将某个Pod的标准输入输出转发到本地)
kubectl attach POD -c CONTAINER
# e.g. 将名字为nginx的Pod的标准输入输出转发到本地
kubectl attach nginx# 运行某个Pod的命令
kubectl run NAME --image=image -- COMMAND [args...]
# e.g. 运行名字为nginx的Pod
kubectl run nginx --image=nginx -- /bin/bash

配置文件使用:

我们创建资源对象时可以通过指定各种参数来配置生成的资源对象的状态,比如kubectl create deployment nginx-dep --image=nginx --replicaset=3,这尊就指定了镜像是 nginx,副本数量是 3,但只在命令行中声明不方便我们日后查看,所以写到配置文件中更实用。

  • 通过配置文件创建资源对象

先创建一个 yaml 文件:

 vi nginx-deployment.yaml
apiVersion: apps/v1  # 定义使用的API版本,这里是apps/v1,表示使用应用的v1版本API。
kind: Deployment  # 定义资源类型为Deployment,表示部署一个应用。
metadata:  # 元数据部分,用于描述Deployment的基本信息。name: nginx-deployment  # Deployment的名称为nginx-deployment。
spec:  # 规格部分,定义Deployment的规格。selector:  # 选择器部分,用于选择要管理的Pod。matchLabels:  # 匹配标签部分。app: nginx  # 匹配标签为app=nginx的Pod。replicas: 3  # 指定副本数为3,意味着会运行3个相同的Pod实例。template:  # 模板部分,定义创建新Pod时使用的模板。metadata:  # 模板的元数据部分。labels:  # 标签部分,为新创建的Pod定义标签。app: nginx  # 新创建的Pod的标签为app=nginx。spec:  # 新创建的Pod的规格。containers:  # 容器列表,定义在Pod中运行的容器。- name: nginx  # 容器的名称为nginx。image: nginx:1.25  # 使用的容器镜像是nginx:1.25。ports:  # 容器的端口配置。- containerPort: 80  # 容器监听的端口号为80。

然后根据配置文件创建一个 Deployment

sudo kubectl create -f nginx-deployment.yaml
ubuntu@k3s:~$ sudo kubectl create -f nginx-deployment.yaml
deployment.apps/nginx-deployment created

创建完查看一下效果,可以看到多出一个 Deployment 且副本数量为 3

也可以加上-o wide参数查看每个 Pod 的 IP

上面的 IP 是集群内部的 IP,无法从集群外部访问

也可以通过配置文件删除资源对象sudo kubectl delete -f nginx-deployment.yaml,通过这个文件创建的所有资源对象都会被删除。

  • 根据配置文件应用资源对象
sudo kubectl apply -f nginx-deployment.yaml

如果该文件对应的资源对象还没创建,则创建并启用资源对象,如果已经存在则更新后启用。

试试把上面的配置文件副本数量改为 2,然后再查看变化。

这就量使用配置文件来管理 Pod 的优势所在,遇到流量高峰的时候,修改一下副本数量就可以快速扩容,高峰过后也可以主很方便地释放资源。

甚至可以通过配置实现自动扩缩容,原理就是定时检查资源对象的状态,比较状态和配置是否一致,如果不一致就自动修改资源的状态,使其和配置保持一致

create 和 apply 的区别:类比创建虚拟机,create 只是创建但没有启用资源对象,apply 会创建/更新资源对象后启用。

使用 Service 提供外部服务:

Pod 使用的是一个集群内部的 IP 地址,如果用 Pod 来运行 nginx 是无法从集群外部访问到页面的。比如上面创建的 Pod,在 Master 节点上执行curl ip就可以访问到 nginx 页面。

exit 退出到 PowerShell 后就无法访问了。

另一个问题就是 Pod 并不是一个稳定的实体,经常会被创建或销毁,这里它的 IP 地址也会发生变化。

解决方案就是使用 Service 来提供外部服务

  • 创建一个 Service
    sudo kubectl service nginx-service
  • 也可以直接将已存在的 Deployment 对外公开为一个服务
    sudo kubectl expose deployment nginx-deployment

  • 查看资源详细信息
    sudo kubectl describe [资源类型] [资源名称]

  • 通过配置文件创建 Service

新建一个配置文件 nginx-service.yaml

apiVersion: v1  # 使用的Kubernetes API版本,这里是v1。
kind: Service  # 定义资源类型为Service,表示创建一个服务。
metadata:  # 元数据部分,用于描述Service的基本信息。name: nginx-service  # Service的名称为nginx-service。
spec:  # 规格部分,定义Service的规格。selector:  # 选择器部分,用于指定服务应该选择哪些Pod作为后端。app: nginx  # 选择具有标签app=nginx的Pod作为后端。ports:  # 端口配置,定义Service暴露的端口。- protocol: TCP  # 使用TCP协议。port: 80  # Service暴露的端口号为80。targetPort: 80  # 转发到后端Pod的端口号也为80。

这里需要先了解一下选择器 selector 的作用:选择特定的资源,一般和 label 标签一起使用,类似 CSS 的选择器,我们前面在创建 Deployment 时已经给 Deployment 绑定了一个选择器,回头看看配置文件里的 matchLabels,也可以sudo kubectl describe deployment nginx-deployment看一下 Deployment 信息,可以看到 Deployment 信息下有个 Selector

然后再看看 Pod 信息,创建的三个 Pod 都有 Labels 标签

总结一下就是,在 Deployment 声明一个选择器,在 Pod 里贴上一个标签,选择器与标签匹配的 Deployment 就可以管理 Pod。

保存配置文件后应用一下这个文件

sudo kubectl apply -f nginx-service.yaml

但是这个服务还是一个集群内部的服务,无法从集群外部访问,这时我们就得用到 NodePort 类型的服务。

NodePort 可以将服务公开到集群的节点上,然后我们通过 IP 和端口就可以访问到服务了。

我们创建 Service 时没有指定服务的类型,那这个 Service 默认就是一个 ClusterIP 类型的服务,也就是集群内部的服务,现在我们来将 Service 的服务类型改为 NodePort,只要在配置文件里加上 type 和 nodePort 就好了。注意端口的范围在 30000~32767 之间(这个范围是由 Kubernetes 团队选择的,因为它们通常不会被其他应用或服务占用)

apiVersion: v1  # 使用的Kubernetes API版本,这里是v1。
kind: Service  # 定义资源类型为Service,表示创建一个服务。
metadata:  # 元数据部分,用于描述Service的基本信息。name: nginx-service  # Service的名称为nginx-service。
spec:  # 规格部分,定义Service的规格。type: NodePort	# 指定服务类型selector:  # 选择器部分,用于指定服务应该选择哪些Pod作为后端。app: nginx  # 选择具有标签app=nginx的Pod作为后端。ports:  # 端口配置,定义Service暴露的端口。- protocol: TCP  # 使用TCP协议。port: 80  # Service暴露的端口号为80。targetPort: 80  # 转发到后端Pod的端口号也为80。nodePort: 30080

保存后 apply 一下,sudo kubectl apply -f nginx-service.yaml

然后查看 Service 信息,可以看到服务类型变成了 NodePort,且端口号为 30080

查看一下 IP 地址sudo kubectl get nodes -o wide

然后打开浏览器,输入 nodeIP:port,可以访问了!

关于 Service 的类型还有其它各类和应用,LoadBalcancer、ExternalName、Headless。

5.K8S可视化管理

Portainer

Portainer 是一个轻量级的容器管理工具, 可以用来管理Docker和Kubernetes, 它提供了一个Web界面来方便我们管理容器, 官方网址: https://www.portainer.io/

安装步骤:

# 创建一个名字叫做portainer的虚拟机
multipass launch --name portainer --cpus 2 --memory 8G --disk 10G

当然也可以直接安装在我们刚刚创建的master节点上

# 在master节点上安装portainer,并将其暴露在NodePort 30777上
kubectl apply -n portainer -f https://downloads.portainer.io/ce2-19/portainer.yaml
或者使用Helm安装
# 使用Helm安装Portainer
helm upgrade --install --create-namespace -n portainer portainer portainer/portainer --set tls.force=true

然后直接访问 `https://localhost:30779/` 或者 `http://localhost:30777/` 就可以了

Helm

Helm 是一个Kubernetes的包管理工具, 可以用来管理Kubernetes的应用, 它提供了一个命令行工具来方便我们管理Kubernetes的应用, 官方网址: https://helm.sh/

使用包管理器安装:

# macOS
brew install helm# Windows
choco install kubernetes-helm
# 或者
scoop install helm# Linux(Debian/Ubuntu)
curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null
sudo apt-get install apt-transport-https --yes
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
sudo apt-get update
sudo apt-get install helm# Linux(CentOS/Fedora)
sudo dnf install helm# Linux(Snap)
sudo snap install helm --classic# Linux(FreeBSD)
pkg install helm

使用脚本安装

$ curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
$ chmod 700 get_helm.sh
$ ./get_helm.sh

或者

curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash


文章转载自:

http://VulAHBO1.rqrxh.cn
http://b56MNy6R.rqrxh.cn
http://bFaEGoBy.rqrxh.cn
http://tmT1vS8h.rqrxh.cn
http://QdWAJyqx.rqrxh.cn
http://Krz6S2uI.rqrxh.cn
http://1LFvOPl5.rqrxh.cn
http://Spg2yVwY.rqrxh.cn
http://3NKVeQm4.rqrxh.cn
http://3DebyVVf.rqrxh.cn
http://zYtrvotC.rqrxh.cn
http://9tVeZOuh.rqrxh.cn
http://g86gYgYP.rqrxh.cn
http://NbBm94ml.rqrxh.cn
http://CBYWE7Nd.rqrxh.cn
http://dikwk6vl.rqrxh.cn
http://n7KhDyUQ.rqrxh.cn
http://MYnJVB0G.rqrxh.cn
http://ivT3WbXo.rqrxh.cn
http://kuASpZDl.rqrxh.cn
http://wPU9U1vv.rqrxh.cn
http://4RIUAdXJ.rqrxh.cn
http://IVPYh2Wt.rqrxh.cn
http://l3WhdzNT.rqrxh.cn
http://IS2HjDzC.rqrxh.cn
http://jfqQuRJS.rqrxh.cn
http://oWhLJBri.rqrxh.cn
http://glDhwTK1.rqrxh.cn
http://tzG0Idgi.rqrxh.cn
http://zSz9qHtU.rqrxh.cn
http://www.dtcms.com/a/383820.html

相关文章:

  • 归并排序递归与非递归实现
  • 第9课:工作流编排与任务调度
  • 淘客app的接口性能测试:基于JMeter的高并发场景模拟与优化
  • C++ 继承:从概念到实战的全方位指南
  • Python中全局Import和局部Import的区别及应用场景对比
  • S16 赛季预告
  • 【硬件-笔试面试题-95】硬件/电子工程师,笔试面试题(知识点:RC电路中的时间常数)
  • synchronized锁升级的过程(从无锁到偏向锁,再到轻量级锁,最后到重量级锁的一个过程)
  • Altium Designer(AD)自定义PCB外观颜色
  • Flink快速上手使用
  • 安卓学习 之 选项菜单(OptionMenu)
  • CKA04--storageclass
  • Dask read_csv未指定数据类型报错
  • 【代码随想录算法训练营——Day11】栈与队列——150.逆波兰表达式求值、239.滑动窗口最大值、347.前K个高频元素
  • TruthfulQA:衡量语言模型真实性的基准
  • 继承与多态
  • Python爬虫实战:研究Pandas,构建新浪网股票数据采集和分析系统
  • 【从零开始】14. 数据评分与筛选
  • 正则表达式与文本三剑客(grep、sed、awk)基础与实践
  • JavaWeb--day5--请求响应分层解耦
  • 去卷积:用魔法打败魔法,让图像清晰
  • Java开发者LLM实战——LangChain4j最新版教学知识库实战
  • 算法 --- 哈希表
  • 【科研绘图系列】R语言绘制全球海洋温度对浮游生物分裂率影响的数据可视化分析
  • 141.环形链表
  • C++ 最短路SPFA
  • 一文读懂 Java 注解运行原理
  • Dify开发中系统变量(system)和用户变量(user)的区别
  • 扩散模型之(五)基于概率流ODE方法
  • 【代码模板】Linux内核模块带指针的函数如何返回错误码?(ERR_PTR(-ENOMEM)、IS_ERR(ent)、PTR_ERR(ent))