努力挣扎的生活 努力挣扎的生活
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • 运维基础
  • 监控
  • 日志系统
  • gitlab安装
  • jenkins安装和管理
  • Jenkins工具集成
  • pipeline流水线
  • Dcoker
  • Kubernetes
  • Nexus
  • Rancher
  • Prometheus
  • ELK(EFK)
  • 虚拟化
  • Mysql
  • PostgreSQL
  • Redis
  • MongoDB
  • clickhouse
关于
  • 分类
  • 标签
  • 归档
  • 收藏
  • 更多
GitHub (opens new window)

yangfk

瑟瑟发抖的小运维
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • 运维基础
  • 监控
  • 日志系统
  • gitlab安装
  • jenkins安装和管理
  • Jenkins工具集成
  • pipeline流水线
  • Dcoker
  • Kubernetes
  • Nexus
  • Rancher
  • Prometheus
  • ELK(EFK)
  • 虚拟化
  • Mysql
  • PostgreSQL
  • Redis
  • MongoDB
  • clickhouse
关于
  • 分类
  • 标签
  • 归档
  • 收藏
  • 更多
GitHub (opens new window)
  • Docker

  • Kubernetes

    • K8S常见组件记录
    • 安装DNS服务(bind-9)
    • 私有仓库harbor部署
    • 证书签发环境CFSSL
    • 一步步部署k8s组件(上)
    • 一步步部署k8s组件(中)
    • 一步步部署k8s组件(下)
    • kubelet常用命令
    • K8s的GUI资源管理之仪表板
    • k8s部署jenkins
    • k8s持久存储StorageClass
    • k8s之Volume类型emptyDir和hostPath
    • 深入了解Deployment
    • k8s之meric-server(HPA环境)
    • k8s-deployment常见参数说明
    • rke部署k8s高可用集群
    • K8S之安全机制
      • K8S之安全机制
      • Secret私密凭据
        • 创建Secret
        • secret使用
        • secret通过Volume挂载
        • secret配置到环境变量
        • ImagePullSecrets
      • Service Account
      • API Server授权管理
        • RBAC授权模式详解
        • Role
        • ClusterRole
        • RoleBinding
        • ClusterRoleBinding
        • 资源引用
        • 生成权限控制的kubeconfig
    • k8s网络策略
    • kubeadm安装k8s(版本1.26.0)
    • kubeadm证书替换
    • Pod探针
  • Nexus

  • Rancher

  • Prometheus

  • ELK

  • 虚拟化

//
  • 云计算虚拟化
  • Kubernetes
yangfk
2022-09-14

K8S之安全机制

//

# K8S之安全机制

Kubernetes通过一系列机制来实现集群的安全控制,其中包括APIServer的认证授权、准入控制机制及保护敏感信息的Secret机制等

集群安全性考虑几个目标:

(1)保证容器与其所在宿主机的隔离。
(2)限制容器给基础设施或其他容器带来的干扰。
(3)最小权限原则—合理限制所有组件的权限,确保组件只执行它被授权的行为,通过限制单个组件的能力来限制它的权限范围。
(4)明确组件间边界的划分。
(5)划分普通用户和管理员的角色。
(6)在必要时允许将管理员权限赋给普通用户。
(7)允许拥有Secret数据(Keys、Certs、Passwords)的应用在集群中运行。

# Secret私密凭据

Secret的主要作用是保管私密数据,比如密码(拉取私有镜像)、OAuth Tokens、SSH Keys等信息。 每个单独的Secret大小最好不能超过1MB,Kubernetes不鼓励创建大的Secret,使用的Secret,会占用API Server和kubelet的内存

在启动之前,如果Secret不存在或暂时无法连接到API Server,则kubelet按一定的时间间隔定期重试获取该Secret,并发送一个Event来解释Pod没有启动的原因。 在kubelet启动Pod中的Container后,Container中和Secret相关的Volume不会被改变,即使Secret本身被修改,除非删除pod,重新创建新的pod

使用方式:

(1)在创建Pod时,通过为Pod指定Service Account来自动使用该Secret。
(2)通过挂载该Secret到Pod来使用它。
(3)在Docker镜像下载时使用,通过指定Pod的spc.ImagePullSecrets来引用它。
(4)Secret分为 kubernetes.io/service-account-token、kubernetes.io/dockerconfigjson、Opaque 三种类型

# 创建Secret

查看帮助:kubectl create secret --help

  • 方式一
echo admin > user

kubectl create ns devtest  #空间名使用 devtest
kubectl create secret generic user --from-file=./user -n devtest
kubectl create secret generic passwd --from-literal=passwd=yfk123456 -n devtest
1
2
3
4
5
  • 方式二

      [root@manage-01 devtest_config]# echo admin |base64
      YWRtaW4K
      [root@manage-01 devtest_config]# echo yfk123456 |base64
      eWZrMTIzNDU2Cg==
    
