1.集群部署与安全配置

K8S集群部署与安全配置

主要内容

❖ K8s安全运维概述

❖ 部署一套完整的K8s高可用集群

❖ CIS 安全基准介绍与K8s安全基准工具kube-bench

❖ Ingress 配置证书

❖ 网络策略控制集群内部网络通信

K8s安全运维概述

  • 安全运维的重要性
  • SecDevOps
  • K8s提供的安全机制
  • K8s安全运维实践思路

安全运维的重要性

  • 万物互联,安全为基,企业的网络安全不可小视
  • 服务器被黑事件频发
  • 公司重要数据资产在运维手中

SecDevOps

SecDevOps与DevOps相似,是一种哲学,鼓励运维人员、开发 人员、测试人员和安全人员进行更高水水平协作,将信息安全被放 在事前考虑,将安全性注入自动化流程中,以确保整个产品周期内 的信息安全。
image-20220411143502253

K8s提供的安全机制

为了保证集群以及容器应用的安全,Kubernetes 提供了多 种安全机制,限制容器的行为,减少容器和集群的攻击面, 保证整个系统的安全性。

  1. 集群安全: TLS证书认证、RBAC
  2. Security Context: 限制容器的行为,例如只读文件系统、特权、运行用户等
  3. Pod Security Policy: 集群级的 Pod 安全策略,自动为集群内的 Pod 配置安全策略
  4. Sysctls: 允许容器设置内核参数
  5. AppArmor: 限制容器中应用对资源的访问权限
  6. Network Policies: 控制集群中网络通信
  7. Seccomp: 限制容器内进程的系统调用

K8s安全运维实践思路

image-20220411143733252

CIS 安全基准

  • CIS安全基准介绍
  • K8s安全基准工具 kube-bench

CIS安全基准

互联网安全中心(CIS,Center for Internet Security),是一个非盈利组织,致力为互联网提供 免费的安全防御解决方案。

官网:https://www.cisecurity.org/

Kubernetes CIS基准:https://www.cisecurity.org/benchmark/kubernetes/

CIS基准测试工具

Kube-bench是容器安全厂商Aquq推出的工具,以CIS K8s基准作为基础,来检查K8s是否安全部署。 主要查找不安全的配置参数、敏感的文件权限、不安全的帐户或公开端口等等。

项目地址:https://github.com/aquasecurity/kube-bench

kube-beach部署

1、下载二进制包

https://github.com/aquasecurity/kube-bench/releases

2、解压使用

[root@master01:~]# tar zxvf kube-bench_0.6.3_linux_amd64.tar.gz 
[root@master01:~]# mkdir /etc/kube-bench 			# 创建默认配置文件路径
[root@master01:~]# mv cfg /etc/kube-bench/cfg

3、kube-beach使用

使用kube-bench run进行测试,该指令有以下常用参数:

常用参数:

  • -s, --targets 指定要基础测试的目标,这个目标需要匹配cfg/中的 文件名称,已有目标:master, controlplane, node, etcd, policies
  • --version: 指定k8s版本,如果未指定会自动检测
  • --benchmark: 手动指定CIS基准版本,不能与–version一起使用

image-20220411150422457

4、运行kube-beach

检查master组件安全配置,需要指定当前的cis目录。

**[PASS]:**测试通过

**[FAIL]:**测试未通过,重点关注,在测试结果会给出修复建议

**[WARN]:**警告,可做了解

**[INFO]:**信息

[root@master01:~] # cd cfg/
[root@master01:~/cfg] # kube-bench run master --config-dir .
···
== Summary policies ==
0 checks PASS
0 checks FAIL
24 checks WARN
0 checks INFO

== Summary total ==
68 checks PASS
13 checks FAIL
41 checks WARN
0 checks INFO

如下是检查后需要建议修复的地方

image-20220411151549372

kube-beach工具将会给出修改建议的方案,可以参考做修改:

  • 1.2.16的建议是: 开启Pod安全策略准入控制器
  • 1.2.22的建议是: 开启日志审计的数据存放路径
  • 1.2.23的建议是: 设置日志最大页数为30
  • 1.2.24的建议是: 设置日志最大的备份数为10
  • 1.2.25的建议是: 设置日志的大小为100M
  • 1.2.26的建议是: 设置请求超时为300s
1.2.16 Follow the documentation and create Pod Security Policy objects as per your environment.
Then, edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml
on the master node and set the --enable-admission-plugins parameter to a
value that includes PodSecurityPolicy:
--enable-admission-plugins=...,PodSecurityPolicy,...
Then restart the API Server.


1.2.22 Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml
on the master node and set the --audit-log-path parameter to a suitable path and
file where you would like audit logs to be written, for example:
--audit-log-path=/var/log/apiserver/audit.log

1.2.23 Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml
on the master node and set the --audit-log-maxage parameter to 30 or as an appropriate number of days:
--audit-log-maxage=30

