桥下の民 - K8S
type: channel
link: https://wordplay.work/index.php/category/K8S
items: 部署 Kubernetes 的 Dashboard-2.1.0
items: kubernetes 核心技术-Helm
items: kubernetes 核心技术-Ingress
items: kubernetes 一次性任务与定时任务
items: kubernetes 部署守护进程
items: kubernetes 部署有状态应用
items: kubernetes 核心技术-认证&鉴权&准入控制
items: kubernetes核心技术-调度器
items: kubernetes 核心技术-init容器&探针&钩子
items: kubernetes 核心技术-Service

部署 Kubernetes 的 Dashboard-2.1.0
type: item
date: 2022-03-21T11:45:00+00:00
description: 一、简介 Dashboard 是基于网页的 Kubernetes 用户界面。可以使用 Dashboard 将容器应用部署到 Kubernetes 集群中，也可以对容器应用排错，还能管理集群本身及其附属资源。您可以使用 Dashboard 获取运行在集群中的应用的概览信息，也可以创建或者修改 Kubernetes 资源（如 Deployment，Job，DaemonSet 等等）。例如，可以对 Deployment 实现弹性伸缩、发起滚动升级、重启 Pod 或者使用向导创建新的应用。 二、生成 Dashboard 1、浏览器打开，复制 dashboard 清单 recommended.yaml 生成 dashboard，kube-dashboard.yaml。 文件如下： kube-dashboard.yaml 三、查看镜像 cat delopyment/kube-dashboard.yaml | grep image image: kubernetesui/dashboard:v2.1.0 imagePullPolicy: Always image: kubernetesui/metrics-scraper:v1.0.6 四、部署 Dashboard 4.1、部署 dashboard [root@k8s-master-001 ~]# kubectl apply -f kube-dashboard.yaml namespace/kubernetes-dashboard created serviceaccount/kubernetes-dashboard created service/kubernetes-dashboard created secret/kubernetes-dashboard-certs created secret/kubernetes-dashboard-csrf created secret/kubernetes-dashboard-key-holder created configmap/kubernetes-dashboard-settings created role.rbac.authorization.k8s.io/kubernetes-dashboard created clusterrole.rbac.authorization.k8s.io/kubernetes-dashboard created rolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created clusterrolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created deployment.apps/kubernetes-dashboard created service/dashboard-metrics-scraper created deployment.apps/dashboard-metrics-scraper created 4.2、查看 pod [root@k8s-master-001 ~]# kubectl get pods -n kubernetes-dashboard NAME READY STATUS RESTARTS AGE dashboard-metrics-scraper-79c5968bdc-q62h5 1/1 Running 0 106s kubernetes-dashboard-7448ffc97b-7f7gg 1/1 Running 0 107s 五、修改对外服务端口 5.1、修改对外服务端口 [root@k8s-master-01 ~]# kubectl edit svc -n kubernetes-dashboard 将 type: ClusterIP 改为 type: NodePort 5.2、查看端口映射 [root@k8s-master-001 ~]# kubectl get svc -n kubernetes-dashboard NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE dashboard-metrics-scraper ClusterIP 10.106.254.133 <none> 8000/TCP 7m29s kubernetes-dashboard NodePort 10.98.245.78 <none> 443:31424/TCP 7m29s 六、访问测试 访问：https://集群任意IP:端口，https://192.168.10.146:32500（记住替换为自己的IP地…

