Docker学习

384 阅读12分钟

1. Docker网络

1.1 概念

Docker 服务默认会创建一个 docker0 网桥(其上有一个 docker0 内部接口),该桥接网络的名称为docker0,它在内核层连通了其他的物理或虚拟网卡,
这就将所有容器和本地主机都放到同一个物理网络。Docker 默认指定了 docker0 接口 的 IP 地址和子网掩码,让主机和容器之间可以通过网桥相互通信。

查看 bridge 网络的详细信息,并通过 grep 获取名称项
docker network inspect bridge | grep name

ifconfig | grep docker

Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Container-IP,
同时Docker网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信。

docker run 的时候,没有指定network的话默认使用的网桥模式就是bridge,使用的就是docker0。
在宿主机ifconfig,就可以看到docker0和自己create的network(后面讲)eth0,eth1,eth2……代表网卡一,网卡二,网卡三……,lo代表127.0.0.1,即localhost,
inet addr用来表示网卡的IP地址

网桥docker0创建一对对等虚拟设备接口一个叫veth,另一个叫eth0,成对匹配。

整个宿主机的网桥模式都是docker0,类似一个交换机有一堆接口,每个接口叫veth,在本地主机和容器内分别创建一个虚拟接口,
并让他们彼此联通(这样一对接口叫veth pair)

每个容器实例内部也有一块网卡,每个接口叫eth0;

docker0上面的每个veth匹配某个容器实例内部的eth0,两两配对,一一匹配。
通过上述,将宿主机上的所有容器都连接到这个内部网络上,两个容器在同一个网络下,会从这个网关下各自拿到分配的ip,此时两个容器的网络是互通的。

1.2 docker 网络命令

docker network ls  :  查看网络
docker network inspect 网络名字  : 查看网络源数据
docker network rm 网络名字  : 删除网络

测试:
    docker run -it --name u0 ubuntu bash
    docker run -it --name u1 ubuntu bash
    docker inspect containerId | tail -n 20
    docker rm -f containerId
    docker run -it --name u2 ubuntu bash
    
docker run -d -p 8083:8080 --name tomcat8083  tomcat:8.0.52
docker run -d -p 8082:8080 --name tomcat8083  tomcat:8.0.52
ip addr
docker exec -it tomcat8081 bash    

1.3 docker网络模式

网络模式:
    1. bridge模式: 使用--network bridge 指定,默认使用docker0
    2. host模式: 使用--network host 指定
    3. none模式: 使用--network none 指定
    4. container模式: 使用--network container:NAME 或者容器id指定
    
docker网络的作用:
    1. 容器间的互联和通信以及端口映射
    2. 容器IP变动时候可以通过服务名直接网络通信而不受到影响

容器实例内默认网络IP生产规则:
    docker容器内部的IP是变化的
    
 host模式:
    docker run -d -p 8082:8080 --network host --name tomcat8082  tomcat:8.0.52
    docker run -d  --network host --name tomcat8082  tomcat:8.0.52
    docker rm -f a3513b019d97

    直接使用宿主机的 IP 地址与外界进行通信,不再需要额外进行NAT 转换。

    容器将不会获得一个独立的Network Namespace, 而是和宿主机共用一个Network 
    Namespace。容器将不会虚拟出自己的网卡而是使用宿主机的IP和端口。

    docker启动时指定--network=host或-net=host,如果还指定了-p映射端口,那这个时候就会
    有此警告

1.5 docker配置镜像加速器

阿里云地址:cr.console.aliyun.com/cn-beijing/…

直接复制下面部分容器执行,执行完docker info查看

image.png

2. docker 命令

2.1. 常用命令

  1. 启动命令: systemctl start docker
  1. docker version, 可以查看docker是否安装成功
  1. 停止命令: systemctl stop docker

systemctl restart docker

  1. docker info
  1. docker images: 列出本地主机上的镜像, -a:列出所有,-q:只显示镜像id docker image imageId
    注意 docker images 等同于命令 docker image ls
  1. docker search --limit 5 redis
  1. docker pull 镜像名称
  1. docker system df :查看镜像,容器,数据卷所占的空间
  1. docker rmi -f imageId:删除镜像 docker rm 删除的是曾经运行的容器,一般结合docker ps -a使用 docker ps -qa -a :列出当前所有正在运行的容器+历史上运行过的 -q :静默模式,只显示容器编号
  1. 启动容器
    docker run imageId
docker run -it ubuntu /bin/bash
    -d: 后台运行容器并返回容器id,也就是启动守护式容器(后台运行)
    -i:以交互模式运行容器,通常与-t同时使用
    
docker start/stop containerId

11. 列出当前正在运行的容器 docker ps

  1. 退出容器, exit ,这样的话就直接退出来了,docker ps 是看不到的 ctrl +p +q 退出以后,容器还在,直接attach就可以进去
  1. 可以吧容器看做一个简易版的Linux环境和运行在其中的应用程序
  1. 重新进入容器 docker exec -it containerId /bin/bash docker attach containerId attach 再次进入容器,不会启动新的进程,exit会直接导致容器的停止,所以推荐大家用exec
