使用k8s官方的交互式教程学习k8s,记录一下学习内容。
官方教程地址:https://kubernetes.io/docs/tutorials/kubernetes-basics/
第一节 创建集群
Kubernetes 集群
Kubernetes 协调一个高度可用的计算机集群,这些计算机连接起来作为一个单元工作。Kubernetes 以更有效的方式在集群中自动分配和调度应用程序容器。
Kubernetes 集群由两种类型的资源组成:控制平面和节点。控制平面负责管理集群。节点是在 Kubernetes 集群中充当工作机器的虚拟机或物理计算机,用于运行应用程序。
minikube
Minikube 是一种轻量级的 Kubernetes 实现,它在本地机器上创建一个 VM,并部署一个仅包含一个节点的简单集群。Minikube 适用于 Linux、macOS 和 Windows 系统。Minikube CLI 提供用于处理集群的基本引导操作,包括启动、停止、状态和删除。非常适合作为Kubernetes入门,或开发测试环境使用。
查看minikube版本
1 | minikube version |
启动集群
1 | minikube start |
kubectl
管理Kubernetes集群的命令行工具
查看kubectl版本
1 | kubectl version |
查看集群详细信息
1 | kubectl cluster-info |
查看集群中的节点
1 | kubectl get nodes |
第二节 部署应用
Pod
Pod 是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元。
就 Docker 概念的术语而言,Pod 类似于共享名字空间和文件系统卷的一组 Docker 容器。
部署应用
指定部署名称和应用程序映像位置(包括托管在 Docker 中心之外的映像的完整存储库 URL)。
1 | kubectl create deployment kubernetes-bootcamp --image=gcr.io/google-samples/kubernetes-bootcamp:v1 |
查看部署
1 | kubectl get deployments |
查看应用程序
在 Kubernetes 内部运行的 Pod 运行在一个私有的、隔离的网络上。默认情况下,它们在同一 kubernetes 集群内的其他 pod 和服务中可见,但在该网络之外不可见。当我们使用 kubectl 时,我们通过 API 端点进行交互以与我们的应用程序进行通信。
打开第二个终端运行代理
1 | kubectl proxy |
现在我们的主机(在线终端)和 Kubernetes 集群之间建立了连接。代理允许从这些终端直接访问 API。
通过API查询版本
1 | curl http://localhost:8001/version |
通过API访问Pod
1 | export POD_NAME=$(kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}') |
第三节 探索应用
Pod
Pod 是一组一个或多个应用程序容器(例如 Docker),以及这些容器的一些共享资源。这些资源包括:
- 共享存储,比如卷
- 网络,比如唯一的集群 IP 地址
- 有关如何运行每个容器的信息,比如容器镜像版本或要使用的特定端口
Pod 为特定于应用程序的“逻辑主机”建模,并且可以包含相对紧密耦合的不同应用程序容器。例如,一个 Pod 可能既包含您的 Node.js 应用程序的容器,也包含一个不同的容器,该容器提供要由 Node.js 网络服务器发布的数据。Pod 中的容器共享 IP 地址和端口空间,始终位于同一位置和协同调度,并在同一节点上的共享上下文中运行。
Pod 是 Kubernetes 平台上的原子单元。当我们在 Kubernetes 上创建 Deployment 时,该 Deployment 会创建带有容器的 Pod(而不是直接创建容器)。每个 Pod 都绑定到它被调度的节点,并保持在那里直到终止(根据重启策略)或删除。如果节点发生故障,相同的 Pod 会被安排在集群中的其他可用节点上。
Node
Pod 总是在Node上运行。Node 是 Kubernetes 中的工作机器,可以是虚拟机或物理机,具体取决于集群。每个节点都由控制平面管理。一个节点可以有多个 Pod,Kubernetes 控制平面会自动处理跨集群中节点的 Pod 调度。控制平面的自动调度会考虑每个节点上的可用资源。
每个 Kubernetes 节点至少运行:
- Kubelet,一个负责 Kubernetes 控制平面和 Node 之间通信的进程;它管理在机器上运行的 Pod 和容器。
- 容器运行环境(如 Docker)负责从注册表中拉取容器镜像、解包容器并运行应用程序。
使用 kubectl 进行故障排除
kubectl的常见操作:
- kubectl get - 列出资源
- kubectl describe - 显示有关资源的详细信息
- kubectl logs - 从 pod 中的容器打印日志
- kubectl exec - 在 pod 中的容器上执行命令
查看应用程序配置
查看pod
1 | kubectl get pods |
查看pod详细信息
详细信息包括但不限于:Pod 的IP地址、使用的端口、Pod 中的容器、用于构建这些容器的镜像、与 Pod 生命周期相关的事件列表。
1 | kubectl describe pods |
查看应用程序的输出
1 | curl http://localhost:8001/api/v1/namespaces/default/pods/$POD_NAME/proxy/ |
查看容器的日志
应用程序通常发送到 STDOUT 的任何内容都会成为 Pod 内容器的日志。 我们可以使用 kubectl logs 命令检索这些日志
1 | kubectl logs $POD_NAME |
在容器中执行命令
在容器中执行env命令
1 | kubectl exec $POD_NAME -- env |
在容器中启动一个 bash 会话
1 | kubectl exec -ti $POD_NAME -- bash |
查看应用的代码源文件
1 | cat server.js |
访问应用
1 | curl localhost:8080 |
第四节 使用服务公开应用
Kubernetes Pod 是转瞬即逝的。 Pod 实际上拥有生命周期。 当一个工作 Node 挂掉后, 在 Node 上运行的 Pod 也会消亡。
Kubernetes 中的服务(Service)是一种抽象概念,它定义了 Pod 的逻辑集和访问 Pod 的协议。Service 下的一组 Pod 通常由 LabelSelector 来标记。
尽管每个 Pod 都有一个唯一的 IP 地址,但是如果没有 Service ,这些 IP 不会暴露在群集外部。Service 允许您的应用程序接收流量。Service 也可以用在 ServiceSpec 标记type
的方式暴露
- ClusterIP (默认) - 在集群的内部 IP 上公开 Service 。这种类型使得 Service 只能从集群内访问。
- NodePort - 使用 NAT 在集群中每个选定 Node 的相同端口上公开 Service 。使用
<NodeIP>:<NodePort>
从集群外部访问 Service。是 ClusterIP 的超集。 - LoadBalancer - 在当前云中创建一个外部负载均衡器(如果支持的话),并为 Service 分配一个固定的外部IP。是 NodePort 的超集。
- ExternalName - 通过返回带有该名称的 CNAME 记录,使用任意名称(由 spec 中的
externalName
指定)公开 Service。不使用代理。这种类型需要kube-dns
的v1.7或更高版本。
创建新的服务
查看服务
1 | kubectl get services |
创建新服务将应用公开到外部
1 | kubectl expose deployment/kubernetes-bootcamp --type="NodePort" --port 8080 |
查看打开的端口
1 | kubectl describe services/kubernetes-bootcamp |
访问应用
设置NODE_PORT环境变量
1 | export NODE_PORT=$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}') |
用curl测试应用程序是否暴露在集群之外
1 | curl $(minikube ip):$NODE_PORT |
使用标签
查看pod的标签
Deployment 自动为我们的 Pod 创建了一个标签。 使用 describe deployment 命令,可以看到标签的名称
1 | kubectl describe deployment |
使用标签来查询 Pod
1 | kubectl get pods -l app=kubernetes-bootcamp |
使用标签来查询 Service
1 | kubectl get services -l app=kubernetes-bootcamp |
添加新标签
设置POD_NAME环境变量
1 | export POD_NAME=$(kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}') |
添加version标签
1 | kubectl label pods $POD_NAME version=v1 |
查看pod的标签
1 | kubectl describe pods $POD_NAME |
使用version标签来查询 Pod
1 | kubectl get pods -l version=v1 |
删除服务
1 | kubectl delete service -l app=kubernetes-bootcamp |
确认服务已经删除
1 | kubectl get services |
确认路由不再公开
1 | curl $(minikube ip):$NODE_PORT |
确认应用程序仍然在 pod 内运行
1 | kubectl exec -ti $POD_NAME -- curl localhost:8080 |