关于kubernetes:01kubernetes笔记-Pod及-Security-Context安全上下文

31次阅读

共计 16467 个字符,预计需要花费 42 分钟才能阅读完成。

kubernetes 资源援用格局

<type>/<name>:  pods/mypod,depolyment/demoapp  #能够同时对不同的资源进行操作
<type> <name>:   pods mypod,deployment demoapp  #只能对同一类型资源操作

示例:

[root@k8s-master ~]# kubectl delete pods/mypod  depolyment/demoapp    #胜利
[root@k8s-master ~]# kubectl delete pods mypod  mypod2    #胜利
[root@k8s-master ~]# kubectl delete pods mypod  depolyment demoapp  #失败 会把 pods 前面的所以字段都当成 pod 

kubectl 常用命令

[root@k8s-master ~]# kubectl api-resources  #查看资源类型与对象缩写
[root@k8s-master ~]# kubectl get all #查看所有资源
[root@k8s-master ~]# kubectl get pod # 可应用 get 查看 pod、svc、ns、deployment 简直所有资源状态
[root@k8s-master ~]# kubectl describe pod   <PodName>  #可应用 describe 查看 pod、svc、ns、deployment 简直所有资源状态更具体的形容信息,包含 pod 的错误信息等
[root@k8s-master ~]# kubectl delete pod  <PodName>    #删除 pod 同样能够针对所有资源可用
[root@k8s-master ~]# kubectl get pod --all-namespaces -o wide   #所有名称空间下的 pod <-o wide> 查看更详细描述 同样能够针对所有资源可用

[root@k8s-master ~]# kubectl delete pod  <PodName>    #删除 pod 同样能够针对所有资源可用 kubectl get pod --show-labels  #查看标签
[root@k8s-master ~]# kubectl get node --show-labels  #查看节点标
[root@k8s-master ~]# kubectl get cm -o yaml  #以 yaml 格局输入

[root@k8s-master ~]# kubectl create -f pop.yaml  #命令式创建对象
[root@k8s-master ~]# kubectl apply -f pod.yaml   #申明式 (幂等) 创建对象
[root@k8s-master ~]# kubectl edit pod myapp-pod  #编辑 pod

[root@k8s-master ~]# kubectl logs myapp-pod -c test   #查看 pop 的日志  -c  指定容器 如果只 1 个容器不须要指定

[root@k8s-master ~]# kubectl exec readiness-httpget-pod -n xx -it -- /bin/sh  #进入容器 如果多个容器 - c 指定容
[root@k8s-master ~]# kubectl exec liveness-httpget-pod -it -- rm -fr /usr/share/nginx/html/index.html #执行命令
[root@k8s-master ~]# kubectl explain  deployment  #查看资源的文档 版本及定义的字段 其中 <[]object> []
KIND:     Deployment
VERSION:  apps/v1

DESCRIPTION:
     Deployment enables declarative updates for Pods and ReplicaSets.

FIELDS:
   apiVersion    <string>    #字段为字符
   metadata    <Object>   #字身为对象  可通过 kubectl explain  deployment.metadata 可查看具体的阐明
$ kubectl explain  deployment.spec

  selector    <Object> -required-  #必须字段
$ kubectl explain  pod.spec 
  containers<[]Object> -required- #在 yaml 中示意对象为列表 能够有多个对象

kubernetes 组件

master node

  • kubernetes API Server

    提供了 kubernetes 各类资源对象(pod,RC,Service 等)的增删改查及 watch 等 HTTP Rest 接口,是整个零碎的数据总线和数据中心。次要性能如下:

    1. 提供了集群治理的 REST API 接口(包含认证受权、数据校验以及集群状态变更);
    2. 提供其余模块之间的数据交互和通信的枢纽(其余模块通过 API Server 查问或批改数据,只有 API Server 才间接操作 etcd);
    3. 是资源配额管制的入口;
    4. 领有齐备的集群平安机制.
  • Controller Manager(control loop)

    控制器 重复性工作代码化 严格意义上 K8S 的控制中心 通过 control loop 循环会始终监督本人管制下的资源对象合乎预期

  • Scheduler – 调度 对 pod 运行进行治理
  • Etcd – 基于 raft 协定分布式存储,K/ V 键 / 值存储系统 作用: 注册表 存储 强统一 状态存储

