概述 首先需要了解这三种机制的区别:
认证(Authenticating)是对客户端的认证,通俗点就是用户名密码验证,
授权(Authorization)是对资源的授权,k8s中的资源无非是容器,最终其实就是容器的计算,网络,存储资源,当一个请求经过认证后,需要访问某一个资源(比如创建一个pod),授权检查都会通过访问策略比较该请求上下文的属性,(比如用户,资源和Namespace),根据授权规则判定该资源(比如某namespace下的pod)是否是该客户可访问的。
准入(Admission Control)机制是一种在改变资源的持久化之前(比如某些资源的创建或删除,修改等之前)的机制。 在k8s中,这三种机制如下图:
k8s-authorition
k8s的整体架构也是一个微服务的架构,所有的请求都是通过一个GateWay,也就是kube-apiserver这个组件(对外提供REST服务),由图中可以看出,k8s中客户端有两类,一种是普通用户,一种是集群内的Pod,这两种客户端的认证机制略有不同,后文会详述。但无论是哪一种,都需要依次经过认证,授权,准入这三个机制。
截图来自华为CCE云课堂
kubernetes 中的认证机制 需要注意的是,kubernetes虽然提供了多种认证机制,但并没有提供user 实体信息的存储,也就是说,账户体系需要我们自己去做维护。当然,也可以接入第三方账户体系(如谷歌账户),也可以使用开源的keystone去做整合。kubernetes 支持多种认证机制,可以配置成多个认证体制共存,这样,只要有一个认证通过,这个request就认证通过了。下面列举的是官网几种常见认证机制:
X509 Client Certs
Static Token File
Bootstrap Tokens
Static Password File
Service Account Tokens
OpenID Connect Tokens
这里我主要还是理解一下常用认证方式:
X509 Client Certs 也叫作双向数字证书认证,HTTPS证书认证,是基于CA根证书签名的双向数字证书认证方式,是所有认证方式中最严格的认证。默认在kubeadm创建的集群中是enabled的,可以在master node上查看kube-apiserver的pod配置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 $ cat /usr/lib/systemd/system/kube-apiserver.service .. .. .. .. .. .. .. .. .. .. ExecStart =/usr/local/bin/kube-apiserver \ --v =2 \ --logtostderr =true \ --allow-privileged =true \ --bind-address =0.0.0.0 \ --secure-port =6443 \ --insecure-port =0 \ --advertise-address =192.168.56.110 \ --service-cluster-ip-range =10.96.0.0/12 \ --service-node-port-range =30000-32767 \ --etcd-servers =https://192.168.56.111:2379,https://192.168.56.112:2379,https://192.168.56.113:2379 \ --etcd-cafile =/etc/etcd/ssl/etcd-ca.pem \ --etcd-certfile =/etc/etcd/ssl/etcd.pem \ --etcd-keyfile =/etc/etcd/ssl/etcd-key.pem \ --client-ca-file =/etc/kubernetes/pki/ca.pem \ --tls-cert-file =/etc/kubernetes/pki/apiserver.pem \ --tls-private-key-file =/etc/kubernetes/pki/apiserver-key.pem \ --kubelet-client-certificate =/etc/kubernetes/pki/apiserver.pem \ --kubelet-client-key =/etc/kubernetes/pki/apiserver-key.pem \ .. .. .. .. .. .. .. .. .. ..
相关的三个启动参数:
client-ca-file: 指定CA根证书文件为/etc/kubernetes/pki/ca.pem
tls-private-key-file: 指定ApiServer私钥文件为/etc/kubernetes/pki/apiserver-key.pem
tls-cert-file:指定ApiServer证书文件为/etc/kubernetes/pki/apiserver.pem
请求中需要带有由该证书签名的证书,才能认证通过,客户端签署的证书里包含user,group信息,具体为证书的subject.CommonName(username)以及subject.Organization(group)
Service Account Tokens Service Account Token 是一种比较特殊的认证机制,适用于上文中提到的pod内部服务需要访问apiserver的认证情况,默认enabled。 还是看上文中apiserver 的启动配置参数有–service-account-key-file,如果没有指明文件,默认使用–tls-private-key-file的值,即API Server的私钥。
通过控制器ServiceAccountController会去list,watch k8s apiserver对于命名空间的创建、删除; 就会在新创建的名称空间下创建一个名为”default”的service account;
TokenController 根据创建的ServiceAccount下面关联生成一个带有Token的secret。 Admission 是在通过认证进行鉴权的一个阶段,那么他会默认给当前名称空间下的pod打上,当前名称空间的那个ServiceAccount。
service accout本身是作为一种资源在k8s集群中,我们可以通过命令行获取
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 $ kubectl get sa --all-namespaces NAMESPACE NAME SECRETS AGE default default 1 16d kube-system default 1 16d kube-public default 1 16d kube-system attachdetach-controller 1 16d kube-system bootstrap-signer 1 16d kube-system calico-node 1 16 .. .. .. .. .. ... .. .. .. .. .$ kubectl describe serviceaccount/default -n kube-system Name: default Namespace: kube-system Labels: <none> Annotations: <none> Image pull secrets: <none> Mountable secrets: default-token-q9s9l Tokens: default-token-q9s9l Events: <none> $ kubectl get secret default-token-q9s9l -o yaml -n kube-system apiVersion: v1 data: ca.crt: LS0tLS1CRUdJ .. .. .. .. .. .. .. .略 namespace: a3ViZS1zeXN0ZW0= token: ZXlKaGJHY2lPaUpTVX- .. .. .. .. .. .. .. .略 kind: Secret metadata: annotations: kubernetes.io/service-account.name: default kubernetes.io/service-account.uid: a5568634-f445-11e8-b4c4-000c295134cf creationTimestamp: 2018-11-30T02:14:19Z name: default-token-q9s9l namespace: kube-system resourceVersion: "337" selfLink: /api/v1/namespaces/kube-system/secrets/default-token-q9s9l uid: a56521fd-f445-11e8-aa44-000c29fe5618 type: kubernetes.io/service-account-token [root@k8s-m1 kubelet]#
可以看到service-account-token的secret资源包含的数据有三部分:
ca.crt,这是API Server的CA公钥证书,用于Pod中的Process对API Server的服务端数字证书进行校验时使用的;
namespace,这是Secret所在namespace的值的base64编码:# echo -n “kube-system”|base64 => “a3ViZS1zeXN0ZW0=”
token:该token就是由service-account-key-file的值签署(sign)生成。
API Server的service account authentication(身份验证) 前面说过,service account为Pod中的Process提供了一种身份标识,在Kubernetes的身份校验(authenticating)环节,以某个service account提供身份的Pod的用户名为:
1 system :serviceaccount :(NAMESPACE) :(SERVICEACCOUNT)
以上面那个kube-system namespace下的default
service account为例,使用它的Pod的username全称为:
1 system: serviceaccount: kube-system: default
默认的service account Kubernetes会为每个cluster中的namespace自动创建一个默认的service account资源,并命名为”default”.
如果Pod中没有显式指定spec.serviceAccount字段值(自定义Admission),那么Kubernetes会默认将该namespace下的default service account自动mount到在这个namespace中创建的Pod里,那这个操作就是通过上面所说的ServiceAccountAdmission来实现的。 我们以namespace “default”为例,我们查看一下其中的一个Pod的信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 $ kubectl describe pod nginx-64f497f8fd-lkmdr Name: nginx-64f497f8fd-lkmdr Namespace: default .. .. .. .. .. .. Containers: .. .. .. .. .. .. Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-d5d8g (ro) Conditions: Type Status Initialized True Ready False ContainersReady False PodScheduled True Volumes: .. .. .. .. .. .. Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 27s default-scheduler Successfully assigned default/nginx-64f497f8fd-lkmdr to k8s-m3 Normal Pulling 17s kubelet, k8s-m3 pulling image "nginx"
可以看到,kubernetes将default namespace中的service account “default”的service account token挂载(mount)到了Pod中容器的/var/run/secrets/kubernetes.io/serviceaccount路径下。
深入容器内部,查看mount的serviceaccount路径下的结构:
1 2 3 4 5 6 $ kubectl exec nginx-64f497f8fd-lkmdr -- ls /var /run /secrets/kubernetes.io/serviceaccount ca .crtnamespace token # 这三个文件与上面提到的service account的token 中的数据是一一对应的。
如何创建一个ServiceAccount 1 2 3 4 5 6 7 8 9 10 11 12 13 14 # 通过命令行直接创建 $ kubectl create sa myk8ssa serviceaccount/myk8ssa created $ kubectl describe sa/myk8ssa Name: mysaNamespace: defaultLabels: <none> Annotations: <none> Image pull secrets: <none> Mountable secrets: mysa-token-kcwqm Tokens: mysa-token-kcwqmEvents: <none> # 如何使用?下面我在讨论
kubernetes 中的鉴权机制 目前,k8s 中一共有 4 种鉴权权限模式:
Node: 一种特殊目的的授权模式,主要用来让 kubernetes 遵从 node 的编排规则,实际上是 RBAC 的一部分,相当于只定义了 node 这个角色以及它的权限;
ABAC: Attribute-based access control;
RBAC: Role-based access control;
Webhook: 以 HTTP Callback 的方式,利用外部授权接口来进行权限控制;
这里我主要学习总结最常用的鉴权方式—RBAC
RBAC的鉴权策略可以利用 kubectl 或者 Kubernetes API 直接进行配置。RBAC 可以授权给用户,让用户有权进行授权管理,这样就可以无需接触节点,直接进行授权管理。RBAC 在 Kubernetes 中被映射为 API 资源和操作。
需要理解 RBAC 一些基础的概念和思路,RBAC 是让用户能够访问 Kubernetes API 资源的授权方式。
role 角色是一系列权限的集合,例如一个角色可以包含读取 Pod 的权限和列出 Pod 的权限, ClusterRole 跟 Role 类似,但是可以在集群中到处使用( Role 是 namespace 一级的)。role binding RoleBinding 把角色映射到用户,从而让这些用户继承角色在 namespace 中的权限。ClusterRoleBinding 让用户继承 ClusterRole 在整个集群中的权限。
另外还要考虑cluster roles
和cluster role binding
。cluster role和cluster role binding方法跟role和role binding一样,出了它们有更广的scope。
Kubernetes中的RBAC RBAC 现在被 Kubernetes 深度集成,并使用他给系统组件进行授权。System Roles 一般具有前缀system:,很容易识别:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 $ kubectl get clusterroles --namespace=kube-system NAME AGE admin 16 d anonymous-dashboard-proxy-role 16 d calico-node 16 d calicoctl 16 d cluster-admin 16 d edit 16 d system: aggregate-to-admin 16 dsystem: aggregate-to-edit 16 dsystem: aggregate-to-view 16 dsystem: auth-delegator 16 dsystem: aws-cloud-provider 16 dsystem: basic-user 16 dsystem: certificates.k8s.io: certificatesigningrequests: nodeclient 16 dsystem: certificates.k8s.io: certificatesigningrequests: selfnodeclient 16 dsystem: controller: attachdetach-controller 16 dsystem: controller: certificate-controller 16 dsystem: controller: clusterrole-aggregation-controller 16 dsystem: controller: cronjob-controller 16 dsystem: controller: daemon-set-controller 16 dsystem: controller: deployment-controller 16 dsystem: controller: disruption-controller 16 dsystem: controller: endpoint-controller 16 dsystem: controller: expand-controller 16 d......略
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 $ cat >> role.yaml << EOF kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: namespace: default name: pod-reader rules: - apiGroups: ["" ] # "" indicates the core API group resources: ["pods" ] # 可用操作资源对象 verbs: ["get" , "watch" , "list" ] # 对上面定义资源有哪些操作权限 EOF $ cat >> rolebinding.yaml << EOF kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: name: pod-reader-binding namespace: default subjects: - kind: ServiceAccount name: mysa namespace: default roleRef: kind: Role name: pod-reader apiGroup: rbac.authorization.k8s.io EOF $ kubectl create -f role.yaml role.rbac.authorization.k8s.io/pod-reader created $ kubectl create -f rolebinding.yaml rolebinding.rbac.authorization.k8s.io/pod-reader-binding created [root@k8s-m1 ~]# kubectl get role NAME AGE pod-reader 36s [root@k8s-m1 ~]# kubectl describe role pod-reader Name: pod-reader Labels: <none> Annotations: <none> PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- pods [] [] [get watch list] $ kubectl describe rolebinding pod-reader-binding Name: pod-reader-binding Labels: <none> Annotations: <none> Role: Kind: Role Name: pod-reader Subjects: Kind Name Namespace ---- ---- --------- ServiceAccount mysa default
上面,
我定义了一个pod-reader的role,其中它的权限定义如上方定义的get
,watch
,list
;
然后定义了一个pod-reader-binding的rolebinding 前面提到过;用户通过认证之后就是鉴权,通过SA的认证方式之后拿到userinfo,然后绑定到role里面;那么此时对应的用户权限就是role里面定义的权限,subjects应用的对象类型也可以是User,Group;总之此时这一步就是获取到userinfo信息,然后通过角色绑定。相对应的权限就会赋予该用户。那用户从何而来?下面就需要创建一个用户来访问我们的集群了。
那如何使用我们自己创建的ServiceAccount来登录并且通过自定义的这个RBAC来鉴权呢?这就涉及到了kubeconfig文件生成的问题了
创建kubeconfig 获取上面已创建的ServiceAccount的Seter名称 这里我是在默认namespace下面创建的。
1 2 3 4 5 6 7 8 9 $ kubectl describe sa /myk8ssa Name: myk8ssa Namespace: default Labels: <none> Annotations: <none> Image pull secrets: <none> Mountable secrets: myk8ssa-token-2 kntd Tokens: myk8ssa-token-2 kntd Events: <none>
获取secret下的token,并base64解码获取token明文 1 2 3 $ token=`kubectl get secret myk8ssa-token-2 kntd -oyaml |grep token: | awk '{print $2}' | xargs echo -n | base64 -d` $ echo $token eyJhbGciOiJSUzI1......略
新增用户guomaoqiu 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 $ kubectl config set-cluster my-k8s --server =https://192.168.56.110:8443 \ --certificate-authority =/etc/kubernetes/pki/ca.pem \--embed-certs =true Cluster "my-k8s" set. $ kubectl config set-credentials guomaoqiu --token =$token User "guomaoqiu" set. $ kubectl config set-context my-k8s --cluster =kubernetes Context "my-k8s" created. $ kubectl config set-context my-k8s --user =guomaoqiu Context "my-k8s" modified.
验证 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 $ kubectl config get-contexts CURRENT NAME CLUSTER AUTHINFO NAMESPACE kubernetes-admin@kubernetes kubernetes kubernetes-admin * my-k8s kubernetes guomaoqiu $ kubectl config use-context my-k8s Switched to context "my-k8s" . $ kubectl get pod NAME READY STATUS RESTARTS AGE nginx-64f497f8fd-4qdnt 1 /1 Running 0 10 m $ kubectl delete pod nginx-64f497f8fd-4qdnt Error from server (Forbidden): pods "nginx-64f497f8fd-4qdnt" is forbidden: User "system:serviceaccount:default:myk8ssa" cannot delete pods in the namespace "default" $ kubectl config view apiVersion: v1 clusters: - cluster: certificate-authority-data: REDACTED server: https://192.168.56.110:8443 name: kubernetes - cluster: certificate-authority-data: REDACTED server: https://192.168.56.110:8443 name: my-k8s contexts: - context: cluster: kubernetes user: kubernetes-admin name: kubernetes-admin@kubernetes - context: cluster: kubernetes user: guomaoqiu name: my-k8s current-context: my-k8s kind: Config preferences: {} users: - name: guomaoqiu user: token: ......略 - name: kubernetes-admin user: client-certificate-data: REDACTED client-key-data: REDACTED
通过namespace我们可以做到不同业务之间的隔离,如果再加上如上这种权限控制将会更加细化、以上实验主要是在默认的namespace下面操作,除此之外也可以新建namespace然后进行验证操作。kubeconfig
切换上下文也是非常实用的一种功能。 常用命令:
1 2 3 4 5 6 7 8 kubectl - 使用kubectl来管理Kubernetes集群。 kubectl config set - 在kubeconfig配置文件中设置一个单独的值。 kubectl config set-cluster - 在kubeconfig配置文件中设置一个集群项。 kubectl config set-context - 在kubeconfig配置文件中设置一个环境项。 kubectl config set-credentials - 在kubeconfig配置文件中设置一个用户项。 kubectl config unset - 在kubeconfig配置文件中清除一个单独的值。 kubectl config use-context - 使用kubeconfig中的一个环境项作为当前配置。 kubectl config view - 显示合并后的kubeconfig设置,或者一个指定的kubeconfig配置文件。
kubernetes 中的准入机制 Kubernetes的Admission Control实际上是一个准入控制器(Admission Controller)插件列表,发送到APIServer的请求都需要经过这个列表中的每个准入控制器插件的检查,如果某一个控制器插件准入失败,就准入失败。 更多可查看: http://docs.kubernetes.org.cn/144.html 这里我们主要学习PodSecurityPolicy
安全上下文(Pod SecurityContext) 分为Pod级别和容器级别,容器级别的会覆盖Pod级别的相同设置。 在有PodSecurityPolicy策略的情况下,两者需要配合使用;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 cat >> pod-security-policy.yaml << EOF apiVersion: v1 kind: Pod metadata: name: test-pod spec: volumes: - name: test emptyDir: {} containers: - name: test-pod image: alpine imagePullPolicy: IfNotPresent command: ['sh', '-c' , 'echo The app is running! && sleep 36000' ] volumeMounts: - name: test mountPath: /data/test securityContext: readOnlyRootFilesystem: false privileged: false runAsUser: 1000 EOF $ kubectl create -f pod-security-policy.yaml pod/test-pod created $ kubectl exec -it test-pod sh / $ id uid=1000 gid=0(root) / $ ps -ef PID USER TIME COMMAND 1 1000 0 :00 sleep 36000 6 1000 0 :00 sh 15 1000 0 :00 sh 21 1000 0 :00 ps -ef / $ sysctl -w net.ipv4.tcp_recovery=2 sysctl: error setting key 'net.ipv4.tcp_recovery' : Read-only file system / $
其他更多参数参见: https://kubernetes.io/docs/concepts/policy/pod-security-policy/
运行态的安全控制—网络策略(NetworkPolicy) Kubernetes要求集群中所有pod,无论是节点内还是跨节点,都可以直接通信,或者说所有pod工作在同一跨节点网络,此网络一般是二层虚拟网络,称为pod网络。在安装引导kubernetes时,由选择并安装的network plugin实现。默认情况下,集群中所有pod之间、pod与节点之间可以互通。
网络主要解决两个问题,一个是连通性,实体之间能够通过网络互通。另一个是隔离性,出于安全、限制网络流量的目的,又要控制实体之间的连通性。Network Policy用来实现隔离性,只有匹配规则的流量才能进入pod,同理只有匹配规则的流量才可以离开pod。
但请注意,kubernetes支持的用以实现pod网络的network plugin有很多种,并不是全部都支持Network Policy,为kubernetes选择network plugin时需要考虑到这点,是否需要隔离?可用network plugin及是否支持Network Policy请参考这里 。
基本原理 Network Policy是kubernetes中的一种资源类型,它从属于某个namespace。其内容从逻辑上看包含两个关键部分,一是pod选择器,基于标签选择相同namespace下的pod,将其中定义的规则作用于选中的pod。另一个就是规则了,就是网络流量进出pod的规则,其采用的是白名单模式,符合规则的通过,不符合规则的拒绝。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: test-network-policy namespace: default spec: podSelector: matchLabels: role: db policyTypes: - Ingress - Egress ingress: - from: - ipBlock: cidr: 172.17 .0 .0 /16 except: - 172.17 .1 .0 /24 - namespaceSelector: matchLabels: project: myproject - podSelector: matchLabels: role: frontend ports: - protocol: TCP port: 6379 egress: - to: - ipBlock: cidr: 10.0 .0 .0 /24 ports: - protocol: TCP
对象创建方法与其它如ReplicaSet相同。apiVersion、kind、metadata与其它类型对象含义相同,不详细描述。
.spec.PodSelector 顾名思义,它是pod选择器,基于标签选择与Network Policy处于同一namespace下的pod,如果pod被选中,则对其应用Network Policy中定义的规则。此为可选字段,当没有此字段时,表示选中所有pod。
.spec.PolicyTypes Network Policy定义的规则可以分成两种,一种是入pod的Ingress规则,一种是出pod的Egress规则。本字段可以看作是一个开关,如果其中包含Ingress,则Ingress部分定义的规则生效,如果是Egress则Egress部分定义的规则生效,如果都包含则全部生效。当然此字段也可选,如果没有指定的话,则默认Ingress生效,如果Egress部分有定义的话,Egress才生效。怎么理解这句话,下文会提到,没有明确定义Ingress、Egress部分,它也是一种规则,默认规则而非没有规则。
.spec.ingress与.spec.egress 前者定义入pod规则,后者定义出pod规则,详细参考这里,这里只讲一下重点。上例中ingress与egress都只包含一条规则,两者都是数组,可以包含多条规则。当包含多条时,条目之间的逻辑关系是“或”,只要匹配其中一条就可以。.spec.ingress[].from 也是数组,数组成员对访问pod的外部source进行描述,符合条件的source才可以访问pod,有多种方法,如示例中的ip地址块、名称空间、pod标签等,数组中的成员也是逻辑或的关系。spec.ingress[].from.prots表示允许通过的协议及端口号。
.spec.egress.to 定义的是pod想要访问的外部destination,其它与ingress相同。
kubernetes 默认NetworkPolicy: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 #默认禁止所有出口请求 apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: default-denyspec: podSelector: {} policyTypes: - Egress # 默认禁止所有入口请求 apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: default-denyspec: podSelector: {} policyTypes: - Ingress # 默认允许所有出口请求 apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: allow-allspec: podSelector: {} egress: - {} policyTypes: - Egress # 默认允许所有入口请求 apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: allow-allspec: podSelector: {} egress: - {} policyTypes: - Ingress
默认策略 无需详解,但请注意,pod与所运行节点之间流量不受Network Policy限制。
示例 下面通过一个真实示例展示Network Policy普通用法。
用Deployment创建nginx pod实例并用service暴露 1 2 3 4 $ kubectl run nginx --image =nginx --replicas =3 deployment.apps/nginx created $ kubectl expose deployment nginx --port =80 service/nginx exposed
确认创建结果 1 2 3 4 5 6 7 8 9 $ kubectl get pod,svc NAME READY STATUS RESTARTS AGE pod/nginx-64 f497f8fd-9 mfd7 1 /1 Running 0 2 m pod/nginx-64 f497f8fd-nss94 1 /1 Running 0 2 m pod/nginx-64 f497f8fd-zs926 1 /1 Running 0 2 m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.96 .0 .1 <none> 443 /TCP 3 d service/nginx ClusterIP 10.111 .254 .191 <none> 80 /TCP 14 s
测试nginx服务连通性 1 2 3 4 5 $ kubectl run busybox --rm -it --image=busybox /bin/sh If you don't see a command prompt, try pressing enter. / Connecting to nginx (10.111.254.191:80) /
通过创建Network Policy对象添加隔离性 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 $ cat >> pod-network-policy.yaml << EOF kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: access-nginx spec: podSelector: matchLabels: # 默认该pod就有run =app这个标签了,我这里无需在从新定义 run: nginx ingress: - from : - podSelector: matchLabels: access: "true" EOF $ kubectl create -f pod-network-policy.yaml networkpolicy.networking.k8s.io/access-nginx created $ kubectl describe networkpolicy access-nginx Name: access-nginx Namespace: default Created on: 2018-12-17 01:16:57 -0500 EST Labels: <none> Annotations: <none> Spec: PodSelector: run =nginx Allowing ingress traffic: To Port: <any> (traffic allowed to all ports) From : PodSelector: access =true Allowing egress traffic: <none> (Selected pods are isolated for egress connectivity) Policy Types: Ingress
测试隔离性 1 2 3 4 5 $ kubectl run busybox --rm -it --image=busybox /bin/sh If you don't see a command prompt, try pressing enter. / Connecting to nginx (10.111.254.191:80) wget: download timed out
为pod添加access: “true”标签后再次测试连通性 1 2 3 4 $ kubectl run busybox --rm -it --labels= "access=true" --image=busybox /bin/sh If you don't see a command prompt, try pressing enter. / Connecting to nginx (10.111.254.191:80)
参考:https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ https://kubernetes.io/docs/reference/access-authn-authz/rbac/ https://kubernetes.io/docs/concepts/services-networking/network-policies/ https://kubernetes.io/docs/tasks/access-application-cluster/configure-access-multiple-clusters/ https://kubernetes.io/docs/concepts/policy/pod-security-policy/