2020年6月

什么时候会释放Gil锁,
1 遇到像 i/o操作这种 会有时间空闲情况 造成cpu闲置的情况会释放Gil
2 会有一个专门ticks进行计数 一旦ticks数值达到100 这个时候释放Gil锁 线程之间开始竞争Gil锁(说明:
    ticks这个数值可以进行设置来延长或者缩减获得Gil锁的线程使用cpu的时间)

互斥锁和Gil锁的关系
Gil锁 : 保证同一时刻只有一个线程能使用到cpu
互斥锁 : 多线程时,保证修改共享数据时有序的修改,不会产生数据修改混乱

首先假设只有一个进程,这个进程中有两个线程 Thread1,Thread2, 要修改共享的数据date, 并且有互斥锁

执行以下步骤

(1)多线程运行,假设Thread1获得GIL可以使用cpu,这时Thread1获得 互斥锁lock,Thread1可以改date数据(但并
没有开始修改数据)

(2)Thread1线程在修改date数据前发生了 i/o操作 或者 ticks计数满100 (注意就是没有运行到修改data数据),这个
时候 Thread1 让出了Gil,Gil锁可以被竞争

(3) Thread1 和 Thread2 开始竞争 Gil (注意:如果Thread1是因为 i/o 阻塞 让出的Gil Thread2必定拿到Gil,如果
Thread1是因为ticks计数满100让出Gil 这个时候 Thread1 和 Thread2 公平竞争)

(4)假设 Thread2正好获得了GIL, 运行代码去修改共享数据date,由于Thread1有互斥锁lock,所以Thread2无法更改共享数据
date,这时Thread2让出Gil锁 , GIL锁再次发生竞争 

(5)假设Thread1又抢到GIL,由于其有互斥锁Lock所以其可以继续修改共享数据data,当Thread1修改完数据释放互斥锁lock,
Thread2在获得GIL与lock后才可对data进行修改

netstat -aptn命令行,查看所有开启的端口号

netstat -nupl 查看所有使用udp协议的端口

netstat -ntpl 查看所有使用tcp协议的端口

-t (tcp) 仅显示tcp相关选项
-u (udp)仅显示udp相关选项
-n 拒绝显示别名,能显示数字的全部转化为数字
-l 仅列出在Listen(监听)的服务状态
-p 显示建立相关链接的程序名

检查 firewalld ufw iptables状态

win端口
netstat -ano | findstr "8009"
taskkill /f /pid 61772

  1. 设置容器内运行用户或开启USER NAMESPACE

永远不要以root用户的身份在容器内运行正式的应用,否则一旦攻击者攻破了应用就能获取容器的全部访问权限。

而且在未开启USER NAMESPACE的情况下,该权限会蔓延到主机挂载到容器中的卷上。

更糟糕的是,若他能突破容器的限制,则它就能获得主机上的root权限了。

  1. 限制容器联网

容器应该仅仅打开必须的端口,且只对所需的容器开放。

为了实现这一点,Docker守护进程启动时需要加上 --icc=false 参数以关容器间的默认通讯。

另外,在主机上发布端口时,Docker默认在主机所有接口上发布,最好明确指定希望绑定的接口以减少攻击面

docker run -p 192.168.1.9:8080:8080 -d httpd

  1. 删除容器中的setuid和setgid文件

这类文件一般只在构建镜像时有用,但却极易被利用来发动提权攻击。

可以通过下面命令来找出并移除二进制文件的suid/sgid设置

RUN find / -perm /6000 -type f -exec chmod a-s {} ;||true

  1. 限制内存使用

限制容器内存使用可以防止DoS攻击和应用程序的内存泄漏。

  1. 限制CPU使用

若不限制容器的CPU使用率,则攻击者可以通过一个容器将主机CPU完全占用,从而导致系统被DoS攻击瘫痪。

CPU的限制参数包括如下:

docker run --help|grep cpu

