Kubernetes 学习(一) —— Pod 资源的创建与管理

实验环境

集群版本和系统信息,参考: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 对象注入特定的信息,如 ConfigMapSecret、存储卷、卷挂载和环境变量等。这样,Pod 模板的创建者无需为每个模板提供所有的信息,可以通过 Pod Preset 对象统一注入配置。

Master 节点根据期望状态和节点资源可用性,将 Pod 调度到合适的工作节点上运行。工作节点会从镜像仓库下载镜像,并在本地容器运行时环境中启动容器。集群状态保存在 etcd 中,并通过 API Server 共享给集群中的其他组件和客户端。

这些概念和流程共同构成了 KubernetesPod 的特性,使得我们能够灵活、高效地管理应用程序的部署和运行。

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

操作步骤

  1. 创建一个名为 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
  1. 创建一个名为 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
  1. 删除这个 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"]

操作步骤

  1. 创建 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"

操作步骤

  1. 在 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>
  1. 在 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
  1. 在 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 将继续监控后续的探针。

  1. 故意写错一下,肯定是没有 /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
  1. 尝试启动运行 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
  1. 修改配置内容,并重新应用
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

操作步骤

  1. 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
  1. 创建 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
  1. 在本地,通过该节点 IP8080 端口映射,可以访问到 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 仓库用户名和密码的 SecretKubernetes 将用它来进行身份验证和拉取镜像。

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

restartPolicyKubernetes Pod 中的一个参数,用于定义当容器终止时,Kubelet 是否应该尝试重新启动容器。它有三个可能的值:AlwaysOnFailureNever

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: restart-policy-pod
spec:
  containers:
  - name: nginx-container
    image: nginx
  # Always(总是重启)| OnFailure(异常停止执行重启)| Never(无论如何都不会重启)
  restartPolicy: Always
相关推荐
热河暖男7 分钟前
【实战解决方案】Spring Boot+Redisson构建高并发Excel导出服务,彻底解决系统阻塞难题
spring boot·后端·excel
oceanweave2 小时前
【K8S学习之生命周期钩子】详细了解 postStart 和 preStop 生命周期钩子
学习·kubernetes
noravinsc4 小时前
redis是内存级缓存吗
后端·python·django
noravinsc5 小时前
django中用 InforSuite RDS 替代memcache
后端·python·django
喝醉的小喵6 小时前
【mysql】并发 Insert 的死锁问题 第二弹
数据库·后端·mysql·死锁
kaixin_learn_qt_ing6 小时前
Golang
开发语言·后端·golang
炒空心菜菜7 小时前
MapReduce 实现 WordCount
java·开发语言·ide·后端·spark·eclipse·mapreduce
gnufre9 小时前
Kubernetes 1.28 无 Docker 运行时环境下的容器化构建实践:Kaniko + Jenkins 全链路详解
kubernetes·jenkins·kaniko
wowocpp9 小时前
spring boot Controller 和 RestController 的区别
java·spring boot·后端
后青春期的诗go10 小时前
基于Rust语言的Rocket框架和Sqlx库开发WebAPI项目记录(二)
开发语言·后端·rust·rocket框架