泰州企业网站模板建站,经典网站赏析,一个简单的个人网站,做网站卖狗挣钱吗###1.Docker介绍### 什么是Docker Docker 是一个开源的应用容器引擎#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中#xff0c;然后发布到任何流行的 Linux或Windows 机器上#xff0c;也可以实现虚拟化。容器是完全使用沙箱机制#xff0c;相互之间…###1.Docker介绍### 什么是Docker Docker 是一个开源的应用容器引擎让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中然后发布到任何流行的 Linux或Windows 机器上也可以实现虚拟化。容器是完全使用沙箱机制相互之间不会有任何接口。 Docker为应用打包、部署平台而非单纯的虚拟化技术。 一个完整的 Docker 由以下几个部分组成 DockerClient 客户端 Docker Daemon 守护进程 Docker Image 镜像 DockerContainer 容器 VM VS Container 传统虚拟化与容器技术对比 docker容器的优势 更高效的利用系统资源 更快速的启动时间 一致的运行环境 持续支付和部署 更轻松的迁移 更轻松的维护和拓展 • 对于开发人员Build once、Run anywhere。 • 对于运维人员Configure once、Run anything。 容器技术大大提升了IT人员的幸福指数 容器工作原理 Docker 使用客户端 - 服务器C/S架构使用远程API管理和创建Docker 容器。Docker 客户端与 Docker 守护进程通信后者负责构建运行和分发 Docker容器。Docker客户端和守护进程可以在同一系统上运行也可以将Docker客户端连接到远程Docker守护进程。Docker客户端和守护进程使用REST API通过UNIX套接字或网络接口进行通信。 Client客户端通过命令行或其他工具与守护进程通信客户端会将这些命令发送给守护进程然后执行这些命令。命令使用Docker APIDocker客户端可以与多个守护进程通信。 Docker daemonDocker守护进程docker daemon监听Docker API请求并管理Docker对象如镜像容器网络和卷。守护程序还可以与其他守护程序通信以管理Docker服务。 Docker HostDocker Host 是物理机或虚拟机用于执行Docker守护进程的仓库。 Docker RegistryDocker仓库用于存储Docker镜像可以是Docker Hub这种公共仓库也可以是个人搭建的私有仓库。使用docker pull或docker run命令时将从配置的仓库中提取所需的镜像。使用docker push命令时镜像将被推送到配置的仓库。 ###2.Docker部署###
[rootserver1 ~]# cd /etc/yum.repos.d/
[rootserver1 yum.repos.d]# vim docker.repo
[docker]
namedocker-ce
baseurlhttps://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/7/x86_64/stable/
gpgcheck0[update]
namecentos
baseurlhttps://mirrors.tuna.tsinghua.edu.cn/centos/7/extras/x86_64/
gpgcheck0安装docker-ce
[rootserver1 yum.repos.d]# yum install -y docker-ce启动服务
[rootserver1 ~]# systemctl enable --now docker[rootserver1 ~]# docker info
WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled ##若出现这两个警告需要激活内核选项激活内核选项
[rootserver1 ~]# vim /etc/sysctl.d/docker.conf
net.bridge.bridge-nf-call-iptables 1
net.bridge.bridge-nf-call-ip6tables 1
net.ipv4.ip_forward 1[rootserver1 ~]# sysctl --system
[rootserver1 ~]# systemctl restart docker 启动容器
[rootserver1 ~]# docker run -d --name web1 -p 80:80 nginx
Unable to find image nginx:latest locally
latest: Pulling from library/nginx
3f9582a2cbe7: Pull complete
9a8c6f286718: Pull complete
e81b85700bc2: Pull complete
73ae4d451120: Pull complete
6058e3569a68: Pull complete
3a1b8f201356: Pull complete
Digest: sha256:aa0afebbb3cfa473099a62c4b32e9b3fb73ed23f2a75a65ce1d4b4f55a5c2ef2
Status: Downloaded newer image for nginx:latest
0ab8d0e38142e97b8c611b156d723b2546fc1623909b65a0f5f016d8a2a1668d显示激活的容器
[rootserver1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0ab8d0e38142 nginx /docker-entrypoint.… 8 seconds ago Up 7 seconds 0.0.0.0:80-80/tcp, :::80-80/tcp web1访问网页http://192.168.56.11/ 删除容器
[rootserver1 ~]# docker rm -f web1查询镜像
[rootserver1 ~]# docker search yakexi007拉取镜像到本地
[rootserver1 ~]# docker pull yakexi007/game2048启动容器
[rootserver1 ~]# docker run -d --name web1 -p 80:80 yakexi007/game2048访问网页http://192.168.56.11/ ###3.Docker镜像###
1镜像的分层结构 • 共享宿主机的kernel • base镜像提供的是最小的Linux发行版 • 同一docker主机支持运行多种Linux发行版 • 采用分层结构的最大好处是共享资源 • Copy-on-Write 可写容器层 • 容器层以下所有镜像层都是只读的 • docker从上往下依次查找文件 • 容器层保存镜像变化的部分并不会对镜像本身进行任何修改 • 一个镜像最多127层 2镜像常用子命令
• images 显示镜像列表
• history 显示镜像构建历史
• commit 从容器创建镜像
• build 从Dockerfile构建镜像
• tag 给镜像打标签
• search 搜索镜像
• pull 从仓库拉取镜像
• push 上传镜像到仓库
• rmi 删除镜像
3镜像构建
①docker commit docker commit 构建新镜像三部曲 • 运行容器 • 修改容器 • 将容器保存为新的镜像 缺点 • 效率低、可重复性弱、容易出错 • 使用者无法对镜像进行审计存在安全隐患 [rootserver1 ~]# docker pull busybox ##拉取一个小的镜像用来做测试
Using default tag: latest
latest: Pulling from library/busybox
ec562eabd705: Pull complete
Digest: sha256:9ae97d36d26566ff84e8893c64a6dc4fe8ca6d1144bf5b87b2b85a32def253c7
Status: Downloaded newer image for busybox:latest
docker.io/library/busybox:latest[rootserver1 ~]# docker run -it --name demo busybox ##交互式进入容器
/ # touch file1
/ # touch file2
ctrld 退出容器后容器自动关闭
ctrlpq 退出容器后继续在后台运行显示所有容器包括被停掉的
[rootserver1 ~]# docker ps -a启动容器
[rootserver1 ~]# docker start demo进入容器
[rootserver1 ~]# docker attach demo提交容器变更到新的镜像
[rootserver1 ~]# docker commit -m add files demo demo:v1[rootserver1 ~]# docker history demo:v1
IMAGE CREATED CREATED BY SIZE COMMENT
2b25ea847e4e 9 seconds ago sh 39B add files
827365c7baf1 13 days ago /bin/sh -c #(nop) CMD [sh] 0B
missing 13 days ago /bin/sh -c #(nop) ADD file:3f2f2548e5ddec788… 4.86MB这种方式不利于安全审计删除镜像
[rootserver1 docker]# docker rmi demo:v1 ②Dockerfile dockerfile常用指令 • FROM 指定base镜像如果本地不存在会从远程仓库下载。 • MAINTAINER 设置镜像的作者比如用户邮箱等。 • COPY 把文件从build context复制到镜像 支持两种形式COPY src dest 和 COPY [src, dest] src必须指定build context中的文件或目录 • ADD 用法与COPY类似不同的是src可以是归档压缩文件文件会被自动解压到dest 也可以自动下载URL并拷贝到镜像 ADD html.tar /var/www ADD http://ip/html.tar /var/www • ENV 设置环境变量变量可以被后续的指令使用 ENV HOSTNAME sevrer1.example.com • EXPOSE 如果容器中运行应用服务可以把服务端口暴露出去 EXPOSE 80 • VOLUME 申明数据卷通常指定的是应用的数据挂在点 VOLUME [/var/www/html] • WORKDIR 为RUN、CMD、ENTRYPOINT、ADD和COPY指令设置镜像中的当 前工作目录如果目录不存在会自动创建。 • RUN 在容器中运行命令并创建新的镜像层常用于安装软件包 RUN yum install -y vim • CMD 与 ENTRYPOINT 这两个指令都是用于设置容器启动后执行的命令但CMD会被docker run后面的命令行覆盖而ENTRYPOINT不会被忽略一定会被执行。 docker run后面的参数可以传递给ENTRYPOINT指令当作参数。 Dockerfile中只能指定一个ENTRYPOINT如果指定了很多只有最后一个有效。 • Shell和exec格式的区别 # cat Dockerfile FROM busybox ENV name world ENTRYPOINT echo hello, $name Shell格式底层会调用/bin/sh -c来执行命令可以解析变量而下面的 exec格式不会 # cat Dockerfile FROM busybox ENV name world ENTRYPOINT [/bin/echo, hello, $name] 需要改写成以下形式 # cat Dockerfile FROM busybox ENV name world ENTRYPOINT [/bin/sh, -c, echo hello, $name] Exec格式时ENTRYPOINT可以通过CMD提供额外参数CMD的额 外参数可以在容器启动时动态替换。在shell格式时ENTRYPOINT会忽 略任何CMD或docker run提供的参数。 # cat Dockerfile FROM busybox ENTRYPOINT [/bin/echo, hello] CMD [world] 看下在运行容器时的区别 # docker run --rm busybox:v1 hello world # docker run --rm busybox:v1 linux hello linux 官方推荐使用exec格式书写 一个简单dockerfile 配置nginx服务dockerfile
[rootserver1 ~]# mdkir docker
[rootserver1 ~]# cd docker/
[rootserver1 docker]# cp ~/nginx-1.23.3.tar.gz .
[rootserver1 docker]# vim Dockerfile
FROM centos:7
ADD nginx-1.23.3.tar.gz /mnt
WORKDIR /mnt/nginx-1.23.3
RUN yum install -y gcc make pcre-devel openssl-devel
RUN sed -i s/CFLAGS$CFLAGS -g/#CFLAGS$CFLAGS -g/g auto/cc/gcc
RUN ./configure --with-http_ssl_module --with-http_stub_status_module
RUN make
RUN make install
EXPOSE 80
VOLUME [/usr/local/nginx/html]
CMD [/usr/local/nginx/sbin/nginx, -g, daemon off;]构建镜像
[rootserver1 docker]# docker build -t webserver:v1 .[rootserver1 docker]# docker images webserver
REPOSITORY TAG IMAGE ID CREATED SIZE
webserver v1 bfd6774cc216 8 seconds ago 494MB[rootserver1 docker]# docker history webserver:v1清理所有停止的容器
[rootserver1 docker]# docker container prune启动容器
[rootserver1 docker]# docker run -d --name web1 webserver:v1
查看容器详情
[rootserver1 docker]# docker inspect web1
访问容器
[rootserver1 docker]# curl 172.17.0.2###4.Docker镜像优化### • 选择最精简的基础镜像 • 减少镜像的层数 • 清理镜像构建的中间产物 • 注意优化网络请求 • 尽量去用构建缓存 • 使用多阶段构建镜像 1缩短镜像层
[rootserver1 docker]# vim Dockerfile
FROM centos:7 as build
ADD nginx-1.23.3.tar.gz /mnt
WORKDIR /mnt/nginx-1.23.3
RUN yum install -y gcc make pcre-devel openssl-devel sed -i s/CFLAGS$CFLAGS -g/#CFLAGS$CFLAGS -g/g auto/cc/gcc ./configure --with-http_ssl_module --with-http_stub_status_module make make install cd .. rm -fr nginx-1.23.3 yum clean all
EXPOSE 80
VOLUME [/usr/local/nginx/html]
CMD [/usr/local/nginx/sbin/nginx, -g, daemon off;][rootserver1 docker]# docker build -t webserver:v2 .[rootserver1 docker]# docker images webserver
REPOSITORY TAG IMAGE ID CREATED SIZE
webserver v2 caf0f80f2332 4 seconds ago 317MB
webserver v1 bfd6774cc216 About an hour ago 494MB 2多阶段构建
[rootserver1 docker]# vim Dockerfile
FROM centos:7 as build
ADD nginx-1.23.3.tar.gz /mnt
WORKDIR /mnt/nginx-1.23.3
RUN yum install -y gcc make pcre-devel openssl-devel sed -i s/CFLAGS$CFLAGS -g/#CFLAGS$CFLAGS -g/g auto/cc/gcc ./configure --with-http_ssl_module --with-http_stub_status_module make make install cd .. rm -fr nginx-1.23.3 yum clean allFROM centos:7
COPY --frombuild /usr/local/nginx /usr/local/nginx
EXPOSE 80
VOLUME [/usr/local/nginx/html]
CMD [/usr/local/nginx/sbin/nginx, -g, daemon off;][rootserver1 docker]# docker build -t webserver:v3 .[rootserver1 docker]# docker images webserver
REPOSITORY TAG IMAGE ID CREATED SIZE
webserver v3 1ac964f2cefe 29 seconds ago 205MB
webserver v2 caf0f80f2332 3 minutes ago 317MB
webserver v1 bfd6774cc216 About an hour ago 494MB 3使用最精简的基础镜像
导入基础镜像
[rootserver1 ~]# docker load -i base-debian12.tar[rootserver1 ~]# mkdir new
[rootserver1 ~]# cd new/
[rootserver1 new]# vim Dockerfile
FROM nginx:latest as base# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
ARG TIME_ZONERUN mkdir -p /opt/var/cache/nginx \cp -a --parents /usr/lib/nginx /opt \cp -a --parents /usr/share/nginx /opt \cp -a --parents /var/log/nginx /opt \cp -aL --parents /var/run /opt \cp -a --parents /etc/nginx /opt \cp -a --parents /etc/passwd /opt \cp -a --parents /etc/group /opt \cp -a --parents /usr/sbin/nginx /opt \cp -a --parents /usr/sbin/nginx-debug /opt \cp -a --parents /lib/x86_64-linux-gnu/ld-* /opt \cp -a --parents /usr/lib/x86_64-linux-gnu/libpcre* /opt \cp -a --parents /lib/x86_64-linux-gnu/libz.so.* /opt \cp -a --parents /lib/x86_64-linux-gnu/libc* /opt \cp -a --parents /lib/x86_64-linux-gnu/libdl* /opt \cp -a --parents /lib/x86_64-linux-gnu/libpthread* /opt \cp -a --parents /lib/x86_64-linux-gnu/libcrypt* /opt \cp -a --parents /usr/lib/x86_64-linux-gnu/libssl.so.* /opt \cp -a --parents /usr/lib/x86_64-linux-gnu/libcrypto.so.* /opt \cp /usr/share/zoneinfo/${TIME_ZONE:-ROC} /opt/etc/localtimeFROM gcr.io/distroless/base-debian11COPY --frombase /opt /EXPOSE 80 443ENTRYPOINT [nginx, -g, daemon off;][rootserver1 new]# docker build -t webserver:v4 .[rootserver1 new]# docker images webserver
REPOSITORY TAG IMAGE ID CREATED SIZE
webserver v4 c0c4e1d49f3d 4 seconds ago 34MB
webserver v3 1ac964f2cefe 12 minutes ago 205MB
webserver v2 caf0f80f2332 15 minutes ago 317MB
webserver v1 bfd6774cc216 About an hour ago 494MB[rootserver1 new]# docker run -d --name web1 webserver:v4[rootserver1 new]# curl 172.17.0.2 ###5.Docker仓库### • Docker 仓库是用来包含镜像的位置 Docker 提供一个注册服务器 Register 来保存多个仓库每个仓库又可以包含多个具备不同 tag 的镜像。 • Docker 运行中使用的默认仓库是 Docker Hub 公共仓库。 1Docker Hub 首先注册账号 https://hub.docker.com/ 创建仓库 客户端登录docker hub
[rootserver1 ~]# docker login
Login with your Docker ID to push and pull images from Docker Hub. If you dont have a Docker ID, head over to https://hub.docker.com to create one.
Username: yakexi007 #docker hub注册的用户
Password: **** #密码
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-storeLogin Succeeded上传镜像
[rootserver1 ~]# docker tag webserver:v4 yakexi007/webserver:v4[rootserver1 ~]# docker push yakexi007/webserver:v4
The push refers to repository [docker.io/yakexi007/webserver]
bbed3d4e37e0: Pushed
0b3d0512394d: Pushed
5b1fa8e3e100: Pushed
v4: digest: sha256:013969b9116df5dc77ddaef6c500129439e9db94f46b61b148b43e53900623e5 size: 949 2配置镜像加速器 从 docker hub 上下载镜像的速度太慢需要配置镜像加速器这里以阿里云为例 [rootserver1 ~]# vim /etc/docker/daemon.json
{registry-mirrors: [https://registry.docker-cn.com] ##docker国内镜像源
}[rootserver1 ~]# systemctl restart docker[rootserver1 ~]# docker info 3registry私有仓库 docker hub虽然方便但是还是有限制 • 需要internet连接速度慢 • 所有人都可以访问 • 由于安全原因企业不允许将镜像放到外网 好消息是docker公司已经将registry开源我们可以快速构建企业私有仓库 官网https://docs.docker.com/registry/deploying/ 拉取registry镜像
[rootserver1 ~]# docker pull registry
运行registry仓库
[rootserver1 docker]# docker run -d -p 5000:5000 --restartalways --name registry registry上传镜像
[rootserver1 ~]# docker tag nginx:latest localhost:5000/nginx:latest
[rootserver1 ~]# docker push localhost:5000/nginx[rootserver1 ~]# curl localhost:5000/v2/_catalog
{repositories:[nginx]}下载镜像
[rootserver1 ~]# docker pull localhost:5000/nginx 4insecure registry配置非加密端口 本地搭建好私有仓库后要验证其他主机是否能远程下载仓库里的镜像 默认情况下用的是https不能直接下载 需要配置非加密端口强制让其他主机使用非加密的仓库 先给远程主机server2配置docker-ce服务 强制让远程主机访问非加密的私有仓库
配置使用非加密端口
[rootserver2 ~]# vim /etc/docker/daemon.json
{insecure-registries : [http://192.168.56.11:5000]
}[rootserver2 docker]# systemctl restart docker拉取镜像
[rootserver2 docker]# docker pull 192.168.56.11:5000/nginx 5仓库加密
加密部署
升级软件包
[rootserver1 ~]# yum install -y openssl11-1.1.1k-4.el7.x86_64.rpm openssl11-libs-1.1.1k-4.el7.x86_64.rpm添加域名解析
[rootserver1 ~]# vim /etc/hosts
...
192.168.56.11 server1 reg.westos.org[rootserver1 ~]# mkdir certs
[rootserver1 ~]# openssl11 req -newkey rsa:4096 -nodes -sha256 -keyout certs/westos.org.key -addext subjectAltName DNS:reg.westos.org -x509 -days 365 -out certs/westos.org.crt启动容器
[rootserver1 ~]# docker run -d --restartalways --name registry
-p 443:443 ##-p做端口映射
-v /opt/registry:/var/lib/registry
-v /root/certs:/certs ##-v把冒号前的目录挂载在容器内的冒号后的目录
-e REGISTRY_HTTP_ADDR0.0.0.0:443 ##registry的http监听443端口
-e REGISTRY_HTTP_TLS_CERTIFICATE/certs/westos.org.crt ##证书的访问位置
-e REGISTRY_HTTP_TLS_KEY/certs/westos.org.key ##key的访问位置
registry ##镜像部署客户端证书不然会报错
[rootserver1 ~]# docker tag nginx:latest reg.westos.org/nginx:latest
[rootserver1 ~]# docker push reg.westos.org/nginx:latest The push refers to repository [reg.westos.org/nginx]
Get https://reg.westos.org/v2/: x509: certificate signed by unknown authority[rootserver1 ~]# mkdir -p /etc/docker/certs.d/reg.westos.org/
[rootserver1 ~]# cp /root/certs/westos.org.crt /etc/docker/certs.d/reg.westos.org/ca.crt验证[rootserver1 ~]# docker push reg.westos.org/nginx:latest[rootserver1 reg.westos.org]# curl -k https://reg.westos.org/v2/_catalog
{repositories:[nginx]}远程主机使用测试
server2上移除非安全仓库设置
[rootserver2 docker]# mv daemon.json /mnt/
[rootserver2 docker]# systemctl restart docker添加解析
[rootserver2 ~]# vim /etc/hosts
...
192.168.56.11 server1 reg.westos.org拷贝证书
[rootserver1 ~]# cd /etc/docker/
[rootserver1 ~]# scp -r certs.d/ server2:/etc/docker/远程拉取server1仓库中镜像
[rootserver2 ~]# docker pull reg.westos.org/nginx
Using default tag: latest
latest: Pulling from nginx
Digest: sha256:c94f3436f3bfcb467e9723bdb4957e2e86c00cc5f21e38a40d668c1a4c324696
Status: Downloaded newer image for reg.westos.org/nginx:latest
reg.westos.org/nginx:latest 6 仓库认证
[rootserver1 ~]# yum install -y httpd-tools
[rootserver1 ~]# mkdir auth
[rootserver1 ~]# htpasswd -Bc auth/htpasswd admin
New password:
Re-type new password:
Adding password for user admin第二次添加不要加“-c”选项不然会覆盖
[rootserver1 ~]# htpasswd -B auth/htpasswd wxh
New password:
Re-type new password:
Adding password for user wxh[rootserver1 ~]# cat auth/htpasswd
admin:$2y$05$Wm2LHttPY5a6i2KMG0fShe92d/PjnaBbGitiClcE3wqHmwO8dIDFm
wxh:$2y$05$9rE9CXyZ1fdcMammhh7f6.soDHgKdSsi0DXBgkRW5sKRw5sEJo1lK删除registry重建
[rootserver1 ~]# docker rm -f registry
[rootserver1 ~]# docker run -d -p 443:443 --restartalways --name registry -v /opt/registry:/var/lib/registry -v /root/certs:/certs -e REGISTRY_HTTP_ADDR0.0.0.0:443 -e REGISTRY_HTTP_TLS_CERTIFICATE/certs/westos.org.crt -e REGISTRY_HTTP_TLS_KEY/certs/westos.org.key -v /root/auth:/auth -e REGISTRY_AUTHhtpasswd -e REGISTRY_AUTH_HTPASSWD_REALMRegistry Realm -e REGISTRY_AUTH_HTPASSWD_PATH/auth/htpasswd registry登录仓库不然无法上传下载
[rootserver1 ~]# docker login reg.westos.org
Username: admin
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-storeLogin Succeeded
[rootserver1 ~]# cat .docker/config.json
{auths: {reg.westos.org: {auth: YWRtaW46d2VzdG9z}}
}验证
[rootserver1 ~]# docker tag busybox:latest reg.westos.org/busybox:latest
[rootserver1 ~]# docker push reg.westos.org/busybox:latest[rootserver1 ~]# curl -k https://reg.westos.org/v2/_catalog -u admin:westos
{repositories:[busybox,nginx]}登出
[rootserver1 ~]# docker logout reg.westos.org远程主机下载镜像
首先登录仓库
[rootserver2 ~]# docker login reg.westos.org
Username: lfj
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-storeLogin Succeeded
拉取
[rootserver2 ~]# docker pull reg.westos.org/busybox
Using default tag: latest
latest: Pulling from busybox
d0f42ecf7e6c: Pull complete
Digest: sha256:28e01ab32c9dbcbaae96cf0d5b472f22e231d9e603811857b295e61197e40a9b
Status: Downloaded newer image for reg.westos.org/busybox:latest
reg.westos.org/busybox:latest 7harbor企业级私有仓库
①仓库部署
删除之前部署的registry不然会冲突
[rootserver1 ~]# docker rm -f registry[rootserver1 ~]# tar zxf harbor-offline-installer-v2.5.0.tgz
[rootserver1 ~]# cd harbor/
[rootserver1 harbor]# cp harbor.yml.tmpl harbor.yml
[rootserver1 harbor]# vim harbor.yml
hostname: reg.westos.orghttp:# port for http, default is 80. If https enabled, this port will redirect to https portport: 80https:# https port for harbor, default is 443port: 443# The path of cert and key files for nginxcertificate: /data/certs/westos.org.crtprivate_key: /data/certs/westos.org.key...
harbor_admin_password: westos拷贝证书
[rootserver1 ~ ]# mkdir /data
[rootserver1 ~ ]# cp -r certs /data部署docker-compose
[rootserver1 ~]# mv docker-compose-linux-x86_64-v2.5.0 /usr/local/bin/docker-compose
[rootserver1 ~]# chmod x /usr/local/bin/docker-compose部署harbor
[rootserver1 harbor]# ./install.sh 使用浏览器登录仓库 用户名admin 密码是上面配置文件设置的westos https://192.168.76.11 ②仓库管理
上传镜像
上传镜像首先需要执行docker login reg.westos.org,此处已经执行过[rootserver1 ~]# docker tag busybox:latest reg.westos.org/library/busybox:latest
[rootserver1 ~]# docker tag nginx:latest reg.westos.org/library/nginx:latest[rootserver1 ~]# docker push reg.westos.org/library/nginx:latest
[rootserver1 ~]# docker push reg.westos.org/library/busybox:latest拉取镜像 远程主机拉取镜像时需要先配置默认仓库 配置默认仓库
[rootserver2 ~]# vim /etc/docker/daemon.json
{registry-mirrors: [https://reg.westos.org]
}[rootserver2 ~]# systemctl restart dockerlibrary项目中的镜像下载时可以直接写镜像名称
[rootserver2 ~]# docker pull nginx 私有仓库管理
创建私有仓库 新建用户 授权新建的用户可以维护私有仓库 私有仓库上传下载都需要认证并且还要指定仓库域名 [rootserver1 ~]# docker tag ubuntu:latest reg.westos.org/westos/ubuntu:latest
[rootserver1 ~]# docker push reg.westos.org/westos/ubuntu:latest[rootserver2 ~]# docker login reg.westos.org
Username: wxh
Password: ***[rootserver2 ~]# docker pull reg.westos.org/westos/ubuntu 仓库附加说明 harbor仓库docker-compose在每次主机重启时会开机自启但经常有某个容器没能自启的情况发生使harbor产生异常因此每次重启后手动运行一下docker-compose start [rootserver1 harbor]# docker-compose down #删除harbor仓库停止所有容器并全部删除但是挂载数据不会消失
[rootserver1 harbor]# docker-compose logs #查看日志添加新模块部署harbor
[rootserver1 harbor]# ./install.sh --with-chartmuseum ###6.Docker网络### docker network子命令 • connect 连接容器到指定网络 • create 创建网络 • disconnect 断开容器与指定网络的连接 • inspect 显示指定网络的详细信息 • ls 显示所有网络 • rm 删除网络 1原生网络 docker的镜像是令人称道的地方但网络功能还是相对薄弱的部分。 docker安装后会自动创建3种网络bridge、host、none 可以使用以下命令查看 [rootserver1 harbor]# docker network ls
NETWORK ID NAME DRIVER SCOPE
fe748c728e1e bridge bridge local
ef483e4d5ab4 host host local
0a4064c6ebb6 none null local ①bridge docker安装时会创建一个名为 docker0 的Linux bridge新建的容器会自动桥接到这个接口。 bridge模式下容器没有一个公有ip只有宿主机可以直接访问外部主机是不可见的。 容器通过宿主机的NAT规则后可以访问外网。 默认使用桥接模式桥接到docker0上
[rootserver1 ~]# docker run -d --name demo nginx
[rootserver1 ~]# yum install -y bridge-utils
[rootserver1 ~]# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.0242ea04cb8d no veth6725905 ②host host 网络模式需要在容器创建时指定 --networkhost host模式可以让容器共享宿主机网络栈不会新建虚拟网卡这样的好处是外部主机与容器直接通信但是容器的网络缺少隔离性。 host模式容器和宿主机共享同一网络栈不会新建虚拟网卡
[rootserver1 ns]# docker run -it --rm --network host busybox host模式下不能同时运行两次同一个容器会发生冲突 因为共用一个网络栈端口资源也是共用的 ③none none模式是指禁用网络功能只有lo接口在容器创建时使用 --networknone指定。 none禁用网络只用回环接口
[rootserver1 harbor]# docker run -it --rm --network none busybox
/ # ip a
1: lo: LOOPBACK,UP,LOWER_UP mtu 65536 qdisc noqueue qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft forever
/ #2自定义网络 自定义网络模式docker提供了三种自定义网络驱动 • bridge • overlay • macvlan bridge驱动类似默认的bridge网络模式但增加了一些新的功能overlay和macvlan是用于创建跨主机网络。 建议使用自定义的网络来控制哪些容器可以相互通信还可以自动DNS解析容器名称到IP地址。 ①自定义网络
自定义网络
docker network create my_net1
查看
[rootserver1 ~]# docker network inspect my_net1 ②自定义网络段
自定义网络地址段
[rootk8s1 ~]# docker network create --subnet 10.0.0.0/24 --gateway 10.0.0.1 my_net2
查看
[rootserver1 ~]# docker network inspect my_net2 ③自定义网络内嵌DNS解析 使用--ip参数可以指定容器ip地址但必须是在自定义网桥上默认的 bridge模式不支持同一网桥上的容器是可以互通的。 桥接到不同网桥上的容器彼此是不通信的。 docker在设计上就是要隔离不同network的 那么如何使两个不同网桥的容器通信呢 使用 docker network connect命令为vm1添加一块my_net2 的网卡。 自定义网络内嵌dns解析同一网桥上的容器是可以互通的
[rootserver1 ~]# docker run -d --name web1 --network my_net1 nginx
[rootserver1 ~]# docker run -it --rm --network my_net1 busybox
/ # ip a
1: lo: LOOPBACK,UP,LOWER_UP mtu 65536 qdisc noqueue qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft forever
97: eth0if98: BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN mtu 1500 qdisc noqueuelink/ether 02:42:ac:14:00:03 brd ff:ff:ff:ff:ff:ffinet 172.20.0.3/16 brd 172.20.255.255 scope global eth0valid_lft forever preferred_lft forever
/ # ping web1
PING web1 (172.20.0.2): 56 data bytes
64 bytes from 172.20.0.2: seq0 ttl64 time0.076 ms
64 bytes from 172.20.0.2: seq1 ttl64 time0.064 ms
64 bytes from 172.20.0.2: seq2 ttl64 time0.062 ms不同网络之间是被隔离的,默认不能通信
[rootserver1 ~]# docker run -it --rm --network my_net2 busybox
/ # ip a
1: lo: LOOPBACK,UP,LOWER_UP mtu 65536 qdisc noqueue qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft forever
85: eth0if86: BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN mtu 1500 qdisc noqueuelink/ether 02:42:0a:00:00:02 brd ff:ff:ff:ff:ff:ffinet 10.0.0.2/24 brd 10.0.0.255 scope global eth0valid_lft forever preferred_lft forever/ # ping web1
ping: bad address web1不同网络之间的通信需要附加虚拟网卡
[rootserver1 ~]# docker run -it --rm --network my_net2 --name demo busybox
/ # ping web1
ping: bad address web1ctrlpq 快捷键退出容器终端把demo接入到my_net1网络
[rootserver1 ~]# docker network connect my_net1 demo再进入容器
[rootserver1 ~]# docker attach demo
/ # ping web1
PING web1 (172.20.0.2): 56 data bytes
64 bytes from 172.20.0.2: seq0 ttl64 time0.079 ms 3Docker容器通信
①joined容器 Joined容器一种较为特别的网络模式 在容器创建时使用--networkcontainer:vm1指定vm1指定的是运行的容器名 处于这个模式下的 Docker 容器会共享一个网络栈这样两个容器之间可以使用localhost 高效快速通信。 由于共享同一份网络栈所以joined模式不能用启动同一个容器会发生冲突 两个容器共享一个网络栈
[rootserver1 ~]# docker run -it --rm --network container:web1 --name web2 busybox
/ # ip a
1: lo: LOOPBACK,UP,LOWER_UP mtu 65536 qdisc noqueue qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft forever
19: eth0if20: BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN mtu 1500 qdisc noqueuelink/ether 02:42:ac:14:00:02 brd ff:ff:ff:ff:ff:ffinet 172.20.0.2/16 brd 172.20.255.255 scope global eth0valid_lft forever preferred_lft forever ②--link --link 可以用来链接2个容器 --link的格式 --link name or id:alias name和id是源容器的name和idalias是源容器在link下的别名。 现在不常用了解即可 [rootaserver1~l#docker run -d nginx
d61a3e7613f9417d29cc97666a80186758581e5f4b067c1de7014ef755ee9ba2
[rootaserver1~]#docker ps
CONTAINER ID IMAGE COMMAND CREATED PORTS NAMES
d61a3e7613f93 nginx nginx-gdaemon of. 3seconds ago 80/tcp hopeful golick[rootserver1 ~]# docker run -it --name ml --link hopeful golick:web ubuntu
roota137597ff4039:/#ping web
PING web(172.17.0.2)56(84)bytes of data.
64 bytes from web(172.17.0.2):icmp segl ttl64 time0.054 ms
64 bytes from web(172.17.0.2):icmp seg2 ttl64 time0.036 ms ③容器访问外网 容器如何访问外网是通过iptables的SNAT实现的 ④外部主机访问容器 外网如何访问容器 • 端口映射 • -p 选项指定映射端口 外网访问容器用到了docker-proxy和iptables DNAT双重保障 • 宿主机访问本机容器使用的是iptables DNAT • 外部主机访问容器或容器之间的访问是docker-proxy实现 外部主机访问容器可以通过DNAT规则和docker-proxy只要有一种正常就能通信
[rootserver1 ~]# docker rm -f web1
[rootserver1 ~]# docker run -d --name web1 -p 80:80 nginx
[rootserver1 ~]# iptables -t nat -nL
...
Chain POSTROUTING (policy ACCEPT) #容器访问外网通过SNAT策略
target prot opt source destination
MASQUERADE all -- 172.17.0.0/16 0.0.0.0/0
MASQUERADE all -- 172.21.0.0/16 0.0.0.0/0
MASQUERADE all -- 10.0.0.0/24 0.0.0.0/0
MASQUERADE all -- 172.20.0.0/16 0.0.0.0/0
MASQUERADE tcp -- 172.17.0.2 172.17.0.2 tcp dpt:80Chain DOCKER (2 references)
target prot opt source destination
RETURN all -- 0.0.0.0/0 0.0.0.0/0
RETURN all -- 0.0.0.0/0 0.0.0.0/0
RETURN all -- 0.0.0.0/0 0.0.0.0/0
RETURN all -- 0.0.0.0/0 0.0.0.0/0
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 to:172.17.0.2:80 #DNAT规则 DNAT规则和docker-proxy策略任何一个down掉另一个会自动起作用两个都在时外部访问优先走docker-proxy 重启容器后DNAT规则和docker-proxy策略会自动恢复 ⑤跨主机容器通信 跨主机网络解决方案 • docker原生的overlay和macvlan • 第三方的flannel、weave、calico 众多网络方案是如何与docker集成在一起的 • libnetwork docker容器网络库 • CNM Container Network Model这个模型对容器网络进行了抽象 CNM分三类组件 • Sandbox容器网络栈包含容器接口、dns、路由表。 namespace • Endpoint作用是将sandbox接入network veth pair • Network包含一组endpoint同一network的endpoint可以通信。 macvlan 网络方案实现 • Linux kernel 提供的一种网卡虚拟化技术。 • 无需 Linux bridge 直接使用物理接口性能极好。 在两台docker主机上各添加一块网卡 开启混杂模式并激活
[rootserver1 ~]# ip link set eth1 promisc on
[rootserver1 ~]# ip link set up eth1创建macvlan网络
[rootserver1 ~]# docker network create -d macvlan --subnet 10.0.0.0/24 --gateway 10.0.0.1 -o parenteth1 macvlan1用创建的网络运行容器
[rootserver1 ~]# docker run -it --rm --network macvlan1 --ip 10.0.0.11 busybox
/ # ip a
1: lo: LOOPBACK,UP,LOWER_UP mtu 65536 qdisc noqueue qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft forever
108: eth0if107: BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN mtu 1500 qdisc noqueuelink/ether 02:42:0a:00:00:0b brd ff:ff:ff:ff:ff:ffinet 10.0.0.11/24 brd 10.0.0.255 scope global eth0server2上以此类推
[rootserver2 ~]# ip link set eth1 promisc on
[rootserver2 ~]# ip link set up eth1[rootserver2 ~]# docker network create -d macvlan --subnet 10.0.0.0/24 --gateway 10.0.0.1 -o parenteth1 macvlan1[rootserver2 ~]# docker run -it --rm --network macvlan1 --ip 10.0.0.12 busybox
i/ # ip a
1: lo: LOOPBACK,UP,LOWER_UP mtu 65536 qdisc noqueue qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft forever
9: eth0if8: BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN mtu 1500 qdisc noqueuelink/ether 02:42:0a:00:00:0c brd ff:ff:ff:ff:ff:ffinet 10.0.0.12/24 brd 10.0.0.255 scope global eth0valid_lft forever preferred_lft forever
/ # ping 10.0.0.11
PING 10.0.0.11 (10.0.0.11): 56 data bytes
64 bytes from 10.0.0.11: seq0 ttl64 time1.117 ms
64 bytes from 10.0.0.11: seq1 ttl64 time1.366 ms server2以此类推 macvlan网络结构分析 • 没有新建linux bridge • 容器的接口直接与主机网卡连接无需NAT或端口映射。 macvlan会独占主机网卡但可以使用vlan子接口实现多macvlan网络 • vlan可以将物理二层网络划分为4094个逻辑网络彼此隔离vlan id取 值为1~4094。 macvlan网络间的隔离和连通 • macvlan网络在二层上是隔离的所以不同macvlan网络的容器是不能通信的。 • 可以在三层上通过网关将macvlan网络连通起来。 • docker本身不做任何限制像传统vlan网络那样管理即可。 ###7.Docke数据卷### 为什么要用数据卷 docker分层文件系统 • 性能差 • 生命周期与容器相同 docker数据卷 • mount到主机中绕开分层文件系统 • 和主机磁盘性能相同容器删除后依然保留 • 仅限本地磁盘不能随容器迁移 docker提供了两种卷 • bind mount • docker managed volume bind mount 与 docker managed volume 对比 • 相同点两者都是 host 文件系统中的某个路径。 • 不同点 1数据卷管理
①bind mount 是将主机上的目录或文件mount到容器里。 使用直观高效易于理解。 使用 -v 选项指定路径格式 host path:container path # docker run -d --name web -v /opt/website:/usr/share/nginx/html nginx bind mount 默认权限是读写rw可以在挂载时指定只读ro。 -v选项指定的路径如果不存在挂载时会自动创建。 [rootserver1 ~]# docker run -it --rm -v /tmp/data1:/data1 -v /tmp/data2:/data2:ro -v /etc/passwd:/mnt/passwd:ro busybox
/ # ls
bin data1 data2 dev etc home lib lib64 mnt proc root sys tmp usr var
/ # cd /data1/
/data1 # ls
/data1 # touch file1
/data1 # ls
file1
/data1 # cd ..
/ # cd /data2/
/data2 # ls
/data2 # touch file2
touch: file2: Read-only file system
/data2 # cd /mnt/
/mnt # ls
passwd
/mnt # cat passwd ②docker managed volume bind mount必须指定host文件系统路径限制了移植性。 docker managed volume 不需要指定mount源docker自动为容器创建数 据卷目录。 默认创建的数据卷目录都在 /var/lib/docker/volumes 中。 如果挂载时指向容器内已有的目录原有数据会被复制到volume中。 [rootserver1 ~]# docker run -d --name web1 webserver:v3
[rootserver1 ~]# docker inspect web1
[rootserver1 ~]# cd /var/lib/docker/volumes/9e6528410eb82a00f89bd1eb5cdda034bb1fbbd0eab1aa36f5ec08fc521a5fae/_data
[rootserver1 _data]# ls
50x.html index.html ##docker managed volume 会复制目标挂载点的数据查询docker managed volume
[rootserver1 volumes]# docker volume ls清理所有数据卷在清理前需要先删除容器释放对数据卷的占用
[rootserver1 volumes]# docker volume ls | grep -v DRIVER | awk {system(docker volume rm $2)} 创建数据卷
[rootserver1 ~]# docker volume create vol1
vol1
[rootserver1 ~]# docker volume ls
DRIVER VOLUME NAME
local vol1
[rootserver1 ~]# docker volume inspect vol1
[{CreatedAt: 2023-03-05T09:21:0108:00,Driver: local,Labels: null,Mountpoint: /var/lib/docker/volumes/vol1/_data,Name: vol1,Options: null,Scope: local}
]使用bind mount方式挂载数据卷,和docker managed volume结合在一起用
[rootserver1 ~]# docker run -d --name web1 -v vol1:/usr/local/nginx/html webserver:v3还能在挂载时控制权限
[rootserver1 ~]# docker rm -f web1
web1
[rootserver1 ~]# docker run -d --name web1 -v vol1:/usr/local/nginx/html:ro webserver:v3共享卷
[rootserver1 ~]# docker create -v /tmp/data1:/data1:rw -v /tmp/data2:/data2:ro -v /etc/passwd:/mnt/passwd:ro --name datavol busybox[rootserver1 ~]# docker run -it --rm --volumes-from datavol busybox2卷插件 docker 卷默认使用的是local类型的驱动只能存在宿主机跨主机的 volume就需要使用第三方的驱动可以查看以下链接: https://docs.docker.com/engine/extend/legacy_plugins/#volume - plugins docker官方只提供了卷插件的api开发者可以根据实际需求定制卷插件驱动。 https://docs.docker.com/engine/extend/plugins_volume/#volume - plugin-protocol Docker Plugin 是以Web Service的服务运行在每一台Docker Host上的通过HTTP协议传输RPC风格的JSON数据完成通信。 Plugin的启动和停止并不归Docker管理Docker Daemon依靠在缺省路径下查找UnixSocket文件自动发现可用的插件。 当客户端与Daemon交互使用插件创建数据卷时Daemon会在后端 找到插件对应的socket 文件建立连接并发起相应的API请求最终结合Daemon自身的处理完成客户端的请求。 ###8.Docker安全###
1理解Docker安全 Docker容器的安全性很大程度上依赖于Linux系统自身评估Docker 的安全性时主要考虑以下几个方面 • Linux内核的命名空间机制提供的容器隔离安全 • Linux控制组机制对容器资源的控制能力安全。 • Linux内核的能力机制所带来的操作权限安全 • Docker程序特别是服务端本身的抗攻击性。 • 其他安全增强机制对容器安全性的影响。 ①命名空间隔离的安全 • 当docker run启动一个容器时Docker将在后台为容器创建一个独立的命名空间。命名空间提供了最基础也最直接的隔离。 • 与虚拟机方式相比通过Linux namespace来实现的隔离不是那么彻底。 • 容器只是运行在宿主机上的一种特殊的进程那么多个容器之间使用的就还是同一个宿主机的操作系统内核。 • 在 Linux 内核中有很多资源和对象是不能被Namespace化的 比如时间。 ②控制组资源控制的安全 • 当docker run启动一个容器时Docker将在后台为容器创建一个独立的控制组策略集合。 • Linux Cgroups提供了很多有用的特性确保各容器可以公平地分享主机的内存、CPU、磁盘IO等资源。 • 确保当发生在容器内的资源压力不会影响到本地主机系统和其他容器它在防止拒绝服务攻击DDoS方面必不可少。 ③内核能力机制 • 能力机制Capability是Linux内核一个强大的特性可以提供细粒度的权限访问控制。 • 大部分情况下容器并不需要“真正的”root权限容器只需要少数的能力即可。 • 默认情况下Docker采用“白名单”机制禁用“必需功能”之外的其他权限。 ④Docker服务端防护 • 使用Docker容器的核心是Docker服务端确保只有可信的用户才能访问到Docker服务。 • 将容器的root用户映射到本地主机上的非root用户减轻容器和主机之间因权限提升而引起的安全问题。 • 允许Docker 服务端在非root权限下运行利用安全可靠的子进程来代理执行需要特权权限的操作。这些子进程只允许在特定范围内进行操作。 ⑤其他安全特性 • 在内核中启用GRSEC和PAX这将增加更多的编译和运行时的安全检查并且通过地址随机化机制来避免恶意探测等。启用该特性不需要Docker进行任何配置。 • 使用一些有增强安全特性的容器模板。 • 用户可以自定义更加严格的访问控制机制来定制安全策略。 • 在文件系统挂载到容器内部时可以通过配置只读模式来避免容器内的应用通过文件系统破坏外部环境特别是一些系统运行状态相关的目录。 2 容器资源控制Linux Cgroups Linux Cgroups 的全称是 Linux Control Group。 • 是限制一个进程组能够使用的资源上限包括 CPU、内存、磁盘、网络带宽等等。 • 对进程进行优先级设置、审计以及将进程挂起和恢复等操作。 Linux Cgroups 给用户暴露出来的操作接口是文件系统。 • 它以文件和目录的方式组织在操作系统的 /sys/fs/cgroup 路径下。 • 执行此命令查看mount -t cgroup • 在 /sys/fs/cgroup 下面有很多诸如 cpuset、cpu、 memory 这样的子目录也叫子系统。 • 在每个子系统下面为每个容器创建一个控制组即创建一个新目录。 • 控制组下面的资源文件里填上什么值就靠用户执行 docker run 时的 参数指定。 ①CPU资源限制 cpu_period 和 cpu_quota 这两个参数需要组合使用用来限制进 程在长度为 cpu_period 的一段时间内只能被分配到总量为 cpu_quota 的 CPU 时间以上设置表示20%的cpu时间。 [rootserver1 cpu]# docker run -it --rm --cpu-period 100000 --cpu-quota 20000 ubuntu ###--cpu-period是cpu总分片 --cpu-quota是cpu配额 这里配额占总的20%
root433a1612a171:/# dd if/dev/zero of/dev/null ②CPU优先级
[rootserver1 cpu]# docker run -it --rm ubuntu
root0280fc49f2d0:/# dd if/dev/zero of/dev/null [rootserver1 cpu]# docker run -it --rm --cpu-shares 100 ubuntu
rootb75b4d5066b8:/# dd if/dev/zero of/dev/null 测试时只保留一个cpu核心可用只有争抢cpu资源时优先级才会生效
[rootserver1 cpu1]# pwd
/sys/devices/system/cpu/cpu1
[rootserver1 cpu1]# echo 0 online ③内存资源限额 容器可用内存包括两个部分 物理内存和swap交换分区。 • --memory设置内存使用限额 • --memory-swap设置swap交换分区限额 ①用命令行控制内存限额
[rootserver1 ~]# docker run -d --name demo --memory 200M --memory-swap200M nginx②直接通过控制cgroup控制内存限额
创建一个容器目录
[rootserver1 memory]# pwd
/sys/fs/cgroup/memory
[rootserver1 memory]# mkdir x1
[rootserver1 memory]# cd x1/
设置x1控制器的内存限额为200M
[rootserver1 x1]# echo 209715200 memory.limit_in_bytes[rootserver1 x1]# yum install -y libcgroup-tools.x86_64
[rootserver1 x1]# cd /dev/shm/
[rootserver1 shm]# cgexec -g memory:x1 dd if/dev/zero ofbigfile bs1M count300
[rootserver1 shm]# free -mtotal used free shared buff/cache available
Mem: 1980 187 1080 206 712 1389
Swap: 2047 103 1944
多出的100m会写入swap[rootserver1 shm]# cd /sys/fs/cgroup/memory/x1/
设置x1控制器内存swap分区限额一共为200M
[rootserver1 x1]# echo 209715200 memory.memsw.limit_in_bytes
[rootserver1 x1]# cd -
/dev/shm
[rootserver1 shm]# cgexec -g memory:x1 dd if/dev/zero ofbigfile bs1M count300
Killed控制用户内存
[rootserver1 shm]# useradd wxh
[rootserver1 shm]# vim /etc/cgrules.conf
wxh memory x1/[rootserver1 shm]# systemctl start cgred.service
[rootserver1 shm]# su - wxh
[wxhserver1 ~]$ cd /dev/shm/
[wxhserver1 shm]$ dd if/dev/zero ofbigfile bs1M count200
Killed ④磁盘IO限制 --device-write-bps限制写设备的bps 目前的block IO限制只对direct IO有效。不使用文件缓存 [rootserver1 ~]# docker run -it --rm --device-write-bps /dev/sda:30MB ubuntu
root3226b0fc6231:/# dd if/dev/zero ofbigfile bs1M count100 oflagdirect
1000 records in
1000 records out
104857600 bytes (105 MB, 100 MiB) copied, 3.31722 s, 31.6 MB/s 3Docker安全加固
①lxcfs安全隔离 利用LXCFS增强docker容器隔离性和资源可见性 [rootserver1 ~]# yum install lxcfs-2.0.5-3.el7.centos.x86_64.rpm
[rootserver1 ~]# lxcfs /var/lib/lxcfs
[rootserver1 ~]# docker run -it -m 256m \-v /var/lib/lxcfs/proc/cpuinfo:/proc/cpuinfo:rw \-v /var/lib/lxcfs/proc/diskstats:/proc/diskstats:rw \-v /var/lib/lxcfs/proc/meminfo:/proc/meminfo:rw \-v /var/lib/lxcfs/proc/stat:/proc/stat:rw \-v /var/lib/lxcfs/proc/swaps:/proc/swaps:rw \-v /var/lib/lxcfs/proc/uptime:/proc/uptime:rw \ubuntu
root45edbc92cc1d:/# free -mtotal used free shared buff/cache available
Mem: 256 0 255 9 0 255
Swap: 256 0 256 ②容器特权 设置特权级运行的容器--privilegedtrue • 有的时候我们需要容器具备更多的权限比如操作内核模块控制swap交 换分区挂载USB磁盘修改MAC地址等。 设置容器白名单--cap-add • --privilegedtrue 的权限非常大接近于宿主机的权限为了防止用户的滥用需要增加限制只提供给容器必须的权限。此时Docker 提供了权限白名单的机制使用--cap-add添加必要的权限。 • capabilities手册地址 • http://man7.org/linux/man -pages/man7/capabilities.7.html 默认容器内的用户是受限的
[rootserver1 ~]# docker run -it --rm busybox
/ # ip a
1: lo: LOOPBACK,UP,LOWER_UP mtu 65536 qdisc noqueue qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft forever
14: eth0if15: BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN mtu 1500 qdisc noqueuelink/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ffinet 172.17.0.2/16 brd 172.17.255.255 scope global eth0valid_lft forever preferred_lft forever
/ # id
uid0(root) gid0(root) groups0(root),10(wheel)
/ # ip link set down eth0
ip: SIOCSIFFLAGS: Operation not permitted
/ # fdisk -l开启容器特权
[rootserver1 ~]# docker run -it --rm --privileged busybox
/ # fdisk -l
Disk /dev/sda: 20 GB, 21474836480 bytes, 41943040 sectors
2610 cylinders, 255 heads, 63 sectors/track
Units: sectors of 1 * 512 512 bytesDevice Boot StartCHS EndCHS StartLBA EndLBA Sectors Size Id Type
/dev/sda1 * 0,32,33 130,170,40 2048 2099199 2097152 1024M 83 Linux
/dev/sda2 130,170,41 1023,254,63 2099200 41943039 39843840 18.9G 8e Linux LVM
Disk /dev/dm-0: 17 GB, 18249416704 bytes, 35643392 sectors
2218 cylinders, 255 heads, 63 sectors/track
Units: sectors of 1 * 512 512 bytesDisk /dev/dm-0 doesnt contain a valid partition table
Disk /dev/dm-1: 2048 MB, 2147483648 bytes, 4194304 sectors
261 cylinders, 255 heads, 63 sectors/track
Units: sectors of 1 * 512 512 bytesDisk /dev/dm-1 doesnt contain a valid partition table
/ # ip link set down eth0
/ # ip link set up eth0设置容器白名单
[rootserver 1 ~]# docker run -it --rm --cap-addNET_ADMIN busybox
/ # fdisk -l
/ # ip a a 10.0.0.1/24 dev eth0
/ # ip a
1: lo: LOOPBACK,UP,LOWER_UP mtu 65536 qdisc noqueue qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft forever
18: eth0if19: BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN mtu 1500 qdisc noqueuelink/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ffinet 172.17.0.2/16 brd 172.17.255.255 scope global eth0valid_lft forever preferred_lft foreverinet 10.0.0.1/24 scope global eth0valid_lft forever preferred_lft forever
/ # ip a d 10.0.0.1/24 dev eth0
/ # ip a 安全加固的思路 1保证镜像的安全 • 使用安全的基础镜像 • 删除镜像中的setuid和setgid权限 • 启用Docker的内容信任 • 最小安装原则 • 对镜像进行安全漏洞扫描镜像安全扫描器Clair • 容器使用非root用户运行 2保证容器的安全 • 对docker宿主机进行安全加固 • 限制容器之间的网络流量 • 配置Docker守护程序的TLS身份验证 • 启用用户命名空间支持(userns-remap) • 限制容器的内存使用量 • 适当设置容器CPU优先级 docker安全的遗留问题 1主要的内核子系统都没有命名空间如 • SELinux • cgroup • 在/sys下的文件系统 • /proc/sys, /proc/sysrq-trigger, /proc/irq, /proc/bus 2设备没有命名空间 • /dev/mem • /dev/sd*文件系统设备 • 内核模块 Docker安全的顶尖开源工具 • Docker Bench for Security 对照安全基准审计Docker容器的脚本 • Clair API驱动的静态容器安全分析工具拥有庞大的CVE数据库 • Cilium 内核层可感知API的网络和安全工具 • Anchore 使用CVE数据和用户定义的策略检查容器安全的工具 • OpenSCAP W orkbench 用于为各种平台创建和维护安全策略的环境 • Dagda 用于在Docker容器中扫描漏洞、特洛伊木马、病毒和恶意软件的工具 • Notary 使用服务器加强容器安全的框架用于以加密方式委派责任 • Sysdig Falco 提供了行为活动监控可深入了解容器