Kubernetes(K8S)集群调度

    Scheduler是K8S的调度器,主要是把定义的Pod分配到集群的节点上。

    Scheduler是作为单独的程序进行的,启动之后会一直监听APIServer,获取PodSpec.NodeName为空的Pod,对每个Pod都会创建一个绑定,表明Pod应该放到哪个节点上。

    这其中要考虑很多的问题:

    公平:如果保证每个节点都能被分配资源。

    资源高效利用:集群所有资源最大化被利用。

    效率:调度性能要好,能够尽快的为大批量的Pod完成调度工作。

    灵活:允许用户根据自己的需求控制调度的逻辑。

 

调度过程:

    调度分为几部分:首先是过滤掉不满足条件的节点,这个过程称为Predicate(断言);然后对通过的节点按照优先级排序,这个过程称为Priority(优先级);最后从中选择优先级最高的节点。

    可以看看回头第一章https://blog.csdn.net/Su_Levi_Wei/article/details/103410078

 

   Predicate常见的算法:

    PodFitsResources:节点上剩余的资源是否大于Pod请求的资源

    PodFitsHost:如果Pod指定了NodeName,检查节点名称是否和NodeName匹配

    PodFitsHostPorts:节点上已经使用的Port是否和Pod申请的Port冲突。

    PodSelectorMatchers:过滤掉和Pod指定的Label不匹配的节点。

    NoDiskConflict:已经Mount的Volume和Pod指定的Volume不冲突,除非它们都是只读。

 

    如果Predicate过程中没有合适的节点,Pod会一直在Pending状态,不断重试调度,直到有节点满足条件,经过这个步骤,如果有多个节点满足条件,就继续Priorities过程:按照优先级大小对节点排序。

    优先级是由一系列键值对组成,键是该优先级项的名称,值是它的权重(重要),这些优先级包括:

LestRequestPriority:通过计算CPU和Memory的使用率来决定权重,权重越高,即空闲资源更多的节点。

    BalanceResourceAllocation:节点上的CPU和Memory使用率接近,权重越高。这个应该和上面的一起使用,不应该单独使用。

    ImageLocalityPriority:倾向于一家有要使用镜像的节点,镜像总大小值越大,权重越高。

 

    即经过算法对所有优先级和权重进行计算,得出最终结果,决定这个Pod到哪里去。

亲和性

节点亲和性:

    pod.spec.nodeAffinity

     requiredDuringSchedulingIgnoredDuringExecution:硬策略,不满足就不允许。

     preferredDuringSchedulingIgnoredDuringExecution:软策略,有就允许,没有就算了。

 

#节点亲和性(Pod与Node) - requiredDuringSchedulingIgnoredDuringExecution硬策略

 

#查看键值的标签的键名和键值

kubectl get node --show-labels

 

#键值运算关系:

#In:label的值在某个列表中

#NotIn:label的值不在某个列表中

#Gt:label的值大于某个值

#Lt:label的值小于某个值

#Exists:某个label存在

#DoesNotExist:某个label不存在

 

#注意:如果nodeSelectorTerms下面有多个选项的话,满足任何一个条件就可以了,如果matchExpressions有多个选项的话,则必须同时满足这些条件才能正常调度Pod

 

 

kubectl delete pv --all

kubectl delete pvc --all

 

kubectl get node --show-labels

 

vi pod1.yaml

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

apiVersion: v1

#资源

kind: Pod

metadata:

 name: affinity

 #标签

 labels:

  app: node-affinity-pod

spec:

 #容器

 containers:

 - name: with-node-affinity

   image: levi.harbor.com/library/nginx:1.9.1

 #关联

 affinity:

  #节点关联

  nodeAffinity:

   #策略,硬策略

   requiredDuringSchedulingIgnoredDuringExecution:

    #节点选择

    nodeSelectorTerms:

    - matchExpressions:

      #Node节点的标签

      - key: kubernetes.io/hostname

        #NotIn:label的值不在某个列表中

        operator: NotIn

        #operator: In

        #标签值

        values:

        - k8s-node02

        #- k8s-node03

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

 