1.2.24 Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml
on the master node and set the --audit-log-maxbackup parameter to 10 or to an appropriate
value.
--audit-log-maxbackup=10

1.2.25 Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml
on the master node and set the --audit-log-maxsize parameter to an appropriate size in MB.
For example, to set it as 100 MB:
--audit-log-maxsize=100

1.2.26 Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml
and set the below parameter as appropriate and if needed.
For example,
--request-timeout=300s

按照1.2.16建议我们修改之后再次检查:

    - --enable-admission-plugins=NodeRestriction,PodSecurityPolicy

image-20220411152909508

Ingress配置证书

  • Ingress是什么
  • HTTPS重要性
  • 将一个项目对外暴露HTTPS访问

Ingress是什么?

Ingress:K8s中的一个抽象资源,给管理员 提供一个暴露应用的入口定义方法

Ingress Controller:根据Ingress生成具体 的路由规则,并对Pod负载均衡器

image-20220411153701818

HTTPS重要性

HTTPS是安全的HTTP,HTTP 协议中的内容都是明文传输,HTTPS 的目的是将这 些内容加密,确保信息传输安全。最后一个字母 S 指的是 SSL/TLS 协议,它位于 HTTP 协议与 TCP/IP 协议中间。

HTTPS优势:

  1. 加密隐私数据:防止您访客的隐私信息(账号、地址、手机号等)被劫持或窃取。
  2. 安全身份认证:验证网站的真实性,防止钓鱼网站。
  3. 防止网页篡改:防止数据在传输过程中被篡改,保护用户体验。
  4. 地址栏安全锁:地址栏头部的“锁”型图标,提高用户信任度。
  5. 提高SEO排名:提高搜索排名顺序,为企业带来更多访问量。

将一个项目对外暴露HTTPS访问

配置HTTPS步骤:

1、准备域名证书文件(来自:openssl/cfssl工具自签或者权威机构颁发)

2、将证书文件保存到Secret

kubectl create secret tls web-aliangedu-cn – cert=web.aliangedu.cn.pem --key=web.aliangedu.cn-key.pem

3、Ingress规则配置tls

4、kubectl get ingress

5、测试,本地电脑绑定hosts记录对应ingress里面配置的域名,IP是 Ingress Concontroller Pod节点IP

1.配置自签名的域名证书文件

[root@master01:~/work/cert]# ls 
certs.sh  cfssl  cfssl-certinfo  cfssljson  cfssl.tar.gz
[root@master01:~/work/cert]# mv cfssl* /usr/local/bin/ 
[root@master01:~/work/cert]# ./certs.sh 
2022/04/11 08:13:18 [INFO] generating a new CA key and certificate from CSR
2022/04/11 08:13:18 [INFO] generate received request
2022/04/11 08:13:18 [INFO] received CSR
2022/04/11 08:13:18 [INFO] generating key: rsa-2048
2022/04/11 08:13:18 [INFO] encoded CSR
2022/04/11 08:13:18 [INFO] signed certificate with serial number 28750654571656584514635094557307694380858081500
2022/04/11 08:13:18 [INFO] generate received request
2022/04/11 08:13:18 [INFO] received CSR
2022/04/11 08:13:18 [INFO] generating key: rsa-2048
2022/04/11 08:13:18 [INFO] encoded CSR
2022/04/11 08:13:18 [INFO] signed certificate with serial number 399813817984941992535618075144209803695431465162
2022/04/11 08:13:18 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").

[root@master01:~/work/cert]# kubectl create secret tls web-aliangedu-cn --cert=web.aliangedu.cn.pem --key=web.aliangedu.cn-key.pem 
secret/web-aliangedu-cn created

2.创建应用测试

[root@master01:~/work/cert]# kubectl create deployment web --image=nginx --port=80       
deployment.apps/web created
[root@master01:~/work/cert]# kubectl expose deployment web --port=80 --type=NodePort 
service/web exposed

3.创建Ingress服务

  • 创建Ingress服务名称为aliangedu-https
  • 使用tls证书web-aliangedu-cn
  • 使用host为web.aliangedu.cn
[root@master01:~/work/cert]# kubectl create ingress aliangedu-https --rule=web.aliangedu.cn/=web:80,tls=web-aliangedu-cn --dry-run -o yaml > ingress.yaml  
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: aliangedu-https
spec:
  rules:
  - host: web.aliangedu.cn
    http:
      paths:
      - backend:
          service:
            name: web
            port:
              number: 80
        path: /
        pathType: Exact
  tls:
  - hosts:
    - web.aliangedu.cn
    secretName: web-aliangedu-cn
    
[root@master01:~/work/cert]# kubectl get ingress
NAME              CLASS    HOSTS              ADDRESS   PORTS     AGE
aliangedu-https   <none>   web.aliangedu.cn             80, 443   35m