kubernetes 核心技术-Helm
type: item
date: 2022-03-21T09:40:00+00:00
description: 一、Helm 引入 K8S 上的应用对象，都是由特定的资源描述组成，包括 deployment、service 等。都保存各自文件中或者集中写到一个配置文件。然后 kubectl apply –f 部署。 如果应用只由一个或几个这样的服务组成，上面部署方式足够了。而对于一个复杂的应用，会有很多类似上面的资源描述文件，例如微服务架构应用，组成应用的服务可能多达十个，几十个。如果有更新或回滚应用的需求，可能要修改和维护所涉及的大量资源文件，而这种组织和管理应用的方式就显得力不从心了。且由于缺少对发布过的应用版本管理和控制，使 Kubernetes 上的应用维护和更新等面临诸多的挑战，主要面临以下问题： 如何将这些服务作为一个整体管理。 这些资源文件如何高效复用。 不支持应用级别的版本管理。 二、Helm Helm 是一个 Kubernetes 的包管理工具，就像 Linux 下的包管理器，如 yum/apt 等，可以很方便的将之前打包好的 yaml 文件部署到 kubernetes 上。 Helm 有 3 个重要概念： helm：一个命令行客户端工具，主要用于 Kubernetes 应用 chart 的创建、打包、发布和管理。 Chart：应用描述，一系列用于描述 k8s 资源相关文件的集合。 Release：基于 Chart 的部署实体，一个 chart 被 Helm 运行后将会生成对应的一个release；将在 k8s 中创建出真实运行的资源对象。 2.1、Helm 作用 使用 helm 可以这些 yaml 文件作为一个整体管理。 实现 yaml 高效复用。 使用 helm 应用级别的版本管理。 2.2、Helm v3 变化 2019 年 11 月 13 日， Helm 团队发布 Helm v3 的第一个稳定版本。该版本主要变化如下： 架构变化： 最明显的变化是 Tiller 的删除。 Release 名称可以在不同命名空间重用。 支持将 Chart 推送至 Docker 镜像仓库中。 使用 JSONSchema 验证 chart values。 其他。 2.3、Helm 客户端安装 1、下载 Helm 安装包 Helm 客户端下载地址：https://github.com/helm/helm/releases [root@kubernetes-master-001 ~]# cd /data/software/ [root@kubernetes-master-001 /data/software]# wget https://get.helm.sh/helm-v3.7.1-linux-amd64.tar.gz 2、解压安装包 [root@kubernetes-master-001 /data/software]# tar xf helm-v3.7.1-linux-amd64.tar.gz -C /opt/ [root@kubernetes-master-001 /data/software]# cd /opt/ [root@kubernetes-master-001 /opt]# ll total 0 drwxr-xr-x 2 3434 3434 50 Oct 14 04:09 linux-amd64 3、配置环境变量 #1.配置环境变量 [root@kubernetes-master-001 /opt]# vim /etc/profile.d/helm.sh export PATH=/opt/linux-amd64:$PATH #2.刷新环境变量 [root@kubernetes-master-001 /opt]# source /etc/profile.d/helm.sh 4、验证 helm [root@kubernetes-master-001 /opt]# helm version version.BuildInfo{Version:"v3.7.1", GitCommit:"1d11fcb5d3f3bf00dbe6fe31b8412839a96b3dc4", GitTreeState:"clean", GoVersion:"go1.16.9"} 2.4、Helm常用命令 create 创建一个 chart 并指定名字 dependency 管理 chart 依赖 get 下载一个 release。可用子命令：all、hooks、manifest、notes、values history 获取 release 历史 install 安装一个 chart list 列出 release package 将 chart 目录打包到 chart 存档文件中 pull 从远程仓库中下载 chart 并解压到本地 # helm p…

