从零开始学Docker

1 篇文章 0 订阅
1 篇文章 0 订阅

从零开始学Docker

Docker的安装

查看centos版本(Docker 要求CentOS系统的内核版本高于3.10)
[root@dawn ~]# uname -r
3.10.0-1062.12.1.el7.x86_64
升级软件包及内核
[root@dawn ~]# yum update
安装Docker
[root@dawn ~]# yum install docker
启动Docker
systemctl start docker
开机自动启动Docker
systemctl enable docker
关闭Docker
systemctl  stop docker

Docker的常用命令

在这里插入图片描述

帮助命令
docker version				#显示docker的版本信息
docker info					#显示docker的系统信息,包括镜像和容器信息
docker 命令 --help			#帮助命令

帮助文档的地址:https://docs.docker.com/engine/reference/commandline/docker/

镜像命令
docker images 查看主机所有镜像
## 可选项
 - -a,--all					#列出所有镜像
 - -q,--quiet				#只显示出镜像的id 
 
## 解释
 - RePOSITORY				#镜像的仓库源
 - TAG						#镜像的标签
 - IMAGE ID					#镜像的id
 - CREATED					#镜像的创建时间
 - SIZE						#镜像的大小
docker search 搜索镜像
docker search mysql
## 可选项,通过搜索来过滤
 - --filter=STARS=3000 
## 搜索出来的镜像就是STARS大于3000的
	docker search mysql --filter=STARS=3000
docker pull 下载镜像
##	下载镜像 docker pull 镜像名[:tag]
 - docker pull mysql		#如果不写tag,默认下载latest
 - docker pull mysql:5.7	#指定版本下载
docker rmi 删除镜像
docker rmi -f 容器id					#删除指定的容器
docker rmi -f 容器id 容器id 			#删除多个容器,空格分隔
docker rmi -f $(docker images -aq)	# 删除全部的容器
容器命令

说明:我们有了镜像才可以创建容器,linux,下载一个centos镜像来测试学习

docker pull centos
新建容器并启动
docker run [可选参数] image
# 参数说明
 - --name="Name"		容器名字  tomcat01  tomcat01, 用来区分容器
 - -d					后台方式运行
 - -it					使用交互方式运行,进入容器查看内容
 - -p					指定容器的端口 -p 8080:8080
 		-p ip: 主机端口:容器端口
 		-p	主机端口:容器端口(常用) 
		-p	容器端口
 - -P					随机指定端口

# 测试,启动并进入容器
[root@dawn /]# docker run -it centos:7 /bin/bash
[root@123066df2102 /]# ls    
anaconda-post.log  bin  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

退出容器
exit			#直接停止容器并退出
Ctrl + p + q	#容器不停止退出 
列出所有运行的容器
docker ps 命令
 -		#列出当前正在运行的容器
 - -a	#列出当前正在运行的容器+运行过的容器
 - -n=?	#显示最近创建的容器
 - -q	#只显示容器的编号
删除容器
docker rm 容器id						#删除指定的容器,不能删除正在运行的容器,如果是强制删除 rm -f
docker rm $(docker ps -aq)			#删除所有的容器
docker ps -a -q|xargs docker rm		#删除所有的容器
启动和停止容器的操作
docker start 容器id		#启动容器
docker restart 容器id	#重启容器
docker stop	容器id		#停止当前正在运行的容器
docker kill 容器id		#强制停止当前容器

Docker的其他命令

后台启动容器
# 命令 docker run -d 镜像名!
[root@dawn /]# docker run -d centos:7
ff50f950600a2498860fad73a375090a7c3ac165bcff3a0ead5313ba1073939d
[root@dawn /]# docker ps

# 问题docker ps,发现 centos 停止了
# 城建的坑, docker 容器使用后台进行,就必须要有一个前台进程,docker发现没有应用,就会自动停止
# nginx,容器启动后,发现自己没有提供服务就会以为没有程序了,就会立即停止
查看日志
docker logs -tf --tall 10 容器id
# 显示日志

 - -tf				#显示日志
 - --tail number	#显示日志条数
查看容器中进程信息
# docker top 容器id
[root@dawn /]# docker top 123066df2102
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                10218               10202               0                   11:02               pts/0               00:00:00            /bin/bash
查看镜像元数据
#命令
docker inspect 容器id