根据ingress-nginx的443端口以及master03节点的IP访问。

[root@master01:~/work/cert]# kubectl get svc -n ingress-nginx 
NAMESPACE       NAME                                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx   ingress-nginx-controller             NodePort    10.108.51.191    <none>        80:31950/TCP,443:31465/TCP   4d4h
ingress-nginx   ingress-nginx-controller-admission   ClusterIP   10.97.104.2      <none>        443/TCP                      4d4h

[root@master01:~/work/cert]# kubectl get  pods -o wide 
NAME                   READY   STATUS    RESTARTS   AGE   IP              NODE       NOMINATED NODE   READINESS GATES
web-64ffb4ff88-rmvct   1/1     Running   0          15m   10.244.235.12   master03   <none>           <none>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-awoMTqZ3-1680592974183)(null)]

网络访问控制

  • 网络策略应用场景
  • 网络策略概述
  • 网络访问控制5个案例

网络访问控制:应用场景

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

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

网络策略的应用场景:

  1. 应用程序间的访问控制,例如项目A不能访问项目B的Pod
  2. 开发环境命名空间不能访问测试环境命名空间Pod • 当Pod暴露到外部时,需要做Pod白名单
  3. 多租户网络环境隔离

网络访问控制:网络策略概述

podSelector: 目标Pod,根据标签选择。

policyTypes: 策略类型,指定策略用于入站、出站流量。

Ingress: from是可以访问的白名单,可以来自于IP段、命名空间、 Pod标签等,ports是可以访问的端口。

Egress: 这个Pod组可以访问外部的IP段和端口。

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

网络访问控制:网络策略概述

网络策略工作流程:

1、创建Network Policy资源

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

3、节点上DaemonSet运行的程序从etcd中获取Policy,调用本 地Iptables创建防火墙规则
image-20220411170248985

网络访问控制案例

  1. 案例1:拒绝命名空间下所有Pod出入站流量
  2. 案例2:拒绝其他命名空间Pod访问
  3. 案例3:允许其他命名空间Pod访问指定应用
  4. 案例4:同一个命名空间下应用之间限制访问
  5. 案例5:只允许指定命名空间中的应用访问
拒绝命名空间下所有Pod入、出站流量

需求:拒绝test命名空间下所有Pod入、出站流量

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all
  namespace: test
spec:
  podSelector: {
    
    } 	# 匹配本命名空间所有pod
  policyTypes: 
  - Ingress
  - Egress
  # ingress和egress没有指定规则,则不允许任何流量进出pod
拒绝其他命名空间Pod访问

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

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-namespaces 
  namespace: test
spec:
  podSelector: {
    
    } 
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector: {
    
    }  # 匹配本命名空间所有pod
允许其他命名空间Pod访问指定应用

需求:允许其他命名空间访问test命名空间指定Pod

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-all-namespaces 
  namespace: test
spec:
  podSelector: 
    matchLabels:
      app: web
  policyTypes:
  - Ingress
  ingress:
  - from:
    - namespaceSelector: {
    
    } # 匹配所有命名空间的pod
同一个命名空间下应用之间限制访问

需求:将test命名空间中标签为run=web的pod隔离, 只允许标签为run=client1的pod访问80端口

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: app-to-app
  namespace: test
spec:
  podSelector:
    matchLabels:
      run: web
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          run: client1
    ports:
    - protocol: TCP
      port: 80
只允许指定命名空间中的应用访问

需求:限制dev命名空间标签为env=dev的pod,只允许 prod命名空间中的pod访问和其他所有命名空间 app=client1标签pod访问

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: dev-web
  namespace: dev
spec:
  podSelector:
    matchLabels:
      env: dev
  policyTypes:
  - Ingress
  ingress:
  # 满足允许prod命名空间中的pod访问
  - from:
    - namespaceSelector:
        matchLabels:
          env: prod
  # 允许pod标签为app=client1的pod访问,所有命名空间
  - from:
    - namespaceSelector: {
    
    }
      podSelector:
        matchLabels:
          app: client1
 port: 80



##### 只允许指定命名空间中的应用访问

`需求:限制dev命名空间标签为env=dev的pod,只允许 prod命名空间中的pod访问和其他所有命名空间 app=client1标签pod访问`

```yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: dev-web
  namespace: dev
spec:
  podSelector:
    matchLabels:
      env: dev
  policyTypes:
  - Ingress
  ingress:
  # 满足允许prod命名空间中的pod访问
  - from:
    - namespaceSelector:
        matchLabels:
          env: prod
  # 允许pod标签为app=client1的pod访问,所有命名空间
  - from:
    - namespaceSelector: {}
      podSelector:
        matchLabels:
          app: client1

猜你喜欢

转载自blog.csdn.net/weixin_46532941/article/details/129954095