[root@manage-01 secret]# cat testsecret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: testsecret
  namespace: devtest
type: Opaque
data:
user: YWRtaW4K
passwd: eWZrMTIzNDU2Cg==
1
2
3
4
5
6
7
8
9
10

创建secret:kubectl apply -f testsecret.yaml

  • 查看

      [root@manage-01 secret]# kubectl get secrets -n devtest 
      NAME                  TYPE                                  DATA   AGE
      default-token-8m289   kubernetes.io/service-account-token   3      5h12m
      passwd                Opaque                                1      49s
      testsecret            Opaque                                2      20m
      user                  Opaque                                1      3m29s
    

# secret使用

# secret通过Volume挂载

apiVersion: v1
kind: Pod
metadata:
  labels:
    app: nginx-test
  name: nginx-test
  namespace: devtest
spec:
  containers:
  - image: nginx:1.20.2
    name: nginx
    volumeMounts:
    - name: nginx-testsecret
      mountPath: /opt/testsecret
      readOnly: true
    - name: nginx-testsecret2
      mountPath: /opt/testsecret2
      readOnly: true
  volumes:
    - name: nginx-testsecret
      secret:
        secretName: testsecret
    - name: nginx-testsecret2
      projected:
        sources:
        - secret:
            name: user
        - secret:
            name: passwd
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

查看会发现,secretName里面有两个,会当作两个文件拷贝到容器里面,而不是像ConfigMap做软链接

[root@manage-01 secret]# kubectl exec -it -n devtest nginx-test cat /opt/testsecret/passwd
yfk123456
[root@manage-01 secret]# kubectl exec -it -n devtest nginx-test cat /opt/testsecret2/passwd
yfk123456
[root@manage-01 secret]# kubectl exec -it -n devtest nginx-test cat /opt/testsecret/user
admin

# secret配置到环境变量

apiVersion: v1
kind: Pod
metadata:
  labels:
    app: nginx-test
  name: nginx-test
  namespace: devtest
spec:
  containers:
  - image: nginx:1.20.2
    name: nginx
    env:
      - name: sec_user
        valueFrom:
          secretKeyRef:
            name: testsecret
            key: user
      - name: sec_passwd
        valueFrom:
          secretKeyRef:
            name: testsecret
            key: passwd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

查看值

    [root@manage-01 secret]# kubectl exec -it -n devtest nginx-test bash
    root@nginx-test:/# echo $sec_user
    admin
    root@nginx-test:/# echo $sec_passwd
    yfk123456

# ImagePullSecrets

imagePullSecrets 是对同一命名空间中 Secret 的引用列表,用于拉取引用此 ServiceAccount 的 Pod 中的任何镜像。 
imagePullSecrets 与 Secrets 不同,因为 Secrets 可以挂载在 Pod 中,但 imagePullSecrets 只能由 kubelet 访问。
  • 登录docker私有仓库,查看dockercfg
docker login harbor.yfklife.cn
cat ~/.dockercfg |base64
1
2
apiVersion: v1
data:
  .dockerconfigjson: eyJhdXRocyI6eyJoYXJib3IueWZrbGlmZS5jbiI6eyJ1c2VybmFtZSI6ImFkbWluIiwicGFzc3dvcmQiOiJ5ZmsxMjM0NTYiLCJhdXRoIjoiWVdSdGFXNDZlV1pyTVRJek5EVTIifX19
kind: Secret
metadata:
  name: harbor
  namespace: devtest
type: kubernetes.io/dockerconfigjson
1
2
3
4
5
6
7
8

也可以使用命令:kubectl create secret docker-registry harbor --docker-server=harbor.yfklife.cn --docker-username=admin --docker-password=yfk123456 -n devops

  • 使用imagePullSecrets
apiVersion: v1
kind: Pod
metadata:
  labels:
    app: nginx-test
  name: nginx-test
  namespace: devtest
spec:
  containers:
  - image: nginx:1.20.2
    name: nginx
  imagePullSecrets:
  - name: harbor #私有仓库密钥
1
2
3
4
5
6
7
8
9
10
11
12
13

# Service Account

官方文档 (opens new window)

Service Account也是一种账号,但它并不是给Kubernetes集群的用户(系统管理员、运维人员、租户用户等)用的,而是给运行在Pod里的进程用的,它为Pod里的进程提供了必要的身份证明
如果一个Pod在定义时没有指定spec.serviceAccountName属性,则系统会自动为其赋值为default,即大家都使用同一个Namespace下的默认Service Account。
用户可以理解的名称,也可能是外围系统理解的身份标识,可以验证和授权的主体,一组 secret
  • 创建sa
