Linux——Docker容器虚拟化平台

安装docker

安装 Docker | Docker 从入门到实践icon-default.png?t=N7T8https://vuepress.mirror.docker-practice.com/install/

 不需要设置防火墙

docker命令说明

docker images  #查看所有本地主机的镜像
docker search 镜像名           #搜索镜像
docker pull 镜像名 [标签]      #下载镜像(如果不写tag,默认是latest)
docker rmi 镜像名 [标签]       #删除镜像    docker rmi -f $(docker images -aq)  删除全部镜像
docker tag  镜像名:版本   新镜像名:版本    #复制镜像并且修改名称
docker commit  -a "xxx"  -c "xxx" 镜像ID 名字:版本   #提交镜像
-a :提交的镜像作者;
-c :使用Dockerfile指令来创建镜像;
-m :提交时的说明文字;

docker load -i    /xxx/xxx.tar         #导入镜像
docker save -o   /xxx/xxx.tar          #保存一个镜像为一个tar包

 容器命令

 docker run [可选参数] image 命令 #启动容器(无镜像会先下载镜像)
#参数说明
--name = "Name"   容器名字
-c   后面跟待完成的命令
-d   以后台方式运行并且返回ID,启动守护进程式容器
-i   使用交互方式运行容器,通常与t同时使用
-t   为容器重新分配一个伪输入终端。也即启动交互式容器
-p   指定容器端口    -p 容器端口:物理机端口  映射端口
-P   随机指定端口
-v   给容器挂载存储卷

docker build  #创建镜像        -f:指定dockerfile文件路径   -t:镜像名字以及标签
docker logs 容器实例的ID          #查看容器日志
docker rename 旧名字  新名字      # 给容器重新命名
docker top    容器实例的ID                  #查看容器内进程
docker ps -a                    #列出所有容器(不加-a就是在运行的)
docker rm      容器实例的ID                 #删除容器(正在运行容器不能删除,除非加-f选项)
docker kill  容器实例的ID        #杀掉容器
docker history   容器实例的ID    #查看docker镜像的变更历史
docker start 容器实例的ID        #启动容器
docker restart 容器实例的ID       #重启容器
docker stop 容器实例的ID         #停止正在运行的容器
docker attach /docker exec  容器实例的ID   #同为进入容器命令,不同的是attach连接终止会让容器退出后台运行,而exec不会。并且,docker attach是进入正在执行的终端,不会情动新的进程,而docker exec则会开启一个新的终端,可以在里面操作。
docker image inspect  容器名称:容器标签       #查看容器内源数据
docker cp  容器id:容器内路径   目的主机路径           #从容器内拷贝文件到主机(常用)或者从主机拷贝到容器(一般用挂载)
exit                           #直接退出容器
crlt + P + Q                   #退出容器但是不终止运行

镜像的导入导出:


[root@docker1 ~]# docker run -itd ubuntu:18.04  bash
aaba782de4aa1de481caefca4c96e6cd32a902660015386d70450f459d7289df
[root@docker1 ~]# docker ps
CONTAINER ID   IMAGE          COMMAND   CREATED         STATUS         PORTS     NAMES
aaba782de4aa   ubuntu:18.04   "bash"    2 minutes ago   Up 2 minutes             quirky_khayyam
[root@docker1 ~]# docker exec -it quirky_khayyam bash  
#为 quirky_khayyam 的容器内部启动一个交互式的 bash shell
root@aaba782de4aa:/# pwd           
/
root@aaba782de4aa:/# touch test.txt
root@aaba782de4aa:/# exit
exit
[root@docker1 ~]# docker export aaba782de4aa  > ubuntu.tar
[root@docker1 ~]#
[root@docker1 ~]# docker stop quirky_khayyam 
quirky_khayyam
[root@docker1 ~]# docker rm quirky_khayyam 
quirky_khayyam
[root@docker1 ~]#[root@docker1 ~]# cat ubuntu.tar | docker import - test/ubuntu:v1.0
sha256:2459841eac991ee8b0b6598e189ada679f1652e5ff95bcb27a38a9f863dc1d40
[root@docker1 ~]#[root@docker1 ~]# docker image ls
REPOSITORY    TAG       IMAGE ID       CREATED          SIZE
test/ubuntu   v1.0      2459841eac99   55 seconds ago   63.2MB
ubuntu        18.04     f9a80a55f492   11 months ago    63.2MB
hello-world   latest    d2c94e258dcb   12 months ago    13.3kB
[root@docker1 ~]#[root@docker1 ~]# docker run -it --name test test/ubuntu:v1.0 bash
root@bfe4f040f985:/# ls /test.txt
/test.txt
root@bfe4f040f985:/# exit
exit
[root@docker1 ~]# docker ps -a
CONTAINER ID   IMAGE              COMMAND   CREATED          STATUS                     PORTS     NAMES
bfe4f040f985   test/ubuntu:v1.0   "bash"    10 seconds ago   Exited (0) 2 seconds ago             test
[root@docker1 ~]# docker rm test 
test
[root@docker1 ~]#注:容器导出为镜像,从镜像运行容器,可恢复导出前的效果

Docker导入导出镜像:

[root@docker1 ~]# docker save hello-world:latest -o hello.tar
[root@docker1 ~]# ls hello.tar 
hello.tar
[root@docker1 ~]#[root@docker1 ~]# scp hello.tar 192.168.99.129:/
root@192.168.99.129's password: 
hello.tar                                                100%   25KB  14.4MB/s   00:00    
[root@docker1 ~]#[root@docker2 ~]# docker load -i /hello.tar 
ac28800ec8bb: Loading layer  14.85kB/14.85kB
Loaded image: hello-world:latest
[root@docker2 ~]# docker image ls
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
hello-world   latest    d2c94e258dcb   12 months ago   13.3kB
[root@docker2 ~]#
[root@docker2 ~]# docker rmi hello-world:latest[root@docker1 ~]# docker save hello-world:latest ubuntu:18.04 -o hello_ubuntu.tar
[root@docker1 ~]# scp hello_ubuntu.tar 192.168.99.129:/
root@192.168.99.129's password: 
hello_ubuntu.tar                                                           100%   63MB  71.0MB/s   00:00    
[root@docker1 ~]#[root@docker2 ~]# docker load -i /hello_ubuntu.tar 
ac28800ec8bb: Loading layer  14.85kB/14.85kB
Loaded image: hello-world:latest
548a79621a42: Loading layer  65.53MB/65.53MB
Loaded image: ubuntu:18.04
[root@docker2 ~]# docker image ls
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
ubuntu        18.04     f9a80a55f492   11 months ago   63.2MB
hello-world   latest    d2c94e258dcb   12 months ago   13.3kB
[root@docker2 ~]#[root@docker2 ~]# docker info 显示docker系统级别的一些信息
[root@docker1 ~]# docker inspect --help 返回docker对象的一些信息(镜像或容器)
[root@docker1 ~]# docker inspect hello-world:latest 输出略

利用 commit 理解镜像构成:

运行nginx镜像:

[root@docker1 ~]# docker pull nginx
[root@docker1 ~]# docker image ls nginx
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
nginx        latest    e784f4560448   13 days ago   188MB
[root@docker1 ~]#[root@docker1 ~]# docker run -d --name nginx1 nginx
d4a4ee4c2ca600935ecf8c63681683c479f8c6d0ce68f093d93161bc7416a1e8
[root@docker1 ~]# docker ps 
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
d4a4ee4c2ca6   nginx     "/docker-entrypoint.…"   15 seconds ago   Up 14 seconds   80/tcp    nginx1
[root@docker1 ~]#[root@docker1 ~]# ip a s docker0
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:4f:7c:ef:33 brd ff:ff:ff:ff:ff:ffinet 172.17.0.1/16 brd 172.17.255.255 scope global docker0valid_lft forever preferred_lft foreverinet6 fe80::42:4fff:fe7c:ef33/64 scope link valid_lft forever preferred_lft forever
[root@docker1 ~]# curl -I 172.17.0.2
HTTP/1.1 200 OK
Server: nginx/1.25.5
Date: Fri, 17 May 2024 07:27:27 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Tue, 16 Apr 2024 14:29:59 GMT
Connection: keep-alive
ETag: "661e8b67-267"
Accept-Ranges: bytes[root@docker1 ~]# 

如果镜像包含ip或ifconfig等命令,可以连接到容器查看ip:

[root@docker1 ~]# docker exec -it nginx1 bash如果没有查看ip的命令:可以使用inspect子命令
[root@docker1 ~]# docker inspect nginx1 | grep -i ipaddress"SecondaryIPAddresses": null,"IPAddress": "172.17.0.2","IPAddress": "172.17.0.2",
[root@docker1 ~]# docker inspect nginx1 | grep -i ip"IpcMode": "private","LinkLocalIPv6Address": "","LinkLocalIPv6PrefixLen": 0,"SecondaryIPAddresses": null,"SecondaryIPv6Addresses": null,"GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"IPAddress": "172.17.0.2","IPPrefixLen": 16,"IPv6Gateway": "","IPAMConfig": null,"IPAddress": "172.17.0.2","IPPrefixLen": 16,"IPv6Gateway": "","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,
[root@docker1 ~]#

此时docker1访问正常:
[root@docker1 ~]# curl -I 172.17.0.2
HTTP/1.1 200 OK
Server: nginx/1.25.5
Date: Fri, 17 May 2024 07:32:55 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Tue, 16 Apr 2024 14:29:59 GMT
Connection: keep-alive
ETag: "661e8b67-267"
Accept-Ranges: bytes[root@docker1 ~]#
Docker2无法访问:
[root@docker2 ~]# curl 172.17.0.2
curl: (7) Failed to connect to 172.17.0.2 port 80: No route to host
[root@docker2 ~]#[root@docker1 ~]# firewall-cmd --set-default-zone=trusted 
success
[root@docker1 ~]# setenforce 0
[root@docker2 ~]# firewall-cmd --set-default-zone=trusted 
success
[root@docker2 ~]# 
[root@docker2 ~]# setenforce 0

此时docker2无法访问:

  1. 因为本机也有172.17.0.1的docker0网桥,找172.17.0.2时在本机找
  2. 即使本机没有172.17.0.1的docker0网桥,也无法访问,因为缺少到容器网段的路由,需手动添加静态路由,容器主机中也需要有返回的路由

如何使docker2能否访问docker1的容器web服务:

可以使用端口映射:将容器的端口映射到虚拟机的端口

