
一、Kubernetes 简介及部署方法一基础知识1.应用部署方式演变在部署应用程序的方式上主要经历了三个阶段阶段描述优点缺点传统部署直接部署在物理机上简单不需要其它技术的参与不能为应用程序定义资源使用边界很难合理地分配计算资源而且程序之间容易产生影响虚拟化部署在物理机上运行多个独立虚拟机程序环境不会相互产生影响提供了一定程度的安全性增加了操作系统浪费了部分资源容器化部署共享操作系统轻量隔离高效、快速启动需解决故障恢复、弹性伸缩等问题2.容器编排工具应用为应对容器化带来的管理挑战主流编排工具包括SwarmDocker 原生编排工具MesosApache 资源管控组合KubernetesGoogle 开源成为事实标准3.kubernetes 简介1Borg 奠定基础Kubernetes 脱胎于 Google 内部运行多年的 Borg 系统后者已在数以万计的容器应用管理中验证了大规模调度、资源隔离和自动恢复等能力。2继承与革新但 Borg 作为内部系统存在配置复杂、扩展性差、绑定内部基础设施等缺陷。Kubernetes 并非简单复制 Borg而是在其设计思想基础上进行了现代化重构——采用声明式 API、插件化架构CRI/CNI/CSI并将管理粒度从容器提升到 Pod。3核心创新Pod 作为最小部署单元允许将多个容器组合为一个逻辑整体如 Sidecar 模式使 Kubernetes 管理的对象从零散容器升维为完整应用服务。4核心理念用户只需声明期望状态副本数、资源、访问方式等Kubernetes 自动完成调度、部署、自愈、滚动更新和弹性伸缩。将底层复杂性屏蔽于平台之内将简洁体验留给用户这正是 Kubernetes 成为云原生时代基础设施标准的核心原因。5功能特点功能作用自我修复一旦某一个容器崩溃能够在1秒中左右迅速启动新的容器弹性伸缩可以根据需要自动对集群中正在运行的容器数量进行调整服务发现服务可以通过自动发现的形式找到它所依赖的服务负载均衡如果一个服务起动了多个容器能够自动实现请求的负载均衡版本回退如果发现新发布的程序版本有问题可以立即回退到原来的版本存储编排可以根据容器自身的需求自动创建存储卷4.K8S 的设计架构1各个组件用途一个kubernetes集群主要是由控制节点(master)、工作节点(node)构成每个节点上都会安装不同的组件各司其职共同完成集群的调度、运行与管理。master 节点集群的控制平面负责集群决策组件名称核心职责补充说明ApiServer资源操作的唯一入口接收用户命令提供认证、授权、API 注册与发现所有 kubectl 请求均先经过它是集群的前台Scheduler负责将 Pod 调度到合适的 Node 节点通过预选和优选算法综合资源、亲和性等因素决策ControllerManager维护集群状态管理部署、故障检测、自动扩缩容、滚动更新等运行 Deployment、ReplicaSet、Node 等多种控制器Etcd存储集群中所有资源对象的信息键值数据库基于 Raft 协议保证数据一致性需定期备份node 节点集群的数据平面负责为容器提供运行环境组件名称核心职责补充说明kubelet管理容器生命周期同时负责存储CSI和网络CNI的接入每个 Node 必装是 Node 上的管家Container runtime负责镜像管理和 Pod 中容器的真正运行通过 CRI 接口对接常见实现有 containerd、CRI-Okube-proxy为 Service 提供集群内部的服务发现和负载均衡通过维护 iptables/IPVS 规则实现流量转发2各组件之间的调用关系当我们要运行一个 Web 服务时各组件按照以下流程协同工作集群启动后Master 和 Node 各自将自身信息注册到 Etcd 数据库中。当用户提交 Web 服务部署请求时请求首先到达 Master 节点的 ApiServer 组件ApiServer 作为集群唯一入口完成认证和准入控制后调用 Scheduler 组件进行 Pod 选址Scheduler 从 Etcd 中读取各 Node 的资源信息通过预选和优选算法选择合适的 Node并将选址结果返回给 ApiServer。随后 ApiServer 调用 ControllerManager 将部署指令下发至目标 Node。目标 Node 上的 kubelet 接收到指令后通知容器运行时如 Docker/containerd拉取镜像并启动 Web 服务的 Pod。Pod 运行后kube-proxy 为 Pod 生成访问代理通过维护 iptables/IPVS 规则实现服务发现和负载均衡使得集群内外可通过 Service 名称访问该 Web 服务。3常用名词观念master集群的控制节点负责集群的管控和决策。每个集群至少需要一个 Master 节点生产环境中通常部署多个以实现高可用。node工作负载节点由 Master 统一管理和分配容器任务。Node 上运行着 kubelet 和容器运行时负责执行 Master 下发的指令并报告自身状态。podKubernetes 的最小部署和调度单元容器均运行在 Pod 之中。一个 Pod 可以包含一个或多个容器这些容器共享网络命名空间、存储卷和生命周期通常将密切协作的容器如主容器与辅助容器部署在同一 Pod 中。controller控制器用于实现对 Pod 的生命周期管理包括启动、停止、重启、滚动更新和弹性伸缩等操作。常见的 Controller 有 Deployment无状态应用、StatefulSet有状态应用、DaemonSet每个节点运行一个和 Job/CronJob任务型等。servicePod 对外服务的统一访问入口。由于 Pod 的 IP 地址是动态变化的Service 通过标签选择器关联一组同类的 Pod为其提供固定的访问地址和负载均衡能力。label标签本质是一组键值对用于对资源如 Pod进行分类和筛选。用户通过 Label 来识别和管理一组具有相同标签的资源是 Service 和 Controller 选择 Pod 的依据。namespace命名空间用于将集群内的资源进行逻辑隔离。不同 Namespace 中的资源名称可以相同互不干扰常用于区分开发、测试、生产环境或多个团队的资源并可结合 ResourceQuota 进行资源配额管理。4分层架构核心层Kubernetes 最基础的功能层对外提供 API 以便构建上层应用对内提供插件式的应用执行环境是整个系统的基石。应用层负责各类工作负载的部署包括无状态应用、有状态应用、批处理任务、集群应用等和路由服务发现、DNS 解析等。管理层提供系统度量基础设施、容器和网络的监控指标、自动化能力自动扩缩容、动态存储 Provision 等以及策略管理RBAC 权限、ResourceQuota 资源配额、PodSecurityPolicy 安全策略、NetworkPolicy 网络策略等。接口层为用户和外部系统提供交互方式包括 kubectl 命令行工具、各类客户端 SDK 以及集群联邦Federation能力。生态系统在接口层之上构建的庞大容器集群管理调度生态可划分为两个范畴Kubernetes 外部生态日志、监控、配置管理、CI/CD、Workflow、FaaS、OTS 应用、ChatOps 等和 Kubernetes 内部生态CRI 容器运行时接口、CNI 容器网络接口、CSI 容器存储接口、镜像仓库、Cloud Provider 云服务商集成、集群自身的配置和管理等。二K8S集群环境搭建1.K8S 中容器的管理方式Kubernetes 通过容器运行时接口CRIContainer Runtime Interface来管理容器支持多种容器运行时作为底层实现。目前主流的容器管理方式有以下三种管理方式说明containerdKubernetes 默认使用的容器运行时方式。在创建集群时无需额外配置K8S 会直接使用 containerd 来管理和运行容器。containerd 是 Docker 底层的核心组件轻量且高效是目前最推荐的运行时。Docker早期使用最广泛的容器运行时。Kubernetes 在 1.24 版本后已移除对 Docker 作为底层运行时的原生支持废弃了 kubelet 中的 Docker 驱动但用户仍可借助 cri-docker 这个适配器来继续使用 Docker 创建集群。CRI-O专门为 Kubernetes 设计的轻量级容器运行时直接实现 CRI 接口无需额外适配层是 Kubernetes 创建容器最直接的方式之一。使用时需在创建集群时安装 CRI-O 插件并对 kubelet 的启动参数进行配置。注意使用 Docker 和 CRI-O 这两种方式时都需要对 kubelet 程序的启动参数进行额外设置以指定所使用的运行时类型和连接方式而 containerd 作为默认选项通常无需额外配置即可直接使用。2.构建 habor 镜像仓库1部署 docker 本地仓库创建一台 harbor 主机进行以下操作卸载系统中的 Podman因为 Kubernetes 用的是 containerd 或 Docker 作为容器引擎而 Podman 是另一套容器工具和它们可能产生冲突。所以安装 K8s 环境之前先把自带的 Podman 删掉避免后续部署出问题。搭建 Harbor 镜像仓库的 Web 访问基础环境添加 Docker 的 yum 软件源下载 docker 的所有软件包将下载好的 Docker RPM 包集中到 HTTP 目录并安装 createrepo 工具目的是搭建本地 yum 源供内网其他主机通过 HTTP 访问和安装 Docker在该目录下生成 repodata 子目录其中包含仓库索引和依赖关系信息安装docker2安装 docker 在 harbor 仓库节点加载 Linux 内核模块并将该配置持久化确保系统重启后依然生效。重新加载配置定义 docker 的启动方式和参数让 Docker 通过 containerd 来运行容器并启用 iptables 管理网络规则重新加载 systemd 配置并启动 Docker 服务同时设置为开机自启3生成key4编辑 harbor 配置文件解压 harbor 安装包修改域名、证书、密码等参数执行 Harbor 安装脚本并启用 ChartMuseum 组件用于存储和管理 Helm Chart 包解决端口占用问题写启动脚本5启动并验证3.所有主机配置1所需主机主机名ip角色harbor172.168.75.254harbor仓库k8s-master172.168.75.100masterk8s集群控制节点k8s-node1172.168.75.10workerk8s集群工作节点k8s-node2172.168.75.20workerk8s集群工作节点2关闭 swap将三个节点的主机名分别映射到对应的 IP 地址确保它们之间互通成功3安装 docker在 harbor 主机中分发证书到所有主机所有主机配置 docker 加速器所有主机配置 kubernetes 安装源检测重启三台主机检查 swap 关了没4.利用 Ansible 构建部署 kubernetes1配置 epel 源安装 ansible2配置所需用户3生成 ansible 的临时配置文件并建立运行环境建立用户4生成 ansible 的主配置文件并测试5利用 ansible 剧本部署 docker- name: devops k8s from ansiblehosts: alltasks:- name: setup docker repoyum_repository:name: dockerdescription: dockerbaseurl: http://172.168.75.254:4444/dockerfile: dockergpgcheck: no- name: install dockerdnf:name: docker-cestate: present- name: setup docker.servicereplace:path: /lib/systemd/system/docker.serviceregexp: ExecStart/usr/bin/dockerd -H fd:// --containerd/run/containerd/containerd.sockreplace: ExecStart/usr/bin/dockerd -H fd:// --containerd/run/containerd/containerd.sock --iptablestrue- name: ensure docker directory existsfile:path: /etc/dockerstate: directorymode: 0755- name: setup docker registrycopy:content: |{registry-mirrors:[https://reg.lyy.org]}dest: /etc/docker/daemon.json- name: setup docker certsfile:path: /etc/docker/certs.d/reg.lyy.orgstate: directory- name: cp certs filecopy:src: {{ item.src }}dest: {{ item.dest }}loop:- src: /etc/docker/certs.d/reg.lyy.org/ca.crtdest: /etc/docker/certs.d/reg.lyy.org/ca.crt- src: /etc/docker/certs.d/reg.lyy.org/ca.crtdest: /etc/pki/ca-trust/source/anchors/ca.crt- name: load modulecopy:dest: {{ item.dest }}content: {{ item.value }}loop:- dest: /etc/modules-load.d/docker_mod.confvalue: br_netfilter- dest: /etc/sysctl.d/docker.confvalue: |net.bridge.bridge-nf-call-iptables 1net.bridge.bridge-nf-call-ip6tables 1net.ipv4.ip_forward 1- name: update ca certshell: update-ca-trust extract;sysctl --system- name: start servicesservice:name: {{ item }}state: restartedenabled: yesloop:- docker- systemd-modules-load.service6利用 ansible 安装 cri-dockerd新增加内容- name: stup cri-dockerdcopy:src: {{item.src}}dest: {{item.dest}}mode: 0755loop:- src: ./cri-dockerd/cri-dockerddest: /usr/bin/cri-dockerd- src: ./cri-dockerd/cri-docker.servicedest: /lib/systemd/system/cri-docker.service- src: ./cri-dockerd/cri-docker.socketdest: /lib/systemd/system/cri-docker.socket- name: update ca certshell: update-ca-trust extract;sysctl --system;systemctl daemon-reload- name: start servicesservice:name: {{item}}state: restartedenabled: yesloop:- docker- systemd-modules-load.service- cri-docker7利用 ansible 部署 k8s 软件- name: install kubernetes from ansiblehosts: alltasks:- name: setup k8s repoyum_repository:name: kubernetesdescription: kubernetesbaseurl: https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.35/rpmfile: kubernetesgpgcheck: no- name: install software in masterdnf:name: {{item}}state: presentloop:- kubeadm-1.35.7-150500.1.1- kubelet-1.35.7-150500.1.1- kubectl-1.35.7-150500.1.1when: inventory_hostname 172.168.75.100- name: install software in work nodednf:name: {{item}}state: presentloop:- kubeadm-1.35.7-150500.1.1- kubelet-1.35.7-150500.1.1when: inventory_hostname 172.168.75.10 or inventory_hostname 172.168.75.20- name: setup kubectl kubeadm complicationlineinfile:path: /root/.bashrcline: |source (kubectl completion bash)source (kubeadm completion bash)when: inventory_hostname 172.168.75.100- name: start kubeletservice:name: kubeletstate: startedenabled: yes让补齐功能生效kubectl 命令后按2次 tab 键5.下载 kubernetes 集群所需镜像1查看镜像2下载镜像3上传镜像到本地 harbor6.在 master 中初始化 kubernetes 集群1在 master 中完成集群初始化其他主机加入本集群的凭证如果忘记可以输入以下命令去查看如果初始化出问题可输入kubeadm reset --cri-socketunix:///var/run/cri-dockerd.sock 重置集群设定2添加 kubernets 环境变量到本机3添加 node 节点到本集群测试4安装网络插件测试