Kubernetes
产生背景
一个应用运行所需要依赖的环境资源
CPU 执行具体的指令 内存 保存执行代码和临时变量 磁盘 保存应用需要读取和写入的文件 网卡 传输网络数据供应用访问外部资源或被访问 ...
应用部署
过去方式: 部署在一台机器上,以一个进程的方式运行 现代方式: 一个应用服务会用多个实例去支撑,以实现流量均摊和高可用 云原生时代: 自动根据流量访问和机器资源 管理应用服务 多实例载
要解决的问题
资源调度, 即一个应用要部署在一群机器里面的那些机器上 根据机器的剩余资源来调度, 即CPU 内存 应用访问规则 域名 域名转发规则
核心定义
- 一个用来管理 跨机器的容器化的应用,提供应用部署、运维、扩展等功能的开源系统
- 容器化应用可以理解为一个镜像,包含应用服务本身和其依赖的环境资源,跨机器部署时可无需再重复下依赖的过程
- 基于容器化技术,k8s自动对应用服务进行 扩、缩容以实现 资源服务 的 最大化 管理调度
基本架构
master
系统的大脑 核心服务: Kube-APIServer,Kube-Scheduler,Kube-Controller-Manager Kube-APIServer 主要提供了 Kubernetes 系统对外的接口,接口的形式是基于 HTTP 协议的。由于大部分情况下,我们会在部署 Kubernetes 的时候采用 HTTPS 的部署方式,所以这个接口真正使用的时候所采用的就是 HTTPS 协议。我们整个课程的大部分内容都是直接和这个服务进行交互。通过 Kubernetes 的 Go SDK 向这个服务发送请求进行资源的操作 Kube-Scheduler 如果说 Master 所在的机器是从外部看 Kubernetes 时的大脑,那么 Scheduler 服务就是从内部看 Kubernetes 时的大脑。我们刚刚说到的关于应用部署相关的细节都是由 Scheduler 服务来考虑的。 例如:对于应用 CPU 和内存资源的需求来说,Scheduler 需要综合考量整体可用 CPU 和内存资源的情况以决定将应用部署到哪些 Nodes 上面;或者是对于软件或者硬件层面的策略限制的考量(比如某些应用需要 GPU 资源);另外还有一些诸如 CPU 亲和性相关的考量等等 Kube-Controller-Manager 刚刚说过,当我们深入到 Kubernetes 架构内部看时,Scheduler 服务是整个 Kubernetes 的大脑,那么 Controller-Manager 就是具体的执行者。这个 Controller-Manager 是一组 Controller 的集合。这些 Controller 的主要任务是让 Kubernetes 的系统状态达到期望的系统状态。 所谓期望的系统状态,举个例子如期望的应用所需的 CPU 配额和限额或者是实例部署的数量等等。当你发送 API 请求去创建、修改、删除应用资源的时候,所做的操作就是设置一个应用部署的期望值。而这些 Controller 就是不断地检查这些部署的实时状态让系统达到应用所期望的状态。 在目前的 Kubernetes 的版本中,这组 Controller 分别为 Replication Controller,Endpoints Controller,Namespace Controller 和 ServiceAccount Controller。分别负责:应用数量的扩容和伸缩;集群服务和后端应用所在 Pod 之间的动态关系的维护;命名空间的管理和 ServiceAccount 的管理
Nodes
Kubelet 主要工作是确保部署在上面的应用正常运行。这个正常运行也就是上面所说的让系统达到期望的状态。为了能够让系统达到这个状态,那肯定得从 Master 获取期望的状态,然后再定时上报当前自己的状态,这样系统才能了解全局的情况。Kubelet 和 Master 的交互也是通过 APIServer 进行的。Kubelet 通过一个称为 cAdvisor 的容器资源分析工具来获取 Node 和容器的数据进行上报 Kube-Proxy 运行在 Nodes 上面的应用提供访问的透明代理服务以及负载均衡服务。从原理上来讲,应用是运行在我们下面会介绍到的 Pod 里面的。一个应用如果有多个实例,其实就是会有多个 Pod。Kubernetes 系统提供了一个称之为 Service 的对象来为这组应用的 Pod 提供集群层面的访问入口。那么当一个请求到达 Service 的时候,如何决定将请求转发给哪个 Pod 里面的服务去处理呢?当扩容或者缩容的时候,这种转发的策略如何随之发生变化呢?这些都是通过 Kube-Proxy 来实现的,Kube-Proxy 为 Service 提供了请求转发和负载均衡
基本资源
# kind启动k8s集群
kind create cluster --name kubernetes --config
# 查看当前系统下存在的命名空间
kubectl get namespace
# or
kubectl get ns
# 查看当前系统下指定命名空间
kubectl get ns
# 以json/yaml格式输出
kubectl get ns -o json
kubectl get ns -o yaml
# 更友好的方式
kubectl describe ns
# 查看所有命名空间里面的Pod(一组容器的集合,包含需要运行的应用服务)
kubectl get pod --all-namespaces
# or 指定命名空间
kubectl get pod --namespaces
# 查看所有命名空间里面的Service(协助Pod对外提供TCP/UDP访问服务)
kubectl get svc --all-namespaces
# or 指定命名空间
kubectl get svc --namespaces
# 查看某命名空间下的deployment(协助Pod调度)
kubectl get deployment -n
# 查看secret(存储敏感信息的资源,诸如用户名密码、TOKEN、SSH KEYS、HTTPS证书)
kubectl get secret
# or 指定secret
kuebcgtl get secret
# 查看ingress(提供OSI七层数据转发至Service资源对象的资源对象)
kubectl get ingress
# 获取所有命名空间下的ServiceAccount
kubectl get sa --all-namespaces
# 创建自己的sa
kubectl create sa
授权ServiceAccount访问K8s资源
k8s的访问控制模型
设置鉴权
# 1. 设置一个账号鉴权信息 # 创建sa $ kubectl create sa demo-admin serviceaccount/demo-admin created # kubectl config set-credentials
--token ## : demo-admin $ kubectl describe sa demo-admin Name: demo-admin Namespace: default Labels: Annotations: Image pull secrets: Mountable secrets: demo-admin-token-w67mg Tokens: demo-admin-token-w67mg Events: ## 查看demo-admin对应的Tokens $ kubectl describe secret demo-admin-token-w67mg [15:38:43] Name: demo-admin-token-w67mg Namespace: default Labels: Annotations: kubernetes.io/service-account.name: demo-admin kubernetes.io/service-account.uid: c096777d-6ce8-454e-bd9d-0096d2149fa0 Type: kubernetes.io/service-account-token Data ==== ca.crt: 1025 bytes namespace: 7 bytes token: eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6InNoaXlhbmxvdS1hZG1pbi10b2tlbi13NjdtZyIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJzaGl5YW5sb3UtYWRtaW4iLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJjMDk2Nzc3ZC02Y2U4LTQ1NGUtYmQ5ZC0wMDk2ZDIxNDlmYTAiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGVmYXVsdDpzaGl5YW5sb3UtYWRtaW4ifQ.KM5SNVdIcz0YY3WkYM_B8FQYmwMfMpEY__Y4mo9qKG-0y70elty8m7JDA4-bhmPrUw7CYt_5ah1z8cEKh27rBPWqoBNR2W61QX5pylAW-5uiRAEBi-K_-Rx-C1B2Rwwi-vLH71nF5x9SWt7L61VtWfVk5r6MLo_B8UjXNHSkZZ5j2wRFWLw0e_Jv4Qh9xibhr2ldfK-NWJUJugFG2GczdZo5foS0BOgZOmYLX9v8ixCc1Tz2miqcCPto6YfTLakQ1wbA2Ae_psOt_uKPkx7IYdxXury9tRCaB5_OxkpXWQ8FTEGgXiP8iq4fTFh8fUGg3iqOn_j9VfUYqy8Ci4x9Pw ## 设置账号鉴权 $ kubectl config set-credentials demo-admin --token eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6InNoaXlhbmxvdS1hZG1pbi10b2tlbi13NjdtZyIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJzaGl5YW5sb3UtYWRtaW4iLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJjMDk2Nzc3ZC02Y2U4LTQ1NGUtYmQ5ZC0wMDk2ZDIxNDlmYTAiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGVmYXVsdDpzaGl5YW5sb3UtYWRtaW4ifQ.KM5SNVdIcz0YY3WkYM_B8FQYmwMfMpEY__Y4mo9qKG-0y70elty8m7JDA4-bhmPrUw7CYt_5ah1z8cEKh27rBPWqoBNR2W61QX5pylAW-5uiRAEBi-K_-Rx-C1B2Rwwi-vLH71nF5x9SWt7L61VtWfVk5r6MLo_B8UjXNHSkZZ5j2wRFWLw0e_Jv4Qh9xibhr2ldfK-NWJUJugFG2GczdZo5foS0BOgZOmYLX9v8ixCc1Tz2miqcCPto6YfTLakQ1wbA2Ae_psOt_uKPkx7IYdxXury9tRCaB5_OxkpXWQ8FTEGgXiP8iq4fTFh8fUGg3iqOn_j9VfUYqy8Ci4x9Pw User "demo-admin" set. # 2. 设置集群的访问信息 # 集群的访问信息就是指 API 服务的地址和服务端的证书 # 使用下面的命令将 Kubernetes 服务端证书保存到 /home/demo/ca.crt 文件中 $ docker exec kubernetes-control-plane cat /etc/kubernetes/pki/ca.crt | tee /home/demo/ca.crt $ kubectl cluster-info Kubernetes master is running at https://127.0.0.1:43522 KubeDNS is running at https://127.0.0.1:43522/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'. $ kubectl config set-cluster k8s-learning \ > --server https://127.0.0.1:43522 \ > --certificate-authority /home/demo/ca.crt \ > --embed-certs=true Cluster "k8s-learning" set. # 3. 创建一个 Context,把集群信息和鉴权信息绑定在一起 $ kubectl config set-context k8s-learning-ctx \ > --cluster k8s-learning \ > --user demo-admin Context "k8s-learning-ctx" created. # 4. 使用这个创建的 Context $ kubectl config use-context k8s-learning-ctx Switched to context "k8s-learning-ctx". # 查看pod资源报错,不慌,因为还没有授权 $ kubectl get pods Error from server (Forbidden): pods is forbidden: User "system:serviceaccount:default:demo-admin" cannot list resource "pods" in API group "" in the namespace "default" # 先切回到 kubectl 默认的无鉴权的访问模式下 $ kubectl config use-context kind-kubernetes
授权简介
kubernetes资源主要分两类: 操作系统层面和命名空间层面 根据访问资源的类别,访问角色也相应分成 ClusterRole(操作系统层面) Role(命名空间层面) 命名空间层面的资源操作包括: create (创建资源) update (更新资源) delete (删除资源) patch (修改资源的字段) get (获取资源) list (获取资源列表) watch (监听资源)
基本步骤
创建ServiceAccount 创建ClusterRole或Role,并相应指定资源操作 创建ClusterRoleBinding或RoleBinding,然后绑定ServiceAccount
演示
# 1.创建一个 Role,在这个 Role 中授予操作相关资源的权限 $ kubectl create role demo-admin-role \ --resource pod,service,deployment,secret,ingress \ --verb create,update,delete,patch,get,list,watch # 2.创建一个 RoleBinding,将这个 Role 和 ServiceAccount 绑定在一起 kubectl create rolebinding demo-admin-role-binding \ --role demo-admin-role \ --serviceaccount default:shiyanlou-admin # 3.切到k8s-learning-ctx kubectl config use-context k8s-learning-ctx