kubernetes 核心技术-Ingress
type: item
date: 2022-03-21T08:42:00+00:00
description: 一、引言 在 Kubernetes 中，Ingress 是一种 API 对象，用于管理外部访问集群服务的方式，通常是 HTTP 和 HTTPS 流量。可以将 Ingress 理解为一个智能的路由器，它根据请求的 URL 路径或主机名将流量路由到不同的服务。 主要功能： 路由：Ingress 可以根据请求的 URL 路径或主机名将流量路由到不同的服务。例如，你可以将 example.com/api 的请求路由到一个服务，而将 example.com/app 的请求路由到另一个服务。 负载均衡：Ingress 可以在多个后端服务之间分配流量，从而实现负载均衡。 SSL/TLS 终止：Ingress 可以处理 SSL/TLS 加密，允许你在 Ingress 控制器中配置证书，而不是在每个服务中配置。 基于主机和路径的路由：Ingress 支持基于主机名和路径的路由规则，使得多个服务可以通过同一个 IP 地址和端口进行访问。 1、把端口号对外暴露，通过 IP+端口号 进行访问。 1）使用 Service 里面的 NodePort 实现。 2、NodePort 缺陷 1）在每个节点上都会启动端口，在访问时候通过任何节点，通过节点 IP+暴露端口号 实现访问。 2）意味着每个端口只能使用一次，一个端口对应一个应用。 3）实际访问中都是用域名，根据不同域名跳转到不同端口服务中。 二、Ingress概述 通常情况下，service 和 pod 的 IP 仅可在集群内部访问。集群外部的请求需要通过负载均衡转发到 service 在 Node 上暴露的 NodePort 上，然后再由 kube-proxy 将其转发给相关的 Pod。 Ingress 为 Kubernetes 集群中的服务提供了入口，可以提供负载均衡、SSL 终止和基于名称的虚拟主机，在生产环境中常用的 Ingress 有 Treafik、Nginx、HAProxy、Istio 等。在 Kubernetes v1.1 版中添加的 Ingress 用于从集群外部到集群内部 Service 的 HTTP 和 HTTPS 路由，流量从 Internet 到 Ingress 再到 Services 最后到 Pod 上，通常情况下，Ingress 部署在所有的 Node 节点上。Ingress 可以配置提供服务外部访问的 URL、负载均衡、终止SSL，并提供基于域名的虚拟主机。但 Ingress 不会暴露任意端口或协议。 三、Ingress 工作流程 Ingress 公开了从集群外部到集群内服务的 HTTP 和 HTTPS 路由。 流量路由由 Ingress 资源上定义的规则控制。 可以将 Ingress 配置为服务提供外部可访问的 URL、负载均衡流量、终止 SSL/TLS，以及提供基于名称的虚拟主机等能力。 Ingress 控制器 通常负责通过负载均衡器来实现 Ingress，尽管它也可以配置边缘路由器或其他前端来帮助处理流量。 Ingress 不会公开任意端口或协议。 将 HTTP 和 HTTPS 以外的服务公开到 Internet 时，通常使用 Service.Type=NodePort 或 Service.Type=LoadBalancer 类型的服务。 四、Ingress 控制器(官方维护) 4.1、官方维护 Ingress 控制器 为了让 Ingress 资源工作，集群必须有一个正在运行的 Ingress 控制器。 与作为 kube-controller-manager 可执行文件的一部分运行的其他类型的控制器不同， Ingress 控制器不是随集群自动启动的。 基于此页面，你可选择最适合你的集群的 ingress 控制器实现。 Kubernetes 作为一个项目，目前支持和维护 AWS， GCE 和 nginx Ingress 控制器。 4.2、其他 Ingress 控制器 AKS 应用程序网关 Ingress 控制器 是一个配置 Azure 应用程序网关 的 Ingress 控制器。 Ambassador API 网关是一个基于 Envoy 的 Ingress 控制器。 Apache APISIX Ingress 控制器 是一个基于 Apache APISIX 网关 的 Ingress 控制器。 Avi Kubernetes Operator 使用 VMware NSX Advanced Load Balancer 提供第 4 到第 7 层的负载均衡。 BFE Ingress 控制器 是一个基于 BFE 的 Ingress 控制器。 Citrix Ingress 控制器 可以用来与 Citrix Application Delivery Controller 一起使用。 C…

kubernetes 一次性任务与定时任务
type: item
date: 2022-03-21T08:25:00+00:00
description: 一、Job 一次性任务概述 主要负责批处理任务，Job 创建一个或多个 Pod，并确保指定数量的 Pod 成功终止。Pod 成功完成后，Job 将跟踪成功完成的情况。当达到指定的成功完成次数时，任务（即Job）就完成了。删除 Job 将清除其创建的 Pod。 一个简单的情况是创建一个 Job 对象，以便可靠地运行一个 Pod 来完成。如果第一个Pod发生故障或被删除（例如，由于节点硬件故障或节点重启），则 Job 对象将启动一个新的 Pod。当然还可以使用 Job 并行运行多个 Pod。 二、Job 终止和清理 Job 完成后，不会再创建其他 Pod，但是 Pod 也不会被删除。这样使我们仍然可以查看已完成容器的日志，以检查是否有错误、警告或其他诊断输出。Job对象在完成后也将保留下来，以便您查看其状态。当我们删除Job对象时，对应的pod也会被删除。 特殊说明: 1）单个 Pod 时，默认 Pod 成功运行后 Job 即结束。 2）restartPolicy 仅支持 Never 和 OnFailure。 3）.spec.completions 标识Job结束所需要成功运行的Pod个数，默认为1 4）.spec.parallelism 标识并行运行的 Pod 个数，默认为1 5）.spec.activeDeadlineSeconds 为 Job 的持续时间，不管有多少 Pod 创建。一旦工作到指定时间，所有的运行 pod 都会终止且工作状态将成为type: Failed与reason: DeadlineExceeded。 三、Job 示例 1、编写 yaml 文件 job.yaml apiVersion: batch/v1 kind: Job metadata: name: pi spec: #completions: 3 # 标识Job结束所需要成功运行的Pod个数，默认为1 template: spec: containers: - name: pi image: registry.cn-beijing.aliyuncs.com/google_registry/perl:5.26 command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] restartPolicy: Never backoffLimit: 4 2、创建一次性任务 kubectl apply -f job.yaml job.batch/pi created 3、查看 pod 状态 # 查看，执行完成后，状态Status会变为Completed [root@kubernetes-master-001 ~]# kubectl get pods NAME READY STATUS RESTARTS AGE ds-test-7krrv 1/1 Running 0 22h ds-test-jnxzm 1/1 Running 0 22h pi-bvvs4 0/1 ContainerCreating 0 106s web-5bb6fd4c98-54ll2 1/1 Running 0 2d22h web-5bb6fd4c98-585rn 1/1 Running 0 2d22h [root@kubernetes-master-001 ~]# kubectl get pods NAME READY STATUS RESTARTS AGE ds-test-7krrv 1/1 Running 0 22h ds-test-jnxzm 1/1 Running 0 22h pi-bvvs4 0/1 Completed 0 2m21s web-5bb6fd4c98-54ll2 1/1 Running 0 2d22h web-5bb6fd4c98-585rn 1/1 Running 0 2d22h 4、查看 Pod 的标准输出 [root@kubernetes-master-001 ~]# kubectl logs --tail 500 pi-bvvs4 3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316527120190914564856692346034861045432664821339360726…

