一、Docker简介
1.什么是docker
Docker是管理容器的引擎,为应用打包、部署平台,而非单纯的虚拟化技术。
它具有以下几个重要特点和优势:
1. 轻量级虚拟化 :Docker 容器相较于传统的虚拟机更加轻量和高效,能够快速启动和停止,节省系统资源。 例如,启动一个 Docker 容器可能只需要几秒钟,而启动一个虚拟机则可能需要几分钟。
2. 一致性 :确保应用程序在不同的环境中(如开发、测试、生产)具有一致的运行表现。 无论在本地还是云端,应用的运行环境都能保持相同,减少了因环境差异导致的问题。
3. 可移植性 :可以轻松地将 Docker 容器从一个平台迁移到另一个平台,无需担心依赖和环境配置的差 异。 比如,在本地开发的容器可以无缝部署到云服务器上。
4. 高效的资源利用:多个 Docker 容器可以共享主机的操作系统内核,从而更有效地利用系统资 源。
5. 易于部署和扩展:能够快速部署新的应用实例,并且可以根据需求轻松地进行水平扩展。总之,Docker 极大地简化了应用程序的开发、部署和管理流程,提高了开发效率和运维的便利性。 它在现代软件开发和云计算领域得到了广泛的应用。
2.Docker与虚拟化的对比
3.Docker的优势
对于开发人员:Build once、Run anywhere
对于运维人员:Configure once、Run anything
容器技术大大提升了IT人员的幸福指数!
二、部署Docker
1.安装
解压上传的packages包
[root@docker-node ~]# tar zxf docker.tar.gz
[root@docker-node ~]# yum install --allowerasing *.rpm -y
[root@docker-node ~]# vim /usr/lib/systemd/system/docker.service
[root@docker-node ~]# systemctl enable --now docker
[root@docker-node ~]# docker info
2.镜像拉取
#搜索镜像
[root@docker-node ~]# docker search nginx
[root@docker-node ~]# docker images
#拉取本地镜像
[root@docker-node ~]# docker load -i nginx-1.23.tar.gz
#查看镜像信息
[root@docker-node ~]# docker image inspect nginx:1.23
#导出镜像
[root@docker-node ~]# docker image save nginx:latest -o nginx-latest.tar.gz
#删除镜像
[root@docker-node ~]# docker rmi nginx:latest
3.容器的常用操作
1.启动容器
[root@docker-node ~]# docker run -it --name centos7 centos:7
#进入到容器中,按+退出并停止容器
#按+退出但 不停止容器
#重新进入容器
[root@docker-node ~]# docker attach centos7
#在容器中执行命令
[root@docker-node ~]# docker exec -it busybox ifconfig
2.查看容器运行信息
#查看当前运行容器
[root@docker-node ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
#查看所有容器
[root@docker-node ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f1eb102f1a48 busybox:latest "sh" 58 minutes ago Exited (0) 16 seconds ago busybox
e4960a39f173 timinglee/mario "python3 -m http.ser…" About an hour ago Exited (0) About an hour ago mario
3.删除容器
#在容器中建立文件
[root@docker-node ~]# docker run -it --name test busybox
#删掉容器后开启新的容器文件不存在
[root@docker-node ~]# docker rm test
[root@docker-node ~]# docker run -it --name test busybox
[root@docker-node ~]# docker commit -m "add leefile" test busybox:v1
[root@docker-node ~]# docker images
[root@docker-node ~]# docker image history busybox:v1
5.系统中的文件和容器中的文件传输
[root@docker-node ~]# docker cp test:/file /mnt
[root@docker-node ~]# docker cp /etc/fstab test:/fstab
6.查询容器内部日志
[root@docker-node ~]# docker logs busybox
三、Docker镜像搭建
1.参数示例及用法
#FROM COPY 和MAINTAINER
[root@docker-node ~]# mkdir docker/
[root@docker-node ~]# cd docker/
[root@docker-node docker]# touch leefile
[root@docker-node docker]# vim Dockerfile
FROM busybox:latest
MAINTAINER qin@timingwxq.org
COPY leefile /
[root@docker-node docker]# docker build -t example:v2 . #构建镜像
#ADD
[root@docker-node docker]# touch leefile{1..3}
[root@docker-node docker]# tar zcf leefile.gz leefile*
[root@docker-node docker]# vim Dockerfile
FROM busybox:latest
MAINTAINER qin@timingwxq.org
COPY leefile /
ADD leefile /
[root@docker-node docker]# docker build -t example:v2 .
[root@docker-node docker]# docker run -it --rm --name test2 example:v2
#ENV CMD
FROM busybox:latest
MAINTAINER qin@timingwxq.org
ENV NAME qin
CMD echo $NAME
#CMD ["/bin/echo", "$NAME"]
#CMD ["/bin/sh", "-c", "/bin/echo $NAME"]
#ENTRYPOINT
FROM busybox:latest
MAINTAINER qin@timingwxq.or
ENV NAME qin
ENTRYPOINT echo $NAME
#EXPOSE VOLUME VOLUME
FROM busybox:latest
MAINTAINER qin@timingwxq.org
ENV NAME qin
EXPOSE 80 443
VOLUME /var/www/html
WORKDIR /var/www/html
RUN touch leefile
2.Dockerfile实例
建立构建目录,编写构建文件
[root@docker-node docker]# mdkir docker
[root@docker-node docker]# cd docker/
[root@docker-node docker]# cp ~/nginx-1.23.3.tar.gz .
[root@docker-node 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;"]
通过Dockerfile生成镜像
[root@docker-node docker]# docker build -t webserver:v1 .
测试镜像可用性
[root@docker-node docker]# docker images webserver
[root@docker-node docker]# docker history webserver:v1
[root@docker-node docker]# docker run -d --name checkimage webserver
四、Docker镜像仓库的管理
1.搭建registry仓库
[root@docker-node ~]# docker load -i registry.tag.gz
[root@docker-node ~]# docker run -d -p 5000:5000 --restart=always --name registry registry
#给要上传的经镜像打标签
[root@docker-node ~]# docker tag busybox:latest 172.25.254.100:5000/busybox:latest
#docker在上传的过程中默认使用https,但是我们并没有建立https认证需要的认证文件所以会报错
[root@docker-node ~]# docker push 172.25.254.100:5000/busybox:latest The push refers to repository [172.25.254.100:5000/busybox] Get "https://172.25.254.100:5000/v2/": http: server gave HTTP response to HTTPS client
#配置非加密端口
[root@docker-node ~]# vim /etc/docker/daemon.json
#上传镜像
[root@docker-node ~]# docker push 172.25.254.100:5000/busybox:latest
#查看镜像上传
2.为Registry提加密传输
#生成认证key和证书
[root@docker-node ~]# openssl req -newkey rsa:4096 \
> -nodes -sha256 -keyout certs/timingwxq.org.key \
> -addext "subjectAltName = DNS:reg.timingwxq.org" \
> -x509 -days 365 -out certs/timingwxq.org.crt
#启动registry仓库
[root@docker ~]# docker run -d -p 443:443 --restart=always --name registry \
> --name registry -v /opt/registry:/var/lib/registry \
> -v /root/certs:/certs \
> -e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
> -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/timingwxq.org.crt \
> -e REGISTRY_HTTP_TLS_KEY=/certs/timingwxq.org.key registry
#为客户端建立证书
[root@docker-node certs]# mkdir /etc/docker/certs.d/reg.timingwxq.org/ -p
[root@docker-node certs]# cp /root/certs/timingwxq.org.crt /etc/docker/certs.d/reg.timingwxq.org/ca.crt
[root@docker-node certs]# systemctl restart docker
[root@docker-node ~]# docker push reg.timingwxq.org/busybox:latest
[root@docker-node ~]# curl -k https://reg.timingwxq.org/v2/_catalog
# 测试
[root@docker-node certs]# docker push reg.timingwxq.org/busybox:latest
3.为仓库建立登陆认证
#安装建立认证文件的工具包
[root@docker-node ~]# yum install httpd-tools -y
#建立认证文件
[root@docker-node ~]# mkdir auth [root@docker-node ~]# htpasswd -Bc auth/htpasswd timingwxq
#添加认证到registry容器中
[root@docker-node ~]# docker run -d -p 443:443 --restart=always --name registry \
> --name registry -v /opt/registry:/var/lib/registry \
> -v /root/certs:/certs \
> -e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
> -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/timingwxq.org.crt \
> -e REGISTRY_HTTP_TLS_KEY=/certs/timingwxq.org.key \
> -v /root/auth:/auth \
> -e "REGISTRY_AUTH=htpasswd" \
> -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
> -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
> registry
[root@docker-node ~]# curl -k https://reg.timingwxq.org/v2/_catalog -u timingwxq:123
#登录测试
[root@docker-node ~]# docker login reg.timingwxq.org
4.部署harbor
[root@docker-node ~]# tar zxf harbor-offline-installer-v2.5.4.tgz
[root@docker-node ~]# cd harbor/
[root@docker-node harbor]# cp harbor.yml.tmpl harbor.yml [root@docker-node harbor]# vim harbor.yml
[root@docker-node harbor]# ./install.sh --with-chartmuseum
[root@docker-node harbor]# docker compose stop
[root@docker-node harbor]# docker compose up -d
#网页登陆
#上传镜像
[root@docker-node harbor]# docker login reg.timingwxq.org
[root@docker-node harbor]# docker tag busybox:latest reg.timingwxq.org/timingwxq/busybox:latest
[root@docker-node harbor]# docker push reg.timingwxq.org/timingwxq/busybox:late
#查看上传的镜像
五、Docker网络
[root@docker-node harbor]# grubby --update-kernel ALL --args iptables=true
1.自定义桥接网络
[root@docker-node ~]# docker network create my_net1
46f9816697e316c44e92c50e151778504cb73118bba92fe9cf0f1452930dcdd7
[root@docker-node ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
24a738c9fab6 bridge bridge local
e8cecbb66c24 harbor_harbor bridge local
9aefe97698cd harbor_harbor-chartmuseum bridge local
a125bf448123 host host local
46f9816697e3 my_net1 bridge local
ceab227c437b none null local
#桥接也支持自定义子网和网关
[root@docker-node ~]# docker network create my_net2 --subnet 192.168.0.0/24 --gateway 192.168.0.100 f5d2435131c5252550da345e7c273f87735092c9aa42502cf1820a3e7fd017cb [root@docker-node ~]# docker network inspect my_net2
2.为什么要自定义桥接
多容器之间可以通过ip互访,但是会出现问题
[root@docker-node ~]# docker run -d --name web1 nginx
[root@docker-node ~]# docker run -d --name web2 nginx
[root@docker-node ~]# docker inspect web1
[root@docker-node ~]# docker inspect web2
#关闭容器后重启容器,启动顺序调换,会发现容器ip颠倒
docker引擎在分配ip时时根据容器启动顺序分配到,谁先启动谁用,是动态变更的 多容器互访用ip很显然不是很靠谱,那么多容器访问一般使用容器的名字访问更加稳定。
[root@docker-node ~]# docker run -d --network my_net1 --name web nginx
[root@docker-node ~]# docker run -it --network my_net1 --name test busybox
3. joined容器网络
利用容器部署phpmyadmin管理mysql
[root@docker-node ~]# docker load -i mysql-5.7.tar.gz
[root@docker-node ~]# docker load -i phpmyadmin-latest.tar.gz
#运行phpmysqladmin
[root@docker-node ~]# docker run -d --name mysqladmin --network my_net1 -e PMA_ARBITRARY=1 -p 80:80 phpmyadmin:latest
#运行数据库
[root@docker-node ~]# docker run -d --name mysql -e MYSQL_ROOT_PASSWORD='123' --network container:mysqladmin mysql:5.7
浏览器访问172.25.254.100:80
4.外网访问docker容器
1.在两台docker主机上各添加一块网卡,打开网卡混杂模式:
[root@docker-node ~]# ip link set eth1 promisc on
[root@docker-node ~]# ip link set up eth1
[root@docker-node ~]# ifconfig eth1
2.添加macvlan网路
[root@docker-node ~]# docker network create \
> -d macvlan \
> --subnet 1.1.1.0/24 \
> --gateway 1.1.1.1 \
> -o parent=eth1 macvlan1
3.测试
#在docker-node1中
[root@docker-node ~]# docker run -it --name busybox --network macvlan1 --ip 1.1.1.100 --rm busybox
#在docker-node2中
[root@docker-node2 ~]# docker run -it --name busybox --network macvlan1 --ip 1.1.1.200 --rm busybox
六、Docker 数据卷管理及优化
为什么要用数据卷?
docker分层文件系统:性能差、生命周期与容器相同。
docker数据卷:mount到主机中,绕开分层文件系统 和主机磁盘性能相同,容器删除后依然保留;仅限本地磁盘,不能随容器迁移 。
docker提供了两种卷: bind mount、docker managed volume
1.bind mount 数据卷
是将主机上的目录或文件mount到容器里。 使用直观高效,易于理解。 使用 -v 选项指定路径,格式 。-v选项指定的路径,如果不存在,挂载时会自动创建。
示例
[root@docker-node ~]# docker run -it --rm \
> -v /tmp/data1:/data1 \
> -v /tmp/data1:/data2:ro \
> -v /etc/passwd:/data/passwd:ro busybox
/ # tail -n 3 /data/passwd
systemd-oom:x:978:978:systemd Userspace OOM Killer:/:/usr/sbin/nologin
qin:x:1000:1000:qin:/home/qin:/bin/bash
named:x:25:25:Named:/var/named:/sbin/nologin
/ # touch /data1/file1
/ # touch /data2/file1
touch: /data2/file1: Read-only file system
2.docker managed 数据卷
bind mount必须指定host文件系统路径,限制了移植性
docker managed volume 不需要指定mount源,docker自动为容器创建数据卷目录
默认创建的数据卷目录都在 /var/lib/docker/volumes 中
如果挂载时指向容器内已有的目录,原有数据会被复制到volume中
示例
[root@docker-node volumes]# docker run -d --name mysql -e MYSQL_ROOT_PASSWORD='123' mysql:5.7
[root@docker-node volumes]# ls -l /var/lib/docker/volumes
drwx-----x 3 root root 19 8月 30 11:51 fbe667bdba9a86e210d7e9e7ab26a197bfa540934911b91180f6523fcf7049d7
[root@docker-node volumes]# touch fbe667bdba9a86e210d7e9e7ab26a197bfa540934911b91180f6523fcf7049d7/_data/file
[root@docker-node volumes]# docker exec -it mysql bash
bash-4.2# cd /var/lib/mysql
bash-4.2# ls
auto.cnf client-cert.pem ib_buffer_pool ibdata1 mysql.sock public_key.pem sys
ca-key.pem client-key.pem ib_logfile0 ibtmp1 performance_schema server-cert.pem
ca.pem file ib_logfile1 mysql private_key.pem server-key.pem
bash-4.2# pwd
/var/lib/mysql
清理未使用的 Docker 数据卷
[root@docker-node ~]# docker volume prune
注意:1. 在执行 docker volume prune 命令之前,请确保你不再需要这些数据卷中的数据,该操作是不可逆的,一旦删除数据将无法恢复。 2. 如果有重要的数据存储在数据卷中,建议先进行备份,或者确保数据已经被妥善保存到其他地方。
建立数据卷
[root@docker-node ~]# docker volume create donci
[root@docker-node ~]# ls -l /var/lib/docker/volumes/donci/_data/
查看卷
[root@docker-node ~]# docker volume ls
使用建立的数据卷
[root@docker-node ~]# docker run -d --name web1 -p 80:80 -v donci:/usr/share/nginx/html nginx
[root@docker-node ~]# cd /var/lib/docker/volumes/donci/_data/
[root@docker-node _data]# ls
50x.html index.html
[root@docker-node _data]# echo liz is a pear > index.html
[root@docker-node _data]# curl 172.25.254.100
liz is a pear
3.数据卷容器
数据卷容器(Data Volume Container)是 Docker 中一种特殊的容器,主要用于方便地在多个容器之间 共享数据卷。
1.建立数据卷容器
[root@docker-node ~]# docker run -d --name datavol \
> -v /tmp/data1:/data1:rw \
> -v /tmp/data2:/data2:ro \
> -v /etc/resolv.conf:/etc/hosts busybox
2.使用数据卷容器
[root@docker-node ~]# docker run -it --name test --rm --volumes-from datavol busybox
4.bind mount 数据卷和docker managed 数据卷的对比
5.备份与迁移数据卷
1.备份数据卷
#建立容器并指定使用卷到要备份的容器
[root@docker-node ~]# docker run --volumes-from datavol \
> -v `pwd`:/backup busybox \ #把当前目录挂在到容器中用于和容器交互保存要备份的容器
> tar zcf /backup/data1.tar.gz /data1 #备份数据到本地
2.数据恢复
[root@docker-node ~]# docker run -it --name test -v donci:/data1 \
> -v `pwd`:/backup busybox /bin/sh \
> -c "tar zxf /backup/data1.tar.gz;/bin/sh"
/ # cd /data1/
/data1 # ls
七、Docker的安全优化
1.命名空间隔离的安全
#使用 cgroup-v1,重启
[root@docker-node ~]# grubby --update-kernel=/boot/vmlinuz-$(uname -r) --args="systemd.unified_cgroup_hierarchy=0 systemd.legacy_systemd_cgroup_controller"
[root@docker-node ~]# docker run -d --name web nginx [root@docker-node ~]# docker inspect web | grep Pid
[root@docker-node ~]# docker run -d --name web nginx
b9fc014e40d411ac506b5d79b5382c557c54b88ee6ae1eb78c833f56d52e9724
[root@docker-node ~]# docker inspect web | grep Pid
"Pid": 3226,
"PidMode": "",
"PidsLimit": null,
[root@docker-node ~]# cd /proc/3226/ns/
[root@docker-node ns]# ls
cgroup ipc mnt net pid pid_for_children time time_for_children user uts
[root@docker-node ns]# ls -d /sys/fs/cgroup/memory/docker/b9fc014e40d411ac506b5d79b5382c557c54b88ee6ae1eb78c833f56d52e9724
/sys/fs/cgroup/memory/docker/b9fc014e40d411ac506b5d79b5382c557c54b88ee6ae1eb78c833f56d52e9724
2.Docker的资源限制
Linux Cgroups 的全称是 Linux Control Group。
是限制一个进程组能够使用的资源上限,包括 CPU、内存、磁盘、网络带宽等等。 对进程进行优先级设置、审计,以及将进程挂起和恢复等操作。
Linux Cgroups 给用户暴露出来的操作接口是文件系统
它以文件和目录的方式组织在操作系统的 /sys/fs/cgroup 路径下。 执行此命令查看:mount -t cgroup
[root@docker-node ~]# mount -t cgroup
3.限制cpu使用
1.限制cpu的使用量
[root@docker-node ~]# docker run -it --rm --name test --cpu-period 100000 --cpu-quota 20000 ubuntu root@b0917acf5314:/# dd if=/dev/zero of=/dev/null & [1] 9 root@b0917acf5314:/# top
2.限制cpu的优先级
#开启容器并限制资源
[root@docker-node ~]# docker run -it --rm --cpu-shares 100 ubuntu root@ca664784bdf9:/# dd if=/dev/zero of=/dev/null & [1] 9 root@ca664784bdf9:/# top
#cpu有被限制
#开启另外一个容器不限制cpu的优先级
[root@docker-node ~]# docker run -it --rm --name test ubuntu root@1eee0641c72b:/# dd if=/dev/zero of=/dev/null & [1] 9 root@1eee0641c72b:/# top
#cpu未被限制
4.限制内存使用
#开启容器并限制容器使用内存大小
[root@docker-node ~]# docker run -d --name test --memory 200M --memory-swap 200M nginx
990b0222d1649801f02de8aa2fa9dfbc66f0761284ab074d79ffeb2225e04e8f
#查看容器内存使用限制
[root@docker-node ~]# cd /sys/fs/cgroup/memory/docker/990b0222d1649801f02de8aa2fa9dfbc66f0761284ab074d79ffeb2225e04e8f/
[root@docker-node 990b0222d1649801f02de8aa2fa9dfbc66f0761284ab074d79ffeb2225e04e8f]# cat memory.limit_in_bytes
209715200
#测试容器内存限制,在容器中我们测试内存限制效果不是很明显,可以利用工具模拟容器在内存中写入数据 #在系统中/dev/shm这个目录被挂在到内存中。
[root@docker-node ~]# docker run -d --name test --rm --memory 200M --memory-swap 200M nginx
a3c01dcef31f3b4c3323666f18c6278b2f8836f6a8cdb296b0a21b30cad219f7
[root@docker-node ~]# cgexec -g memory:docker/a3c01dcef31f3b4c3323666f18c6278b2f8836f6a8cdb296b0a21b30cad219f7 dd if=/dev/zero of=/dev/shm/bigfile bs=1M count=150
[root@docker-node ~]# cgexec -g memory:docker/a3c01dcef31f3b4c3323666f18c6278b2f8836f6a8cdb296b0a21b30cad219f7 dd if=/dev/zero of=/dev/shm/bigfile bs=1M count=180
可以自建控制器
[root@docker-node ~]# mkdir -p /sys/fs/cgroup/memory/x1/
[root@docker-node ~]# ls /sys/fs/cgroup/memory/x1/
#内存大小限制
[root@docker-node ~]# echo 209715200 > /sys/fs/cgroup/memory/x1/memory.limit_in_bytes
#此控制器被那个进程调用
[root@docker-node ~]# cat /sys/fs/cgroup/memory/x1/tasks
[root@docker-node ~]# cgexec -g memory:x1 dd if=/dev/zero of=/dev/shm/bigfile bs=1M count=100
记录了100+0 的读入
记录了100+0 的写出
104857600字节(105 MB,100 MiB)已复制,0.0343375 s,3.1 GB/s
[root@docker-node ~]# free -m
total used free shared buff/cache available
Mem: 1743 1228 159 169 687 515
Swap: 2047 146 1901
[root@docker-node ~]# cgexec -g memory:x1 dd if=/dev/zero of=/dev/shm/bigfile bs=1M count=300
记录了300+0 的读入
记录了300+0 的写出
314572800字节(315 MB,300 MiB)已复制,0.223419 s,1.4 GB/s
##内存溢出部分被写入swap交换分区
[root@docker-node ~]# free -m
total used free shared buff/cache available
Mem: 1743 1307 80 236 755 436
Swap: 2047 258 1789
[root@docker-node ~]# rm -fr /dev/shm/bigfile
#内存+swap控制
[root@docker-node ~]# echo 209715200 > /sys/fs/cgroup/memory/x1/memory.memsw.limit_in_bytes
[root@docker-node ~]# cgexec -g memory:x1 dd if=/dev/zero of=/dev/shm/bigfile bs=1M count=200
已杀死
[root@docker-node ~]# rm -fr /dev/shm/bigfile
[root@docker-node ~]# cgexec -g memory:x1 dd if=/dev/zero of=/dev/shm/bigfile bs=1M count=180
记录了180+0 的读入
记录了180+0 的写出
188743680字节(189 MB,180 MiB)已复制,0.052281 s,3.6 GB/s
5.限制docker的磁盘io
[root@docker-node ~]# docker run -it --rm \
> --device-write-bps \ #指定容器使用磁盘io的速率
> /dev/nvme0n1:30M \ #/dev/nvme0n1是指定系统的磁盘,30M即每秒30M数据
> ubuntu
##开启容器后会发现速度和设定不匹配,是因为系统的缓存机制
root@1a156e68d00c:/# dd if=/dev/zero of=bigfile
dd: writing to 'bigfile': No space left on device
8403833+0 records in
8403832+0 records out
4302761984 bytes (4.3 GB, 4.0 GiB) copied, 11.0747 s, 389 MB/s
root@1a156e68d00c:/# dd if=/dev/zero of=bigfile bs=1M count=100
100+0 records in
100+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 0.0446808 s, 2.3 GB/s
#设定dd命令直接写入磁盘
root@1a156e68d00c:/# dd if=/dev/zero of=bigfile bs=1M count=100 oflag=direct
100+0 records in
100+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 2.53844 s, 41.3 MB/s
root@1a156e68d00c:/#
八、Docker的安全加固
1.解决Docker的默认隔离性
LXCFS 是一个为 LXC(Linux Containers)容器提供增强文件系统功能的工具。
主要功能
-
资源可见性: LXCFS 可以使容器内的进程看到准确的 CPU、内存和磁盘 I/O 等资源使用信息。在没有 LXCFS 时,容器内看到的资源信息可能不准确,这会影响到在容器内运行的应用程序对资源的评估和 管理。
- 性能监控: 方便对容器内的资源使用情况进行监控和性能分析。通过提供准确的资源信息,管理员和开发 人员可以更好地了解容器化应用的性能瓶颈,并进行相应的优化。
安装lxcfs
[root@docker-node ~]# yum install --allowerasing lxcfs/*.rpm
运行lxcfs并解决容器隔离性
[root@docker-node ~]# 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
root@c514e0f4cdf2:/# free -m
2.容器特权
容器特权在容器中默认情况下即使我是容器的超级用户也无法修改某些系统设定,比如网络。
这是因为容器使用的很多资源都是和系统真实主机公用的,如果允许容器修改这些重要资源,系统的稳定性会变的非常差。但是由于某些需要求,容器需要控制一些默认控制不了的资源,如何解决此问题,这时我们就要设置容器特权。
[root@docker-node ~]# docker run --rm -it --privileged busybox
/ # id root
uid=0(root) gid=0(root) groups=0(root),10(wheel)
/ # ip a a 192.168.0.100/24 dev eth0
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
35: eth0@if36: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
inet 192.168.0.100/24 scope global eth0
valid_lft forever preferred_lft forever
/ # fdisk -l
Disk /dev/nvme0n1: 20 GB, 21474836480 bytes, 41943040 sectors
82241 cylinders, 255 heads, 2 sectors/track
Units: sectors of 1 * 512 = 512 bytes
Device Boot StartCHS EndCHS StartLBA EndLBA Sectors Size Id Type
/dev/nvme0n1p1 * 4,4,1 1023,254,2 2048 2099199 2097152 1024M 83 Linux
/dev/nvme0n1p2 1023,254,2 1023,254,2 2099200 41943039 39843840 18.9G 8e Linux LVM
3.容器特权的白名单
--privileged=true 的权限非常大,接近于宿主机的权限,为了防止用户的滥用,需要增加限制,只提供 给容器必须的权限。此时Docker 提供了权限白名单的机制,使用--cap-add添加必要的权限。
[root@docker-node ~]# docker run --rm -it --cap-add NET_ADMIN busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
37: eth0@if38: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
/ # ip a a 192.168.0.100/24 dev eth0 #网络可以设定
/ # fdisk -l #无法管理磁盘
九、容器编排工具Docker Compose
1.Docker Compose 的常用命令参数
设置vim参数
[root@docker-node ~]# vim ~/.vimrc
[root@docker-node ~]# mkdir test
[root@docker-node ~]# cd test/
[root@docker-node test]# vim docker-compose.yml
#启动配置文件中定义的所有服务,-d 参数在后台启动服务
[root@docker-node test]# docker compose up -d
#可以用-f来指定yml文件
[root@docker-node test]# docker compose -f docker-compose.yml up -d
#停止并删除配置文件中定义的所有服务以及相关的网络和存储卷。
[root@docker-node test]# docker compose down
[root@docker-node test]# docker compose -f test.yml down
启动已经存在的服务,但不会创建新的服务。
[root@docker-node test]# docker compose start
停止正在运行的服务
[root@docker-node test]# docker compose stop
服务状态查看
[root@docker-node test]# docker compose ps
2.构建和重新构建服务
构建配置文件中定义的服务的镜像。可以指定服务名称来只构建特定的服务。
[root@docker-node test]# cat Dockerfile
FROM busybox:latest
RUN touch /donci1
[root@docker-node test]# cat qin.Dockerfile
FROM busybox:latest
RUN touch /donci2
[root@docker-node test]# cat test.yml
services:
test1:
image: test1
build:
context: /root/test
dockerfile: qin.Dockerfile
command: ["/bin/sh","-c","sleep 3000"]
restart: always
container_name: busybox1
test2:
image: test2
build:
context: /root/test
dockerfile: Dockerfile
command: ["/bin/sh","-c","sleep 3000"]
restart: always
container_name: busybox2
#构建 services中的所有
[root@docker-node test]# docker compose -f test.yml build
#构建 services中的test1
[root@docker-node test]# docker compose -f test.yml build test1
启动服务并在启动前重新构建镜像。
#会去仓库拉去镜像
[root@docker-node test]# docker compose -f test.yml up -d
#会先构建镜像后 启动容器
[root@docker-node test]# docker compose -f test.yml up --build
#清理孤立容器
[root@docker-node test]# docker compose -f test.yml up -d --remove-orphans
3. Docker Compose 的yml文件
1.端口映射
2.存储卷
3.网络
[root@docker-node test]# vim docker-compose.yml
services:
test:
image: busybox1
command: ["/bin/sh","-c","sleep 3000"]
restart: always
network_mode: default
container_name: busybox
test1:
image: busybox2
command: ["/bin/sh","-c","sleep 3000"]
restart: always
container_name: busybox1
networks:
- mynet1
test3:
image: busybox3
command: ["/bin/sh","-c","sleep 3000"]
restart: always
container_name: busybox1
networks:
- mynet1
networks:
mynet1:
driver: bridge #使用桥接驱动,也可以使用macvlan用于跨主机连接
default:
external: true #不建立新的网络而使用外部资源
name: bridge #指定外部资源网络名字
mynet2:
ipam:
driver: default
config:
- subnet: 172.28.0.0/16
gateway: 172.28.0.254
利用容器编排完成haproxy和nginx负载均衡架构实施