一篇文章教你玩转Docker!

目录

一、基础操作

二、构建镜像

1、参数示例及使用方法

2、Docker构建实例

3、镜像优化示例

三、docker镜像仓库管理

1、docker hub

2、搭建私有仓库

(1)、搭建简单无加密私有仓库

(2)、搭建加密的私有仓库

(3)、搭建用户认证的私有仓库

3、构建企业级私有仓库-harbor

四、docker的网络

1、dacker的原生网络

(1)、bridge

(2)、host

(3)、none

2、docker的自定义网络

3、不同的自定义网络之间的通信

(1)、容器用不同的网络栈

(2)、容器用相同的网络战栈-joined网络

4、容器内外网的访问

(1)、容器访问外网

(2)、外网访问容器

5、容器的跨主机网络通信

五、docker的数据卷管理

1、bind mount数据卷

2、docker managed数据卷

​编辑

3、数据卷容器

六、docker的安全优化

1、docker的资源限制

(1)、限制cpu的使用量

(2)、限制cpu的优先级

(3)、限制内存使用

(4)、限制docker的磁盘io

七、docker的安全加固

1、docker默认隔离性

2、解决默认隔离性问题

4、容器特权

5、容器白名单

八、容器编排工具Docker Compose

1、基础操作

2、构建和重新构建服务

3、其他操作

4、Docker Compose 的yml文件

(1)、服务

(2)、网络

(3)、存储卷

九、利用docker编排完成haproxy和nginx负载均衡架构

1、只下载haproxy,找出haproxy的配置文件,编辑配置文件

2、编辑docker compose容器编排文件

3、启动容器

4、查看是否启动

5、写入网页内容

6、测试


准备工作:

搭建本地网络源:

cd /etc/yum.repos.d/
vim docker-ce.repo

一、基础操作

#拉取镜像
[root@decker-node1 ~]# docker pull nginx:1.26-alpine

#查看本地镜像
[root@decker-node1 ~]# docker images
REPOSITORY           TAG       IMAGE ID       CREATED         SIZE
nginx                latest    5ef79149e0ec   12 days ago     188MB
busybox              latest    65ad0d468eb1   15 months ago   4.26MB
timinglee/game2048   latest    19299002fdbe   7 years ago     55.5MB
timinglee/mario      latest    9a35a9e43e8c   8 years ago     198MB

#查看镜像(nginx)
[root@decker-node1 ~]# docker image inspect nginx

#保存镜像
[root@decker-node1 ~]# docker image save nginx:latest -o nginx-latest.tar.gz

[root@Docker-node1 ~]# docker ps #查看当前运行容器
[root@Docker-node1 ~]# docker ps -a #查看所有容器
[root@Docker-node1 ~]# docker inspect busybox #查看容器运行的详细信息
[root@Docker-node1 ~]# docker stop busybox #停止容器
[root@Docker-node1 ~]# docker kill busybox #杀死容器,可以使用信号
[root@Docker-node1 ~]# docker start busybox #开启停止的容器
[root@docker-node1 ~]# docker load -i game2048.tar.gz 
[root@docker-node1 ~]# docker load -i mario.tar.gz 
[root@docker-node1 ~]# docker images
REPOSITORY           TAG       IMAGE ID       CREATED       SIZE
timinglee/game2048   latest    19299002fdbe   7 years ago   55.5MB
timinglee/mario      latest    9a35a9e43e8c   8 years ago   198MB

[root@docker-node1 ~]# docker run -d --rm --name game1 -p 80:8080 timinglee/mario

[root@docker-node1 ~]# docker ps
CONTAINER ID   IMAGE             COMMAND                   CREATED         STATUS         PORTS                                   NAMES
475d1ada9324   timinglee/mario   "python3 -m http.ser…"   2 minutes ago   Up 2 minutes   0.0.0.0:80->8080/tcp, :::80->8080/tcp   game1 