kubectl apply -f pod1.yaml

 

kubectl get pod

 

#可以看到是在node1

kubectl get pod -o wide

 

kubectl describe pod pod名

 

kubectl get pod -o wide

 

kubectl delete pod -all

 

#删除重新创建,会发现一直在node01

kubectl delete pod --all && kubectl create -f pod1.yaml && kubectl get pod -o wide

 

#可把yaml找那个的operator改为In,此时会发现一直在node02

vi pod1.yaml

#

kubectl delete pod --all && kubectl create -f pod1.yaml && kubectl get pod -o wide

 

#可以把vlues中的node03改为03,会发现如果找不到就不运行了,这个就是硬策略

vi pod1.yaml

kubectl delete pod --all && kubectl create -f pod1.yaml && kubectl get pod -o wide

 

 

#测试:preferredDuringSchedulingIgnoredDuringExecution软策略

kuctlget node --show-labels

 

vi pod2.yaml

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

apiVersion: v1

#资源

kind: Pod

metadata:

 name: affinity

 #标签

 labels:

  app: node-affinity-pod

spec:

 #容器

 containers:

 - name: wide-node-affinity

   image: levi.harbor.com/library/nginx:1.9.1

 #亲和性关联

 affinity:

  #节点亲和性

  nodeAffinity:

   #软策略

   preferredDuringSchedulingIgnoredDuringExecution:

     #权重越大更亲和

   - weight: 1

     preference:

      #匹配节点

      matchExpressions:

        #标签key

      - key: kubernetes.io/hostname

        #label存在某个列表中

        operator: In

        #标签值

        values:

        - k8s-node03

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

 

#会发现依然运行,软策略及有就更好,没有就满足它即可

kubectl delete pod --all && kubectl create -f pod2.yaml && kubectl get pod -o wide

 

Pod的亲和性:

    pod.spec.affinity.podAffinity(两个Pod运行在同一个Node)/podAntAffinity(两个Pod运行在不同的Node)

     requiredDuringSchedulingIgnoredDuringExecution:硬策略

     preferredDuringSchedulingIgnoredDuringExecution:软策略

 

kubeclt delete pod --all

 

kubectl get pod

 

#podAffinity(两个Pod运行在同一个Node)/podAntiAffinity(两个Pod运行在不同的Node)

vi pod3.yaml

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

apiVersion: v1

kind: Pod

metadata:

 name: pod-3

 #name: pod-2

 labels:

  app: pod-3

spec:

 containers:

 - name: pod-3-container

   image: levi.harbor.com/library/nginx:1.9.1

 affinity:

  #Pod亲和性,运行在同一Node上

  podAffinity:

  #运行在不同Node上

  #podAntiAffinity:

   #硬策略

   requiredDuringSchedulingIgnoredDuringExecution:

   - labelSelector:

      #匹配规则

      matchExpressions:

        #标签值和Key是这个

      - key: app

        values:

        - pod-1

        #label的值在某个列表中

        operator: In

     #运行的Node的节点的key

     topologyKey: kubernetes.io/hostname

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

 

kubectl create -f pod3.yaml

 

kubectl get pod -o wide

 

#给pod打标签

kubectl label pod pod-3 app=pod-1 --overwrite=true

 

kubectl get pod --show-labels -o wide

 

#改为 pod-2,使用podAntiAffinity亲和性策略

vi pod3.yaml

kubectl create -f pod3.yaml && kubectl get pod -o wide

 

#同一节点运行,改为使用podAffinity

vi pod3.yaml

kubectl delete pod pod-2 && kubectl create -f pod3.yaml && kubectl get pod --show-labels -o wide

 

亲和性/反亲和性调度策略比较:

调度策略

匹配标签

操作符

拓扑域支持

调度目标

nodeAffinity

主机

In、NotIn、Exists、DoesNotExist、Gt、Lt

指定主机

podAffinity

Pod

In、NotIn、Exists、DoesNotExist

Pod与指定Pod同一拓扑域

podAnitAffinity

Pod