--cpu-period int                 Limit CPU CFS (Completely Fair
--cpu-quota int                  Limit CPU CFS (Completely Fair
--cpu-rt-period int              Limit CPU real-time period in
--cpu-rt-runtime int             Limit CPU real-time runtime in

-c, --cpu-shares int CPU shares (relative weight)

--cpus decimal                   Number of CPUs
--cpuset-cpus string             CPUs in which to allow execution
--cpuset-mems string             MEMs in which to allow execution
  1. 限制IO

docker help run |grep -E 'jbps|IO'
Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

  --blkio-weight uint16            Block IO (relative weight),
  --blkio-weight-device list       Block IO weight (relative device
  --device-read-iops list          Limit read rate (IO per second)
  --device-write-iops list         Limit write rate (IO per second)
  1. 限制重启次数

若系统不断崩溃又不断重启,将会造成大量系统时间和资源浪费。

为了防止这种情况出现,我们可以将重启策略由 always 改成 on-failure 并指定重启次数

docker run -d --restart=on-failure:10 $image
容器的重启次数可以通过 docker inspect 的 .RestartCount 元数据找到

docker inspect -f "{{.RestartCount}}" $container
另外,Docker重启容器的时间间隔采用指数递增的方式进行,即第一次重启等待100ms,第二次200ms,第三次400ms,这个措施能有效防止利用重启机制引发DoS攻击

  1. 设置文件系统只读

阻止攻击者对容器内文件系统的写入可以抵御系统的攻击。

在 docker run 中使用 --read-only 参数可以把容器的文件系统设置为只读:

docker run --read-only ubuntu touch x 2>&1 || exit 0
touch: cannot touch 'x': Read-only file system
给数据卷参数后加上 :ro 则能够把卷设为只读

docker run -v ${pwd}:/pwd:ro ubuntu touch /touch /pwd/x 2>&1 ||exit 0
touch: cannot touch '/pwd/x': No such file or directory

  1. 限制内核能力

我们可以通过 docker run 的 --cap-add 和 --cap-drop 参数来控制容器允许使用的内核能力。

最不安全的做法就是通过 --privileged 参数放开权限。

一般的做法是先把所有权限清空,再把需要的权限添加回去

docker run --cap-drop all --cap-add CHOWN ubuntu chown 770 /tmp

  1. 应用资源限制

Linux内核定义了一些用于进程的资源限制,可以限制进程允许fork的子进程数,或者允许打开的文件描述符数量等。

通过 docker run 的 --ulimit 选项可以将限制也用于容器上。 同时,我们可以在启动Docker守护进程时加上 --default-ulimit 选项来给所有容器设置资源限制的默认值。 选项参数中包括两个数值,其格式为 资源=软限制:硬限制 ,若只提供一个值,则表示同时作为软限制和硬限制。

比较常用的限制包括以下几个:

cpu
把CPU时间限制为给定参数,以秒为单位。

当达到软限制后,会发送一个 SIGXCPU给容器,达到硬限制后则会发送一个 SIGKILL 信号给容器

docker run --ulimit cpu=12:14 stress stress --cpu 1
nofile
制定容器中能够同时打开的最多文件描述符数量

docker run --ulimit nofile=5 ubuntu cat /etc/hostname
需要注意的是,操作系统本身会占用3个文件描述符,分别对应stdin,stdout,stderr

nproc
指定运行容器的用户能够创建进程的最大数量。

docker run --user 500 --ulimit nproc=2 -d ubuntu sleep 100
需要注意的是: nproc限制的不是容器,而是运行这个容器的用户的所有进程数量

  1. 启用Linux安全模块(LSM)

最常见的Linux安全模块包括AppArmor和SELinux。

通过 docker run 的 --security-opt 选项可以设置容器的标签,使之与LSM整合在一起

  1. 审核容器和镜像

定期检查正在运行的容器,确保使用的镜像是最新的,而且这些镜像所使用的如那件也是最新的,没有安全隐患的。
使用 docker diff 检查容器与镜像之间的差异
运行极简的镜像,其中只包含应用程序必需的文件和程序库

  1. 为Docker Daemon开启TLS加密传输

若Docker Daemon通过TCP方式与外界通讯,则可能传输内容会被截获,为此Docker Daemon提供了4个参数来开启TLS加密传输
docker daemon --tlsverify \

   --tlscacert=ca.pem \
   --tlscert=server-cert.pem \
   --tlskey=server-key.pem \
   -H=0.0.0.0:2376

--tlsverify
安全传输验证
--tlscacert=ca.pem
信任的证书
--tlscert=server-cert.pem
服务证书
--tlskey=server-key.pem
服务器或客户端密钥
当然,相应的在客户端连接时也需要设置这四个参数:
docker --tlsverify \

   --tlscacert=ca.pem \
   --tlscert=cert.pem \
   --tlskey=key.pem \
   -H=${DAEMON_HOST}:2376
  1. 注意那些未隔离的内核资源

目前namespace在隔离上并不完善,还有许多未隔离的内核资源可能会影响到容器安全,比如 procfs, syslog 等

YAML 的语法和其他高级语言类似,并且可以简单表达清单、散列表,标量等数据形态。它使用空白符号缩进和大量依赖外观的特色,特别适合用来表达或编辑数据结构、各种配置文件、倾印调试内容、文件大纲(例如:许多电子邮件标题格式和YAML非常接近)。

YAML 的配置文件后缀为 .yml,如:runoob.yml 。

基本语法
大小写敏感
使用缩进表示层级关系
缩进不允许使用tab,只允许空格
缩进的空格数不重要,只要相同层级的元素左对齐即可
'#'表示注释

数据类型
YAML 支持以下几种数据类型:

对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)
纯量(scalars):单个的、不可再分的值

AML 对象
对象键值对使用冒号结构表示 key: value,冒号后面要加一个空格。

也可以使用 key:{key1: value1, key2: value2, ...}。

还可以使用缩进表示层级关系;

key:

child-key: value
child-key2: value2

较为复杂的对象格式,可以使用问号加一个空格代表一个复杂的 key,配合一个冒号加一个空格代表一个 value:

?

- complexkey1
- complexkey2

:

- complexvalue1
- complexvalue2

意思即对象的属性是一个数组 [complexkey1,complexkey2],对应的值也是一个数组 [complexvalue1,complexvalue2]

YAML 数组
以 - 开头的行表示构成一个数组:

  • A
  • B
  • C
    YAML 支持多维数组,可以使用行内表示:

key: [value1, value2, ...]
数据结构的子成员是一个数组,则可以在该项下面缩进一个空格。

-

  • A
  • B
  • C
    一个相对复杂的例子:

companies:

-
    id: 1
    name: company1
    price: 200W
-
    id: 2
    name: company2
    price: 500W

意思是 companies 属性是一个数组,每一个数组元素又是由 id、name、price 三个属性构成。

数组也可以使用流式(flow)的方式表示:

companies: [{id: 1,name: company1,price: 200W},{id: 2,name: company2,price: 500W}]

复合结构
数组和对象可以构成复合结构,例:

languages:

  • Ruby
  • Perl
  • Python
    websites:

YAML: yaml.org
Ruby: ruby-lang.org
Python: python.org
Perl: use.perl.org
转换为 json 为:

{
languages: [ 'Ruby', 'Perl', 'Python'],
websites: {

YAML: 'yaml.org',
Ruby: 'ruby-lang.org',
Python: 'python.org',
Perl: 'use.perl.org' 

}
}

纯量
纯量是最基本的,不可再分的值,包括:

字符串
布尔值
整数
浮点数
Null
时间
日期

引用
& 锚点和 * 别名,可以用来引用:

defaults: &defaults
adapter: postgres
host: localhost

development:
database: myapp_development
<<: *defaults

test:
database: myapp_test
<<: *defaults
相当于:

defaults:
adapter: postgres
host: localhost

development:
database: myapp_development
adapter: postgres
host: localhost

test:
database: myapp_test
adapter: postgres
host: localhost
& 用来建立锚点(defaults),<< 表示合并到当前数据,* 用来引用锚点。

下面是另一个例子:

  • &showell Steve
  • Clark
  • Brian
  • Oren
  • *showell
    转为 JavaScript 代码如下:

[ 'Steve', 'Clark', 'Brian', 'Oren', 'Steve' ]

镜像的保存
[root@wxtest1607 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat8 3.0 90457edaf6ff 6 hours ago 1.036 GB
[root@wxtest1607 lixr]# docker save 9045 > tomcat8-apr.tar
[root@wxtest1607 lixr]# ls -lh
总用量 1.2G
-rw-r--r-- 1 root root 1005M 8月 24 17:42 tomcat8-apr.tar

镜像的导入
当前缺一台CentOS7服务器,实践方式变成,先删除image,然后再导入,折腾呀!
[root@wxtest1607 lixr]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat8 3.0 90457edaf6ff 7 hours ago 1.036 GB
[root@wxtest1607 lixr]# docker rmi 9045
Untagged: tomcat8:3.0
Deleted: sha256:90457edaf6ff4ce328dd8a3131789c66e6bd89e1ce40096b89dd49d6e9d62bc8
Deleted: sha256:00df1d61992f2d87e7149dffa7afa5907df3296f5775c53e3ee731972e253600
[root@wxtest1607 lixr]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
[root@wxtest1607 lixr]# docker load < tomcat8-apr.tar
60685807648a: Loading layer [==================================================>] 442.7 MB/442.7 MB
[root@wxtest1607 lixr]# yer [> ] 527.7 kB/442.7 MB
[root@wxtest1607 lixr]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 90457edaf6ff 7 hours ago 1.036 GB
[root@wxtest1607 lixr]# docker tag 9045 tomcat8-apr:3.0
[root@wxtest1607 lixr]#
[root@wxtest1607 lixr]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat8-apr 3.0 90457edaf6ff 7 hours ago 1.036 GB

容器的导出
[root@wxtest1607 lixr]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b91d9ad83efa 9045 "/bin/bash" 18 seconds ago Up 15 seconds trusting_colden
f680b58163ab aa79 "/bin/bash" 8 hours ago Up 8 hours stupefied_mayer
4db6aa9b8278 4052 "mysqld_safe" 21 hours ago Up 21 hours 8080/tcp, 0.0.0.0:53307->3306/tcp nostalgic_leavitt
7bcfe52af7a0 599d "mysqld_safe" 21 hours ago Up 21 hours 8080/tcp, 0.0.0.0:53306->3306/tcp sleepy_hodgkin
[root@wxtest1607 lixr]#
[root@wxtest1607 lixr]#
[root@wxtest1607 lixr]# docker export b91d9ad83efa > tomcat80824.tar
[root@wxtest1607 lixr]# ls -lh
总用量 2.1G
-rw-r--r-- 1 root root 943M 8月 24 18:37 tomcat80824.tar
-rw-r--r-- 1 root root 1005M 8月 24 17:42 tomcat8-apr.tar

b91d9ad83efa 是 镜像90457edaf6ff 启动后的容器。
镜像导出的文件比容器导出文件大哦。

容器的导入
[root@wxtest1607 lixr]# docker import tomcat80824.tar
sha256:880fc96a6bb6abdfa949a56d40ef76f32f086fa11024ddcfb4e4e8b22041d5f2
[root@wxtest1607 lixr]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 880fc96a6bb6 6 seconds ago 971.9 MB
[root@wxtest1607 lixr]# docker tag 880f tomcat80824:1.0
[root@wxtest1607 lixr]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat80824 1.0 880fc96a6bb6 About a minute ago 971.9 MB
tomcat8-apr 3.0 90457edaf6ff 8 hours ago 1.036 GB

镜像和容器 导出和导入的区别
镜像导入和容器导入的区别:
1)容器导入 是将当前容器 变成一个新的镜像
2)镜像导入 是复制的过程
save 和 export区别:
1)save 保存镜像所有的信息-包含历史
2)export 只导出当前的信息
[root@wxtest1607 lixr]# docker history 880fc96a6bb6
IMAGE CREATED CREATED BY SIZE COMMENT
880fc96a6bb6 12 minutes ago 971.9 MB Imported from -
[root@wxtest1607 lixr]# docker history 90457edaf6ff
IMAGE CREATED CREATED BY SIZE COMMENT
90457edaf6ff 8 hours ago /bin/bash 434.4 MB
<missing> 23 hours ago /bin/bash 406.5 MB
<missing> 7 weeks ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0 B
<missing> 7 weeks ago /bin/sh -c #(nop) LABEL license=GPLv2 0 B
<missing> 7 weeks ago /bin/sh -c #(nop) LABEL vendor=CentOS 0 B
<missing> 7 weeks ago /bin/sh -c #(nop) LABEL name=CentOS Base Imag 0 B
<missing> 7 weeks ago /bin/sh -c #(nop) ADD file:b3bdbca0669a03490e 194.6 MB
<missing> 7 weeks ago /bin/sh -c #(nop) MAINTAINER The CentOS Proje 0 B