kubernetes 部署守护进程
type: item
date: 2022-03-21T08:13:00+00:00
description: 一、DaemonSet概述 官方文档：daemonset DaemonSet 确保在所有（或部分）Node节点上运行 Pod 的副本。随着新的 Node 被添加到群集中的同时，会将 Pod 添加到新 Node 中。随着节点从群集中删除，垃圾收集器也将会删除这些 Pod。DaemonSet 的一些典型场景和用法： 集群存储：在每个Node节点上，运行集群存储守护程序，例如 glusterd，ceph。 日志收集：在每个Node节点上，运行日志收集守护程序，例如 fluentd或logstash。 节点监控：在每个Node节点上，运行节点监控守护程序，例如 Prometheus Node Exporter,collectd，Dynatrace OneAgent，Datadog agent，New Relic agent，Ganglia gmond 或者 Instana agent。 二、创建DaemonSet应用 1、在每个node节点安装数据采集工具，编写yaml文件 test.yaml apiVersion: apps/v1 kind: DaemonSet metadata: name: ds-test labels: app: filebeat spec: # 标签选择器 selector: matchLabels: app: filebeat # 标签类型 template: metadata: labels: app: filebeat spec: # 配置容器 containers: - name: logs image: nginx ports: - containerPort: 80 # 挂载目录 volumeMounts: - name: varlog mountPath: /tmp/log volumes: - name: varlog hostPath: path: /var/log 2、必填字段 与 Kubernetes 中其它的对象一样，DaemonSet 必须包含 apiVersion，kind 和 metadata 字段。同时，DaemonSet 还需要 spec 字段部分的内容。 3、Pod 模板 .spec.template 是 .spec 的必填字段。.spec.template 用来定义 Pod 模板。DaemonSet 中的 Pod 模板必须设置 RestartPolicy 等于 Always，未指定的默认值即为 Always。 4、Pod 选择器 通过 .spec.selector 字段定义 Pod 选择器。从 Kubernetes 1.8 开始，必须指定一个与 .spec.template 标签相匹配选择器。一旦创建了 DaemonSet，就不能对 .spec.selector 进行修改，改变 Pod 选择器可能会导致 Pod 成为孤儿。 .spec.selector是一个由两个字段组成的对象： matchLabels 与 ReplicationControlle 的 .spec.selector 字段同样的工作机制。 matchExpressions 允许通过指定键，值列表以及与键和值相关的运算符来构建更复杂的选择器。 如果同时指定了两者时，结果取两者的和。如果指定了.spec.selector，则必须匹配 .spec.template.metadata.labels，如果不匹配将会被 API 拒绝。 5、仅在某些节点上运行 Pod 如果指定了 .spec.template.spec.nodeSelector，则 DaemonSet 控制器将在与该节点选择器匹配的 Node 节点上部署 Pod 。同样，如果指定了 .spec.template.spec.affinity，则 DaemonSet 控制器将在与该节点关联相匹配的 Node 节点上创建 Pod 。如果您未指定上述两个字段，则 DaemonSet 控制器将会在所有的 Node 节点上创建 Pod。 三、部署DaemonSet应用 #1.部署DaemonSet应用 kubectl apply -f test.yaml daemonset.apps/ds-test created #2.查看DaemonSet应用 kubectl get pods NAME READY STATUS RESTARTS AGE ds-test-7krrv 1/1 Running 0 59s ds-test-jnxzm 1/1 Running 0 59s web-5bb6fd4c98-54ll2 1/1 Running 0 2d web-5bb6fd4c98-585rn 1/1 Running 0 2d 四、进入DaemonSet查看 > kubect…

