K8s 简单上手

2024-10-08 16:51:37 浏览数 (4)

基础的运行和部署 Pod

在 K8s 中,创建一个 Pod 有两种主流方式:

  1. 直接使用命令创建
代码语言:bash复制
kubectl run webserver --image=registry.access.redhat.com/ubi8/httpd-24:1-161

上面的命令就是基于指定的 image,创建一个名为 webserver 的 pod。运行过后,用 kubectl get pods 能够看到当前 namespace 下的所有 pod 的信息

  1. 根据 yaml 配置文件创建
代码语言:bash复制
kubectl apply -f xxx.yml

上面的命令就是根据 xxx.yml 来创建一个 pod。当然如果不清楚 K8s yaml 配置的格式,可以运行:

代码语言:bash复制
kubectl run probes --image=quay.io/redhattraining/do100-probes:latest --dry-run=client -o yaml

它会在终端输出一个 yaml 配置文件的模板

实际部署一个应用

Kubernetes 最显著的特性之一,就是它支持开发者采用声明式方法进行自动的容器生命周期管理。声明式方法意味着开发者只需声明什么应用的目标状态,Kubernetes 便会负责更新容器以达成该状态。

针对应用的目标状态,最基础的几个信息是:

  1. 应用程序使用的容器镜像
  2. Kubernetes 必须同时运行的应用程序实例(副本)数量
  3. 当新版本的应用程序可用时,更新副本的策略

为了实现提到的自动容器生命周期管理,K8s 具备以下特性

  1. 自动部署:自动部署配置好的应用程序,无需人工介入。
  2. 自动扩缩容:创建与请求数量相同的应用程序副本。如果请求的副本数量增加或减少,K8s 将自动创建新的容器(扩容)或终止多余的容器(缩容),以匹配请求的数量。
  3. 自动更新:当检测到应用程序的新版本或应用新的配置时,K8s 会自动更新现有的副本。K8s 监控此滚动更新过程,确保应用程序保持所声明的活跃副本数量

最基础的,创建一个 Deployment 的命令是:

代码语言:bash复制
kubectl create deployment do100-versioned-hello --image quay.io/redhattraining/do100-versioned-hello:v1.0

命令基于指定的镜像,创建了一个名为 do100-versioned-hello 的 Deployment,它只有一个 Pod。想查看 deployment 的具体信息,可以用:

代码语言:bash复制
# 基础查看信息的命令
kubectl describe deployment do100-versioned-hello

# 以 yaml 配置文件的格式查看信息
kubectl describe deployment do100-versioned-hello -o yaml

目前只有一个 Pod,可以用下面的命令来快速调整,命令将 Pod 的期望个数调整为 2,K8s 会自动创建 Pod 以符合期望,这就是自动扩缩容特性。

代码语言:bash复制
kubectl scale deployment do100-versioned-hello --replicas=2

同时也可以使用 edit 命令,直接编辑配置文件来修改配置

代码语言:bash复制
kubectl edit deployment do100-versioned-hello

Service

当创建 Pod 时,它们会被分配一个 IP 地址。你可以使用这个 IP 地址从 Kubernetes 集群内的任何地方访问 Pod。Pod 内的容器共享同一网络空间,这意味着,在 Pod 内部,容器之间可以通过使用localhost地址进行通信。

服务是一种抽象概念,它定义了对一组 Pod 的访问。通过使用服务,您不是直接通过 Pod 的私有 IP 地址访问它们。相反,服务会根据某些标准(例如标签)定位多个 Pod,并将任何请求转发给其中一个符合该标准的 Pod。服务使你能够将具有逻辑关系的 pod 分组,并允许你以可靠的方式访问它们。同时,它在其所针对的 pod 之间实现了负载均衡机制。

![Pasted image 20240926162202.png]

ClusterIP

ClusterIP 是一种 Service 类型。默认情况下,服务会被分配一个集群内部的 IP 地址,该 IP 仅在集群内部有效。这种类型的服务称为 ClusterIP。这意味着在集群中部署的 Pod 可以通过使用 ClusterIP 向服务发出请求

如果想对外暴露服务,可以使用其他类型的 Service,如 NodePortLoadBalancer 或者 Ingress

创建 Service

创建 Service 简单的方法是直接执行下面的命令,命令为名为 name-generator 的 deployment 创建一个 Service,将外部 80 端口的请求转发到内部的 8080 端口上,同时指定

代码语言:bash复制
kubectl expose deployment name-generator --port=80 --target-port=8080 --name=name-generator-service

或者可以用 manifest 文件配置。以下示例创建了一个名为 nginx-service 的服务,并针对带有标签 app: nginx 的任何 Pod。该服务监听 8080 端口的请求,并将它们转发到 Pod 内部的 3000 端口。由于清单中未包含 type 字段,因此将创建一个类型为 ClusterIP 的服务。

代码语言:yaml复制
apiVersion: v1
kind: Service
metadata:
  name: nginx-service (1)
spec:
  selector: (2)
    app: nginx
  ports: (3)
    - protocol: TCP
      port: 8081 (4)
      targetPort: 3000 (5)

更进一步

