Docker基础篇

感觉作为web负责人不会Docker是一件比较奇怪的事情,所以拿零碎的时间入门了一下Docker

安装

我这里用的是Centos系统

Install Docker Engine on CentOS | Docker Documentation

1、需要的安装包
yum install -y yum-utils
2、阿里云镜像
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
3、安装docker  ce社区版  ee企业版
yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin
4、启动docker
systemctl start docker
5、测试
docker run hello-world
6、查看当前镜像
docker images

卸载

yum remove docker-ce docker-ce-cli containerd.io
rm -rf /var/lib/docker
rm -rf /var/lib/containerd

docker执行流程

Docker基础篇_第1张图片

docker为什么比vm块

1、Docker有着比虚拟机更少的抽象层。

2、docker利用的是宿主机的内核,vm需要的是Guest OS

Docker基础篇_第2张图片

所以说,新建一个容器的时候,docker不需要像虚拟机一样重新加载一个操作系统内核,避免引导。虚拟机是加载Guest OS,分钟级别的,而docker是利用宿主机的操作系统吗,省略了这个复杂的过程,秒级!

Docker常用命令

帮助命令

docker version

docker 命令 --help

docker info

镜像命令

docker images 查看所有本地主机上的镜像文件

可选项

 -a --all  		#列出所有镜像
 -q --quiet 	#只显示镜像的id

docker search 搜索镜像

docker search mysql 搜索mysql镜像
# 可选项
-- filters=STARS=3000 #搜索出镜像stars大于3000的镜像

docker pull 下载镜像

docker pull mysql:5.7

docker rmi 删除镜像

docker rmi -f 容器id 				   #删除指定容器
docker rmi -f 容器id 容器id 容器id 	#删除多个指定容器
docker rmi -f $(docker images -aq)  #删除全部的容器

容器命令

有了镜像才能创建容器,下载centos镜像测试学习

docker pull centos

新建容器并启动

docker run [可选参数] image

#参数说明
--name="Name" 		容器名字 xxx01 xxx02,用来区分容器
-d					后台运行
-it					使用交互方式运行,进入容器查看内容
-p					指定容器的端口 -p 8080:8080
	-p ip:主机端口自:容器端口
	-p 主机端口:容器端口(常用)
	-p 容器端口
	容器端口
-P					随机指定端口

[root@VM-16-10-centos /]# docker run -it centos /bin/bash
[root@0c6ab50f2a8c /]# ls
bin  etc   lib    lost+found  mnt  proc  run   srv  tmp  var
dev  home  lib64  media       opt  root  sbin  sys  usr
[root@0c6ab50f2a8c /]# exit
exit
[root@VM-16-10-centos /]# ls
bin   data  etc   lib    log         media  opt    proc  run   srv  tmp  var
boot  dev   home  lib64  lost+found  mnt    patch  root  sbin  sys  usr  www

列出所有运行的容器

# docker ps 命令
		#列出当前正在运行的容器
-a  	#列出当前正在运行的容器+历史运行过的容器
-n=x	#列出最近创建的x条容器
-q		#只显示容器编号

退出容器

exit	#停止并退出容器
Ctrl + P + Q  #容器退出但不停止

删除容器

docker rm 容器id 					#删除指定的容器,不能删除正在运行的容器,若要强制删除rm -rf
docker rm -f $(docker ps -aq)	 #删除所有容器
docker ps -a -q|xargs docker rm  #删除所有容器

启动停止容器

docker start 容器id 		#启动融洽
docker restart 容器id 	#重启容器
docker stop 容器id		#停止容器
docker kill 容器id 		#强制停止当前容器

其他常用命令

后台启动容器

#命令 docker run -d 镜像名
[root@VM-16-10-centos /]# docker run -d centos
#问题docker ps,发现centos没有运行——docker容器后台运行后,就必须要有一个前台进程,docker若发现没有应用则会立即停止

查看日志

#命令 docker logs -f -t --tail n 容器id
-t		#时间戳
-f 		#跟踪日志输出
[root@VM-16-10-centos /]# docker logs -f -t --tail 10 7110c7daf02d

查看容器中进程信息

# 命令 docker top 容器id
[root@VM-16-10-centos /]# docker top 7110c7daf02d
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                6988                6968                0                   08:23               pts/0               00:00:00            /bin/bash

查看镜像的原数据

# 命令 docker inspect 容器id

进入当前正在运行的容器

