MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

Bash中的脚本与Kubernetes集群

2024-03-101.2k 阅读

一、Bash 脚本基础

1.1 Bash 脚本的基本结构

Bash 脚本以#!/bin/bash这一行作为开头,这被称为 shebang 行,它告诉系统应该使用哪个解释器来执行脚本。例如:

#!/bin/bash
echo "Hello, World!"

在上述示例中,echo是一个常用的命令,用于在标准输出上打印文本。

1.2 变量

在 Bash 脚本中,变量可以用来存储数据。定义变量的方式很简单,例如:

#!/bin/bash
name="John"
echo "My name is $name"

这里定义了一个名为name的变量,并将其值设置为John。在echo语句中,通过$name来引用这个变量的值。

变量命名有一定规则,变量名只能包含字母、数字和下划线,并且不能以数字开头。

1.3 条件语句

条件语句允许根据不同的条件执行不同的代码块。最常见的条件语句是if - then - else结构。例如:

#!/bin/bash
num=10
if [ $num -gt 5 ]; then
    echo "The number is greater than 5"
else
    echo "The number is less than or equal to 5"
fi

在这个例子中,[ $num -gt 5 ]是一个测试条件,-gt表示大于。如果条件为真,就会执行then后面的代码块;否则,执行else后面的代码块。

除了-gt,还有其他常用的比较操作符,如-lt(小于)、-eq(等于)等。

1.4 循环语句

循环语句允许重复执行一段代码。常见的循环有for循环和while循环。

1.4.1 for 循环

#!/bin/bash
for i in 1 2 3 4 5; do
    echo "Number: $i"
done

在这个for循环中,变量i依次取15的值,每次循环都会执行dodone之间的代码块。

1.4.2 while 循环

#!/bin/bash
count=1
while [ $count -le 5 ]; do
    echo "Count: $count"
    count=$((count + 1))
done

这里使用while循环,只要count小于等于5,就会一直执行循环体中的代码。count=$((count + 1))用于每次循环时增加count的值。

二、Kubernetes 集群基础

2.1 Kubernetes 简介

Kubernetes,简称 K8s,是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。它提供了一种在集群中高效运行容器化服务的方式,使得应用的部署、维护和扩展变得更加容易。

2.2 Kubernetes 集群组件

2.2.1 Master 组件

  • kube - apiserver:作为 Kubernetes 集群的前端接口,接受来自客户端的请求,并与 etcd 交互,对集群的资源进行增删改查等操作。
  • etcd:一个高可用的键值对存储,用于保存 Kubernetes 集群的所有配置数据和状态信息。
  • kube - scheduler:负责将 Pod 调度到合适的 Node 节点上运行。它根据节点的资源状况、Pod 的资源需求以及调度策略等因素进行调度决策。
  • kube - controller - manager:运行各种控制器,如副本控制器、节点控制器、服务账号控制器等。这些控制器负责维护集群的状态,例如确保 Pod 的期望副本数与实际运行的副本数一致。

2.2.2 Node 组件

  • kubelet:运行在每个 Node 节点上,负责与 Master 通信,管理本机上的 Pod。它根据 Master 的指令创建、启动、停止 Pod 及其容器。
  • kube - proxy:在每个 Node 节点上运行,负责实现 Kubernetes 服务的网络代理功能。它通过 iptables 等工具将服务的虚拟 IP 映射到后端实际的 Pod IP,实现服务发现和负载均衡。

2.3 Kubernetes 资源对象

2.3.1 Pod

Pod 是 Kubernetes 中最小的可部署和可管理的计算单元,它可以包含一个或多个紧密相关的容器。这些容器共享网络命名空间和存储卷,通常用于运行一组协同工作的容器化应用。例如,一个 Web 应用及其相关的缓存容器可以放在同一个 Pod 中。

2.3.2 Service

Service 为一组 Pod 提供了一个稳定的网络接口,使得客户端可以通过这个接口访问 Pod 提供的服务,而无需关心 Pod 的具体 IP 地址和数量变化。例如,一个负载均衡 Service 可以将外部流量均匀地分发到后端的多个 Pod 上。

2.3.3 Deployment

Deployment 用于管理 Pod 的部署和更新。它可以定义 Pod 的副本数、镜像版本等信息,并且支持滚动更新和回滚操作,确保应用的高可用性和版本控制。

三、Bash 脚本与 Kubernetes 集群的交互

3.1 安装和配置 kubectl

kubectl是 Kubernetes 的命令行工具,用于与 Kubernetes 集群进行交互。在使用 Bash 脚本操作 Kubernetes 集群之前,需要先安装并配置好kubectl