从镜像容器角度,可以把容器看做是一个简易版的Linux环境和运行在其中的应用程序


docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录:ro   镜像名称


docker inspect containerId: 查看容器的元数据

15 docker build -t image_name dockerfile -t 参数是 -tag 参数的缩写形式,允许镜像 image 指定名称和可选标签(冒号后面的部分),标 签通常用于区分镜像的版本;

  1. docker logs 使用 docker logs 命令,可以查看正在运行的容器的日志。语法是:
docker logs container_name

docker top conatinerId

docker logs -tf --tail num container_name

  1. docker cp

可以将容器内的文件拷贝到宿主机

docker cp conatinerId:/home.text.java /home

  1. docker volume

-v 卷名称:容器内路径

docker volume inspect juming-nginx

docker volume list

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

不建议使用匿名挂载

如何确定是具名挂载还是匿名挂载还是指定路径挂载

-v 容器内路径 匿名挂载

-v 宿主机路径:容器内路径 指定路径挂载

-v 卷名称:容器内路径 指定路径挂载

ro说明路径只能通过宿主机来操作,容器内无法操作

2.2 docker 安装tomcat

 docker search tomcat
 docker pull tomcat:8.0.52
 docker images tomcat
 docker run -it --name mytomcat -p 8080:8080  tomcat:8.0.52

 有一次安装遇到个问题:
 
 启动命令:
 docker run -d -p 3355:8080 --name mytomcat b8e65a4d736d
 
 我启动了以后,访问80端口提示404,根本的问题是webapps下面没有资源
 
 solution:
 直接执行 cp -r webapps/* webapps
 
 提交新的镜像
 docker commit -a="dingyawu" -m="add webapps" 8bda8a4650bd  tomcatplus:1.0.0
 

2.3 docker 安装mysql

    一切在云端,处处是镜像
 docker pull mysql:5.7

 docker run -d -p 3306:3306 --privileged=true 
 -v /tmp/mysql/log:/var/log/mysql 
 -v /tmp/mysql/data:/var/lib/mysql 
 -v /tmp/mysql/conf:/etc/mysql/conf.d 
 -e MYSQL_ROOT_PASSWORD=dyw862749167  --name mysql mysql:5.7

 docker exec -it c0c1ff9b6b3b /bin/bash
 
 mysql -uroot -p
 密码: dyw862749167
 
 在这个目录下/tmp/mysql/conf,创建文件my.cnf,写入下面的内容
    [client]
    default_character_set=utf8
    [mysqld]
    collation_server = utf8_general_ci
    character_set_server = utf8
 
 show variables like 'character%';
    
  docker ps -l  
  
  docker restart c0c1ff9b6b3b
  
  人生到处都是坑哈:有一次我开着阿里郎连接我的云数据库,贼慢,慢的我想卸载了自己的云机器上的
  docker,后来我关了阿里郎的科学上网,就很快了

2.4 本机安装的portainer

参考文章:https://blog.csdn.net/vistaup/article/details/128628916

采用的汉化版的镜像
docker pull 6053537/portainer-ce  #直接用汉化版镜像

docker volume create portainer_data

docker run -d --name portainer -p 9000:9000 --restart=always 
    -v /var/run/docker.sock:/var/run/docker.sock 
    -v portainer_data:/data  6053537/portainer-ce

--restart=always 的意思就是只要我docker启动了,这个容器也跟着启动
访问网址: http://1.117.109.40:9000/#!/home
账号密码: admin, dyw862749167

2.5 docker 安装redis

docker run -p 6379:6379 --name redis6.2.6 -v /Users/jlgl/dockerData/redis/conf/redis.config:/etc/redis/redis.conf -v /Users/jlgl/dockerData/redis/data:/data -v /Users/jlgl/dockerData/redis/logs:/logs -d redis:6.2.6 redis-server /etc/redis/redis.conf

参考链接:https://blog.csdn.net/javaxueba/article/details/134800960

2.6 docker 安装 nginx

http://1.117.109.40/

docker ps

docker exec -it 8df64653587f /bin/bash

/usr/share/nginx/html

echo "this is nginx for dingyawu tengxunyun desktop" > index.html 访问页面就变了

nginx 用户配置文件存放的位置:/etc/nginx/nginx.conf

nginx 自己本身的配置文件/etc/nginx/conf.d/default.conf

image.png

2.7 docker 运行java项目

docker run

本地打包

scp app.jar root@1.117.109.40:/tmp

docker run -d -p 3001:6001 --restart=always -v /tmp/app.jar:/tmp/app.jar --name docker-springboot java:latest java -jar /tmp/app.jar

查看日志:docker logs -f docker-springboot

开通防火墙端口,本地访问http://1.117.109.40:6001/user/find/123

image.png

2.8 docker 安装ES

docker run -d --name elasticsearch --net somenetwork -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx256m" elasticsearch:7.6.2

要指定ES_JAVA_OPTS,不然会把机器干爆

要先执行这个 docker network create somenetwork
否则会出现异常
/usr/bin/docker-current: Error response from daemon: network somenetwork not found.

image.png

2.9 使用DockerFile创建镜像

image.png

FROM: 指定基础镜像,写在第一行

ARG: 申明创建镜像过程中用到的变量

LABEL:给镜像元数据添加标签

EXPOSE:申明需要的端口,但是不做端口映射

ENV:指定环境变量

ENTRYPOINT: 设置镜像的默认入口命令,容器启动的时候,首先去执行这个命令

WORKDIR:配置进入容器之后的第一个工作目录

ONBUILD: build镜像时,优先执行的指令,只会在子镜像中执行

操作指令:

RUN: 运行制定指令

CMD: 用来指定启动容器时默认执行的命令,与run不同的地方是只能执行一次,如果出现多次,只有最后一条生效

ADD:添加内容到镜像

COPY: 复制内容到镜像,如果是本地目录推荐使用COPY

    FROM nginx:latest
    ARG version=1
    LABEL author="dingyawu"
    EXPOSE 80 443
    ENV profile dev
    WORKDIR /usr/share/nginx/html
    ONBUILD RUN apt-get update
    ONBUILD RUN apt install -y tree
    RUN echo 'dockerfile build success......'
    RUN rm -rf /usr/share/nginx/html/*
    ADD ./html/index.html /usr/share/nginx/html/

docker build -t nginx:dywv2 .

docker run -d -p 32768:80 --name nginxv2 nginx:dywv2

docker push 镜像

CMD 和ENTRYPOINT的区别

CMD: 容器启动了以后运行的命令,只有最后一个会生效
ENTRYPOINT:可以追加

CMD ["ls", "-a"]

2.10 容器之间共享数据卷

docker run -it --name linux03 -v 03Volume:/tmpdir docker.io/centos

docker run -it --name linux04 --volumes-from linux03 docker.io/centos

2.9 docker继续学习

检查是否安装docker和docker-compose

docker version

docker-compose version

docker info

重新打一个镜像tag, docker tag test_docker:1.8 test_docker:1.8_exttag

查看镜像的详细信息, docker inspect test_docker:1.8_exttag

搜索镜像 ,docker search kafka --filter=stars=500

删除镜像, docker rmi imageId

基于已有容器创建镜像

创建镜像: docker commit -m "第一次制作一个自己的镜像" -a "dyw" 1765438bb8a8 myubantu:1.3

docker run -it docker.io/ubuntu /bin/bash

echo "add new context" > newFile.txt

exit

容器命令: 创建一个容器,并不会启动:docker create -it ubuntu

启动一个容器:docker start fbddb7e48dd1

一个命令就可以代替上面两个: docker run -it ubuntu,

docker run -d ubuntu

-d表示改后台启动

docker logs -f containerId: 查看容器控制台日志

进入容器 : docker exec -it containerId /bin/bash

查看容器信息: docker inspect containerid

查看容器内进程:docker top containerid

查看容器运行统计信息: docker stats containerid

复制本地文件到容器: docker cp 本地目录 containerId:/容器目录

查看端口映射: docker port containerId

更新配置docker update --restart=always/no containerId

2.9.1 如何搞一个自己的私服

安装私有仓库: docker run -d -p 5000:5000 registry:2

浏览器查看: http://1.117.109.40:5000/v2/_catalog

打标签

docker tag docker.io/ubuntu:latest 1.117.109.40:5000/testregistry

docker tag 镜像名称:标签 仓库地址:仓库端口/镜像名称:标签

配置改变,允许http推送 { "insecure-registries": ["192.168.64.3:5000"], "registry-mirrors": ["lhf8btpm.mirror.aliyuncs.com"] }

重启容器: systemctl daemon-reload && systemctl restart docker

推送仓库: docker push 1.117.109.40:5000/testregistry

拉取镜像: docker pull 1.117.109.40:5000/testregistry

docker run -d -v 本地绝对路径:容器内部路径 镜像名称

端口映射和容器互联

docker run -d -P --name nginx nginx 任意映射一个端口

docker run -d -p 8081:80 --name nginx nginx 映射8081端口

查看端口配置: docker port containerId

容器互联: docker run -d -p 8081:80 --name --link 容器名称:内部名称

2.8.2 docker 遇到的坑

当我遇到这个WARNING: IPv4 forwarding is disabled. Networking will not work.

image.png

解决方案: blog.csdn.net/listeningdu…

3. docker学习

等待学习

www.bilibili.com/video/BV1og…

看到第37个了

学习笔记:www.kuangstudy.com/

4. docker 概念

4.1 Docker和虚拟机技术的不同

  • 传统虚拟机,虚拟出一条硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软件。

  • 容器内的应用直接运行在宿主机的内核中,容器是没有自己的内核的,也没有虚拟我们的硬件,所以就轻便了。

  • 每个容器间是互相隔离,每个容器内都有一个属于自己的文件系统,互不影响。