CKA认证 | Day8 K8s安全

第八章 Kubernetes安全

1、Kubernetes RBAC授权

Kubernetes 基于角色的访问控制(Role-Based Access Control, RBAC) 是一种强大的权限管理机制,用于控制用户、用户组、服务账户对 Kubernetes 集群资源的访问。通过 RBAC,可以细粒度地定义哪些用户或服务账户可以执行哪些操作,从而增强集群的安全性和可管理性。

1.1 Kubernetes 安全框架

K8S安全控制框架主要由下面3个阶段进行控制,每一个阶段都支持 插件方式,通过 API Server 配置来启用插件。

  1. Authentication(鉴权),验证用户身份是否为可信任的

  2. Authorization(授权),判断用户是否有权限访问某个资源

  3. Admission Control(准入控制),是否有额外的校验能力做相关方面的验证

1.1.1 鉴权(Authentication)

K8s Apiserver提供三种客户端身份认证:

  • HTTPS 证书认证:基于CA证书签名的数字证书认证(kubeconfig),例如./kube/config
  • HTTP Token认证:通过一个Token来识别用户(serviceaccount),例如加入集群、Dashboard的Token
  • HTTP Base认证:用户名+密码的方式认证(1.19版本弃用)
1.1.2 授权(Authorization)

RBAC(Role-Based Access Control,基于角色的访问控制):负责完成授权(Authorization)工作。

RBAC根据API请求属性,决定允许还是拒绝。

比较常见的授权维度:

  • user:用户名
  • group:用户分组
  • 资源,例如pod、deployment
  • 资源操作方法:get,list,create,update,patch,watch,delete
  • 命名空间
  • API组
1.1.3 准入控制(Admission Control)

Adminssion Control实际上是一个准入控制器插件列表,发送到API Server的请求都需要经过这个列表中的每个准入控 制器插件的检查,检查不通过,则拒绝请求。

  • 启用一个准入控制器:

kube-apiserver --enable-admission-plugins=NamespaceLifecycle,LimitRanger ...

  • 关闭一个准入控制器:

kube-apiserver --disable-admission-plugins=PodNodeSelector,AlwaysDeny ...

  • 查看默认启用:

kubectl exec kube-apiserver-k8s-master -n kube-system -- kube-apiserver -h | grep enable-admission-plugins

**补充:**方便用于可以自定义、扩展访问时的检查控制功能;对k8s功能做一个解耦

javascript 复制代码
## 查看准入控制器
[root@k8s-master-1-71 ~]# vi /etc/kubernetes/manifests/kube-apiserver.yaml

1.2 基于角色的权限访问控制:RBAC

RBAC(Role-Based Access Control,基于角色的访问控制), 是K8s默认授权策略,并且是动态配置策略(修改即时生效)

主体(subject)

  • User:用户
  • Group:用户组
  • ServiceAccount:服务账号

角色

  • Role:授权特定命名空间的访问权限
  • ClusterRole:授权所有命名空间的访问权限

角色绑定

  • RoleBinding:将角色绑定到主体(即subject)
  • ClusterRoleBinding:将集群角色绑定到主体

注:RoleBinding在指定命名空间中执行授权,ClusterRoleBinding在集群范围执行授权。

RBAC 的工作原理

定义角色:

  • 使用 Role 或 ClusterRole 定义权限规则。
  • 例如,定义一个 Role 允许用户查看和列出 Pod。

绑定角色:

  • 使用 RoleBinding 将 Role 绑定到特定用户、用户组或服务账户。
  • 例如,将 pod-reader 角色绑定到用户 jane,使其在 default 命名空间中拥有对 Pod 的读取权限。

权限验证:

  • 当用户尝试执行操作时,Kubernetes 会检查相关的 RoleBinding 和 ClusterRoleBinding。
  • 根据绑定的角色和规则,决定是否允许该操作。

1)角色相关命令:
① role角色:

  • 创建role: kubectl create role <role-name> --verb=<操作方法> --resource=<资源> [-n namespace]

例如:创建名称为 "pod-reader" 的 Role 对象,允许用户对 Pods 执行 get、watch 和 list 操作

bash 复制代码
kubectl create role pod-reader --verb=get --verb=list --verb=watch --resource=pods
  • 查看role:kubectl get role [-n namespace]
  • 删除role:kubectl delete role <role-name> [-n namespace]