[root@docker-node1 ~]# docker rm -f game1 
game1
[root@docker-node1 ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS 

二、构建镜像

1、参数示例及使用方法

FROM
指定 base 镜像 eg FROM busybox:version
COPY
复制文件 eg COPY file /file 或者 COPY [“file”,”/”]
MAINTAINER 指定作者信息,比如邮箱 eg MAINTAINER user@example.com
在最新版的 docker 中用 LABEL KEY="VALUE" 代替
ADD
功能和 copy 相似,指定压缩文件或 url eg: ADD test.tar /mnt 或者 eg ADD
http://ip/test.tar /mnt
ENV
指定环境变量 eg ENV FILENAME test
EXPOSE
暴漏容器端口 eg EXPOSE 80
VOLUME
申明数据卷,通常指数据挂载点 eg VOLUME [“/var/www/html”]
WORKDIR
切换路径 eg WORKDIR /mnt
RUN
在容器中运行的指令 eg: touch file
CMD
在启动容器时自动运行动作可以被覆盖 eg CMD echo $FILENAME 会调用
shell 解析 eg CMD [“/bin/sh”,”-c”,“echo $FILENAME”] 不调用 shell 解析
ENTRYPOINT
CMD 功能和用法类似,但动作不可被覆盖
[root@decker-node1 ~]# cd docker/
[root@decker-node1 docker]# touch dockerfile
[root@decker-node1 docker]# vim dockerfile 

volume:
docker inspect test #查看挂载点、宿主机的目录

2、Docker构建实例

删除没有挂在成功的镜像:

[root@decker-node1 docker]# docker rmi `docker images | awk '/none/{print $2}'`
[root@decker-node1 docker]# docker rmi 04f578596280 931faa592f44

加载centos7镜像:

[root@decker-node1 docker]# docker load -i centos-7.tar.gz

编写构建文件:

开始构建: 

root@decker-node1 docker]# docker build -t nginx:v1 .

构建时出现报错:yum时候出现问题->原因是centos镜像的问题

dnf install httpd -y
#配置文件的端口改为8888
systemctl restart httpd

新加cdroom:

挂载本地软件仓库sr1: 

开启centos7容器:

[root@decker-node1 ~]# docker run -it --name centos centos:7

配置该容器的本地软件仓库: 

将配置好的容器提交镜像(centos的repo版本)

[root@decker-node1 ~]# docker commit -m "add repo" centos centos:repo

 修改构建文件:

继续构建nginx镜像:

[root@decker-node1 docker]# docker build -t busybox:v1 .

可以看到nginx:vi版本有356MB,可以进行优化减少大小。

3、镜像优化示例

缩减镜像层:

[root@decker-node1 docker]# vim dockerfile 

可以看出nginx:v1版本变小了(292MB):

 多阶段构建:

可以看出nginx:v2版本变小(210MB): 

使用最精简镜像

加载nginx1.23镜像和最小精简镜像:

[root@decker-node1 docker]# docker load -i nginx-1.23.tar.gz
[root@decker-node1 docker]# docker load -i debian11.tar.gz

编辑构建文件:

可以看到nginx:v3版本只有34.5MB: 

三、docker镜像仓库管理

1、docker hub

2、搭建私有仓库

(1)、搭建简单无加密私有仓库

下载镜像:

[root@decker-node1 ~]# docker load -i registry.tag.gz 

开启容器: 

[root@decker-node1 ~]# docker run -d -p 5000:5000 --restart=always registry

给要上传的镜像添加标签:

[root@decker-node1 ~]# docker tag nginx:v2 172.25.254.100:5000/nginx:v2

配置非加密端口: 

daemon.json是 Docker 的配置文件,通常位于/etc/docker/目录下(不同系统可能有所不同)。
以下是一个示例的daemon.json文件内容及解释:
json
复制
{
  "registry-mirrors": ["https://your-custom-mirror.com"],
  "insecure-registries": ["your-insecure-registry:port"],
  "max-concurrent-downloads": 10,
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}
解释:
"registry-mirrors": 指定 Docker 镜像加速地址,可以提高拉取镜像的速度。
"insecure-registries": 指定不安全的私有镜像仓库地址,如果你的私有仓库没有使用 HTTPS,需要将其添加到这个列表中。
"max-concurrent-downloads": 设置同时下载的最大层数,可根据系统资源和网络情况调整。
"log-driver": 设置日志驱动,这里设置为json-file表示以 JSON 格式的文件记录日志。
"log-opts": 日志相关的选项,这里设置了单个日志文件最大为10m,最多保留3个日志文件。
你可以根据自己的需求对daemon.json进行配置。修改后,通常需要重启 Docker 服务使配置生效。

[root@decker-node1 ~]# vim /etc/docker/daemon.json
[root@decker-node1 ~]# systemctl restart docker

上传:

[root@decker-node1 ~]# docker push 172.25.254.100:5000/nginx:v2

查看镜像上传:

[root@decker-node1 docker]# curl 172.25.254.100:5000/v2/_catalog

(2)、搭建加密的私有仓库

生成认证证书和key

#删除配置文件的非加密配置
[root@decker-node1 ~]# vim /etc/docker/daemon.json 
[root@decker-node1 ~]# systemctl restart docker
mk[root@decker-node1 ~]# mkdir certs