In、NoIn、Exists、DoesNotExist

Pod与指定Pod不在同一拓扑域

 

   小结:就是让不同的pod处于同一节点或不同节点进行管理

 

污点与容忍

    节点亲和性是Pod的一种属性(偏好或硬件要求),它使得Pod被吸引到一类特定的节点。Taint(污点)则相反,它使节点能够排斥一类特定的Pod。即一个是拉进来,一个是推出去。

    Taint(污点)和Toleration(容忍)相互配合,可以避免Pod被分配到不合适的节点上,每个节点上都可以应用一个或多个Taint(无敌啊),这表示对于那些不能容忍Taint的Pod是不会被该节点接受的。如果将Toleration(容忍)应用于Pod上,则表示这些Pod可以(但不要求)被调度到具有匹配Taint(污点)的节点上。

 

Taint(污点):

    使用kubectl taint命令可以给某个Node节点设置污点,Node被设置上污点之后就和Pod之间存在了一种相斥的关系,可以让Node拒绝Pod的调度执行,甚至将Node已经存在的Pod驱逐出去。

    每个污点的组成:key=value:effect

   

    每个污点都有一个KV作为污点的标签,其中value可以为空,effect则是描述污点的作用。

当前的taint effect(污点影响)支持三个选项:

    NoSchedule K8S不会将Pod调度到据有该污点的Node上。

    PreferNoScheduleK8S将尽量避免将Pod调度到具有该污点的Node上。

    NoExecuteK8S不会将Pod调度到具有该污点上的Node,同时会将Node上已经存在的Pod驱逐出去。

 

#查看污点,可以发现这也是为什么不会分配在Master节点上的原因(NoSchedule)

kubectl describe node k8s-master01 | grep 'Taints'

 

#设置污点

kubectl get pod -o wide

 

#Master是天生就有个污点NoScheduler,给node01和node02也打上污点

kubectl taint nodes k8s-node01 testk=test2:NoExecute

kubectl taint nodes k8s-node02 testk=test2:NoExecute

 

#会发现pod去掉了

kubectl get pod -o wide

 

#运行pod会发现一直处于pending

kubectl create -f pod3.yaml

 

#删除污点

kubectl taint nodes k8s-node01 testk=test2:NoExecute-

kubectl taint nodes k8s-node02 testk=test2:NoExecute-

 

kubectl delete pod --all

 

Tolerations(容忍):

    设置了污点的Node将根据Taint(污点)的effect:NoSchedule、PreferNoSchedule、NoExecute和Pod之间产生互斥关系,Pod将在一定程度上不会被调度到Node上。但可以在Pod上设置Tolerations(容忍),意思是设置了容忍的Pod将可以容忍污点的存在,可以被调度到存在污点的Node上。

 

pod.spec.tolerations

tolerations:

#要与Node上设置的taint的key保持一致

- key: "123"

#要与Node上设置的taint的value保持一致

value: "321"

#要与Node上设置的taint的effect保持一致

effet: "NoSchedule"

#operator的值为Exists时,将会忽略value值

operator: "Equal"

#描述当前Pod需要驱逐时可以在Pod上继续保留运行的时间

tolerationSeconds: 3600

 

#当不指定key值时,表示容忍所有的污点key:

tolerations

- operaor: "Exists"

 

#当不指定effect值时,表示容忍所有的污点作用

tolerations:

 - key: "key"

   operator: "Exists"

 

#先给node01和02打上污点

kubectl taint nodes k8s-node01 testk=test2:NoExecute

kubectl taint nodes k8s-node02 testk=test2:NoExecute

kubectl describe node k8s-node01 | grep 'Taints'

 

#取出污点的key和value,effect要为之前设置的对应的

vi pod.yaml

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

apiVersion: v1

kind: Pod

metadata:

 #name: pod-3

 name: pod-2

 labels:

  app: pod-3

