一、Docker的数据持久化
1)将本地目录映射到容器里
mkdir -p /data/
docker run -tid -v /data/:/data ubuntu bash ## -v 用来指定挂载目录 :前面的/data/为宿主机本地目录 :后面的/data/为容器里的目录,会在容器中自动创建
[root@bogon ~]# docker run --name webssh -itd -v /root/dockertest/:/root/ webssh
a5b4ce30e9f6e73b497fdc8049d5019020d261c880560117a232e68141aebee4
可以在/data/里创建一个文件
echo "hello" > /data/1.txt
然后到容器里查看
docker exec -it c82a5a00ae68 bash -c "cat /data/1.txt" ####-c就是command
[root@bogon ~]# cd dockertest/
[root@bogon dockertest]# touch aaaaa.txt
[root@bogon dockertest]# ls
aaaaa.txt
[root@bogon dockertest]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a5b4ce30e9f6 webssh "/webssh" 21 seconds ago Up 20 seconds webssh
[root@bogon dockertest]# docker exec -it webssh sh
/ # cd /root/
~ # ls
aaaaa.txt
docker exec -it webssh sh -c "ls /root/"
aaaaa.txt
[root@bogon dockertest]# echo 1111 > aaaaa.txt
[root@bogon dockertest]# docker exec -it webssh sh -c "cat /root/aaaaa.txt"
1111
2)数据卷
创建数据卷
docker volume create testvol ##testvol为数据卷名字
[root@bogon dockertest]# docker volume create 20240702
20240702
列出数据卷
docker volume ls
[root@bogon dockertest]# docker volume ls
DRIVER VOLUME NAME
local 20240702
查看数据卷信息
docker volume inspect testvol
[root@bogon dockertest]# docker volume inspect 20240702
[
{
"CreatedAt": "2024-07-02T02:24:35-07:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/20240702/_data", ###宿主机目录
"Name": "20240702",
"Options": null,
"Scope": "local"
}
]
使用数据卷
docker run -itd --name aming01 -v testvol:/data/ ubuntu ##和前面直接映射本地目录不同,冒号左边为数据卷名字
[root@bogon dockertest]# docker run --name webssh111 -itd -v 20240702:/root/ webssh
19abac7eb320f7cb13b7edefea03cf01e61994411bbcf0172066b96b35d4327a
多个容器可以共享一个数据卷
docker run -itd --name aming02 -v testvol:/data/ ubuntu
docker exec -it webssh111 sh -c "cat /root/test.sh"
hello
3)将宿主机上的文件快速传输进容器里
docker cp /etc/fstab aming01:/tmp/test.txt ###aming01为容器名,:后边为容器的目录
[root@bogon ~]# docker cp anaconda-ks.cfg webssh000:/root/anaconda-ks.cfg
Successfully copied 4.61kB to webssh000:/root/anaconda-ks.cfg
docker exec -it aming01 cat /tmp/test.txt
[root@bogon ~]# docker exec -it webssh000 cat /root/test.sh
hello
二、Docker网络
Docker服务启动时会生成一个docker0的网卡,这个网卡是实现容器网络通信的根本。 默认容器使用的网络类型为桥接(bridge)模式,这个桥接和我们的vmware里的桥接可不是一回事。它更像是vmware的NAT模式。
每启动一个容器,都会产生一个虚拟网卡 vethxxx
iptables -nvL -t nat ##可以看到DOCKER相关规则,容器之所以可以联网,是靠这些规则实现的
1)host模式
docker run -itd --net=host --name aming03 ubuntu
可以进入容器内,查看hostname,查看ip地址。 这种模式,容器和宿主机共享主机名、IP。
[root@bogon ~]# docker exec -it webssh222 sh
/ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:a1:45:7c brd ff:ff:ff:ff:ff:ff
inet 192.168.100.160/24 brd 192.168.100.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet6 fe80::dbc9:c997:8540:fcf7/64 scope link noprefixroute
valid_lft forever preferred_lft forever
[root@bogon ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:a1:45:7c brd ff:ff:ff:ff:ff:ff
inet 192.168.100.160/24 brd 192.168.100.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet6 fe80::dbc9:c997:8540:fcf7/64 scope link noprefixroute
valid_lft forever preferred_lft forever
2)container模式
该模式下,在启动容器时,需要指定目标容器ID或者name,意思是将要.启动的容器和已启动的目标容器使用一样的网络,即它们的IP一样
docker run -itd --net=container:/aming01 --name aming04 ubuntu ###aming01:已存在的容器,aming04是要启动的容器名称
[root@bogon ~]# docker run -itd --net=container:/webssh111 --name webssh2222 webssh
3b49c8521233d4f952698a31b796bc83d765d725668a814263d4f2bf5eab52c8
3)none模式
即不需要配置网络
docker run -itd --net=none --name=aming05 ubuntu_test bash
[root@bogon ~]# docker run -itd --net=none --name webssh333 webssh
1374c0bdae08abccde01307bee9e615420699cbb921b5ba0e75784f1891317bd
查看:
docker exec -it aming05 bash -c "ip add"
[root@bogon ~]# docker exec -it webssh333 sh -c "ip add"
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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
[root@bogon ~]#
4)bridge模式
也就是默认模式,可以--net=bridge 也可以不指定--net,默认就是bridge,类似vmware的NAT模式。
5)端口映射
docker run -itd -v /data/:/var/www/html/ -p 8088:80 --name aming06 ubuntu_test bash
说明: -p后面跟 宿主机监听端口:容器监听端口
[root@bogon ~]# docker run -itd --name lucky -p 5000:16601 lucky
ff1da934eceb46b7ed94989dc7881621224d4a4cec1b24fa4b0e4c53554151e2
[root@bogon ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ff1da934eceb lucky "/app/lucky -c /good…" 4 seconds ago Up 3 seconds 0.0.0.0:5000->16601/tcp, :::5000->16601/tcp lucky
[root@bogon ~]# netstat -ltnp | grep 5000
tcp 0 0 0.0.0.0:5000 0.0.0.0:* LISTEN 63253/docker-proxy
tcp6 0 0 :::5000 :::* LISTEN 63258/docker-proxy
三、 Dockerfile编写
什么是Dockerfile?是实现自定义镜像的一种手段,通过编写Dockerfile,来编译成自己想要的镜像。
Dockerfile 格式
1)FROM 指定基于哪个基础镜像,例如:
FROM ubuntu:latest
2)MAINTAINER 指定作者信息,例如:
MAINTAINER aming aming@aminglinux.com
3)RUN 后面跟具体的命令,例如:
RUN apt update
RUN apt install -y curl
RUN ["apt","install","-y","curl" ] ##这种写法偏复杂
4)CMD 用来指定容器启动时用到的命令,只能有一条,格式如下:
CMD ["executable", "param1", "param2"]
CMD command param1 param2
CMD ["param1", "param2"]
CDM示例:
CMD ["/bin/bash", "/usr/local/nginx/sbin/nginx", "-c", "/usr/local/nginx/conf/nginx.conf"]
5)EXPOSE 指定要映射的端口,格式:
EXPOSE <port> [<port>...]
EXPOSE示例:
EXPOSE 22 80 8443 ##要暴露22,80,8443三个端口
说明:这个需要配合-P(大写)来工作,也就是说在启动容器时,需要加上-P,让它自动分配。如果想指定具体的端口,也可以使用-p(小写)来指定。
6)ENV 为后续的RUN指令提供一个环境变量,我们也可以定义一些自定义的变量,例如
ENV MYSQL_version 5.7
7)ADD 将本地的一个文件或目录拷贝到容器的某个目录里。 其中src为Dockerfile所在目录的相对路径,它也可以是一个url。例如:
ADD conf/vhosts /usr/local/nginx/conf
8)COPY 类似于ADD,将本地文件拷贝到容器里,不过它不支持URL,例如:
COPY 123.txt /data/456.txt
9)ENTRYPOINT 格式类似CMD
容器启动时要执行的命令,它和CMD很像,也是只有一条生效,如果写多个只有最后一条有效。
和CMD不同是: CMD 是可以被 docker run 指令覆盖的,而ENTRYPOINT不能覆盖。
比如,容器名字为aming 我们在Dockerfile中指定如下CMD:
CMD ["/bin/echo", "test"]
假如启动容器的命令是
docker run aming
则会输出 test
假如启动容器的命令是
docker run -it aming /bin/bash
则什么都不会输出
ENTRYPOINT不会被覆盖,而且会比CMD或者docker run指定的命令要靠前执行
ENTRYPOINT ["echo", "test"]
假如启动容器的命令是
docker run -it aming 123
则会输出 test 123 ,这相当于要执行命令 echo test 123
10)VOLUME 创建一个可以从本地主机或其他容器挂载的挂载点。
VOLUME ["/data"]
11)USER指定RUN、CMD或者ENTRYPOINT运行时使用的用户
USER aming
12)WORKDIR 为后续的RUN、CMD或者ENTRYPOINT指定工作目录
WORKDIR /tmp/
Dockerfile示例:
vi Dockerfile
FROM ubuntu ########基础镜像
MAINTAINER aming aming@aminglinux.com ####作者信息
RUN apt update ####操作命令
RUN apt install -y libpcre2-dev net-tools gcc zlib1g-dev make ####操作命令
ADD http://nginx.org/download/nginx-1.23.2.tar.gz . ####下载文件,.指当前目录
RUN tar zxvf nginx-1.23.2.tar.gz ####操作命令
RUN mkdir -p /usr/local/ ####操作命令
RUN cd nginx-1.23.2 && ./configure --prefix=/usr/local/nginx && make && make install ####操作命令
COPY index.html /usr/local/nginx/html/index.html ####将本地文件拷贝到容器里
COPY index2.html /usr/local/nginx/html/2.html ####将本地文件拷贝到容器里
EXPOSE 80 ####暴露80端口
ENTRYPOINT /usr/local/nginx/sbin/nginx -g "daemon off;" ####启动命令,-g "daemon off;" 前台启动,如果启动命令在后台,则终止,在前台则一直运行
[root@bogon test]# cat Dockerfile
FROM webssh
MAINTAINER yeyunyi yeyunyi@ourteam.top
RUN cat /etc/resolv.conf
ADD http://nginx.org/download/nginx-1.23.2.tar.gz .
RUN tar zxvf nginx-1.23.2.tar.gz
RUN mkdir -p /usr/local/
COPY ip /etc/resolv.conf
EXPOSE 80
ENTRYPOINT /usr/local/nginx/sbin/nginx -g "daemon off;" ####启动命令,-g "daemon off;"
[root@bogon test]#
编译成镜像
docker build -t ubuntu_nginx:1.0 . ####-t,用来指定镜像的名字和tag,.指代当前目录,指定dockerfile位置 ,也可以使用-f指定dockerfile文件
[root@bogon test]# docker build -t webssh:5.0 .
[+] Building 5.6s (12/12) FINISHED docker:default
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 429B 0.0s
=> [internal] load metadata for docker.io/library/webssh:latest 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> CACHED [1/6] FROM docker.io/library/webssh:latest 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 83B 0.0s
=> [2/6] RUN cat /etc/resolv.conf 0.7s
=> [3/6] ADD http://nginx.org/download/nginx-1.23.2.tar.gz . 1.2s
=> [3/6] ADD http://nginx.org/download/nginx-1.23.2.tar.gz . 0.1s
=> [4/6] RUN tar zxvf nginx-1.23.2.tar.gz 2.0s
=> [5/6] RUN mkdir -p /usr/local/ 1.1s
=> [6/6] COPY ip /etc/resolv.conf 0.2s
=> exporting to image 0.6s
=> => exporting layers 0.5s
=> => writing image sha256:d6b785ab9b96da3bae569866ba442a9b02aa9c4c51370f7f290cbd4876e7f6e0 0.0s
=> => naming to docker.io/library/webssh:5.0
说明: -t 后面跟镜像名字:tag, 这里的. 表示使用当前目录下的Dockerfile,并且工作目录也为当前目录,如果想使用其它目录下的Dockerfile,还可以使用-f选项来指定,例如
docker build -t ubuntu_nginx:1.0 -f /data/docker/nginx.dkf /tmp/ ##这里/tmp/目录为工作目录,比如COPY文件的时候,到/tmp/下面去找
使用镜像
docker run -itd --name nginx -P ubuntu_nginx:1.0 ##使用-P(大写P)可以随机映射一个端口到宿主机,也可以使用-p(小p)指定具体端口