#添加解析
[root@decker-node1 ~]# vim /etc/hosts
172.25.254.100  decker-node1 reg.gaoyingjie.org
#生成key和证书
[root@decker-node1 ~]# openssl req -newkey rsa:4096 \
> -nodes -sha256 -keyout certs/gaoyingjie.org.key \
> -addext "subjectAltName = DNS:reg.gaoyingjie.org" \
> -x509 -days 365 -out certs/gaoyingjie.org.crt

让docker读取证书:

[root@decker-node1 ~]# mkdir /etc/docker/certs.d/reg.gaoyingjie.org/ -p
[root@decker-node1 ~]# cp /root/certs/gaoyingjie.org.crt /etc/docker/certs.d/reg.gaoyingjie.org/ca.crt
[root@decker-node1 ~]# systemctl restart docker

 开启registry容器:

[root@decker-node1 ~]# 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/gaoyingjie.org.crt \
> -e REGISTRY_HTTP_TLS_KEY=/certs/gaoyingjie.org.key registry:latest

#-v: 挂载目录,容器下有该目录

添加tag标签:

[root@decker-node1 docker]# docker tag busybox:latest reg.gaoyingjie.org/busybox:latest

上传:

[root@decker-node1 docker]# docker push reg.gaoyingjie.org/busybox:latest

 查看上传的镜像:

[root@decker-node1 docker]# curl -k https://reg.gaoyingjie.org/v2/_catalog

(3)、搭建用户认证的私有仓库

解释:需要用户输入密码才能的上传到搭建的私有仓库。

创建认证文件(使用md5加密):

[root@decker-node1 ~]# mkdir auth
[root@decker-node1 ~]# htpasswd -Bc auth/htpasswd gaoyingjie    #-B:最强加密方式
New password: 
Re-type new password: 
Adding password for user gaoyingjie
开启容器, 添加认证到registry容器中:
[root@decker-node1 ~]# 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/gaoyingjie.org.crt -e REGISTRY_HTTP_TLS_KEY=/certs/gaoyingjie.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@decker-node1 ~]# docker login reg.gaoyingjie.org
Authenticating with existing credentials...
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/#credential-stores

Login Succeeded

上传镜像:

[root@decker-node1 ~]# docker push reg.gaoyingjie.org/busybox:latest 

 查看上传的镜像:

curl -k https://172.25.254.100/v2/ catalog -ugaoyingjie:gaoyingjie

若未登录私有仓库:则显示上传失败。

3、构建企业级私有仓库-harbor

在第2步的基础上部署harbor

[root@docker ~]# tar zxf harbor-offline-installer-v2.5.4.tgz
[root@docker ~]# ls
anaconda-ks.cfg certs harbor-offline-installer-v2.5.4.tgz
auth harbor
[root@docker ~]# cd harbor/
[root@docker harbor]# cp harbor.yml.tmpl harbor.yml
[root@docker harbor]# vim harbor.yml

生成证书和key:

[root@docker-harbor harbor]# openssl req -newkey rsa:4096 -nodes -sha256 -keyout certs/gaoyingjie.org.key -addext "subjectAltName = DNS:reg.gaoyingjie.org" -x509 -days 365 -out certs/gaoyingjie.org.crt

 将证书和key放入配置文件里指定目录:

[root@decker-node1 harbor]# mkdir /data
[root@decker-node1 harbor]# cp -r /root/certs/ /data/
[root@decker-node1 harbor]# ls /data/
certs

#让docker读取证书
[root@docker-harbor certs]# cp /root/certs/gaoyingjie.org.crt /etc/docker/certs.d/reg.gaoyingjie.org/ca.crt

 安装harbor:

[root@decker-node1 harbor]# ./install.sh  --with-chartmuseum 

启动harbor:

[root@decker-node1 harbor]# docker compose stop
[root@decker-node1 harbor]# docker compose up -d

本地解析:

登录harbor:浏览器输入reg.gaoyingjie.org(仓库名,也就是hostname)

 

新建项目:

上传镜像到仓库新建项目newtest:

#登录harbor私有仓库
#先将之前的退出,如果没登陆过则不用
[root@decker-node1 harbor]# docker logout reg.gaoyingjie.org
Removing login credentials for reg.gaoyingjie.org
#登录
[root@decker-node1 harbor]# docker login reg.gaoyingjie.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/#credential-stores

Login Succeeded

添加标签:

[root@decker-node1 harbor]# docker tag nginx:v3 reg.gaoyingjie.org/newtest/nginx:v3

上传镜像:

[root@decker-node1 harbor]# docker push reg.gaoyingjie.org/newtest/nginx:v3

可以看到已上传nginx 

小tip:

#一键加载镜像
#所有的镜像文件在/root/images下
[root@docker-harbor images]# for i in `ls /root/images`; do docker load -i $i; done

#一键清除所有容器(慎重)
[root@docker-harbor harbor]# docker container prune -f
#一键添加标签
[root@docker-harbor ~]# docker images | awk 'NR>1{system("docker tag "$1":"$2" reg.gaoyingjie.org/library/"$1":"$2)}'

#一键push
[root@docker-harbor ~]# docker images | awk '/reg.gaoyingjie.org/{system("docker push "$1":"$2)}'

#一键删除某些镜像
[root@k8s-master ~]# docker images | awk '/reg.timinglee.org/{system("docker rmi "$1":"$2)}'

四、docker的网络

修改防火墙策略

[root@decker-node1 ~]# grubby --update-kernel ALL --args iptables=true
[root@decker-node1 ~]# reboot

1、dacker的原生网络

(1)、bridge

(2)、host

(3)、none

2、docker的自定义网络

自定义桥接:原生的桥接模式是没有dns模块,所以要用自定义桥接,可以用容器名称通信。

容器的开启顺序不同会导致ip不同,会导致容器之间通讯出现问题。