② clusterrole角色:

  • 创建clusterrole:kubectl create clusterrole <clusterrole-name> --verb=<操作方法> --resource=<资源>

例如:创建名称为 "pod-reader" 的 ClusterRole 对象,允许用户对 Pods 对象执行 get、 watch 和 list 操作

bash 复制代码
kubectl create clusterrole pod-reader --verb=get,list,watch --resource=pods
  • 查看clusterrole:kubectl get clusterrole
  • 删除clusterrole:kubectl delete clusterrole <clusterrole-name>

2)角色绑定相关命令:
① rolebinding

  • 绑定rolebinding: kubectl create rolebinding <rolebinding-name> --serviceaccount=<namespace:serviceaccount-name> --clusterrole=<role-name或clusterrole-name> [-n namespace]
  • 查看rolebinding: kubectl get rolebinding [-n namespace]
  • 删除rolebinding: kubectl delete rolebinding <rolebinding-name> [-n namespace]

② clusterrolebinding

  • 绑定clusterrolebinding: kubectl create clusterrolebinding <clusterrolebinding-name> --serviceaccount=<namespace:serviceaccount-name> --clusterrole=<clusterrole-name>
  • 查看clusterrolebinding: kubectl get clusterrolebinding
  • 删除clusterrolebinding: kubectl delete clusterrolebinding <clusterrolebinding-name>

1.3 RBAC授权-kubeConfig(配置文件)

**案例:**为指定用户授权访问不同命名空间权限,例如新入职一个小弟,希望让他先熟悉K8s集群,为了 安全性,先不能给他太大权限,因此先给他授权访问default命名空间Pod读取权限。

RBAC授权流程:

  1. 用K8S CA根证书去签发客户端证书

  2. 生成kubeconfig授权文件

  3. 创建RBAC权限策略(限制访问资源)

  4. 指定kubeconfig文件测试权限:kubectl get pods --kubeconfig=./aliang.kubeconfig


步骤1:使用cfsll工具,拿K8S CA根证书去签发客户端证书

命令:

javascript 复制代码
cfssl gencert -ca=ca.crt \   //根证书
-ca-key=ca.key \             //根密钥
-config=ca-config.json \     //根证书配置文件
-profile="kubernetes" \      //ca-config.json根证书配置文件的"profiles"
aliang-csr.json | cfssljson -bare aliang    //aliang-csr.json为客户端证书请求配置文件,aliang为生成证书前缀
bash 复制代码
# 查看 k8s CA 根证书目录
[root@k8s-master-1-71 ~]# ls /etc/kubernetes/pki/
apiserver.crt              apiserver-etcd-client.key  apiserver-kubelet-client.crt  ca.crt  etcd                front-proxy-ca.key      front-proxy-client.key  sa.pub
apiserver-etcd-client.crt  apiserver.key              apiserver-kubelet-client.key  ca.key  front-proxy-ca.crt  front-proxy-client.crt  sa.key
## ca.crt 根证书,ca.key 根证书密钥

**补充:**CA根证书可理解为大学,客户端证书类似毕业证,需要由CA证书去签发

**补充:**在kubeadm部署集群的时候,生成ca根证书的配置文件(ca-config.json,主要描述有效期及其它属性)已自动删除,所以在 /etc/kubernetes/pki/ 目录下无法查看到,需要使用 ca根证书的配置文件 及 客户端证书请求配置文件(xx-csr.json) 去签发客户端证书

javascript 复制代码
[root@k8s-master-1-71 ~]# mkdir rbac-ssl ; mv rbac.zip rbac-ssl/

[root@k8s-master-1-71 ~]# unzip rbac.zip -d rbac-ssl/
[root@k8s-master-1-71 rbac]# bash cert.sh    //运行签发客户端证书脚本
cat > ca-config.json <<EOF     ## ca根证书的配置文件
{
  "signing": {
    "default": {
      "expiry": "87600h"
    },
    "profiles": {
      "kubernetes": {
        "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ],
        "expiry": "87600h"
      }
    }
  }
}
EOF

cat > aliang-csr.json <<EOF     ## 客户端证书请求配置文件
{
  "CN": "aliang",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "k8s",
      "OU": "System"
    }
  ]
}
EOF

cfssl gencert -ca=/etc/kubernetes/pki/ca.crt -ca-key=/etc/kubernetes/pki/ca.key -config=ca-config.json -profile=kubernetes aliang-csr.json | cfssljson -bare aliang