# 命令
docker exec it 容器id bashshell
docker attach 容器id
# 测试
[root@VM-16-10-centos /]# docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED        STATUS        PORTS     NAMES
7110c7daf02d   centos    "/bin/bash"   24 hours ago   Up 24 hours             romantic_vaughan
[root@VM-16-10-centos /]# docker exec -it 7110c7daf02d /bin/bash
[root@7110c7daf02d /]# ls
bin  etc   lib    lost+found  mnt  proc  run   srv  tmp  var
dev  home  lib64  media       opt  root  sbin  sys  usr
[root@7110c7daf02d /]# exit
exit
[root@VM-16-10-centos /]# ls
bin   data  etc   lib    log         media  opt    proc  run   srv  tmp  var
boot  dev   home  lib64  lost+found  mnt    patch  root  sbin  sys  usr  www

# docker attch 容器id
# 若有正在运行的程序则attach会进入正在运行的程序,不会启动新进程

从容器内拷贝文件到主机

# 命令 docker cp 容器id:容器路径  主机路径
[root@7110c7daf02d /]# cd home
[root@7110c7daf02d home]# touch Sentiment.java
[root@7110c7daf02d home]# ls
Sentiment.java
[root@7110c7daf02d home]# exit
exit
[root@VM-16-10-centos /]# docker cp 7110c7daf02d:/home/Sentiment.java /home
[root@VM-16-10-centos /]# cd home
[root@VM-16-10-centos home]# ls
lighthouse  Sentiment.java  www

练习

docker安装nginx

[root@VM-16-10-centos ]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
Digest: sha256:b95a99feebf7797479e0c5eb5ec0bdfa5d9f504bc94da550c2f58e839ea6914f
Status: Image is up to date for nginx:latest
docker.io/library/nginx:latest

[root@VM-16-10-centos ]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
nginx        latest    2b7d6430f78d   13 days ago     142MB

[root@VM-16-10-centos ]# docker run -d --name nginx01 -p 7777:80 nginx
f955336f4e8a760d47fa0289e16825c56fe732c58d71f116c16aaef4dafab29d

[root@VM-16-10-centos ]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                                   NAMES
f955336f4e8a   nginx     "/docker-entrypoint.…"   5 seconds ago   Up 4 seconds   0.0.0.0:7777->80/tcp, :::7777->80/tcp   nginx01

[root@VM-16-10-centos ]# curl localhost:7777
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

[root@VM-16-10-centos ]# docker exec -it nginx01 /bin/bash

docker安装tomcat

之前出了道java题,借此用docker尝试部署一下

#安装tomcat9+jdk8
[root@VM-16-10-centos home]# docker pull tomcat:9-jdk8-temurin-focal
9-jdk8-temurin-focal: Pulling from library/tomcat
675920708c8b: Pull complete 
9f80c8980f9f: Pull complete 
ef18550d9ddf: Pull complete 
f9ef9c318985: Pull complete 
058be3f9fa17: Pull complete 
818a3c41a8e1: Pull complete 
c85727d6562f: Pull complete 
Digest: sha256:6ec577d3b8ab0623bb60d4cedc5bcc4d9a1ee06e4dfe5ff2ff015d3d14d65f58
Status: Downloaded newer image for tomcat:9-jdk8-temurin-focal
docker.io/library/tomcat:9-jdk8-temurin-focal

#启动tomcat
[root@VM-16-10-centos home]# docker run -d -p 7777:8080 --name tomcat01 tomcat:9-jdk8-temurin-focal
77485b64c75fea0a836672b191e792c61378623dab100c9619174b948d902f6e
[root@VM-16-10-centos home]# docker ps
CONTAINER ID   IMAGE                         COMMAND             CREATED         STATUS         PORTS                                       NAMES
77485b64c75f   tomcat:9-jdk8-temurin-focal   "catalina.sh run"   2 minutes ago   Up 2 minutes   0.0.0.0:7777->8080/tcp, :::7777->8080/tcp   tomcat01

#将本地文件传到webapps下
[root@VM-16-10-centos home]# docker cp /home/WarmJava_war_exploded/ 77485b64c75f:/usr/local/tomcat/webapps
[root@VM-16-10-centos home]# docker exec -it tomcat01 /bin/bash
root@77485b64c75f:/usr/local/tomcat# ls webapps
WarmJava_war_exploded

访问题中路由并传参

Docker基础篇_第3张图片

成功反弹shell

Docker基础篇_第4张图片

docker镜像

commit镜像