spec:

 containers:

 - name: pod-3-container

   image: levi.harbor.com/library/nginx:1.9.1

 #污点容忍

 tolerations:

   #污点设置的Key和Value的值

 - key: "testk"

   value: "test2"

   #运算

   operator: "Equal"

   effect: "NoExecute"

   #当前Pod需要被驱逐时可以在Pod上继续保留运行的时间

   tolerationSeconds: 3600

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

 

kubectl delete pod --all

 

kubectl apply -f pod.yaml

 

#此时发现有效了

kubectl get pod -o wide

 

#有多个master存在时,防止资源浪费,可以在Master节点上运行pod,但是尽量不允许,可以如下设置

kubectl taint nodes k8s-master01 node-rolt.kubernetes.io/master=:PreferNoSchedule

 

kubectl get node

 

#去除污点

kubectl taint nodes k8s-node01 testkd=test2:NoExecute-

kubectl taint nodes k8s-node02 testkd=test2:NoExecute-

 

固定节点调度

#1.Pod.spec.nodeName将Pod直接调度到指定的Node节点上,会跳过Scheduler的调度策略,该匹配规则是强制匹配

kubectl delete deployment --all

kubectl delete pod --all

kubectl get pod

 

vi assign-pod.yaml

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

apiVersion: extensions/v1beta1

kind: Deployment

metadata:

 name: myweb

spec:

 #副本

 replicas: 7

 #运行配置

 template:

  metadata:

   labels:

    app: myweb-pod

  spec:

   #运行的节点

   nodeName: k8s-node01

   #容器

   containers:

   - name: myweb

     image: levi.harbor.com/library/nginx:1.9.1

     ports:

     - containerPort: 80

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

 

kubectl create -f assign-pod.yaml

 

kubectl get pod -o wide

 

#2.Pod.spec.nodeSelector:通过K8S的label-selector机制选择节点,由调度器调度策略匹配label,而后调度Pod到目标节点,该匹配规则属于强制约束

kubectl delete deployment --all

kubectl delete pod --all

kubectl get pod

 

vi po1.yaml

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

apiVersion: extensions/v1beta1

kind: Deployment

metadata:

 name: myweb221

spec:

 #副本

 replicas: 2

 #运行配置

 template:

  metadata:

   labels:

    app: myweb22222

  spec:

   #使用节点选择器

   nodeSelector:

    #节点标签必须符合test:levi

    test: levi

   #容器

   containers:

   - name: myweb-container

     image: levi.harbor.com/library/nginx:1.9.1

     ports:

     - containerPort: 80

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

 

kubectl apply -f pod1.yaml

 

kubectl get pod

 

#添加标签

kubectl label node k8s-node02 test=levi

 

kubectl get pod

 

kubectl delete deployment --all

kubectl delete pod --all

 

Kubernetes(K8S)安全

    K8S作为一个分布式集群的官吏工具,安全是一个很重要的事情。

    APIServer是集群内部各个组件通信的中介,也是外部控制的入口。所以K8S的安全机制基本是围绕保护APIServer来设计的。

    K8S使用了认证(Authentication)、鉴权(Authorization)、准入控制(Admission Control)三步来保证APIServer的安全。

认证

    Http Token认证:用一个很长的特殊编码方式,且是难易模仿的字符串,Token来表达客户的一种方式。Tomken是一个很长的很复杂的字符串,每一个Token对应一个用户名存储在APIServer能够访问的文件中。当客户端发起API调用请求时,需要再Http Header里面放入Token。

    Http Base认证:通过Base64算法进行编码后的字符串放到Http Request中的Heather Authorization域里发送给服务端,服务端接收到后进行编码,获取用户名和密码。

    Https证书认证:基于CA根证书签名认证客户端身份,可以说是最严格Http验证。

 

K8S需要认证的节点:

 

    K8S组件对APIServer的访问:kubectl、Controller Manager、Scheduler、kubelet、kube-proxy

    K8S管理的Pod对容器的访问:Pod(dashborad也是以Pod形式运行)

 

安全性说明:

    Controller Manager、Sheduler与APIServer在同一台机器,所以直接使用APIServer的非端口发给我你,--insecure-bin-address=127.0.0.1

    kubectl、kubelet、kube-proxy访问APIServer就都需要进行Https双向认证。

 

