1 安全管理
1.1 安全框架
1.1.1 认证框架
学习目标
这一节,我们从 基础知识、认证流程、小结 三个方面来学习。
基础知识
资源操作
用户访问k8s业务应用的流程:
方法一:无需api_server认证
用户 -- ingress|service -- pod
方法二:基于api_server认证
管理k8s平台上各种应用对象
认证流程
简介
对APIServer的访问一般都要经过的三个步骤,认证(Authn)+授权(Authz)、准入控制(Admission),它也能在一定程度上提高安全性,不过更多是资源管理方面的作用。
注意:认证和授权功能都是以插件化的方式来实现的,这样可以最大化的用户自定义效果。
认证(Authn)
对用户身份进行基本的认证,只允许被当前系统许可的人进入集群内部
授权(Authz)
不同的用户可以获取不同的资源操作权限,比如普通用户、超级用户、等
准入控制(Admission)
类似于审计,主要侧重于 操作动作的校验、语法规范的矫正等写操作场景。
解析
左侧:
对于k8s来说,它主要面对两种用户:
普通人类用户(交互模式) - User Account
集群内部的pod用户(服务进程) - Service Account
中间:
每个部分都是以插件的方式来整合到 k8s 集群环境中:
- 认证和授权是按照 插件的顺序进行依次性的检测,并且遵循 "短路模型" 的认证方式
所谓的"短路"即,失败的时候,到此结束,后续的规则不会进行。
- 准入控制 由于仅用户写操作场景,所以它不遵循 "短路模型",而是会全部检测
原因在于,它要记录为什么不执行,原因是什么,方便后续审计等动作。
小结
1.1.2 框架解读
学习目标
这一节,我们从 流程解读、对象梳理、小结 三个方面来学习。
流程解读
认证
认证用户
在我们的认证范围中,有一个术语叫Subject,它表示我们在集群中基于某些规则和动作尝试操作的对象,在k8s集群中定义了两种类型的subject资源:
User Account:
有外部独立服务进行管理的,对于用户的管理集群内部没有一个关联的资源对象
如果需要操作k8s资源,需要集群内部证书的认证签名。
Service Account
通过Kubernetes API 来管理的一些用户帐号,和 namespace 进行关联的
一般是内部资源对象操作资源的一种方式
用户组
单个控制用户的权限台繁琐,可以借助于用户组的机制实现批量用户的自动化管理,主要有以下几种
system:unauthenticated
未能通过任何一个授权插件检验的账号的所有未通过认证测试的用户统一隶属的用户组;
system:authenticated
认证成功后的用户自动加入的一个专用组,用于快捷引用所有正常通过认证的用户账号;
system:serviceaccounts
所有名称空间中的所有ServiceAccount对象
system:serviceaccounts:<namespace>
特定名称空间内所有的ServiceAccount对象
认证方式
kubernetes的认证方式主要有两种:
证书认证 - 本质上就是TLS双向认证
令牌认证 - 大量手动配置TLS认证比较麻烦,可以将证书生成token进行间接使用。
授权
授权主要是在认证的基础上,用于对集群资源的访问控制权限设置,通过检查请求包含的相关属性值,与相对应的访问策略相比较,API请求必须满足某些策略才能被处理。常见授权机制有:
Node
主要针对节点的基本通信授权认证,比如kubelet的正常通信。
ABAC(Attribute Based Access Control):
基于属性的访问控制,与apiserver服务的本地策略规则紧密相关,一旦变动需要重启。
RBAC(Role Based Access Control):
基于角色的访问控制,这是1.6+版本主推的授权策略,可以使用API自定义角色和集群角色,并将角色和特定的用户,用户组,Service Account关联起来,可以用来实现多租户隔离功能(基于namespace资源)
准入控制
准入控制(Admission Control),实际上是一个准入控制器插件列表,发送到APIServer的请求都需要经过这个列表中的每个准入控制器插件的检查,如果某一个控制器插件准入失败,就准入失败。它主要涉及到pod和容器对特定用户和特定权限之间的关联关系。
比如操作的对象是否存在依赖关系、被操作的对象是否能够增删改查等限制。
对象梳理
资源对象
对象简介
认证对象:SA、token
授权对象:Role、ClusterRole、RoleBinding、ClusterRoleBinding
准入对象:LimitRanger、ResourceQuota、PodSecurityPolicy等
小结
1.2 认证实践
1.2.1 用户实践
学习目标
这一节,我们从 SA实践、UA实践、小结 三个方面来学习。
SA实践
资源属性
apiVersion: v1 # ServiceAccount所属的API群组及版本
kind: ServiceAccount # 资源类型标识
metadata:
name <string> # 资源名称
namespace <string> # ServiceAccount是名称空间级别的资源
automountServiceAccountToken <boolean> # 是否让Pod自动挂载API令牌
secrets <[]Object> # 以该SA运行的Pod所要使用的Secret对象组成的列表
apiVersion <string> # 引用的Secret对象所属的API群组及版本,可省略
kind <string> # 引用的资源的类型,这里是指Secret,可省略
name <string> # 引用的Secret对象的名称,通常仅给出该字段即可
namespace <string> # 引用的Secret对象所属的名称空间
uid <string> # 引用的Secret对象的标识符;
imagePullSecrets <[]Object> # 引用的用于下载Pod中容器镜像的Secret对象列表
name <string> # docker-registry类型的Secret资源的名称
命令解析
命令格式:kubectl create serviceaccount NAME [--dry-run] [options]
作用:创建一个"服务账号"
参数详解
--dry-run=false 模拟创建模式
--generator='serviceaccount/v1' 设定api版本信息
-o, --output='' 设定输出信息格式,常见的有:
json|yaml|name|template|...
--save-config=false 保存配置信息
--template='' 设定配置模板文件
简单实践
创建专属目录
[root@kubernetes-master1 ~]# mkdir /data/kubernetes/secure -p; cd /data/kubernetes/secure
手工创建SA账号
[root@kubernetes-master1 /data/kubernetes/secure]# kubectl create serviceaccount mysa
serviceaccount/mysa created
检查效果
[root@kubernetes-master1 /data/kubernetes/secure]# kubectl get sa mysa
NAME SECRETS AGE
mysa 1 9s
资源清单创建SA
[root@kubernetes-master1 /data/kubernetes/secure]# 01_kubernetes_secure_sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: superopsmsb
---
apiVersion: v1
kind: Pod
metadata:
name: nginx-web
spec:
containers:
- name: nginx-web
image: kubernetes-register.superopsmsb.com/superopsmsb/nginx_web:v0.1
serviceAccountName: superopsmsb
应用资源清单
[root@kubernetes-master1 /data/kubernetes/secure]# kubectl apply -f 01_kubernetes_secure_sa.yaml
serviceaccount/superopsmsb created
pod/nginx-web created
查看资源属性
[root@kubernetes-master1 /data/kubernetes/secure]# kubectl describe pod nginx-web
Name: nginx-web
...
Containers:
nginx-web:
...
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-wqb6w (ro)
...
结果显示:
用户信息挂载到容器的 /var/run/secrets/kubernetes.io/serviceaccount 目录下了
容器内部的账号身份信息
[root@kubernetes-master1 /data/kubernetes/secure]# kubectl exec -it nginx-web -- /bin/sh
# ls /var/run/secrets/kubernetes.io/serviceaccount/
ca.crt namespace token
UA实践
简介
所谓的UA其实就是我们平常做CA时候的基本步骤,主要包括如下几步
1 创建私钥文件
2 基于私钥文件创建证书签名请求
3 基于私钥和签名请求生成证书文件
1 创建私钥文件
给用户 superopsmsb 创建一个私钥,命名成:superopsmsb.key(无加密)
[root@kubernetes-master1 ~]# cd /etc/kubernetes/pki/
[root@kubernetes-master1 /etc/kubernetes/pki]# (umask 077; openssl genrsa -out superopsmsb.key 2048)
G
命令解析:
genrsa 该子命令用于生成RSA私钥,不会生成公钥,因为公钥提取自私钥
-out filename 生成的私钥保存至filename文件,若未指定输出文件,则为标准输出
-numbits 指定私钥的长度,默认1024,该项必须为命令行的最后一项参数
2 签名请求
用刚创建的私钥创建一个证书签名请求文件:superopsmsb.csr
[root@kubernetes-master1 /etc/kubernetes/pki]# openssl req -new -key superopsmsb.key -out superopsmsb.csr -subj "/CN=superopsmsb/O=superopsmsb"
参数说明:
-new 生成证书请求文件
-key 指定已有的秘钥文件生成签名请求,必须与-new配合使用
-out 输出证书文件名称
-subj 输入证书拥有者信息,这里指定 CN 以及 O 的值,/表示内容分隔
CN以及O的值对于kubernetes很重要,因为kubernetes会从证书这两个值对应获取相关信息:
"CN":Common Name,用于从证书中提取该字段作为请求的用户名 (User Name);
浏览器使用该字段验证网站是否合法;
"O":Organization,用于分组认证
检查效果:
[root@kubernetes-master1 /etc/kubernetes/pki]# ls superopsmsb.*
superopsmsb.csr superopsmsb.key
结果显示:
*.key 是我们的私钥,*.csr是我们的签名请求文件
3 生成证书
利用Kubernetes集群的CA相关证书对UA文件进行认证
[root@kubernetes-master1 /etc/kubernetes/pki]# openssl x509 -req -in superopsmsb.csr -CA ./ca.crt -CAkey ./ca.key -CAcreateserial -out superopsmsb.crt -days 365
Signature ok
subject=/CN=superopsmsb/O=superopsmsb
Getting CA Private Key
参数说明:
-req 产生证书签发申请命令
-in 指定需要签名的请求文件
-CA 指定CA证书文件
-CAkey 指定CA证书的秘钥文件
-CAcreateserial 生成唯一的证书序列号
-x509 表示输出一个X509格式的证书
-days 指定证书过期时间为365天
-out 输出证书文件
检查文件效果
[root@kubernetes-master1 /etc/kubernetes/pki]# ls superopsmsb.*
superopsmsb.crt superopsmsb.csr superopsmsb.key
结果显示:
*.crt就是我们最终生成的签证证书
提取信息效果
]# openssl x509 -in superopsmsb.crt -text -noout
Certificate:
...
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=kubernetes
...
Subject: CN=superopsmsb, O=superopsmsb
结果显示:
Issuer: 表示是哪个CA机构帮我们认证的
我们关注的重点在于Subject内容中的请求用户所属的组信息
小结
1.2.2 集群用户
学习目标
这一节,我们从 config基础、简单实践、小结 三个方面来学习。
config基础
简介
根据我们之前对kubernetes集群的了解,我们主要是通过config文件来进入到kubernetes集群内部的,然后具有操作相关资源的权限。
在config文件内部主要做了四件事情:
1 创建登录k8s集群的用户
基于证书和秘钥信息创建用户
2 创建登录k8s集群的地址
3 将登录用户和目标k8s集群关联在一起,形成k8s集群入口
4 设定默认的k8s集群入口
注意:
这里的k8s集群入口其实就类似于我们 通过ssh登录远程主机的一个入口,示例如下:
ssh root@10.0.0.12
命令解读
集群操作
get-clusters 显示 kubeconfig 文件中定义的集群
delete-cluster 删除 kubeconfig 文件中指定的集群
set-cluster Set a cluster entry in kubeconfig
用户操作
delete-user Delete the specified user from the kubeconfig
get-users Display users defined in the kubeconfig
set-credentials Set a user entry in kubeconfig
上下文操作
current-context Display the current-context
delete-context 删除 kubeconfig 文件中指定的 context
get-contexts 描述一个或多个 contexts
rename-context Rename a context from the kubeconfig file
set-context Set a context entry in kubeconfig
use-context Set the current-context in a kubeconfig file
其他操作
set Set an individual value in a kubeconfig file
unset Unset an individual value in a kubeconfig file
view 显示合并的 kubeconfig 配置或一个指定的 kubeconfig 文件
简单实践
创建用户
创建用户
[root@kubernetes-master1 /etc/kubernetes/pki]# kubectl config set-credentials superopsmsb --client-certificate=./superopsmsb.crt --client-key=./superopsmsb.key --embed-certs=true --kubeconfig=/tmp/superopsmsb.conf
参数详解:
set-credentials 子命令的作用就是给kubeconfig认证文件创建一个用户条目
--client-certificate=path/to/certfile 指定用户的签证证书文件
--client-key=path/to/keyfile 指定用户的私钥文件
--embed-certs=true,在kubeconfig中为用户条目嵌入客户端证书/密钥,默认值是false,
--kubeconfig=/path/to/other_config.file 表示将属性信息单独输出到一个文件,不指定的话,表示存到默认的 ~/.kube/config文件中
创建集群
创建集群
[root@kubernetes-master1 /etc/kubernetes/pki]# kubectl config set-cluster mycluster --server="https://10.0.0.200:6443" --certificate-authority=/etc/kubernetes/pki/ca.crt --embed-certs=true --kubeconfig=/tmp/superopsmsb.conf
参数详解:
--server=cluster_api_server
--certificate-authority=path/to/certificate/authority
关联用户和集群
配置上下文信息
[root@kubernetes-master1 /etc/kubernetes/pki]# kubectl config set-context superopsmsb@mycluster --cluster=mycluster --user=superopsmsb --kubeconfig=/tmp/superopsmsb.conf
属性详解
--cluster=cluster_nickname 关联的集群名称
--user=user_nickname 关联的用户名称
--namespace=namespace 可以设置该生效的命名空间
设定默认的入口
更改默认登录kubernetes的用户
[root@kubernetes-master1 /etc/kubernetes/pki]# kubectl config use-context superopsmsb@mycluster --kubeconfig=/tmp/superopsmsb.conf
测试效果
查看配置文件内容
[root@kubernetes-master1 /etc/kubernetes/pki]# kubectl config view --kubeconfig=/tmp/superopsmsb.conf
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://10.0.0.200:6443
name: mycluster
contexts:
- context:
cluster: mycluster
user: superopsmsb
name: superopsmsb@mycluster
current-context: superopsmsb@mycluster
kind: Config
preferences: {}
users:
- name: superopsmsb
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
查看资源测试
[root@kubernetes-master1 /etc/kubernetes/pki]# kubectl get pod --kubeconfig=/tmp/superopsmsb.conf
Error from server (Forbidden): pods is forbidden: User "superopsmsb" cannot list resource "pods" in API group "" in the namespace "default"
结果显示:
虽然提示报错,但是这也证明了用户已经被kubernetes承认了
小结
1.2.3 授权基础
学习目标
这一节,我们从 基础知识、Role实践、clusterRole实践、小结 四个方面来学习。
基础知识
授权场景
授权机制
RBAC使用rbac.authorization.k8s.io API Group 来实现授权决策,允许管理员通过 Kubernetes API 动态配置策略,要启用RBAC,需要在 apiserver 中添加参数--authorization-mode=RBAC,kubeadm安装的集群默认开启了RBAC,我们可以通过查看 Master 节点上 apiserver 的静态Pod定义文件:
[root@kubernetes-master1 ~]# grep authorization-mode /etc/kubernetes/manifests/kube-apiserver.yaml
- --authorization-mode=Node,RBAC
Kubernetes的基本特性就是它的所有资源对象都是模型化的 API 对象,我们可以基于api-server对各种资源进行增、删、改、查等操作,但是这些操作涉及到的不仅仅是资源本身和动作,而且还涉及到资源和动作之间的内容,比如api的分组版本和资源和api的关联即权限授权等。
授权
所谓的授权,其实指的是,将某些subject对象赋予执行某些资源动作的权限。我们有时候会将其称为Group(权限组),而这个组其实是有两部分组成:组名和组关联(也称绑定)。
简单来说:所谓的授权,其实是为用户授予xx角色
关于kubernetes的授权属性,主要包括如下三个层次:namespace级别、cluster级别、混合级别
授权级别
namespace级别
rules
- 规则,是一组属于不同 API Group 资源上的权限操作的集合
role
- 表示在一个namespace中基于rules使用资源的权限,主要涉及到操作和对象
RoleBingding
- 将Subject和Role绑定在一起,表示Subject具有指定资源的role操作权限
cluster级别
ClusterRole
- 表示在一个Cluster中基于rules使用资源的权限
ClusterRoleBingding
- 将Subject和ClusterRole绑定在一起,表示Subject指定资源的ClusterRole操作权限
混合级别
RoleBingding
- 将Subject基于RoleBingding与ClusterRole绑定在一起
- 表示Subject可以使用所有ClusterRole中指定资源的role角色
- 但是限制在了只能操作某个命名空间的资源。
- 也就是所谓的"权限降级"
场景1:
多个namespace中的role角色都一致,如果都使用内部的RoleBingding的话,每个namespace都必须单独创建role,而使用ClusterRole的话,只需要一个就可以了,大大的减轻批量使用namespace中的RoleBingding 操作。
场景2:
我们对A用户要提升权限,但是,由于A处于考察期,那么我们暂时给他分配一个区域,测试一下它的运行效果。生活中的场景,提升张三为公司副总裁,但是由于是新手,所以加了一个限制 -- 主管销售范围的副总裁。
简单实践
属性解析
我们可以使用 kubectl explain role 的方式来查看一下Role的属性信息:
apiVersion <string>
kind <string>
metadata <Object>
rules <[]Object>
apiGroups <[]string>
nonResourceURLs <[]string>
resourceNames <[]string>
resources <[]string>
verbs <[]string> -required-
结果显示:
对于role来说,其核心的内容主要是rules的权限规则
在这么多rules属性中,最重要的是verbs权限条目,而且所有的属性都是可以以列表的形式累加存在
命令行创建role,查看具有pod资源的get、list权限的属性信息
[root@kubernetes-master1 ~]# kubectl create role pods-reader --verb=get,list --resource=pods --dry-run -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
creationTimestamp: null 时间信息
name: pods-reader role的名称
rules: 授权规则
- apiGroups: 操作的对象
- "" 所有权限
resources: 资源对象
- pods pod的对象
verbs: 对pod允许的权限
- get 获取
- list 查看
结果显示:
对于一个role必备的rules来说,他主要有三部分组成:apiGroup、resources、verbs
apiGroups 设定包含资源的api组,如果是多个,表示只要属于api组范围中的任意资源都可以操作
resources 位于apiGroup范围中的某些具体的资源对象
verbs 针对具体资源对象的一些具体操作
注意:
关于api组的信息获取,可以参照https://kubernetes.io/docs/reference/#api-reference
简单实践
按照上面的role格式,我们写一个role资源文件,允许用户操作 Deployment、Pod、RS 的所有权限
[root@kubernetes-master1 /data/kubernetes/secure]# 02_kubernetes_secure_role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: myrole
rules:
- apiGroups: ["", "extensions", "apps"]
resources: ["pods", "deployments", "replicasets"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
属性解析:
Pod属于 core 的 API Group,在YAML中用空字符就可以,Deployment 属于 apps 的 API Group,ReplicaSets属于extensions这个 API Group,所以 rules 下面的 apiGroups 的内容:["", "extensions", "apps"]
verbs是可以对这些资源对象执行的操作,如果是所有动作,也可以使用["*"]来代替。
查看资源对象
初始化实例对象
[root@kubernetes-master1 /data/kubernetes/secure]# kubectl apply -f 02_kubernetes_secure_role.yaml
role.rbac.authorization.k8s.io/myrole created
查看效果
[root@kubernetes-master1 /data/kubernetes/secure]# kubectl describe role myrole
Role用户授权实践
限定用户只能访问命名空间资源
[root@kubernetes-master1 /data/kubernetes/secure]# kubectl create rolebinding super-rolebind --role=myrole --user=superopsmsb
rolebinding.rbac.authorization.k8s.io/super-rolebind created
查看资源效果
[root@kubernetes-master1 /data/kubernetes/secure]# kubectl get pod --kubeconfig=/tmp/superopsmsb.conf
NAME READY STATUS RESTARTS AGE
nginx-web 1/1 Running 0 56m
[root@kubernetes-master1 /data/kubernetes/secure]# kubectl get svc --kubeconfig=/tmp/superopsmsb.conf
Error from server (Forbidden): services is forbidden: User "superopsmsb" cannot list resource "services" in API group "" in the namespace "default"
[root@kubernetes-master1 /data/kubernetes/secure]# kubectl get svc --kubeconfig=/tmp/superopsmsb.conf -n kube-system
Error from server (Forbidden): services is forbidden: User "superopsmsb" cannot list resource "services" in API group "" in the namespace "kube-system"
清理授权
[root@kubernetes-master1 /data/kubernetes/secure]# kubectl delete rolebindings super-rolebind
rolebinding.rbac.authorization.k8s.io "super-rolebind" deleted
ClusterRole实践
属性解析
[root@kubernetes-master1 /data/kubernetes/secure]# kubectl explain clusterrole
aggregationRule <Object>
apiVersion <string>
kind <string>
metadata <Object>
rules <[]Object>
apiGroups <[]string>
nonResourceURLs <[]string>
resourceNames <[]string>
resources <[]string>
verbs <[]string> -required-
结果显示:
clusterrole相对于role的属性多了一个集中控制器的属性aggregationRule,而这是一个可选的属性
命令行创建clusterrole,查看具有pod资源的get、list权限的属性信息
[root@kubernetes-master1 ~]# kubectl create clusterrole myclusterrole --verb=get,list --resource=pods --dry-run -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
creationTimestamp: null 时间信息
name: myclusterrole role的名称
rules: 授权规则
- apiGroups: 操作的对象
- "" 所有权限
resources: 资源对象
- pods pod的对象
verbs: 对pod允许的权限
- get 获取
- list 查看
结果显示:
ClusterRole与role的配置一样,也由三部分组成:apiGroup、resources、verbs
简单实践
按照上面的clusterrole格式,我们写一个clusterrole资源文件,允许用户操作 Deployment、Pod、RS 的所有权限
[root@kubernetes-master1 /data/kubernetes/secure]# 03_kubernetes_secure_clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: myclusterrole
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
创建资源对象
[root@kubernetes-master1 /data/kubernetes/secure]# kubectl apply -f 03_kubernetes_secure_clusterrole.yaml
clusterrole.rbac.authorization.k8s.io/myclusterrole created
查看效果
[root@kubernetes-master1 /data/kubernetes/secure]# kubectl describe clusterrole myclusterrole
Name: myclusterrole
Labels: <none>
Annotations: <none>
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
pods [] [] [get list watch]
ClusterRole用户授权实践
限定用户只能访问命名空间资源
[root@kubernetes-master1 /data/kubernetes/secure]# kubectl create clusterrolebinding super-clusterrolebind --clusterrole=myclusterrole --user=superopsmsb
查看资源效果
[root@kubernetes-master1 /data/kubernetes/secure]# kubectl get pod --kubeconfig=/tmp/superopsmsb.conf
NAME READY STATUS RESTARTS AGE
nginx-web 1/1 Running 0 68m
[root@kubernetes-master1 /data/kubernetes/secure]# kubectl get svc --kubeconfig=/tmp/superopsmsb.conf
Error from server (Forbidden): services is forbidden: User "superopsmsb" cannot list resource "services" in API group "" in the namespace "default"
[root@kubernetes-master1 /data/kubernetes/secure]# kubectl get pod --kubeconfig=/tmp/superopsmsb.conf -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-5d555c984-hzq8q 1/1 Running 0 9h
清理授权
[root@kubernetes-master1 /data/kubernetes/secure]# kubectl delete clusterrolebinding super-clusterrolebind
rolebinding.rbac.authorization.k8s.io "super-clusterrolebind" deleted
小结
1.3.1 授权案例
学习目标
这一节,我们从 案例解读、文件实践、小结 三个方面来学习。
案例解读
简介
接下来我们在kubernetes的默认dashboard上面,来综合演示一下用户的安全管理操作。
对于dashboard来说,他的认证方法主要有两种:令牌认证和文件认证。由于涉及面比较多,我们通过两节的内容来进行讲解,在这里我们用令牌的方式来学习完整的服务认证流程。
令牌认证
- 基于认证用户的唯一令牌来进行认证,有默认的超时机制,一会儿就失效了
文件认证
- 基于账号的token信息,创建kubeconfig文件,实现长久的认证方式。
根据我们之前对serviceaccount的工作流程的学习,对于dashboard的配置也应该遵循相应的操作流程:
1、创建专用的serviceaccount
2、创建对应的权限角色
3、将serviceaccount和权限角色进行关联绑定
令牌认证
集群级别
资源定义文件方式
[root@kubernetes-master1 /data/kubernetes/secure]# 04_kubernetes_secure_dashboard_cluster.yaml
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: dashboard-admin
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
name: dashboard-admin
namespace: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: dashboard-admin
namespace: kube-system
labels:
kubernetes.io/cluster-service: "true"
addonmanager.kubernetes.io/mode: Reconcile
创建资源对象
[root@kubernetes-master1 /data/kubernetes/secure]# kubectl apply -f 04_kubernetes_secure_dashboard_cluster.yaml
clusterrolebinding.rbac.authorization.k8s.io/dashboard-admin created
serviceaccount/dashboard-admin created
获取token信息
[root@kubernetes-master1 /data/kubernetes/secure]# kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')
Name: dashboard-admin-token-4cdrd
...
token: eyJhbG...qU3__b9ITbLHEytrA
复制token到浏览器查看效果
用户级别
资源定义文件方式
[root@kubernetes-master1 /data/kubernetes/secure]# 05_kubernetes_secure_dashboard_namespace.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: dashboard-ns
namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: dashboard-ns
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: admin
subjects:
- kind: ServiceAccount
name: dashboard-ns
namespace: default
创建资源对象
[root@kubernetes-master1 /data/kubernetes/secure]# kubectl apply -f 05_kubernetes_secure_dashboard_namespace.yaml serviceaccount/dashboard-ns created
rolebinding.rbac.authorization.k8s.io/dashboard-ns created
获取token信息
[root@kubernetes-master1 /data/kubernetes/secure]# kubectl describe secrets $(kubectl get secret | awk '/dashboard-ns/{print $1}')
Name: dashboard-ns-token-btq6w
...
token: eyJhbG...qU3__8Kqc0Q
复制token到浏览器查看效果
文件实践
namespace文件实践
设置集群信息
kubectl config set-cluster kubernetes --certificate-authority=/etc/kubernetes/pki/ca.crt --server="https://10.0.0.200:6443" --embed-certs=true --kubeconfig=/root/dashboard-ns.conf
获取秘钥信息
[root@kubernetes-master1 /data/kubernetes/secure]# NAMESPACE_TOKEN=$(kubectl get secret $(kubectl get secret | awk '/dashboard-ns/{print $1}') -o jsonpath={.data.token} |base64 -d)
设置用户信息
kubectl config set-credentials dashboard-ns --token=$NAMESPACE_TOKEN --kubeconfig=/root/dashboard-ns.conf
配置上下文信息
kubectl config set-context dashboard-ns@kubernetes --cluster=kubernetes --user=def-ns-admin --kubeconfig=/root/dashboard-ns.conf
切换用户
kubectl config use-context dashboard-ns@kubernetes --kubeconfig=/root/dashboard-ns.conf
查看效果
[root@kubernetes-master1 /data/kubernetes/secure]# kubectl config view --kubeconfig=/root/dashboard-ns.conf
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://10.0.0.200:6443
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: def-ns-admin
name: dashboard-ns@kubernetes
current-context: dashboard-ns@kubernetes
kind: Config
preferences: {}
users:
- name: dashboard-ns
user:
token: REDACTED
- name: def-ns-admin
user:
token: REDACTED
下载dashboard-ns.conf到windows主机,然后在浏览器上,以kubeconfig文件方式登录dashboard
cluster文件实践
设置集群信息
kubectl config set-cluster kubernetes --certificate-authority=/etc/kubernetes/pki/ca.crt --server="https://10.0.0.200:6443" --embed-certs=true --kubeconfig=/root/dashboard-cluster.conf
获取秘钥信息
[root@kubernetes-master1 /data/kubernetes/secure]# CLUSTER_TOKEN=$(kubectl get secret -n kube-system $(kubectl get secret -n kube-system | awk '/dashboard-admin/{print $1}') -o jsonpath={.data.token} |base64 -d)
设置用户信息
kubectl config set-credentials dashboard-cluster --token=$CLUSTER_TOKEN --kubeconfig=/root/dashboard-cluster.conf
配置上下文信息
kubectl config set-context dashboard-cluster@kubernetes --cluster=kubernetes --user=dashboard-cluster --kubeconfig=/root/dashboard-cluster.conf
切换用户
kubectl config use-context dashboard-cluster@kubernetes --kubeconfig=/root/dashboard-cluster.conf
查看效果
[root@kubernetes-master1 /data/kubernetes/secure]# kubectl config view --kubeconfig=/root/dashboard-cluster.conf
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://10.0.0.200:6443
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: dashboard-cluster
name: dashboard-cluster@kubernetes
current-context: dashboard-cluster@kubernetes
kind: Config
preferences: {}
users:
- name: dashboard-cluster
user:
token: REDACTED
下载dashboard-cluster.conf到windows主机,然后在浏览器上,以kubeconfig文件方式登录dashboard
小结
1.3 网络策略
1.3.1 策略基础
学习目标
这一节,我们从 网络策略、环境部署、小结 三个方面来学习。
网络策略
简介
所谓的网络策略,其实指的是数据的流转控制,我们可以可以借助于网络解决方案来实现,最常见的网络解决方案是: calico
calico
Calico是一个开源的虚拟化网络方案,用于为云原生应用实现互联及策略控制.相较于 Flannel 来说,Calico 的优势是对网络策略(network policy),它允许用户动态定义 ACL 规则控制进出容器的数据报文,实现为 Pod 间的通信按需施加安全策略.不仅如此,Calico 还可以整合进大多数具备编排能力的环境,可以为 虚机和容器提供多主机间通信的功能。
软件结构
Felix
每个节点都有,负责配置路由、ACL、向etcd宣告状态等
BIRD
每个节点都有,负责把 Felix 写入Kernel的路由信息 分发到整个 Calico网络,确保 workload 连通
etcd
存储calico自己的状态数据,可以结合kube-apiserver来工作
官方推荐;
< 50节点,可以结合 kube-apiserver 来实现数据的存储
> 50节点,推荐使用独立的ETCD集群来进行处理。
Route Reflector
路由反射器,用于集中式的动态生成所有主机的路由表,非必须选项
Calico编排系统插件
实现更广范围的虚拟网络解决方案。
参考资料:https://docs.projectcalico.org/reference/architecture/overview
工作模式
对于节点量少的情况下,我们推荐使用左侧默认的模式,当节点量多的时候,我们推荐使用右侧的反射器模式
准备工作
我们之前曾经说过,kubernetes支持很多种网络插件,但是默认情况下只能使用1种,所以为了后续的操作,需要清理之前的flannel插件环境
[root@kubernetes-master1 ~]# cd /data/kubernetes/flannel/
[root@kubernetes-master1 /data/kubernetes/flannel]# kubectl delete -f kube-flannel.yml
在所有节点上重启主机,直接清空所有的路由表信息
[root@kubernetes-master1 /data/kubernetes/flannel]# reboot
重启后,查看网络效果
[root@kubernetes-master1 ~]# ifconfig flannel.1
flannel.1: error fetching interface information: Device not found
[root@kubernetes-master1 ~]# ip route list
default via 10.0.0.2 dev eth0
10.0.0.0/24 dev eth0 proto kernel scope link src 10.0.0.12
169.254.0.0/16 dev eth0 scope link metric 1002
169.254.0.0/16 dev eth1 scope link metric 1003
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1
192.168.8.0/24 dev eth1 proto kernel scope link src 192.168.8.12
结果显示:
网络环境干净了
环境部署
步骤解析
1 获取资源配置文件
从calico官网获取相关的配置信息
2 定制CIDR配置
定制calico自身对于pod网段的配置信息,并且清理无关的网络其他插件
3 定制pod的manifest文件分配网络配置
默认的k8s集群在启动的时候,会有一个cidr的配置,有可能与calico进行冲突,那么我们需要修改一下
4 应用资源配置文件
5 命令完善
1 获取文件
获取文件
[root@kubernetes-master1 /data/kubernetes/secure]# mkdir calico
[root@kubernetes-master1 /data/kubernetes/secure]# cd calico/
[root@kubernetes-master1 /data/kubernetes/secure/calico]# curl https://docs.projectcalico.org/manifests/calico.yaml -O
[root@kubernetes-master1 /data/kubernetes/secure/calico]# cp calico.yaml calico-base.yaml
获取镜像
[root@kubernetes-master1 /data/kubernetes/secure/calico]# for i in $(grep image calico.yaml | uniq | awk -F '/' '{print $3}')
do
docker pull docker.io/calico/$i
docker tag docker.io/calico/$i kubernetes-register.superopsmsb.com/google_containers/$i
docker push kubernetes-register.superopsmsb.com/google_containers/$i
docker rmi docker.io/calico/$i
done
修改配置文件
[root@kubernetes-master1 /data/kubernetes/secure/calico]# sed -i 's#docker.io/calico#kubernetes-register.superopsmsb.com/google_containers#g' calico.yaml
2 配置CIDR
[root@kubernetes-master1 /data/kubernetes/secure/calico]# vim calico.yaml
---- 官网推荐的修改内容
3878 - name: CALICO_IPV4POOL_CIDR
3879 value: "10.244.0.0/16"
---- 方便我们的后续实验,新增调小子网段的分配
3880 - name: CALICO_IPV4POOL_BLOCK_SIZE
3881 value: "24"
配置解析:
开放默认注释的CALICO_IPV4POOL_CIDR变量,然后定制我们当前的pod的网段范围即可
原则上来说,我们修改官方提示的属性即可
3 定制pod的manifest文件分配网络配置
注意:这里我们直接让calico使用kube-controller-manager为节点分配的网段信息
[root@kubernetes-master1 /data/kubernetes/secure/calico]# vim calico.yaml
---- 修改下面的内容
34 "ipam": {
35 "type": "calico-ipam"
36 },
---- 修改后的内容
34 "ipam": {
35 "type": "host-local",
36 "subnet": "usePodCidr"
37 },
---- 定制calico使用k8s集群节点的地址
3882 - name: USE_POD_CIDR
3883 value: "true"
配置解析:
Calico默认并不会从Node.Spec.PodCIDR中分配地址,但可通过USE_POD_CIDR变量并结合host-local这一IPAM插件以强制从PodCIDR中分配地址
4 应用资源配置文件
应用calico插件
[root@kubernetes-master1 /data/kubernetes/secure/calico]# kubectl apply -f calico.yaml
在calico-node部署的时候,会启动多个进程
[root@kubernetes-master1 /data/kubernetes/secure/calico]# kubectl get pod -n kube-system | egrep 'NAME|calico'
5 命令完善
获取专用命令
cd /usr/local/bin/
curl -L https://github.com/projectcalico/calico/releases/download/v3.23.3/calicoctl-linux-amd64 -o calicoctl
mv calicoctl kubectl-calico
chmod +x kubectl-calico
测试效果
kubectl calico node status
5 网络测试
网卡效果
[root@kubernetes-master1 ~]# ifconfig | grep -A1 tunl
tunl0: flags=193<UP,RUNNING,NOARP> mtu 1480
inet 10.244.0.1 netmask 255.255.255.255
路由效果
[root@kubernetes-master1 ~]# ip route list | grep tunl
10.244.1.0/24 via 192.168.8.15 dev tunl0 proto bird onlink
10.244.2.0/24 via 192.168.8.16 dev tunl0 proto bird onlink
10.244.3.0/24 via 192.168.8.17 dev tunl0 proto bird onlink
10.244.5.0/24 via 192.168.8.14 dev tunl0 proto bird onlink
创建一个deployment
[root@kubernetes-master1 ~]# kubectl create deployment nginx-web --image=kubernetes-register.superopsmsb.com/superopsmsb/nginx_web:v0.1 --replicas=3
暴露一个service
[root@kubernetes-master1 ~]# kubectl expose deployment nginx-web --port=80
确认效果
[root@kubernetes-master1 ~]# kubectl get svc nginx-web
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-web ClusterIP 10.101.181.105 <none> 80/TCP 15s
[root@kubernetes-master1 ~]# curl 10.101.181.105
Hello Nginx, nginx-web-5865bb968d-759lc-1.23.0
[root@kubernetes-master1 ~]# curl 10.101.181.105
Hello Nginx, nginx-web-5865bb968d-vsnpv-1.23.0
[root@kubernetes-master1 ~]# curl 10.101.181.105
Hello Nginx, nginx-web-5865bb968d-hrmfw-1.23.0
小结
1.3.2 简单实践
学习目标
这一节,我们从 属性解读、基本控制、小结 三个方面来学习。
属性解读
策略简介
为了使用Network Policy,Kubernetes引入了一个新的资源对象Network Policy,供用户设置Pod间网络访问的策略。策略控制器用于监控指定区域创建对象(pod)时所生成的新API端点,并按需为其附加网络策略。
对于Pod对象来说,网络流量分为 流入(Ingress)和流出(Egress)两个方向,每个方向包含允许和禁止两种控制策略,默认情况下,所有的策略都是允许的,应用策略后,所有未经明确允许的流量都将拒绝。
注意:
网络策略的控制,可以是多个级别:
集群级别、namespace级别、Pod级别、ip级别、端口级别
资源对象属性
apiVersion: networking.k8s.io/v1 # 资源隶属的API群组及版本号
kind: NetworkPolicy # 资源类型的名称,名称空间级别的资源;
metadata: # 资源元数据
name <string> # 资源名称标识
namespace <string> # NetworkPolicy是名称空间级别的资源
spec: # 期望的状态
podSelector <Object> # 当前规则生效的一组目标Pod对象,必选字段;空值表示当前名称空间中的所有Pod资源
policyTypes <[]string> # Ingress表示生效ingress字段;Egress表示生效egress字段,同时提供表示二者均有效
ingress <[]Object> # 入站流量源端点对象列表,白名单,空值表示“所有”
- from <[]Object> # 具体的端点对象列表,空值表示所有合法端点
- ipBlock <Object> # IP地址块范围内的端点,不能与另外两个字段同时使用
- namespaceSelector <Object> # 匹配的名称空间内的端点
podSelector <Object> # 由Pod标签选择器匹配到的端点,空值表示<none>
ports <[]Object> # 具体的端口对象列表,空值表示所有合法端口
egress <[]Object> # 出站流量目标端点对象列表,白名单,空值表示“所有”
- to <[]Object> # 具体的端点对象列表,空值表示所有合法端点,格式同ingres.from;
ports <[]Object> # 具体的端口对象列表,空值表示所有合法端口
注意:
入栈和出栈哪个策略生效,由 policyTypes 来决定。
如果仅配置了podSelector,表明,当前限制仅限于当前的命名空间
配置示例
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: 10.244.0.0/16
except:
- 10.244.1.0/24
- namespacesSelector:
matchLabels:
project: develop
- podSelector:
matchLabels:
arch: frontend
ports:
- protocol: TCP
port: 6379
egress:
- to:
- ipBlock:
cidr: 10.244.0.0/24
ports:
- protocol: TCP
port: 3306
准备工作
在default命名空间创建应用
[root@kubernetes-master1 ~]# kubectl create deployment nginx-web --image=kubernetes-register.superopsmsb.com/superopsmsb/nginx_web:v0.1
[root@kubernetes-master1 ~]# kubectl expose deployment nginx-web --port=80
在superopsmsb命名空间创建应用
[root@kubernetes-master1 ~]# kubectl create deployment nginx-web --image=kubernetes-register.superopsmsb.com/superopsmsb/nginx_web:v0.1 --namespace=superopsmsb
[root@kubernetes-master1 ~]# kubectl expose deployment nginx-web --port=80 --namespace=superopsmsb
确认效果
[root@kubernetes-master1 ~]# kubectl get pod -o wide
NAME READY... AGE IP ...
nginx-web-5865bb968d-759lc 1/1 ... 10s 10.244.1.4 ...
[root@kubernetes-master1 ~]# kubectl get pod -o wide -n superopsmsb
NAME READY... AGE IP ...
nginx-web-65d688fd6-h6sbpp 1/1 ... 10s 10.244.1.5 ...
开启superopsmsb的测试容器
[root@kubernetes-master1 ~]# kubectl exec -it nginx-web-65d688fd6-h6sbp -n superopsmsb -- /bin/bash
root@nginx-web-65d688fd6-h6sbp:/# apt update; apt install net-tools iputils-ping dnsutils curl -y
进入到容器里面查看效果
[root@kubernetes-master1 ~]# kubectl exec -it nginx-web-5865bb968d-759lc -- /bin/bash
root@nginx-web-5865bb968d-759lc:/# apt update; apt install net-tools iputils-ping dnsutils curl -y
域名检测
root@nginx-web-5865bb968d-759lc:/# nslookup nginx-web
Server: 10.96.0.10
Address: 10.96.0.10#53
Name: nginx-web.default.svc.cluster.local
Address: 10.101.181.105
root@nginx-web-5865bb968d-759lc:/# nslookup nginx-web.superopsmsb.svc.cluster.local
Server: 10.96.0.10
Address: 10.96.0.10#53
Name: nginx-web.superopsmsb.svc.cluster.local
Address: 10.105.110.175
ping检测
root@nginx-web-5865bb968d-759lc:/# ifconfig | grep 244
inet 10.244.1.4 netmask 255.255.255.255 broadcast 0.0.0.0
RX packets 22442 bytes 20956160 (19.9 MiB)
root@nginx-web-5865bb968d-759lc:/# ping -c 1 10.244.1.5
PING 10.244.1.5 (10.244.1.5) 56(84) bytes of data.
64 bytes from 10.244.1.5: icmp_seq=1 ttl=63 time=0.357 ms
基本控制
默认拒绝规则
查看资源清单文件
[root@kubernetes-master1 /data/kubernetes/secure]# cat 06_kubernetes_secure_networkpolicy_refuse.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress
namespace: superopsmsb
spec:
podSelector: {}
policyTypes: ["Ingress", "Egress"]
应用资源清单文件
[root@kubernetes-master1 /data/kubernetes/secure]# kubectl apply -f 06_kubernetes_secure_networkpolicy_refuse.yaml
networkpolicy.networking.k8s.io/deny-all-ingress created
尝试default空间资源访问superopsmsb空间资源
root@nginx-web-5865bb968d-759lc:/# ping -c 1 10.244.1.5
PING 10.244.1.5 (10.244.1.5) 56(84) bytes of data.
--- 10.244.1.5 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms
root@nginx-web-5865bb968d-759lc:/# curl nginx-web.superopsmsb.svc.cluster.local
curl: (28) Failed to connect to nginx-web.superopsmsb.svc.cluster.local port 80: Connection timed out
结果显示:
访问失败
default空间资源访问非superopsmsb空间资源正常。
root@nginx-web-5865bb968d-759lc:/# curl nginx-web
Hello Nginx, nginx-web-5865bb968d-759lc-1.23.0
默认启用规则
查看资源清单文件
[root@kubernetes-master1 /data/kubernetes/secure]# cat 07_kubernetes_secure_networkpolicy_allow.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all-ingress
namespace: superopsmsb
spec:
podSelector: {}
policyTypes: ["Ingress", "Egress"]
egress:
- {}
ingress:
- {}
应用资源清单文件
[root@kubernetes-master1 /data/kubernetes/secure]# kubectl apply -f 07_kubernetes_secure_networkpolicy_allow.yaml
networkpolicy.networking.k8s.io/allow-all-ingress created
在default空间访问superopsmsb空间资源
root@nginx-web-5865bb968d-759lc:/# curl nginx-web.superopsmsb.svc.cluster.local
Hello Nginx, nginx-web-65d688fd6-h6sbp-1.23.0
root@nginx-web-5865bb968d-759lc:/# ping -c 1 10.244.1.5
PING 10.244.1.5 (10.244.1.5) 56(84) bytes of data.
64 bytes from 10.244.1.5: icmp_seq=1 ttl=63 time=0.181 ms
结果显示:
网络策略成功了,而且多个网络策略可以叠加
注意:仅仅同名策略或者同类型策略可以覆盖
清理网络策略
[root@kubernetes-master1 /data/kubernetes/secure]# kubectl delete -f 07_kubernetes_secure_networkpolicy_allow.yaml
当前namespace的流量限制
查看资源清单文件
[root@kubernetes-master1 /data/kubernetes/secure]# cat 08_kubernetes_secure_networkpolicy_ns.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-current-ns
namespace: superopsmsb
spec:
podSelector: {}
policyTypes: ["Ingress", "Egress"]
egress:
- to:
- podSelector: {}
ingress:
- from:
- podSelector: {}
配置解析:
虽然设置了egress和ingress属性,但是下面的podSelector没有选择节点,表示只有当前命名空间所有节点不受限制
应用资源清单文件
[root@kubernetes-master1 /data/kubernetes/secure]# kubectl apply -f 08_kubernetes_secure_networkpolicy_ns.yaml
networkpolicy.networking.k8s.io/allow-current-ns created
default资源访问superopsmsb资源
root@nginx-web-5865bb968d-759lc:/# curl nginx-web.superopsmsb.svc.cluster.local
curl: (28) Failed to connect to nginx-web.superopsmsb.svc.cluster.local port 80: Connection timed out
root@nginx-web-5865bb968d-759lc:/# ping -c 1 10.244.1.5
PING 10.244.1.5 (10.244.1.5) 56(84) bytes of data.
结果显示:
访问失败
superopsmsb资源访问同命名空间的其他资源
root@nginx-web-65d688fd6-h6sbp:/# ping 10.244.1.2
PING 10.244.1.2 (10.244.1.2) 56(84) bytes of data.
64 bytes from 10.244.1.2: icmp_seq=1 ttl=63 time=0.206 ms
结果显示:
同命名空间可以正常访问
小结
1.3.3 流量管控
学习目标
这一节,我们从 ip限制实践、pod限制实践、小结 三个方面来学习。
ip限制知识
准备工作
准备同名空间的两个测试pod
终端1
kubectl run superopsmsb-client1 --image=kubernetes-register.superopsmsb.com/superopsmsb/busybox:1.28 -n superopsmsb --rm -it -- /bin/sh
终端2
kubectl run superopsmsb-client2 --image=kubernetes-register.superopsmsb.com/superopsmsb/busybox:1.28 -n superopsmsb --rm -it -- /bin/sh
简介
查看资源清单文件
[root@kubernetes-master1 /data/kubernetes/secure]# cat 09_kubernetes_secure_networkpolicy_ns_pod.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-ns-pod
namespace: superopsmsb
spec:
podSelector: {}
policyTypes: ["Ingress", "Egress"]
egress:
- to:
- podSelector: {}
ingress:
- from:
- ipBlock:
cidr: 10.244.0.0/16
except:
- 10.244.2.0/24
ports:
- protocol: TCP
port: 80
配置解析:
虽然设置了egress和ingress属性,但是下面的podSelector没有选择节点,表示只有当前命名空间所有节点不受限制
应用资源对象文件
[root@kubernetes-master1 /data/kubernetes/secure]# kubectl apply -f 09_kubernetes_secure_networkpolicy_ns_pod.yaml
networkpolicy.networking.k8s.io/deny-ns-pod created
3网段测试容器查看效果
/ # ifconfig | grep 244
inet addr:10.244.3.7 Bcast:0.0.0.0 Mask:255.255.255.255
/ # wget 10.244.1.5
Connecting to 10.244.1.5 (10.244.1.5:80)
index.html 100% |*****************************************************| 46 0:00:00 ETA
/
2网段测试容器查看效果
/ # ifconfig | grep 244
inet addr:10.244.2.6 Bcast:0.0.0.0 Mask:255.255.255.255
/ # wget 10.244.1.5
Connecting to 10.244.1.5 (10.244.1.5:80)
wget: can't connect to remote host (10.244.1.5): Connection timed out
/
结果显示:
同namespace可以进行ip级别的访问测试
pod限制实践
实践
查看在ip限制的基础上,扩充pod限制资源清单文件
[root@kubernetes-master1 /data/kubernetes/secure]# cat 10_kubernetes_secure_networkpolicy_ns_port.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: egress-controller
namespace: superopsmsb
spec:
podSelector: {}
policyTypes: ["Egress"]
egress:
- to:
ports:
- protocol: UDP
port: 53
- to:
ports:
- protocol: TCP
port: 80
配置解析:
虽然设置了egress和ingress属性,但是下面的podSelector没有选择节点,表示只有当前命名空间所有节点不受限制
应用资源对象文件
[root@kubernetes-master1 /data/kubernetes/secure]# kubectl apply -f 10_kubernetes_secure_networkpolicy_ns_port.yaml
networkpolicy.networking.k8s.io/egress-controller created
在所有pod测试容器中
/ # nslookup nginx-web.default.svc.cluster.local
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: nginx-web.default.svc.cluster.local
Address 1: 10.101.181.105 nginx-web.default.svc.cluster.local
/ # nslookup nginx-web
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: nginx-web
Address 1: 10.105.110.175 nginx-web.superopsmsb.svc.cluster.local
结果显示:
在不影响之前的策略的前提下,扩充了dns的解析功能
小结