暴露 Kubernetes 应用程序

KubernetesKubernetesBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

介绍

在本实验中,你将学习如何使用多种技术暴露 Kubernetes 应用程序,包括创建内部和外部服务、使用标签以及探索 Ingress 的基础知识。你将首先使用 Minikube 设置一个本地 Kubernetes 集群,然后部署一个示例 NGINX 应用程序,并将其在内部和外部暴露。你还将探索如何使用标签来组织和选择资源,最后,你将了解 Ingress 并查看一个简单的 Ingress YAML 示例。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL kubernetes(("`Kubernetes`")) -.-> kubernetes/BasicsGroup(["`Basics`"]) kubernetes(("`Kubernetes`")) -.-> kubernetes/BasicCommandsGroup(["`Basic Commands`"]) kubernetes(("`Kubernetes`")) -.-> kubernetes/AdvancedCommandsGroup(["`Advanced Commands`"]) kubernetes(("`Kubernetes`")) -.-> kubernetes/TroubleshootingandDebuggingCommandsGroup(["`Troubleshooting and Debugging Commands`"]) kubernetes(("`Kubernetes`")) -.-> kubernetes/ConfigurationandVersioningGroup(["`Configuration and Versioning`"]) kubernetes/BasicsGroup -.-> kubernetes/initialization("`Initialization`") kubernetes/BasicCommandsGroup -.-> kubernetes/get("`Get`") kubernetes/BasicCommandsGroup -.-> kubernetes/create("`Create`") kubernetes/BasicCommandsGroup -.-> kubernetes/delete("`Delete`") kubernetes/AdvancedCommandsGroup -.-> kubernetes/apply("`Apply`") kubernetes/TroubleshootingandDebuggingCommandsGroup -.-> kubernetes/describe("`Describe`") kubernetes/ConfigurationandVersioningGroup -.-> kubernetes/label("`Label`") kubernetes/ConfigurationandVersioningGroup -.-> kubernetes/version("`Version`") subgraph Lab Skills kubernetes/initialization -.-> lab-434647{{"`暴露 Kubernetes 应用程序`"}} kubernetes/get -.-> lab-434647{{"`暴露 Kubernetes 应用程序`"}} kubernetes/create -.-> lab-434647{{"`暴露 Kubernetes 应用程序`"}} kubernetes/delete -.-> lab-434647{{"`暴露 Kubernetes 应用程序`"}} kubernetes/apply -.-> lab-434647{{"`暴露 Kubernetes 应用程序`"}} kubernetes/describe -.-> lab-434647{{"`暴露 Kubernetes 应用程序`"}} kubernetes/label -.-> lab-434647{{"`暴露 Kubernetes 应用程序`"}} kubernetes/version -.-> lab-434647{{"`暴露 Kubernetes 应用程序`"}} end

启动 Kubernetes 集群

在这一步中,你将学习如何使用 Minikube 启动并验证一个本地 Kubernetes 集群。这是在本地机器上开发和测试 Kubernetes 应用程序的重要第一步。

首先,启动 Minikube 集群:

minikube start

示例输出:

😄  minikube v1.29.0 on Ubuntu 22.04
✨  自动选择 docker 驱动
📌  使用 Docker 驱动并具有 root 权限
🔥  在 Kubernetes 集群中创建 Kubernetes
🔄  重启现有的 Kubernetes 集群
🐳  在 Docker 20.10.23 上准备 Kubernetes v1.26.1 ...
🚀  启动 Kubernetes ...
🌟  启用插件:storage-provisioner, default-storageclass
🏄  完成!kubectl 现在已配置为使用 "minikube" 集群和 "default" 命名空间

使用多个命令验证集群状态:

minikube status
kubectl get nodes

minikube status 的示例输出:

minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured

kubectl get nodes 的示例输出:

NAME       STATUS   ROLES           AGE   VERSION
minikube   Ready    control-plane   1m    v1.26.1