kubernetes 部署有状态应用
type: item
date: 2022-03-21T07:57:00+00:00
description: 一、概念 有状态：db 如果 mysql 的主从，必须是远程的存储，在任意节点都可以挂载恢复之前的状态，而且还有网络 ID 唯一，从得知道主的地址，pod 是短暂的，新的就会换IP，得保证这个 IP 能一直在使用。 无状态：web 比如部署 2 个副本，跟其他没啥直接的关系，本地也没有需要持久化的数据，其中有一个副本挂了，其他节点起来仍然可以提供服务没有影响。 K8S 适合访问波动大、版本迭代快的、弹性伸缩的。 二、特点 1、无状态应用（Deployment） 认为 Pod 都是一样的 没有顺序要求 不用考虑在那个 node 运行 随意进行伸缩和扩展 2、有状态应用 上面因素都需要考虑到 让每个 Pod 独立的，保持 Pod 启动顺序和唯一性 唯一的网络标识符，持久存储 有序性，比如 mysql 主从 三、Headless Service kubernates 中还有一种 service 类型：headless serivces功能，字面意思无头 service 其实就是该 service 对外无提供 IP，即 ClusterIP: none。一般用于对外提供域名服务的时候。 headless-service.yaml kind: Service apiVersion: v1 metadata: name: nginx labels: app: nginx spec: clusterIP: None # 设置为 None 表示这是一个 Headless Service selector: app: nginx ports: - port: 80 targetPort: 80 name: web --- apiVersion: apps/v1 kind: StatefulSet metadata: name: nginx-statefulset namespace: default spec: serviceName: nginx # 关联的 Service 名称 replicas: 3 # 副本数 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 操作 kubectl apply -f headless-service.yaml service/nginx created statefulset.apps/nginx-statefulset created 查看 [root@kubernetes-master-001 ~]# kubectl get svc,pods NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d2h service/nginx ClusterIP None <none> 80/TCP 3m3s service/web ClusterIP 10.100.37.233 <none> 80/TCP 47h service/web1 NodePort 10.103.214.171 <none> 80:32023/TCP 47h NAME READY STATUS RESTARTS AGE pod/nginx-statefulset-0 1/1 Running 0 2m36s pod/nginx-statefulset-1 1/1 Running 0 119s pod/nginx-statefulset-2 1/1 Running 0 97s pod/web-5bb6fd4c98-54ll2 1/1 Running 0 47h pod/web-5bb6fd4c98-585rn 1/1 Running 0 47h 四、statefulset(简称sts) 官方文档：statefulset StatefulSet 与 Deployment 区别：statefulset 是有身份的（唯一标识的）。 身份三要素：域名、主机名、存储（PVC） 这里有状态的约定，肯定不是简简单单通过名称来进行约定，而是更加复杂的操作。 deployment：是有身份的，有唯一标识 statefulset：根据主机名 + 按照一定规则生成域名 每个pod有唯一的主机名，并且有唯一的域名 格式：主机名称.service名称.名称空间.svc.cluster.local 举例：nginx-statefulset-0.default.svc.clust…

