Kubernetes 容器部署全攻略
1. 容器部署到 Kubernetes
在使用 Kubernetes Dashboard 时,可利用特定文件在仪表板中直接创建新 Pod,但这里暂不详细探讨此方法,有兴趣的话可以自行探索。
1.1 验证资源创建
运行
kubectl apply
命令后,可通过
kubectl get pods
验证资源是否创建成功,执行该命令后会有相应输出。
1.2 Pod 状态
Pod 的状态(即 Pod 的阶段)有以下几种:
-
Pending
:Pod 正在创建,尚未运行。通常意味着容器正在从容器注册表中拉取,或者仍在启动中。
-
Running
:Pod 正在运行,其容器也在运行。
-
Succeeded
:对于非持续运行的 Pod,此状态表示 Pod 已成功完成。
-
Failed
:表示 Pod 运行失败。
-
Unknown
:由于某些原因,无法获取 Pod 的状态。
一般来说,几分钟后 NGINX 容器镜像应该能成功运行。若未运行,可使用
kubectl describe pod <pod - name>
或
kubectl logs <pod - name>
来调查 Pod。NGINX 容器镜像非常成熟,容器本身不太可能出错,但我们为 Python 和 Node.js 项目构建的容器可能并非如此。
1.3 访问 NGINX 默认页面
Pod 资源使容器运行起来后,若要访问面向互联网的 NGINX 默认页面,就需要引入第一个 Service 资源。
2. 第一个 Service
与虚拟机上未发布的容器类似,Pod 若不进行额外配置,就无法与外界通信,Pod 之间的通信也需要额外配置。在实现集群内部通信之前,先通过 Kubernetes Service 资源将 Pod 暴露到互联网。要实现这一点,需创建一个包含 Service 资源(
kind: Service
)的新清单,将 NGINX Pod 暴露到互联网。
2.1 Kubernetes Service 类型
Kubernetes 有以下几种基本的 Service 类型:
| 类型 | 描述 |
| ---- | ---- |
| NodePort(外部流量) | 集群有三个节点(虚拟机),每个节点都有 ISP 和 Akamai Connected Cloud 提供的静态公共 IP 地址。使用 NodePort Service 资源可将 Pod 暴露到 K8s 集群中每个可用节点的特定端口,如 30007。 |
| LoadBalancer(外部流量) | 这是一种很实用的 Service 类型,它会自动为 K8s Service 资源配置一个基于云的负载均衡器,并分配一个静态公共 IP 地址。在 Akamai Connected Cloud 中,Linode Kubernetes Engine 会通过名为 Linode NodeBalancers 的基于云的负载均衡服务为我们提供一个公共静态 IP 地址。 |
| ClusterIP(仅内部集群流量) | 使用此 Service 类型可让 Kubernetes 集群中的其他容器与我们的 Pod(或 Deployments)进行通信,实现集群内的容器间通信。更准确地说,ClusterIP 用于集群内的 Pod 到 Pod 或 Deployment 到 Deployment 的通信。对于不需要暴露到互联网的 Pod 或 Deployment,如数据库、内部 API 等,ClusterIP 非常适用。 |
这里我们先从 NodePort 开始,因为它无需在集群或云提供商中添加其他内容,便于快速测试。
2.2 更新 Pod 清单
在创建 Service 资源之前,需要更新 Pod 清单,以便 Service 能更轻松地找到并关联到它。在 Pod 清单(
your - first - pod.yaml
)的
metadata
块中添加一个标签,示例如下:
apiVersion: v1
kind: Pod
metadata:
name: first - pod - nginx
label:
app: my - nginx
若 Pod 或 Deployment 没有标签,Service 资源将无法正常工作。更新 Pod 清单后,使用
kubectl apply - f my - first - pod.yaml
应用更改。然后运行
kubectl get pods
确保 Pod 仍在运行,再运行
kubectl get pods my - nginx - o yaml
查看更多 Pod 详细信息,包括验证标签是否存在。
2.3 元数据标签与选择器
在任何 Kubernetes 清单中,无论其类型(Pod、Service、Deployment 等),都可以为资源应用元数据标签。元数据标签是键值对,可用于过滤任何 Kubernetes 资源。例如,更新后的 Pod 资源使用
app: my - nginx
标签,可使用
kubectl get pods - l app = my - nginx
命令查看匹配该选择器的 Pod 列表,可能会列出匹配的 Pod 或没有任何 Pod。
选择器(过滤器)用于缩小任何给定 Kubernetes 资源的结果列表,使用
-l
或
--selector
标志,例如
kubectl get <resource> - l <key>=<value>
或
kubectl get <resource> --selector <key>=<value>
。以下是一些选择器过滤的示例:
-
kubectl get pods - l my - label = my - value
-
kubectl get pods - l app = my - nginx
-
kubectl get pods --l app = nginx
-
kubectl get services - l app = my - nginx
-
kubectl get deployments - l sugar = spice
-
kubectl get deployments - l maverick = pilot
元数据标签的键和值可以是任意的,资源的元数据标签键值(如 Pod 清单中的
app:
)对 Kubernetes 本身没有特殊意义,只是一个惯用名称。只需记住使用的键值对将作为资源的选择器值。
2.4 Service 关键声明
在
spec:
块中,为 Service 定义以下关键声明:
-
type:
:选择要使用的 Kubernetes Service 类型,如 NodePort、LoadBalancer 或 ClusterIP。
-
selector:
:选择器是 Service 最重要的部分。Service 将根据此处定义的匹配键值对自动负载均衡请求。若使用的键值对没有过滤结果(如
kubectl get pods - l incorrect:data
),则该 Service 无效。
-
ports
:类似于 Docker 的
publish
参数(
-p
或
--publish
),在
kind = NodePort
的情况下,需定义三个端口值:
-
port
:供集群内部通信访问此 Service。
-
targetPort
:由 Pod 或 Deployment 定义的运行容器的端口,类似于 Docker 中的映射端口。
-
nodePort
:要在集群中每个节点上暴露的端口,如
http://<node - static - public - ip>:<nodePort>
。
2.5 创建 Service 清单
在创建 Service 之前,先做如下检查:
- 节点使用的端口为 30007(
nodePort: 30007
)。
- 用于集群内部通信的端口为 5050(
port: 5050
)。
- 容器期望的端口作为
targetPort
,如 80(
targetPort: 80
)。
- Pod 有
app: my - nginx
标签,Service 可使用该选择器找到 Pod。
基于以上信息,在
roadtok8s - kube
目录中创建一个名为
my - first - service.yaml
的文件,内容如下:
apiVersion: v1
kind: Service
metadata:
name: first - service - nginx
spec:
type: NodePort
ports:
- port: 5050
targetPort: 80
nodePort: 30007
selector:
app: my - nginx
使用
kubectl apply - f my - first - service.yaml
配置此 Service。配置完成后,可使用
kubectl get service
或
kubectl get svc
验证 Service 是否可用并列出。列出的 Services 应包含我们创建的
first - service - nginx
和默认的 Kubernetes Service。默认的 Kubernetes Service 用于集群与托管 Kubernetes API 通信,此 API 即控制平面,是资源运行的核心。
2.6 验证 NodePort
要验证 NodePort 是否正常工作,需获取每个节点的公共静态 IP 地址,可通过以下两种方式:
- 登录 Akamai Connected Cloud 控制台查看。
- 运行
kubectl get nodes - o wide
命令,该命令会列出内部和外部 IP 地址。
找到节点的公共静态 IP 地址后,访问
http://<your - node - public - ip>:30007
,就能看到 NGINX 的欢迎页面,这意味着已成功在 Kubernetes 上部署第一个连接到互联网的容器。
2.7 从 Pod 到 Deployments
Deployment 资源是将容器部署到 Kubernetes 最常用的方式,它能让我们扩展 Pod,进而扩展容器。Deployment 允许在集群的各个节点和虚拟机上运行同一容器应用的多个实例。扩展 Deployment 后,Service 资源会自动将流量负载均衡到每个可用且准备好接收流量的 Pod。
Deployment 本质上是 Pod 的集合,其清单基本是 Pod 清单在
spec:
块中增加了一些声明:
graph LR
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
A(Deployment):::process --> B(replicas):::process
A --> C(selector):::process
A --> D(template):::process
D --> E(metadata):::process
D --> F(spec):::process
E --> G(labels):::process
F --> H(containers):::process
- replicas: :此 Deployment 要运行的 Pod 数量。若未指定,默认为 1。
- selector: :预先定义标签选择器以匹配 Pod,该选择器也会在 Pod 模板中使用。
-
template:
:这就是去掉
kind和apiVersion声明的 Pod 清单,可直接复制粘贴metadata和spec值。在metadata值中,要确保标签的键值对与 Deployment 的selector:块中的选择器匹配。 -
apiVersion:
:对于 Deployment,使用
apps/v1作为apiVersion。
在
roadtok8s - kube
目录中创建一个名为
my - first - deployment.yaml
的新文件,内容如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx - deployment
spec:
replicas: 15
selector:
matchLabels:
app: my - nginx
template:
metadata:
labels:
app: my - nginx
spec:
containers:
- name: nginx
image: nginx:latest
使用
kubectl apply - f my - first - deployment.yaml
应用更改,然后使用
kubectl get deployments
或
kubectl get deploy
验证 Deployment。示例中设置了 15 个副本,若运行
kubectl get pods --selector app = my - nginx
,应该能看到至少 15 个 Pod 在运行(可能因为之前的 Pod 资源清单有 16 个)。
副本数量是 Kubernetes Deployment 资源的期望状态,Kubernetes 会持续部署 Pod,直到达到清单中定义的 15 个且都健康运行。若有 Pod 失败,Kubernetes 会自动推出新的 Pod,直到达到副本数量。默认情况下,推出过程是分层的,更新 Deployment 清单时,每次只会更新几个 Pod,这有助于在不造成停机的情况下部署容器的新版本,并确保失败的容器对 Service 的影响最小。
Pod 资源没有副本数量的概念,若 Pod 清单(如
kind: Pod
)中的容器失败,开发者需手动干预。使用配置好的 Deployment 清单时,无需更改 Service 清单,因为 Deployment 和 Pod 使用了相同的选择器,Service 会自动将流量负载均衡到 Deployment 资源的 15 个 Pod 和 Pod 资源的 1 个 Pod 上,总共 16 个 Pod 可供 Service 资源调用。最后,可使用以下命令删除所有三个资源:
-
kubectl delete - f my - first - pod.yaml
-
kubectl delete - f my - first - deployment.yaml
-
kubectl delete - f my - first - service.yaml
2.8 使用 ConfigMaps 自定义 NGINX
ConfigMaps 资源可作为卷或环境变量附加到 Deployment(或直接附加到 Pod 资源),是在不重建容器镜像的情况下修改容器默认配置的好方法。
在
roadtok8s - kube
目录中创建一个名为
custom - nginx
的新文件夹,在该文件夹中创建
1 - configmap.yaml
文件,内容如下:
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx - configmap
data:
index.html: |
<html>
<head>
<title>Hello World</title>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>
ConfigMap 资源使用
data:
而不是
spec:
来定义我们选择使用的键值对,非常灵活。这里使用
index.html
作为键,其值是一个多行的简单 HTML。
为了覆盖 NGINX 容器镜像自带的默认
index.html
值,在 Deployment 中会使用
data:
里的
index.html:
键值。为此,将 ConfigMap 作为卷挂载到 Deployment 清单中。在 Deployment 上挂载卷时,挂载的是只读卷,因为 ConfigMap 不打算被容器修改。若需要挂载读写卷,Deployment 或 Pod 可使用持久卷。
在
custom - nginx
文件夹中创建
2 - deployment.yaml
文件,内容如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: custom - nginx - deploy
spec:
replicas: 15
selector:
matchLabels:
app: custom - nginx
template:
metadata:
labels:
app: custom - nginx
spec:
containers:
- name: nginx
image: nginx:latest
volumeMounts:
- name: my - configmap - volume
mountPath: /usr/share/nginx/html
readOnly: true
volumes:
- name: my - configmap - volume
configMap:
name: nginx - configmap
再为这个 Deployment 创建一个新的 Service。在
custom - nginx
文件夹中创建
3 - service.yaml
文件,内容如下:
apiVersion: v1
kind: Service
metadata:
name: custom - nginx - svc
spec:
type: NodePort
ports:
- port: 8080
targetPort: 80
nodePort: 30008
selector:
app: custom - nginx
注意,这里的
port
和
nodePort
与之前的 Service 不同,是为了避免端口冲突。现在
custom - nginx
文件夹有以下文件:
-
1 - configmap.yaml
-
2 - deployment.yaml
-
3 - service.yaml
文件的显示顺序很重要,因为 Deployment 依赖于 ConfigMap,Service 依赖于 Deployment。若顺序错误,部分或所有这些 Services 可能无法正确配置,可能需要多次配置才能正常工作。可使用以下命令配置这些文件:
-
kubectl apply - f custom - nginx/1 - configmap.yaml
-
kubectl apply - f custom - nginx/2 - deployment.yaml
-
kubectl apply - f custom - nginx/3 - service.yaml
或者简单地使用
kubectl apply - f custom - nginx/
,它会按文件夹中文件的显示顺序配置所有文件,这就是为什么给文件加上
1 -
、
2 -
和
3 -
前缀的原因。打开任意节点公共 IP 地址上的
nodePort
(如 30008),就能看到自定义的页面。
3. 配置与部署总结
3.1 资源配置顺序总结
在 Kubernetes 中,不同资源之间存在依赖关系,因此配置顺序至关重要。以下是之前操作中涉及的资源及其配置顺序:
| 资源类型 | 文件名 | 依赖关系 | 配置命令 |
| ---- | ---- | ---- | ---- |
| ConfigMap | 1 - configmap.yaml | 无 | kubectl apply - f custom - nginx/1 - configmap.yaml |
| Deployment | 2 - deployment.yaml | 依赖 ConfigMap | kubectl apply - f custom - nginx/2 - deployment.yaml |
| Service | 3 - service.yaml | 依赖 Deployment | kubectl apply - f custom - nginx/3 - service.yaml |
为了确保配置顺序正确,我们给文件添加了前缀,也可以使用
kubectl apply - f custom - nginx/
按文件夹中文件的显示顺序进行配置。
3.2 验证与访问总结
在完成资源配置后,需要进行验证和访问操作,确保部署成功。以下是验证和访问的步骤总结:
1.
验证 Pod 状态
:使用
kubectl get pods
命令查看 Pod 的运行状态,确保 Pod 正常运行。
2.
验证 Service 状态
:使用
kubectl get service
或
kubectl get svc
命令查看 Service 的状态,确认 Service 可用。
3.
获取节点 IP 地址
:可以通过登录 Akamai Connected Cloud 控制台或运行
kubectl get nodes - o wide
命令获取节点的公共静态 IP 地址。
4.
访问应用
:根据配置的
nodePort
,访问
http://<your - node - public - ip>:<nodePort>
查看应用的运行情况。
3.3 资源清理总结
在不需要这些资源时,需要进行清理操作,避免资源浪费。可以使用以下命令删除之前创建的资源:
-
kubectl delete - f my - first - pod.yaml
-
kubectl delete - f my - first - deployment.yaml
-
kubectl delete - f my - first - service.yaml
-
kubectl delete - f custom - nginx/1 - configmap.yaml
-
kubectl delete - f custom - nginx/2 - deployment.yaml
-
kubectl delete - f custom - nginx/3 - service.yaml
4. 深入理解 Kubernetes 资源
4.1 不同资源的作用对比
Kubernetes 中有多种资源类型,如 Pod、Service、Deployment 和 ConfigMap,它们各自有不同的作用。以下是这些资源的作用对比:
| 资源类型 | 作用 | 特点 |
| ---- | ---- | ---- |
| Pod | 是 Kubernetes 中最小的可部署单元,用于运行容器 | 单个容器或多个相关容器的组合,不具备自动扩展能力 |
| Service | 为 Pod 提供稳定的网络访问方式,实现负载均衡 | 可以将流量分发到多个 Pod,有不同的类型(NodePort、LoadBalancer、ClusterIP) |
| Deployment | 用于管理 Pod 的副本数量和滚动更新,实现容器的扩展和升级 | 可以自动创建和管理多个 Pod 副本,支持滚动更新和回滚 |
| ConfigMap | 用于存储配置数据,可作为卷或环境变量挂载到 Pod 中 | 可以在不重建容器镜像的情况下修改容器的配置 |
4.2 选择器的重要性
选择器在 Kubernetes 中起着至关重要的作用,它用于过滤和匹配资源。通过选择器,Service 可以找到对应的 Pod,Deployment 可以管理特定的 Pod 副本。以下是选择器的使用示例:
-
kubectl get pods - l app = my - nginx
:查找带有
app: my - nginx
标签的 Pod。
-
kubectl get services - l app = my - nginx
:查找带有
app: my - nginx
标签的 Service。
选择器的使用使得资源的管理和调度更加灵活和高效。
4.3 副本数量与自动修复机制
Deployment 资源中的副本数量定义了要运行的 Pod 数量,Kubernetes 会自动确保实际运行的 Pod 数量达到副本数量。如果某个 Pod 失败,Kubernetes 会自动创建新的 Pod 来替换它,实现自动修复。这种机制保证了应用的高可用性和稳定性。
graph LR
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
A(Deployment):::process --> B(replicas: 15):::process
B --> C{Pod 数量是否达到 15?}:::process
C -->|是| D(正常运行):::process
C -->|否| E(创建新 Pod):::process
E --> C
5. 常见问题与解决方案
5.1 Pod 无法正常运行
如果 Pod 无法正常运行,可能是由于以下原因:
-
镜像拉取失败
:检查镜像的名称和版本是否正确,确保镜像仓库可访问。
-
资源不足
:检查节点的资源使用情况,确保节点有足够的 CPU、内存等资源。
-
配置错误
:检查 Pod 清单中的配置是否正确,如端口号、环境变量等。
解决方案:
- 使用
kubectl describe pod <pod - name>
命令查看 Pod 的详细信息,定位问题。
- 使用
kubectl logs <pod - name>
命令查看 Pod 的日志,获取更多错误信息。
5.2 Service 无法访问
如果 Service 无法访问,可能是由于以下原因:
-
选择器配置错误
:检查 Service 的
selector
配置是否与 Pod 的标签匹配。
-
端口配置错误
:检查
port
、
targetPort
和
nodePort
的配置是否正确。
-
网络问题
:检查节点的网络连接是否正常,防火墙是否允许访问。
解决方案:
- 使用
kubectl get service <service - name> - o yaml
命令查看 Service 的详细配置,确保配置正确。
- 使用
kubectl get pods - l <selector>
命令查看匹配的 Pod 是否正常运行。
5.3 Deployment 滚动更新失败
如果 Deployment 滚动更新失败,可能是由于以下原因:
-
新镜像有问题
:检查新镜像的版本和配置是否正确,确保新镜像可正常运行。
-
资源不足
:检查节点的资源使用情况,确保节点有足够的资源来创建新的 Pod。
-
配置冲突
:检查 Deployment 清单中的配置是否与现有资源冲突。
解决方案:
- 使用
kubectl rollout status deployment <deployment - name>
命令查看滚动更新的状态。
- 使用
kubectl rollout undo deployment <deployment - name>
命令回滚到上一个版本。
6. 总结与展望
6.1 总结
通过本文的介绍,我们学习了如何将容器部署到 Kubernetes,包括创建 Pod、Service、Deployment 和 ConfigMap 等资源。了解了不同资源的作用和配置方法,以及如何使用选择器进行资源过滤和匹配。同时,还介绍了常见问题的解决方案,帮助我们在实际操作中快速定位和解决问题。
6.2 展望
Kubernetes 作为容器编排领域的领导者,不断发展和完善。未来,我们可以进一步探索 Kubernetes 的高级特性,如 StatefulSet、DaemonSet、Ingress 等,实现更复杂的应用部署和管理。同时,结合云原生技术,如微服务、DevOps 等,构建更加高效、稳定和可扩展的应用架构。
希望本文能帮助你更好地理解和使用 Kubernetes,在实际项目中取得更好的效果。
超级会员免费看

被折叠的 条评论
为什么被折叠?