worker node

  • Kubelet – 监听 API Server 以守护过程运行 相似 zabbixr agent

    每 10s 向 master 发送心跳信息,包含 Images 等信息,这时的报文容量很大,会占用很多网络资源,1.13 版后启动 Node status 字段,引入租约的概念,在肯定工夫内只更新心跳状态就能够 减小报文的大小

  • container engine – 被 kubelet 调成生成运行 pod 默认为 docker
  • kube-proxy – 生成 svc 规定 兴许是 IPtabs 或 ipvs

Add-ons

  • KubeDNS:CoreDNS
  • Dashboard, web UI
  • 监控零碎: Prometheus
  • 集群日志零碎:ELK、EFK、LG ElasticSear + Filebeat/Fluentd/fluent-bit/logstatsh + Kibana /Loki+ Grafana
  • CRI:Runtime 运行时
  • CSI: Storage 存储

Ntework

  • Ingress Controller 入站流量控制器相同的为 Engress
  • CNI:Container Network Interface 分为 overlay 叠加、underlay 承载网络

    1. flannel – 简略易用 易了解 尽实现网络, 没有网络策略 比方不同名称空间 pod 能够拜访

      1. Project Calico – 实现网络和网络策略 性能更好 生产环境中应用
      2. Pod 默认子网:10.244.0.0/16、
        4.Service 默认子网:10.96.0.0/12 并由 kube-proxy 治理

1.1 示例:HTTPS 拜访 kubernetes API Server

API Server 就是一个 web 服务器 通过 https 与其余组件通信 通过配置也可能定义为 http
kubectl 管理工具 通过家目录 .kube/config 中的秘钥认证与 api sever 通信

[root@k8s-master ~]#  kubectl get apiservice #查看所有 api
[root@k8s-master ~]#  kubectl get apiservice v1.apps -o yaml  #查看指定 api 详情
  • 拜访 api 具体资源 格局:
    /apis/GROUP/VERSION/namespaces/NAMESPACE/pods/POD_NAME
[root@k8s-master ~]#  kubectl get --raw /apis/apps/v1/namespaces/default/replicasets/my-grafana-7d788c5479|jq .  #查看资源详情 
[root@k8s-master ~]#  kubectl get --raw /api/v1/namespaces/default/pods/my-grafana-7d788c5479-kpq9q|jq .  #拜访 v1 外围组用 aip 而不是 aps
既然是 web 那就能够通过 curl 拜访


[root@k8s-master ~]# curl  https://k8s-master:6443/api/v1/namespaces/default/pods/my-grafana-7d788c5479-kpq9q
curl: (60) Peer's Certificate issuer is not recognized.
More details here: http://curl.haxx.se/docs/sslcerts.html

#提醒没有 SSL 认证 因为.kube/config 秘钥格局 curl 无奈辨认

