01.kubernetes笔记 Pod及 Security Context安全上下文

Bigyong

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 --终止时执行
    Pod存活周期
  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
阅读 159
16 声望
4 粉丝
0 条评论
你知道吗?

16 声望
4 粉丝
宣传栏