证书颁发:

    手动:通过K8S集群跟CA进行签发Https证书。

    自动:kubelet首次访问APIServer时,使用Token做认证,通过后,Controller Manager会为kubelet生成一个证书,以后的访问都是用证书做认证了。

 

kubeconfig

    K8S组件通过启动时指定不同的kubeconfig文件可以切换到不同的集群。

kubeconfig这个文件包含:

集群参数(CA证书、APIServer地址)

客户端参数(上面生成的证书和私钥)

    集群context信息(集群名称、用户名)

#查看

cd ~

cd .kube

ls

cat config

 

ServiceAccount

    Pod的容器访问APIServer。因为Pod的创建、销毁是动态的,所以要为它生成证书就不行了。K8S使用了ServiceAccount解决Pod访问APIServer的认证问题。

 

Secret与SA的关系:

    K8S设计了一种资源对象叫Secret,分为两类:一是用于ServiceAccount的service-account-token;二是用于保护用户自定义保密信息的Opaque。ServiceAccount中用到包含三个部分:Token、ca.crt、namespace。

    Token使用APIServer私钥签名的JWT。用来访问APIServer时,Server端认证。

    ca.crt根证书,用于Client端验证APIServer发送的证书。

    namespace标识这个service-account-token的作用域名空间。

 

    JWT(Json Web Token):是为了在网络应用环境之间传递声明而执行的一种基于JSON的开放标准(RFC 7519),该Token被设计为紧凑且安全的,特别使用与分布式站点的单点登录SSO场景。JWT的声明一般被用来身份提供者和服务提供者之间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其他业务逻辑所必须的声明信息,该Token也可以直接被用于认证,也可以被用于加密。

 

#默认情况下每个namespace都会有一个serviceaccount,如果pod在创建时没有指定serviceaccount,就会使用pod所属的namespace的serviceaccount

#默认挂载目录/run/secrets/kubernetes.io/serviceaccount

kubectl get pod -n kube-system

 

#进入容器

kubectl exec kube-proxy-xxx -n kube-system -it -- /bin/sh

cd /run/secrets/kubernetes.io

ls

cd serviceaccount

ls

 

kubectl get secret --all-namespaces

 

kubectl describe secret default-token --namespace=kube-system

 

鉴权

认证过程:

    这个认证过程只是去人了通信双方都确认了对方是可信的,可以相互通信。而鉴权是确定请求发有哪些资源的权限。

APIServer目前支持几种授权策略:(通过APIServer的启动参数”—authorization-mode”设置)

    AlwaysDeny拒绝所有的请求,一般用于测试。

    AlwaysAllow允许接收所有请求,如果集群不需要授权流程,则可以采用

    ABAC(Attribute-Based Access Control):基于属性的访问控制,表示使用用户配置的授权规则对用户请求进行匹配和控制。

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

    RBAC(Role-Based Access Control):基于角色的访问控制,现行默认规则。

 

RBAC授权模式:

    RBAC(Role-Based Access Control)基于角色的访问控制,在K8S 1.5中引入,现行版本默认默认标准。

   优势:

    对集群中的资源和非资源均拥有完整的覆盖。

    整个RBAC完全由几个API对象完成,同其他API对象一样,可以用kubectl或API进行操作。

    可以在运行时进行调整,无需重启APIServer

    RBAC的API资源对象:Role、ClusterRole、RoleBinding、ClusterRolebingding,这四种对象类均可通过kubectl与API操作。

    需要注意的是K8S并不会提供用户管理。K8S组件(kubectl、kube-proxy)或者是其他自定义的用户在向CA申请证书时,需要提供一个证书请求文件。

{

 "CN": "devuser",

 "hosts": [],

 "key": {

  "algo": "rsa",

  "size": 2048

 },

 "names": [

  {

   "C": "CN",

   "ST": "GuangZhou",

   "L": "GuangZhou",

   "O": "k8s",

   "OU": "System"

  } 

 ]

}

 

    APIServer会把客户端证书的CN字段作为User,把name.O字段作为Group。

    kubelet使用TLS Bootstaping认证时,APIServer可以使用Bootstrap Tokens或者Token Authentication File验证=token,无论哪一种K8S都会为token绑定一个默认的User和Group

    Pod使用ServiceAccount认证时,service-account-token中的JWT会保存User信息。