用commit命令提交自己的镜像,可以方便以后的使用,或将镜像打包给其他人

#命令
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]

测试

#启动之前的tomcat
[root@VM-16-10-centos ~]# docker start tomcat01
tomcat01
[root@VM-16-10-centos ~]# docker ps
CONTAINER ID   IMAGE                         COMMAND             CREATED        STATUS         PORTS                                       NAMES
77485b64c75f   tomcat:9-jdk8-temurin-focal   "catalina.sh run"   17 hours ago   Up 3 seconds   0.0.0.0:7777->8080/tcp, :::7777->8080/tcp   tomcat01

#commit 将修改好的tomcat打包
[root@VM-16-10-centos ~]# docker commit -m="Add Java Ctf" -a="Sentiment" 77485b64c75f tomcat1:1.0
sha256:8b280f81c6b1f788111844d60e6d21ae95b1fcaed2d4757a98a90b0eb18df497

#此时刚刚定义的tomcat1 成为了新的镜像
[root@VM-16-10-centos ~]# docker images
REPOSITORY   TAG                    IMAGE ID       CREATED         SIZE
tomcat1      1.0                    8b280f81c6b1   4 seconds ago   345MB
tomcat       9-jdk8-temurin-focal   05c35a4e6b74   4 days ago      342MB

容器数据卷

使用数据卷

方法一

命令挂载 -v

docker run it -v 主机目录:容器目录

#可以发现通过挂载后主机的home和docker容器中的home目录内容共享了
[root@VM-16-10-centos ~]# docker run -it -v /home:/home centos /bin/bash
[root@f6c0993fd2e5 /]# cd home
[root@f6c0993fd2e5 home]# ls
Sentiment.java  WarmJava_war_exploded  lighthouse  www
[root@f6c0993fd2e5 home]# exit
exit
[root@VM-16-10-centos ~]# ls /home
lighthouse  Sentiment.java  WarmJava_war_exploded  www

Mysql同步数据

docker run -d -p 7777:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7

挂载后此时在数据库中添加个test数据库,本地data中也就多了一个test目录

在这里插入图片描述

之后将数据库容器删除,但文件仍在本地保留

[root@VM-16-10-centos data]# docker rm -f mysql01
mysql01
[root@VM-16-10-centos data]# docker ps -a
CONTAINER ID   IMAGE     COMMAND       CREATED        STATUS                    PORTS     NAMES
f6c0993fd2e5   centos    "/bin/bash"   18 hours ago   Exited (0) 18 hours ago             ecstatic_vaughan
[root@VM-16-10-centos data]# ls
auto.cnf    ca.pem           client-key.pem  ibdata1      ib_logfile1  mysql       performance_schema  public_key.pem   server-key.pem  test
ca-key.pem  client-cert.pem  ib_buffer_pool  ib_logfile0  ibtmp1       mysql.sock  private_key.pem     server-cert.pem  sys

具名挂载和匿名挂载

[root@VM-16-10-centos ~]# docker run -d -P --name nginx01 -v /etc/nginx nginx
[root@VM-16-10-centos ~]# docker volume ls
DRIVER    VOLUME NAME
local     674500de4c3a5a344fbac4b4e097b8c49c48c67a4787faf0aa9afc59c7c8d640

[root@VM-16-10-centos ~]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
b6ec76db6e9b5a5bb05ce4cb94ffc9ead91305680313d362817e71f38318cecc
[root@VM-16-10-centos ~]# docker volume ls
DRIVER    VOLUME NAME
local     juming-nginx

[root@VM-16-10-centos ~]# docker volume inspect juming-nginx
[
    {
        "CreatedAt": "2022-09-10T16:09:42+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
        "Name": "juming-nginx",
        "Options": null,
        "Scope": "local"
    }
]

所有的docker容器内的卷,没有指定目录的情况下都是在/var/lib/docker/volumes/xxx/_data

我们通过具名挂载可以方便的找到我们的一个卷,大多数情况使用具名挂载

-v 容器内路径 		 #匿名挂载
-v 卷名:容器内路径 	# 具名挂载
-v /宿主机路径::容器内路径 #指定路径挂载

扩展:

# 通过 -v 容器内路径:ro rw改变读写权限
ro 		#只读
rw 		#可读可写

#一旦设置了容器权限,容器对我们挂载出来的内容就有限定了
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx

#ro 只要看到ro就说明这个路径只能通过宿主机来操作,容器内无法操作

初识dockerfile

Dockerfile就是用来构建docker镜像的构建文件