kubernetes 核心技术-认证&鉴权&准入控制
type: item
date: 2022-03-20T14:23:00+00:00
description: Kubernetes 作为一个分布式集群的管理工具，保证集群的安全性是其一个重要的任务。API Server 是集群内部各个组件通信的中介，也是外部控制的入口。所以 Kubernetes 的安全机制基本就是围绕保护 API Server 来设计的。Kubernetes 使用了认证（Authentication）、鉴权（Authorization）、准入控制（Admission Control）三步来保证API Server的安全，称为 3A 服务。 一、认证 HTTP Token 认证：通过一个 Token 来识别合法用户。 HTTP Token 的认证是用一个很长的特殊编码方式的并且难以被模仿的字符串 - Token 来表达客户的一种方式。Token 是一个很长的很复杂的字符串，每一个 Token 对应一个用户名存储在 API Server 能访问的文件中。当客户端发起 API 调用请求时，需要在 HTTP Header 里放入 Token** HTTP Base 认证：通过用户名+密码 的方式认证。 用户名+：+密码 用 BASE64 算法进行编码后的字符串放在 HTTP Request 中的 Heather Authorization 域里发送给服务端，服务端收到后进行编码，获取用户名及密码** 最严格的 HTTPS 证书认证：基于 CA 根证书签名的客户端身份认证方式**。 1.1、HTTPS 证书认证 HTTPS 加密： 单向认证：客户端认证服务器端。 双向认证：客户端与服务器端互相认证。 1.2、需要认证的节点 两种类型： （1）Kubenetes 组件对 API Server 的访问：kubectl、Controller Manager、Scheduler、kubelet、kube-proxy。 （2）Kubernetes 管理的 Pod 对容器的访问：Pod（dashborad 也是以 Pod 形式运行）。 安全性说明： （1）Controller Manager、Scheduler 与 API Server 在同一台机器，所以直接使用 API Server 的非安全端口访问，--insecure-bind-address=127.0.0.1 （2）kubectl、kubelet、kube-proxy 访问 API Server 就都需要证书进行 HTTPS 双向认证。 证书颁发： （1）手动签发：通过 k8s 集群的跟 ca 进行签发 HTTPS 证书** （2）自动签发：kubelet 首次访问 API Server 时，使用 token 做认证，通过后，Controller Manager 会为 kubelet 生成一个证书，以后的访问都是用证书做认证了** 1.3、kubeconfig kubeconfig 文件包含集群参数（CA证书、API Server地址），客户端参数（上面生成的证书和私钥），集群 context 信息（集群名称、用户名）。Kubenetes 组件通过启动时指定不同的 kubeconfig 文件可以切换到不同的集群。 1.4、ServiceAccount Pod 中的容器访问API Server。因为Pod的创建、销毁是动态的，所以要为它手动生成证书就不可行了。Kubenetes使用了Service Account解决Pod 访问API Server的认证问题。 1.5、Secret 与 SA 的关系 Kubernetes 设计了一种资源对象叫做 Secret，分为两类，一种是用于 ServiceAccount 的 service-account-token， 另一种是用于保存用户自定义保密信息的Opaque。ServiceAccount 中用到包含三个部分：Token、ca.crt、namespace。 （1）token是使用 API Server 私钥签名的 JWT。用于访问API Server时，Server端认证。 （2）ca.crt，根证书。用于Client端验证API Server发送的证书。 （3）namespace, 标识这个service-account-token的作用域名空间。 1.5.1、创建SA实验 #创建张三的sa证书 kubectl create sa zhangsan --dry-run -o yaml 操作 #查看kube-system名称空间下的pod kubectl get pod -n kube-system #查看caloco-node绑定的SA kubectl get pod calico-node-2pm9r -n kube-system -o yaml #进入pod内的容器 kubectl exec -it calico-node-2…

kubernetes核心技术-调度器
type: item
date: 2022-03-19T12:56:00+00:00
description: 一、概述 一个容器平台的主要功能就是为容器分配运行时所需要的计算，存储和网络资源。容器调度系统负责选择在最合适的主机上启动容器，并且将它们关联起来。它必须能够自动的处理容器故障并且能够在更多的主机上自动启动更多的容器来应对更多的应用访问。 目前三大主流的容器平台 Swarm, Mesos 和 Kubernetes 具有不同的容器调度系统。 Swarm 的特点是直接调度 Docker 容器，并且提供和标准 Docker API 一致的 API。 Mesos 针对不同的运行框架采用相对独立的调度系统，其中 Marathon 框架提供了 Docker 容器的原生支持。 Kubernetes 则采用了 Pod 和 Label 这样的概念把容器组合成一个个的互相存在依赖关系的逻辑单元。相关容器被组合成 Pod 后被共同部署和调度，形成服务（Service）。 这个是 Kubernetes 和 Swarm，Mesos 的主要区别。 相对来说，Kubernetes 采用这样的方式简化了集群范围内相关容器被共同调度管理的复杂性。换一种角度来看，Kubernetes 采用这种方式能够相对容易的支持更强大，更复杂的容器调度算法。 二、k8s 调度工作方式 Kubernetes 调度器作为集群的大脑，在如何提高集群的资源利用率、保证集群中服务的稳定运行中也会变得越来越重要。 Kubernetes 的资源分为两种属性。 可压缩资源（例如 CPU 循环，Disk I/O 带宽）都是可以被限制和被回收的，对于一个 Pod 来说可以降低这些资源的使用量而不去杀掉 Pod。 不可压缩资源（例如内存、硬盘空间）一般来说不杀掉 Pod 就没法回收。未来 Kubernetes 会加入更多资源，如网络带宽，存储 IOPS 的支持。 三、k8s 调度器 3.1、kube-scheduler kube-scheduler 是 kubernetes 系统的核心组件之一，主要负责整个集群资源的调度功能，根据特定的调度算法和策略，将 Pod 调度到最优的工作节点上面去，从而更加合理、更加充分的利用集群的资源，这也是选择使用 kubernetes 一个非常重要的理由。 3.2、调度流程 默认情况下，kube-scheduler 提供的默认调度器能够满足我们绝大多数的要求，之前接触的示例也基本上用的默认的策略，都可以保证我们的 Pod 可以被分配到资源充足的节点上运行。但是在实际的线上项目中，可能我们自己会比 kubernetes 更加了解我们自己的应用，比如我们希望一个 Pod 只能运行在特定的几个节点上，或者这几个节点只能用来运行特定类型的应用，这就需要我们的调度器能够可控。 kube-scheduler 是 kubernetes 的调度器，它的主要作用就是根据特定的调度算法和调度策略将 Pod 调度到合适的 Node 节点上去，是一个独立的二进制程序，启动之后会一直监听 API Server，获取到 PodSpec.NodeName 为空的 Pod，对每个 Pod 都会创建一个 binding。 调度主要分为以下几个部分： 首先是预选过程，过滤掉不满足条件的节点，这个过程称为 Predicates。 然后是优选过程，对通过的节点按照优先级排序，称之为 Priorities。 最后从中选择优先级最高的节点，如果中间任何一步骤有错误，就直接返回错误。 3.2.1、Predicates 阶段 Predicates 阶段首先遍历全部节点，过滤掉不满足条件的节点，属于强制性规则，这一阶 段输出的所有满足要求的 Node 将被记录并作为第二阶段的输入，如果所有的节点都不满足条件，那么 Pod 将会一直处于 Pending 状态，直到有节点满足条件，在这期间调度器会不断的重试。 所以我们在部署应用的时候，如果发现有 Pod 一直处于 Pending 状态，那么就是没有满足调度条件的节点，这个时候可以去检查下节点资源是否可用。 3.2.2、Priorities 阶段 Priorities 阶段即再次对节点进行筛选，如果有多个节点都满足条件的话，那么系统会按照节点的优先级(priorites)大小对节点进行排序，最后选择优先级最高的节点来部署 Pod 应用。 下面是调度过程的简单示意图： 更详细的流程是这样的： 首先，客户端通过 API Server 的 REST API 或者 kubectl 工具创建 Pod 资源。 API Server 收到用户请求后，存储相关数据到 etcd 数据库中。 调度器监听 API Server 查看为调度(bind)的 Pod 列表，循环遍历地为每个 Pod 尝试分 配节点，这个分配过程就是我们上面提到的两个阶段： 预选阶段(Predicates)，过滤节点…