[root@docker-node1 ~]# docker network create mynet1 -d bridge 
7e2fe742ddd7221d316d60276be1078e28f09ae1b2b6ca1ec79f8df5ca31ceda
[root@docker-node1 ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
ad53e07c3e80   bridge    bridge    local
12e886188af6   host      host      local
7e2fe742ddd7   mynet1    bridge    local
cf8dda13f1cb   none      null      local

[root@docker-node1 ~]# docker run -it  --name test1 --network mynet1 busybox
[root@docker-node1 ~]# docker run -it  --name test2 --network mynet1 busybox

#删除网络
[root@docker-node1 ~]# docker network rm mynet1 
mynet1
[root@docker-node1 ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
ad53e07c3e80   bridge    bridge    local
12e886188af6   host      host      local
cf8dda13f1cb   none      null      local

可以看出,两个容器test1和test2处于同一网络,之间可以用ip通信,也可以用容器名通信。而传统的桥接模式是不能用容器名称通信的。

3、不同的自定义网络之间的通信

有两种情况:用相同网络栈和不同网络栈

(1)、容器用不同的网络栈

#创建两个自定义桥接网络
[root@docker-node1 ~]# docker network create mynet1 -d bridge 
2a79172a5fe1a4b433c3daf4bdefaabf89b0a656aa5e7a07c007ae6a05a7b078
[root@docker-node1 ~]# docker network create mynet2 -d bridge 
a79928a1c7ec8d4037863138b02a5fb967254ee3a560388572b0b16fd6ae0745

可以看到不同自定义网络是是不能通信的。

将一个容器加入网卡接入另一个网络中:

#将test2接入mynet1网络中
#所以test2容器有172.28.0.2(mynet1)和172.19.0.2(mynet2)两个ip 
[root@docker-node1 ~]# docker network connect mynet1 test2

(2)、容器用相同的网络战栈-joined网络

示例1:

[root@docker-node1 ~]# docker run -d --name test1 --network mynet1 nginx
8d1ad6dd316d38816f509a8db9ab1c057d766e8c92b437b98b4c72578eb4700c

#用mynet2的网络栈
[root@docker-node1 ~]# docker run -d --name test2 --network container:test1 centos:7 
7ae5ac441717042123b0ddf964a1918725dfc2070709200772d46a900c79b343

镜像centos是没有web服务的,但是test1和test2用了同个网络栈,所以test2有wab服务: 

示例2:

phpmyadmin和mysql两个容器共用一个网络栈,phpmyadmin通过回环接口就能管理mysql,更安全。

[root@docker-node1 ~]# docker load -i mysql-5.7.tar.gz 

[root@docker-node1 ~]# docker load -i phpmyadmin-latest.tar.gz 

[root@docker-node1 ~]#  docker network create mynet1 -d bridge 

#开启phpmyadmin容器
[root@docker-node1 ~]# docker run -d --name mysqladmin --network mynet1 \
> -e PMA_ARBITRARY=1 \
> -p 80:80 phpmyadmin:latest

#开启mysql容器
[root@docker-node1 ~]# docker run -d --name mysql \
> -e MYSQL_ROOT_PASSWORD='gyj' \
> --network container:mysqladmin \
> mysql:5.7

登录:浏览器输入172.25.254.100

在mysql容器内执行命令:

[root@docker-node1 ~]# docker exec -it mysql bash
bash-4.2# 

也可以用phpmyadmin管理数据库。

4、容器内外网的访问

(1)、容器访问外网

(2)、外网访问容器

5、容器的跨主机网络通信

macvlan

在两台 docker 主机上各添加一块网卡,打开网卡混杂模式:
[root@docker-node1 ~]# ip link set eth1 promisc on
[root@docker-node1 ~]# ip link set up eth1

两主机添加macvlan网络:

[root@docker-node2 ~]# docker network create -d macvlan --subnet 1.1.1.0/24 --gateway 1.1.1.1 -o parent=eth1 macvlan1

开启容器:

[root@docker-node1 ~]# docker run -it --name test1 --network macvlan1 --ip 1.1.1.100 --rm busybox
[root@docker-node2 ~]# docker run -it --name test2 --network macvlan1 --ip 1.1.1.200 --rm busybox

 测试:开处于不同主机的两个容器是否可以通信

五、docker的数据卷管理

1、bind mount数据卷

  • 是将主机上的目录或文件mount到容器里。
  • 使用直观高效,易于理解。
  • 使用 -v 选项指定路径。
[root@docker-node1 ~]# docker run -it --rm -v /test1:/data1:rw -v /etc/passwd:/data2/passwd:ro busybox

2、docker managed数据卷

  • bind mount必须指定host文件系统路径,限制了移植性
  • docker managed volume 不需要指定mount源,docker自动为容器创建数据卷目录
  • 默认创建的数据卷目录都在 /var/lib/docker/volumes
  • 如果挂载时指向容器内已有的目录,原有数据会被复制到volume
[root@docker-node1 ~]# docker run -d --name mysql -e MYSQL_ROOT_PASSWORD='gyj' mysql:5.7

[root@docker-node1 ~]#cd /var/lib/docker/volumes/09c6f145e4449d1cbdfd5118fdd869adb32573a4195c18dc22a6ac93f3c7596b/_data/
[root@docker-node1 _data]# touch newfile

#进入容器查看是否有newfile
[root@docker-node1 ~]# docker exec -it mysql bash
bash-4.2# cd /var/lib/mysql
bash-4.2# ls

可以看到没有指定数据卷目录,默认在挂载到host的/var/lib/docker/volume/容器id/_data中,在此目录下新建文件,可以在容器内部的/var/lib/容器名/中看到新文件。

3、数据卷容器

数据卷容器( Data Volume Container )是 Docker 中一种特殊的容器,主要用于方便地在多个容器之间 共享数据卷。
#建立数据卷容器
[root@docker ~]# docker run -d --name datavol \
-v /tmp/data1:/data1:rw \
-v /tmp/data2:/data2:ro \
-v /etc/resolv.conf:/etc/hosts busybox

#使用数据卷容器
[root@docker ~]# docker run -it --name test --rm --volumes-from datavol busybox

六、docker的安全优化

[root@docker-node1 ~]# docker run -d --name web nginx
516df6628241e9b4f3e802cbef696163ce681070d739b8ae716efe74708466c7
[root@docker-node1 ~]# docker inspect web | grep Pid
            "Pid": 1898,
            "PidMode": "",
            "PidsLimit": null,
[root@docker-node1 ~]# cd /proc/
[root@docker-node1 proc]# cd 1898
[root@docker-node1 1898]# cd ns
[root@docker-node1 ns]# ls
cgroup  ipc  mnt  net  pid  pid_for_children  time  time_for_children  user  uts

[root@docker-node1 ns]# cd /sys/fs/cgroup/
[root@docker-node1 cgroup]# ls
blkio    cpu,cpuacct  freezer  misc              net_prio    rdma
cpu      cpuset       hugetlb  net_cls           perf_event  systemd
cpuacct  devices      memory   net_cls,net_prio  pids
[root@docker-node1 cgroup]# cd memory/
[root@docker-node1 memory]# cd docker/
[root@docker-node1 docker]# ls
516df6628241e9b4f3e802cbef696163ce681070d739b8ae716efe74708466c7
cgroup.clone_children
cgroup.event_control
***

[root@docker-node1 docker]# cd 516df6628241e9b4f3e802cbef696163ce681070d739b8ae716efe74708466c7/
[root@docker-node1 516df6628241e9b4f3e802cbef696163ce681070d739b8ae716efe74708466c7]# ls
cgroup.clone_children               memory.memsw.failcnt
cgroup.event_control                memory.memsw.limit_in_bytes
cgroup.procs                        memory.memsw.max_usage_in_bytes
memory.failcnt                      memory.memsw.usage_in_bytes
memory.force_empty                  memory.move_charge_at_immigrate
memory.kmem.failcnt                 memory.numa_stat
memory.kmem.limit_in_bytes          memory.oom_control
memory.kmem.max_usage_in_bytes      memory.pressure_level
memory.kmem.slabinfo                memory.soft_limit_in_bytes
memory.kmem.tcp.failcnt             memory.stat
memory.kmem.tcp.limit_in_bytes      memory.swappiness
memory.kmem.tcp.max_usage_in_bytes  memory.usage_in_bytes
memory.kmem.tcp.usage_in_bytes      memory.use_hierarchy
memory.kmem.usage_in_bytes          notify_on_release
memory.limit_in_bytes               tasks
memory.max_usage_in_bytes

1、docker的资源限制

(1)、限制cpu的使用量

[root@docker-node1 ~]# docker run -it --rm --name test1 --cpu-period 100000 --cpu-quota 20000 ubuntu
root@3c63c90f85ef:/# dd if=/dev/zero of=/dev/null &
[1] 9
root@3c63c90f85ef:/# top

[root@docker-node1 ~]# docker run -it --rm --name test2 --cpu-period 100000 --cpu-quota 30000 ubuntu
root@9ba159f17589:/# dd if=/dev/zero of=/dev/null &
[1] 9
root@9ba159f17589:/# top

(2)、限制cpu的优先级

[root@docker-node1 ~]# docker run -it --rm --name test1 --cpu-shares 100  ubuntu
root@0d33e9d6b5a3:/# dd if=/dev/zero of=/dev/null &
[1] 8
root@0d33e9d6b5a3:/# top

[root@docker-node1 ~]# docker run -it --rm --name test2  ubuntu
dd if=/dev/zero of=/dev/null &root@c30ea1c45318:/# dd if=/dev/zero of=/dev/null &
[1] 9
root@c30ea1c45318:/# top

(3)、限制内存使用

上传工具:

libcgroup-0.41-19.el8.x86_64.rpm
libcgroup-tools-0.41-19.el8.x86_64.rpm

[root@docker-node1 ~]# dnf install *.rpm -y

开启容器并限制内存: 

[root@docker-node1 ~]# docker run -d --rm --name test1 --memory 200M --memory-swap 200M nginx
9dec367f92ee6874fb5a6e543d369b1f0aa81f2ae8dff875ae30e1f710a04616
[root@docker-node1 ~]# cd /sys/fs/cgroup/
[root@docker-node1 cgroup]# cgexec -g memory:docker/9dec367f92ee6874fb5a6e543d369b1f0aa81f2ae8dff875ae30e1f710a04616 dd if=/dev/zero of=/dev/shm/bigfile bs=1M count=150

查看该容器id下的内存资源限制文件,可以看到200m的字节为 209715200,也可通过echo写入文件将内存限制从200mb改为300mb:

[root@docker-node1 ~]#cd /sys/fs/cgroup/memory/docker/9dec367f92ee6874fb5a6e543d369b1f0aa81f2ae8dff875ae30e1f710a04616/
[root@docker-node1 9dec367f92ee6874fb5a6e543d369b1f0aa81f2ae8dff875ae30e1f710a04616]# 
cat memory.memsw.limit_in_bytes
209715200

[root@docker-node1 9dec367f92ee6874fb5a6e543d369b1f0aa81f2ae8dff875ae30e1f710a04616]# echo 314572800 > memory.memsw.limit_in_bytes
[root@docker-node1 9dec367f92ee6874fb5a6e543d369b1f0aa81f2ae8dff875ae30e1f710a04616]# cgexec -g memory:docker/9dec367f92ee6874fb5a6e543d369b1f0aa81f2ae8dff875ae30e1f710a04616 dd if=/dev/zero of=/dev/shm/bigfile bs=1M count=300

(4)、限制docker的磁盘io

[root@docker-node1 ~]# docker run -it --rm --device-write-bps /dev/nvme0n1:30M ubuntu
root@452768b7f1e0:/# dd if=/dev/zero of=bigfile
root@452768b7f1e0:/#  dd if=/dev/zero of=bigfile bs=1M count=100
root@452768b7f1e0:/# dd if=/dev/zero of=bigfile bs=1M count=100 oflag=direct

七、docker的安全加固

1、docker默认隔离性

可以看到虽然限制了容器200m的内存,但是内存资源并没有完全隔离。

2、解决默认隔离性问题

LXCFS 是一个为 LXC Linux Containers )容器提供增强文件系统功能的工具。
LXCFS 可以使容器内的进程看到准确的 CPU 、内存和磁盘 I/O 等资源使用信息。在没有 LXCFS 时,容器内看到的资源信息可能不准确,这会影响到在容器内运行的应用程序对资源的评估和管理。

安装lxcfs

[root@docker-node1 ~]# cd /mnt/
[root@docker-node1 mnt]# ls
hgfs                          lxc-libs-4.0.12-1.el9.x86_64.rpm
lxcfs-5.0.4-1.el9.x86_64.rpm  lxc-templates-4.0.12-1.el9.x86_64.rpm
[root@docker-node1 mnt]# dnf install *.rpm

运行lxcfs解决隔离性问题:

[root@docker-node1 ~]# lxcfs /var/lib/lxcfs &

开启容器并指定内存:

docker run  -it --name test -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

可以看到指定的内存为256m,容器显示的内存就为256m。

4、容器特权

5、容器白名单

八、容器编排工具Docker Compose

编辑vim配置文件:

vim ~/.vimrc

1、基础操作

[root@docker-node1 ~]# mkdir test
[root@docker-node1 test]# cd test/
#编辑yml文件
[root@docker-node1 test]# vim docker-compose.yml
#启动服务
[root@docker-node1 test]# docker compose up -d
[+] Running 3/3
 ✔ Network test_default   Created                                    0.2s 
 ✔ Container test-web-1   Started                                    1.6s 
 ✔ Container test-test-1  Started                                    1.5s 
[root@docker-node1 test]# docker ps
CONTAINER ID   IMAGE          COMMAND                   CREATED          STATUS         PORTS     NAMES
1b571c4c09aa   nginx:latest   "/docker-entrypoint.…"   10 seconds ago   Up 9 seconds   80/tcp    test-web-1

[root@docker-node1 test]# cp docker-compose.yml new-compose.yml
[root@docker-node1 test]# rm -rf docker-compose.yml 
[root@docker-node1 test]# vim new-compose.yml 

#可以使用-f 来指定yml文件
[root@docker-node1 test]# docker compose -f new-compose.yml up -d
[+] Running 2/2
 ✔ Container test-test-1  Started                                    1.1s 
 ✔ Container test-web-1   Started 
#停止正在运行的服务
[root@docker-node1 test]# docker compose stop
[+] Stopping 2/2
 ✔ Container test-web-1   Stopped                                    0.1s 
 ✔ Container test-test-1  Stopped                                    0.0s 
#重启服务
[root@docker test]# docker compose restart
#停止并删除配置文件中定义的所有服务以及相关的网络和存储卷。
[root@docker test]# docker compose down
#查看状态
[root@docker-node1 test]# docker compose ps
NAME         IMAGE          COMMAND                   SERVICE   CREATED              STATUS          PORTS
test-web-1   nginx:latest   "/docker-entrypoint.…"   web       About a minute ago   Up 11 seconds   80/tcp

2、构建和重新构建服务

编辑构建docker的文件:

[root@docker-node1 test]# vim Dockerfile
[root@docker-node1 test]# vim new.Dockerfile

写重新构建的文件:在之前test1、test2的基础上重新构建 

[root@docker-node1 test]# vim docker-compose.yml 

构建生效: 

#build
[root@docker-node1 test]# docker compose -f docker-compose.yml  build#构建
services中所有
[root@docker test]# docker compose -f test.yml build test1 #构建
services中的test1

可以看到构建的新镜像:test1、test2 

开启容器:可以看到旧的test1、test2构建时创建的文件

以上是构建好镜像后手动开启容器。 

自动开启容器:

# --build
[root@docker test]# docker compose -f docker-compose.yml up -d #会去仓库拉去镜
像

[root@docker test]# docker compose -f docker-compose.yml up --build #会先构建镜像后
启动容器

可以看到自动开启容器: 

3、其他操作

  • docker-compose exec
[root@docker-node1 test]# vim docker-compose.yml 
[root@docker-node1 test]# vim docker-compose.yml 
[root@docker-node1 test]# docker compose -f docker-compose.yml up -d
#在正在运行的服务容器中执行命令
[root@docker-node1 test]# docker compose -f docker-compose.yml  exec test1 sh
/ # touch newfile
/ # ls
bin      etc      lib      newfile  root     tmp      var
dev      home     lib64    proc     sys      usr
/ #

  • docker-compose pull
拉取配置文件中定义的服务所使用的镜像。
[root@docker test]# docker compose -f docker-compose.yml pull
[+] Pulling 2/2
✔ test Pulled
✔ ec562eabd705 Pull complete
  • docker-compose config
验证并查看解析后的 Compose 文件内容
[root@docker-node1 test]# docker compose config 
name: test
services:
  test1:
    command:
      - /bin/sh
      - -c
      - sleep 3000
    container_name: busybox1
    image: busybox:latest
    networks:
      default: null
    restart: always
networks:
  default:
    name: test_default

4、Docker Compose yml文件

(1)、服务

#服务名称(service1_name/service2_name 等):每个服务在配置文件中都有一个唯一的名称,用于在命令行和其他部分引用该服务。

services:
web:
# 服务1的配置
mysql:
# 服务2的配置
#镜像(image):
#指定服务所使用的 Docker 镜像名称和标签。例如, image: nginx:latest 表示使用 nginx镜像的最新版本

services:
  web:
    images:nginx
  mysql:
    images:mysql:5.7
#将容器内部的端口映射到主机的端口,以便外部可以访问容器内的服务。例如, -"8080:80" 表示将主机的 8080 端口映射到容器内部的 80 端口。

services:
  web:
    image: nginx:latest
    container_name: nginx1 #指定容器名称
    restart: always #docekr容器自动启动
    expose:
        - 1234 #指定容器暴露那些端口,些端口仅对链接的服务可见,不会映射到主机的端口
    ports:
        - "80:8080"
#环境变量(environment):为容器设置环境变量,可以在容器内部的应用程序中使用。例如, VAR1: value1 设置环境变量 VAR1 的值为 value1

services:
  web:
    image: mysql:5.7
    container_name: mysql1
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: gyj
#存储卷(volumes):将主机上的目录或文件挂载到容器中,以实现数据持久化或共享。例如, -
/host/data:/container/data 将主机上的 /host/data 目录挂载到容器内的/container/data 路径。

services:
  test:
    image: busybox
    command: ["/bin/sh","-c","sleep 3000"]
    restart: always
    container_name: busybox1
    volumes:
        - /etc/passwd:/tmp/passwd:ro   #只读挂在本地文件到指定位置
#网络(networks):将服务连接到特定的网络,以便不同服务的容器可以相互通信

services:
  web:
    image: nginx
    container_name: webserver
    network_mode: bridge  #使用本机自带bridge网络

services:
  test:
    image: busybox
    container_name: webserver
    command: ["/bin/sh","-c","sleep 10000"]

  #network_mode: mynet2

  networks:
    - mynet1
    - mynet2
  networks:
    mynet1:
      driver: bridge
    mynet2:
      driver: bridge
#命令(command):覆盖容器启动时默认执行的命令。例如, command: python app.py 指定容器启动时运行
python app.py 命令

[root@docker test]# vim busybox.yml

services:
  web:
    image: busybox
    container_name: busybox
    #network_mode: mynet2
    command: ["/bin/sh","-c","sleep10000000"]

(2)、网络

  • 定义 Docker Compose 应用程序中使用的网络。可以自定义网络名称和驱动程序等属性。
  • 默认情况下docker compose 在执行时会自动建立网路
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

(3)、存储卷

services:
    test:
    image: busybox
    command: ["/bin/sh","-c","sleep 3000"]
    restart: always
    container_name: busybox1
    volumes:
        - data:/test #挂在data卷
        - /etc/passwd:/tmp/passwd:ro #只读挂在本地文件到指定位置

volumes:
    data:
    name: timinglee #指定建立卷的名字

九、利用docker编排完成haproxy和nginx负载均衡架构

1、只下载haproxy,找出haproxy的配置文件,编辑配置文件

#只下载不安装haproxy
[root@docker-node1 ~]# dnf install haproxy -y --downloadonly --downloaddir=/mnt
#解压文件并输出为目录,-id:i是输出,d是目录
[root@docker-node1 mnt]# rpm2cpio haproxy-2.4.22-1.el9.x86_64.rpm | cpio -id

2、编辑docker compose容器编排文件

[root@docker-node1 ~]# vim haproxy.yml

3、启动容器

[root@docker-node1 ~]# docker compose -f /root/haproxy.yml up -d

4、查看是否启动

5、写入网页内容

从配置文件可以看到,在主机的/var/lib/docker/volumes/data_web目录下,有data_web1和data_web2,这两个文件挂载的是nginx容器的网站首发内容页,所以在data_web1、data_web2这两个目录下写入网站首页内容。

6、测试

haproxy用的是轮询调度算法

删除镜像、加速器、volume 

ldd /usr/local/nginx/sbin/nginx  nginx运行时必须调用的模块

  • 13
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值