45、Kubernetes容器操作与高可用集群搭建指南

Kubernetes容器操作与高可用集群搭建指南

1. Kubernetes配置文件格式

Kubernetes支持两种不同的文件格式:YAML和JSON,每种格式都能描述Kubernetes的相同功能。

  • YAML格式 :语法规则较少,简单易懂,便于人类读写。可参考 YAML官方规范 了解更多。以下是使用YAML格式设置nginx pod的示例:
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    name: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80
  • JSON格式 :同样简单易读,更适合程序处理。由于具有数据类型(如数字、字符串、布尔值和对象),在系统间交换数据时很受欢迎。可参考 JSON官方网站 了解更多。以下是与上述YAML格式等效的JSON示例:
{
    "apiVersion": "v1",
    "kind": "Pod",
    "metadata": {
        "name": "nginx",
        "labels": {
            "name": "nginx"
        }
    },
    "spec": {
        "containers": [
            {
                "name": "nginx",
                "image": "nginx",
                "ports": [
                    {
                        "containerPort": 80
                    }
                ]
            }
        ]
    }
}
2. 生成Kubernetes配置文件的Schema

Kubernetes有一个使用配置格式定义的Schema,可通过执行 kubectl create 命令在 /tmp/kubectl.schema/ 目录下生成。以下是具体操作步骤:
1. 创建 pod.json 文件,内容如下:

{
    "apiVersion": "v1",
    "kind": "Pod",
    "metadata": {
        "name": "nginx",
        "labels": {
            "name": "nginx"
        }
    },
    "spec": {
        "containers": [
            {
                "name": "nginx",
                "image": "nginx",
                "ports": [
                    {
                        "containerPort": 80
                    }
                ]
            }
        ]
    }
}
  1. 执行 kubectl create -f pod.json 命令创建pod:
# kubectl create -f pod.json
pod "nginx" created
  1. 查看生成的Schema文件:
# ls -l /tmp/kubectl.schema/v1.1.3/api/v1/schema.json
-rw------- 2 root root 446224 Jan 24 04:50 /tmp/kubectl.schema/v1.1.3/api/v1/schema.json