[root@docker1 ~]# docker stop nginx1 
nginx1
[root@docker1 ~]# docker rm nginx1 
nginx1
[root@docker1 ~]# docker run -d --name nginx2 -p 80:80 nginx
db4296a9e0e2f6f84a8032e45567b39d5921ac613af89bea1b194842ed58b197
[root@docker1 ~]#[root@docker1 ~]# docker exec -it nginx2 bash
root@db4296a9e0e2:/# find / -name "index.html"
find: '/proc/29/map_files': Permission denied
find: '/proc/30/map_files': Permission denied
find: '/proc/31/map_files': Permission denied
find: '/proc/32/map_files': Permission denied
/usr/share/nginx/html/index.html
root@db4296a9e0e2:/# echo docker1-nginx2 > /usr/share/nginx/html/test.html
root@db4296a9e0e2:/# exit
exit
[root@docker1 ~]#
[root@docker1 ~]# ip a s ens160
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000link/ether 00:50:56:31:08:49 brd ff:ff:ff:ff:ff:ffaltname enp3s0inet 192.168.99.138/24 brd 192.168.99.255 scope global dynamic noprefixroute ens160valid_lft 1092sec preferred_lft 1092secinet6 fe80::250:56ff:fe31:849/64 scope link noprefixroute valid_lft forever preferred_lft forever
[root@docker1 ~]# curl 192.168.99.138/test.html
docker1-nginx2
[root@docker1 ~]# [root@docker2 ~]# curl  192.168.99.138/test.html
docker1-nginx2
[root@docker2 ~]#
注:
此时docker1和docker2的防火墙都是trusted状态,如果是public,自行放行服务或端口注: -p 80:80  前面是宿主机端口,后面是容器端口
[root@docker1 ~]# docker stop nginx2 
nginx2
[root@docker1 ~]# docker rm nginx2 
nginx2
[root@docker1 ~]#
[root@docker1 ~]# docker run -d --name nginx3 -p 8080:80 nginx
566dfc7e1e699d5fc159421804fc1092f60c342f4d59fb7d7c77e44b1db659e6
[root@docker1 ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                                   NAMES
566dfc7e1e69   nginx     "/docker-entrypoint.…"   4 seconds ago   Up 3 seconds   0.0.0.0:8080->80/tcp, :::8080->80/tcp   nginx3
[root@docker1 ~]# curl -I 192.168.99.138:8080
HTTP/1.1 200 OK
Server: nginx/1.25.5
Date: Fri, 17 May 2024 07:47:35 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Tue, 16 Apr 2024 14:29:59 GMT
Connection: keep-alive
ETag: "661e8b67-267"
Accept-Ranges: bytes[root@docker1 ~]#
[root@docker1 ~]# curl -I 192.168.122.1:8080
HTTP/1.1 200 OK
Server: nginx/1.25.5
Date: Fri, 17 May 2024 07:48:57 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Tue, 16 Apr 2024 14:29:59 GMT
Connection: keep-alive
ETag: "661e8b67-267"
Accept-Ranges: bytes[root@docker1 ~]#
[root@docker1 ~]# ss -antpul | grep 8080
tcp   LISTEN 0      128           0.0.0.0:8080       0.0.0.0:*    users:(("docker-proxy",pid=61079,fd=4))
tcp   LISTEN 0      128              [::]:8080          [::]:*    users:(("docker-proxy",pid=61085,fd=4))
[root@docker1 ~]#可以只映射到宿主机指定ip的80端口:
[root@docker1 ~]# docker stop nginx3 
nginx3
[root@docker1 ~]# docker rm nginx3 
nginx3
[root@docker1 ~]# docker run -d --name nginx4 -p 192.168.99.138:8080:80 nginx
e5a62599706c1e7634ca763394340aa34f9436d3caeece143025524898f40607
[root@docker1 ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                         NAMES
e5a62599706c   nginx     "/docker-entrypoint.…"   5 seconds ago   Up 4 seconds   192.168.99.138:8080->80/tcp   nginx4
[root@docker1 ~]# ss -antpul | grep 8080
tcp   LISTEN 0      128    192.168.99.138:8080       0.0.0.0:*    users:(("docker-proxy",pid=61383,fd=4))
[root@docker1 ~]#[root@docker1 ~]# curl -I 192.168.122.1:8080
curl: (7) Failed to connect to 192.168.122.1 port 8080: Connection refused
[root@docker1 ~]# curl -I 192.168.122.1:8080
curl: (7) Failed to connect to 192.168.122.1 port 8080: Connection refused
[root@docker1 ~]# curl -I 192.168.99.138:8080
HTTP/1.1 200 OK
Server: nginx/1.25.5
Date: Fri, 17 May 2024 07:50:46 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Tue, 16 Apr 2024 14:29:59 GMT
Connection: keep-alive
ETag: "661e8b67-267"
Accept-Ranges: bytes[root@docker1 ~]#-P:随机映射,前提是容器已经定义了需要暴露的端口
[root@docker1 ~]# docker stop nginx4
nginx4
[root@docker1 ~]# docker rm nginx4
nginx4
[root@docker1 ~]# docker run -d --name nginx5 -P nginx
60ca1a4b8ffca7328e5bf0dcf84a5b86829c68f2ba970d2a6281a796624cbbd8
[root@docker1 ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                                     NAMES
60ca1a4b8ffc   nginx     "/docker-entrypoint.…"   4 seconds ago   Up 3 seconds   0.0.0.0:32768->80/tcp, :::32768->80/tcp   nginx5
[root@docker1 ~]#
[root@docker1 ~]# curl -I 192.168.99.138:32768
HTTP/1.1 200 OK
Server: nginx/1.25.5
Date: Fri, 17 May 2024 07:53:22 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Tue, 16 Apr 2024 14:29:59 GMT
Connection: keep-alive
ETag: "661e8b67-267"
Accept-Ranges: bytes[root@docker1 ~]#

查看容器要暴露的端口:

[root@docker1 ~]# docker inspect nginx5 | grep -A 5  ExposedPorts"ExposedPorts": {"80/tcp": {}},"Tty": false,"OpenStdin": false,"StdinOnce": false,
[root@docker1 ~]#

查看镜像定义的暴露端口:

[root@docker1 ~]# docker inspect nginx:latest | grep -A 5  ExposedPorts"ExposedPorts": {"80/tcp": {}},"Tty": false,"OpenStdin": false,"StdinOnce": false,
[root@docker1 ~]#

[root@docker1 ~]# docker stop nginx5 
nginx5
[root@docker1 ~]# docker rm nginx5 
nginx5
[root@docker1 ~]#
[root@docker1 ~]# docker run -d --name nginx6 -p 80:80 nginx
e31bc64cd4958b83394565d0fa269a00c33f59c3728a3eda1b70cf9e93452c9c
[root@docker1 ~]# docker exec -it nginx6 bash
root@e31bc64cd495:/# echo nginx-test > /usr/share/nginx/html/test.html
root@e31bc64cd495:/# exit
exit
[root@docker1 ~]#[root@docker1 ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                               NAMES
e31bc64cd495   nginx     "/docker-entrypoint.…"   39 seconds ago   Up 38 seconds   0.0.0.0:80->80/tcp, :::80->80/tcp   nginx6
[root@docker1 ~]# docker commit --message "add test.html" nginx6 nginx-test:v1
sha256:cb4960a17a3342101dd984daa6facba546c8c3952e94ac807f2f2ff4dc6de50d
[root@docker1 ~]# docker image ls nginx-test:v1
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
nginx-test   v1        cb4960a17a33   8 seconds ago   188MB
[root@docker1 ~]#[root@docker1 ~]# docker image ls | grep nginx
nginx-test    v1        cb4960a17a33   44 seconds ago   188MB
nginx         latest    e784f4560448   13 days ago      188MB
[root@docker1 ~]#
[root@docker1 ~]# curl 192.168.99.138/test.html
nginx-test
[root@docker1 ~]#
[root@docker1 ~]# docker stop nginx6;docker rm nginx6
nginx6
nginx6
[root@docker1 ~]# docker run -d --name nginx7 -p 80:80 nginx-test:v1
11e90accf1772d7516f80a418ae5f53104c8819c8e2878831c970e10b0fa403e
[root@docker1 ~]# curl 192.168.99.138/test.html
nginx-test
[root@docker1 ~]#[root@docker1 ~]# docker stop nginx7 
nginx7
[root@docker1 ~]# docker rm nginx7 
nginx7
[root@docker1 ~]# docker image rm nginx-test:v1 
Untagged: nginx-test:v1
Deleted: sha256:cb4960a17a3342101dd984daa6facba546c8c3952e94ac807f2f2ff4dc6de50d
Deleted: sha256:b07365485892d137124c53286c7dd4a6464da9f187e4300110fcf2f863324056
[root@docker1 ~]# 有些层被nginx:latest镜像使用,没有删除

Docker export和docker commit的区别:

Docker export:Export a container's filesystem as a tar archive 保存文件系统快照

Docker commit:Create a new image from a container's changes 根据变更生成新镜像

Commit会保留元数据、运行时状态等内容:

[root@docker1 ~]#  docker run ubuntu:18.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"

此终端保留

另起一个终端:

[root@docker1 ~]# docker export vibrant_turing > test_export.tar
[root@docker1 ~]# docker commit --message "use while" vibrant_turing test_commit:v1
sha256:766f22a748b9102411744a377fa0f5c6b6c284756a40e984e41e700dfb0fffce
[root@docker1 ~]#[root@docker1 ~]# docker stop vibrant_turing 
vibrant_turing
[root@docker1 ~]# docker rm vibrant_turing 
vibrant_turing
[root@docker1 ~]#[root@docker1 ~]# cat test_export.tar | docker import - test_export:v1
sha256:de19b4e7f444c5495b9ae713664142a617b725e19ec58cf070a5ffa951c8b295
[root@docker1 ~]# [root@docker1 ~]# docker image ls | grep test_
test_export   v1        de19b4e7f444   17 seconds ago       63.2MB
test_commit   v1        766f22a748b9   About a minute ago   63.2MB
[root@docker1 ~]#
[root@docker1 ~]# docker history ubuntu:18.04 
IMAGE          CREATED         CREATED BY                                      SIZE      COMMENT
f9a80a55f492   11 months ago   /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B        
<missing>      11 months ago   /bin/sh -c #(nop) ADD file:3c74e7e08cbf9a876…   63.2MB    
<missing>      11 months ago   /bin/sh -c #(nop)  LABEL org.opencontainers.…   0B        
<missing>      11 months ago   /bin/sh -c #(nop)  LABEL org.opencontainers.…   0B        
<missing>      11 months ago   /bin/sh -c #(nop)  ARG LAUNCHPAD_BUILD_ARCH     0B        
<missing>      11 months ago   /bin/sh -c #(nop)  ARG RELEASE                  0B        
[root@docker1 ~]#[root@docker1 ~]# docker history test_commit:v1 
IMAGE          CREATED         CREATED BY                                      SIZE      COMMENT
766f22a748b9   2 minutes ago   /bin/sh -c while true; do echo hello world; …   0B        use while
f9a80a55f492   11 months ago   /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B        
<missing>      11 months ago   /bin/sh -c #(nop) ADD file:3c74e7e08cbf9a876…   63.2MB    
<missing>      11 months ago   /bin/sh -c #(nop)  LABEL org.opencontainers.…   0B        
<missing>      11 months ago   /bin/sh -c #(nop)  LABEL org.opencontainers.…   0B        
<missing>      11 months ago   /bin/sh -c #(nop)  ARG LAUNCHPAD_BUILD_ARCH     0B        
<missing>      11 months ago   /bin/sh -c #(nop)  ARG RELEASE                  0B        
[root@docker1 ~]#[root@docker1 ~]# docker history test_export:v1 (没有历史元数据)
IMAGE          CREATED         CREATED BY   SIZE      COMMENT
de19b4e7f444   2 minutes ago                63.2MB    Imported from -
[root@docker1 ~]#[root@docker1 ~]# docker run test_export:v1(没有保存程序运行的状态)
docker: Error response from daemon: no command specified.
See 'docker run --help'.
[root@docker1 ~]# docker run test_export:v1 cat /etc/hosts
127.0.0.1	localhost
::1	localhost ip6-localhost ip6-loopback
fe00::0	ip6-localnet
ff00::0	ip6-mcastprefix
ff02::1	ip6-allnodes
ff02::2	ip6-allrouters
172.17.0.2	328c0312c571
[root@docker1 ~]#
[root@docker1 ~]# docker ps -a
CONTAINER ID   IMAGE            COMMAND            CREATED          STATUS                      PORTS     NAMES
328c0312c571   test_export:v1   "cat /etc/hosts"   39 seconds ago   Exited (0) 38 seconds ago             hopeful_jemison
[root@docker1 ~]# docker rm hopeful_jemison 
hopeful_jemison
[root@docker1 ~]#[root@docker1 ~]# docker run test_commit:v1 (保留了程序的运行状态)
hello world
hello world
…….
[root@docker1 ~]# docker stop recursing_thompson
recursing_thompson
[root@docker1 ~]# docker rm recursing_thompson
recursing_thompson
[root@docker1 ~]#[root@docker1 ~]# docker rmi test_export:v1 test_commit:v1 
Untagged: test_export:v1
Deleted: sha256:de19b4e7f444c5495b9ae713664142a617b725e19ec58cf070a5ffa951c8b295
Deleted: sha256:52c27cd07f847f4a06c176cb00ac51e6459d9d8b557136320ad12111093a2a6c
Untagged: test_commit:v1
Deleted: sha256:766f22a748b9102411744a377fa0f5c6b6c284756a40e984e41e700dfb0fffce
[root@docker1 ~]#

使用 Dockerfile 定制镜像:

Dockerfile 是一个文本文件,其内包含了一条条的 指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。

使用dockerfile构建nginx镜像:

[root@docker1 ~]# mkdir /nginxdir
[root@docker1 ~]# cd /nginxdir
[root@docker1 nginxdir]# touch Dockerfile
[root@docker1 nginxdir]# vim Dockerfile
[root@docker1 nginxdir]# cat Dockerfile
FROM nginx:latest
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
[root@docker1 nginxdir]#

注:

Dockerfile 中每一个指令都会建立一层

Union FS 是有最大层数限制的,比如 AUFS,曾经是最大不得超过 42 层,现在是不得超过 127 层。

执行构建:

docker build [选项] <上下文路径/URL/->

下面命令中:.(点) 代表上下文路径
[root@docker1 nginxdir]# docker build -t nginx:v1 .
[+] Building 0.7s (6/6) FINISHED                                            docker:default=> [internal] load build definition from Dockerfile                                  0.0s=> => transferring dockerfile: 182B                                                  0.0s=> [internal] load metadata for docker.io/library/nginx:latest                       0.0s=> [internal] load .dockerignore                                                     0.0s=> => transferring context: 2B                                                       0.0s=> [1/2] FROM docker.io/library/nginx:latest                                         0.0s=> [2/2] RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html       0.5s=> exporting to image                                                                0.0s=> => exporting layers                                                               0.0s=> => writing image sha256:45619c5922baedbe007f2e632c592db9ffd2c6f4b8ea41608ee9e29a  0.0s=> => naming to docker.io/library/nginx:v1                                           0.0s
[root@docker1 nginxdir]#
[root@docker1 nginxdir]# docker image ls | grep nginx
nginx         v1        45619c5922ba   2 minutes ago   188MB
nginx         latest    e784f4560448   13 days ago     188MB
[root@docker1 nginxdir]# docker history nginx:v1
[root@docker1 nginxdir]# docker run -d -p 80:80 nginx:v1
ef8dd71f77eddded5e5b35ed698ba3b469c65c707998f89e5fe9ce7dddc86c9a
[root@docker1 nginxdir]# curl 192.168.99.138
<h1>Hello, Docker!</h1>
[root@docker1 nginxdir]# docker stop brave_kapitsa 
brave_kapitsa
[root@docker1 nginxdir]# docker rm brave_kapitsa 
brave_kapitsa
[root@docker1 nginxdir]#

COPY:复制

格式:

    COPY [--chown=<user>:<group>] <源路径>... <目标路径>

COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]

参考:COPY 复制文件 | Docker 从入门到实践icon-default.png?t=N7T8https://vuepress.mirror.docker-practice.com/image/dockerfile/copy/

添加两个页面到nginx容器中:

[root@docker1 nginxdir]# cat Dockerfile
FROM nginx:v1
COPY test*.html /usr/share/nginx/html/
[root@docker1 nginxdir]#
[root@docker1 nginxdir]# echo test2 > test2.html
[root@docker1 nginxdir]# echo test3 > test3.html
[root@docker1 nginxdir]# ls
Dockerfile  test2.html  test3.html
[root@docker1 nginxdir]#
[root@docker1 nginxdir]# docker build -t nginx:v2 . 输出略

注:如果dockerfile文件名不是Dockerfile,是其他名字,需用-f选项指定

如:docker build -f dfile -t nginx:v2

验证:

[root@docker1 nginxdir]# docker run -d --name nginxv2 --rm -p 80:80 nginx:v2
41f46e9bf3c86f63bd7edf22c6dc3a04d139bba8bc626593edf310fe0865da62
[root@docker1 nginxdir]# curl 192.168.99.138
<h1>Hello, Docker!</h1>
[root@docker1 nginxdir]# curl 192.168.99.138/test2.html
test2
[root@docker1 nginxdir]# curl 192.168.99.138/test3.html
test3
[root@docker1 nginxdir]# docker stop nginxv2 
nginxv2
[root@docker1 nginxdir]# docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@docker1 nginxdir]#

Sed的替换命令:

[root@docker1 ~]# cat test.txt
book
booka
bookb
bookc
aabb
[root@docker1 ~]#
[root@docker1 ~]# sed 's/book/books/' test.txt(没有真正的修改文件内容)
books
booksa
booksb
booksc
aabb
[root@docker1 ~]#-n选项和p命令一起使用表示只打印那些发生替换的行:
[root@docker1 ~]# sed -n 's/book/books/p' test.txt (没有真正的修改文件内容)
books
booksa
booksb
booksc
[root@docker1 ~]#[root@docker1 ~]# sed -i 's/book/books/' test.txt(-i:真正修改文件)
[root@docker1 ~]# cat test.txt
books
booksa
booksb
booksc
aabb
[root@docker1 ~]#可以使用正则表达式:
[root@docker1 ~]# sed -n 's/^a.*/bbaa/p' test.txt;
bbaa
[root@docker1 ~]#/可以换成其他字符,和命令中的其他符号不冲突即可:
[root@docker1 ~]# sed -n 's,^a.*,books,p' test.txt
books
[root@docker1 ~]# sed -n 's;^a.*;books;p' test.txt
books
[root@docker1 ~]#Sed根据正则表达式打印指定的行:
[root@docker1 ~]# vim test-nginx.conf (nginx配置文件的副本)
[root@docker1 ~]# sed -n '/root/p' test-nginx.confroot         /usr/share/nginx/html;
#        root         /usr/share/nginx/html;
[root@docker1 ~]#[root@docker1 ~]# sed -n '/^#.*root.*/p' test-nginx.conf
#        root         /usr/share/nginx/html;
[root@docker1 ~]#
[root@docker1 ~]# sed -n '/^ .*root.*/p' test-nginx.confroot         /usr/share/nginx/html;
[root@docker1 ~]#[root@docker1 ~]# sed -n 's,^ .*root.*$,        root /webdir;,p' test-nginx.confroot /webdir;
[root@docker1 ~]#

实验1,使用Dockerfile构建镜像:

在docker1:

基于nginx的基础镜像,修改网站根目录为/webdir

使用RUN命令修改主页index.html的内容为index

使用COPY命令添加页面page1.html和page2.html,内容分别为page1和page2

构建镜像名为nginx-test:v1,构建完镜像后,将镜像发送到docker2

在docker2:

导入镜像,并运行容器,将nginx的80端口映射到docker2的82端口

设置防火墙默认区域为public

验证效果:

在docker1:

Curl docker2ip:82--------index

Curl docker2ip:82/page1.html--------page1

Curl docker2ip:82/page2.html--------index2

[root@docker1 ~]# mkdir /webdir/
[root@docker1 ~]# echo page1 > /webdir/page1.html
[root@docker1 ~]# echo page2 > /webdir/page2.html
[root@docker1 ~]# vim /webdir/Dockerfile
[root@docker1 webdir]# cat Dockerfile 
FROM nginx:latest
RUN sed -i 's,^     .*root.*$,        root /webdir;,' /etc/nginx/conf.d/default.conf && mkdir /webdir && echo index > /webdir/index.html
COPY *.html /webdir
[root@docker1 webdir]#
[root@docker1 webdir]# docker build -t nginx-test:v1 .
[root@docker1 webdir]# docker image ls nginx-test
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
nginx-test   v1        6adced280b20   22 seconds ago   188MB
[root@docker1 webdir]#
[root@docker1 webdir]# docker run -d --name nginx-test1 --rm -p82:80 nginx-test:v1 
056ea76311defbdc06cc75a821f86c62224fc9cb4fbc3358c5f21dfe0d9114db
[root@docker1 webdir]# curl 127.0.0.1:82
index
[root@docker1 webdir]# curl 127.0.0.1:82/page1.html
page1
[root@docker1 webdir]# curl 127.0.0.1:82/page2.html
page2
[root@docker1 webdir]#

实验2使用scratch空白镜像创建一个镜像,并运行出容器,能查看执行命令的输出即可(+5/-0)

制作镜像时,可以将容器内的default.conf先复制出来,修改后使用COPY复制到容器指定位置,替换原来的配置文件

空白镜像:FROM scratch
[root@docker1 ~]# mkdir /hello-c
[root@docker1 ~]# cd /hello-c
[root@docker1 hello-c]# vim hello.c
[root@docker1 hello-c]# cat hello.c 
#include<stdio.h> 
int main(void)
{printf ("Hello world!\n");                 return 0;
}
[root@docker1 hello-c]# [root@docker1 hello-c]# yum -y install gcc gcc-c++ 安装编译工具
[root@docker1 hello-c]# gcc hello.c -o hello
[root@docker1 hello-c]# ls
hello  hello.c
[root@docker1 hello-c]#
[root@docker1 hello-c]# ./hello 
Hello world!
[root@docker1 hello-c]#

实验3

以centos的镜像为基础镜像,在其中安装httpd,添加apache的用户和组(如果没有的话)

同时在dockerfile中暴露80端口,编写index.html和page1.html拷贝至容器网站根目录

安装后编写ep.sh作为entrypoint要执行的脚本:参照redis编写

如果第一个参数是apache,则将所有的httpd相关的文件属主修改为apache

可修改/etc/httpd目录和/var/www/html目录下的所有文件的属主为apache

如果第一个参数是httpd,则运行httpd -D FOREGROUND启动httpd服务,如果第一个参数不是httpd,则将参数作为命令执行

[root@docker1 custom_httpd]# echo index > index.html
[root@docker1 custom_httpd]# echo page1 > page1.html
[root@docker1 ~]# mkdir /custom_httpd
[root@docker1 ~]# cd /custom_httpd
[root@docker1 custom_httpd]# cat ep.sh 
#! /bin/bash
if [ "$1" = 'httpd' ]; thenchown -R apache /etc/httpdchown -R apache /var/www/htmlhttpd -D FOREGROUNDfi
$@[root@docker1 custom_httpd]#
[root@docker1 custom_httpd]# chmod +x ep.sh
[root@docker1 custom_httpd]# cat Dockerfile 
FROM centos
RUN rm -rf /etc/yum.repos.d/* \&& curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-vault-8.5.2111.repo \&& yum -y install httpd \&& yum clean all
COPY ep.sh /
COPY *.html /var/www/html
EXPOSE 80
ENTRYPOINT ["/ep.sh"]
CMD ["httpd"][root@docker1 custom_httpd]#
[root@docker1 custom_httpd]# docker build -t myhttpd:v1 .[root@docker1 custom_httpd]# docker run --rm myhttpd:v1 id
uid=0(root) gid=0(root) groups=0(root)
[root@docker1 custom_httpd]# docker run -d --rm myhttpd:v1 httpd
f31efccb26405f73aaa0cc6ad6e6729947bc52b12e0a7dadc6df25128b9e25d8
[root@docker1 custom_httpd]# docker ps -a
CONTAINER ID   IMAGE        COMMAND          CREATED         STATUS         PORTS     NAMES
f31efccb2640   myhttpd:v1   "/ep.sh httpd"   3 seconds ago   Up 2 seconds   80/tcp    exciting_williams
[root@docker1 custom_httpd]#
[root@docker1 custom_httpd]# curl 172.17.0.2
index
[root@docker1 custom_httpd]# curl 172.17.0.2/page1.html
page1
[root@docker1 custom_httpd]# docker stop exciting_williams 
exciting_williams
[root@docker1 custom_httpd]#(
如果页面在容器生成,可修改Dockerfile如下:尽可能的减少层数
[root@docker1 custom_httpd]# cat Dockerfile
FROM centos
RUN rm -rf /etc/yum.repos.d/* \&& curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-vault-8.5.2111.repo \&& yum -y install httpd \&& yum clean all \&& echo index > /var/www/html/index.html \&& echo page1 > /var/www/html/page1.html 
COPY ep.sh /
EXPOSE 80
ENTRYPOINT ["/ep.sh"]
CMD ["httpd"][root@docker1 custom_httpd]# 
[root@docker1 custom_httpd]#
[root@docker1 custom_httpd]# docker build -t myhttpd:v1 .[root@docker1 custom_httpd]# docker run --rm myhttpd:v1 id
uid=0(root) gid=0(root) groups=0(root)
[root@docker1 custom_httpd]# docker run -d --rm myhttpd:v1 httpd
f31efccb26405f73aaa0cc6ad6e6729947bc52b12e0a7dadc6df25128b9e25d8
[root@docker1 custom_httpd]# docker ps -a
CONTAINER ID   IMAGE        COMMAND          CREATED         STATUS         PORTS     NAMES
f31efccb2640   myhttpd:v1   "/ep.sh httpd"   3 seconds ago   Up 2 seconds   80/tcp    exciting_williams
[root@docker1 custom_httpd]#
[root@docker1 custom_httpd]# curl 172.17.0.2
index
[root@docker1 custom_httpd]# curl 172.17.0.2/page1.html
page1
[root@docker1 custom_httpd]# docker stop exciting_williams 
exciting_williams
[root@docker1 custom_httpd]#(
如果页面在容器生成,可修改Dockerfile如下:尽可能的减少层数
[root@docker1 custom_httpd]# cat Dockerfile
FROM centos
RUN rm -rf /etc/yum.repos.d/* \&& curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-vault-8.5.2111.repo \&& yum -y install httpd \&& yum clean all \&& echo index > /var/www/html/index.html \&& echo page1 > /var/www/html/page1.html 
COPY ep.sh /
EXPOSE 80
ENTRYPOINT ["/ep.sh"]
CMD ["httpd"][root@docker1 custom_httpd]# 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/14981.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mybatis-plus 优雅的写service接口中方法(3)

多表联查 上文讲过了自定义sql &#xff0c;和wrapper的使用&#xff0c;但是我们可以发现 我们查询的都是数据库中的一张表&#xff0c;那么怎么进行多表联查呢&#xff0c;当然也是用自定义sql来进行实现 比如说 查询 id 为 1 2 4 的用户 并且 地址在北京 的 用户名称 普…

Elasticsearch不删原有jdk8导致的系列安装和启动问题

以前在空机器直接装elasticsearch&#xff0c;没有遇到什么问题。今天在现有JDK上安装&#xff0c;遇到的问题记录一下&#xff1a; 1. JDK的环境变量配置与我原有的不一致报如下错误&#xff1a; [estestZK-DES-I root]$ /usr/elasticsearch/bin/elasticsearch could not fi…

python-数据分析与可视化基础

1、data1.csv中的B、C、D和E列数据分别是日期、权重、A企业的销售额、B企业的销售额。读取C、D、E列数据,并统计E列数据的算术平均数、加权平均值(权值为C列数据)、方差、中位数、最小值、最大值。并绘制E列数据的直方图。 &#xff08;1&#xff09;源代码&#xff1a; impo…

什么生信流程语言让你极度爽?

生信流程搭建有多难&#xff1f;行业为解决这一问题提出了各种各样的配方&#xff0c;有你熟悉的吗&#xff1f; 一、困境 - 乱 无数机构投入大量人力物力&#xff0c;以期获得一条条可用的生信流程。而有些流程&#xff0c;由于种种原因&#xff0c;存在着巨大的缺陷&#xf…

安全风险 - 切换后台时背景模糊处理

因为安全风险中提到当app处于后台卡片状态时&#xff0c;显示的卡片页面应该为模糊效果&#xff0c;否则容易泄露用户隐私&#xff0c;尤其当前页涉及个人信息、资产信息等&#xff0c;都会造成信息泄露&#xff01;基于这种场景&#xff0c;我研究了下这种业务下的模糊效果 找…

普通函数的参数中的auto

2.1 普通函数的参数中的auto 从c14起&#xff0c;lambda可以使用auto占位符声明或者定义参数: auto printColl [] (const auto& coll) // generic lambda{ for (const auto& elem : coll) {std::cout << elem << \n;}} 只要支持Lambda 内部的操作&…

Golang创建文件夹

方法 package zdpgo_fileimport ("os" )// AddDir 创建文件夹 func AddDir(dir string) error {if !IsExist(dir) {return os.MkdirAll(dir, os.ModePerm)}return nil }测试 package zdpgo_fileimport "testing"func TestAddDir(t *testing.T) {data : […

JAVA云HIS医院系统源码 HIS源码:云HIS系统与SaaS的关系

云HIS系统与SaaS的关系 云HIS系统是一种基于云计算技术的医院信息系统&#xff0c;它采用B/S架构&#xff0c;通过云端SaaS服务的方式提供。用户可以通过浏览器访问云HIS系统&#xff0c;无需关注系统的部署、维护、升级等问题。云HIS系统通常具有模板化、配置化、智能化等特点…

hot100 -- 回溯(上)

目录 &#x1f35e;科普 &#x1f33c;全排列 AC DFS &#x1f6a9;子集 AC DFS &#x1f382;电话号码的字母组合 AC DFS &#x1f33c;组合总和 AC DFS &#x1f35e;科普 忘记 dfs 的&#xff0c;先看看这个&#x1f447; DFS&#xff08;深度优先搜索&#xf…

百度软件测试面试经历,期望薪资27K

一面 1、 请为百度搜索框设计测试用例&#xff1f; 2、百度设计框上线前需要进行那些测试&#xff1f; 界面测试&#xff0c;功能测试&#xff0c;性能测试&#xff0c;安全性测试&#xff0c;易用性测试&#xff0c;兼容性测试&#xff0c;UI测试。 3、如何查看http状态码…

重学java 38.创建线程的方式⭐

It is during our darkest moments that we must focus to see the light —— 24.5.24 一、第一种方式_继承extends Thread方法 1.定义一个类,继承Thread 2.重写run方法,在run方法中设置线程任务(所谓的线程任务指的是此线程要干的具体的事儿,具体执行的代码) 3.创建自定义线程…

基于灰狼优化算法优化支持向量机(GWO-SVM)回归预测

代码原理 基于灰狼优化算法优化支持向量机&#xff08;GWO-SVM&#xff09;的回归预测代码的原理和流程如下&#xff1a; 1. **初始化灰狼群体**&#xff1a;随机生成一定数量的灰狼&#xff0c;并初始化它们的位置和速度。 2. **初始化SVM模型参数**&#xff1a;根据问题要…

【JAVA基础之网络编程】UDP和TCP协议以及三次握手和四次挥手的过程

&#x1f525;作者主页&#xff1a;小林同学的学习笔录 &#x1f525;mysql专栏&#xff1a;小林同学的专栏 目录 1. 网络编程 1.1 概述 1.2 网络编程的三要素 1.2.1 IP地址 1.2.2 InetAddress 1.2.3 端口和协议 1.3 UDP协议 1.3.1 UDP发送数据 1.3.2 UDP接收数据 1.4…

C语言——小知识和小细节18

一、力扣题目 1、题目本体 2、题解 本题目我们使用异或分组的方法来解决。可以在我之前的文章《C语言——操作符CSDN博客》中看一下异或的特点。 由于异或的运算规则为相同为0&#xff0c;不同为1&#xff0c;而且是在二进制补码上进行操作的&#xff0c;我们可以发现的一个…

c++|多态

c|多态 1 多态的概念2 多态的定义及其实现2.1 满足多态的条件2.2 虚函数2.3 虚函数的重写2.4 析构函数适合加virtural吗2.4 C11 override 和 final2.5 三个概念的对比 3 多态的原理4 抽象类4.1 概念4.2 纯虚函数 1 多态的概念 多态的概念&#xff1a;通俗来说&#xff0c;就是…

【再探】设计模式—代理模式

代理是指授权代理人在一定范围内代表其向第三方进行处理有关事务。 1 代理模式 需求&#xff1a;1&#xff09;将业务代码与非业务代码分离&#xff0c;在不改变代码结构的基础上&#xff0c;为其添加新的功能。2&#xff09;为系统中的某些操作做同一处理&#xff0c;例如进…

[实例] Unity Shader 逐像素漫反射与半兰伯特光照

漫反射光照是Unity中最基本最简单的光照模型&#xff0c;本篇将会介绍在片元着色器中实现反射效果&#xff0c;并会采用半兰伯特光照技术对其进行改进。 1. 逐顶点光照与逐像素光照 在Unity Shader中&#xff0c;我们可以有两个地方可以用来计算光照&#xff1a;在顶点着色器…

z3-加法器实验

补码器加减法&#xff0c;运算方法简介 我们要知道什么是补码的加法&#xff0c;我们为什么要用补码的加法&#xff1f; 补码的加法其实就是将两个补码形式的二进制数字直接相加&#xff0c;处理的时候忽略超出固定位数的进位。补码的加法运算和无符号二进制数的加法操作一样&…

【最新区块链论文录用资讯】CCF A — SP 2024 共17篇

Conference&#xff1a;45th IEEE Symposium onSecurity and Privacy CCF level&#xff1a;CCF A Categories&#xff1a;网络与信息安全 Year&#xff1a;2024 Num&#xff1a;17 Efficient Zero-Knowledge Arguments For Paillier Cryptosystem Paillier 加密系统的有效…

基于python的网页自动刷新工具

1.下载webdriver https://msedgewebdriverstorage.z22.web.core.windows.net/?prefix122.0.2365.59/下载Edge的浏览器驱动 2.安装selenium pip install selenium4.11.1 3.写代码 # -*- coding: utf-8 -*- import tkinter as tk from tkinter import messagebox import thr…