在不同的操作系统上安装方式略有不同。以 Ubuntu 为例,可以通过以下命令安装:

sudo apt - get update
sudo apt - get install - y kubectl

安装完成后,需要配置kubectl连接到正确的 Kubernetes 集群。可以通过kubeconfig文件来配置,通常这个文件位于~/.kube/config。如果是在云平台上创建的集群,一般会提供相应的配置文件下载和导入方法。

3.2 使用 Bash 脚本创建 Kubernetes 资源

3.2.1 创建 Pod

可以使用kubectl create -f命令来创建 Pod,其中-f参数指定资源描述文件的路径。假设我们有一个名为pod.yaml的文件,内容如下:

apiVersion: v1
kind: Pod
metadata:
  name: my - pod
spec:
  containers:
  - name: my - container
    image: nginx:1.14.2
    ports:
    - containerPort: 80

然后可以编写一个 Bash 脚本来创建这个 Pod:

#!/bin/bash
kubectl create -f pod.yaml

执行这个脚本后,Kubernetes 集群就会创建一个名为my - pod的 Pod,其中运行着一个基于nginx:1.14.2镜像的容器,并暴露 80 端口。

3.2.2 创建 Service

同样,对于 Service 也可以通过资源描述文件和kubectl命令来创建。假设service.yaml文件内容如下:

apiVersion: v1
kind: Service
metadata:
  name: my - service
spec:
  selector:
    app: my - app
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: ClusterIP

Bash 脚本可以这样写:

#!/bin/bash
kubectl create -f service.yaml

这个脚本会创建一个名为my - service的 ClusterIP 类型的 Service,它会将流量转发到具有app: my - app标签的 Pod 上的 80 端口。

3.3 使用 Bash 脚本查询 Kubernetes 资源状态

3.3.1 查询 Pod 状态

可以使用kubectl get pods命令来获取 Pod 的状态信息。在 Bash 脚本中,可以这样实现:

#!/bin/bash
pod_status=$(kubectl get pods my - pod - o jsonpath='{.status.phase}')
echo "The status of my - pod is: $pod_status"

这里使用kubectl get pods命令获取my - pod的状态,并通过jsonpath提取出状态阶段信息,然后打印出来。

3.3.2 查询 Service 状态

类似地,查询 Service 的状态可以使用kubectl get services命令:

#!/bin/bash
service_ip=$(kubectl get services my - service - o jsonpath='{.spec.clusterIP}')
echo "The cluster IP of my - service is: $service_ip"

这个脚本获取my - service的集群 IP 地址并打印出来。

3.4 使用 Bash 脚本更新和删除 Kubernetes 资源

3.4.1 更新 Deployment

假设我们要更新一个 Deployment 的镜像版本。首先修改 Deployment 的资源描述文件deployment.yaml中的镜像版本,然后使用kubectl apply -f命令来更新。Bash 脚本如下:

#!/bin/bash
# 修改镜像版本
sed -i 's/nginx:1.14.2/nginx:1.15.0/' deployment.yaml
kubectl apply -f deployment.yaml

这里使用sed命令在deployment.yaml文件中替换镜像版本,然后使用kubectl apply命令应用更新,Kubernetes 会自动进行滚动更新。

3.4.2 删除资源

删除 Pod 或 Service 可以使用kubectl delete命令。例如,删除名为my - pod的 Pod:

#!/bin/bash
kubectl delete pod my - pod

删除名为my - service的 Service:

#!/bin/bash
kubectl delete service my - service

四、在 Kubernetes 集群中自动化部署应用的 Bash 脚本示例

4.1 整体流程

假设我们有一个简单的 Web 应用,包含一个后端 API 服务和一个前端界面服务。我们将使用 Kubernetes 来部署这个应用,并通过 Bash 脚本来自动化整个部署过程。流程如下:

  1. 创建后端 API 的 Deployment 和 Service。
  2. 创建前端界面的 Deployment 和 Service。
  3. 等待所有 Pod 就绪。
  4. 打印服务的访问地址。

4.2 后端 API 资源描述文件

假设后端 API 的deployment - api.yaml文件内容如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api - deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: api
  template:
    metadata:
      labels:
        app: api
    spec:
      containers:
      - name: api - container
        image: my - api - image:1.0
        ports:
        - containerPort: 8080

service - api.yaml文件内容如下:

apiVersion: v1
kind: Service
metadata:
  name: api - service
spec:
  selector:
    app: api
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080
  type: ClusterIP

4.3 前端界面资源描述文件