有了用户信息,在创建一对角色/角色绑定(集群角色/集群角色绑定)资源对象,就可以完成全线绑定了。

 

Role And ClusterRole

    在RBAC API中,Role表示一组规则权限,权限只会增加(累加权限),不存在一个资源一开始就有很多权限,而通过RBAC对其进行减少的操作;Role可以定义在一个namespace中,如果想要跨越namespace则可以创建ClusterRole。

apiVersion: rbac.authorization.k8s.io/v1beta1

kind: Role

metadata:

name: pod-reader

namespace: default

rules:

- apiGroups: [""] # "" indicates the core API group

resources: ["pods"]

verbs: ["get", "watch", "list"]

 

    ClusterRole具有与Role相同的权限角色控制能力,不同的是ClusterRole是集群级别的。

ClusterRole可以用于:

    集群级别的资源控制(例如Node访问权限)

    非资源型endpoints(例如/healthz访问)

    所有命名空间资源控制(利润pods)

apiVersion: rbac.authorization.k8s.io/v1beta1

kind: ClusterRole

metadata:

#namespace被省略,因为ClusterRoles没有名称空间

name: secret-reader

rules:

- apiGroups: [""]

resources: ["secrets"]

verbs: ["get", "watch", "list"]

 

RoleBinding And ClusterRoleBinding

    RoleBinding可以将角色中定义的权限授予用户或用户组,RoleBinding包含一组权限列表(Subjects),权限列表中包含有不同形式的待授予权限资源类型(users、groups、or service accounts);RoleBinding同样包含被Bind的Role引用。

apiVersion: rbac.authorization.k8s.io/v1beta1

kind: RoleBinding

metadata:

name: read-pods

namespace: default

subjects:

- kind: User

name: levi

apiGroup: rbac.authorization.k8s.io

roleRef:

kind: Role

name: pod-reader

apiGroup: rbac.authorization.k8s.io

 

RoleBinding适用于某个名称空间的授权,而ClusterRoleBinding适用于集群范围内的授权。

    RoleBinding同样可以引用ClusterRole来对当前的namepsace内用户、用户组或ServiceAccount进行授权,这种操作允许集群管理员在整个集群内定义一些通用的ClusterRole,然后在不同的namespace中使用RoleBinding。

    RoleBinding可以绑定ClusterRoleBinding,而ClusterRoleBinding只能绑定ClusterRoleBinding。

 

Rsources

    对集群内一些资源一般以名称字符串来标识,这些字符串一把会在API的URL地址中出现,同时某些资源也会包含子资源,例如logs资源就属于pods的子资源。

GET /api/v1/namespaces/{namespace}/pods/{name}/log

 

    如果要在RBAC授权默写中控制这些子资源的访问权限可以通过 / 分隔符来实现。

 

#定义一个pods资源logs访问权限的Role定义样例

apiVersion: rbac.authorization.k8s.io/v1beta1

kind: Role

metadata:

namespace: default

name: pod-and-pod-logs-reader

rules:

- apiGroups: [""]

resources: ["pods/log"]

verbs: ["get", "list"]

 

To Subjects

    RoeBinding和ClusterRoleBinding可以将Role绑定到Subjects;Subjects可以是groups、users或service accounts。

#新建一个新的用户

useradd devuser

passwd devuser

 

#使用这个用户登录

su devuser

#访问不了,需要创建一个证书请求

kubectl get pod

#退出

exit

 

#回到root用户

cd /usr/local/kubernetes

mkdir cert

cd cert

mkdir devuser && cd devuser/

vi devuser-cert.json

#将JSON复制过来

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