服务将应用与所用 Pod 的实际位置隔离开来,但你仍需知道 Service 的 IP 才能从应用中使用它。直接使用 IP 地址并非良策,因为未来一旦 IP 变更, 必须手动更新维护。为避免此情形,K8s 提供了两种发现服务的方式:

  1. 环境变量
  2. DNS:服务的 DNS 示例 service.namespace.svc.cluster.local

K8s 创建临时终端 Pod

实际情况中,我们可能需要一个位于指定命名空间的终端,在终端发起请求来测试服务。下面的命令在指定的 namespace 中创建一个 Pod 并创建一个与之交互的远程 shell 会话,在退出后 Pod 会被终止

代码语言:bash复制
kubectl run -n ubuntu-stage curl -it --rm --image=registry.access.redhat.com/ubi8/ubi-minimal -- sh

暴露到外部访问

资源访问限制

资源请求(Resource Requests)和资源限制(Resource Limits) 是 Kubernetes 中用于管理和控制 Pod 资源使用的两种机制。request 是最少申请的资源量,limit 是资源使用上限值

资源配额(Resource Quota) 是用于限制命名空间(Namespace)中资源使用的机制。通过定义资源配额,可以控制命名空间中所有 Pod 总共可以使用的资源量

在配置文件配置资源限制:CPU 的 m 是指 1/1000 CPU 利用率

代码语言:yaml复制
spec:
  replicas: 1
  selector:
    matchLabels:
      app: hello-limit
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: hello-limit
    spec:
      containers:
      - image: quay.io/redhattraining/hello-world-nginx:v1.0
        name: hello-world-nginx
        resources:
          requests:
            cpu: "1200m"
            memory: 20Mi

K8s 探针

目前 K8s 有三种类型的探针:

  1. Startup Probe: 在 Pod 配置的 spec.containers.startupprobe 属性中进行配置 启动探针用于验证容器内的应用程序是否已启动。它在所有其他探针之前运行,除非它成功完成,否则会禁用其他探针。如果容器启动探测失败,则该容器会被终止,并遵循 pod 的 restartPolicy
  2. Readiness Probe(就绪探针): 在 Pod 配置的 spec.containers.readinessprobe 属性中进行配置 用于确定容器是否准备好处理请求,如果探测失败,K8s 会从对应的 Service 中移除该容器的 IP
  3. Liveness Probe(存活探针): Pod 配置中的spec.containers.livenessprobe 进行配置 存活探针用于确定容器中运行的应用程序是否处于健康状态。如果存活探针检测到不健康状态,Kubernetes 将终止该容器并尝试重新部署

启动、就绪和存活探测器常见的使用场景,可以通过三种方式检查应用程序的健康状况:HTTP 检查、容器执行检查和 TCP 套接字检查

代码语言:yaml复制
# HTTP 探测
readinessProbe:
  httpGet:
    path: /health
    port: 8080
  initialDelaySeconds: 15
  timeoutSeconds: 1

# 容器执行检查
livenessProbe:
  exec:
    command:
    - cat
    - /tmp/health
  initialDelaySeconds: 15
  timeoutSeconds: 1

# TCP Socket 检查
livenessProbe:
  tcpSocket:
    port: 8080 (1)
  initialDelaySeconds: 15
  timeoutSeconds: 1

在现有的 Deployment 中设置探针,可以使用 kubectl edit 编辑现有 deployment 的配置文件或者使用 kubectl set probe 命令

应用配置文件分离

参考 https://kubebyexample.com/learning-paths/application-development-kubernetes/lesson-4-customize-deployments-application-4

K8s 提供了 secret 和 configmap 资源类型,用于外部化和管理应用程序的配置

可以使用 kubectl 命令创建配置 configmap 和 secret 资源。然后在 Pod 配置中引用它们,Kubernetes 会自动将资源数据作为环境变量注入容器,或通过卷挂载到应用程序容器内的文件中。还可以配置 Deployment 以引用 configmap 和 secret 资源。Kubernetes 会自动重新部署应用程序,并将数据提供给容器使用。

configmap 和 secret 资源的特点:

  1. 它们可以在其定义之外被独立引用
  2. 出于安全考虑,这些资源的挂载卷由临时文件存储设施(tmpfs)提供支持,并且永远不会存储在节点上
  3. 它们的范围限定在一个命名空间内

配置示例:

代码语言:yaml复制
# 配置文件形式
apiVersion: v1
data:
    key1: value1
    key2: value2
kind: ConfigMap
metadata:
    name: myconf

# 命令行形式
kubectl create configmap appconfmap --from-literal APP_MSG="Test Message"

kubectl create secret generic appconffilesec --from-file app-config/app/myapp.sec

使用示例:

代码语言:yaml复制
# 将 cm 中所有值注入 Pod 的环境变量
kubectl set env deployment/mydcname --from configmap/myconf

# cm 中所有 key 以文件形式挂载到由一个 `Deployment` 创建的 Pod
kubectl set volume deployment/mydcname --add -t configmap -m  /path/to/mount/volume --name myvol --configmap-name myconf

部署策略

K8s 默认使用滚动更新(RollingUpdate)策略

maxSurge 参数设置可以超出所需 pod 数量的最大 pod 数量

maxUnavailable 参数设定更新过程中允许不可用的最大 Pod 数量。K8s 向下取整从配置的百分比计算出绝对数值

代码语言:yaml复制
spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 50%
      maxUnavailable: 10%

1 人点赞