apiVersion: v1
kind: ServiceAccount
metadata:
  name: test-sa
  namespace: default
1
2
3
4
5

# API Server授权管理

当客户端发起API Server调用时,API Server内部要先进行用户认证,然后执行用户授权流程,即通过授权策略来决定一个API调用是否合法。对合法用户进行授权并且随后在用户访问时进行鉴权,是权限与安全系统的重要一环。简单地说,授权就是授予不同的用户不同的访问权限。

授权策略:

AlwaysDeny:表示拒绝所有请求,一般用于测试。
AlwaysAllow:允许接收所有请求,如果集群不需要授权流程,则可以采用该策略,这也是Kubernetes的默认配置。
ABAC(Attribute-Based Access Control):基于属性的访问控制,表示使用用户配置的授权规则对用户请求进行匹配和控制。
Webhook:通过调用外部REST服务对用户进行授权。
RBAC:Role-Based Access Control,基于角色的访问控制。
Node:是一种专用模式,用于对kubelet发出的请求进行访问控制。

# RBAC授权模式详解

rabc官方详解 (opens new window)

基于角色(Role)的访问控制(RBAC)是一种基于组织中用户的角色来调节控制对计算机或网络资源的访问的方法。

RBAC 鉴权机制使用 rbac.authorization.k8s.io API 组来驱动鉴权决定, 允许你通过 Kubernetes API 动态配置策略。

要启用 RBAC,在启动 API 服务器时将 --authorization-mode 参数设置为一个逗号分隔的列表并确保其中包含 RBAC。

RBAC API 声明了四种 Kubernetes 对象:Role、ClusterRole、RoleBinding 和 ClusterRoleBinding。

# Role

一个角色就是一组权限的集合,这里的权限都是许可形式的,不存在拒绝的规则

Role 总是用来在某个名字空间内设置访问权限; 在你创建 Role 时,你必须指定该 Role 所属的命名空间。

  • 示例
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: ["","apps"] # "" 标明 core API 组,"apps" 可以使用别的资源如果resorces 添加了,比如deployment,rc等等
  resources: ["pods"]
  verbs: ["get", "watch", "list"]
1
2
3
4
5
6
7
8
9

# ClusterRole

ClusterRole 则是一个集群作用域的资源。这两种资源的名字不同(Role 和 ClusterRole) 是因为 Kubernetes 对象要么是名字空间作用域的,要么是集群作用域的,不可两者兼具

定义对某名字空间域对象的访问权限,并将在个别名字空间内被授予访问权限;
为名字空间作用域的对象设置访问权限,并被授予跨所有名字空间的访问权限;
为集群作用域的资源定义访问权限。
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  # "namespace" 被忽略,因为 ClusterRoles 不受名字空间限制
  name: secret-reader
rules:
- apiGroups: [""]
  # 在 HTTP 层面,用来访问 Secret 资源的名称为 "secrets"
  resources: ["secrets"]
  verbs: ["get", "watch", "list"]
1
2
3
4
5
6
7
8
9
10

# RoleBinding

角色绑定(Role Binding)是将角色中定义的权限赋予一个或者一组用户。 它包含若干 主体(用户、组或服务账户)的列表和对这些主体所获得的角色的引用。

RoleBinding 在指定的名字空间中执行授权,而 ClusterRoleBinding 在集群范围执行授权

apiVersion: rbac.authorization.k8s.io/v1
# 此角色绑定允许 "jane" 读取 "default" 名字空间中的 Pod
# 你需要在该命名空间中有一个名为 “pod-reader” 的 Role
kind: RoleBinding
metadata:
  name: read-pods
  namespace: default
subjects:
# 你可以指定不止一个“subject(主体)”
- kind: User
  name: jane # "name" 是区分大小写的
  apiGroup: rbac.authorization.k8s.io
roleRef:
  # "roleRef" 指定与某 Role 或 ClusterRole 的绑定关系
  kind: Role        # 此字段必须是 Role 或 ClusterRole
  name: pod-reader  # 此字段必须与你要绑定的 Role 或 ClusterRole 的名称匹配
  apiGroup: rbac.authorization.k8s.io
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

当roleRef 引用的king 是ClusterRole ,read-pods 用户也只能访问default里面的资源,因为 RoleBinding 所在的名字空间是 "default"(由其 metadata 决定)。

# ClusterRoleBinding

要跨整个集群完成访问权限的授予,你可以使用一个 ClusterRoleBinding。

创建后不可改变,如果你想要改变现有绑定对象中 roleRef 字段的内容,必须删除重新创建绑定对象。

apiVersion: rbac.authorization.k8s.io/v1
# 此集群角色绑定允许 “manager” 组中的任何人访问任何名字空间中的 Secret 资源
kind: ClusterRoleBinding
metadata:
  name: read-secrets-global