步骤2:生成kubeconfig授权文件

补充: kubectl config 命令用来生成或修改 kubeconfig 配置文件用途

javascript 复制代码
[root@k8s-master-1-71 rbac]# bash kubeconfig.sh    //运行脚本
# 设置集群
kubectl config set-cluster kubernetes \         ## set-cluster名称可自定义
--certificate-authority=/etc/kubernetes/pki/ca.crt \
--embed-certs=true \                            ## 将证书嵌套kubeconfig配置文件里,false则是路径形式
--server=https://192.168.1.71:6443 \            ## 指定APIserver地址
--kubeconfig=aliang.kubeconfig                  ## 指定生成的kubeconfig,文件名自定义

# 设置客户端认证
kubectl config set-credentials aliang \         ## set-credentials名称可自定义
--client-key=aliang-key.pem \                   ## 指定客户端证书
密钥
--client-certificate=aliang.pem \               ## 指定客户端证书

--embed-certs=true \
--kubeconfig=aliang.kubeconfig

# 设置默认上下文
kubectl config set-context kubernetes \         ## set-context名称可自定义
--cluster=kubernetes \                          ## 指定上述的cluster
--user=aliang \                                 ## 指定上述的user
--kubeconfig=aliang.kubeconfig

# 设置当前使用配置
kubectl config use-context kubernetes --kubeconfig=aliang.kubeconfig    ## 指定上述的默认上下文

**补充:**适用于一个kubeconfig配置文件中有多个上下文,只需要 use-context 指定即可。

步骤3:创建角色,并将用户与角色绑定

**补充:**apiGroups: 指定组,可以通过kubectl api-resources查看,v1是核心API组,apps/V1则apps为组

javascript 复制代码
### 创建角色(权限集合)
[root@k8s-master-1-71 rbac]# kubectl apply -f rbac.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""]         # api组,例如apps组,而空值表示是核心API组,像namespace、pod、service、pv、pvc都在里面
  resources: ["pods"]     # 资源名称(复数),例如pods、deployments、services
  verbs: ["get","watch","list"]      # 资源操作方法

# 将用户与角色绑定
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: default
subjects:              # 绑定的主体
- kind: User
  name: aliang         # 主体名称(aliang-csr.json的 CN 字段)
  apiGroup: rbac.authorization.k8s.io
roleRef:               # 绑定的角色
  kind: Role
  name: pod-reader     # role名称
  apiGroup: rbac.authorization.k8s.io
javascript 复制代码
# 查看角色与角色绑定
[root@k8s-master-1-71 rbac]# kubectl get role
NAME                                    CREATED AT

pod-reader                              2023-03-06T19:27:06Z
[root@k8s-master-1-71 rbac]# kubectl get rolebinding
NAME                                    ROLE                                         AGE

read-pods                               Role/pod-reader                              111s

步骤4:在不同节点上进行验证

javascript 复制代码
kubectl get pod --kubeconfig=aliang.kubeconfig

上述步骤是以kubeconfig文件访问k8s集群,kubeconfig文件会绑定一个用户的证书,而RBAC则是在k8s集群里绑定了用户参数即客户端配置文件的"CN"字段, 所以不管在哪里使用config文件访问集群,集群都会识别config文件里的用户,通过鉴权识别是否有这个用户,授权手段查看用户有什么权限;因考虑K8S集群的安全性,建议可以把生成xxx.kubeconfig的配置文件拷贝至其它的机器上运行,前提是网络之间需要优先联通


**示例:**针对核心API组、deployemnt组的pods、deployment资源可进行delete删除操作

javascript 复制代码
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: ["","apps"]         # 核心API组、deployemnt组
  resources: ["pods","deployments"]     # 资源名称
  verbs: ["delete"]      # 资源操作方法

1.4 RBAC授权- ServiceAccount(服务账号)

ServiceAccount(服务账号)简称SA,用于让集群内Pod访问k8s Api。RBAC的授权方式与kubeconfig方式一样。

**补充:**SA不需要使用证书授权访问,SA属于集群里的虚拟账号

命令:

  • 创建Serviceaccount(主体): kubectl create serviceaccount [-n namespace]

  • 查看Serviceaccount(主体): kubectl get serviceaccount [-n namespace]

**补充:**在创建Role角色的时候需要指定命名空间,创建ClusterRole角色是不需要指定。