前端界面的deployment - frontend.yaml文件内容如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend - deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      containers:
      - name: frontend - container
        image: my - frontend - image:1.0
        ports:
        - containerPort: 3000

service - frontend.yaml文件内容如下:

apiVersion: v1
kind: Service
metadata:
  name: frontend - service
spec:
  selector:
    app: frontend
  ports:
  - protocol: TCP
    port: 80
    targetPort: 3000
  type: NodePort

4.4 自动化部署的 Bash 脚本

#!/bin/bash

# 创建后端 API 的 Deployment 和 Service
kubectl create -f deployment - api.yaml
kubectl create -f service - api.yaml

# 创建前端界面的 Deployment 和 Service
kubectl create -f deployment - frontend.yaml
kubectl create -f service - frontend.yaml

# 等待后端 API Pod 就绪
echo "Waiting for API pods to be ready..."
while true; do
    ready_count=$(kubectl get pods -l app=api -o jsonpath='{.items[?(@.status.phase=="Running")].status.containerStatuses[0].ready}' | grep -c true)
    if [ $ready_count -eq 3 ]; then
        break
    fi
    sleep 5
done

# 等待前端界面 Pod 就绪
echo "Waiting for frontend pods to be ready..."
while true; do
    ready_count=$(kubectl get pods -l app=frontend -o jsonpath='{.items[?(@.status.phase=="Running")].status.containerStatuses[0].ready}' | grep -c true)
    if [ $ready_count -eq 2 ]; then
        break
    fi
    sleep 5
done

# 获取前端服务的访问地址
frontend_service_ip=$(kubectl get services frontend - service - o jsonpath='{.spec.clusterIP}')
frontend_service_port=$(kubectl get services frontend - service - o jsonpath='{.spec.ports[0].nodePort}')
echo "The frontend service can be accessed at: http://$frontend_service_ip:$frontend_service_port"

这个脚本首先创建后端 API 和前端界面的 Deployment 与 Service,然后通过循环等待所有相关 Pod 就绪,最后获取前端服务的访问地址并打印出来,实现了整个应用在 Kubernetes 集群中的自动化部署。

五、Bash 脚本在 Kubernetes 集群管理中的高级应用

5.1 基于条件的资源操作

在实际的集群管理中,可能需要根据集群的状态或某些条件来执行不同的资源操作。例如,只有当集群中有足够的空闲资源时,才创建新的 Deployment。

#!/bin/bash

# 获取当前集群的空闲 CPU 资源
idle_cpu=$(kubectl get nodes -o jsonpath='{.items[*].status.allocatable.cpu}' | awk '{sum += $1} END {print sum}')

# 设置所需的 CPU 资源
required_cpu=2

if (( $(echo "$idle_cpu >= $required_cpu" | bc -l) )); then
    kubectl create -f new - deployment.yaml
else
    echo "Not enough idle CPU resources to create the deployment"
fi

在这个脚本中,首先获取集群中所有节点的空闲 CPU 资源总和,然后与所需的 CPU 资源进行比较。如果空闲资源足够,则创建新的 Deployment;否则,打印提示信息。

5.2 批量操作资源

有时候需要对多个资源对象进行相同的操作,例如批量删除所有处于Failed状态的 Pod。

#!/bin/bash

failed_pods=$(kubectl get pods -o jsonpath='{.items[?(@.status.phase=="Failed")].metadata.name}')

for pod in $failed_pods; do
    kubectl delete pod $pod
done

这个脚本通过jsonpath筛选出所有状态为Failed的 Pod 的名称,然后使用for循环逐个删除这些 Pod。

5.3 与其他工具结合使用

Bash 脚本可以与其他工具结合,进一步增强对 Kubernetes 集群的管理能力。例如,与helm结合进行应用的安装和管理。helm是 Kubernetes 的包管理器,类似于 Linux 系统中的aptyum

假设已经安装了helm,并且有一个名为my - chart的 Helm Chart。可以编写如下 Bash 脚本来安装这个 Chart:

#!/bin/bash

# 添加 Helm Chart 仓库
helm repo add my - repo https://my - repo.com/charts

# 更新 Helm Chart 仓库索引
helm repo update

# 安装 Helm Chart
helm install my - release my - repo/my - chart

这个脚本首先添加 Helm Chart 仓库,然后更新仓库索引,最后使用helm install命令安装指定的 Helm Chart,并为这次安装命名为my - release

通过以上高级应用,可以看到 Bash 脚本在 Kubernetes 集群管理中具有很大的灵活性和扩展性,能够满足各种复杂的管理需求。