{

 "CN": "devuser",

 "hosts": [],

 "key": {

  "algo": "rsa",

  "size": 2048

 },

 "names": [

  {

   "C": "CN",

   "ST": "GuangZhou",

   "L": "GuangZhou",

   "O": "k8s",

   "OU": "System"

  } 

 ]

}

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

 

#安装插件

cd /usr/local/kubernetes/cert

wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64

wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64

wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64

cp cfssl* /usr/local/bin

mv /usr/local/bin/cfssljson_linux-amd64 /usr/local/bin/cfssljson

mv /usr/local/bin/cfssl_linux-amd64 /usr/local/bin/cfssl

mv /usr/local/bin/cfssl-certinfo_linux-amd64 /usr/local/bin/cfssl-certinfo

chmod a+x /usr/local/bin/*

 

#此处存储的都是秘钥信息

cd /etc/kubernetes/pki/

cfssl gencert -ca=ca.crt -ca-key=ca.key -profile=kubernetes /usr/local/kubernetes/cert/devuser/devuser-cert.json | cfssljson -bare devuser

 

#devuser.csr、devuser-key.pem、devuser.pem文件

ls

 

cd /usr/local/kubernetes/cert/devuser

 

# 设置集群参数

export KUBE_APISERVER="https://MasterIP:6443"

export KUBE_APISERVER="https://192.168.70.110:6443"

 

kubectl config set-cluster kubernetes \

--certificate-authority=/etc/kubernetes/pki/ca.crt \

--embed-certs=true \

--server=${KUBE_APISERVER} \

--kubeconfig=devuser.kubeconfig

 

#devuser.kubeconfig文件

ls

 

cat devuser.kubeconfig

 

# 设置客户端认证参数

kubectl config set-credentials devuser \

--client-certificate=/etc/kubernetes/pki/devuser.pem \

--client-key=/etc/kubernetes/pki/devuser-key.pem \

--embed-certs=true \

--kubeconfig=devuser.kubeconfig

 

#创建名称空间

kubectl create namespace dev

 

# 设置上下文参数,绑定至某一个名称空间

kubectl config set-context kubernetes \

--cluster=kubernetes \

--user=devuser \

--namespace=dev \

--kubeconfig=devuser.kubeconfig

 

#绑定K8S角色至用户

kubectl create rolebinding devuser-admin-binding --clusterrole=admin --user=devuser --namespace=dev

 

mkdir /home/devuser/.kube/

 

cp /usr/local/kubernetes/cert/devuser/devuser.kubeconfig /home/devuser/.kube/

 

chown devuser:devuser -R /home/devuser/.kube/

chmod 766 /home/devuser/.kube/devuser.kubeconfig

 

chmod 666 /etc/kubernetes/admin.conf

 

#使用新用户登录

su devuser

cd ~/.kube/

ls

mv devuser.kubeconfig config

 

#设置默认上下文 - 使用新用户

kubectl config use-context kubernetes --kubeconfig=config

 

kubectl get pod

 

kubectl run --help

 

kubectl run nginx --image=levi.harbor.com/library/nginx:1.9.1

 

kubectl get pod

 

#在master节点上查看

kubectl get pod --all-namespaces -o wide | grep nginx

 

#新用户执行

kubectl get pod -n default

 

安全准入控制

    准入控制是APIServer的插件集合,通过添加不同的插件,实现额外的准入控制规则。甚至与APIServer的一些主要的功能都需要通过AdmissionControllers实现,比如ServiceAccount。

   官方V1.14版本的准入控制推荐列表:

    NamespaceLifecycle、LimitRanger、ServiceAccount、DefaultStorageClass、DefaultTolerationSeconds、MutatingAdmissionWebhook、ValidatingAdmissionWebhook、ResourceQuota

   常用:

    NamespaceLifecycle防止不存在的namespace上创建对象,防止删除系统预置的namespace,删除namespace时,会连带删除它的所有资源对象。

    LimitRanger确保请求的资源不会超过资源所在Namespace的LimitRange的限制。

    ServiceAccount实现了自动化添加ServiceAccount。

    ResourceQuota确保请求的资源不会超过资源的ResourceQuota限制。

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