探索云原生技术之容器编排引擎-Kubernetes/K8S详解(9)

❤️作者简介:2022新星计划第三季云原生与云计算赛道Top5🏅、华为云享专家🏅、云原生领域潜力新星🏅

💛博客首页:C站个人主页🌞

💗作者目的:如有错误请指正,将来会不断的完善笔记,帮助更多的Java爱好者入门,共同进步!

文章目录

基本理论介绍

什么是云原生

Pivotal公司的Matt Stine于2013年首次提出云原生(Cloud-Native)的概念;2015年,云原生刚推广时,Matt Stine在《迁移到云原生架构》一书中定义了符合云原生架构的几个特征:12因素、微服务、自敏捷架构、基于API协作、扛脆弱性;到了2017年,Matt Stine在接受InfoQ采访时又改了口风,将云原生架构归纳为模块化、可观察、可部署、可测试、可替换、可处理6特质;而Pivotal最新官网对云原生概括为4个要点:DevOps+持续交付+微服务+容器

总而言之,符合云原生架构的应用程序应该是:采用开源堆栈(K8S+Docker)进行容器化,基于微服务架构提高灵活性和可维护性,借助敏捷方法、DevOps支持持续迭代和运维自动化,利用云平台设施实现弹性伸缩、动态调度、优化资源利用率。

此处摘选自《知乎-华为云官方帐号》

什么是kubernetes

kubernetes,简称K8s ,是用8代替8个字符"ubernete"而成的缩写。是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kubernetes的目标是让部署容器化的应用简单并且高效,Kubernetes提供了应用部署,规划,更新,维护的一种机制

传统的应用部署方式:是通过插件或脚本来安装应用。这样做的缺点是应用的运行、配置、管理、所有生存周期将与当前操作系统绑定,这样做并不利于应用的升级更新/回滚等操作,当然也可以通过创建虚拟机的方式来实现某些功能,但是虚拟机非常重,并不利于可移植性。

新的部署方式:是通过部署容器方式实现,每个容器之间互相隔离,每个容器有自己的文件系统 ,容器之间进程不会相互影响,能区分计算资源。相对于虚拟机,容器能快速部署,由于容器与底层设施、机器文件系统解耦的,所以它能在不同云、不同版本操作系统间进行迁移。

容器占用资源少、部署快,每个应用可以被打包成一个容器镜像,每个应用与容器间成一对一关系也使容器有更大优势,使用容器可以在build或release 的阶段,为应用创建容器镜像,因为每个应用不需要与其余的应用堆栈组合,也不依赖于生产环境基础结构,这使得从研发到测试、生产能提供一致环境。类似地,容器比虚拟机轻量、更"透明",这更便于监控和管理。

Kubernetes是Google开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、应用容器化管理。在生产环境中部署一个应用程序时,通常要部署该应用的多个实例以便对应用请求进行负载均衡。

在Kubernetes中,我们可以创建多个容器,每个容器里面运行一个应用实例,然后通过内置的负载均衡策略,实现对这一组应用实例的管理、发现、访问,而这些细节都不需要运维人员去进行复杂的手工配置和处理。

此处摘选自《百度百科》

kubernetes核心功能

  • 存储系统挂载(数据卷):pod中容器之间共享数据,可以使用数据卷
  • 应用健康检测:容器内服务可能进程阻塞无法处理请求,可以设置监控检查策略保证应用健壮性
  • 应用实例的复制(实现pod的高可用):pod控制器(deployment)维护着pod副本数量(可以自己进行设置,默认为1),保证一个pod或一组同类的pod数量始终可用,如果pod控制器deployment当前维护的pod数量少于deployment设置的pod数量,则会自动生成一个新的pod,以便数量符合pod控制器,形成高可用。
  • Pod的弹性伸缩:根据设定的指标(比如:cpu利用率)自动缩放pod副本数
  • 服务发现:使用环境变量或者DNS插件保证容器中程序发现pod入口访问地址
  • 负载均衡:一组pod副本分配一个私有的集群IP地址,负载均衡转发请求到后端容器。在集群内部其他pod可通过这个clusterIP访问应用
  • 滚动更新:更新服务不会发生中断,一次更新一个pod,而不是同时删除整个服务。
  • 容器编排:通过文件来部署服务,使得应用程序部署变得更高效
  • 资源监控:node节点组件集成cAdvisor资源收集工具,可通过Heapster汇总整个集群节点资源数据,然后存储到InfluxDb时序数据库,再由Grafana展示。
  • 提供认证和授权:支持角色访问控制(RBAC)认证授权等策略

k8s的安全认证

访问控制概述
概述
  • kubernetes作为一个分布式集群的管理工具,保证集群的安全性是其一个重要的任务。所谓的安全性其实就是保证对kubernetes的各种客户端进行认证和授权操作。