[root@dawn /]# docker inspect 123066df2102
[
    {
        "Id": "123066df21023544dc65329734fb184c04c2d0dc66f21992f9788a5a05d5dd47",
        "Created": "2020-11-26T02:25:01.792197429Z",
        "Path": "/bin/bash",
        "Args": [],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 10218,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2020-11-26T03:02:54.008546447Z",
            "FinishedAt": "2020-11-26T02:38:40.78598665Z"
        },
        "Image": "sha256:8652b9f0cb4c0599575e5a003f5906876e10c1ceb2ab9fe1786712dac14a50cf",
        "ResolvConfPath": "/var/lib/docker/containers/123066df21023544dc65329734fb184c04c2d0dc66f21992f9788a5a05d5dd47/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/123066df21023544dc65329734fb184c04c2d0dc66f21992f9788a5a05d5dd47/hostname",
        "HostsPath": "/var/lib/docker/containers/123066df21023544dc65329734fb184c04c2d0dc66f21992f9788a5a05d5dd47/hosts",
        "LogPath": "/var/lib/docker/containers/123066df21023544dc65329734fb184c04c2d0dc66f21992f9788a5a05d5dd47/123066df21023544dc65329734fb184c04c2d0dc66f21992f9788a5a05d5dd47-json.log",
        "Name": "/stoic_knuth",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": null,
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "default",
            "PortBindings": {},
            "RestartPolicy": {
                "Name": "no",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "CapAdd": null,
            "CapDrop": null,
            "Capabilities": null,
            "Dns": [],
            "DnsOptions": [],
            "DnsSearch": [],
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "private",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "ConsoleSize": [
                0,
                0
            ],
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": [],
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": [],
            "DeviceCgroupRules": null,
            "DeviceRequests": null,
            "KernelMemory": 0,
            "KernelMemoryTCP": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": false,
            "PidsLimit": null,
            "Ulimits": null,
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0,
            "MaskedPaths": [
                "/proc/asound",
                "/proc/acpi",
                "/proc/kcore",
                "/proc/keys",
                "/proc/latency_stats",
                "/proc/timer_list",
                "/proc/timer_stats",
                "/proc/sched_debug",
                "/proc/scsi",
                "/sys/firmware"
            ],
            "ReadonlyPaths": [
                "/proc/bus",
                "/proc/fs",
                "/proc/irq",
                "/proc/sys",
                "/proc/sysrq-trigger"
            ]
        },
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/3bffcf81d93ab1e3c1815077352287e44434ab01ba34991ec3394b557266cbfe-init/diff:/var/lib/docker/overlay2/ddd4290a76fdaa5ba65393d2b59b979a0d6daf3a1b5c3b3967901bc29c70bf47/diff",
                "MergedDir": "/var/lib/docker/overlay2/3bffcf81d93ab1e3c1815077352287e44434ab01ba34991ec3394b557266cbfe/merged",
                "UpperDir": "/var/lib/docker/overlay2/3bffcf81d93ab1e3c1815077352287e44434ab01ba34991ec3394b557266cbfe/diff",
                "WorkDir": "/var/lib/docker/overlay2/3bffcf81d93ab1e3c1815077352287e44434ab01ba34991ec3394b557266cbfe/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [],
        "Config": {
            "Hostname": "123066df2102",
            "Domainname": "",
            "User": "",
            "AttachStdin": true,
            "AttachStdout": true,
            "AttachStderr": true,
            "Tty": true,
            "OpenStdin": true,
            "StdinOnce": true,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/bash"
            ],
            "Image": "centos:7",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "org.label-schema.build-date": "20201113",
                "org.label-schema.license": "GPLv2",
                "org.label-schema.name": "CentOS Base Image",
                "org.label-schema.schema-version": "1.0",
                "org.label-schema.vendor": "CentOS",
                "org.opencontainers.image.created": "2020-11-13 00:00:00+00:00",
                "org.opencontainers.image.licenses": "GPL-2.0-only",
                "org.opencontainers.image.title": "CentOS Base Image",
                "org.opencontainers.image.vendor": "CentOS"
            }
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "4dc97ef13891a406ba86760b0b736bf8488c971080fb98d15ed1a37d2deb263c",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "/var/run/docker/netns/4dc97ef13891",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "f729f565726f7a3d5ea8e36a2947bf38e8a8ed6c8184c4b16f3971823d3ebde5",
            "Gateway": "172.17.0.1",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.17.0.2",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "02:42:ac:11:00:02",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "58388b98caaa30951f981df32ddccffd9cb445ee2b26bf5b09e4e55b893f59e9",
                    "EndpointID": "f729f565726f7a3d5ea8e36a2947bf38e8a8ed6c8184c4b16f3971823d3ebde5",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:02",
                    "DriverOpts": null
                }
            }
        }
    }
]