kubernetes 核心技术-init容器&探针&钩子
type: item
date: 2022-03-19T12:36:00+00:00
description: 一、概述 1、当一个 pod 被创建的时候，会启动第一个容器 pause。 作用：挂载可能存在的存储卷，初始化网络栈，后来僵尸进程的杀死。维护。 2、pause 容器启动后，就会启动另一个部分，不是mainC，而是 initC（初始化容器，initC>=0） initC初始化容器的特性： 线性启动 阻塞特性，前一个 initC-1 必须退出，后面的 initC-2 才会运行。执行退出命令的返回码为 0，代表成功退出。如果 initC 启动过程中失败，出现错误，那么 pause 会重新开始创建 initC-1，initC-2，initC-3 等等。只有所有 initC 全部成功启动退出，才会继续往下运行。 独立于应用容器 Init 容器可以有自己的独立镜像，这与应用容器使用的镜像可以完全不同。因此，它们具有其特殊的依赖和工具，不会影响应用容器的镜像构成。 运行到完成 Init 容器必须在终止前运行到完成。它们不是用来启动长期运行的进程的。一旦它们成功执行了启动命令，它们就会终止。 重新启动策略 如果 Init 容器失败，Kubernetes 默认的重新启动策略是 'Always'，它会一直重试直到容器成功为止。这与应用容器的启动失败策略是独立的。 二、init容器 2.1、概述 Pod 能够具有多个容器，应用运行在容器里面，但是它也可能有一个或多个先于应用容器启动的 Init 容器。 Init 容器与普通的容器非常像，除了如下两点： 1、Init 容器总是运行到成功完成为止。 2、每个 Init 容器都必须在下一个 Init 容器启动之前成功完成。 如果 Pod 的 Init 容器失败，Kubernetes 会不断地重启该 Pod，直到 Init 容器成功为止。然而，如果 Pod 对应的 restartPolicy 为 Never，它不会重新启动。 2.2、init容器作用 因为 Init 容器具有与应用程序容器分离的单独镜像，所以它们的启动相关代码具有如下优势： 1、可以包含并运行实用工具，但是出于安全考虑，是不建议在应用程序容器镜像中包含这些实用工具的。 2、应用程序镜像可以分离出创建和部署的角色，而没有必要联合它们构建一个单独的镜像。 3、Init 容器使用 Linux Namespace，所以相对应用程序容器来说具有不同的文件系统视图。因此，它们能够具有访问 Secret 的权限，而应用程序容器则不能。 4、它们必须在应用程序容器启动之前运行完成，而应用程序容器是并行运行的，所以 Init 容器能够提供了一种简单的阻塞或延迟应用容器的启动的方法，直到满足了一组先决条件。 2.3、InitC 容器示例 initC-pod.yaml apiVersion: v1 kind: Pod metadata: name: myapp-pod labels: app: myapp spec: containers: - name: myapp-container image: busybox:1.35.0 command: ['sh', '-c', 'echo The app is running! && sleep 3600'] initContainers: - name: init-myservice image: busybox:1.35.0 command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;'] - name: init-mydb image: busybox:1.35.0 command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;'] 操作 kubectl apply -f initC-pod.yaml kubectl get pod kubectl describe pod myapp-pod #因为这里无法解析myservice的dns地址，所以才会报错 kubectl logs myapp-pod -c init-myservice kubectl create svc clusterip myservice --tcp=80:80 kubectl get svc #这里只加载好一个是因为，只解析了myservice的DNS，找不到mydb的DNS，所以无法加载 kubectl get pod kubectl create svc clusterip mydb --tcp=80:80 #稍等一会再次查看,就会加载完成 kubectl get pod 三、容器探针 3.1、探…