这些命令确认了以下内容:

  1. Minikube 已成功运行
  2. 本地 Kubernetes 集群已创建
  3. 集群已准备就绪
  4. 你拥有一个具有控制平面功能的单节点集群

部署示例应用程序

在这一步中,你将学习如何使用 YAML 清单文件创建并部署一个 Kubernetes 应用程序。我们将创建一个简单的 NGINX Web 服务器部署,以演示定义和应用 Kubernetes 资源的过程。

首先,为你的 Kubernetes 清单文件创建一个目录:

mkdir -p ~/project/k8s-manifests
cd ~/project/k8s-manifests

创建一个用于 NGINX 部署的 YAML 文件:

nano nginx-deployment.yaml

添加以下部署清单内容:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:latest
          ports:
            - containerPort: 80

保存文件(按 Ctrl+X,然后按 Y,最后按 Enter)。

将部署应用到 Kubernetes 集群:

kubectl apply -f nginx-deployment.yaml

示例输出:

deployment.apps/nginx-deployment created

验证部署和 Pod:

kubectl get deployments
kubectl get pods

kubectl get deployments 的示例输出:

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           1m

kubectl get pods 的示例输出:

NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-xxx-yyy            1/1     Running   0          1m
nginx-deployment-xxx-zzz            1/1     Running   0          1m
nginx-deployment-xxx-www            1/1     Running   0          1m

等待 Pod 进入 "Running" 状态后再继续。

让我们分解一下 YAML 清单:

  • apiVersion:指定 Kubernetes API 版本
  • kind:定义资源类型(Deployment)
  • metadata:为部署提供名称和标签
  • spec.replicas:设置 Pod 副本的数量
  • selector:帮助部署管理正确的 Pod
  • template:定义 Pod 的规格
  • containers:指定容器镜像和端口

此部署创建了三个相同的 NGINX Pod,展示了 Kubernetes 如何管理容器化应用程序。

通过 YAML 创建服务以内部或外部暴露应用程序

在这一步中,你将学习如何创建 Kubernetes 服务以内部和外部暴露你的 NGINX 部署。我们将演示两种常见的服务类型:ClusterIP 和 NodePort。

首先,导航到你的项目目录:

cd ~/project/k8s-manifests

创建一个 ClusterIP 服务的 YAML 文件:

nano nginx-clusterip-service.yaml

添加以下服务清单内容:

apiVersion: v1
kind: Service
metadata:
  name: nginx-clusterip-service
spec:
  selector:
    app: nginx
  type: ClusterIP
  ports:
    - port: 80
      targetPort: 80

现在,创建一个 NodePort 服务的 YAML 文件:

nano nginx-nodeport-service.yaml

添加以下服务清单内容:

apiVersion: v1
kind: Service
metadata:
  name: nginx-nodeport-service
spec:
  selector:
    app: nginx
  type: NodePort
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30080

应用这两个服务配置:

kubectl apply -f nginx-clusterip-service.yaml
kubectl apply -f nginx-nodeport-service.yaml

示例输出:

service/nginx-clusterip-service created
service/nginx-nodeport-service created

验证服务:

kubectl get services

示例输出:

NAME                        TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes                  ClusterIP   10.96.0.1        <none>        443/TCP        30m
nginx-clusterip-service     ClusterIP   10.104.xxx.xxx   <none>        80/TCP         1m
nginx-nodeport-service      NodePort    10.108.yyy.yyy   <none>        80:30080/TCP   1m

要访问 NodePort 服务,获取 Minikube 的 IP 地址:

minikube ip

示例输出:

192.168.49.2

服务类型的关键区别:

  • ClusterIP:仅限集群内部访问
  • NodePort:在每个节点的 IP 上通过静态端口暴露服务
  • NodePort 范围:30000-32767

验证服务配置

在这一步中,你将学习如何使用 kubectl describe service 来检查 Kubernetes 服务的详细配置,并了解其网络属性。

首先,确保你在项目目录中:

cd ~/project/k8s-manifests

详细描述 ClusterIP 服务:

kubectl describe service nginx-clusterip-service

示例输出:

Name:              nginx-clusterip-service
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=nginx
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.104.xxx.xxx
IPs:               10.104.xxx.xxx
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.0.7:80,10.244.0.8:80,10.244.0.9:80
Session Affinity:  None
Events:            <none>

现在,描述 NodePort 服务:

kubectl describe service nginx-nodeport-service

示例输出:

Name:                     nginx-nodeport-service
Namespace:                default
Labels:                   <none>
Annotations:              <none>
Selector:                 app=nginx
Type:                     NodePort
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.108.yyy.yyy
IPs:                      10.108.yyy.yyy
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  30080/TCP
Endpoints:                10.244.0.7:80,10.244.0.8:80,10.244.0.9:80
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

检查服务端点以验证网络连接性:

kubectl get endpoints

示例输出:

NAME                        ENDPOINTS                               AGE
kubernetes                  192.168.49.2:8443                       45m
nginx-clusterip-service     10.244.0.7:80,10.244.0.8:80,10.244.0.9:80   15m
nginx-nodeport-service      10.244.0.7:80,10.244.0.8:80,10.244.0.9:80   15m

从服务描述中需要理解的关键信息:

  • Selector:显示哪些 Pod 属于该服务
  • IP:服务的集群内部 IP 地址
  • Endpoints:提供服务 Pod 的 IP 地址和端口列表
  • Port 和 TargetPort:定义流量如何路由
  • NodePort:NodePort 服务类型的外部端口

使用标签组织和选择资源

在这一步中,你将学习如何在 Kubernetes 中使用标签来高效地组织和选择资源。标签是键值对,可以帮助你管理和组织 Kubernetes 对象。

首先,验证当前 Pod 上的标签:

kubectl get pods --show-labels

示例输出:

NAME                                READY   STATUS    RESTARTS   AGE   LABELS
nginx-deployment-xxx-yyy            1/1     Running   0          30m   app=nginx,pod-template-hash=xxx
nginx-deployment-xxx-zzz            1/1     Running   0          30m   app=nginx,pod-template-hash=yyy
nginx-deployment-xxx-www            1/1     Running   0          30m   app=nginx,pod-template-hash=zzz

使用特定标签选择 Pod:

kubectl get pods -l app=nginx

示例输出:

NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-xxx-yyy            1/1     Running   0          30m
nginx-deployment-xxx-zzz            1/1     Running   0          30m
nginx-deployment-xxx-www            1/1     Running   0          30m

让我们为其中一个 Pod 添加一个自定义标签:

kubectl label pods nginx-deployment-xxx-yyy environment=development

nginx-deployment-xxx-yyy 替换为你其中一个 Pod 的名称。

示例输出:

pod/nginx-deployment-xxx-yyy labeled

现在,使用多个标签选择器选择 Pod:

kubectl get pods -l app=nginx,environment=development

示例输出:

NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-xxx-yyy            1/1     Running   0          30m

从 Pod 中移除一个标签:

kubectl label pods nginx-deployment-xxx-yyy environment-

示例输出:

pod/nginx-deployment-xxx-yyy unlabeled

在服务中演示标签选择:

kubectl describe service nginx-clusterip-service

查看 "Selector" 部分,它展示了服务如何使用标签来识别 Pod。

关于标签的关键点:

  • 标签是附加到 Kubernetes 对象上的键值对
  • 用于组织、选择和过滤资源
  • 可以动态添加、修改或移除
  • 服务和部署使用标签来管理相关的 Pod

删除和管理服务

在这一步中,你将学习如何使用 kubectl 命令删除和管理 Kubernetes 服务。理解服务管理对于维护和清理 Kubernetes 资源至关重要。

首先,列出当前的服务:

kubectl get services

示例输出:

NAME                        TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes                  ClusterIP   10.96.0.1        <none>        443/TCP        1h
nginx-clusterip-service     ClusterIP   10.104.xxx.xxx   <none>        80/TCP         45m
nginx-nodeport-service      NodePort    10.108.yyy.yyy   <none>        80:30080/TCP   45m

