Kubernetes容器编排解决方案【基础篇】
-author: liuchao
-email: mirs_chao@163.com
-gitee: https://gitee.com/mirschao
### 文章目录
- [Kubernetes容器编排解决方案【基础篇】](#文章目录 Kubernetes容器编排解决方案【基础篇】 @[toc] 1. kubernetes简要概述 1.1 kubernetes 功能简介 1.2 Kubernetes架构及组件 2. Kubernetes 集群部署 2.1 测试环境集群部署 2.2 生产环境集群部署 2.3 增加worker节点 2.4 部署dashboard 3. Kubernetes基础资源 3.1 k8s中的资源层级关系及管理 3.2 k8s中的Pod 3.2.1 单容器 Pod 3.2.2 多容器 Pod 3.2.3 共享数据卷 3.2.4 容器探针 3.2.5 资源限额 3.3 k8s中的Deployment 3.4 k8s中的DaemonSet 3.5 k8s中的CronJob、Job 3.6 k8s中的Service 3.7 k8s中的ingress 3.8 k8s中的ConfigMap、Secret 3.9 k8s中的StorageClass 3.9.1 nfs共享卷 3.9.2 glusterfs共享卷 3.10 k8s中的StatefulSet 3.11 k8s中的serviceaccount 4. Kubernetes错误排查导向图)
- [@[toc]](#文章目录 Kubernetes容器编排解决方案【基础篇】 @[toc] 1. kubernetes简要概述 1.1 kubernetes 功能简介 1.2 Kubernetes架构及组件 2. Kubernetes 集群部署 2.1 测试环境集群部署 2.2 生产环境集群部署 2.3 增加worker节点 2.4 部署dashboard 3. Kubernetes基础资源 3.1 k8s中的资源层级关系及管理 3.2 k8s中的Pod 3.2.1 单容器 Pod 3.2.2 多容器 Pod 3.2.3 共享数据卷 3.2.4 容器探针 3.2.5 资源限额 3.3 k8s中的Deployment 3.4 k8s中的DaemonSet 3.5 k8s中的CronJob、Job 3.6 k8s中的Service 3.7 k8s中的ingress 3.8 k8s中的ConfigMap、Secret 3.9 k8s中的StorageClass 3.9.1 nfs共享卷 3.9.2 glusterfs共享卷 3.10 k8s中的StatefulSet 3.11 k8s中的serviceaccount 4. Kubernetes错误排查导向图)
- [1. kubernetes简要概述](#文章目录 Kubernetes容器编排解决方案【基础篇】 @[toc] 1. kubernetes简要概述 1.1 kubernetes 功能简介 1.2 Kubernetes架构及组件 2. Kubernetes 集群部署 2.1 测试环境集群部署 2.2 生产环境集群部署 2.3 增加worker节点 2.4 部署dashboard 3. Kubernetes基础资源 3.1 k8s中的资源层级关系及管理 3.2 k8s中的Pod 3.2.1 单容器 Pod 3.2.2 多容器 Pod 3.2.3 共享数据卷 3.2.4 容器探针 3.2.5 资源限额 3.3 k8s中的Deployment 3.4 k8s中的DaemonSet 3.5 k8s中的CronJob、Job 3.6 k8s中的Service 3.7 k8s中的ingress 3.8 k8s中的ConfigMap、Secret 3.9 k8s中的StorageClass 3.9.1 nfs共享卷 3.9.2 glusterfs共享卷 3.10 k8s中的StatefulSet 3.11 k8s中的serviceaccount 4. Kubernetes错误排查导向图)
- [1.1 kubernetes 功能简介](#文章目录 Kubernetes容器编排解决方案【基础篇】 @[toc] 1. kubernetes简要概述 1.1 kubernetes 功能简介 1.2 Kubernetes架构及组件 2. Kubernetes 集群部署 2.1 测试环境集群部署 2.2 生产环境集群部署 2.3 增加worker节点 2.4 部署dashboard 3. Kubernetes基础资源 3.1 k8s中的资源层级关系及管理 3.2 k8s中的Pod 3.2.1 单容器 Pod 3.2.2 多容器 Pod 3.2.3 共享数据卷 3.2.4 容器探针 3.2.5 资源限额 3.3 k8s中的Deployment 3.4 k8s中的DaemonSet 3.5 k8s中的CronJob、Job 3.6 k8s中的Service 3.7 k8s中的ingress 3.8 k8s中的ConfigMap、Secret 3.9 k8s中的StorageClass 3.9.1 nfs共享卷 3.9.2 glusterfs共享卷 3.10 k8s中的StatefulSet 3.11 k8s中的serviceaccount 4. Kubernetes错误排查导向图)
- [1.2 Kubernetes架构及组件](#文章目录 Kubernetes容器编排解决方案【基础篇】 @[toc] 1. kubernetes简要概述 1.1 kubernetes 功能简介 1.2 Kubernetes架构及组件 2. Kubernetes 集群部署 2.1 测试环境集群部署 2.2 生产环境集群部署 2.3 增加worker节点 2.4 部署dashboard 3. Kubernetes基础资源 3.1 k8s中的资源层级关系及管理 3.2 k8s中的Pod 3.2.1 单容器 Pod 3.2.2 多容器 Pod 3.2.3 共享数据卷 3.2.4 容器探针 3.2.5 资源限额 3.3 k8s中的Deployment 3.4 k8s中的DaemonSet 3.5 k8s中的CronJob、Job 3.6 k8s中的Service 3.7 k8s中的ingress 3.8 k8s中的ConfigMap、Secret 3.9 k8s中的StorageClass 3.9.1 nfs共享卷 3.9.2 glusterfs共享卷 3.10 k8s中的StatefulSet 3.11 k8s中的serviceaccount 4. Kubernetes错误排查导向图)
- [2. Kubernetes 集群部署](#文章目录 Kubernetes容器编排解决方案【基础篇】 @[toc] 1. kubernetes简要概述 1.1 kubernetes 功能简介 1.2 Kubernetes架构及组件 2. Kubernetes 集群部署 2.1 测试环境集群部署 2.2 生产环境集群部署 2.3 增加worker节点 2.4 部署dashboard 3. Kubernetes基础资源 3.1 k8s中的资源层级关系及管理 3.2 k8s中的Pod 3.2.1 单容器 Pod 3.2.2 多容器 Pod 3.2.3 共享数据卷 3.2.4 容器探针 3.2.5 资源限额 3.3 k8s中的Deployment 3.4 k8s中的DaemonSet 3.5 k8s中的CronJob、Job 3.6 k8s中的Service 3.7 k8s中的ingress 3.8 k8s中的ConfigMap、Secret 3.9 k8s中的StorageClass 3.9.1 nfs共享卷 3.9.2 glusterfs共享卷 3.10 k8s中的StatefulSet 3.11 k8s中的serviceaccount 4. Kubernetes错误排查导向图)
- [2.1 测试环境集群部署](#文章目录 Kubernetes容器编排解决方案【基础篇】 @[toc] 1. kubernetes简要概述 1.1 kubernetes 功能简介 1.2 Kubernetes架构及组件 2. Kubernetes 集群部署 2.1 测试环境集群部署 2.2 生产环境集群部署 2.3 增加worker节点 2.4 部署dashboard 3. Kubernetes基础资源 3.1 k8s中的资源层级关系及管理 3.2 k8s中的Pod 3.2.1 单容器 Pod 3.2.2 多容器 Pod 3.2.3 共享数据卷 3.2.4 容器探针 3.2.5 资源限额 3.3 k8s中的Deployment 3.4 k8s中的DaemonSet 3.5 k8s中的CronJob、Job 3.6 k8s中的Service 3.7 k8s中的ingress 3.8 k8s中的ConfigMap、Secret 3.9 k8s中的StorageClass 3.9.1 nfs共享卷 3.9.2 glusterfs共享卷 3.10 k8s中的StatefulSet 3.11 k8s中的serviceaccount 4. Kubernetes错误排查导向图)
- [2.2 生产环境集群部署](#文章目录 Kubernetes容器编排解决方案【基础篇】 @[toc] 1. kubernetes简要概述 1.1 kubernetes 功能简介 1.2 Kubernetes架构及组件 2. Kubernetes 集群部署 2.1 测试环境集群部署 2.2 生产环境集群部署 2.3 增加worker节点 2.4 部署dashboard 3. Kubernetes基础资源 3.1 k8s中的资源层级关系及管理 3.2 k8s中的Pod 3.2.1 单容器 Pod 3.2.2 多容器 Pod 3.2.3 共享数据卷 3.2.4 容器探针 3.2.5 资源限额 3.3 k8s中的Deployment 3.4 k8s中的DaemonSet 3.5 k8s中的CronJob、Job 3.6 k8s中的Service 3.7 k8s中的ingress 3.8 k8s中的ConfigMap、Secret 3.9 k8s中的StorageClass 3.9.1 nfs共享卷 3.9.2 glusterfs共享卷 3.10 k8s中的StatefulSet 3.11 k8s中的serviceaccount 4. Kubernetes错误排查导向图)
- [2.3 增加worker节点](#文章目录 Kubernetes容器编排解决方案【基础篇】 @[toc] 1. kubernetes简要概述 1.1 kubernetes 功能简介 1.2 Kubernetes架构及组件 2. Kubernetes 集群部署 2.1 测试环境集群部署 2.2 生产环境集群部署 2.3 增加worker节点 2.4 部署dashboard 3. Kubernetes基础资源 3.1 k8s中的资源层级关系及管理 3.2 k8s中的Pod 3.2.1 单容器 Pod 3.2.2 多容器 Pod 3.2.3 共享数据卷 3.2.4 容器探针 3.2.5 资源限额 3.3 k8s中的Deployment 3.4 k8s中的DaemonSet 3.5 k8s中的CronJob、Job 3.6 k8s中的Service 3.7 k8s中的ingress 3.8 k8s中的ConfigMap、Secret 3.9 k8s中的StorageClass 3.9.1 nfs共享卷 3.9.2 glusterfs共享卷 3.10 k8s中的StatefulSet 3.11 k8s中的serviceaccount 4. Kubernetes错误排查导向图)
- [2.4 部署dashboard](#文章目录 Kubernetes容器编排解决方案【基础篇】 @[toc] 1. kubernetes简要概述 1.1 kubernetes 功能简介 1.2 Kubernetes架构及组件 2. Kubernetes 集群部署 2.1 测试环境集群部署 2.2 生产环境集群部署 2.3 增加worker节点 2.4 部署dashboard 3. Kubernetes基础资源 3.1 k8s中的资源层级关系及管理 3.2 k8s中的Pod 3.2.1 单容器 Pod 3.2.2 多容器 Pod 3.2.3 共享数据卷 3.2.4 容器探针 3.2.5 资源限额 3.3 k8s中的Deployment 3.4 k8s中的DaemonSet 3.5 k8s中的CronJob、Job 3.6 k8s中的Service 3.7 k8s中的ingress 3.8 k8s中的ConfigMap、Secret 3.9 k8s中的StorageClass 3.9.1 nfs共享卷 3.9.2 glusterfs共享卷 3.10 k8s中的StatefulSet 3.11 k8s中的serviceaccount 4. Kubernetes错误排查导向图)
- [3. Kubernetes基础资源](#文章目录 Kubernetes容器编排解决方案【基础篇】 @[toc] 1. kubernetes简要概述 1.1 kubernetes 功能简介 1.2 Kubernetes架构及组件 2. Kubernetes 集群部署 2.1 测试环境集群部署 2.2 生产环境集群部署 2.3 增加worker节点 2.4 部署dashboard 3. Kubernetes基础资源 3.1 k8s中的资源层级关系及管理 3.2 k8s中的Pod 3.2.1 单容器 Pod 3.2.2 多容器 Pod 3.2.3 共享数据卷 3.2.4 容器探针 3.2.5 资源限额 3.3 k8s中的Deployment 3.4 k8s中的DaemonSet 3.5 k8s中的CronJob、Job 3.6 k8s中的Service 3.7 k8s中的ingress 3.8 k8s中的ConfigMap、Secret 3.9 k8s中的StorageClass 3.9.1 nfs共享卷 3.9.2 glusterfs共享卷 3.10 k8s中的StatefulSet 3.11 k8s中的serviceaccount 4. Kubernetes错误排查导向图)
- [3.1 k8s中的资源层级关系及管理](#文章目录 Kubernetes容器编排解决方案【基础篇】 @[toc] 1. kubernetes简要概述 1.1 kubernetes 功能简介 1.2 Kubernetes架构及组件 2. Kubernetes 集群部署 2.1 测试环境集群部署 2.2 生产环境集群部署 2.3 增加worker节点 2.4 部署dashboard 3. Kubernetes基础资源 3.1 k8s中的资源层级关系及管理 3.2 k8s中的Pod 3.2.1 单容器 Pod 3.2.2 多容器 Pod 3.2.3 共享数据卷 3.2.4 容器探针 3.2.5 资源限额 3.3 k8s中的Deployment 3.4 k8s中的DaemonSet 3.5 k8s中的CronJob、Job 3.6 k8s中的Service 3.7 k8s中的ingress 3.8 k8s中的ConfigMap、Secret 3.9 k8s中的StorageClass 3.9.1 nfs共享卷 3.9.2 glusterfs共享卷 3.10 k8s中的StatefulSet 3.11 k8s中的serviceaccount 4. Kubernetes错误排查导向图)
- [3.2 k8s中的Pod](#文章目录 Kubernetes容器编排解决方案【基础篇】 @[toc] 1. kubernetes简要概述 1.1 kubernetes 功能简介 1.2 Kubernetes架构及组件 2. Kubernetes 集群部署 2.1 测试环境集群部署 2.2 生产环境集群部署 2.3 增加worker节点 2.4 部署dashboard 3. Kubernetes基础资源 3.1 k8s中的资源层级关系及管理 3.2 k8s中的Pod 3.2.1 单容器 Pod 3.2.2 多容器 Pod 3.2.3 共享数据卷 3.2.4 容器探针 3.2.5 资源限额 3.3 k8s中的Deployment 3.4 k8s中的DaemonSet 3.5 k8s中的CronJob、Job 3.6 k8s中的Service 3.7 k8s中的ingress 3.8 k8s中的ConfigMap、Secret 3.9 k8s中的StorageClass 3.9.1 nfs共享卷 3.9.2 glusterfs共享卷 3.10 k8s中的StatefulSet 3.11 k8s中的serviceaccount 4. Kubernetes错误排查导向图)
- [3.2.1 单容器 *Pod*](#文章目录 Kubernetes容器编排解决方案【基础篇】 @[toc] 1. kubernetes简要概述 1.1 kubernetes 功能简介 1.2 Kubernetes架构及组件 2. Kubernetes 集群部署 2.1 测试环境集群部署 2.2 生产环境集群部署 2.3 增加worker节点 2.4 部署dashboard 3. Kubernetes基础资源 3.1 k8s中的资源层级关系及管理 3.2 k8s中的Pod 3.2.1 单容器 Pod 3.2.2 多容器 Pod 3.2.3 共享数据卷 3.2.4 容器探针 3.2.5 资源限额 3.3 k8s中的Deployment 3.4 k8s中的DaemonSet 3.5 k8s中的CronJob、Job 3.6 k8s中的Service 3.7 k8s中的ingress 3.8 k8s中的ConfigMap、Secret 3.9 k8s中的StorageClass 3.9.1 nfs共享卷 3.9.2 glusterfs共享卷 3.10 k8s中的StatefulSet 3.11 k8s中的serviceaccount 4. Kubernetes错误排查导向图)
- [3.2.2 多容器 *Pod*](#文章目录 Kubernetes容器编排解决方案【基础篇】 @[toc] 1. kubernetes简要概述 1.1 kubernetes 功能简介 1.2 Kubernetes架构及组件 2. Kubernetes 集群部署 2.1 测试环境集群部署 2.2 生产环境集群部署 2.3 增加worker节点 2.4 部署dashboard 3. Kubernetes基础资源 3.1 k8s中的资源层级关系及管理 3.2 k8s中的Pod 3.2.1 单容器 Pod 3.2.2 多容器 Pod 3.2.3 共享数据卷 3.2.4 容器探针 3.2.5 资源限额 3.3 k8s中的Deployment 3.4 k8s中的DaemonSet 3.5 k8s中的CronJob、Job 3.6 k8s中的Service 3.7 k8s中的ingress 3.8 k8s中的ConfigMap、Secret 3.9 k8s中的StorageClass 3.9.1 nfs共享卷 3.9.2 glusterfs共享卷 3.10 k8s中的StatefulSet 3.11 k8s中的serviceaccount 4. Kubernetes错误排查导向图)
- [3.2.3 共享数据卷](#文章目录 Kubernetes容器编排解决方案【基础篇】 @[toc] 1. kubernetes简要概述 1.1 kubernetes 功能简介 1.2 Kubernetes架构及组件 2. Kubernetes 集群部署 2.1 测试环境集群部署 2.2 生产环境集群部署 2.3 增加worker节点 2.4 部署dashboard 3. Kubernetes基础资源 3.1 k8s中的资源层级关系及管理 3.2 k8s中的Pod 3.2.1 单容器 Pod 3.2.2 多容器 Pod 3.2.3 共享数据卷 3.2.4 容器探针 3.2.5 资源限额 3.3 k8s中的Deployment 3.4 k8s中的DaemonSet 3.5 k8s中的CronJob、Job 3.6 k8s中的Service 3.7 k8s中的ingress 3.8 k8s中的ConfigMap、Secret 3.9 k8s中的StorageClass 3.9.1 nfs共享卷 3.9.2 glusterfs共享卷 3.10 k8s中的StatefulSet 3.11 k8s中的serviceaccount 4. Kubernetes错误排查导向图)
- [3.2.4 容器探针](#文章目录 Kubernetes容器编排解决方案【基础篇】 @[toc] 1. kubernetes简要概述 1.1 kubernetes 功能简介 1.2 Kubernetes架构及组件 2. Kubernetes 集群部署 2.1 测试环境集群部署 2.2 生产环境集群部署 2.3 增加worker节点 2.4 部署dashboard 3. Kubernetes基础资源 3.1 k8s中的资源层级关系及管理 3.2 k8s中的Pod 3.2.1 单容器 Pod 3.2.2 多容器 Pod 3.2.3 共享数据卷 3.2.4 容器探针 3.2.5 资源限额 3.3 k8s中的Deployment 3.4 k8s中的DaemonSet 3.5 k8s中的CronJob、Job 3.6 k8s中的Service 3.7 k8s中的ingress 3.8 k8s中的ConfigMap、Secret 3.9 k8s中的StorageClass 3.9.1 nfs共享卷 3.9.2 glusterfs共享卷 3.10 k8s中的StatefulSet 3.11 k8s中的serviceaccount 4. Kubernetes错误排查导向图)
- [3.2.5 资源限额](#文章目录 Kubernetes容器编排解决方案【基础篇】 @[toc] 1. kubernetes简要概述 1.1 kubernetes 功能简介 1.2 Kubernetes架构及组件 2. Kubernetes 集群部署 2.1 测试环境集群部署 2.2 生产环境集群部署 2.3 增加worker节点 2.4 部署dashboard 3. Kubernetes基础资源 3.1 k8s中的资源层级关系及管理 3.2 k8s中的Pod 3.2.1 单容器 Pod 3.2.2 多容器 Pod 3.2.3 共享数据卷 3.2.4 容器探针 3.2.5 资源限额 3.3 k8s中的Deployment 3.4 k8s中的DaemonSet 3.5 k8s中的CronJob、Job 3.6 k8s中的Service 3.7 k8s中的ingress 3.8 k8s中的ConfigMap、Secret 3.9 k8s中的StorageClass 3.9.1 nfs共享卷 3.9.2 glusterfs共享卷 3.10 k8s中的StatefulSet 3.11 k8s中的serviceaccount 4. Kubernetes错误排查导向图)
- [3.3 k8s中的Deployment](#文章目录 Kubernetes容器编排解决方案【基础篇】 @[toc] 1. kubernetes简要概述 1.1 kubernetes 功能简介 1.2 Kubernetes架构及组件 2. Kubernetes 集群部署 2.1 测试环境集群部署 2.2 生产环境集群部署 2.3 增加worker节点 2.4 部署dashboard 3. Kubernetes基础资源 3.1 k8s中的资源层级关系及管理 3.2 k8s中的Pod 3.2.1 单容器 Pod 3.2.2 多容器 Pod 3.2.3 共享数据卷 3.2.4 容器探针 3.2.5 资源限额 3.3 k8s中的Deployment 3.4 k8s中的DaemonSet 3.5 k8s中的CronJob、Job 3.6 k8s中的Service 3.7 k8s中的ingress 3.8 k8s中的ConfigMap、Secret 3.9 k8s中的StorageClass 3.9.1 nfs共享卷 3.9.2 glusterfs共享卷 3.10 k8s中的StatefulSet 3.11 k8s中的serviceaccount 4. Kubernetes错误排查导向图)
- [3.4 k8s中的DaemonSet](#文章目录 Kubernetes容器编排解决方案【基础篇】 @[toc] 1. kubernetes简要概述 1.1 kubernetes 功能简介 1.2 Kubernetes架构及组件 2. Kubernetes 集群部署 2.1 测试环境集群部署 2.2 生产环境集群部署 2.3 增加worker节点 2.4 部署dashboard 3. Kubernetes基础资源 3.1 k8s中的资源层级关系及管理 3.2 k8s中的Pod 3.2.1 单容器 Pod 3.2.2 多容器 Pod 3.2.3 共享数据卷 3.2.4 容器探针 3.2.5 资源限额 3.3 k8s中的Deployment 3.4 k8s中的DaemonSet 3.5 k8s中的CronJob、Job 3.6 k8s中的Service 3.7 k8s中的ingress 3.8 k8s中的ConfigMap、Secret 3.9 k8s中的StorageClass 3.9.1 nfs共享卷 3.9.2 glusterfs共享卷 3.10 k8s中的StatefulSet 3.11 k8s中的serviceaccount 4. Kubernetes错误排查导向图)
- [3.5 k8s中的CronJob、Job](#文章目录 Kubernetes容器编排解决方案【基础篇】 @[toc] 1. kubernetes简要概述 1.1 kubernetes 功能简介 1.2 Kubernetes架构及组件 2. Kubernetes 集群部署 2.1 测试环境集群部署 2.2 生产环境集群部署 2.3 增加worker节点 2.4 部署dashboard 3. Kubernetes基础资源 3.1 k8s中的资源层级关系及管理 3.2 k8s中的Pod 3.2.1 单容器 Pod 3.2.2 多容器 Pod 3.2.3 共享数据卷 3.2.4 容器探针 3.2.5 资源限额 3.3 k8s中的Deployment 3.4 k8s中的DaemonSet 3.5 k8s中的CronJob、Job 3.6 k8s中的Service 3.7 k8s中的ingress 3.8 k8s中的ConfigMap、Secret 3.9 k8s中的StorageClass 3.9.1 nfs共享卷 3.9.2 glusterfs共享卷 3.10 k8s中的StatefulSet 3.11 k8s中的serviceaccount 4. Kubernetes错误排查导向图)
- [3.6 k8s中的Service](#文章目录 Kubernetes容器编排解决方案【基础篇】 @[toc] 1. kubernetes简要概述 1.1 kubernetes 功能简介 1.2 Kubernetes架构及组件 2. Kubernetes 集群部署 2.1 测试环境集群部署 2.2 生产环境集群部署 2.3 增加worker节点 2.4 部署dashboard 3. Kubernetes基础资源 3.1 k8s中的资源层级关系及管理 3.2 k8s中的Pod 3.2.1 单容器 Pod 3.2.2 多容器 Pod 3.2.3 共享数据卷 3.2.4 容器探针 3.2.5 资源限额 3.3 k8s中的Deployment 3.4 k8s中的DaemonSet 3.5 k8s中的CronJob、Job 3.6 k8s中的Service 3.7 k8s中的ingress 3.8 k8s中的ConfigMap、Secret 3.9 k8s中的StorageClass 3.9.1 nfs共享卷 3.9.2 glusterfs共享卷 3.10 k8s中的StatefulSet 3.11 k8s中的serviceaccount 4. Kubernetes错误排查导向图)
- [3.7 k8s中的ingress](#文章目录 Kubernetes容器编排解决方案【基础篇】 @[toc] 1. kubernetes简要概述 1.1 kubernetes 功能简介 1.2 Kubernetes架构及组件 2. Kubernetes 集群部署 2.1 测试环境集群部署 2.2 生产环境集群部署 2.3 增加worker节点 2.4 部署dashboard 3. Kubernetes基础资源 3.1 k8s中的资源层级关系及管理 3.2 k8s中的Pod 3.2.1 单容器 Pod 3.2.2 多容器 Pod 3.2.3 共享数据卷 3.2.4 容器探针 3.2.5 资源限额 3.3 k8s中的Deployment 3.4 k8s中的DaemonSet 3.5 k8s中的CronJob、Job 3.6 k8s中的Service 3.7 k8s中的ingress 3.8 k8s中的ConfigMap、Secret 3.9 k8s中的StorageClass 3.9.1 nfs共享卷 3.9.2 glusterfs共享卷 3.10 k8s中的StatefulSet 3.11 k8s中的serviceaccount 4. Kubernetes错误排查导向图)
- [3.8 k8s中的ConfigMap、Secret](#文章目录 Kubernetes容器编排解决方案【基础篇】 @[toc] 1. kubernetes简要概述 1.1 kubernetes 功能简介 1.2 Kubernetes架构及组件 2. Kubernetes 集群部署 2.1 测试环境集群部署 2.2 生产环境集群部署 2.3 增加worker节点 2.4 部署dashboard 3. Kubernetes基础资源 3.1 k8s中的资源层级关系及管理 3.2 k8s中的Pod 3.2.1 单容器 Pod 3.2.2 多容器 Pod 3.2.3 共享数据卷 3.2.4 容器探针 3.2.5 资源限额 3.3 k8s中的Deployment 3.4 k8s中的DaemonSet 3.5 k8s中的CronJob、Job 3.6 k8s中的Service 3.7 k8s中的ingress 3.8 k8s中的ConfigMap、Secret 3.9 k8s中的StorageClass 3.9.1 nfs共享卷 3.9.2 glusterfs共享卷 3.10 k8s中的StatefulSet 3.11 k8s中的serviceaccount 4. Kubernetes错误排查导向图)
- [3.9 k8s中的StorageClass](#文章目录 Kubernetes容器编排解决方案【基础篇】 @[toc] 1. kubernetes简要概述 1.1 kubernetes 功能简介 1.2 Kubernetes架构及组件 2. Kubernetes 集群部署 2.1 测试环境集群部署 2.2 生产环境集群部署 2.3 增加worker节点 2.4 部署dashboard 3. Kubernetes基础资源 3.1 k8s中的资源层级关系及管理 3.2 k8s中的Pod 3.2.1 单容器 Pod 3.2.2 多容器 Pod 3.2.3 共享数据卷 3.2.4 容器探针 3.2.5 资源限额 3.3 k8s中的Deployment 3.4 k8s中的DaemonSet 3.5 k8s中的CronJob、Job 3.6 k8s中的Service 3.7 k8s中的ingress 3.8 k8s中的ConfigMap、Secret 3.9 k8s中的StorageClass 3.9.1 nfs共享卷 3.9.2 glusterfs共享卷 3.10 k8s中的StatefulSet 3.11 k8s中的serviceaccount 4. Kubernetes错误排查导向图)
- [3.9.1 nfs共享卷](#文章目录 Kubernetes容器编排解决方案【基础篇】 @[toc] 1. kubernetes简要概述 1.1 kubernetes 功能简介 1.2 Kubernetes架构及组件 2. Kubernetes 集群部署 2.1 测试环境集群部署 2.2 生产环境集群部署 2.3 增加worker节点 2.4 部署dashboard 3. Kubernetes基础资源 3.1 k8s中的资源层级关系及管理 3.2 k8s中的Pod 3.2.1 单容器 Pod 3.2.2 多容器 Pod 3.2.3 共享数据卷 3.2.4 容器探针 3.2.5 资源限额 3.3 k8s中的Deployment 3.4 k8s中的DaemonSet 3.5 k8s中的CronJob、Job 3.6 k8s中的Service 3.7 k8s中的ingress 3.8 k8s中的ConfigMap、Secret 3.9 k8s中的StorageClass 3.9.1 nfs共享卷 3.9.2 glusterfs共享卷 3.10 k8s中的StatefulSet 3.11 k8s中的serviceaccount 4. Kubernetes错误排查导向图)
- [3.9.2 glusterfs共享卷](#文章目录 Kubernetes容器编排解决方案【基础篇】 @[toc] 1. kubernetes简要概述 1.1 kubernetes 功能简介 1.2 Kubernetes架构及组件 2. Kubernetes 集群部署 2.1 测试环境集群部署 2.2 生产环境集群部署 2.3 增加worker节点 2.4 部署dashboard 3. Kubernetes基础资源 3.1 k8s中的资源层级关系及管理 3.2 k8s中的Pod 3.2.1 单容器 Pod 3.2.2 多容器 Pod 3.2.3 共享数据卷 3.2.4 容器探针 3.2.5 资源限额 3.3 k8s中的Deployment 3.4 k8s中的DaemonSet 3.5 k8s中的CronJob、Job 3.6 k8s中的Service 3.7 k8s中的ingress 3.8 k8s中的ConfigMap、Secret 3.9 k8s中的StorageClass 3.9.1 nfs共享卷 3.9.2 glusterfs共享卷 3.10 k8s中的StatefulSet 3.11 k8s中的serviceaccount 4. Kubernetes错误排查导向图)
- [3.10 k8s中的StatefulSet](#文章目录 Kubernetes容器编排解决方案【基础篇】 @[toc] 1. kubernetes简要概述 1.1 kubernetes 功能简介 1.2 Kubernetes架构及组件 2. Kubernetes 集群部署 2.1 测试环境集群部署 2.2 生产环境集群部署 2.3 增加worker节点 2.4 部署dashboard 3. Kubernetes基础资源 3.1 k8s中的资源层级关系及管理 3.2 k8s中的Pod 3.2.1 单容器 Pod 3.2.2 多容器 Pod 3.2.3 共享数据卷 3.2.4 容器探针 3.2.5 资源限额 3.3 k8s中的Deployment 3.4 k8s中的DaemonSet 3.5 k8s中的CronJob、Job 3.6 k8s中的Service 3.7 k8s中的ingress 3.8 k8s中的ConfigMap、Secret 3.9 k8s中的StorageClass 3.9.1 nfs共享卷 3.9.2 glusterfs共享卷 3.10 k8s中的StatefulSet 3.11 k8s中的serviceaccount 4. Kubernetes错误排查导向图)
- [3.11 k8s中的serviceaccount](#文章目录 Kubernetes容器编排解决方案【基础篇】 @[toc] 1. kubernetes简要概述 1.1 kubernetes 功能简介 1.2 Kubernetes架构及组件 2. Kubernetes 集群部署 2.1 测试环境集群部署 2.2 生产环境集群部署 2.3 增加worker节点 2.4 部署dashboard 3. Kubernetes基础资源 3.1 k8s中的资源层级关系及管理 3.2 k8s中的Pod 3.2.1 单容器 Pod 3.2.2 多容器 Pod 3.2.3 共享数据卷 3.2.4 容器探针 3.2.5 资源限额 3.3 k8s中的Deployment 3.4 k8s中的DaemonSet 3.5 k8s中的CronJob、Job 3.6 k8s中的Service 3.7 k8s中的ingress 3.8 k8s中的ConfigMap、Secret 3.9 k8s中的StorageClass 3.9.1 nfs共享卷 3.9.2 glusterfs共享卷 3.10 k8s中的StatefulSet 3.11 k8s中的serviceaccount 4. Kubernetes错误排查导向图)
- [4. Kubernetes错误排查导向图](#文章目录 Kubernetes容器编排解决方案【基础篇】 @[toc] 1. kubernetes简要概述 1.1 kubernetes 功能简介 1.2 Kubernetes架构及组件 2. Kubernetes 集群部署 2.1 测试环境集群部署 2.2 生产环境集群部署 2.3 增加worker节点 2.4 部署dashboard 3. Kubernetes基础资源 3.1 k8s中的资源层级关系及管理 3.2 k8s中的Pod 3.2.1 单容器 Pod 3.2.2 多容器 Pod 3.2.3 共享数据卷 3.2.4 容器探针 3.2.5 资源限额 3.3 k8s中的Deployment 3.4 k8s中的DaemonSet 3.5 k8s中的CronJob、Job 3.6 k8s中的Service 3.7 k8s中的ingress 3.8 k8s中的ConfigMap、Secret 3.9 k8s中的StorageClass 3.9.1 nfs共享卷 3.9.2 glusterfs共享卷 3.10 k8s中的StatefulSet 3.11 k8s中的serviceaccount 4. Kubernetes错误排查导向图)
1. kubernetes简要概述
Kubernetes 是用于自动部署, 扩展和管理容器化应用程序的开源系统. 它将组成应用程序的容器组合成逻辑单元, 以便于管理和服务发现. Kubernetes 源自Google 15 年生产环境的运维经验, 同时凝聚了社区的最佳创意和实践
在容器化应用的大趋势下, 越来越多的单体应用被划分成了无数个微小的服务, 从之前的裸机部署单体服务到现今使用容器承载服务运行; 容器越来越贴近研发、运维、测试等IT职能部门, 越来越多的人也渐渐转向了云进行开发, 而不再单独强调单体一致性问题; 这一切的功臣就是 --- 容器;
其实容器这个产物, 早在Linux内核诞生后就已经有了它, 那时候程序员创建一个容器需要编写代码, 调用Linux内核中的Cgroup 和 NameSpace用作资源限制, 而创建出来的容器所观看到的底层文件系统却是和宿主机是同一套文件系统, 导致在容器中操作文件就相当于更改了宿主机的文件系统, 这就大大暴露了容器的应用性差的特性; 后来横空出世的docker解决了这个问题, docker创造了一个叫做镜像的东西, 并将其进行分层, 使得用户在启动容器的时候将镜像拷贝一份读写层挂载到容器中, 让容器看到的底层文件系统只是镜像中的内容从而避免了上述的问题, 镜像带来的好处远不止这一个, 比如在生产、测试、研发三个环境中总是因为环境不统一造成上线后的应用很快崩溃的局面, 而有了镜像就不需要考虑环境的问题, 因为所有的服务运行在容器中, 而提供给容器运行的底层文件系统是镜像, 只要使用的是同一个镜像那么不管在什么环境中, 都是一样的效果, 这对于运维、测试、研发三类人而言就能彻底的和应用运行环境要考虑的事情甩手拜拜了; 而docker这个引擎又提供了很多易于使用的控制容器的指令, 大大降低了程序员操作的难度, 又提供相应的镜像和存储镜像的公共仓库, 使得容器技术飞速发展起来;
就在容器飞速发展的第五年里, Google发布了容器编排系统 kubernetes, 它解决了容器在多个宿主机间调度的问题, 同时提供可靠的API接口来控制容器的运行, 并时刻保持容器启动的状态, 融合了故障自愈、服务发现等新功能; 从而占领了容器市场的高地; 从此容器圈内又向容器编排发起了猛烈的攻势;
1.1 kubernetes 功能简介
-
服务发现和负载均衡
Kubernetes 可以使用 DNS 名称或自己的 IP 地址公开容器, 如果进入容器的流量很大, Kubernetes 可以负载均衡并分配网络流量, 从而使部署稳定. 常用的DNS插件为coreDNS, 用作服务发现和集群中容器通讯; 负载均衡器常使用集群内的service资源进行对外暴露服务, 同时也提供ingress插件接口对外暴露服务
-
存储编排
Kubernetes 允许你自动挂载你选择的存储系统, 例如本地存储、公共云提供商等. 对于集群内部的应用有时会需要持久化数据, 这时容器如果被删除数据也会随之消失, 所以一个稳定的外部存储集群就显得很重要了; 常见的对k8s提供存储能力的集群有: heketi + gluesterfs 、Rook + Ceph、阿里云OSS等, 配合集群内的storageclass可直接向存储集群申请存储空间
-
自动部署和回滚
你可以使用 Kubernetes 描述已部署容器的所需状态, 它可以以受控的速率将实际状态 更改为期望状态. 例如, 你可以自动化 Kubernetes 来为你的部署创建新容器, 删除现有容器并将它们的所有资源用于新容器. 控制k8s集群中容器的状态大多数时候都会采用 yaml 资源配置清单的形式, 方便记忆也易于识别
-
自动完成装箱计算
Kubernetes 允许你指定每个容器所需 CPU 和内存(RAM). 当容器指定了资源请求时, Kubernetes 可以做出更好的决策来管理容器的资源. 这就与Linux操作系统中的资源限额有关系了, 有些容器在接收高并发访问的时候, 往往会无限制的占用宿主机资源, 从而导致其他服务容器争抢不到应有的资源进行运行和服务, 从而导致大面积瘫痪
-
自我修复
Kubernetes 重新启动失败的容器、替换容器、杀死不响应用户定义的 运行状况检查的容器, 并且在准备好服务之前不将其通告给客户端. 在创建pod的时候, 只有当设置在pod中的探针全部探测正常后才会将pod连接到集群内网络中对外进行服务, 否则将通过监控告警给运维人员; 同样的对于k8s中的容器会受到kubelet和kube-apiserver的双重管理, kubelet上报容器运行状态, api-server向etcd中请求期望状态, 比较后让其达到期望的状态, 从而保证其功能/服务容器永久保持在线
-
密钥与配置管理
Kubernetes 允许你存储和管理敏感信息, 例如密码、OAuth 令牌和 ssh 密钥. 你可以在不重建容器镜像的情况下部署和更新密钥和应用程序配置, 也无需在堆栈配置中暴露密钥. 对于无状态应用(exam: nginx)的配置文件, 可以使用k8s中的configmap资源进行存储, 但对于密码和某些私密信息而言就可以使用secret资源进行存储, 从而避免频繁更改和私密信息泄漏的风险
1.2 Kubernetes架构及组件
一个 Kubernetes 集群由一组被称作节点的机器组成. 这些节点上运行 Kubernetes 所管理的容器化应用. 集群具有至少一个工作节点. 工作节点托管作为应用负载的组件的 Pod . 控制平面管理集群中的工作节点和 Pod . 为集群提供故障转移和高可用性, 这些控制平面一般跨多主机运行, 集群跨多个节点运行.
-
kube-apiserverAPI 服务器是 Kubernetes 控制面的组件, 该组件公开了 Kubernetes API. API 服务器是 Kubernetes 控制面的前端. Kubernetes API 服务器的主要实现是 kube-apiserver. kube-apiserver 设计上考虑了水平伸缩, 也就是说, 它可通过部署多个实例进行伸缩. 你可以运行 kube-apiserver 的多个实例, 并在这些实例之间平衡流量.
-
etcd
etcd 是兼具一致性和高可用性的键值数据库, 可以作为保存 Kubernetes 所有集群数据的后台数据库. 你的 Kubernetes 集群的 etcd 数据库通常需要有个备份计划. 要了解 etcd 更深层次的信息, 请参考 etcd 文档.
-
kube-scheduler
控制平面组件, 负责监视新创建的、未指定运行节点(node)的 Pods, 选择节点让 Pod 在上面运行. 调度决策考虑的因素包括单个 Pod 和 Pod 集合的资源需求、硬件/软件/策略约束、亲和性和反亲和性规范、数据位置、工作负载间的干扰和最后时限.
-
kube-controller-manager
运行控制器进程的控制平面组件. 从逻辑上讲, 每个控制器都是一个单独的进程, 但是为了降低复杂性, 它们都被编译到同一个可执行文件, 并在一个进程中运行. 这些控制器包括:
-
节点控制器(Node Controller): 负责在节点出现故障时进行通知和响应
-
任务控制器(Job controller): 监测代表一次性任务的 Job 对象, 然后创建 Pods 来运行这些任务直至完成
-
端点控制器(Endpoints Controller): 填充端点(Endpoints)对象(即加入 Service 与 Pod)
-
服务帐户和令牌控制器(Service Account & Token Controllers): 为新的命名空间创建默认帐户和 API 访问令牌
-
-
cloud-controller-manager
云控制器管理器是指嵌入特定云的控制逻辑的 控制平面组件. 云控制器管理器使得你可以将你的集群连接到云提供商的 API 之上, 并将与该云平台交互的组件同与你的集群交互的组件分离开来.
cloud-controller-manager仅运行特定于云平台的控制回路. 如果你在自己的环境中运行 Kubernetes, 或者在本地计算机中运行学习环境, 所部署的环境中不需要云控制器管理器. 与kube-controller-manager类似,cloud-controller-manager将若干逻辑上独立的 控制回路组合到同一个可执行文件中, 供你以同一进程的方式运行. 你可以对其执行水平扩容(运行不止一个副本)以提升性能或者增强容错能力. 下面的控制器都包含对云平台驱动的依赖:-
节点控制器(Node Controller): 用于在节点终止响应后检查云提供商以确定节点是否已被删除
-
路由控制器(Route Controller): 用于在底层云基础架构中设置路由
-
服务控制器(Service Controller): 用于创建、更新和删除云提供商负载均衡器
-
-
Node 组件: 节点组件在每个节点上运行, 维护运行的 Pod 并提供 Kubernetes 运行环境.
-
kubelet
一个在集群中每个节点(node)上运行的代理. 它保证容器(containers)都 运行在 Pod 中. kubelet 接收一组通过各类机制提供给它的 PodSpecs, 确保这些 PodSpecs 中描述的容器处于运行状态且健康. kubelet 不会管理不是由 Kubernetes 创建的容器.
-
kube-proxy
kube-proxy 是集群中每个节点上运行的网络代理, 实现 Kubernetes 服务(Service) 概念的一部分. kube-proxy 维护节点上的网络规则. 这些网络规则允许从集群内部或外部的网络会话与 Pod 进行网络通信. 如果操作系统提供了数据包过滤层并可用的话, kube-proxy 会通过它来实现网络规则. 否则, kube-proxy 仅转发流量本身.
-
容器运行时(Container Runtime)
容器运行环境是负责运行容器的软件. Kubernetes 支持容器运行时, 例如 Docker、 containerd、CRI-O 以及 Kubernetes CRI (容器运行环境接口) 的其他任何实现.
-
插件(Addons)
插件使用 Kubernetes 资源实现集群功能. 因为这些插件提供集群级别的功能, 插件中命名空间域的资源属于
kube-system命名空间. 下面描述众多插件中的几种. 有关可用插件的完整列表, 请参见 插件(Addons).-
DNS
尽管其他插件都并非严格意义上的必需组件, 但几乎所有 Kubernetes 集群都应该 有集群 DNS, 因为很多示例都需要 DNS 服务. 集群 DNS 是一个 DNS 服务器, 和环境中的其他 DNS 服务器一起工作, 它为 Kubernetes 服务提供 DNS 记录. Kubernetes 启动的容器自动将此 DNS 服务器包含在其 DNS 搜索列表中.
-
Web 界面(仪表盘)
Dashboard 是 Kubernetes 集群的通用的、基于 Web 的用户界面. 它使用户可以管理集群中运行的应用程序以及集群本身并进行故障排除.
-
容器资源监控
容器资源监控 将关于容器的一些常见的时间序列度量值保存到一个集中的数据库中, 并提供用于浏览这些数据的界面.
-
集群层面日志
集群层面日志 机制负责将容器的日志数据 保存到一个集中的日志存储中, 该存储能够提供搜索和浏览接口 ELK/Loki+grafana
-
2. Kubernetes 集群部署
2.1 测试环境集群部署
| role | ipaddress | configure |
|---|---|---|
| k8s-master | 10.9.12.51 | 4 core, 4Gb; 50GBS, CentOS 7.9 |
| k8s-worker-01 | 10.9.12.52 | 4 core, 4Gb; 100GBS, CentOS 7.9 |
| k8s-worker-02 | 10.9.12.53 | 4 core, 4Gb; 100GBS, CentOS 7.9 |
⚠️**++不要用克隆机器作这次的实验++**
测试集群部署采用单master节点部署, 可以使IT人员得到一个完整功能的测试Kubernetes集群; 由于其构建简单, 所以其内部很多相关设计没有凸显出来, 想了解Kubernetes的组件配置工作及细节请移至 ++生产环境集群部署++ 查看;
为加快安装速度, 可使用mirrors.hiops.icu提供的base源、epel源(需事先安装好)、docker源、Kubernetes源; 配置方法可在https://mirrors.hiops.icu 中进行查看; 但要注意下方initialenv.sh脚本的内容修改
bash
#>>> 下载部署k8s集群的安装仓库
$ git clone https://gitee.com/mirschao/k8sconfig.git
$ cd k8sconfig/kubeadm-deploys
export MASTER='10.9.12.51'
export WORKER1='10.9.12.52'
export WORKER2='10.9.12.53'
export MASTER_HOSTNAME='k8s-master'
export WORKER1_HOSTNAME='k8s-worker-01'
export WORKER2_HOSTNAME='k8s-worker-02'
-
初始化每个节点(all master & all node)
bash$ bash initialenv.sh -
安装 kubeadm 程序(all master & all node)
bash$ yum list kubeadm.x86_64 --showduplicates | sort -r kubeadm.x86_64 1.21.2-0 kubernetes kubeadm.x86_64 1.21.14-0 kubernetes kubeadm.x86_64 1.21.13-0 kubernetes #> master中执行 $ yum -y install kubeadm-1.21.14-0 kubelet-1.21.14-0 kubectl-1.21.14-0 #> worker中执行 $ yum -y install kubeadm-1.21.14-0 kubelet-1.21.14-0 #> master及worker节点均要执行 $ cat <<-EOF >/etc/sysconfig/kubelet KUBELET_EXTRA_ARGS="--cgroup-driver=systemd" EOF $ systemctl enable --now kubelet -
生成集群初始化配置文件(only k8s-master)
bash$ kubeadm config print init-defaults >initial.yaml #> 配置初始化文件 $ IPADDRESS=$(ifconfig | grep ens33 -A 2 | awk 'NR==2{ print $2 }') $ sed -i "s/1.2.3.4/${IPADDRESS}/" initial.yaml $ REGISTRYADDR="registry.cn-hangzhou.aliyuncs.com/google_containers" #> 设置如下信息可加快k8s镜像加载速度 $ REGISTRYADDR="harbor.hiops.icu/kuberntes" $ sed -i "s#k8s.gcr.io#${REGISTRYADDR}#" initial.yaml $ sed -i "s# node# ${HOSTNAME}#" initial.yaml #> 拉取初始化所需要的镜像文件 $ kubeadm config images pull --config initial.yaml #> 初始化集群 $ kubeadm init --config initial.yaml --upload-certs To start using your cluster, you need to run the following as a regular user: mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config Alternatively, if you are the root user, you can run: export KUBECONFIG=/etc/kubernetes/admin.conf You should now deploy a pod network to the cluster. Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at: https://kubernetes.io/docs/concepts/cluster-administration/addons/ Then you can join any number of worker nodes by running the following on each as root: kubeadm join 10.9.12.51:6443 --token abcdef.0123456789abcdef \ --discovery-token-ca-cert-hash sha256:1e4a4f89c9b0278318144821bd91ffb28500babc146aa52d270ae0b2743a6460 #> 部署calico网络插件 $ sed -i 's#etcd_endpoints: "http://<ETCD_IP>:<ETCD_PORT>"#etcd_endpoints: "https://10.9.12.51:2379"#g' calico-etcd.yaml ETCD_CA=`cat /etc/kubernetes/pki/etcd/ca.crt | base64 | tr -d '\n'` ETCD_CERT=`cat /etc/kubernetes/pki/etcd/server.crt | base64 | tr -d '\n'` ETCD_KEY=`cat /etc/kubernetes/pki/etcd/server.key | base64 | tr -d '\n'` $ sed -i "s@# etcd-key: null@etcd-key: ${ETCD_KEY}@g; s@# etcd-cert: null@etcd-cert: ${ETCD_CERT}@g; s@# etcd-ca: null@etcd-ca: ${ETCD_CA}@g" calico-etcd.yaml $ sed -i 's#etcd_ca: ""#etcd_ca: "/calico-secrets/etcd-ca"#g; s#etcd_cert: ""#etcd_cert: "/calico-secrets/etcd-cert"#g; s#etcd_key: ""#etcd_key: "/calico-secrets/etcd-key"#g' calico-etcd.yaml $ sed -i 's@# - name: CALICO_IPV4POOL_CIDR@- name: CALICO_IPV4POOL_CIDR@g; s@# value: "192.168.0.0/16"@ value: '"192.168.0.0/16"'@g;' calico-etcd.yaml #> 配置以下选项可以加快安装速度 $ sed -i "s@docker.io/calico/kube-controllers:v3.23.1@harbor.hiops.icu/kuberntes/calico-kube-controller:v3.23.1@g; s@docker.io/calico/cni:v3.23.1@harbor.hiops.icu/kuberntes/calico-cni:v3.23.1@g; s@docker.io/calico/node:v3.23.1@harbor.hiops.icu/kuberntes/calico-node:v3.23.1@g" calico-etcd.yaml $ kubectl apply -f calico-etcd.yaml #> 配置calicoctl设置 $ wget https://github.com/projectcalico/calico/releases/download/v3.23.1/calicoctl-linux-amd64 -O /usr/local/bin/calicoctl $ chmod a+x /usr/local/bin/calicoctl $ calicoctl node status Calico process is running. IPv4 BGP status +----------------+-------------------+-------+----------+-------------+ | PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO | +----------------+-------------------+-------+----------+-------------+ | 10.9.12.52 | node-to-node mesh | up | 13:53:54 | Established | | 10.9.12.53 | node-to-node mesh | up | 13:59:43 | Established | +----------------+-------------------+-------+----------+-------------+ IPv6 BGP status No IPv6 peers found. -
对于集群后续的配置和设置(only k8s-master)
bash#> 集群网络规则采用 ipvs 模式 $ kubectl edit configmap kube-proxy -n kube-system ... 43 mode: "ipvs" ... $ kubectl get pod -n kube-system NAME READY STATUS RESTARTS AGE calico-kube-controllers-7f494f5676-79nlm 1/1 Running 0 4m8s calico-node-g5xnl 1/1 Running 0 4m8s calico-node-gtdv7 1/1 Running 0 4m8s calico-node-wtf9x 0/1 PodInitializing 0 4m8s coredns-6f6b8cc4f6-5ghl9 1/1 Running 0 21m coredns-6f6b8cc4f6-xrr9t 1/1 Running 0 21m etcd-k8s-master 1/1 Running 0 21m kube-apiserver-k8s-master 1/1 Running 0 21m kube-controller-manager-k8s-master 1/1 Running 0 21m kube-proxy-28hd5 1/1 Running 0 16m kube-proxy-b76xv 1/1 Running 0 17m kube-proxy-bz7pd 1/1 Running 0 21m kube-scheduler-k8s-master 1/1 Running 0 21m $ kubectl delete pod kube-proxy-28hd5 -n kube-system pod "kube-proxy-28hd5" deleted $ kubectl delete pod kube-proxy-b76xv -n kube-system pod "kube-proxy-b76xv" deleted $ kubectl delete pod kube-proxy-bz7pd -n kube-system pod "kube-proxy-bz7pd" deleted $ kubectl get pod -n kube-system NAME READY STATUS RESTARTS AGE calico-kube-controllers-7f494f5676-79nlm 1/1 Running 0 5m21s calico-node-g5xnl 1/1 Running 0 5m21s calico-node-gtdv7 1/1 Running 0 5m21s calico-node-wtf9x 0/1 PodInitializing 0 5m21s coredns-6f6b8cc4f6-5ghl9 1/1 Running 0 22m coredns-6f6b8cc4f6-xrr9t 1/1 Running 0 22m etcd-k8s-master 1/1 Running 0 22m kube-apiserver-k8s-master 1/1 Running 0 22m kube-controller-manager-k8s-master 1/1 Running 0 22m kube-proxy-htks4 1/1 Running 0 11s kube-proxy-rdtvw 1/1 Running 0 26s kube-proxy-zv84c 1/1 Running 0 38s kube-scheduler-k8s-master 1/1 Running 0 22m #> 如果集群初始化失败: (每个节点都要执行) $ kubeadm reset -f; ipvsadm --clear; rm -rf ~/.kube $ systemctl restart kubelet #> 如果忘记token值 $ kubeadm token create --print-join-command $ kubeadm init phase upload-certs --upload-certs -
测试集群是否成功安装(only k8s-master)
bash$ cat <<-EOF | kubectl apply -f - apiVersion: v1 kind: Pod metadata: name: webserver spec: containers: - name: nginx-contianer image: nginx:1.22 ports: - containerPort: 80 EOF $ kubectl get pods -owide
2.2 生产环境集群部署
Pod-net-segment: 192.168.0.0/16
Service-net-segment: 10.96.0.0/12
| role | ipaddress | Configure |
|---|---|---|
| loadbalancer | 10.9.12.99 | None |
| k8s-prod-master-01 & etcd | 10.9.12.51 | 4core, 4Gb, 50G; CentOS 7.9 |
| k8s-prod-master-02 & etcd | 10.9.12.52 | 4core, 4Gb, 50G; CentOS 7.9 |
| k8s-prod-master-03 & etcd | 10.9.12.53 | 4core, 4Gb, 50G; CentOS 7.9 |
| k8s-prod-worker-01 | 10.9.12.61 | 4core, 16Gb, 100G; CentOS 7.9 |
| k8s-prod-worker-02 | 10.9.12.62 | 4core, 16Gb, 100G; CentOS 7.9 |
⚠️**++不要用克隆机器作这次的实验++**
生产环境部署k8s在现今的IT圈中, 比较流行在阿里云或者腾讯云上直接购买Kubernetes的SaaS服务, 而不是自己费劲儿部署一套出来; 但是对于IDC机房中的裸金属服务器而言, 并没有云那么方便, 所以还是需要自己手动的部署一套可高度定制化的Kubernetes集群; 这时就需要使用二进制方式部署Kubernetes集群了; 而且还要考虑高可用方面的设置;
bash
$ git clone https://gitee.com/mirschao/k8sconfig.git
$ cd k8sconfig/binary-deploys
sed -i 's/LOADBALANCER/10.9.12.99/' initialenv.sh
sed -i 's/MASTER1/10.9.12.51/' initialenv.sh
sed -i 's/MASTER2/10.9.12.52/' initialenv.sh
sed -i 's/MASTER3/10.9.12.53/' initialenv.sh
sed -i 's/WORKER1/10.9.12.61/' initialenv.sh
sed -i 's/WORKER2/10.9.12.62/' initialenv.sh
-
所有节点初始化
bash$ bash initialenv.sh -
所有节点升级内核 【https://mirrors.tuna.tsinghua.edu.cn/elrepo/kernel/el7/x86_64/RPMS/】
bash$ yum -y localinstall kernel-lt-* $ grub2-set-default 0 && grub2-mkconfig -o /etc/grub2.cfg $ grubby --args="user_namespace.enable=1" --update-kernel="$(grubby --default-kernel)" $ reboot -
k8s-prod-master-01中操作: 解压并分发二进制指令
bash$ tar xf kubernetes-server-linux-amd64.tar.gz --strip-components=3 -C /usr/local/bin/ kubernetes/server/bin/kube{let,ctl,-apiserver,-controller-manager,-scheduler,-proxy} $ for HOST in k8s-prod-master-02 k8s-prod-master-03;do scp /usr/local/bin/kube* ${HOST}:/usr/local/bin/;done $ for HOST in k8s-prod-worker-01 k8s-prod-worker-02;do scp /usr/local/bin/kube{let,-proxy} ${HOST}:/usr/local/bin/;done $ tar -zxvf etcd-v3.5.4-linux-amd64.tar.gz --strip-components=1 -C /usr/local/bin/ etcd-v3.5.4-linux-amd64/etcd{,ctl} $ for HOST in k8s-prod-master-02 k8s-prod-master-03;do scp /usr/local/bin/etcd* ${HOST}:/usr/local/bin/;done -
k8s-prod-master-01中操作: 生成集群内部通信证书
bash$ wget https://github.com/cloudflare/cfssl/releases/download/v1.6.1/cfssl_1.6.1_linux_amd64 -O /usr/local/bin/cfssl $ wget https://github.com/cloudflare/cfssl/releases/download/v1.6.1/cfssljson_1.6.1_linux_amd64 -O /usr/local/bin/cfssljson $ chmod a+x /usr/local/bin/cfssl* $ cd k8sconfig/binary-deploys/certs sed -i 's/LOADBALANCER/10.9.12.99/' generate-certs.sh sed -i 's/MASTER1/10.9.12.51/' generate-certs.sh sed -i 's/MASTER2/10.9.12.52/' generate-certs.sh sed -i 's/MASTER3/10.9.12.53/' generate-certs.sh $ bash generate-certs.sh $ cp /etc/etcd/ssl/* /etc/kubernetes/pki/etcd/ #>>> 将k8s以及etcd证书传送到两外两台master机器中 $ for HOST in k8s-prod-master-02 k8s-prod-master-03;do scp -r /etc/kubernetes/* ${HOST}:/etc/kubernetes/;done $ for HOST in k8s-prod-master-02 k8s-prod-master-03;do scp /etc/etcd/ssl/* ${HOST}:/etc/etcd/ssl/;done -
k8s-prod-master-01中操作: 配置etcd服务
bash$ cd ~/k8sconfig/binary-deploys/services/etcd $ sed 's/HOSTNAME/k8s-prod-master-01/; s/MASTER1/10.9.12.51/; s/MASTER2/10.9.12.52/; s/MASTER3/10.9.12.53/; s/MASTER/10.9.12.51/' etcd-config.yaml >etcd-config-01.yaml $ sed 's/HOSTNAME/k8s-prod-master-02/; s/MASTER1/10.9.12.51/; s/MASTER2/10.9.12.52/; s/MASTER3/10.9.12.53/; s/MASTER/10.9.12.52/' etcd-config.yaml >etcd-config-02.yaml $ sed 's/HOSTNAME/k8s-prod-master-03/; s/MASTER1/10.9.12.51/; s/MASTER2/10.9.12.52/; s/MASTER3/10.9.12.53/; s/MASTER/10.9.12.53/' etcd-config.yaml >etcd-config-03.yaml $ cp etcd-config-01.yaml /etc/etcd/etcd.config.yml $ scp etcd-config-02.yaml k8s-prod-master-02:/etc/etcd/etcd.config.yml $ scp etcd-config-03.yaml k8s-prod-master-03:/etc/etcd/etcd.config.yml $ cp etcd-service-config.service /usr/lib/systemd/system/etcd.service $ scp etcd-service-config.service k8s-prod-master-02:/usr/lib/systemd/system/etcd.service $ scp etcd-service-config.service k8s-prod-master-03:/usr/lib/systemd/system/etcd.service ######>每台master均执行<###### $ systemctl daemon-reload && systemctl enable --now etcd ######>任意master执行检查<###### $ export ETCDCTL_API=3 $ etcdctl --endpoints="10.9.12.51:2379,10.9.12.52:2379,10.9.12.53:2379" \ --cacert=/etc/kubernetes/pki/etcd/etcd-ca.pem --cert=/etc/kubernetes/pki/etcd/etcd.pem \ --key=/etc/kubernetes/pki/etcd/etcd-key.pem endpoint status \ --write-out=table -
k8s-prod-master-01中操作: 配置负载均衡及高可用
bash#> 三台master中均执行 $ yum -y install haproxy keepalived $ cd ~/k8sconfig/binary-deploys/services/loadbalancer sed -i 's/MASTER1/10.9.12.51/' haproxy.conf sed -i 's/MASTER2/10.9.12.52/' haproxy.conf sed -i 's/MASTER3/10.9.12.53/' haproxy.conf $ cp -rf haproxy.conf /etc/haproxy/haproxy.cfg $ for HOST in k8s-prod-master-02 k8s-prod-master-03;do scp haproxy.conf ${HOST}:/etc/haproxy/haproxy.cfg;done $ NETINTERFACE="eth0" $ sed "s#MSID#${NETINTERFACE}#; s#MSI#10.9.12.51#; s#LOADBALANCER#10.9.12.99#" keepalived.conf >k1.conf $ cp -rf k1.conf /etc/keepalived/keepalived.conf $ sed "s#MSID#${NETINTERFACE}#; s#MSI#10.9.12.52#; s#LOADBALANCER#10.9.12.99#" keepalived.conf >k2.conf $ scp k2.conf k8s-prod-master-02:/etc/keepalived/keepalived.conf $ sed "s#MSID#${NETINTERFACE}#; s#MSI#10.9.12.53#; s#LOADBALANCER#10.9.12.99#" keepalived.conf >k3.conf $ scp k3.conf k8s-prod-master-03:/etc/keepalived/keepalived.conf $ cp -rf check.sh /etc/keepalived/check_apiserver.sh $ for HOST in k8s-prod-master-02 k8s-prod-master-03;do scp check.sh ${HOST}:/etc/keepalived/check_apiserver.sh;done #> 三台master中均执行 $ systemctl enable --now haproxy keepalived -
k8s-prod-master-01中操作: 配置apiserver、controller、scheduler服务配置
bash$ cd ~/k8sconfig/binary-deploys/services/cplane #> apiserver configure. $ sed 's/LBMASTER/10.9.12.51/; s/MASTER1/10.9.12.51/; s/MASTER2/10.9.12.52/; s/MASTER3/10.9.12.53/' apiserver.service >api1.service $ cp api1.service /usr/lib/systemd/system/kube-apiserver.service $ sed 's/LBMASTER/10.9.12.52/; s/MASTER1/10.9.12.51/; s/MASTER2/10.9.12.52/; s/MASTER3/10.9.12.53/' apiserver.service >api2.service $ scp api2.service k8s-prod-master-02:/usr/lib/systemd/system/kube-apiserver.service $ sed 's/LBMASTER/10.9.12.53/; s/MASTER1/10.9.12.51/; s/MASTER2/10.9.12.52/; s/MASTER3/10.9.12.53/' apiserver.service >api3.service $ scp api3.service k8s-prod-master-03:/usr/lib/systemd/system/kube-apiserver.service #> contoller configure. POD_NET_SEGMENT='192.168.0.0/16' $ sed -i "s#POD_NET_SEGMENT#${POD_NET_SEGMENT}#" controller.service $ cp controller.service /usr/lib/systemd/system/kube-controller-manager.service $ for HOST in k8s-prod-master-02 k8s-prod-master-03;do scp controller.service ${HOST}:/usr/lib/systemd/system/kube-controller-manager.service;done #> scheduler configure. $ cp scheduler.service /usr/lib/systemd/system/kube-scheduler.service $ for HOST in k8s-prod-master-02 k8s-prod-master-03;do scp scheduler.service ${HOST}:/usr/lib/systemd/system/kube-scheduler.service;done #> 三台master中均执行 $ systemctl daemon-reload $ systemctl enable --now kube-scheduler kube-controller-manager kube-apiserver -
k8s-prod-master-01中执行: 配置集群认证证书自动颁发
bash$ cd ~/k8sconfig/binary-deploys/services/bootstrap $ sed -i 's#LOADBALANCER#10.9.12.99#' create-certs.sh $ bash create-certs.sh $ for HOST in k8s-prod-master-02 k8s-prod-master-03;do scp /etc/kubernetes/bootstrap-kubelet.kubeconfig ${HOST}:/etc/kubernetes/bootstrap-kubelet.kubeconfig;done -
k8s-prod-master-01中执行: 配置所有节点的kubelet、kube-proxy
bash$ cd ~/k8sconfig/binary-deploys/services/allmachines #> kubelet配置 cp kubelet.service /usr/lib/systemd/system/kubelet.service for HOST in k8s-prod-master-02 k8s-prod-master-03 k8s-prod-worker-01 k8s-prod-worker-02;do scp kubelet.service ${HOST}:/usr/lib/systemd/system/kubelet.service;done cp kubelet-10.conf /etc/systemd/system/kubelet.service.d/10-kubelet.conf for HOST in k8s-prod-master-02 k8s-prod-master-03 k8s-prod-worker-01 k8s-prod-worker-02;do scp kubelet-10.conf ${HOST}:/etc/systemd/system/kubelet.service.d/10-kubelet.conf;done cp kubelet.yaml /etc/kubernetes/kubelet-conf.yml for HOST in k8s-prod-master-02 k8s-prod-master-03 k8s-prod-worker-01 k8s-prod-worker-02;do scp kubelet.yaml ${HOST}:/etc/kubernetes/kubelet-conf.yml;done #[ADD NODE]> 想增加worker时可执行以下两条指令 for NODE in k8s-prod-worker-01 k8s-prod-worker-02;do for FILE in etcd-ca.pem etcd.pem etcd-key.pem;do scp /etc/etcd/ssl/${FILE} ${NODE}:/etc/etcd/ssl;done;done for NODE in k8s-prod-worker-01 k8s-prod-worker-02;do for FILE in pki/ca.pem pki/ca-key.pem pki/front-proxy-ca.pem bootstrap-kubelet.kubeconfig;do scp /etc/kubernetes/${FILE} ${NODE}:/etc/kubernetes/${FILE};done;done #> kube-proxy配置 sed -i 's/LOADBALANCER/10.9.12.99/' kube-proxy-create.sh bash kube-proxy-create.sh cp kube-proxy.service /usr/lib/systemd/system/kube-proxy.service for HOST in k8s-prod-master-02 k8s-prod-master-03 k8s-prod-worker-01 k8s-prod-worker-02;do scp kube-proxy.service ${HOST}:/usr/lib/systemd/system/kube-proxy.service;done POD_NET_SEGMENT='192.168.0.0/16' sed -i "s#POD_NET_SEGMENT#${POD_NET_SEGMENT}#" kube-proxy.conf cp kube-proxy.conf /etc/kubernetes/kube-proxy.conf for HOST in k8s-prod-master-02 k8s-prod-master-03 k8s-prod-worker-01 k8s-prod-worker-02;do scp kube-proxy.conf ${HOST}:/etc/kubernetes/kube-proxy.conf;done #[ADD NODE]> 想增加worker时可执行以下两条指令 for HOST in k8s-prod-master-02 k8s-prod-master-03 k8s-prod-worker-01 k8s-prod-worker-02;do scp /etc/kubernetes/kube-proxy.kubeconfig ${HOST}:/etc/kubernetes/kube-proxy.kubeconfig;done #> 所有节点操作 systemctl daemon-reload systemctl enable --now kubelet kube-proxy -
k8s-prod-master-01中操作: 安装calico网络插件
bash$ cd ~/k8sconfig/binary-deploys sed -i 's#etcd_endpoints: "http://<ETCD_IP>:<ETCD_PORT>"#etcd_endpoints: "https://10.9.12.51:2379,https://10.9.12.52:2379,https://10.9.12.53:2379"#g' calico-etcd.yaml ETCD_CA=$(cat /etc/kubernetes/pki/etcd/etcd-ca.pem | base64 | tr -d '\n') ETCD_CERT=$(cat /etc/kubernetes/pki/etcd/etcd.pem | base64 | tr -d '\n') ETCD_KEY=$(cat /etc/kubernetes/pki/etcd/etcd-key.pem | base64 | tr -d '\n') sed -i "s@# etcd-key: null@etcd-key: ${ETCD_KEY}@g; s@# etcd-cert: null@etcd-cert: ${ETCD_CERT}@g; s@# etcd-ca: null@etcd-ca: ${ETCD_CA}@g" calico-etcd.yaml sed -i 's#etcd_ca: ""#etcd_ca: "/calico-secrets/etcd-ca"#g; s#etcd_cert: ""#etcd_cert: "/calico-secrets/etcd-cert"#g; s#etcd_key: ""#etcd_key: "/calico-secrets/etcd-key"#g' calico-etcd.yaml sed -i 's@# - name: CALICO_IPV4POOL_CIDR@- name: CALICO_IPV4POOL_CIDR@g; s@# value: "192.168.0.0/16"@ value: '"192.168.0.0/16"'@g;' calico-etcd.yaml $ kubectl apply -f calico-etcd.yaml -
k8s-prod-master-01中操作: 安装coreDNS服务发现
bash$ cd ~/k8sconfig/binary-deploys/services/coredns $ ./deploy.sh -s -i 10.96.0.10 >coredns.yaml $ COREDNS_VERSION=$(grep "image:" coredns.yaml | awk '{ print $2 }') $ sed "s#${COREDNS_VERSION}#coredns/coredns:1.8.3#" coredns.yaml | kubectl apply -f - -
k8s-prod-master-01中操作: 验证集群的完整性
bash集群安装验证 # 原则: - pod能解析service - pod必须能解析跨namespace的service - 每个节点都能连通kubernetes service的 443及53端口 - pod和pod之间能正常通信(涵盖同namespace和不同namespace) # 创建pod用于测试 $ cat <<-EOF | kubectl apply -f - apiVersion: v1 kind: Pod metadata: name: busybox namespace: default spec: containers: - name: busybox image: busybox:1.28 command: - sleep - "36000" imagePullPolicy: IfNotPresent restartPolicy: Always EOF $ kubectl exec busybox -n default -- nslookup kubernetes Server: 10.96.0.10 Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local Name: kubernetes Address 1: 10.96.0.1 kubernetes.default.svc.cluster.local $ kubectl exec busybox -n default -- nslookup kube-dns.kube-system Server: 10.96.0.10 Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local Name: kube-dns.kube-system Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local #> 各个节点执行测试端口连通性 $ telnet 10.96.0.1 443 Trying 10.96.0.1... Connected to 10.96.0.1. Escape character is '^]'. #> 清除测试pod $ kubectl delete pod busybox
2.3 增加worker节点
bash
#> 以下步骤需要在k8s-prod-master-01中执行
$ cd addworker
$ chmod a+x add.sh
$ ./add.sh <dest_ipaddress>
2.4 部署dashboard
bash
#> 以下步骤需要在k8s-prod-master-01中执行
$ cd ~/k8sconfig/binary-deploys/dashboard
##>> 生成私有证书
$ openssl genrsa -out dashboard.key 2048
$ openssl req -days 3650 -new -out dashboard.csr -key dashboard.key -subj '/CN=10.9.12.99'
$ openssl x509 -req -in dashboard.csr -signkey dashboard.key -out dashboard.crt
$ kubectl apply -f dashboard.yaml
##>> 创建私有secret资源
$ kubectl create secret generic kubernetes-dashboard-certs --from-file=dashboard.key --from-file=dashboard.crt -n kubernetes-dashboard
##>> 创建dashboard管理serviceaccount
$ kubectl create serviceaccount dashboard-admin -n kubernetes-dashboard
$ kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kubernetes-dashboard:dashboard-admin
##>> 获取登录token
$ kubectl describe secrets -n kubernetes-dashboard $(kubectl -n kubernetes-dashboard get secret | awk '/dashboard-admin/{print $1}') | tail -1
⚠️: dashboard在访问时不接受 Google Chrome浏览器进行访问
3. Kubernetes基础资源
Kubernetes中的基础资源包含最小的执行单元Pod、用于暴露业务服务的四层负载Service、用于暴露业务服务的七层负载Ingress、用来控制Pod运行的控制器(Deployment、DaemonSet、Job、CronJob、StatefulSet、ReplicaSet)、用来提供业务容器持久化存储的StorageClass动态存储(PV, PVC)、用来解耦业务程序与配置的configmap、用来存储集群中的加密信息的Secret; 这些基础资源共同作用组成满足不同应用场景的业务服务体系, 再配合上开源社区提供的产品就构成了整个k8s的周边生态了;
3.1 k8s中的资源层级关系及管理
namespace
Ingress
Deployment
DaemonSet
CronJob
Job
StatefulSet
ReplicaSet
Pod
Service
ConfigMap
Secret
StorageClass[不属于namespace]
pv,pvc[会创建到指定的namespace下]
-
k8s基本控制指令
bash# 查看对应资源: 状态 $ kubectl get <SOURCE_NAME> -n <NAMESPACE> -owide # 查看对应资源: 事件信息 $ kubectl describe <SOURCE_NAME> <SOURCE_NAME_RANDOM_ID> -n <NAMESPACE> # 查看pod资源: 日志 $ kubectl logs -f <SOURCE_NAME_RANDOM_ID> [CONTINER_NAME] -n <NAMESPACE> # 创建资源: 根据资源清单 yaml json $ kubectl apply[or create/replace] -f <SOURCE_FILENAME>.yaml # 删除资源: 根据资源清单 $ kubectl delete -f <SOURCE_FILENAME>.yaml
3.2 k8s中的Pod
Pod 是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元; Pod 中会启动一个或一组紧密相关的业务容器, 各个业务容器相当于Pod 中的各个进程, 此时就可以将Pod 作为虚拟机看待; 在创建 Pod 时会启动一个init容器, 用来初始化存储和网络, 其余的业务容器都将在init容器启动后启动, 业务容器共享init容器的存储和网络; Pod 只是一个逻辑单元, 并不是真实存在的"主机", 这种类比主机的概念可以更好的符合现有互联网中几乎所有的虚拟化设计; 像之前运行在虚拟机中的 nginx、mysql、php均可以使用对应的镜像运行出对应的容器在Pod中, 来类比虚拟机中运行这三者;

对于 Pod 而言, 在运行的过程中, k8s为了控制其生命周期的状态, 增加了++容器探测指针++ 、++资源限额++ 、++期望状态保持++ 、++多容器结合++ 、++安全策略设定++ 、++控制器受管++ 、++故障处理策略++ 等; Pod在平时是不能够被单独创建的, 而是需要使用控制器对其创建, 这样可以时刻保持Pod的期望状态;
在Kubernetes中所有的资源均可通过命令行参数或者资源清单[yaml/json]的方式进行创建和修改, 但由于Kubernetes属于声明式资源控制集群, 故大多管理Kubernetes集群的方式采用资源配置清单; 资源配置清单可以很好的追溯资源的原型和详细的配置, 且配合版本控制能够完成更好的溯源、回滚、发布等操作; 所以课程中所有的资源创建和修改都会采用资源配置清单的方式, 除部分命令行操作以外;
3.2.1 单容器 Pod
yaml
---
apiVersion: v1
kind: Pod
metadata:
name: nginx-single
namespace: default
labels:
app: nginx
spec:
restartPolicy: OnFailure
containers:
- name: webserver
image: mirschao/webserver:v1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
3.2.2 多容器 Pod
yaml
---
apiVersion: v1
kind: Pod
metadata:
name: nginx-many
namespace: cloud2204
labels:
app: nginx
application: v1
spec:
restartPolicy: OnFailure
containers:
- name: webserver
image: mirschao/webserver:v1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
- name: php-fpm
image: php:8.0-fpm-alpine
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9000
3.2.3 共享数据卷
yaml
---
kind: Pod
apiVersion: v1
metadata:
name: nginx
namespace: default
labels:
app: nginx
spec:
restartPolicy: OnFailure
volumes:
- name: webdir
hostPath:
path: /tmp/webdir
containers:
- name: webserver
image: mirschao/webserver:v1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
volumeMounts:
- name: webdir
mountPath: /usr/share/nginx/html
- name: php-fpm
image: php:8.0-fpm-alpine
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9000
volumeMounts:
- name: webdir
mountPath: /usr/share/nginx/html
3.2.4 容器探针
针对运行中的容器,kubelet 可以选择是否执行以下三种探针,以及如何针对探测结果作出反应:
livenessProbe: 指示容器是否正在运行.如果存活态探测失败,则 kubelet 会杀死容器, 并且容器将根据其重启策略决定未来.如果容器不提供存活探针, 则默认状态为Success.readinessProbe: 指示容器是否准备好为请求提供服务.如果就绪探测失败, 端点控制器将从与 Pod 匹配的所有服务的端点列表中删除该 Pod 的 IP 地址. 初始延迟之前的就绪的状态值默认为Failure. 如果容器不提供就绪态探针,则默认状态为SuccessstartupProbe: 指示容器中的应用是否已经启动.如果提供了启动探针,则所有其他探针都会被 禁用,直到此探针成功为止.如果启动探测失败,kubelet将杀死容器,而容器依其 重启策略进行重启. 如果容器没有提供启动探测,则默认状态为Success
Probe 是由 kubelet 对容器执行的定期诊断. 要执行诊断,kubelet 调用由容器实现的 Handler (处理程序).有三种类型的处理程序:
- ExecAction: 在容器内执行指定命令.如果命令退出时返回码为 0 则认为诊断成功.
- TCPSocketAction: 对容器的 IP 地址上的指定端口执行 TCP 检查.如果端口打开,则诊断被认为是成功的.
- HTTPGetAction: 对容器的 IP 地址上指定端口和路径执行 HTTP Get 请求.如果响应的状态码大于等于 200 且小于 400,则诊断被认为是成功的.
每次探测都将获得以下三种结果之一:
Success(成功): 容器通过了诊断.Failure(失败): 容器未通过诊断.Unknown(未知): 诊断失败,因此不会采取任何行动.
liveness之exec探针
periodSeconds 字段指定了 kubelet 应该每 5 秒执行一次存活探测. initialDelaySeconds 字段告诉 kubelet 在执行第一次探测前应该等待 5 秒. kubelet 在容器内执行命令 cat /tmp/healthy 来进行探测. 如果命令执行成功并且返回值为 0, kubelet 就会认为这个容器是健康存活的. 如果这个命令返回非 0 值, kubelet 会杀死这个容器并重新启动它.
yaml
---
apiVersion: v1
kind: Pod
metadata:
name: liveness-exec
namespace: default
labels:
test: liveness
spec:
containers:
- name: liveness-probe
image: mirschao/probebusybox:v1
imagePullPolicy: IfNotPresent
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 60
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 3
periodSeconds: 5
liveness之http探针
periodSeconds 字段指定了 kubelet 每隔 3 秒执行一次存活探测. initialDelaySeconds 字段告诉 kubelet 在执行第一次探测前应该等待 3 秒. kubelet 会向容器内运行的服务(服务会监听 8080 端口)发送一个 HTTP GET 请求来执行探测. 如果服务器上 /healthz 路径下的处理程序返回成功代码, 则 kubelet 认为容器是健康存活的. 如果处理程序返回失败代码, 则 kubelet 会杀死这个容器并且重新启动它
yaml
---
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-http
spec:
containers:
- name: liveness-probe
image: mirschao/webserver:liveness-httpget-probe
imagePullPolicy: IfNotPresent
livenessProbe:
httpGet:
path: /healthz
port: 80
httpHeaders:
- name: Custom-Header
value: Awesome
initialDelaySeconds: 3
periodSeconds: 3
liveness之tcp端口探针
kubelet 会在容器启动 5 秒后发送第一个就绪探测. 这会尝试连接 webserver 容器的 80 端口. 如果探测成功, 这个 Pod 会被标记为就绪状态, kubelet 将继续每隔 10 秒运行一次检测. 除了就绪探测, 这个配置包括了一个存活探测. kubelet 会在容器启动 15 秒后进行第一次存活探测. 与就绪探测类似, 会尝试连接 webserver 容器的 80 端口. 如果存活探测失败, 这个容器会被重新启动
yaml
---
apiVersion: v1
kind: Pod
metadata:
name: liveness-tcpsocket
labels:
app: webserver
spec:
containers:
- name: webserver
image: mirschao/webserver:liveness-httpget-probe
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
livenessProbe:
tcpSocket:
port: 8765
initialDelaySeconds: 5
periodSeconds: 10
readnessProbe:
httpGet:
- path: /ok
- port: 8765
initialDelaySeconds: 5
periodSeconds: 10
多探针共存
有时候, 会有一些现有的应用在启动时需要较长的初始化时间. 要这种情况下, 若要不影响对死锁作出快速响应的探测, 设置存活探测参数是要技巧的. 技巧就是使用相同的命令来设置启动探测, 针对 HTTP 或 TCP 检测, 可以通过将 failureThreshold * periodSeconds 参数设置为足够长的时间来应对糟糕情况下的启动时间; failureThreshold表示检查几次后认为不健康; 有启动探测, 应用程序将会有最多 5 分钟(30 * 10 = 300s)的时间来完成其启动过程. 一旦启动探测成功一次, 存活探测任务就会接管对容器的探测, 对容器死锁作出快速响应. 如果启动探测一直没有成功, 容器会在 300 秒后被杀死, 并且根据 restartPolicy 来 执行进一步处置
yaml
ports:
- name: liveness-port
containerPort: 8080
hostPort: 8080
livenessProbe:
httpGet:
path: /healthz
port: liveness-port
failureThreshold: 1
periodSeconds: 10
startupProbe:
httpGet:
path: /healthz
port: liveness-port
failureThreshold: 30
periodSeconds: 10
readiness之exec探针
有时候, 应用会暂时性地无法为请求提供服务. 例如, 应用在启动时可能需要加载大量的数据或配置文件, 或是启动后要依赖等待外部服务. 在这种情况下, 既不想杀死应用, 也不想给它发送请求. Kubernetes 提供了就绪探测器来发现并缓解这些情况. 容器所在 Pod 上报还未就绪的信息, 并且不接受通过 Kubernetes Service 的流量. 就绪探测器在容器的整个生命周期中保持运行状态; 活跃探测器 不等待 就绪性探测器成功. 如果要在执行活跃探测器之前等待, 应该使用 initialDelaySeconds 或 startupProbe; 就绪探测器的配置和存活探测器的配置相似; 唯一区别就是要使用 readinessProbe 字段, 而不是 livenessProbe 字段;
yaml
readinessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
3.2.5 资源限额
如果你没有为一个容器指定内存限制,则自动遵循以下情况之一:
- 容器可无限制地使用内存.容器可以使用其所在节点所有的可用内存, 进而可能导致该节点调用 OOM Killer. 此外,如果发生 OOM Kill,没有资源限制的容器将被杀掉的可行性更大.
- 运行的容器所在命名空间有默认的内存限制,那么该容器会被自动分配默认限制. 集群管理员可用使用 LimitRange 来指定默认的内存限制.
yaml
---
apiVersion: v1
kind: Pod
metadata:
name: memory-limit
namespace: default
spec:
containers:
- name: memory-demo
image: mirschao/stress:memory-limit
resources:
limits: # Max
memory: "200Mi"
cpu: 1
requests: # 申请大小 -> 历史监控记录的平均值进行设定
memory: "100Mi"
cpu: 0.5
command: ["stress"]
args: ["--vm", "1", "--vm-bytes", "250M", "--vm-hang", "1"]
如果你没有为容器指定 CPU 限制,则会发生以下情况之一:
- 容器在可以使用的 CPU 资源上没有上限.因而可以使用所在节点上所有的可用 CPU 资源.
- 容器在具有默认 CPU 限制的名字空间中运行,系统会自动为容器设置默认限制. 集群管理员可以使用 LimitRange 指定 CPU 限制的默认值.
yaml
---
apiVersion: v1
kind: Pod
metadata:
name: cpu-limit
namespace: pod-webservice
spec:
containers:
- name: cpu-demo
image: mirschao/stress:cpu-limit
resources:
limits:
cpu: "1"
requests:
cpu: "0.5"
args:
- -cpus
- "2"
使用右侧命令观察pod的生命周期状态 watch -n 1 kubectl get pods -owide
yaml
---
apiVersion: v1
kind: Pod
metadata:
name: podname
namespace: default
lables:
app: nginx
spec:
volumes:
hostPath:
path: /tmp/webdir
containers:
- name: webserver
image: nginx:1.22
imagePullPolicy: IfNotPersent
volumeMounts:
- name: webdir
path: /usr/share/nginx/html
livenessProbe:
tcpSocket:
port: 8765
initialDelaySeconds: 5
periodSeconds: 10
readnessProbe:
httpGet:
- path: /ok
- port: 8765
initialDelaySeconds: 5
periodSeconds: 10
resources:
limits:
memory: "200Mi"
cpu: 1
requests:
memory: "100Mi"
cpu: 0.5
3.3 k8s中的Deployment
在Kubernetes中经常使用的核心角色就是pod, 但是单独的创建pod则会导致遇到错误时没有 ++合适的处理解决方案++ 而再导致业务宕掉, 那么在Kubernetes中就需要一个专门控制pod运行的控制器, 来保障pod时刻都会保持在期望的状态下运行, 从而让pod不会因为运行错误或负载超量而导致的非正常退出, 而影响业务的正常运行; 而且**++控制器并不是控制一个pod而是控制多个相同的pod, 让业务运行不再受到单点故障的困扰; 且时刻保持在与 etcd 中声明的期望状态++**;
Deployment控制器是Kubernetes中最常用的控制器, 大多用来控制 无状态应用 的运行和状态维护, 它会根据**++标签++ 来控制携带对应标签的pod; 但究其原理: deployment 去控制 replicaset, replicaset 控制 pod; 那也就是说deployment是控制副本集的控制器, 用来管理新老的replicaset副本集, 从而能够完成对 ++业务pod版本++ 的更新和回退; 而对于 ++pod的数量++ 是由replicaset来控制的, 主要控制pod的运行实例个数( ++准确的说应该是健康实例个数++**); 当然不管是deployment还是replicaset都是通过kubelet向apiserver请求etcd中的期望状态值和声明好的配置内容的, 从而来保障pod的稳定健康的运行;
yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: default
spec:
selector:
matchLabels:
app: nginx
replicas: 2 # tells deployment to run 2 pods matching the template
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.22
ports:
- containerPort: 80
尝试使用 kubectl delete pod nginx-<custom_id> -n <namespace> 来删除pod, 并观察是否有新的pod启动起来了; 这时就能体会到Kubernetes控制的强大之处了; 如果虚拟机也配备这样的能力岂不更加具备未来色彩; 当然Google已经实现了, 那就是他们这么多年一直在用的 Borg系统 , 同时它也是Kubernetes的前身, 也就是说其脱产于Borg系统;
并不是只有nginx才是无状态应用, 比如tomcat、前后端的服务、数据分析的服务等, 这些不存储请求端数据的应用就是无状态应用; 下面以前端Vue代码为例演示如何在Kubernetes中发布前端应用的服务;
Dcokerfile:
dockerfile
# 多阶段构建应用镜像
FROM node:14 AS builder
WORKDIR /srv/app/projects
COPY . .
RUN npm install && npm run build
FROM nginx
RUN mkdir /app
COPY --from=builder /srv/app/projects/dist /app
COPY nginx.conf /etc/nginx/nginx.conf
Nginx.conf:
nginx
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name daemon.hiops.icu;
location / {
root /app;
index index.html;
try_files $uri $uri/ /index.html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
}
deployment.yaml
yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: fronted-daemon-deployment
labels:
app: fronted-daemon
spec:
replicas: 3
selector:
matchLabels:
app: fronted
template:
metadata:
labels:
app: fronted
spec:
containers:
- name: vue-app-index
image: mirschao/fronted:vue-app-index-v1.0
ports:
- containerPort: 80
Deployment之滚动更新: 假设对于上述的vue应用而言, 并不是一成不变的, 需要在研发的过程中进行更新以适配不同的用户喜好, 那就需要在特定的时间或者空间中去更新它, 那么此时经过分析可知, 更新deployment控制的pod实际上就是改变pod中所应用的镜像tag即可, 这样就可以将新代码封装的镜像替换掉旧镜像进行版本和功能上的更新了; 也称之为版本迭代;
但值得说明的是这并不是作为发布迭代的最好方案, 因为在更新的过程中是新旧版本交替的过程, 也是一个此消彼长的过程; 旧版本在被删除的时候并不会考虑到正在链接用户的请求是否被处理完成, 那么直接滚动更新就会造成不好的用户体验, 从而影响网站的用户增长率问题, 此问题在后续的章节中会详细讲解 ArgoCD 的发布模式;
yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: fronted-daemon-deployment
labels:
app: fronted-daemon
spec:
replicas: 3
selector:
matchLabels:
app: fronted
template:
metadata:
labels:
app: fronted
spec:
containers:
- name: vue-app-index
image: mirschao/fronted:vue-app-index-v1.1
ports:
- containerPort: 80
Deployment回滚: 这时就需要 replicaset 来起作用了, 每次更新deployment的时候都会将原来的 replicaset 记录下来, 而此时想要回滚即将原来的 replicaset 启动起来即可; 但在生产中这是禁止直接操作的, 大多数时候你所编写的yaml资源清单都是与某些仓库关联的, 所以牵一发而动全身, 一定要分析好再修改, 此细节在后续课程会详细讲解; 这里为了实验采用最原始暴力的方式:
bash
$ kubectl edit fronted-daemon-deployment -n default
# 修改镜像的label即可进行回滚
3.4 k8s中的DaemonSet
DaemonSet 确保全部(或者某些)节点上运行一个 Pod 的副本. 当有节点加入集群时, 也会为他们新增一个 Pod . 当有节点从集群移除时, 这些 Pod 也会被回收. 删除 DaemonSet 将会删除它创建的所有 Pod.
DaemonSet 的一些典型用法:
- 在每个节点上运行集群守护进程
- 在每个节点上运行日志收集守护进程
- 在每个节点上运行监控守护进程
一种简单的用法是为每种类型的守护进程在所有的节点上都启动一个 DaemonSet. 一个稍微复杂的用法是为同一种守护进程部署多个 DaemonSet;每个具有不同的标志, 并且对不同硬件类型具有不同的内存、CPU 要求
yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-elasticsearch
namespace: kube-system
labels:
k8s-app: fluentd-logging
spec:
selector:
matchLabels:
name: fluentd-elasticsearch
template:
metadata:
labels:
name: fluentd-elasticsearch
spec:
tolerations:
# 这些容忍度设置是为了让该守护进程集在控制平面节点上运行
# 如果你不希望自己的控制平面节点运行 Pod, 可以删除它们
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule
- key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
containers:
- name: fluentd-elasticsearch
image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 100Mi
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
terminationGracePeriodSeconds: 30
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers # 容器的日志大多会放到这个目录
建议为无状态的服务使用 Deployments, 比如前端服务. 对这些服务而言, 对副本的数量进行扩缩容、平滑升级, 比精确控制 Pod 运行在某个主机上要重要得多. 当需要 Pod 副本总是运行在全部或特定主机上, 并且当该 DaemonSet 提供了节点级别的功能(允许其他 Pod 在该特定节点上正确运行)时, 应该使用 DaemonSet
对于k8s节点而言, 并不是能够时刻在线的, 且有些正在服务且没有问题的节点, 有相应的维护需求时会将其内所有的pod调度到其他节点上运行, 此时就需要一个动作将并没有问题的节点的上的pod调度到其他没问题的节点上; 驱逐==打污点
3.5 k8s中的CronJob、Job
Job 会创建一个或者多个 Pod, 并将继续重试 Pod 的执行, 直到指定数量的 Pod 成功终止. 随着 Pod 成功结束, Job 跟踪记录成功完成的 Pod 个数. 当数量达到指定的成功个数阈值时, 任务(即 Job)结束. 删除 Job 的操作会清除所创建的全部 Pod. 挂起 Job 的操作会删除 Job 的所有活跃 Pod, 直到 Job 被再次恢复执行.
一种简单的使用场景下, 你会创建一个 Job 对象以便以一种可靠的方式运行某 Pod 直到完成. 当第一个 Pod 失败或者被删除(比如因为节点硬件失效或者重启)时, Job 对象会启动一个新的 Pod
注意 Job 的 .spec.activeDeadlineSeconds 优先级高于其 .spec.backoffLimit 设置. 因此, 如果一个 Job 正在重试一个或多个失效的 Pod, 该 Job 一旦到达 activeDeadlineSeconds 所设的时限即不再部署额外的 Pod, 即使其重试次数还未达到 backoffLimit 所设的限制
yaml
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
spec:
containers:
- name: pi
image: perl:5.34
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
backoffLimit: 4
activeDeadlineSeconds: 100
一个 CronJob 对象就像 crontab (cron table) 文件中的一行. 它用 Cron 格式进行编写, 并周期性地在给定的调度时间执行 Job, CronJob 用于执行周期性的动作, 例如备份、报告生成等. 这些任务中的每一个都应该配置为周期性重复的(例如:每天/每周/每月一次); 你可以定义任务开始执行的时间间隔
yaml
apiVersion: batch/v1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/2 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox:1.28
imagePullPolicy: IfNotPresent
command:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure
3.6 k8s中的Service
Kubernetes Service 定义了这样一种抽象:逻辑上的一组 Pod,一种可以访问它们的策略 ------ 通常称为微服务。 Service 所针对的 Pods 集合通常是通过选择算符来确定的, 举个例子,考虑一个图片处理后端,它运行了 3 个副本。这些副本是可互换的 ------ 前端不需要关心它们调用了哪个后端副本。 然而组成这一组后端程序的 Pod 实际上可能会发生变化, 前端客户端不应该也没必要知道,而且也不需要跟踪这一组后端的状态。Pod 中的端口定义是有名字的,你可以在 Service 的 targetPort 属性中引用这些名称。 例如,我们可以通过以下方式将 Service 的 targetPort 绑定到 Pod 端口
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
namespace: default
spec:
selector:
matchLabels:
run: my-nginx
replicas: 3
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx:1.22
ports:
- containerPort: 80
name: http-web-svc
---
apiVersion: v1
kind: Service
metadata:
name: my-nginx
namespace: default
labels:
run: my-nginx
spec:
selector:
run: my-nginx
ports:
- name: name-of-service-port
protocol: TCP
port: 80
targetPort: http-web-svc
对一些应用的某些部分(如前端),可能希望将其暴露给 Kubernetes 集群外部 的 IP 地址。Kubernetes ServiceTypes 允许指定你所需要的 Service 类型,默认是 ClusterIP。Type 的取值以及行为如下:
-
ClusterIP:通过集群的内部 IP 暴露服务,选择该值时服务只能够在集群内部访问。 这也是默认的ServiceType。 -
NodePort:通过每个节点上的 IP 和静态端口(NodePort)暴露服务。NodePort服务会路由到自动创建的ClusterIP服务。 通过请求<节点 IP>:<节点端口>,你可以从集群的外部访问一个NodePort服务。yamlapiVersion: v1 kind: Service metadata: name: my-service spec: type: NodePort selector: app: MyApp ports: # 默认情况下,为了方便起见,`targetPort` 被设置为与 `port` 字段相同的值。 - port: 80 targetPort: 80 # 可选字段 # 默认情况下,为了方便起见,Kubernetes 控制平面会从某个范围内分配一个端口号(默认:30000-32767) nodePort: 30007 -
LoadBalancer:使用云提供商的负载均衡器向外部暴露服务。 外部负载均衡器可以将流量路由到自动创建的NodePort服务和ClusterIP服务上yamlapiVersion: v1 kind: Service metadata: name: my-service spec: selector: app: MyApp ports: - protocol: TCP port: 80 targetPort: 80 type: LoadBalancer
Metallb 裸金属集群网络负载均衡器(Beta)
bash
$ kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.2/config/manifests/metallb-native.yaml
$ cat <<-EOF | kubectl apply -f -
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: cheap
namespace: metallb-system
spec:
addresses:
- 10.9.12.40-10.9.12.50
EOF
3.7 k8s中的ingress
3.8 k8s中的ConfigMap、Secret
ConfigMap 是一种 API 对象,用来将非机密性的数据保存到键值对中。使用时, Pods 可以将其用作环境变量、命令行参数或者存储卷中的配置文件。ConfigMap 将你的环境配置信息和 容器镜像 解耦,便于应用配置的修改。
比如,假设你正在开发一个应用,它可以在你自己的电脑上(用于开发)和在云上 (用于实际流量)运行。 你的代码里有一段是用于查看环境变量 DATABASE_HOST,在本地运行时, 你将这个变量设置为 localhost,在云上,你将其设置为引用 Kubernetes 集群中的 公开数据库组件的 服务。
bash
kubectl create configmap nginxconfigmap --from-file=default.conf
Secret 是一种包含少量敏感信息例如密码、令牌或密钥的对象。 这样的信息可能会被放在 Pod 规约中或者镜像中。 使用 Secret 意味着你不需要在应用程序代码中包含机密数据。
由于创建 Secret 可以独立于使用它们的 Pod, 因此在创建、查看和编辑 Pod 的工作流程中暴露 Secret(及其数据)的风险较小。 Kubernetes 和在集群中运行的应用程序也可以对 Secret 采取额外的预防措施, 例如避免将机密数据写入非易失性存储。
bash
# 创建公钥和相对应的私钥
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /d/tmp/nginx.key -out /d/tmp/nginx.crt -subj "/CN=my-nginx/O=my-nginx"
# 对密钥实施 base64 编码
cat /d/tmp/nginx.crt | base64
cat /d/tmp/nginx.key | base64
yaml
apiVersion: "v1"
kind: "Secret"
metadata:
name: "nginxsecret"
namespace: "default"
type: kubernetes.io/tls
data:
tls.crt: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURIekNDQWdlZ0F3SUJBZ0lKQUp5M3lQK0pzMlpJTUEwR0NTcUdTSWIzRFFFQkJRVUFNQ1l4RVRBUEJnTlYKQkFNVENHNW5hVzU0YzNaak1SRXdEd1lEVlFRS0V3aHVaMmx1ZUhOMll6QWVGdzB4TnpFd01qWXdOekEzTVRKYQpGdzB4T0RFd01qWXdOekEzTVRKYU1DWXhFVEFQQmdOVkJBTVRDRzVuYVc1NGMzWmpNUkV3RHdZRFZRUUtFd2h1CloybHVlSE4yWXpDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBSjFxSU1SOVdWM0IKMlZIQlRMRmtobDRONXljMEJxYUhIQktMSnJMcy8vdzZhU3hRS29GbHlJSU94NGUrMlN5ajBFcndCLzlYTnBwbQppeW1CL3JkRldkOXg5UWhBQUxCZkVaTmNiV3NsTVFVcnhBZW50VWt1dk1vLzgvMHRpbGhjc3paenJEYVJ4NEo5Ci82UVRtVVI3a0ZTWUpOWTVQZkR3cGc3dlVvaDZmZ1Voam92VG42eHNVR0M2QURVODBpNXFlZWhNeVI1N2lmU2YKNHZpaXdIY3hnL3lZR1JBRS9mRTRqakxCdmdONjc2SU90S01rZXV3R0ljNDFhd05tNnNTSzRqYUNGeGpYSnZaZQp2by9kTlEybHhHWCtKT2l3SEhXbXNhdGp4WTRaNVk3R1ZoK0QrWnYvcW1mMFgvbVY0Rmo1NzV3ajFMWVBocWtsCmdhSXZYRyt4U1FVQ0F3RUFBYU5RTUU0d0hRWURWUjBPQkJZRUZPNG9OWkI3YXc1OUlsYkROMzhIYkduYnhFVjcKTUI4R0ExVWRJd1FZTUJhQUZPNG9OWkI3YXc1OUlsYkROMzhIYkduYnhFVjdNQXdHQTFVZEV3UUZNQU1CQWY4dwpEUVlKS29aSWh2Y05BUUVGQlFBRGdnRUJBRVhTMW9FU0lFaXdyMDhWcVA0K2NwTHI3TW5FMTducDBvMm14alFvCjRGb0RvRjdRZnZqeE04Tzd2TjB0clcxb2pGSW0vWDE4ZnZaL3k4ZzVaWG40Vm8zc3hKVmRBcStNZC9jTStzUGEKNmJjTkNUekZqeFpUV0UrKzE5NS9zb2dmOUZ3VDVDK3U2Q3B5N0M3MTZvUXRUakViV05VdEt4cXI0Nk1OZWNCMApwRFhWZmdWQTRadkR4NFo3S2RiZDY5eXM3OVFHYmg5ZW1PZ05NZFlsSUswSGt0ejF5WU4vbVpmK3FqTkJqbWZjCkNnMnlwbGQ0Wi8rUUNQZjl3SkoybFIrY2FnT0R4elBWcGxNSEcybzgvTHFDdnh6elZPUDUxeXdLZEtxaUMwSVEKQ0I5T2wwWW5scE9UNEh1b2hSUzBPOStlMm9KdFZsNUIyczRpbDlhZ3RTVXFxUlU9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K"
tls.key: "LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ2RhaURFZlZsZHdkbFIKd1V5eFpJWmVEZWNuTkFhbWh4d1NpeWF5N1AvOE9ta3NVQ3FCWmNpQ0RzZUh2dGtzbzlCSzhBZi9WemFhWm9zcApnZjYzUlZuZmNmVUlRQUN3WHhHVFhHMXJKVEVGSzhRSHA3VkpMcnpLUC9QOUxZcFlYTE0yYzZ3MmtjZUNmZitrCkU1bEVlNUJVbUNUV09UM3c4S1lPNzFLSWVuNEZJWTZMMDUrc2JGQmd1Z0ExUE5JdWFubm9UTWtlZTRuMG4rTDQKb3NCM01ZUDhtQmtRQlAzeE9JNHl3YjREZXUraURyU2pKSHJzQmlIT05Xc0RadXJFaXVJMmdoY1kxeWIyWHI2UAozVFVOcGNSbC9pVG9zQngxcHJHclk4V09HZVdPeGxZZmcvbWIvNnBuOUYvNWxlQlkrZStjSTlTMkQ0YXBKWUdpCkwxeHZzVWtGQWdNQkFBRUNnZ0VBZFhCK0xkbk8ySElOTGo5bWRsb25IUGlHWWVzZ294RGQwci9hQ1Zkank4dlEKTjIwL3FQWkUxek1yall6Ry9kVGhTMmMwc0QxaTBXSjdwR1lGb0xtdXlWTjltY0FXUTM5SjM0VHZaU2FFSWZWNgo5TE1jUHhNTmFsNjRLMFRVbUFQZytGam9QSFlhUUxLOERLOUtnNXNrSE5pOWNzMlY5ckd6VWlVZWtBL0RBUlBTClI3L2ZjUFBacDRuRWVBZmI3WTk1R1llb1p5V21SU3VKdlNyblBESGtUdW1vVlVWdkxMRHRzaG9reUxiTWVtN3oKMmJzVmpwSW1GTHJqbGtmQXlpNHg0WjJrV3YyMFRrdWtsZU1jaVlMbjk4QWxiRi9DSmRLM3QraTRoMTVlR2ZQegpoTnh3bk9QdlVTaDR2Q0o3c2Q5TmtEUGJvS2JneVVHOXBYamZhRGR2UVFLQmdRRFFLM01nUkhkQ1pKNVFqZWFKClFGdXF4cHdnNzhZTjQyL1NwenlUYmtGcVFoQWtyczJxWGx1MDZBRzhrZzIzQkswaHkzaE9zSGgxcXRVK3NHZVAKOWRERHBsUWV0ODZsY2FlR3hoc0V0L1R6cEdtNGFKSm5oNzVVaTVGZk9QTDhPTm1FZ3MxMVRhUldhNzZxelRyMgphRlpjQ2pWV1g0YnRSTHVwSkgrMjZnY0FhUUtCZ1FEQmxVSUUzTnNVOFBBZEYvL25sQVB5VWs1T3lDdWc3dmVyClUycXlrdXFzYnBkSi9hODViT1JhM05IVmpVM25uRGpHVHBWaE9JeXg5TEFrc2RwZEFjVmxvcG9HODhXYk9lMTAKMUdqbnkySmdDK3JVWUZiRGtpUGx1K09IYnRnOXFYcGJMSHBzUVpsMGhucDBYSFNYVm9CMUliQndnMGEyOFVadApCbFBtWmc2d1BRS0JnRHVIUVV2SDZHYTNDVUsxNFdmOFhIcFFnMU16M2VvWTBPQm5iSDRvZUZKZmcraEppSXlnCm9RN3hqWldVR3BIc3AyblRtcHErQWlSNzdyRVhsdlhtOElVU2FsbkNiRGlKY01Pc29RdFBZNS9NczJMRm5LQTQKaENmL0pWb2FtZm1nZEN0ZGtFMXNINE9MR2lJVHdEbTRpb0dWZGIwMllnbzFyb2htNUpLMUI3MkpBb0dBUW01UQpHNDhXOTVhL0w1eSt5dCsyZ3YvUHM2VnBvMjZlTzRNQ3lJazJVem9ZWE9IYnNkODJkaC8xT2sybGdHZlI2K3VuCnc1YytZUXRSTHlhQmd3MUtpbGhFZDBKTWU3cGpUSVpnQWJ0LzVPbnlDak9OVXN2aDJjS2lrQ1Z2dTZsZlBjNkQKckliT2ZIaHhxV0RZK2Q1TGN1YSt2NzJ0RkxhenJsSlBsRzlOZHhrQ2dZRUF5elIzT3UyMDNRVVV6bUlCRkwzZAp4Wm5XZ0JLSEo3TnNxcGFWb2RjL0d5aGVycjFDZzE2MmJaSjJDV2RsZkI0VEdtUjZZdmxTZEFOOFRwUWhFbUtKCnFBLzVzdHdxNWd0WGVLOVJmMWxXK29xNThRNTBxMmk1NVdUTThoSDZhTjlaMTltZ0FGdE5VdGNqQUx2dFYxdEYKWSs4WFJkSHJaRnBIWll2NWkwVW1VbGc9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K"
现在修改 nginx 副本以启动一个使用 Secret 中的证书的 HTTPS 服务器以及相应的用于暴露其端口(80 和 443)的 Service:
yaml
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
run: my-nginx
spec:
type: NodePort
ports:
- port: 8080
targetPort: 80
protocol: TCP
name: http
- port: 443
protocol: TCP
name: https
selector:
run: my-nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 1
template:
metadata:
labels:
run: my-nginx
spec:
volumes:
- name: secret-volume
secret:
secretName: nginxsecret
- name: configmap-volume
configMap:
name: nginxconfigmap
containers:
- name: nginxhttps
image: bprashanth/nginxhttps:1.0
ports:
- containerPort: 443
- containerPort: 80
volumeMounts:
- mountPath: /etc/nginx/ssl
name: secret-volume
- mountPath: /etc/nginx/conf.d
name: configmap-volume
3.9 k8s中的StorageClass
3.9.1 nfs共享卷
3.9.2 glusterfs共享卷
3.10 k8s中的StatefulSet
3.11 k8s中的serviceaccount
4. Kubernetes错误排查导向图