客户端
  • 在kubernetes集群中,客户端通常由两类:

  • ① User Account:一般是独立于kubernetes之外的其他服务管理的用户账号。

  • ② Service Account:kubernetes管理的账号,用于为Pod的服务进程在访问kubernetes时提供身份标识

认证、授权和准入控制
  • API Server是访问和管理资源对象的唯一入口。任何一个请求访问API Server,都要经过下面的三个流程:

  • ① Authentication(认证):身份鉴别,只有正确的账号才能通过认证。

  • ② Authorization(授权):判断用户是否有权限对访问的资源执行特定的动作。

  • ③ Admission Control(注入控制):用于补充授权机制以实现更加精细的访问控制功能。

认证管理
kubernetes的客户端身份认证方式
  • kubernetes集群安全的关键点在于如何识别并认证客户端身份,它提供了3种客户端身份认证方式:(任选一种即可)

  • 1:HTTP Base认证:

  • 通过用户名+密码的方式进行认证。

  • 这种方式是把"用户名:密码"用BASE64算法进行编码后的字符串放在HTTP请求中的Header的Authorization域里面发送给服务端。服务端收到后进行解码,获取用户名和密码,然后进行用户身份认证的过程。

  • 2:HTTP Token认证:

  • 通过一个Token来识别合法用户。

  • 这种认证方式是用一个很长的难以被模仿的字符串--Token来表明客户端身份的一种方式。每个Token对应一个用户名,当客户端发起API调用请求的时候,需要在HTTP的Header中放入Token,API Server接受到Token后会和服务器中保存的Token进行比对,然后进行用户身份认证的过程。

  • 3: HTTPS证书认证:(安全性最高的方式,也是最推荐的方式)

  • 基于CA根证书签名的双向数字证书认证方式。

  • 这种认证方式是安全性最高的一种方式,但是同时也是操作起来最麻烦的一种方式。

HTTPS证书认证过程
  • 1:证书申请和下发:HTTPS通信双方的服务器向CA机构申请证书,CA机构发根证书、服务端证书及私钥给申请者。

  • 2:客户端和服务器的双向认证:

  • 客户端向服务端发起请求,服务端下发自己的证书给客户端。客户端收到证书后,通过私钥解密证书,在证书中获取服务端的私钥。客户端利用服务器端的公钥认证证书中的信息,如果一致,则认可这个服务器。

  • 客户端发送自己的证书给服务器端,服务端接收到证书后,通过私钥解密证书。在证书中获取客户端的公钥,并用该公钥认证证书信息,确认客户端是否合法。

  • ③ 服务器端和客户端进行通信。

  • 服务器端和客户端协商好加密方案后,客户端会产生一个随机的私钥并加密,然后发送到服务器端。

  • 服务器端接收到这个私钥后,双方接下来通信的所有内容都通过该随机私钥加密。

授权管理
概述
  • 授权发生在认证成功之后,通过认证就可以知道请求用户是谁,然后kubernetes会根据事先定义的授权策略来决定用户是否有权限访问,这个过程就称为授权。

  • 每个发送到API Server的请求都带上了用户和资源的信息:比如发送请求的用户、请求的路径、请求的动作等,授权就是根据这些信息和授权策略进行比较,如果符合策略,则认为授权通过,否则会返回错误。

API Server目前支持的几种授权策略
  • AlwaysDeny:表示拒绝所有请求,一般用于测试。

  • AlwaysAllow:允许接收所有的请求,相当于集群不需要授权流程(kubernetes默认的策略)。

  • ABAC:基于属性的访问控制,表示使用用户配置的授权规则对用户请求进行匹配和控制。

  • Webhook:通过调用外部REST服务对用户进行授权。

  • Node:是一种专用模式,用于对kubelet发出的请求进行访问控制。

  • RBAC:基于角色的访问控制(kubeadm安装方式下的默认选项)。

RBAC
概述
  • RBAC(Role Based Access Control):基于角色的访问控制,主要是在描述一件事情:给哪些对象授权了哪些权限。

  • RBAC涉及到了下面几个概念:

  • 对象:User、Groups、ServiceAccount。

  • 角色:代表着一组定义在资源上的可操作的动作(权限)的集合。

  • 绑定:将定义好的角色和用户绑定在一起。

  • RBAC还引入了4个顶级资源对象:

  • Role、ClusterRole:角色,用于指定一组权限。

  • RoleBinding、ClusterRoleBinding:角色绑定,用于将角色(权限的集合)赋予给对象。

