基础的运行和部署 Pod
在 K8s 中,创建一个 Pod 有两种主流方式:
- 直接使用命令创建
kubectl run webserver --image=registry.access.redhat.com/ubi8/httpd-24:1-161
上面的命令就是基于指定的 image,创建一个名为 webserver 的 pod。运行过后,用 kubectl get pods
能够看到当前 namespace 下的所有 pod 的信息
- 根据 yaml 配置文件创建
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 便会负责更新容器以达成该状态。
针对应用的目标状态,最基础的几个信息是:
- 应用程序使用的容器镜像
- Kubernetes 必须同时运行的应用程序实例(副本)数量
- 当新版本的应用程序可用时,更新副本的策略
为了实现提到的自动容器生命周期管理,K8s 具备以下特性
- 自动部署:自动部署配置好的应用程序,无需人工介入。
- 自动扩缩容:创建与请求数量相同的应用程序副本。如果请求的副本数量增加或减少,K8s 将自动创建新的容器(扩容)或终止多余的容器(缩容),以匹配请求的数量。
- 自动更新:当检测到应用程序的新版本或应用新的配置时,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 的具体信息,可以用:
# 基础查看信息的命令
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,如 NodePort
或 LoadBalancer
或者 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
的服务。
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 提供了两种发现服务的方式:
- 环境变量
- 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 有三种类型的探针:
- Startup Probe:
在 Pod 配置的 spec.containers.startupprobe 属性中进行配置
启动探针用于验证容器内的应用程序是否已启动。它在所有其他探针之前运行,除非它成功完成,否则会禁用其他探针。如果容器启动探测失败,则该容器会被终止,并遵循 pod 的
restartPolicy
- Readiness Probe(就绪探针):
在 Pod 配置的
spec.containers.readinessprobe
属性中进行配置 用于确定容器是否准备好处理请求,如果探测失败,K8s 会从对应的 Service 中移除该容器的 IP - 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 资源的特点:
- 它们可以在其定义之外被独立引用
- 出于安全考虑,这些资源的挂载卷由临时文件存储设施(tmpfs)提供支持,并且永远不会存储在节点上
- 它们的范围限定在一个命名空间内
配置示例:
代码语言: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 向下取整从配置的百分比计算出绝对数值
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 50%
maxUnavailable: 10%