进入当前正在运行的容器
# 我们通常容器都是使用后台方式运行的,需要进入容器,修改一些配置

# 命令

 - 方式一:	docker exec -it 容器id /bin/bash 
 - 方式二:	docker attach 容器id	
	
# docker exec		# 进入容器后开启一个新的终端,可以在里面操作(常用)
# docker attach		# 进入容器正在执行的终端,不会启动新的进程
从容器内拷贝文件到主机上
docker cp 容器id:容器内路径  目的主机路径
# 拷贝是一个手动过程,未来可以使用 -v 卷的技术,可以实现

Docker练习

部署Nginx
  • 搜索镜像,search 建议去docker搜索,可以看到文档帮助
  • 下载镜像 pull
[root@dawn /]# docker pull nginx
  • 运行测试
 	[root@dawn /]# docker run -d --name nginx01 -p 3344:80 nginx
 	# -d 后台运行
 	# --name 给容器命名
 	# -p 宿主机端口,容器内部端口
  • 进入容器
   [root@dawn /]# docker exec -it nginx01 /bin/bash
   root@271a455fce1b:/# whereis nginx
   nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
   root@271a455fce1b:/# ls
   bin   dev		   docker-entrypoint.sh  home  lib64  mnt  proc  run   srv  tmp  var
   boot  docker-entrypoint.d  etc			 lib   media  opt  root  sbin  	sys  usr
   root@271a455fce1b:/# 
  • 外网访问在这里插入图片描述
部署tomcat
  • 下载tomcat
[root@dawn /]# docker pull tomcat
  • 启动运行
[root@dawn /]# docker run -d  --name nginx01 -p 3344:80 nginx
  • 外网访问
    在这里插入图片描述
  • 进入容器
[root@dawn /]# docker exec -it nginx01 /bin/bash

发现问题,1.linux命令少了。2.没有webapps.阿里云镜像的原因。默认是最小的镜像,所以不必要的都剔除掉。保证最小的运行环境

部署 es + kibana

es 暴露的端口很多 -9200、9300
es 十分的耗内存 - “ES_JAVA_OPTS=-Xms512m -Xmx512m”
es 的数据一般需要放置到安全目录!挂载data、plugins、conf

  • 扩展命令
docker stats 容器id         # 查看容器的cpu内存和网络状态
  • 直接运行es测试

(–net somenetwork ? 网络配置)
9200作为Http协议,主要用于外部通讯( ES节点 和 外部 通讯使用 )
9300作为Tcp协议,jar之间就是通过tcp协议通讯( ES节点之间通讯使用 )

[root@dawn /]# docker run --name es01  -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node"  elasticsearch:7.6.2
  • 启动后发下很卡
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
ba236371acd0        elasticsearch       0.32%               1.226GiB / 3.7GiB   33.12%              0B / 0B             0B / 0B             43
  • 增加上内存限制启动
[root@dawn /]# docker run -d --name es01 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2

  • 启动之后,使用 docker stats 查看下cpu状态
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
179b21241d90        es01                0.72%               342MiB / 1.7GiB     9.02%               0B / 0B             0B / 0B             44
  • 测试es是否成功