subjects:
- kind: Group
  name: manager      # 'name' 是区分大小写的
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io
1
2
3
4
5
6
7
8
9
10
11
12
13

# 资源引用

通过rules来定义规则

rules:

  • apiGroups: [""] resources: ["pods", "pods/log"] verbs: ["get", "list"]
  • apiGroups: ["","storage.k8s.io"] resources: ["storageclasses"] verbs: ["get", "list", "watch"]
  • apiGroups: ["apps"] resources: ["pods","deployments","replicasets","replicationcontrollers","configmaps","services"] verbs: ["get","list","watch","create","update","delete"]

第一个apiGroup,只允许访问核心里面的pod,第二个apiGroups,只允许查看存储资源里面的storageclasses,第三个apiGroups,只允许访问apps组里面的resources对应的资源

apugroup (opens new window)

# 生成权限控制的kubeconfig

在某些情况,公司的k8s集群要给开发自己去测试,但又不想影响到别的项目(namespace),通过权限控制生成一个config指定在某个空间有权限

比如:Namespace:devtest ,Username:dev

Namespace=devtest
Username=dev

#创建namespace
kubectl create ns $Namespace

test -d ${Namespace}_config || mkdir ${Namespace}_config && cd ${Namespace}_config
1
2
3
4
5
6
7
  • 创建ServiceAccoount
cat >${Username}-sa.yaml<<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
  name: ${Username}-sa
  namespace: ${Namespace}
EOF
kubectl apply -f ${Username}-sa.yaml
1
2
3
4
5
6
7
8
  • 创建一个 Role

在用户命名空间下创建 Role,分配给使用者的资源和权限

cat >${Username}-role.yaml<<EOF
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: ${Username}-role
  namespace: ${Namespace}
rules:
- apiGroups: ["","apps"]
  resources: 
  - pods
  - deployments
  - services
  - replicasets
  - replicationcontrollers
  - configmaps
  verbs: 
  - get
  - list
  - watch
  - create
  - update
  - delete
EOF

kubectl apply -f ${Username}-role.yaml
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
  • 创建 RoleBinding

将刚刚创建的 SA 和 Role 进行绑定, 上面创建的ServiceAccount 就可以访问 devtest 命名空间下的相应资源了

cat >${Username}-roleBinding.yaml<<EOF
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: ${Username}-binding
  namespace: ${Namespace}
subjects:
- kind: ServiceAccount
  name: ${Username}-sa
roleRef:
  kind: Role
  name: ${Username}-role
  apiGroup: rbac.authorization.k8s.io
EOF

kubectl apply -f ${Username}-roleBinding.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  • 生成kubeconfig
KUBE_APISERVER=`kubectl config view --minify -o=jsonpath="{.clusters[*].cluster.server}"`
TOKEN_KEY=`kubectl get sa ${Username}-sa -n ${Namespace} -o=jsonpath="{.secrets[0].name}"`
TOKEN=`kubectl get secrets $TOKEN_KEY -n ${Namespace} -o=jsonpath="{.data.token}"`
CLUSTER_AUTH=`kubectl config view --flatten --minify -o=jsonpath="{.clusters[0].cluster.certificate-authority-data}"`
TOKEN_DECODE=`echo $TOKEN | base64 --decode`

# 生成 kubeconfig 文件
cat > $Username.config  <<EOF
apiVersion: v1
kind: Config
users:
- name: $Username
  user:
    token: $TOKEN_DECODE
clusters:
- cluster:
    certificate-authority-data: $CLUSTER_AUTH
    server: $KUBE_APISERVER
  name: $Username-cluster
contexts:
- context:
    cluster: $Username-cluster
    namespace: $Namespace
    user: $Username
  name: $Username-cluster
current-context: $Username-cluster
EOF
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
  • 检查

把 XXX.config 拷贝到 ~/.kube/config里,或者使用参数指定:--kubeconfig=XXX.config

kubectl create deployment nginx-test --image=nginx:1.20.2 -n devtest --kubeconfig=${Username}.config

#有权限的显示,没权限的提示禁止
kubectl get all --kubeconfig=${Username}.config
1
2
3
4

参考文档 (opens new window)

//
点击 -->> 给博主买咖啡 (opens new window)
上次更新: 2022/09/14, 18:30:01
rke部署k8s高可用集群
k8s网络策略

← rke部署k8s高可用集群 k8s网络策略→

最近更新
01
Pod探针
12-20
02
kubeadm证书替换
12-20
03
kubeadm安装k8s(版本1.26.0)
12-16
更多文章>
Theme by Vdoing | Copyright © 2019-2023 yangfk | 湘ICP备2021014415号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×
//