#dockerfile内容 指令(大写)
FROM centos

VOLUME ["volume01","volume02"]

CMD echo "----end----"

CMD /bin/bash 

执行dockerfile

Docker基础篇_第5张图片

启动自己写的容器

Docker基础篇_第6张图片

在卷中创建一个文件

[root@843d3ff7753c volume01]# touch test.txt
[root@843d3ff7753c volume01]# ls
test.txt

docker inspect 查看当前容器信息,发现了刚才挂载的两个卷

Docker基础篇_第7张图片

切换到volume01目录,发现刚才创建的文件

在这里插入图片描述

数据卷容器

–volumes-from

Docker基础篇_第8张图片

启动容器docker02通过–volumes-from继承docker01的数据卷

Docker基础篇_第9张图片

此时如果在docker01的数据卷中创建文件,会直接共享到docker02的volume01中,并且这属于一种拷贝,当docker01被删除后docker02的数据仍然存在

Dockerfile

构建步骤

1、编写一个 dockerfile 文件

2、docker build 构建成为一个镜像

3、docker run 运行镜像

4、docker push 发布镜像(DockerHub、阿里云镜像仓库)

基础知识

1、每个保留关键字(指令)都必须是大写

2、执行从上到下顺序执行

3、#代表注释

4、每一个指令都会创建提交一个新的镜像层,并提交

Dockerfile指令

FROM			# 基础镜像,一切从这里开始构建
MAINTAINER		# 构建镜像的作者,姓名+邮箱
RUN				# 镜像构建的时候需要运行的命令
ADD				# 步骤:tomcat镜像,这个tomncat压缩包,谭家内容
WORKDIR			# 镜像的工作目录
VOLUME			# 挂载的目录
EXPOSE 			# 对外端口设置
CMD				# 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被代替
ENTRYPOINT  	# 指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD			# 当构建一个被继承 Dockerfile 这个时候就会运行 ONBUILD 的命令,触发指令。
COPY			# 类似ADD,将我们文件拷贝到镜像中
ENV				# 构建的时候设置的环境变量

创建centos

FROM centos
MAINTAINER Sentiment<1509041516@qq.com>

ENV MYPATH /usr/local
WORKDIR MYPATH

RUN yum -y install vim
RUN yum -y install net-tools

EXPOSE 80

CMD echo $MYPATH
CMD echo ---- end ----
CMD /bin/bash 

Docker基础篇_第10张图片

CMD和ENTRPOINT区别

CMD测试

定义CMD后运行,直接输出了ls -a 的内容

Docker基础篇_第11张图片

若此时想追加l 即:ls -al,用cmd的方式只能替换:

docker run cmdtest ls -al

ENTRYPOINT测试

同理运行后执行ls -a

Docker基础篇_第12张图片

但此时若想 执行ls -al只需要在后边追加l即可:

docker run entrypoint-test -l

练习

dockerfile制作tomcat镜像

1、准备镜像文件tomcat压缩包和jdk压缩包

[root@VM-16-10-centos tomcat]# ls
apache-tomcat-9.0.65.tar.gz 
jdk-8u65-linux-x64.tar.gz

2、编写dockerfile文件,官方命名问dockerfile,使用该命名后build时会自动寻找这个文件,不再需要加- f

FROM centos
MAINTAINER sentiment<1509041516@qq.com>

ADD jdk-8u65-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.65.tar.gz /usr/local/


ENV MYPATH /usr/local
WORKDIR $MYPATH

ENV JAVA_HOME /usr/local/jdk1.8.0_65
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.65
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.65
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

EXPOSE 8080

CMD /usr/local/apache-tomcat-9.0.65/bin/startup.sh &&tail -F /usr/local/apache-tomcat-9.0.65/bin/logs/catalina.out

3、构建镜像

docker build -t idytomcat

4、启动镜像

docker run -d -p 4000:8080 --name sentimenttomcat -v /dockerfile/tomcat/test:/usr/local/apache-tomcat-9.0.65/webapps/test -v /dockerfile/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.65/logs diytomcat

5、访问4000端口测试

6、发布项目,在test目录下创建index.jsp和WEB-INF文件夹以及对应的web.xml

xml


<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    version="3.1">
web-app>

jsp

<html>
<head>
    <title>Tomcattitle>
head>
<body>
<h2>Hi,Sentiment!h2>
body>
html>

此时访问test目录

Docker基础篇_第13张图片

发布镜像

docker login 

