实验环境
集群版本和系统信息,参考:juejin.cn/post/730041...
命名规范
在学习任何技术之前,遵循规范是必不可少的一步。在 Kubernetes
学习过程中,我们始终坚持遵守 Kubernetes
官方文档和示例,以及社区的通用规范。
文件命名规范
在 Kubernetes
中,我们通常采用 Kind-Resource.yaml
的命名约定,例如:
pod-nginx.yaml
deployment-webapp.yaml
service-database.yaml
请注意,Kubernetes
社区更倾向于使用短横线(-
)而不是下划线(_
),并且 YAML
文件的扩展名通常是 .yaml
而不是 .yml
。这种一致性有助于提高可读性,确保代码库的统一性,同时也符合社区的惯例。
Pod 资源对象
Pod 是 Kubernetes 中最小的部署单元,它可以包含一个或多个相关联的容器。这些容器共享同一网络命名空间和文件系统,并能够直接相互通信和访问共享数据。通过将容器组合到一个 Pod 中,我们可以更方便地管理它们之间的关系和依赖。
Pod
资源对象是 Kubernetes
中的一个核心概念,它代表了一个应用程序的运行实例。Pod
可以包含一个或多个相关联的容器、存储资源和其他配置选项。

网络模型要求每个 Pod
对象拥有独立的 IP
地址,并且所有 Pod
在同一网络平面内进行通信。这些 Pod
相当于在同一局域网中的多台主机。每个 Pod
内部的容器共享网络和 UTS
名称空间,包括主机名、IP
地址和端口等。而与 Pod
外部的组件通信则需要使用 Service
资源对象的 ClusterIP
和相应的端口。
Pod
还可以配置存储卷资源,这些存储卷资源可以共享给 Pod
内的所有容器使用,实现容器间的数据共享。存储卷还可以确保在容器终止后重新启动时数据不会丢失,从而提供了持久化存储的功能。
创建多个 Pod
实例来扩展应用程序时,每个实例都代表着该应用程序的一个副本(replica)。控制器对象负责创建和管理这些副本化的 Pod
,如 Deployment
控制器对象。
在创建 Pod
时,可以使用 Pod Preset
对象注入特定的信息,如 ConfigMap
、Secret
、存储卷、卷挂载和环境变量等。这样,Pod
模板的创建者无需为每个模板提供所有的信息,可以通过 Pod Preset
对象统一注入配置。
Master
节点根据期望状态和节点资源可用性,将 Pod
调度到合适的工作节点上运行。工作节点会从镜像仓库下载镜像,并在本地容器运行时环境中启动容器。集群状态保存在 etcd
中,并通过 API Server
共享给集群中的其他组件和客户端。
这些概念和流程共同构成了 Kubernetes
中 Pod
的特性,使得我们能够灵活、高效地管理应用程序的部署和运行。
Pod related commands
以下列出的一些与 Pod
相关的常用命令参考:
命令 | 描述 |
---|---|
kubectl create -f pod-definition.yaml |
创建 Pod |
kubectl get pods |
查看 Pod 列表 |
kubectl describe pod <pod-name> |
查看 Pod 详细信息 |
kubectl logs <pod-name> |
查看 Pod 日志 |
kubectl exec -it <pod-name> -- /bin/bash |
进入 Pod 内部的容器 |
kubectl delete pod <pod-name> |
删除 Pod |
kubectl delete pod <pod-name> --grace-period=0 --force |
强制删除 Pod(立即终止) |
kubectl apply -f updated-pod-definition.yaml |
应用更新(用于 Deployment 等) |
kubectl exec -it <pod-name> -- <command> |
执行命令(在容器内部执行命令) |
kubectl port-forward <pod-name> <local-port>:<pod-port> |
端口转发(将本地端口映射到 Pod 端口) |
kubectl exec <pod-name> -- env |
查看 Pod 中的环境变量 |
Create a pod
官方文档:kubernetes.io/zh-cn/docs/...
Run a busybox container
创建一个基础 Pod
配置文件
pod-busybox.yaml
文件
yaml
apiVersion: v1
kind: Pod
metadata:
name: busybox
namespace: test
labels:
app: busybox
spec:
containers:
- name: busybox
image: busybox
操作步骤
- 创建一个名为 test 的
Namespace
bash
# 创建名为 test 的命名空间
root@k8s-master:~# kubectl create ns test
namespace/test created
# 检查命名空间的状态
root@k8s-master:~# kubectl get ns
NAME STATUS AGE
calico-apiserver Active 4d20h
calico-system Active 4d21h
default Active 4d21h
kube-node-lease Active 4d21h
kube-public Active 4d21h
kube-system Active 4d21h
test Active 6s
tigera-operator Active 4d21h
- 创建一个名为 busybox 的
Pod
bash
# 应用 Pod 配置文件 pod-busybox.yaml 在 test 命名空间创建一个名为 busybox 的 Pod
root@k8s-master:~# kubectl apply -f pod-busybox.yaml
pod/busybox created
# 检查 test 命名空间下的 Pod 列表,确认 busybox Pod 的状态
root@k8s-master:~# kubectl get pods -n test
NAME READY STATUS RESTARTS AGE
busybox 0/1 Completed 1 (4s ago) 14s
- 删除这个 busybox
Pod
,并再次检查
bash
# 删除已创建的 busybox Pod
root@k8s-master:~# kubectl delete -f pod-busybox.yaml
pod "busybox" deleted
# 检查 test 命名空间下是否有 Pod 存在
root@k8s-master:~# kubectl get pods -n test
No resources found in test namespace.
添加一些常用配置
配置文件
pod-busybox.yaml
文件
yaml
apiVersion: v1
kind: Pod
metadata:
name: busybox
namespace: test
labels:
app: busybox
spec:
containers:
- name: busybox
image: busybox
# 可选值: Always | IfNotPresent | Never
imagePullPolicy: IfNotPresent
# 环境变量
env:
- name: APP_NAME
value: busybox
# 运行终端
tty: true
# 特权模式(拥有root权限)
securityContext:
privileged: true
# 工作目录
workingDir: /tmp
# 命令
command: ["/bin/sh"]
# 参数
args: ["-c", "while true; do echo hello world; sleep 3; done"]
操作步骤
- 创建
Pod
并进入交互式Shell
bash
# 修改配置后,重新应用 Pod 配置文件 pod-busybox.yaml 创建 busybox Pod
root@k8s-master:~# kubectl apply -f pod-busybox.yaml
pod/busybox created
# 在 Pod 中执行交互式 Shell
root@k8s-master:~# kubectl -n test exec -it busybox -- /bin/sh
# 查看容器内的进程列表
/tmp # ps -ef
PID USER TIME COMMAND
1 root 0:00 /bin/sh -c while true; do echo hello world; sleep 3; done
93 root 0:00 /bin/sh
101 root 0:00 ps -ef
# 在容器内查看环境变量
/tmp # env
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.96.0.1:443
HOSTNAME=busybox
SHLVL=1
HOME=/root
APP_NAME=busybox
TERM=xterm
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_HOST=10.96.0.1
PWD=/tmp
# 退出容器内的交互式 Shell
/tmp # exit
# 在 Pod 中实时查看日志
root@k8s-master:~# kubectl logs -f busybox -n test
hello world
hello world
hello world
More configurations for containers
容器的资源分配与限制
配置文件
pod-stress.yaml
文件
yaml
apiVersion: v1
kind: Pod
metadata:
name: stress-pod
namespace: test
labels:
app: stress-pod
spec:
containers:
- name: stress-container
image: progrium/stress
# 在容器中运行 stress 工具,同时进行 CPU、IO 和内存的压力测试
command: ["stress"]
args: ["--cpu", "1", "--io", "1", "--vm", "1", "--vm-bytes", "64M", "--timeout", "60s"]
# 指定容器资源
resources:
# requests 表示对资源的请求
requests:
# Mi(Mebibyte): 表示内存大小,1Mi 是 2^20 字节,约为 1.048576 兆字节
memory: "100Mi"
# m(milliCPU): 表示 CPU 的计算单位,表示千分之一,"1000m" 表示容器的 CPU 请求为 1000 毫核(1 个完整的 CPU 核心)
cpu: "1000m"
# limits 表示对资源的上限设置
limits:
memory: "200Mi"
cpu: "1000m"
操作步骤
- 在 k8s-master 节点,运行并查看
Pod
相关信息(注意:该Pod
分配到了 k8s-node1 节点上)
bash
# 应用 Pod 配置文件 pod-stress.yaml 创建名为 stress-pod 的 Pod
root@k8s-master:~# kubectl apply -f pod-stress.yaml
pod/stress-pod created
# 查看在 test 命名空间下的所有 Pod 的详细信息,包括 IP 地址、节点等
root@k8s-master:~# kubectl get pods -n test -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
stress-pod 1/1 Running 0 8s 10.244.36.74 k8s-node1 <none> <none>
- 在 k8s-node1 节点,查看
Container
资源使用情况
bash
# 使用 crictl 工具查看在容器运行时的信息,包括容器 ID、镜像、状态等
root@k8s-node1:~# crictl ps --name stress-container
CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID POD
d0bbffcf25fd4 9d98b4a6b6d1f 10 seconds ago Running stress-container 1 8d0fd26b87b34 stress-pod
# 使用 crictl 工具查看容器的统计信息,包括 CPU 使用率、内存使用量等
root@k8s-node1:~# crictl stats --id d0bbffcf25fd4
CONTAINER NAME CPU % MEM DISK INODES
d0bbffcf25fd4 stress-container 100.21 6.98MB 20.48kB 5
- 在 k8s-master 节点,查看
Pod
信息与Container
运行日志
bash
# 使用 kubectl 查看 Pod 中 stress-container 容器的日志,实时刷新
root@k8s-master:~# kubectl logs -f stress-pod -c stress-container -n test
stress: info: [1] dispatching hogs: 1 cpu, 1 io, 1 vm, 0 hdd
stress: info: [1] successful run completed in 60s
# 使用 kubectl describe 命令查看 Pod 的详细信息,包括容器的状态、资源限制、事件等
root@k8s-master:~# kubectl describe pod stress-pod -n test
Name: stress-pod
Namespace: test
Priority: 0
Service Account: default
Node: k8s-node1/10.2.102.242
Start Time: Sat, 18 Nov 2023 14:27:01 +0800
Labels: app=stress-pod
Annotations: cni.projectcalico.org/containerID: 8d0fd26b87b344c0b21274ef87f91e71475c5d77ce0cb0dbad12d0f2c6bebbc1
cni.projectcalico.org/podIP: 10.244.36.74/32
cni.projectcalico.org/podIPs: 10.244.36.74/32
Status: Running
IP: 10.244.36.74
IPs:
IP: 10.244.36.74
Containers:
stress-container:
Container ID: containerd://420ef15d07c36208afbe7dfb727476b1c51561db2588e03dec0ef87ad954c0fb
Image: progrium/stress
Image ID: sha256:9d98b4a6b6d1fe7346174111650132fd189b9153fb48a94a7b898f55f9d15a17
Port: <none>
Host Port: <none>
Command:
stress
Args:
--cpu
1
--io
1
--vm
1
--vm-bytes
64M
--timeout
60s
State: Waiting
Reason: CrashLoopBackOff
Last State: Terminated
Reason: Completed
Exit Code: 0
Started: Sat, 18 Nov 2023 14:39:28 +0800
Finished: Sat, 18 Nov 2023 14:40:28 +0800
Ready: False
Restart Count: 6
Limits:
cpu: 1
memory: 200Mi
Requests:
cpu: 1
memory: 100Mi
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-lk9kt (ro)
Conditions:
Type Status
Initialized True
Ready False
ContainersReady False
PodScheduled True
Volumes:
kube-api-access-lk9kt:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: Burstable
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 16m default-scheduler Successfully assigned test/stress-pod to k8s-node1
Normal Pulled 16m kubelet Successfully pulled image "progrium/stress" in 5.441s (5.441s including waiting)
Normal Pulled 15m kubelet Successfully pulled image "progrium/stress" in 5.378s (5.378s including waiting)
Normal Pulled 13m kubelet Successfully pulled image "progrium/stress" in 5.215s (5.215s including waiting)
Normal Pulled 12m kubelet Successfully pulled image "progrium/stress" in 5.134s (5.134s including waiting)
Normal Started 12m (x4 over 16m) kubelet Started container stress-container
Pod 容器的健康检查
启动探针
startupProbe: 用于检测容器是否已经启动完成。如果 startupProbe 失败,Kubernetes 将重新执行(由 failureThreshold 指定失败次数),一旦 startupProbe 成功,Kubernetes 将继续监控后续的探针。
- 故意写错一下,肯定是没有 /index 这个请求路径的
yaml
apiVersion: v1
kind: Pod
metadata:
name: liveness-probe-pod
namespace: test
labels:
app: liveness
spec:
containers:
- name: my-container
image: nginx
# 每隔3s向容器中进行探测,是否正常
startupProbe:
httpGet:
path: /index
port: 80
failureThreshold: 3
periodSeconds: 3
- 尝试启动运行
Pod
,启动探针被激活
bash
# 创建带有 Liveness Probe 的 Pod
root@k8s-master:~# kubectl apply -f pod-nginx.yaml
pod/liveness-probe-pod created
# 查看 Pod 状态
root@k8s-master:~# kubectl get pods -n test
NAME READY STATUS RESTARTS AGE
liveness-probe-pod 0/1 Running 0 5s
# 再次查看 Pod 状态,观察重启次数增加
root@k8s-master:~# kubectl get pods -n test
NAME READY STATUS RESTARTS AGE
liveness-probe-pod 0/1 Running 2 (11s ago) 35s
# 继续观察,直到 Pod 进入 CrashLoopBackOff 状态
root@k8s-master:~# kubectl get pods -n test
NAME READY STATUS RESTARTS AGE
liveness-probe-pod 0/1 CrashLoopBackOff 3 (2s ago) 50s
# 查看 Pod 日志,观察 liveness probe 的错误信息
root@k8s-master:~# kubectl logs -f liveness-probe-pod -n test
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2023/11/18 09:08:08 [notice] 1#1: using the "epoll" event method
2023/11/18 09:08:08 [notice] 1#1: nginx/1.25.3
2023/11/18 09:08:08 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14)
2023/11/18 09:08:08 [notice] 1#1: OS: Linux 6.1.0-7-amd64
2023/11/18 09:08:08 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2023/11/18 09:08:08 [notice] 1#1: start worker processes
2023/11/18 09:08:08 [notice] 1#1: start worker process 29
2023/11/18 09:08:08 [notice] 1#1: start worker process 30
2023/11/18 09:08:08 [notice] 1#1: start worker process 31
2023/11/18 09:08:08 [notice] 1#1: start worker process 32
2023/11/18 09:08:11 [error] 29#29: *1 open() "/usr/share/nginx/html/index" failed (2: No such file or directory), client: 10.2.102.242, server: localhost, request: "GET /index HTTP/1.1", host: "10.244.36.78:80"
10.2.102.242 - - [18/Nov/2023:09:08:11 +0000] "GET /index HTTP/1.1" 404 153 "-" "kube-probe/1.28" "-"
2023/11/18 09:08:14 [error] 30#30: *2 open() "/usr/share/nginx/html/index" failed (2: No such file or directory), client: 10.2.102.242, server: localhost, request: "GET /index HTTP/1.1", host: "10.244.36.78:80"
10.2.102.242 - - [18/Nov/2023:09:08:14 +0000] "GET /index HTTP/1.1" 404 153 "-" "kube-probe/1.28" "-"
2023/11/18 09:08:17 [error] 31#31: *3 open() "/usr/share/nginx/html/index" failed (2: No such file or directory), client: 10.2.102.242, server: localhost, request: "GET /index HTTP/1.1", host: "10.244.36.78:80"
10.2.102.242 - - [18/Nov/2023:09:08:17 +0000] "GET /index HTTP/1.1" 404 153 "-" "kube-probe/1.28" "-"
2023/11/18 09:08:17 [notice] 1#1: signal 3 (SIGQUIT) received, shutting down
2023/11/18 09:08:17 [notice] 29#29: gracefully shutting down
2023/11/18 09:08:17 [notice] 30#30: gracefully shutting down
2023/11/18 09:08:17 [notice] 31#31: gracefully shutting down
2023/11/18 09:08:17 [notice] 32#32: gracefully shutting down
2023/11/18 09:08:17 [notice] 29#29: exiting
2023/11/18 09:08:17 [notice] 30#30: exiting
2023/11/18 09:08:17 [notice] 31#31: exiting
2023/11/18 09:08:17 [notice] 32#32: exiting
2023/11/18 09:08:17 [notice] 29#29: exit
2023/11/18 09:08:17 [notice] 30#30: exit
2023/11/18 09:08:17 [notice] 31#31: exit
2023/11/18 09:08:17 [notice] 32#32: exit
2023/11/18 09:08:17 [notice] 1#1: signal 17 (SIGCHLD) received from 30
2023/11/18 09:08:17 [notice] 1#1: worker process 29 exited with code 0
2023/11/18 09:08:17 [notice] 1#1: worker process 30 exited with code 0
2023/11/18 09:08:17 [notice] 1#1: worker process 31 exited with code 0
2023/11/18 09:08:17 [notice] 1#1: signal 29 (SIGIO) received
2023/11/18 09:08:17 [notice] 1#1: signal 17 (SIGCHLD) received from 31
2023/11/18 09:08:17 [notice] 1#1: signal 17 (SIGCHLD) received from 32
2023/11/18 09:08:17 [notice] 1#1: worker process 32 exited with code 0
2023/11/18 09:08:17 [notice] 1#1: exit
- 修改配置内容,并重新应用
bash
# 移除 Liveness Probe 中的 path 字段的值 "index",修改为正确的请求路径
root@k8s-master:~# sed -i '/path/s/index//' pod-nginx.yaml
# 使用 --force 选项替换 Pod 配置,删除现有 Pod,并创建新的 Pod
root@k8s-master:~# kubectl replace --force -f pod-nginx.yaml
pod "liveness-probe-pod" deleted
pod/liveness-probe-pod replaced
# 查看更新后的 Pod 状态
root@k8s-master:~# kubectl get pods -n test
NAME READY STATUS RESTARTS AGE
liveness-probe-pod 1/1 Running 0 7s
就绪探针
就绪探针(Readiness Probe
)用于指示容器是否已准备好接收流量。如果就绪探针失败,容器将从服务负载均衡器的池中剔除,直到就绪探针再次成功。这对于确保应用程序在接收流量之前已经初始化并准备好处理请求非常重要。
yaml
apiVersion: v1
kind: Pod
metadata:
name: readiness-probe-example
namespace: test
spec:
containers:
- name: my-container
image: nginx
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 3
存活探针
存活探针(Liveness Probe
)用于检测容器是否处于运行状态。如果存活探针失败,Kubernetes
将根据容器的重启策略执行相应的操作,以帮助维持应用程序的可用性。
yaml
apiVersion: v1
kind: Pod
metadata:
name: liveness-probe-example
namespace: test
spec:
containers:
- name: my-container
image: nginx
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 3
periodSeconds: 3
三种探针比较
在 Kubernetes
中,有三种主要的探针用于监测容器的状态,它们分别是启动探针(Startup Probe
)、存活探针(Liveness Probe
)和就绪探针(Readiness Probe
)。下面是它们的对比:
探针类型 | 目的 | 配置选项 | 典型应用场景 |
---|---|---|---|
启动探针 | 检查容器是否已启动并处于健康状态 | HTTP GET、TCP Socket、Exec | 解决启动时间较长的问题,确保容器在启动后立即变为健康状态 |
就绪探针 | 检查容器是否准备好接收流量 | HTTP GET、TCP Socket、Exec | 防止将流量引导到尚未准备好的容器,确保容器已初始化 |
存活探针 | 检查容器是否运行,并在必要时重新启动 | HTTP GET、TCP Socket、Exec | 处理容器进程崩溃或无响应,确保应用程序的持续可用性 |
对比总结:
- 启动探针主要用于容器启动过程的监测,而存活探针和就绪探针主要用于容器运行时的监测和流量管理。
- 存活探针关注容器是否 "存活",异常会重启 Pod;就绪探针关注容器是否 "准备好接收流量",它不会导致 Pod 发生重启。
- 这三种探针可以根据业务需求和容器特性进行单独或组合配置,以更好地控制容器的生命周期和流量管理。
简易 ASCII 图:
用于表示启动探针、就绪探针和存活探针之间的关系。
text
┌───────────────┐ ┌─────────────┐
│ │ │ 就绪探针 | <-- 2. 就绪探针
│ │ └─────────────┘
| 启动探针 | <-- 1. 启动探针 (Startup Probe) 通常会在容器启动后立即执行
│ │ ┌─────────────┐
│ │ │ 存活探针 | <-- 3. 存活探针
└───────────────┘ └─────────────┘
▲ ▲
│ │
│ │
│ │
--------------------------------------------------------->
More configurations for global pods
网络的基本使用
配置文件
pod-nginx.yaml
文件
yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
namespace: test
labels:
app: nginx
spec:
hostNetwork: false
# 可选值: Default | ClusterFirst | ClusterFirstwithHostNet | None
dnsPolicy: "Default"
# dns配置
dnsConfig:
nameservers:
- 8.8.8.8
# 域名映射
hostAliases:
- ip: 10.2.102.242
hostnames:
- "node01"
- "worker01"
- ip: 10.2.102.243
hostnames:
- "node02"
- "worker02"
containers:
- name: nginx-container
image: nginx
imagePullPolicy: IfNotPresent
ports:
- name: default
containerPort: 80
# 如果在容器中启用了 hostNetwork,即容器与宿主机共享网络命名空间,那么这里就不能指定端口
hostPort: 8080
操作步骤
DNS
策略:如果设置为默认值(Default
),将使用kube-dns
作为DNS
服务。其服务IP
地址如下
bash
root@k8s-master:~# kubectl get svc -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 5d12h
- 创建
Pod
并进入容器内部查看网络相关配置
bash
# 创建一个名为 nginx-pod 的 Pod
root@k8s-master:~# kubectl apply -f pod-nginx.yaml
pod/nginx-pod created
# 检查 Pod 的应用节点
root@k8s-master:~# kubectl get pods -n test -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-pod 1/1 Running 0 25s 10.244.36.76 k8s-node1 <none> <none>
# 进入 Pod 容器
root@k8s-master:~# kubectl exec -it nginx-pod -n test -- /bin/bash
# 查看 DNS 服务器
root@nginx-pod:/# cat /etc/resolv.conf
nameserver 114.114.114.114
nameserver 8.8.8.8
# 查看 hosts 域名解析
root@nginx-pod:/# cat /etc/hosts
# Kubernetes-managed hosts file.
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
fe00::0 ip6-mcastprefix
fe00::1 ip6-allnodes
fe00::2 ip6-allrouters
10.244.36.76 nginx-pod
# Entries added by HostAliases.
10.2.102.242 node01 worker01
10.2.102.243 node02 worker02
- 在本地,通过该节点
IP
的8080
端口映射,可以访问到Nginx
服务
bash
# 使用 ncat 工具对节点 IP 地址的 8080 端口进行扫描,检查端口状态
➜ nc -zv 10.2.102.242 8080
Connection to 10.2.102.242 port 8080 [tcp/http-alt] succeeded!
# 使用 curl 命令获取 HTTP 响应,内容显示 Nginx 的欢迎页面
➜ curl http://10.2.102.242:8080
<!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>
卷的基本使用
配置文件
pod-redis.yaml
文件
yaml
apiVersion: v1
kind: Pod
metadata:
name: redis
namespace: test
labels:
app: redis
spec:
containers:
- name: redis
image: redis
volumeMounts:
- name: redis-storage
mountPath: /data/redis
volumes:
# 意味着每次 Pod 启动时,都会创建一个新的空目录并将其挂载到 Pod 内部的 /data/redis 路径上
- name: redis-storage
emptyDir: {}
操作步骤
bash
# 应用 Redis Pod 的配置文件
root@k8s-master:~# kubectl apply -f pod-redis.yaml
pod/redis created
# 查看在 test 命名空间中的 Pod 列表
root@k8s-master:~# kubectl get pods -n test
NAME READY STATUS RESTARTS AGE
redis 1/1 Running 0 12s
# 进入 Redis Pod,并在 /data/redis/ 目录下创建一个名为 test-file 的文件
root@k8s-master:~# kubectl -n test exec -it redis -- /bin/bash
root@redis:/data# cd /data/redis/
root@redis:/data/redis# echo "Hello, Redis!" > test-file
root@redis:/data/redis# ls -l
total 4
-rw-r--r-- 1 root root 14 Nov 19 05:15 test-file
root@redis:/data/redis# exit
# 删除 test 命名空间中的 Redis Pod
root@k8s-master:~# kubectl delete pod redis -n test
pod "redis" deleted
我们可以尝试重新连接到容器,查看文件是否存在。此外,我们还可以删除 Pod
后重新应用,以验证文件是否仍然存在。
关于 emptyDir
,它是最基础的 Volume
类型。如其名所示,emptyDir Volume
是主机上的一个空目录。尽管对容器来说是持久的,但对于 Pod
而言并非如此。当 Pod
从节点中删除时,Volume
的内容也会被清除。
其它 Pod 参数配置
验证 imagePullSecrets
imagePullSecrets
用于安全地从私有仓库拉取容器镜像。可以指定一个包含 Docker
仓库用户名和密码的 Secret
,Kubernetes
将用它来进行身份验证和拉取镜像。
yaml
apiVersion: v1
kind: Pod
metadata:
name: private-image-pod
spec:
containers:
- name: my-container
image: private-registry.example.com/my-image:latest
imagePullSecrets:
- name: my-secret
创建一个名为 my-secret 的 Kubernetes Secret
,其中包含 Docker
仓库的凭据。以下是创建该 Secret
的示例:
bash
# 创建一个 Secret
kubectl create secret docker-registry my-secret \
--docker-server=private-registry.example.com \
--docker-username=username \
--docker-password=password \
[email protected]
# 查看 Secret 的详细信息
kubectl get secret my-secret -o yaml
验证 restartPolicy
restartPolicy
是 Kubernetes Pod
中的一个参数,用于定义当容器终止时,Kubelet
是否应该尝试重新启动容器。它有三个可能的值:Always
、OnFailure
和 Never
。
yaml
apiVersion: v1
kind: Pod
metadata:
name: restart-policy-pod
spec:
containers:
- name: nginx-container
image: nginx
# Always(总是重启)| OnFailure(异常停止执行重启)| Never(无论如何都不会重启)
restartPolicy: Always