使用 kubectl delete 删除特定服务:

kubectl delete service nginx-clusterip-service

示例输出:

service "nginx-clusterip-service" deleted

验证服务是否已删除:

kubectl get services

示例输出:

NAME                        TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes                  ClusterIP   10.96.0.1        <none>        443/TCP        1h
nginx-nodeport-service      NodePort    10.108.yyy.yyy   <none>        80:30080/TCP   45m

一次性删除多个服务:

kubectl delete service nginx-nodeport-service

示例输出:

service "nginx-nodeport-service" deleted

验证所有服务是否已删除(默认的 kubernetes 服务除外):

kubectl get services

示例输出:

NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   1h

其他删除方法:

## 使用 YAML 文件删除服务
kubectl delete -f nginx-nodeport-service.yaml

## 通过标签删除服务
kubectl delete service -l app=nginx

关于服务删除的关键点:

  • 删除服务会移除网络端点
  • 删除服务时不会删除 Pod
  • 默认的 kubernetes 服务无法删除
  • 你可以通过名称、YAML 文件或标签删除服务

介绍 Ingress 基础知识并展示一个简单的 Ingress YAML 示例

在这一步中,你将学习 Kubernetes Ingress,这是一种管理 Kubernetes 集群中服务外部访问的强大方式。首先,在 Minikube 中启用 Ingress 插件:

minikube addons enable ingress

示例输出:

💡  ingress 是由 Kubernetes 维护的插件。如有任何问题,请在 GitHub 上联系 minikube。
🔉  ingress 已成功启用

为两个示例应用程序创建部署:

kubectl create deployment web1 --image=nginx:alpine
kubectl create deployment web2 --image=httpd:alpine

将这些部署暴露为服务:

kubectl expose deployment web1 --port=80 --type=ClusterIP --name=web1-service
kubectl expose deployment web2 --port=80 --type=ClusterIP --name=web2-service

创建一个 Ingress YAML 文件:

nano ingress-example.yaml

添加以下 Ingress 配置:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
    - http:
        paths:
          - path: /web1
            pathType: Prefix
            backend:
              service:
                name: web1-service
                port:
                  number: 80
          - path: /web2
            pathType: Prefix
            backend:
              service:
                name: web2-service
                port:
                  number: 80

应用 Ingress 配置:

kubectl apply -f ingress-example.yaml

验证 Ingress 资源:

kubectl get ingress

示例输出:

NAME              CLASS   HOSTS   ADDRESS        PORTS   AGE
example-ingress   nginx   *       192.168.49.2   80      1m

检查 Ingress 详细信息:

kubectl describe ingress example-ingress

示例输出将显示路由规则和后端服务。

接下来,你可以使用 curl 命令验证暴露的服务是否正常工作。假设你的 Ingress 资源配置正确且 Minikube IP 为 192.168.49.2,你可以运行以下命令:

curl 192.168.49.2

如果服务正常工作,你应该会看到适当的响应输出。

Ingress 的关键概念:

  • 管理服务的外部访问
  • 提供 HTTP/HTTPS 路由
  • 允许基于路径的路由
  • 可以实现 SSL 终止
  • 比 NodePort 或 LoadBalancer 服务更灵活

总结

在本实验中,你学习了如何使用 Minikube 启动并验证一个本地 Kubernetes 集群,这是在本地机器上开发和测试 Kubernetes 应用程序的重要第一步。随后,你使用 YAML 清单文件创建并部署了一个简单的 NGINX Web 服务器部署,演示了定义和应用 Kubernetes 资源的过程。此外,你还学习了如何创建 Kubernetes 服务以内部或外部暴露你的应用程序,以及如何使用标签来组织和选择资源。最后,你探索了 Kubernetes Ingress 的基础知识,并查看了一个简单的 Ingress YAML 示例。

您可能感兴趣的其他 Kubernetes 教程