另外,Kubernetes还使用Swagger(http://swagger.io/)生成REST API,可通过 http://<kubernetes-master>:8080/swagger-ui/ 访问Swagger UI。每个配置(如pods、replication controllers和services)都在POST部分进行描述。

3. 配置文件的必要项

不同类型的配置文件有一些必须定义的项,如下表所示:
| 类型 | 项 | 类型 | 示例 |
| ---- | ---- | ---- | ---- |
| Pods | apiVersion | String | v1 |
| | kind | String | Pod |
| | metadata.name | String | my-nginx |
| | spec | v1.PodSpec | - |
| | v1.PodSpec.containers | array[v1.Container] | - |
| | v1.Container.name | String | my-nginx |
| | v1.Container.image | String | nginx |
| Replication controllers | apiVersion | String | v1 |
| | kind | String | ReplicationController |
| | metadata.name | String | my-nginx-rc |
| | spec | v1.ReplicationControllerSpec | - |
| | v1.ReplicationControllerSpec.template | v1.PodTemplateSpec | - |
| | v1.PodTemplateSpec.metadata.labels | Map of String | app: nginx |
| | v1.PodTemplateSpec.spec | v1.PodSpec | - |
| | v1.PodSpec.containers | array[v1.Container] | 同Pod |
| Services | apiVersion | String | v1 |
| | kind | String | Service |
| | metadata.name | String | my-nginx-service |
| | spec | v1.ServiceSpec | - |
| | v1.ServiceSpec.selector | Map of String | sel: my-selector |
| | v1.ServiceSpec.ports | array[v1.ServicePort] | - |
| | v1.ServicePort.protocol | String | TCP |
| | v1.ServicePort.port | Integer | 80 |

以下是不同类型配置文件的最小配置示例:
- Pod(YAML格式)

apiVersion: v1
kind: Pod
metadata:
  name: my-nginx
spec:
  containers:
  - name: my-nginx
    image: nginx
  • Replication Controller(YAML格式)
apiVersion: v1
kind: ReplicationController
metadata:
  name: my-nginx-rc
spec:
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: my-nginx
        image: nginx
  • Service(YAML格式)
apiVersion: v1
kind: Service
metadata:
  name: my-nginx
spec:
  selector:
    sel: my-selector
  ports:
    - protocol: TCP
      port: 80
4. etcd集群搭建

etcd在Kubernetes中存储网络信息和状态,数据丢失可能会导致严重后果,因此强烈建议对etcd进行集群化。etcd支持集群,N个成员的集群最多可容忍(N - 1) / 2个成员故障。创建etcd集群有三种机制:静态、etcd发现和DNS发现。这里主要讨论静态和etcd发现两种方式。

4.1 准备工作

在开始构建etcd集群之前,需要确定成员数量。在生产环境中,建议至少使用三个成员,这样集群可以容忍至少一个永久故障。以下是开发环境中使用三个成员的示例:
| 名称/主机名 | IP地址 |
| ---- | ---- |
| ip-172-31-0-1 | 172.31.0.1 |
| ip-172-31-0-2 | 172.31.0.2 |
| ip-172-31-0-3 | 172.31.0.3 |

4.2 静态方式

静态方式是设置集群最简单的方法,但需要事先知道每个成员的IP地址。使用静态方式时,需要了解以下参数的含义:
| 参数 | 含义 |
| ---- | ---- |
| -name | 成员名称 |
| -initial-advertise-peer-urls | 用于与其他成员建立对等连接,应与 -initial-cluster 中列出的一致 |
| -listen-peer-urls | 接受对等流量的URL |
| -listen-client-urls | 接受客户端流量的URL |
| -advertise-client-urls | etcd成员用于向其他成员通告的URL |
| -initial-cluster-token | 用于区分不同集群的唯一令牌 |
| -initial-cluster | 所有成员通告的对等URL |
| -initial-cluster-state | 指定初始集群的状态 |

以下是在每个成员上使用 etcd 命令行工具引导集群的示例:

# 在主机ip-172-31-0-1上
# etcd -name ip-172-31-0-1 \
       -initial-advertise-peer-urls http://172.31.0.1:2380 \
       -listen-peer-urls http://172.31.0.1:2380 \
       -listen-client-urls http://0.0.0.0:2379 \
       -advertise-client-urls http://172.31.0.1:2379 \
       -initial-cluster-token mytoken \
       -initial-cluster ip-172-31-0-1=http://172.31.0.1:2380,ip-172-31-0-2=http://172.31.0.2:2380,ip-172-31-0-3=http://172.31.0.3:2380 \
       -initial-cluster-state new

依次在其他成员上执行类似命令,启动所有成员后,etcd集群将完成初始化,并进行领导者选举。etcd集群会向成员发送心跳以检查健康状态。如果需要添加或删除成员,需要在所有成员上重新运行 etcd 命令以通知集群有新成员加入。

4.3 etcd发现方式

使用etcd发现方式之前,需要有一个用于引导集群的发现URL。如果要添加或删除成员,可以使用 etcdctl 命令进行运行时重新配置。具体步骤如下:
1. 从etcd发现服务请求一个发现URL:

# curl -w "\n" 'https://discovery.etcd.io/new?size=3'
https://discovery.etcd.io/be7c1938bbde83358d8ae978895908bd
  1. 使用请求到的URL初始化集群:
# etcd -name ip-172-31-0-1 -initial-advertise-peer-urls http://172.31.43.209:2380 \
 -listen-peer-urls http://172.31.0.1:2380 \
 -listen-client-urls http://0.0.0.0:2379 \
 -advertise-client-urls http://172.31.0.1:2379 \
 -discovery https://discovery.etcd.io/be7c1938bbde83358d8ae978895908bd

依次在其他成员上执行类似命令,新节点加入后,etcd会进行新的选举,确保服务始终在线。

5. 多主节点Kubernetes系统搭建

主节点是Kubernetes系统的核心组件,负责从数据存储和etcd服务器推送和拉取信息、作为请求的门户、向节点分配任务以及监控运行任务等。单主节点系统存在单点故障风险,而多主节点Kubernetes系统不仅具有容错能力,还能实现负载均衡。

5.1 准备工作

构建多主节点系统的简要概念如下:
- 在主节点前添加负载均衡服务器,作为节点和客户端访问的新端点。
- 每个主节点运行自己的API服务器守护进程。
- 系统中仅存在一个调度器和一个控制器管理器,以避免在管理容器时不同守护进程发出冲突指令。
- 在每个主节点安装 pod master 守护进程,通过选举决定运行调度器和控制器管理器的主节点,这两个守护进程可以运行在同一个主节点上。
- 以容器方式运行调度器和控制器管理器,在主节点安装 kubelet ,并通过配置文件将守护进程作为pod进行管理。

5.2 操作步骤

以下是构建双主节点系统的详细步骤:
1. 准备多个主节点 :在现有的Kubernetes系统中安装另一个主节点,确保其与原主节点环境相同。然后停止两个主节点上的调度器和控制器管理器守护进程:
- 对于systemd控制的系统,直接使用以下命令停止服务:

systemctl kube-scheduler stop
systemctl kube-controller-manager stop
- 对于init服务控制的系统,先停止主服务,然后在初始化脚本中删除或注释掉关于调度器和控制器管理器的行:
# service kubernetes-master status
kube-apiserver (pid 3137) is running...
kube-scheduler (pid 3138) is running...
kube-controller-manager (pid 3136) is running...
# service kubernetes-master stop
Shutting down /usr/local/bin/kube-controller-manager:      [  OK  ]
Shutting down /usr/local/bin/kube-scheduler:               [  OK  ]
Shutting down /usr/local/bin/kube-apiserver:               [  OK  ]

修改初始化脚本后,重新启动主服务:

# service kubernetes-master start
Starting apiserver:
  1. 在主节点设置kubelet :由于要将调度器和控制器管理器守护进程作为pod安装,因此需要在主节点安装 kubelet 进程。可以从以下链接下载最新版本(1.1.4)的 kubelet 二进制文件:
# wget https://storage.googleapis.com/kubernetes-release/release/v1.1.4/bin/linux/amd64/kubelet
# chmod 755 kubelet
# mv kubelet /usr/local/bin/

对于RHEL系统,也可以从YUM仓库下载:

# yum install kubernetes-node

配置 kubelet 守护进程的参数如下:
| 标签名称 | 值 | 用途 |
| ---- | ---- | ---- |
| –api-servers | 127.0.0.1:8080 | 与本地API服务器通信 |
| –register-node | false | 避免将本地主机作为节点注册 |
| –allow-privileged | true | 允许容器请求特权模式,使其能够访问主机设备,特别是网络设备 |
| –config | /etc/kubernetes/manifests | 通过指定目录下的模板文件管理本地容器 |

根据系统使用的服务管理方式,将参数配置到相应的配置文件中。配置完成后,可暂时保持 kubelet 服务停止状态,待调度器和控制器管理器的配置文件准备好后再启动。
3. 准备配置文件 :需要三个模板作为配置文件: pod master 、调度器和控制器管理器。这些文件应放置在指定位置。
- pod master模板 :用于选举决定哪个主节点运行调度器和控制器管理器守护进程,并将结果记录在etcd服务器中。模板文件 /etc/kubernetes/manifests/podmaster.yaml 内容如下:

apiVersion: v1
kind: Pod
metadata:
  name: podmaster
  namespace: kube-system
spec:
  hostNetwork: true
  containers:
  - name: scheduler-elector
    image: gcr.io/google_containers/podmaster:1.1
    command: ["/podmaster", "--etcd-servers=<ETCD_ENDPOINT>", "--key=scheduler", "--source-file=/kubernetes/kube-scheduler.yaml", "--dest-file=/manifests/kube-scheduler.yaml"]
    volumeMounts:
    - mountPath: /kubernetes
      name: k8s
      readOnly: true
    - mountPath: /manifests
      name: manifests
  - name: controller-manager-elector
    image: gcr.io/google_containers/podmaster:1.1
    command: ["/podmaster", "--etcd-servers=<ETCD_ENDPOINT>", "--key=controller", "--source-file=/kubernetes/kube-controller-manager.yaml", "--dest-file=/manifests/kube-controller-manager.yaml"]
    terminationMessagePath: /dev/termination-log
    volumeMounts:
    - mountPath: /kubernetes
      name: k8s
      readOnly: true
    - mountPath: /manifests
      name: manifests
  volumes:
  - hostPath:
      path: /srv/kubernetes
    name: k8s
  - hostPath:
      path: /etc/kubernetes/manifests
    name: manifests
- **调度器模板**:`/srv/kubernetes/kube-scheduler.yaml`内容如下:
apiVersion: v1
kind: Pod
metadata:
  name: kube-scheduler
  namespace: kube-system
spec:
  hostNetwork: true
  containers:
  - name: kube-scheduler
    image: gcr.io/google_containers/kube-scheduler:34d0b8f8b31e27937327961528739bc9
    command:
    - /bin/sh
    - -c
    - /usr/local/bin/kube-scheduler --master=127.0.0.1:8080 --v=2 1>>/var/log/kube-scheduler.log 2>&1
    livenessProbe:
      httpGet:
        path: /healthz
        port: 10251
      initialDelaySeconds: 15
      timeoutSeconds: 1
    volumeMounts:
    - mountPath: /var/log/kube-scheduler.log
      name: logfile
    - mountPath: /usr/local/bin/kube-scheduler
      name: binfile
  volumes:
  - hostPath:
      path: /var/log/kube-scheduler.log
    name: logfile
  - hostPath:
      path: /usr/local/bin/kube-scheduler
    name: binfile
- **控制器管理器模板**:`/srv/kubernetes/kube-controller-manager.yaml`内容如下:
apiVersion: v1
kind: Pod
metadata:
  name: kube-controller-manager
  namespace: kube-system
spec:
  containers:
  - command:
    - /bin/sh
    - -c
    - /usr/local/bin/kube-controller-manager --master=127.0.0.1:8080 --cluster-cidr=<KUBERNETES_SYSTEM_CIDR> --allocate-node-cidrs=true --v=2 1>>/var/log/kube-controller-manager.log 2>&1
    image: gcr.io/google_containers/kube-controller-manager:fda24638d51a48baa13c35337fcd4793
    livenessProbe:
      httpGet:
        path: /healthz
        port: 10252
      initialDelaySeconds: 15
      timeoutSeconds: 1
    name: kube-controller-manager
    volumeMounts:
    - mountPath: /srv/kubernetes
      name: srvkube
      readOnly: true
    - mountPath: /var/log/kube-controller-manager.log
      name: logfile
    - mountPath: /usr/local/bin/kube-controller-manager
      name: binfile
  hostNetwork: true
  volumes:
  - hostPath:
      path: /srv/kubernetes
    name: srvkube
  - hostPath:
      path: /var/log/kube-controller-manager.log
    name: logfile
  - hostPath:
      path: /usr/local/bin/kube-controller-manager
    name: binfile

在启动 pod master 之前,还需要进行一些预配置:
- 创建空的日志文件:

# touch /var/log/kube-scheduler.log
# touch /var/log/kube-controller-manager.log
- 创建新的命名空间:
# kubectl create namespace kube-system
# 或者
# curl -XPOST -d'{"apiVersion":"v1","kind":"Namespace","metadata":{"name":"kube-system"}}' "http://127.0.0.1:8080/api/v1/namespaces"
  1. 启动kubelet服务并开启守护进程 :在启动 kubelet 之前,确保已经启动了Docker和flanneld服务。然后在每个主节点上启动 kubelet 服务:
# service kubelet start

等待一段时间后,每个主节点上会运行一个 pod master ,最终会得到一对调度器和控制器管理器:

# kubectl get pod --namespace=kube-system
NAME                                   READY     STATUS    RESTARTS   AGE
kube-controller-manager-kube-master1   1/1       Running   0          3m
kube-scheduler-kube-master2            1/1       Running   0          3m
podmaster-kube-master1                 2/2       Running   0          1m
podmaster-kube-master2                 2/2       Running   0          1m
5.3 工作原理

通过查看 pod master 容器的日志,可以得到两种类型的消息,一种表明持有密钥,另一种表明未持有密钥。持有密钥的主节点将负责运行特定的守护进程(调度器或控制器管理器)。当前主节点的高可用性解决方案是通过etcd中的租约锁方法实现的。该方法有两个重要的时间周期: SLEEP (检查锁的周期)和 Time to Live (TTL) (租约过期的周期)。如果运行守护进程的主节点崩溃,另一个主节点接管其工作的最坏情况时间为 SLEEP + TTL ,默认情况下, SLEEP 为5秒, TTL 为30秒。

总结

本文详细介绍了Kubernetes中容器操作、配置文件使用、etcd集群搭建以及多主节点系统构建的相关知识和操作步骤。通过合理运用这些技术,可以提高Kubernetes系统的可用性和性能,避免单点故障带来的风险。希望这些内容对您在Kubernetes的实践中有所帮助。

Kubernetes容器操作与高可用集群搭建指南

6. 整体流程总结

为了更清晰地展示从容器操作到高可用集群搭建的整个过程,我们可以用以下mermaid流程图来表示:

graph LR
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px

    A(选择配置文件格式):::process --> B(生成配置文件Schema):::process
    B --> C(确定配置文件必要项):::process
    C --> D(搭建etcd集群):::process
    D --> E(选择搭建方式):::process
    E --> E1(静态方式):::process
    E --> E2(etcd发现方式):::process
    D --> F(搭建多主节点Kubernetes系统):::process
    F --> F1(准备多个主节点):::process
    F --> F2(设置kubelet):::process
    F --> F3(准备配置文件):::process
    F --> F4(启动kubelet服务):::process

这个流程图展示了整个操作的先后顺序,从基础的配置文件操作开始,逐步进行etcd集群搭建,最后完成多主节点Kubernetes系统的搭建。

7. 常见问题及解决方法

在实际操作过程中,可能会遇到一些常见问题,以下是一些问题及对应的解决方法:

问题描述 可能原因 解决方法
etcd集群启动时出现连接拒绝错误 其他成员节点未启动或网络配置问题 检查其他成员节点是否启动,确保网络配置正确,防火墙是否允许相应端口通信
kubelet服务无法启动 配置文件参数错误或依赖服务未启动 检查kubelet配置文件参数是否正确,确保Docker和flanneld服务已启动
pod创建失败 配置文件格式错误或命名空间未创建 检查配置文件格式是否正确,确保已创建所需的命名空间
8. 性能优化建议

为了提高Kubernetes系统的性能和稳定性,可以考虑以下优化建议:
- 合理规划etcd集群规模 :根据实际业务需求和数据量,合理确定etcd集群的成员数量,以提高集群的容错能力和性能。
- 负载均衡配置 :在多主节点系统中,确保负载均衡器的配置合理,能够均匀分配请求,避免单个主节点负载过高。
- 资源监控与调整 :定期监控系统资源使用情况,如CPU、内存、网络等,根据监控结果调整容器和节点的资源分配。

9. 未来发展趋势

随着云计算和容器技术的不断发展,Kubernetes作为容器编排的主流工具,也在不断演进。未来可能会出现以下发展趋势:
- 更强大的自动化功能 :Kubernetes将进一步增强自动化能力,如自动伸缩、自动故障恢复等,减少人工干预。
- 与其他技术的深度融合 :与人工智能、机器学习等技术深度融合,实现更智能的资源调度和管理。
- 安全性能提升 :加强安全机制,如身份认证、数据加密等,保障系统的安全性。

10. 总结与展望

通过本文的介绍,我们详细了解了Kubernetes中容器操作、配置文件使用、etcd集群搭建以及多主节点系统构建的相关知识和操作步骤。这些技术的合理运用可以有效提高Kubernetes系统的可用性和性能,避免单点故障带来的风险。

在实际应用中,我们可以根据具体的业务需求和环境,灵活选择合适的技术和方法。同时,关注Kubernetes的未来发展趋势,不断学习和掌握新的技术,将有助于我们更好地应对各种挑战,构建更加稳定、高效的云计算环境。希望本文能为您在Kubernetes的实践中提供有价值的参考。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值