输入账号密码后可以登录自己的dockerhub,之后就可以通过docker push命令 上传我们的镜像

docker push sentiment/diytomcat:1.0
The push refers to repository [docker.io/sentiment/diytomcat]
An image does not exist locally with the tag: sentiment/diytomcat

这里报错 tag有问题,所以尝试修改一下,修改后成功上传

Docker基础篇_第14张图片

Docker网络

理解Docker0

先清除所有镜像和容器

docker rmi -f $(docker images -aq) 
docker ps -a -q|xargs docker rm

Docker基础篇_第15张图片

启动一个tomcat容器,查看IP地址

#启动docker容器
[root@VM-16-10-centos /]# docker run -d -P --name=tomcat01 tomcat

#执行ip addr后报错:没有命令
[root@VM-16-10-centos /]# docker exec -it tomcat01 ip addr
OCI runtime exec failed: exec failed: unable to start container process: exec: "ip": executable file not found in $PATH: unknown

#所以先进入容器,下载基础命令
[root@VM-16-10-centos /]# docker exec -it tomcat01 /bin/bash
root@6cd0a231ba62:/usr/local/tomcat# ip addr
bash: ip: command not found
root@6cd0a231ba62:/usr/local/tomcat# apt update && apt install -y iproute2

此时执行ip addr,发现了两个地址 lo 和eth0,其中eth0就是docker为各容器分配的,可以看到 docker0的ip地址为:172.17.0.1 ,启动的tomcat01容器分配的地址为:172.17.0.2,这两个ip在同一网段。

Docker基础篇_第16张图片

此时用本机ping容器,发现也是可以ping通的

再输入 ip addr 可以发现多了一对网卡和上面启动的tomcat01容器相对应

在这里插入图片描述

  • 我们只要安装了docker,就会有一个网卡(docker0),网络模式为桥接模式,使用的是 evth-pair技术;
  • 每启动一个容器docker就会为它分配一个IP地址,对应的也会多一对网卡(本机是@if92,容器内是@if93)!
  • 容器和linux主机可以ping通,而且每个容器之间也可以通过ip地址ping通。

网络模型

02ping03时,相当于通过01路由器转发到了03

Docker基础篇_第17张图片

Docker基础篇_第18张图片

容器互联–link

容器之间通过ip地址能ping通,但是通过容器名是无法ping通的

Docker基础篇_第19张图片

所以这时就需要使用–link解决此问题

docker run -d -P --name tomcat03 --link tomcat02 tomcat

此时03就能通过容器名ping通02了,但是02不能ping03,后来查看hosts文件发现是因为03的hosts文件中写入了02所以能ping通

Docker基础篇_第20张图片

自定义网络

查看docker中的所有网络

Docker基础篇_第21张图片

#通过命令创建一个自己的网络
[root@VM-16-10-centos ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
ed14e1ecebb9c311ddecc3670f5c6e0429e84a46181ccbf9ff997e6ec9c07441

#查看网络
[root@VM-16-10-centos ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
760dea8f9135   bridge    bridge    local
fa5c4ad578ff   host      host      local
ed14e1ecebb9   mynet     bridge    local
531177f2dd44   none      null      local

#查看网络配置
[root@VM-16-10-centos ~]# docker network inspect mynet

Docker基础篇_第22张图片

#使用自定义网络创建容器
[root@VM-16-10-centos ~]# docker run -d -P --name=tomcat01-net --net mynet tomcat
4af4c548f11381f6fcf736d2fa5417ca216d134bc51635fc1aa681cde8f4fc02
[root@VM-16-10-centos ~]# docker run -d -P --name=tomcat02-net --net mynet tomcat
cf59546f20cbfd9c660142f5464a95250b7aa6e0bb1b872245a88a3cc1f6636e

通过自定义网络方式,能直接实现容器间的网络连接,就不在需要通过–link,

docker exec -it tomcat01-net ping tomcat02-net

网络连通

启动之前定义的docker0网络镜像tomcat03

此时用tomcat03 ping mynet网络的容器是ping不通的,但是可以通过 connect命令进行连通

#connect连通
docker network connect mynet tomcat03

#ping测试
docker exec -it tomcat03 ping tomcat01-net
PING tomcat01-net (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat01-net.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.101 ms
64 bytes from tomcat01-net.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.066 ms

此时执行docker network inspect mynet,发现mynet中多了tomcat03的网络

Docker基础篇_第23张图片

你可能感兴趣的:(Docker,docker,运维,linux)