K8S集群安全机制:
Kubernetes 作为一个分布式集群的管理工具,保证集群的安全性是其一个重要的任务。API Server 是集群内部
各个组件通信的中介,也是外部控制的入口。所以 Kubernetes 的安全机制基本就是围绕保护 API
Server 来设计的。Kubernetes 使用了认证(Authentication)、鉴权(Authorization)、准入控制(Admission Control)三步来保证API Server的安全 。
Authentication(认证)
第三方授权协议: authenticating proxy
HTTP Token 认证:通过一个 Token 来识别合法用户
HTTP Token 的认证是用一个很长的特殊编码方式的并且难以被模仿的字符串 - Token 来表达客户
的一种方式。Token 是一个很长的很复杂的字符串,每一个 Token 对应一个用户名存储在 API Server能访问的文件中。当客户端发起 API 调用请求时,需要在 HTTP Header 里放入 Token
HTTP Base 认证:通过 用户名+密码 的方式认证
用户名+:+密码 用 BASE64 算法进行编码后的字符串放在 HTTP Request 中的 Heather
Authorization 域里发送给服务端,服务端收到后进行编码,获取用户名及密码
最严格的 HTTPS 证书认证:基于 CA 根证书签名的客户端身份认证方式
1. HTTPS 证书认证: 采用双向加密认证方式
2. 证书颁发 :
手动签发:通过 k8s 集群的跟 ca 进行签发 HTTPS 证书
自动签发:kubelet 首次访问 API Server 时,使用 token 做认证,通过后,Controller
Manager 会为 kubelet 生成一个证书,以后的访问都是用证书做认证了
3. 安全性说明
Controller Manager、Scheduler 与 API Server 在同一台机器,所以直接使用 API Server 的
非安全端口 访问, --insecure-bind-address=127.0.0.1
kubectl、kubelet、kube-proxy 访问 API Server 就都需要证书进行 HTTPS 双向认证
4. kubeconfig 文件包含集群参数(CA证书、API Server地址),客户端参数(上面生成的证书
和私钥),集群context 信息(集群名称、用户名)。Kubenetes 组件通过启动时指定不同的
kubeconfig 文件可以切换到不同的集群
一个 Kubernetes 集群包含 集群由一组被称作节点的机器组成。这些节点上运行 Kubernetes 所管理的容器化应用。集群具有至少一个工作节点和至少一个主节点。
工作节点托管作为应用程序组件的 Pod 。主节点管理集群中的工作节点和 Pod 。多个主节点用于为集群提供故障转移和高可用性。
这张图表展示了包含所有相互关联组件的 Kubernetes 集群。
控制平面组件(Control Plane Components)
控制平面的组件对集群做出全局决策(比如调度),以及检测和响应集群事件(例如,当不满足部署的replicas 字段时,启动新的 pod)。
控制平面组件可以在集群中的任何节点上运行。然而,为了简单起见,设置脚本通常会在同一个计算机上启动所有控制平面组件,并且不会在此计算机上运行用户容器。
kube-apiserver
主节点上负责提供 Kubernetes API 服务的组件;它是 Kubernetes 控制面的前端。
1. kube-apiserver是Kubernetes最重要的核心组件之一
2. 提供集群管理的REST API接口,包括认证授权,数据校验以及集群状态变更等
3. 提供其他模块之间的数据交互和通信的枢纽(其他模块通过API Server查询或修改数据,只有API Server才直接操作etcd)
4. 生产环境可以为apiserver做LA或LB。在设计上考虑了水平扩缩的需要。 换言之,通过部署多个实例可以实现扩缩。 参见构造高可用集群。
etcd
1. kubernetes需要存储很多东西,像它本身的节点信息,组件信息,还有通过kubernetes运行的pod,deployment,service等等。都需要持久化。etcd就是它的数据中心。生产环境中为了保证数据中心的高可用和数据的一致性,一般会部署最少三个节点。
2. 这里只部署一个节点在master。etcd也可以部署在kubernetes每一个节点。组成etcd集群。
3. 如果已经有etcd外部的服务,kubernetes直接使用外部etcd服务
节点组件在每个节点上运行,维护运行的 Pod 并提供 Kubernetes 运行环境。
kubelet
一个在集群中每个节点上运行的代理。它保证容器都运行在 Pod 中。
1. 一个在集群中每个工作节点上都运行一个kubelet服务进程,默认监听10250端口,接收并执行master发来的指令,管理Pod及Pod中的容器。每个kubelet进程会在API Server上注册节点自身信息,定期向master节点汇报节点的资源使用情况,并通过cAdvisor监控节点和容器的资源。
kube-proxy
1. 一个在集群中每台工作节点上都应该运行一个kube-proxy服务,它监听API server中service和endpoint的变化情况,并通过iptables等来为服务配置负载均衡,是让我们的服务在集群外可以被访问到的重要方式。
容器运行环境(Container Runtime)
容器运行环境是负责运行容器的软件。
Kubernetes 支持多个容器运行环境: Docker、 containerd、cri-o、 rktlet 以及任何实现 Kubernetes
CRI (容器运行环境接口)。
NameSpace介绍
Namespace是对一组资源和对象的抽象集合,比如可以用来将系统内部的对象划分为不同的项目组或用户组。常见的pods, services, replication controllers和deployments等都是属于某一个namespace的(默认是default),而node, persistentVolumes等则不属于任何namespace。
大多数的Kubernetes中的集群默认会有一个叫default的namespace。实际上,应该是4个:
default:你的资源默认被创建于default命名空间。
kube-system:kubernetes系统组件使用。
kube-node-lease: kubernetes集群节点租约状态,v1.13加入
kube-public:公共资源使用。但实际上现在并不常用。
这个默认(default)的namespace并没什么特别,但你不能删除它
查看命名空间
kubectl get namespace
查看所有命名空间的pod资源
kubectl get pod --all-namespaces
kubectl get pod -A
简写命令
kubectl get ns
说明
default 用户创建的pod默认在此命名空间
kube-public 所有用户均可以访问,包括未认证用户
kube-node-lease kubernetes集群节点租约状态,v1.13加入
kube-system kubernetes集群在使用
创建NameSpace
kubectl create namespace lagou
简写命令
kubectl create ns lagou
删除NameSpace
kubectl delete namespace lagou
简写命令
kubectl delete ns lagou
pod
Pod是kubernetes集群能够调度的最小单元。Pod是容器的封装 。
在Kubernetes集群中,Pod是所有业务类型的基础,也是K8S管理的最小单位级,它是一个或多个
容器的组合。这些容器共享存储、网络和命名空间,以及如何运行的规范。在Pod中,所有容器都被同一安排和调度,并运行在共享的上下文中。对于具体应用而言,Pod是它们的逻辑主机,Pod包含业务相关的多个应用容器。
Pod有两个必须知道的特点。
网络:每一个Pod都会被指派一个唯一的Ip地址,在Pod中的每一个容器共享网络命名空间,包括Ip地址和网络端口。在同一个Pod中的容器可以和localhost进行互相通信。当Pod中的容器需要与Pod外的实体进行通信时,则需要通过端口等共享的网络资源。
存储:Pod能够被指定共享存储卷的集合,在Pod中所有的容器能够访问共享存储卷,允许这些容器共享数据。存储卷也允许在一个Pod持久化数据,以防止其中的容器需要被重启。
Pod的工作方式
K8s一般不直接创建Pod。 而是通过控制器和模版配置来管理和调度
Pod重启
在Pod中的容器可能会由于异常等原因导致其终止退出,Kubernetes提供了重启策略以重启容器。重启策略对同一个Pod的所有容器起作用,容器的重启由Node上的kubelet执行。Pod支持三种重启策略,在配置文件中通过restartPolicy字段设置重启策略:
1. Always:只要退出就会重启。
2. OnFailure:只有在失败退出(exit code不等于0)时,才会重启。
3. Never:只要退出,就不再重启
资源限制
Kubernetes通过cgroups限制容器的CPU和内存等计算资源,包括requests(请求,调度器保证调度到资源充足的Node上)和limits(上限)等。
查看Pod
查看default命名空间下的pods
kubectl get pods
查看kube-system命名空间下的pods
kubectl get pods -n kube-system
查看所有命名空间下的pods
kubectl get pod --all-namespaces
kubectl get pod -A
创建Pod
下载镜像
K8S集群的每一个节点都需要下载镜像:选择不同的基础镜像,下载镜像的大小也不同。
docker pull tomcat:9.0.20-jre8-alpine 108MB
docker pull tomcat:9.0.37-jdk8-openjdk-slim 305MB
docker pull tomcat:9.0.37-jdk8 531MB
同学们可以自行下载后进行备份。
docker save -o tomcat9.tar tomcat:9.0.20-jre8-alpine
docker load -i tomcat9.tar
运行pod
在default命名空间中创建一个pod副本的deployment
kubectl run tomcat9-test --image=tomcat:9.0.20-jre8-alpine --port=8080
kubectl get pod
kubectl get pod -o wide
使用pod的IP访问容器
crul ***:8080
扩容
将副本扩容至3个
kubectl scale --replicas=3 deployment/tomcat9-test
kubectl get deployment
kubectl get deployment -o wide
使用deployment的IP访问pod
创建服务
kubectl expose deployment tomcat9-test --name=tomcat9-svc --port=8888 --
target-port=8080 --protocol=TCP --type=NodePort
kubectl get svc
kubectl get svc -o wide
访问服务端口
curl 10.105.225.0:8888
访问集群外端口
http://192.168.198.120:30217