命令行-示例1:为一个服务账号分配只能创建deployment、daemonset、 statefulset的权限。

javascript 复制代码
# 创建命名空间
[root@k8s-master-1-71 ~]# kubectl create namespace app-team
[root@k8s-master-1-71 ~]# kubectl get ns
NAME                   STATUS   AGE
app-team               Active   27s

# 指定在app-team命名空间下,创建服务账号
[root@k8s-master-1-71 ~]# kubectl create serviceaccount sa-test -n app-team

[root@k8s-master-1-71 ~]# kubectl get sa -n app-team
NAME      SECRETS   AGE
sa-test   0         39s

# 创建集群角色(指定操作方法,指定限制资源)
[root@k8s-master-1-71 ~]# kubectl create clusterrole controller-test \
--verb=create --resource=deployments,daemonsets,statefulsets
[root@k8s-master-1-71 ~]# kubectl get clusterrole | grep test
controller-test                                                        2023-03-07T01:48:07Z

# 将服务账号绑定角色(指定主体,指定角色)
[root@k8s-master-1-71 ~]# 
kubectl create rolebinding controller-sa-test-bind \
--serviceaccount=app-team:sa-test \          //指定主体,命名空间:Serviceaccount-name
--clusterrole=controller-test \    //指定要绑定的角色
-n app-team    //给Rolebinding指定命名空间,不指定默认是在default空间

**注意:**如果 sa 和 role 在某个指定的命名空间下,使用 rolebinding 绑定时需要指定该ns,否则无法使用sa账户+role角色去访问该命名空间的资源。

补充:

  • role 是指定命名空间的role角色,绑定时需要指定到某命名空间(不指定默认是在default空间)
  • clusterrole 是集群的role全局角色,绑定时任何命名空间都可以

测试:服务账号权限

javascript 复制代码
[root@k8s-master-1-71 ~]# kubectl --as=system:serviceaccount:app-team:sa-test create deployment web2 --image=nginx -n app-team
[root@k8s-master-1-71 ~]# kubectl get pods -n app-team
NAME                    READY   STATUS    RESTARTS   AGE
web2-5d48fb75c5-2brvr   1/1     Running   0          14m

对应的YAML文件-示例2:

javascript 复制代码
apiVersion: v1
kind: ServiceAccount
metadata:
  name: sa-test
  namespace: app-team

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: controller-test
rules:
- apiGroups: ["apps"]
  resources: ["deployments","daemonsets","statefulsets"] 
  verbs: ["create"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: controller-test-bind
  namespace: app-team
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: controller-test
subjects:
- kind: ServiceAccount
  name: sa-test
  namespace: app-team
1.4.1 SA服务账号使用场景:

**场景1:**使用role角色与rolebinding的方法

javascript 复制代码
[root@k8s-master-1-71 ~]# kubectl create sa test1 -n app-team

[root@k8s-master-1-71 ~]# kubectl create role test1-role --verb=get,list,watch,create --resource=deployments,daemonsets,statefulsets -n app-team

[root@k8s-master-1-71 ~]# kubectl create rolebinding test1-rb --serviceaccount=app-team:test1 --role=test1-role -n app-team

# 测试:
[root@k8s-master-1-71 ~]# kubectl --as=system:serviceaccount:app-team:test1 get deployments
Error from server (Forbidden): deployments.apps is forbidden: User "system:serviceaccount:app-team:test1" cannot list resource "deployments" in API group "apps" in the namespace "default"
[root@k8s-master-1-71 ~]# kubectl --as=system:serviceaccount:app-team:test1 get deployments -n app-team
No resources found in app-team namespace.

结论:需要保证sa、role、rolebingding在同一个命名空间下,否则不指定命名空间将无法访问

注意:如角色是role,无法通过clusterrolebinding去绑定主体和角色。

**场景2:**使用clusterrole角色 与 rolebinding、clusterrolebinding 的方法,且不指定命名空间(默认为defaults)

javascript 复制代码
[root@k8s-master-1-71 ~]# kubectl create sa test2
[root@k8s-master-1-71 ~]# kubectl create clusterrole test2-role --verb=get,list,watch,create --resource=deployments,daemonsets,statefulsets
[root@k8s-master-1-71 ~]# kubectl create rolebinding test2-rb --serviceaccount=default:test2 --clusterrole=test2-role

## 使用 clusterrolebinding(可以在任意命名空间下查看deployments)
[root@k8s-master-1-71 ~]# kubectl create clusterrolebinding test2-rb2 --serviceaccount=default:test2 --clusterrole=test2-role
[root@k8s-master-1-71 ~]# kubectl --as=system:serviceaccount:default:test2 get deployments
No resources found in default namespace.

[root@k8s-master-1-71 ~]# kubectl --as=system:serviceaccount:default:test2 get deployments -n app-team
No resources found in app-team namespace.

## 使用 rolebinding(只可以在sa所在的命名空间下查看deployments)
[root@k8s-master-1-71 ~]# kubectl delete clusterrolebinding test2-rb2

[root@k8s-master-1-71 ~]# kubectl --as=system:serviceaccount:default:test2 get deployments
No resources found in default namespace.

[root@k8s-master-1-71 ~]# kubectl --as=system:serviceaccount:default:test2 get deployments -n app-team
Error from server (Forbidden): deployments.apps is forbidden: User "system:serviceaccount:default:test2" cannot list resource "deployments" in API group "apps" in the namespace "app-team"

结论:role 和 rolebinding 在绑定服务帐号,一般都需要指定服务帐号的命名空间创建(包括default);而 clusterrolebinding 是全局性的绑定不用考虑命名空间

2、网络访问控制

2.1 网络访问控制应用场景

默认情况下,Kubernetes 集群网络没任何网络限制,Pod 可以与任何其他 Pod 通信,在 某些场景下就需要进行网络控制,减少网络攻击面,提高安全性,这就会用到网络策略。

网络策略(Network Policy):是一个K8s资源,用于限制Pod出入流量,提供Pod级别和 Namespace级别网络访问控制。

网络策略的应用场景(偏重多租户下):

  • 应用程序间的访问控制,例如项目A不能访问项目B的Pod

  • 开发环境命名空间不能访问测试环境命名空间Pod

  • 当Pod暴露到外部时,需要做Pod白名单

2.2 网络策略概述

官网:Search Results | Kubernetes

javascript 复制代码
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
          port: 5978
  • **podSelector:**根据标签进行选择目标Pod(把网络策略应用到目标Pod上)
  • **policyTypes:**策略类型,指定策略用于入站、出站流量。
  • **Ingress:**from是可以访问的白名单,可以来自于IP段、命 名空间、Pod标签等,ports是可以访问的端口。
  • **Egress:**这个Pod组可以访问外部的IP段和端口。

Network Policy 网络策略工作流程:

1、客户端创建Network Policy资源提交到集群中

2、Policy Controller监控网络策略,同步并通知节点上程序

3、节点上DaemonSet运行的程序从etcd中获取Policy,调用本 地Iptables创建防火墙规则
补充:NetworkPolicy是由网络组件实现的,例如calico,在每个节点上都是DaemonSet进行部署的。而kube-controllers则是负责网络策略下发的。

相关命令:

  • 查看网络策略: kubectl get networkpolicy -n

2.3 网络访问控制3个案例

javascript 复制代码
# 准备测试环境,分别在不同的命名空间创建Pod
kubectl create namespace test   //创建命名空间
kubectl run bs --image=busybox -- sleep 24h
kubectl run web --image=nginx
kubectl run bs --image=busybox -n test -- sleep 24h
kubectl run web --image=nginx -n test

[root@k8s-master-1-71 ~]# kubectl get pods -o wide
NAME                                  READY   STATUS    RESTARTS      AGE   IP              NODE             NOMINATED NODE   READINESS GATES
bs                                    1/1     Running   0             50m   10.244.117.17   k8s-node1-1-72   <none>           <none>
web                                   1/1     Running   0             49m   10.244.117.18   k8s-node1-1-72   <none>           <none>

[root@k8s-master-1-71 ~]# kubectl get pods -o wide -n test
NAME   READY   STATUS    RESTARTS   AGE     IP              NODE             NOMINATED NODE   READINESS GATES
bs     1/1     Running   0          2m31s   10.244.114.23   k8s-node2-1-73   <none>           <none>
web    1/1     Running   0          54m     10.244.114.19   k8s-node2-1-73   <none>           <none>

案例1:拒绝其他命名空间Pod访问

需求:test 命名空间下所有pod可以互相访问,也可以访问其他命 名空间Pod,但其他命名空间不能访问test命名空间Pod。

javascript 复制代码
[root@k8s-master-1-71 ~]# kubectl apply -f networkpolicy-test1.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy-1
  namespace: test
spec:
  podSelector: {}       # 配置{},表示匹配当前命名空间所有的pod
  policyTypes:          # 定义策略类型
    - Ingress
  ingress:
    - from:
        - podSelector: {}   # 配置{},只有当前命名空间pod可以进流量

测试:

javascript 复制代码
[root@k8s-master-1-71 ~]# kubectl get networkpolicy -n test
NAME                    POD-SELECTOR   AGE
test-network-policy-1   <none>         31s
[root@k8s-master-1-71 ~]# kubectl describe networkpolicy test-network-policy-1 -n test
Name:         test-network-policy-1
Namespace:    test
Created on:   2023-03-24 18:38:39 +0800 CST
Labels:       <none>
Annotations:  <none>
Spec:
  PodSelector:     <none> (Allowing the specific traffic to all pods in this namespace)   //允许特定流量到该名称空间中的所有pod
  Allowing ingress traffic:
    To Port: <any> (traffic allowed to all ports)
    From:
      PodSelector: <none>
  Not affecting egress traffic
  Policy Types: Ingress


# 从test命名空间访问外部Pod可以正常访问
[root@k8s-master-1-71 ~]# kubectl exec -it bs -n test -- sh
/ # ping 10.244.117.18
PING 10.244.117.18 (10.244.117.18): 56 data bytes
64 bytes from 10.244.117.18: seq=0 ttl=62 time=0.635 ms

# 在default命名空间测试访问test命名空间pod web不能访问
[root@k8s-master-1-71 ~]# kubectl exec -it bs -- sh
/ # ping 10.244.114.19
PING 10.244.114.19 (10.244.114.19): 56 data bytes
4 packets transmitted, 0 packets received, 100% packet loss

案例2:同一个命名空间下,应用之间限制访问

需求:将 test 命名空间携带run=web标签的Pod隔离,只允许携 带 run=client1 标签的Pod访问80端口。

**注意:**若存在2个不同的网络策略,不能同时用在同一个命名空间下的Pod

javascript 复制代码
[root@k8s-master-1-71 ~]# kubectl apply -f networkpolicy-test2.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy-2
  namespace: test
spec:
  podSelector:
    matchLabels:
      run: web
  policyTypes:
    - Ingress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              run: client1
      ports:
        - protocol: TCP
          port: 80

测试

javascript 复制代码
# 查看 networkpolicy 网络策略
[root@k8s-master-1-71 ~]# kubectl get networkpolicy -n test   //限制的是标签为 run=web 的Pod
NAME                    POD-SELECTOR   AGE
test-network-policy-2   run=web        30s

[root@k8s-master-1-71 ~]# kubectl describe networkpolicy test-network-policy-2 -n test
Name:         test-network-policy-2
Namespace:    test
Created on:   2023-03-24 19:13:27 +0800 CST
Labels:       <none>
Annotations:  <none>
Spec:
  PodSelector:     run=web
  Allowing ingress traffic:
    To Port: 80/TCP               //运行TCP 80进流量访问
    From:
      PodSelector: run=client1    //标签为 run=client1 访问
  Not affecting egress traffic
  Policy Types: Ingress

[root@k8s-master-1-71 ~]# kubectl get pods -n test --show-labels
NAME   READY   STATUS    RESTARTS   AGE   LABELS
bs     1/1     Running   0          23m   run=bs
web    1/1     Running   0          75m   run=web

# 限制前,标签为 run=bs Pod还可以正常访问 run=web Pod
[root@k8s-master-1-71 ~]# kubectl exec -it bs -n test -- sh
/ # ping 10.244.114.19
PING 10.244.114.19 (10.244.114.19): 56 data bytes
64 bytes from 10.244.114.19: seq=0 ttl=63 time=0.122 ms

# 限制后,标签为 run=bs Pod不能访问 run=web Pod
[root@k8s-master-1-71 ~]# kubectl exec -it bs -n test -- sh
/ # ping 10.244.114.19
PING 10.244.114.19 (10.244.114.19): 56 data bytes
4 packets transmitted, 0 packets received, 100% packet loss

# 重新设置标签为 run=client1 ,再次测试网页下载正常
[root@k8s-master-1-71 ~]# kubectl label pods bs -n test run=client1 --overwrite
[root@k8s-master-1-71 ~]# kubectl get pods -n test --show-labels
NAME   READY   STATUS    RESTARTS   AGE   LABELS
bs     1/1     Running   0          40m   run=client1
[root@k8s-master-1-71 ~]# kubectl exec -it bs -n test -- sh
/ # ping 10.244.114.19
PING 10.244.114.19 (10.244.114.19): 56 data bytes
14 packets transmitted, 0 packets received, 100% packet loss     //由于策略是限制TCP 80访问,ICMP被限制
/ # wget 10.244.114.19    //网页下载正常
'index.html' saved

案例3:只允许指定命名空间中的应用访问

需求:只允许dev命名空间中的Pod 访问 prod命名空间中的pod 80端口

环境准备:

javascript 复制代码
[root@k8s-master-1-71 ~]# kubectl create namespace dev
[root@k8s-master-1-71 ~]# kubectl create namespace prod
[root@k8s-master-1-71 ~]# kubectl label namespace dev name=dev

[root@k8s-master-1-71 ~]# kubectl get ns --show-labels | grep -E "prod|dev"
dev                    Active   30m    kubernetes.io/metadata.name=dev,name=dev
prod                   Active   29m    kubernetes.io/metadata.name=prod
[root@k8s-master-1-71 ~]# kubectl run bs --image=busybox -n dev -- sleep 24h
[root@k8s-master-1-71 ~]# kubectl run web --image=nginx -n prod
javascript 复制代码
[root@k8s-master-1-71 ~]# kubectl apply -f networkpolicy-test3.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: networkpolicy-test3
  namespace: prod
spec:
  podSelector: {} 
  policyTypes:
    - Ingress
  ingress:
    - from:
        - namespaceSelector:     # 匹配命名空间标签
            matchLabels:
              name: dev
      ports:
        - protocol: TCP
          port: 80

测试:

javascript 复制代码
# dev命名空间中的Pod 可以访问 prod命名空间中的pod,且是80端口
[root@k8s-master-1-71 ~]# kubectl exec -it bs -n dev -- sh
/ # wget 10.244.117.20
'index.html' saved

# default命名空间中的Pod 无法访问 prod命名空间中的pod
[root@k8s-master-1-71 ~]# kubectl exec -it bs -- sh
/ # wget 10.244.117.20
Connecting to 10.244.117.20 (10.244.117.20:80)
...

课后作业

1、完成网络策略案例3:只允许指定命名空间中的应用访问

小结

本篇为 【Kubernetes CKA认证 Day8】的学习笔记,希望这篇笔记可以让您初步了解到 RBAC授权、网络访问控制;课后还有扩展实践,不妨跟着我的笔记步伐亲自实践一下吧!


Tip:毕竟两个人的智慧大于一个人的智慧,如果你不理解本章节的内容或需要相关笔记、视频,可私信小安,请不要害羞和回避,可以向他人请教,花点时间直到你真正的理解。

相关推荐
bugtraq20216 分钟前
XiaoMi Mi5(gemini) 刷入Ubuntu Touch 16.04——安卓手机刷入Linux
linux·运维·ubuntu
xmweisi13 分钟前
【华为】报文统计的技术NetStream
运维·服务器·网络·华为认证
VVVVWeiYee17 分钟前
BGP配置华为——路径优选验证
运维·网络·华为·信息与通信
陆鳐LuLu38 分钟前
日志管理利器:基于 ELK 的日志收集、存储与可视化实战
运维·elk·jenkins
土豆沒加1 小时前
K8S的Dashboard登录及验证
云原生·容器·kubernetes
DC_BLOG1 小时前
Linux-GlusterFS进阶分布式卷
linux·运维·服务器·分布式
cookies_s_s1 小时前
Linux--进程(进程虚拟地址空间、页表、进程控制、实现简易shell)
linux·运维·服务器·数据结构·c++·算法·哈希算法
大腕先生2 小时前
微服务环境搭建&架构介绍(附超清图解&源代码)
微服务·云原生·架构
终端行者2 小时前
kubernetes1.28部署mysql5.7主从同步,使用Nfs制作持久卷存储,适用于centos7/9操作系统,
数据库·容器·kubernetes
zhouwu_linux2 小时前
MT7628基于原厂的SDK包, 修改ra1网卡的MAC方法。
linux·运维·macos