[root@dawn /]# curl localhost:9200
{
  "name" : "57bb765ae7f9",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "pPMOBwVzTgyIMBJdz6ujNQ",
  "version" : {
    "number" : "7.6.2",
    "build_flavor" : "default",
    "build_type" : "docker",
    "build_hash" : "ef48eb35cf30adf4db14086e8aabd07ef6fb113f",
    "build_date" : "2020-03-26T06:34:37.794943Z",
    "build_snapshot" : false,
    "lucene_version" : "8.4.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}
  • 使用kibana连接es

正在思考

在这里插入图片描述

容器数据卷

docker的理念回顾
将应用和环境打包成一个镜像
容器之间可以有一个数据共享的技术,Docker容器中产生的数据同步到本地。这就是卷的技术,目录的挂在,将我们容器内的目录,挂载到Linux上上面。

总结一句话:容器的持久化和同步操作!容器间也是可以数据共享的!

在这里插入图片描述

使用数据卷

方式一:直接使用命令来挂在 -v

# 测试
[root@dawn /]# docker run -it -v /home/ceshi:/home centos /bin/bash
# 启动起来时候我们可以通过 docker inspect 容器id

在这里插入图片描述
测试文件同步(停止容器,在宿主机修改文件,容器内的文件依旧同步)
在这里插入图片描述

实战:安装MySql

思考:MySql 的数据持久化问题

  • 获取镜像
[root@dawn ~]# docker pull  mysql:5.7
  • 运行容器

运行容器需要做数据挂载。 安装启动MySql,需要配置密码
官方测试, docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
注意
-d 后台运行
-p 端口映射
-v 卷挂载
-e 环境配置
–name 容器名字

[root@dawn /]# docker run -d -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf -v /home/mysql/conf -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysqltest  mysql:5.7

启动成功之后,我们在本地使用数据库客户端 来连接测试一下,注意打开安全组
连接到服务器的3306端口 和容器的3306端口映射,我们连接上了
在本地创建一个数据库,查看一下我们的映射路径是否ok!
在这里插入图片描述
在这里插入图片描述

具名挂载和匿名挂载
  • 匿名挂载
-v 容器内路径
[root@dawn /]# docker run -d -P --name nginx01 -v /ect/nginx nginx
20732ef060165cfd2f6dee1890b5be775c06db5bee00c871112a079a7e9e3185
# 查看所有的volume 的情况
[root@dawn /]# docker volume ls
DRIVER              VOLUME NAME
# 这里发现,这种就是匿名挂载,我们在 -v 只写了容器内路径
local               ee2f8fc49acdde5dacb4d63a7625ce3bf29dd6d6fa592bb5b4d3da2f7e855060
local               fc6c71802abd65ab382879869a0df942fdbba2a5105b5d5e6631062a08ef31c2

  • 具名挂载(推荐)
# 通过 -v 卷名:容器内路径
[root@dawn /]# docker run -d -P --name nginx02 -v juming-nginx:/ect/nginx nginx
d34b1f3bb27edf0c9ad0e2399250b08152ed4f99fc78b5796ae86ef7878a2b33
[root@dawn /]# docker volume ls
DRIVER              VOLUME NAME
local               ee2f8fc49acdde5dacb4d63a7625ce3bf29dd6d6fa592bb5b4d3da2f7e855060
local               fc6c71802abd65ab382879869a0df942fdbba2a5105b5d5e6631062a08ef31c2
local               juming-nginx

# 查看一下这个卷
[root@dawn /]# docker volume inspect juming-nginx
[
    {
        "CreatedAt": "2020-11-27T10:53:12+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/xxxx/_data
[root@dawn /]# cd /var/lib/docker/volumes/   
[root@dawn volumes]# ls
ee2f8fc49acdde5dacb4d63a7625ce3bf29dd6d6fa592bb5b4d3da2f7e855060  juming-nginx
fc6c71802abd65ab382879869a0df942fdbba2a5105b5d5e6631062a08ef31c2  metadata.db

我们通过具名挂载可以方便的找到我们的一个卷。

如何确定是剧名挂载还是匿名挂在,还是指定路径挂载
-v 容器内路径 # 匿名挂在
-v 卷名:容器内路径 # 具名挂载
-v /宿主机路径:容器内路径 # 指定路径挂载

拓展

通过 -v 容器内路径,ro rw 改变读写权限
ro readonly # 只读
rw readwrite # 可读可写
一旦这个设置了容器权限,容器对我们挂在出来的内容就有了限定
ro 只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法操作的

docker run -d -P --name nginx02 -v juming-nginx:/ect/nginx:rw nginx
docker run -d -P --name nginx02 -v juming-nginx:/ect/nginx:ro nginx

初识Dockerfile

创建自己的容器

Dockerfile 就是用来构建docker 镜像的构建文件,命令脚本。
通过这个脚本可以生成镜像,镜像是一层一层的,脚本一个个的命令,每个命令都是一层!

# 创建一个dockerfile文件,建议 Dockerfile
# 文件中的的内容  指令(大写) 参数
FROM centos
VOLUME ["volume01","volume02"]
CMD echo "----end----"
CMD /bin/bach

在这里插入图片描述

启动自己的容器

在这里插入图片描述
这个卷和外部一定有一个同步目录
在这里插入图片描述
匿名挂载,查看一下卷挂载的路径
在这里插入图片描述
测试一下刚才的文件是否同步出去了。
这种方式我们使用的很多,假设构建镜像的时候没有挂载卷,哟啊手动镜像挂载 -v 卷名:容器内路径

数据卷容器

–volumes-form

多个 mysql 同步数据
在这里插入图片描述

# 启动容器
[root@dawn /]# docker run -it --name docker01 down/centos /bin/bash
[root@00865e79e4dd /]# [root@dawn /]# 

# 启动第二个容器
[root@dawn /]# docker run -it --name docker02 --volumes-from docker01 down/centos /bin/bash
[root@d86228473db2 /]# ls

# 启动第三个容器
[root@dawn ~]# docker run -it --name docker03 --volumes-from docker02 down/centos /bin/bash
[root@3350eb0b2956 /]# ls

删除一个容器,其他容器数据并不影响
在这里插入图片描述

多个mysql实现数据共享
docker run -d -p 3306:3306 -v /etc/mysql/conf -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysqltest  mysql:5.7

docker run -d -p 3307:3306 -v /etc/mysql/conf -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysqltest --volumes-form mysql:5.7
结论

容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用位置。
但是一旦你持久化到本地,这个时候,本地的数据是不会删除的!

DockerFile

dockerfile 是用来构建docker镜像的文件!命令参数脚本!
构建步骤:

  1. 编写一个 dokerfile 文件
  2. docker build 构建成为一个镜像
  3. docker run 运行镜像
  4. docker push 发布镜像(DockerHub、阿里云镜像仓库)

很多官方镜像都是基础包,很多功能没有,我们通常会自己搭建自己的镜像

DicjerFile 构建过程

基础知识

  1. 每个保留关键字(指令)都必须是大写字母
  2. 按照从上到下顺序执行
  3. 表示注释
  4. 每一个指令都会创建提交一个新的镜像层,并提交

dockerfile 是面向开发的,我们以后发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单

Docker镜像逐渐成为企业交付的标准,必须要掌握
步骤:开发,部署,运维。。。缺一不可
DockerFile:构建文件,定义了一切的步骤,源代码
DockerImages:通过DockerFile 构建生成的镜像,最终发布和运行的产品
Docker容器:容器就是镜像运行起来提供的服务器

DockerFile 的指令

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

Docker Hub 中 99% 镜像都是从这个基础镜像过来的 FROM scratch ,然后配置需要的软件和配置进行构建的

创建一个自己的centos

# 1. 编写Dockerfile的文件
FROM centos
MAINTAINER dawn<1114613633@qq.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN yum -y install vm
RUN yum -y install net-tools
EXPOSE 80
CMD echo $MYPATH
CMD echo "---end---"
CMD /bin/bash

 # 2. 通过这个文件构建镜像
 # 命令 docker build -f dockerfile文件名 -t 镜像名:[tag]
 docker build -f my_centos -t mycentos:1.0 .
 
 # 3. 测试运行

对比:之前的原生的centos
在这里插入图片描述
我们增加之后的镜像
在这里插入图片描述
我们还可以列出本地镜像的变更历史
在这里插入图片描述
我们平时拿到一个镜像时,可以研究一下它是怎么做的

实战:Dockerfile制作tomcat+jdk 镜像
  1. 准备镜像文件 tomcat 压缩包,jdk压缩包
  2. 编写dockerfile文件,官方命名Dockerfile,build 会自动秀找这个文件,就不需要-f 指定了
FROM centos
MAINTAINER dawn<1114613633@qq.com>
ADD jdk-8u212-linux-x64.tar.gz /usr/local
ADD apache-tomcat-9.0.39.tar.gz /usr/local

RUN yum -y install vim

ENV MYPATH /usr/local
WORKDIR $MYPATH
# jdk 环境配置
ENV JAVA_HOME /usr/local/jdk1.8.0_212
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
# tomcat 环境配置
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.39
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.39

ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

EXPOSE 8080

CMD /usr/local/apache-tomcat-9.0.39/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.39/bin/logs/catalina.out
  1. 构建镜像
[root@dawn tomcatDemo]# docker build -t my_tomcat .
  1. 启动镜像
[root@dawn /]# docker run -d -p 9090:8080 --name my_tomcat_01 -v /data/docker/mount/my_tomcat/text:/usr/local/apache-tomcat-9.0.39/webapps/test -v /data/docker/mount/my_tomcat/logs/:/usr/local/apache-tomcat-9.0.39/logs my_tomcat

  1. 访问测试
curl localhost:9090
http://toneystk.cn:9090/
  1. 发布项目(由于做了卷挂载,我们直接在本地编写项目就可以发布了)
# WEB-INF/web.xml
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    version="2.4">

    <description>
      JSP 2.0 Examples.
    </description>
    <display-name>JSP 2.0 Examples</display-name>
</web-app>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
		<!DOCTYPE html>
		<html>
			<head>
				<meta charset="utf-8">
				<title>hello dawn</title>
			</head>
			<body>
			Hello World!<br/>
			<%
			System.out.println("hello dawnnnnn");
			%>
			</body>
		</html>

发布自己的镜像

DockerHub

  • 地址:https://hub.docker.com/ 注册自己的账号
  • 确定这个账号可以登录
  • 在我们的服务器上提交自己的镜像
[root@dawn ~]# docker login --help

Usage:	docker login [OPTIONS] [SERVER]

Log in to a Docker registry.
If no server is specified, the default is defined by the daemon.

Options:
  -p, --password string   Password
      --password-stdin    Take the password from stdin
  -u, --username string   Username

在这里插入图片描述

  • 登录完毕后就可以发布镜像了
# push 自己的镜像到服务器上,增加一个tar
# docker tag 镜像id 名称:[tar]
# 自己发布的镜像,尽量带上版本号 
docker tag 2ljweq21 dawn/my_tomcat:1.0

# 提交的时候也是按照镜像的层级来进行提交的
发布到阿里云镜像

Docker 网络

理解Docker0

清空所有环境

测试
在这里插入图片描述

三个网络

问题,docker是如何处理容器网络访问的?

在这里插入图片描述

[root@dawn ~]# docker run -d -P --name tomcat01 tomcat
# 查看容器的内部网络地址 ip addr  , 发现容器启动的时候会得到一个 eht0@if127  ip地址,docker分配的
[root@dawn ~]# docker exec -it tomcat01 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
126: eth0@if127: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

# 思考,linux 能不能ping 通容器内部!

[root@dawn ~]# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.051 ms
# linux 可以ping通 docker 容器内部

原理

  1. 我们每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要安装了docker,就会有一个docker0桥接模式,使用的技术是evth-pair技术
    再次测试 ip addr
    在这里插入图片描述
  2. 在启动一个容器测试,发现又多了一对网卡
    在这里插入图片描述
    我们发现,这个容器带来的网卡,都是一对一对的
    evth-pair 就是一对的虚拟设备接口,他们都是成对出现的,一段连着协议,一段彼此相连
    正式因为有这个特性,evth-pair 充当一个桥梁,连接各种虚拟网络设备
    OpenStac,Docker 容器之前的连接,ovs的连接,都是使用evth-pair技术
  3. 我们来测试下 tomcat01和tomcat02 是否可以ping通
[root@dawn ~]# docker exec -it tomcat02 ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.076 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.045 ms

在这里插入图片描述

结论:tomcat01 和 tomcat02 是公用的一个路由器,docker0.
所有的容器不指定网络的情况下,都是docker0 路由的,docker会给我们的容器分配一个默认的可用IP

小结
Docker 使用的是Linux的桥接,宿主机中是一个Docker容器的网桥 docker0.
在这里插入图片描述
Docker 中的所有网络接口都是虚拟的。虚拟的转发效率高
只要容器删除,对应的网桥就消失了

–link

思考一个场景,我们编写了一个微服务,database url=ip,项目不重启,数据库ip换掉了,我们希望可以处理这个问题,可以用名字来进行访问容器?

[root@dawn ~]# docker exec -it tomcat02 ping tomcat01
ping: tomcat01: Name or service not known

# 如何可以解决
[root@dawn ~]# docker run -d --name tomcat03 --link tomcat02  -P tomcat
[root@dawn ~]# docker exec -it tomcat03 ping tomcat02
PING tomcat02 (172.17.0.3) 56(84) bytes of data.
64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.068 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.044 ms

# 其实这个tomcat03 就是在本地配置了tomcat02的配置

# 查看 hosts 配置,在这里原理发现
[root@dawn ~]# docker exec -it tomcat03 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.3	tomcat02 f8b747fff7e6
172.17.0.4	2799b3911dcb

本质探究:–link 就是我们在hosts 配置中增加了一个 172.18.0.3 tomcat02 f8b747fff7e6
我们现在玩Docker 已经不建议使用 --link了
自定义网络,不适用docker0
docker0 问题:它不支持容器名连接访问

自定义网络

在这里插入图片描述
网络模式

birdge: 桥接 docker (默认,自己创建也会使用 bridge 模式)
none: 不配置网络
hose: 和宿主机共享网络
container:容器网络连通

# 我们直接启动的命令 --net bridge ,这个就是我们的docker0
docker run -d -P --name tomcat01 tomcat
docker run -d -P --name tomcat01 --net bridge tomcat

# docker0特点,默认,域名不能访问,--link 可以打通链接
# 我们可以自定义网络
# --driver bridge
# --subnet 192.168.0.0/16
# --gateway 192.168.0.1
[root@dawn ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet

[root@dawn ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
4c49603e3416        bridge              bridge              local
0997bd5e2dbe        host                host                local
8ca9cd7fa8c5        mynet               bridge              local
94adb6185e33        none                null                local

# 在自己的网络部署tomat
[root@dawn ~]# docker run -d -P tomcat-net-01 --net mynet tomcat
Unable to find image 'tomcat-net-01:latest' locally
^[[D^[[Adocker: Error response from daemon: pull access denied for tomcat-net-01, repository does not exist or may require 'docker login': denied: requested access to the resource is denied.
See 'docker run --help'.
[root@dawn ~]# docker run -d -P --name tomcat-net-01 --net mynet tomcat
0eff92ad3e846930e28d702acc89bdf5081b5c12293f7fb4c0c97c766274a2f4
[root@dawn ~]# docker run -d -P --name tomcat-net-02 --net mynet tomcat
b678ee8dfe743d364d3e86dfb6d1be1413b4ae7da0ab968128e7d920fbab9e52
[root@dawn ~]# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "8ca9cd7fa8c5c5954880e601b28022a9ebd94528c6db909a4058ecf7720f94e6",
        "Created": "2020-12-02T09:41:20.743746524+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.0.0/16",
                    "Gateway": "192.168.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "0eff92ad3e846930e28d702acc89bdf5081b5c12293f7fb4c0c97c766274a2f4": {
                "Name": "tomcat-net-01",
                "EndpointID": "ae73925d78b84db252573ef4b9fb377bb05d3cde97b23a2f6f7868535c815506",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            },
            "b678ee8dfe743d364d3e86dfb6d1be1413b4ae7da0ab968128e7d920fbab9e52": {
                "Name": "tomcat-net-02",
                "EndpointID": "4312cfd8fb0b7a3908bba83218dd4217cef82bccd12d48ce0b5de3a51ffab847",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

# 再次测试ping连接 
[root@dawn ~]# docker exec -it tomcat-net-01  ping 192.168.0.3
PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data.
64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.069 ms
64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.044 ms
# 现在不使用 --link,也可以ping 名字
[root@dawn ~]# docker exec -it tomcat-net-01  ping tomcat-net-02
PING tomcat-net-02 (192.168.0.3) 56(84) bytes of data.

我们自定义的网络docker都已经帮我们维护好了对应的关系,推荐我们平时使用自定义网络
好处:保证不同集群使用不同的网络,保证集群安全和健康

网路连通

在这里插入图片描述
在这里插入图片描述

# 测试打通
[root@dawn ~]# docker network connect mynet tomcat01
# 连通之后就是将 tomcat01 放到了 mynet网络下
# 一个容器两个ip地址
	例:阿里云,公网ip 私网ip

在这里插入图片描述


# 01 连通
[root@dawn ~]# docker exec -it tomcat01  ping tomcat-net-01
PING tomcat-net-01 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.054 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.045 ms
# 02 是依旧打不通的
[root@dawn ~]# docker exec -it tomcat02  ping tomcat-net-01
ping: tomcat-net-01: Name or service not known

结论:假设要跨无网络操作别人,就需要使用docker network connect连通

SpringBoot微服务打包Docker镜像

  1. 构建springboot项目
  2. 打包应用
  3. 编写dockerfile
FROM java:8
COPY *.jar /app.jar
CMD ["--server.post=8080"]
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar"]

  1. 构建镜像
  2. 发布运行
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值