kubernetes 核心技术-Service
type: item
date: 2022-03-19T12:26:00+00:00
description: 一、Service 概述 Service 是 Kubernetes 最核心概念，通过创建 Service，可以为一组具有相同功能的容器应用提供一个统一的入口地址，并且将请求负载分发到后端的各个容器应用上。 目前一致的service有两个要求：标签匹配，就绪，如果不满足这两个，则无法匹配。 二、service 类型 2.1、ClusterIp 默认类型，自动分配一个仅 Cluster 内部可以访问的虚拟 IP。 2.2、NodePort（节点端口） 在 ClusterIP 基础上为 Service 在每台机器上绑定一个端口，这样就可以通过 <NodeIP>: NodePort 来访问该服务。 2.3、LoadBalancer 在 NodePort 的基础上，借助 cloud provider 创建一个外部负载均衡器，并将请求转发到 <NodeIP>: NodePort。 2.4、ExternalName（DNS别名） 把集群外部的服务引入到集群内部来，在集群内部直接使用。没有任何类型代理被创 建，这只有 kubernetes 1.7 或更高版本的 kube-dns 才支持。 DNS别名解析流程： 我们要创建一个 ExternalName 的 service（domain），当创建完 domain 以后，我们就会得到一个域名，tomcat 只要去访问到这个域名，这个域名就会经过 coredns 解析，解析到一个结果上，这个结果可能是一个域名，也可能是一个 IP，这个域名或 IP 可能指向这个 db。 当外部的 db 的 IP 发生变化时，只要修改 domain 的别名地址就好了，例如 db 数据库原来是 bbs.aaa.com，现在是 db.aaa.com，那么只需要将 domain 的别名地址写成 db.aaa.com 即可。 三、Service 的定义 yaml 格式的 Service 定义文件。 apiVersion: v1 kind: Service metadata: name: string namespace: string labels: name: string annotations: name: string spec: selector: {} # 选择器，用于关联 Pod type: string # 可选值：ClusterIP, NodePort, LoadBalancer, ExternalName clusterIP: string sessionAffinity: string # 可选值：None, ClientIP ports: - name: string protocol: string # 可选值：TCP, UDP, SCTP port: int # Service 端口 targetPort: int # Pod 端口 nodePort: int # 节点端口（当 type: NodePort 时使用） status: loadBalancer: ingress: - ip: string hostname: string 四、使用 4.1、ClusterIP 创建 ClusterIP.yaml apiVersion: v1 kind: Service #service类型 metadata: name: myapp #当前service的名是myapp namespace: default #放到default名称空间下 spec: #期望 type: ClusterIP #ClusterIP的类型 selector: #标签选择器，匹配下面两个标签 app: myapp release: stabel ports: #端口， - name: http #端口名称为http port: 80 #端口是80，集群访问的VIP的端口。 targetPort: 80 #后端目标80，真实服务器的端口 #IPVS是基于NAT工作模式运行的 创建 #基于yaml文件创建ClusterIP类型的svc kubectl apply -f ClusterIP.yaml #查看已经创建的svc kubectl get svc 4.2、NodePort 创建 NodePort.yaml apiVersion: v1 kind: Service metadata: name: myapp-nodeport namespace: default #放在default名称空间下 spec: #期望 type: NodePort #当前的工作模式是NodePort方式 selector: app: myapp release: stabel ports: - name: http #定义的别名为http por…