curl performs SSL certificate verification by default, using a "bundle"
 of Certificate Authority (CA) public keys (CA certs). If the default
 bundle file isn't adequate, you can specify an alternate file
 using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
 the bundle, the certificate verification probably failed due to a
 problem with the certificate (it might be expired, or the name might
 not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
 the -k (or --insecure) option.
  • 提醒没有 SSL 认证 因为.kube/config 秘钥格局 curl 无奈辨认
  • 解决办法是让 kubectl proxy 实现 https 会话卸载 通过 kubectl—->API service 互相认证 curl 通过 http 拜访 kubectl 映射端口
[root@k8s-master ~]# kubectl proxy
Starting to serve on 127.0.0.1:8001

[root@k8s-master ~]# curl  127.0.0.1:8001   #查看所有 aip 分组
[root@k8s-master ~]# curl  127.0.0.1:8001/api/v1/namespaces/default/pods/my-grafana-7d788c5479-kpq9q| jq .  #查看资源 api

Pod 控制器

Pod 简介:
Pod 是 Kubernetes 创立或部署的最小 / 最简略的根本单位,一个 Pod 代表集群上正在运行的一个过程。
一个 Pod 封装一个利用容器(也能够有多个容器),存储资源、一个独立的网络 IP 以及管理控制容器运行形式的策略选项。Pod 代表部署的一个单位:Kubernetes 中单个利用的实例,它可能由单个容器或多个容器共享组成的资源。

  • 容器存活周期
    init containers – 能够有多个,串行运行 实现后才会持续运行后续操作
    post start hook – 启动后操作
    startup probe – 启动开始执行
    liveness probe – 循环周期性探针
    readiness probe – 循环周期性探针
    pre stop hook – 终止时执行
  1. 用户通过 kubectl 或者其余 API 客户端提交 Pod Spec 给 API Server。
  2. API Server 将 Pod 对象的相干信息存入 etcd 中。
  3. 待写入 etcd 操作实现,etcd 将写入操作实现信息发送给 API Server。
  4. .API Server 将 etcd 写入实现信息返回给 kubectl 或者其余客户端。
  5. kube-scheduler 监听到 API Server 要创立一个新的 Pod,而后开始对 Pod 进行调度绑定到 Node。
  6. 绑定 Node 胜利后,kube-scheduler 将 bind 后果返回给 API Server。
  7. API Server 将 bind 信息存储到 etcd 零碎中
  8. etcd 将存储后果返回给 API Server。
  9. API Server 告知 kube-scheduler 调度 Pod 信息已存储实现。
  10. kubelet 也在始终监听 API Server,所以 kubelet 从 API Server 得悉有一个 Pod 被调度到以后 Node 上,此时 API Server 也在监 kubelet 的信息。
  11. kubelet 调用以后节点的 Docker 来启动容器。
  12. 容器启动胜利后,docker 将启动状态返回给 kubelet。
  13. kubelet 收到 docker 返回的容器状态信息后,将容器状态信息更新给 API Server。
  14. API Server 将 Pod 更新信息写入到 etcd 中。
  15. etcd 写入后将写入后果返回给 API Server。
  16. API Server 将确认信息发送至相干的 kubelet,事件将通过它被承受。

2.1 kubernetes yaml 文件资源定义标准

- apiVersion: ... #资源对象所属的 API 群组及版本
- kind:... #资源类型
- metadata:  #资源对象的原数据
......
- spec:   #所需状态或称为冀望状态
......
- status:  #零碎定义  理论状态

2.2 Pod env 环境变量

  • env 是容器级别的资源 所以只能在 containers 级别以下

    [root@k8s-master pod]# cat mypod-env.yaml 
    apiVersion: v1
    kind: Pod
    metadata:
    name: mypod-env
    labels:
      app: mypod
      release: canary
    spec:
    containers:
    - name: demoapp
      image: ikubernetes/demoapp:v1.0
      env:     #创立环境变量
      - name: HOST
        value: "127.0.0.1"
      - name: PORT
        value: "8080"   #能过环境变量批改主镜像默认端口
    
    [root@k8s-master pod]# kubectl apply -f mypod-env.yaml 
    pod/mypod-env created
    [root@k8s-master pod]# kubectl exec mypod-env -- netstat -tnl
    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State       
    tcp        0      0 127.0.0.1:8080          0.0.0.0:*               LISTEN      
    [root@k8s-master pod]# kubectl exec mypod-env -- printenv
    PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    HOSTNAME=mypod-env
    PORT=8080
    HOST=127.0.0.1
    MY_GRAFANA_SERVICE_PORT=80
    MY_GRAFANA_PORT_80_TCP=tcp://10.96.4.185:80
    KUBERNETES_PORT=tcp://10.96.0.1:443
    MY_GRAFANA_SERVICE_HOST=10.96.4.185
    MY_GRAFANA_SERVICE_PORT_SERVICE=80
    MY_GRAFANA_PORT=tcp://10.96.4.185:80
    MYAPP_SERVICE_HOST=10.106.116.205
    KUBERNETES_SERVICE_HOST=10.96.0.1
    KUBERNETES_SERVICE_PORT=443
    

    2.3 容器端口裸露 2 种办法

办法 1:应用 hostPort: 字段 毛病:只能在 pod 运行的节点宿主节点拜访,事先要确定可用端口
在试验测试中:
宿主机 win7 无奈关上:http://192.168.54.171:10080/ tcping64 端口测试时是通的,Linux 宿主机能关上
进入 K8S 容器 也能通过 192.168.54.171:10080/ 关上

这个有待换一个环境从新测试 确定是否为公司网络问题导致

示例 1:通过 hostPort 裸露端口

[root@k8s-master pod]# kubectl explain pods.spec.containers.ports  #通过 explain 查看 Pod 的对象阐明
KIND:     Pod
VERSION:  v1
...
FIELDS:
   containerPort    <integer> -required-
     Number of port to expose on the pod's IP address. This must be a valid port
     number, 0 < x < 65536.

   hostIP    <string>
     What host IP to bind the external port to.

   hostPort    <integer>
     Number of port to expose on the host. If specified, this must be a valid
     port number, 0 < x < 65536. If HostNetwork is specified, this must match
     ContainerPort. Most containers do not need this.

   name    <string>
     If specified, this must be an IANA_SVC_NAME and unique within the pod. Each
     named port in a pod must have a unique name. Name for the port that can be
     referred to by services.

   protocol    <string>
     Protocol for port. Must be UDP, TCP, or SCTP. Defaults to "TCP".

[root@k8s-master pod]# cat mypod-port.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: mypod-port
  labels:
    app: mypod
    release: canary
spec:
  containers:
  - name: demoapp
    image: ikubernetes/demoapp:v1.0
    ports:
    - containerPort: 80
      name: http    #从阐明看不是必须字段 
      protocol: TCP  #也不是必须字段  默认就是 TCP 协定
      hostPort: 10080  #应用节点 IP 但指能在部署的节点失效

[root@k8s-master pod]# kubectl apply -f mypod-port.yaml 


[root@k8s-master pod]# kubectl describe  pod mypod-port
Name:         mypod-port
Namespace:    default
Priority:     0
Node:         k8s-node1/192.168.4.171
Start Time:   Mon, 19 Jul 2021 06:27:36 +0800
Labels:       app=mypod
              release=canary
Annotations:  <none>
Status:       Running
IP:           10.244.1.75
IPs:
  IP:  10.244.1.75
Containers:
  demoapp:
    Container ID:   docker://4a2902d4fcc8bdb872f289bae68a17dee3f127cf6dc2e5e9fa625ee1de12f45b
    Image:          ikubernetes/demoapp:v1.0
    Image ID:       docker-pullable://ikubernetes/demoapp@sha256:6698b205eb18fb0171398927f3a35fe27676c6bf5757ef57a35a4b055badf2c3
    Port:           80/TCP
    Host Port:      10080/TCP

[root@centos-deployment-nq5b2 /]# curl 192.168.54.171:10080
iKubernetes demoapp v1.0 !! ClientIP: 192.168.54.172, ServerName: mypod-port, ServerIP: 10.244.1.75!

[root@centos-deployment-nq5b2 /]# curl 192.168.4.171:10080
iKubernetes demoapp v1.0 !! ClientIP: 192.168.4.172, ServerName: mypod-port, ServerIP: 10.244.1.75!

示例 2:通过 hostNetwork 应用宿主机的网络名称空间

不倡议应用 存在很大危险

[root@k8s-master pod]# cat  mypod-port.network.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: mypod-port-network
  labels:
    app: mypod
    release: canary
spec:
  hostNetwork: True  #为 spec 级别下字段
  containers:
  - name: demoapp
    image: ikubernetes/demoapp:v1.0
    ports:
    - containerPort: 80
      name: http    #从阐明看不是必须字段 

[root@k8s-master pod]# kubectl describe pod mypod-port-network
Name:         mypod-port-network
Namespace:    default
Priority:     0
Node:         k8s-node1/192.168.4.171   #调度到了节点 1
Start Time:   Mon, 19 Jul 2021 06:54:52 +0800
Labels:       app=mypod
              release=canary
Annotations:  <none>
Status:       Running
IP:           192.168.4.171
IPs:
  IP:  192.168.4.171
Containers:
  demoapp:
    Container ID:   docker://5f87c717de36d6f3366880f0289834091b0274d20e31037f45ce799f8c566ed0
    Image:          ikubernetes/demoapp:v1.0
    Image ID:       docker-pullable://ikubernetes/demoapp@sha256:6698b205eb18fb0171398927f3a35fe27676c6bf5757ef57a35a4b055badf2c3
    Port:           80/TCP
    Host Port:      80/TCP



[root@centos-deployment-nq5b2 /]# curl 192.168.54.171
iKubernetes demoapp v1.0 !! ClientIP: 192.168.54.172, ServerName: k8s-node1, ServerIP: 192.168.4.171!
[root@centos-deployment-nq5b2 /]# curl 192.168.4.171
iKubernetes demoapp v1.0 !! ClientIP: 192.168.4.172, ServerName: k8s-node1, ServerIP: 192.168.4.171!
[root@centos-deployment-nq5b2 /]# curl 192.168.4.172
curl: (7) Failed to connect to 192.168.4.172 port 80: Connection refused

[root@k8s-master pod]# kubectl exec mypod-port-network -it -- /bin/sh
[root@k8s-node1 /]# ifconfig    #能够看到应用的是 node1 的网络名称空间
cni0      Link encap:Ethernet  HWaddr DE:D3:66:00:87:D9  
          inet addr:10.244.1.1  Bcast:10.244.1.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1450  Metric:1
          RX packets:206602 errors:0 dropped:0 overruns:0 frame:0
          TX packets:294192 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:24995776 (23.8 MiB)  TX bytes:29296512 (27.9 MiB)

docker0   Link encap:Ethernet  HWaddr 02:42:C0:7C:39:EA  
          inet addr:172.17.0.1  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

eth0      Link encap:Ethernet  HWaddr 52:54:00:CD:20:65  
          inet addr:192.168.4.171  Bcast:192.168.4.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:416493 errors:0 dropped:0 overruns:0 frame:0
          TX packets:297963 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:226545589 (216.0 MiB)  TX bytes:58159114 (55.4 MiB)

flannel.1 Link encap:Ethernet  HWaddr D6:E6:E4:7F:B6:C0  
......

平安上下文 Security Context

  • 一组用于决定容器是如何创立和运行的约束条件, 它们代表创立和运行容器时应用的运行时参数;
    比方:容器运行时的用户、用户的权限等

Pod 上的 SC 有两个级别 别离为 Pod 级别、容器级别

3.1 常用字段 Pod 级别的平安上下文

apiVersion: v1
kind: Pod
metadata: {...}
spec:
  securityContext:    #Pod 级别的平安上下文, 对外部所有容器均无效
    runAsUser <integer>  #以指定的用户身份运行容器过程,默认由镜像中的 USER 指定
    runAsGroup <integer>  #以指定的用户组运行容器过程,默认应用的组随容器运行时
    supplementalGroups <[]integer> #为容器中 1 号过程的用户增加的附加组;
    fsGroup <integer>    #为容器中的 1 号过程附加的一个专用组,其性能相似于 sgid
    runAsNonRoot <boolean> #是否以非 root 身份运行
    seLinuxOptions <0bject>  #SELinux 的相干配置
    windowsOptions<Object>   #Windows 容器专用的设置
    sysctls   <[]Object>   #利用到以后 Pod 上的名称空间级别的 sysctl 参数设置列表
        Pod 内可平安内核参数只有 4 个: 
        kernel.shm_rmid_forced
        net.ipv4.ip_local_port_range
        net.ipv4.tcp_syncookies
        net.ipv4.ping_group_range(从 Kubernetes 1.18 开始)其它参数须要重启 K8S 在 /etc/defaulte/kubelte(如果没有则新建)中增加
        net.ipv4.ip_unprivileged_port_start
        --allowed-unsafe-sysctls=net.core.somaxconn
        ......

3.2 常用字段 容器级别的平安上下文

  containers:
  - name: ...
    image: .
    securityContext:  #容器级别的平安上下文, 仅失效于以后容器
      runAsUser <integer>    #以指定的用户身份运行容器过程
      runAsGroup <integer>   #以指定的用户组运行容器过程
      runAsNonRoot <boolean>  #是否以非 root 身份运行
      allowPrivilegeEscalation <boolean> #是否容许特权降级
      capabilities <Object>  #于以后容器上增加 (add) 或删除 (drop) 的内核能力
        add<[]string>  #增加由列表定义的各内核能力
        drop <[]string>  #移除由列表定义的各内核能力
            CAP_CHOWN: 扭转 UID 和 GID;
            CAP_MKNOD:mknod() 创立设施文件;
            CAP_NET_ADMIN: 网络管理权限;
            CAP_SYSADMIN: 大部分的管理权限;
            CAP_SYS_TIME: 同步工夫
            CAP_SYS MODULE: 装载卸载内核模块
            CAP_NET_BIND_SERVER: 容许绑定 1024 以内特权端口
            也能够管理员 getcap, setcap 间接设置权限(理解)
      privileged <boolean>  #是否运行为特权容器 可间接应用宿主机内核 审慎应用
      procMount <string>   #设置容器的 procMount 类型,默认为 DefaultProcMount;
      readOnlyRootFilesystem boolean>  #是否将根文件系统设置为只读模式
      seLinux0ptions <Object> #SELinux 的相干配置
      windowsoptions <Object> #windows 容器专用的设置

3.3 inagePullPolicy 镜像拉取策略

  • inagePullPolicy:

    • Never: 从不执行拉取操作,意味着只应用节点上本地镜像
    • IfNotPresent: 被绑定的节点上不存在指标镜像去拉取; 非 latest 标签的默认值
    • Always: 总是拉取; latest 标签的默认值

示例 1 要求:1. 普通用户运行容器;2. 普通用户运行容器

$ cat securitycontext-runasuser-demo.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: securitycontext-runasuser-damo
  namespace: default
spec:
  containers:
  - name: demo
    image: ikubernetes/demoapp:v1.0
    imagePullPolicy: IfNotPresent
    env:
    - name: PORT
      value: "8080"    #普通用户不具备应用 1024 以下端口 为避免出错应用 8080 让 demoapp 运行在非 80 端口上
    securityContext:
      runAsUser: 1001   #应用非管理员启动
      runAsGroup: 1001

$ kubectl apply -f securitycontext-runasuser-demo.yaml
$ kubectl exec securitycontext-runasuser-damo -- ps aux  #查看运行的帐户为 1001
PID   USER     TIME  COMMAND
    1 1001      0:00 python3 /usr/local/bin/demo.py   
    8 1001      0:00 ps aux

$ kubectl exec securitycontext-runasuser-damo -- netstat -tnlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      1/python3

示例 2 要求:1. 批改网络权限;2. 实现 8080 端口转 80 端口

$ cat securitycontext-capabilities-demo.yaml    #先正文权限字段
apiVersion: v1
kind: Pod
metadata:
  name: securitycontext-capabilities-damo
  namespace: default
spec:
  containers:
  - name: demo
    image: ikubernetes/demoapp:v1.0
    imagePullPolicy: IfNotPresent
    command: ["/bin/sh","-c"]   #相当于 docker 的 cmd
    args: ["/sbin/iptables -t nat -A PREROUTING -p tcp  --dport 8080 -j REDITRECT  --to-port 80 && /usr/bin/python3 /usr/local/bin/demo.py"]   #传递 cmd 命令  iptables 端口 8080 转发到 80
#    securityContext:
#      capabilities:
#        add: ['NET_ADMIN']  #增加网络权限
#        drop: ['CHOWN']   #禁用默认的批改权限

$ kubectl apply -f securitycontext-capabilities-demo.yaml 
$ kubectl get pod
NAME                                READY   STATUS    RESTARTS   AGE
...
securitycontext-capabilities-damo   0/1     Error     0          4s

$ kubectl describe pod securitycontext-capabilities-damo
...
Containers:
...
    Command:
      /bin/sh
      -c
    Args:
      /sbin/iptables -t nat -A PREROUTING -p tcp  --dport 8080 -j REDIRECT  --to-port 80 && /usr/bin/python3 /usr/local/bin/demo.py
    State:          Terminated
      Reason:       Error
......

$ kubectl logs   securitycontext-capabilities-damo #权限有余
getsockopt failed strangely: Operation not permitted  

$ kubectl delete -f securitycontext-capabilities-demo.yaml --force --grace-period=0

$ cat securitycontext-capabilities-demo.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: securitycontext-capabilities-damo
  namespace: default
spec:
  containers:
  - name: demo
    image: ikubernetes/demoapp:v1.0
    imagePullPolicy: IfNotPresent
    command: ["/bin/sh","-c"]      #相当于 docker 的 cmd
    args: ["/sbin/iptables -t nat -A PREROUTING -p tcp  --dport 8080 -j REDIRECT  --to-port 80 && /usr/bin/python3 /usr/local/bin/demo.py"]   #传递 cmd 命令  iptables 端口 8080 转发到 80
    securityContext:
      capabilities:
        add: ['NET_ADMIN']  #增加网络权限
        drop: ['CHOWN']   #禁用默认的批改权限

$ kubectl get pod -o wide
NAME                                READY   STATUS    RESTARTS   AGE   IP              NODE        NOMINATED NODE   READINESS GATES
...
securitycontext-capabilities-damo   1/1     Running   0          7m    10.244.1.81     k8s-node1   <none>           <none>
  • 查看 iptables 规定 实现端口 8080 转发

    [root@k8s-master secucontext]# kubectl exec securitycontext-capabilities-damo -it -- iptables -vnL -t nat
    Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination         
      0     0 REDIRECT   tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:8080 redir ports 80
  • 两个端口都能够拜访

    $ curl 10.244.1.81
    iKubernetes demoapp v1.0 !! ClientIP: 10.244.0.0, ServerName: securitycontext-capabilities-damo, ServerIP: 10.244.1.81!
    $ curl 10.244.1.81:8080
    iKubernetes demoapp v1.0 !! ClientIP: 10.244.0.0, ServerName: securitycontext-capabilities-damo, ServerIP: 10.244.1.81!
  • 测试批改权限
$ kubectl exec securitycontext-capabilities-damo -it -- id  #root 帐户
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)
$ kubectl exec securitycontext-capabilities-damo -it -- ls -l /etc/hosts
-rw-r--r--    1 root     root           229 Jul 20 15:43 /etc/hosts
$ kubectl exec securitycontext-capabilities-damo -it -- chown test  /etc/hosts   #批改权限失败
chown: unknown user test
command terminated with exit code 1

示例 3 要求: 增加网络管理权限

[root@k8s-master secucontext]# cat securitycontext-sysctls-damo.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: securitycontext-sysctls-damo
  namespace: default
spec:
  securityContext:
    sysctls:
    - name: kernel.shm_rmid_forced
      value: "0"
    - name: net.ipv4.ip_unprivileged_port_start  #特权端口从 0 开始 但须要增加到 k8s 配置重启 K8S
      value: "0"
  containers:
  - name: demo
    image: ikubernetes/demoapp:v1.0
    imagePullPolicy: IfNotPresent
    securityContext:
      runAsUser: 1001   #普通用户运行 本意是下面设置特权端口从 0 开始 普通用户也就能够应用 80 端口 
      runAsGroup: 1001

[root@k8s-master secucontext]# kubectl get pod     #提醒 sysctl 批改被回绝
NAME                                READY   STATUS            RESTARTS   AGE
...
securitycontext-sysctls-damo        0/1     SysctlForbidden   0          4s

正文完
 0