Role和ClusterRole(角色/权限)
  • 角色:一个角色就是一组权限的集合,这里的权限都是许可形式的(白名单)。

  • Role的资源清单(Role只能对命名空间内的资源进行授权,需要指定namespace

yaml 复制代码
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: authorization-role
  namespace: test #要指定namespace
rules:
  - apiGroups: [""] # 支持的API组列表,""空字符串,表示核心API群
    resources: ["pods"] # 支持的资源对象列表
    verbs: ["get","list"] #支持的操作方法
  • ClusterRole的资源清单(ClusterRole可以对集群范围内的资源、跨namespace的范围资源、非资源类型进行授权,所以不用指定其namespace
yaml 复制代码
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: authorization-clusterrole
rules:
  - apiGroups: [""] # 支持的API组列表,""空字符串,表示核心API群
    resources: ["pods"] # 支持的资源对象列表
    verbs: ["get","list"] #支持的操作方法

rules中的参数说明:

  • apiGroups:

  • 支持的API组列表。

  • "","apps","autoscaling","batch"。

  • resources:

  • 支持的资源对象列表。

  • -"services","endpoints","pods","secrets","configmaps","crontabs","deployments","jobs","nodes","rolebindings","clusterroles","daemonsets","replicasets","statefulsets","horizontalpodautoscalers","replicationcontrollers","cronjobs"。

  • verbs:

  • 对资源对象的操作方法列表。

  • "get", "list", "watch", "create", "update", "patch", "delete", "exec"。

RoleBinding和ClusterRoleBinding(角色绑定)
  • 角色绑定:角色绑定是用来把一个角色绑定到一个目标对象上,绑定目标可以是User、Group或者ServiceAccount。

  • RoleBinding的资源清单:(RoleBinding可以将同一namespace中的subject对象绑定到某个Role下,则此Subject具有该Role定义的权限)

yaml 复制代码
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: authorization-role-binding
  namespace: test
subjects:
  - kind: User
    name: myname
    apiGroup: rbac.authorization.k8s.io  
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: authorization-role
  • ClusterRoleBinding的资源清单:(ClusterRoleBinding在整个集群级别和所有namespaces将特定的subject与ClusterRole绑定,授予权限,其不用指定namespace
yaml 复制代码
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: authorization-clusterrole-binding
subjects:
  - kind: User
    name: myname
    apiGroup: rbac.authorization.k8s.io
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: authorization-clusterrole
RBAC实战(重点⭐)

案例:创建一个只能管理test命名空间下Pods资源的kubernetes账号(帐号名为:user-test)。

创建kubernetes账号
  • 注意:如果账户名你想自定义成自己想要的,那就把所有user-test替换成你的帐号新名称。

  • 1:创建证书:

shell 复制代码
cd /etc/kubernetes/pki/
shell 复制代码
(umask 077;openssl genrsa -out user-test.key 2048)
  • 用API Server的证书去签署证书:

  • 签名申请:申请的用户是user-test,组是testgroup

shell 复制代码
[root@k8s-master pki]# openssl req -new -key user-test.key -out user-test.csr -subj "/CN=user-test/O=testgroup"
  • 签署证书:

shell 复制代码
[root@k8s-master pki]# openssl x509 -req -in user-test.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out user-test.crt -days 3650
Signature ok
subject=/CN=user-test/O=testgroup
Getting CA Private Key
  • 设置集群、用户、上下文信息:(注意:--server的ip地址要改成你的)

shell 复制代码
[root@k8s-master pki]# kubectl config set-cluster kubernetes --embed-certs=true --certificate-authority=/etc/kubernetes/pki/ca.crt --server=https://192.168.184.100:6443
Cluster "kubernetes" set.
shell 复制代码
[root@k8s-master pki]# kubectl config set-credentials user-test --embed-certs=true --client-certificate=/etc/kubernetes/pki/user-test.crt --client-key=/etc/kubernetes/pki/user-test.key
User "user-test" set.
shell 复制代码
[root@k8s-master pki]# kubectl config set-context user-test@kubernetes --cluster=kubernetes --user=user-test
Context "user-test@kubernetes" created.
  • 切换账号到user-test:

shell 复制代码
[root@k8s-master pki]# kubectl config use-context user-test@kubernetes
Switched to context "user-test@kubernetes".
  • 查看namespace为test下的Pod,发现没有权限:

shell 复制代码
[root@k8s-master pki]# kubectl get pods -n test
Error from server (Forbidden): pods is forbidden: User "user-test" cannot list resource "pods" in API group "" in the namespace "test"
  • 切换到admin账户:

shell 复制代码
[root@k8s-master pki]# kubectl config use-context kubernetes-admin@kubernetes
Switched to context "kubernetes-admin@kubernetes".
创建Role和RoleBinding,为user-test授权
  • 1:编写配置文件:
shell 复制代码
vim role-test.yaml
  • 内容如下:
yaml 复制代码
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: role-test
  namespace: test # 通过指定namespace方式来限制这个帐号只能操作这个test命名空间内的资源
rules:
  - apiGroups: [""] # 支持的API组列表,""空字符串,表示核心API群
    resources: ["pods"] # 支持的资源对象列表
    verbs: ["get","list"]

---

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: role-binding-test
  namespace: test # 通过指定namespace方式来限制这个帐号只能操作这个test命名空间内的资源
subjects:
  - kind: User
    name: user-test # 我们在k8s新建的帐号名
    apiGroup: rbac.authorization.k8s.io 
roleRef:
  kind: Role 
  name: role-test
  apiGroup: rbac.authorization.k8s.io
  • 2:执行配置文件:
shell 复制代码
[root@k8s-master pki]# kubectl apply -f role-test.yaml
role.rbac.authorization.k8s.io/role-test created
rolebinding.rbac.authorization.k8s.io/role-binding-test created
切换到新账户进行验证
  • 1:切换账户到user-test:
shell 复制代码
[root@k8s-master pki]# kubectl config use-context user-test@kubernetes
Switched to context "user-test@kubernetes".
  • 2:使用这个新帐号user-test查看namespace为test下的Pod,看看是否成功:(说明权限分配成功了)
shell 复制代码
[root@k8s-master pki]# kubectl get pod -n test
NAME            READY   STATUS    RESTARTS   AGE
pod-configmap   1/1     Running   1          21h
pod-secret      1/1     Running   1          16h
  • 3:因为我们的帐号只能查看test命名空间下的Pod,我们现在查看其它资源:
shell 复制代码
[root@k8s-master pki]# kubectl get pod -n kube-system
Error from server (Forbidden): pods is forbidden: User "user-test" cannot list resource "pods" in API group "" in the namespace "kube-system"
  • 4:切换到admin账户:
shell 复制代码
[root@k8s-master pki]# kubectl config use-context kubernetes-admin@kubernetes
Switched to context "kubernetes-admin@kubernetes".
准入控制
当前可配置的Admission Control(准入控制)
  • AlwaysAdmit:允许所有请求。

  • AlwaysDeny:禁止所有请求,一般用于测试。

  • AlwaysPullImages:在启动容器之前总去下载镜像。

  • DenyExecOnPrivileged:它会拦截所有想在Privileged Container上执行命令的请求。

  • ImagePolicyWebhook:这个插件将允许后端的一个Webhook程序来完成admission controller的功能。

  • Service Account:实现ServiceAccount实现了自动化。

  • SecurityContextDeny:这个插件将使用SecurityContext的Pod中的定义全部失效。

  • ResourceQuota:用于资源配额管理目的,观察所有请求,确保在namespace上的配额不会超标。

  • LimitRanger:用于资源限制管理,作用于namespace上,确保对Pod进行资源限制。

  • InitialResources:为未设置资源请求与限制的Pod,根据其镜像的历史资源的使用情况进行设置。

  • NamespaceLifecycle:如果尝试在一个不存在的namespace中创建资源对象,则该创建请求将被拒 绝。当删除一个namespace时,系统将会删除该namespace中所有对象。

  • DefaultStorageClass:为了实现共享存储的动态供应,为未指定StorageClass或PV的PVC尝试匹配默认StorageClass,尽可能减少用户在申请PVC时所需了解的后端存储细节。

  • DefaultTolerationSeconds:这个插件为那些没有设置forgiveness tolerations并具有notready:NoExecute和unreachable:NoExecute两种taints的Pod设置默认的"容忍"时间,为5min。

  • PodSecurityPolicy:这个插件用于在创建或修改Pod时决定是否根据Pod的security context和可用的 PodSecurityPolicy对Pod的安全策略进行控制

❤️💛🧡本章结束,我们下一章见❤️💛🧡

相关推荐
许白掰1 小时前
Linux入门篇学习——Linux 工具之 make 工具和 makefile 文件
linux·运维·服务器·前端·学习·编辑器
B1nna2 小时前
Docker学习
学习·docker·容器
缘友一世2 小时前
网安系列【15】之Docker未授权访问漏洞
docker·容器
longze_75 小时前
Ubuntu连接不上网络问题(Network is unreachable)
linux·服务器·ubuntu
Dirschs5 小时前
【Ubuntu22.04安装ROS Noetic】
linux·ubuntu·ros
qianshanxue115 小时前
ubuntu 操作记录
linux
AmosTian8 小时前
【系统与工具】Linux——Linux简介、安装、简单使用
linux·运维·服务器
慕木兮人可9 小时前
Docker部署MySQL镜像
spring boot·后端·mysql·docker·ecs服务器
这我可不懂11 小时前
Python 项目快速部署到 Linux 服务器基础教程
linux·服务器·python
车车不吃香菇11 小时前
java idea 本地debug linux服务
java·linux·intellij-idea