Docker 学习笔记

Posted dkbnull

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Docker 学习笔记相关的知识,希望对你有一定的参考价值。

Docker概述

开发、上线两套环境,应用环境、应用配置

集群

隔离,docker核心思想,打包装箱,每个箱子是相互隔离的

轻巧

基于Go语言开发,开源


虚拟机技术:虚拟出一套硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软件。资源占用多、冗余步骤多、启动慢

容器化技术:容器内的应用直接运行在宿主机的内核上,容器是没有自己的内核的,也没有虚拟硬件,所以就轻便

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


DevOps 开发、运维

应用更快速的交付和部署,打包镜像发布测试,一键运行

更便捷的升级和扩容

更简单的系统运维

更高效的计算资源利用

Docker安装

镜像image

容器container

仓库respository

# 卸载旧版本
yum remove docker \\
                  docker-client \\
                  docker-client-latest \\
                  docker-common \\
                  docker-latest \\
                  docker-latest-logrotate \\
                  docker-logrotate \\
                  docker-engine

# 需要的安装包
yum install -y yum-utils

# 设置镜像仓库
yum-config-manager \\
    --add-repo \\
    https://download.docker.com/linux/centos/docker-ce.repo
    
# *可选 更新软件包索引
yum makecache fast

# docker安装 ce 社区版 ee 企业版
yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin

# 启动docker
systemctl start docker

# 查看docker版本号,是否安装成功
docker version

----------------------------------------------------------------------
----------------------------------------------------------------------

# hello world
docker run hello-world

# 查看镜像
docker images

# 卸载docker,卸载依赖
yum remove docker-ce docker-ce-cli containerd.io docker-compose-plugin docker-ce-rootless-extras
# 卸载docker,删除资源,/var/lib/docker默认工作路径
rm -rf /var/lib/docker
rm -rf /var/lib/containerd
# 刷新配置文件
systemctl daemon-reload

# 重启
systemctl restart docker

底层原理

Docker是一个Client-Server结构的系统,Docker的守护进程运行在宿主机上,通过Socket从客户端访问。

Docker-Server接收到Docker-Client的指令,就会执行这个命令


Docker为什么比VM快

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

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

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

Docker命令

# 显示docker的版本信息
docker version

# 显示docker的系统信息,包括镜像和容器的数量
docker info

# 帮助文档
docker 命令 --help

# 查看cpu的状态
docker stats

# 查看网络状态
docker network

镜像命令

# 查看宿主机上的镜像
docker images
# 显示所有镜像
docker images -a
# 只显示镜像的id
docker images -q

# 搜索镜像
docker search mysql
docker search mysql --filter=STARS=10000

# 下载镜像,分层下载
docker pull mysql

# 删除镜像
docker rmi -f 镜像id/镜像名称
# 删除多个镜像
docker rmi -f 镜像id 镜像id 镜像id
# 删除全部镜像
docker rmi -f $(docker images -aq)

# 查看镜像元数据
docker image inspect 镜像id:镜像版本

容器命令

# 新建容器并启动
docker run [可选参数] image
--name	容器名字,用来区分容器
-d		后台方式运行
-it		使用交互方式运行,可进入容器查看内容
-p		端口映射
	-p ip:主机端口:容器端口
	-p 主机端口:容器端口 (常用)
	-p 容器端口
	容器端口
	
-P		随机指定端口
--rm	一般用于测试,用完即删
-e		环境配置
-v		数据卷挂载

docker run -itd --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root mysql
docker run -it centos /bin/bash

# 列出所有运行的容器
docker ps
		当前正在运行的容器
-a		当前正在运行的容器+历史运行过的容器
-n=?	显示最近创建的容器,?指定数量
-q		只显示容器id

# 退出容器
exit			直接退出容器并停止
Ctrl + P + Q	只退出,不停止

# 删除容器,不能删除正在运行的容器,如果要强制删除,rm -f
docker rm 容器id
# 删除全部容器
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 logs
-t				显示日志
-f				显示时间戳
--tail number	要显示的日志条数

# 查看容器中的进程信息
docker top 容器id

# 查看容器元数据
docker inspect 容器id

# 进入当前正在运行的容器
docker exec -it 容器id bashshell		# 进入容器后开启一个新的终端
docker attach 容器id					# 进入容器正在执行的终端,不会启动新的进程

# 从容器内拷贝文件到宿主机
docker cp 容器id:容器内路径 目的主机路径

# 查看容器元数据
docker inspect 容器id
docker run -d centos

# 问题,docker ps,发现centos停止了
# 常见的坑,docker容器使用后台运行,就必须要有一个前台进程,docker发现没有应用,就会自动停止
# nginx,容器启动后,发现自己没有提供服务,就会立即停止,就是没有程序了

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

操作命令

可视化

  • portainer docker图形化界面管理工具
docker run -d -p 9000:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
  • Rancher

Docker镜像

镜像是什么

镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,他包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。

Docker镜像加载原理

UnionFS 联合文件系统

docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统就是UnionFS

bootFS 系统启动需要引导加载

rootFS

Docker镜像默认都是只读的,当容器启动时,一个新的可写层加载到镜像的顶部。

这一层就是我们通常说的容器层,容器之下的都叫镜像层。

所有操作都是基于容器层的

commit镜像

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

容器数据卷

容器之间可以有一个数据共享的技术,Docker容器中产生的数据,同步到本地

卷技术,目录的挂载,将我们容器内的目录,挂载到Linux目录上

容器的持久化和同步操作,容器间也是可以数据共享的(多个容器挂载同一目录)

使用数据卷

直接使用命令来挂载 -v

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

MySQL的数据持久化

docker pull mysql:5.7

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

匿名、具名挂载

# 匿名挂载
-v 容器目录

# 具名挂载
-v 卷名:容器目录

# 指定路径挂载
-v /宿主机目录:容器目录

# 查看所有券的情况
docker volume ls

# 查看卷路径
docker volume inspect 卷名

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

# 改变读写权限 只读,这个目录只能通过宿主机操作,容器内部无法操作
-v 容器目录:ro
# 可读可写
-v 容器目录:rw

DockerFile挂载

数据卷容器

--volumes-from

删除一个容器,其他容器依旧可以使用共享卷

拷贝的概念

容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用未为止

但是一旦持久化到了本地,本地的数据是不会删除的

DockerFile

用来构建docker镜像的文件,命令参数脚本

通过这个脚本可以生成镜像,镜像是一层一层的,脚本是一个一个的命令,每个命令都是一层

DockerFile 构建过程

基础知识

  • 每个保留关键字(指令)必须是大写字母

  • 指令从上到下顺序执行

  • # 表示注释

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


DockerFile是面向开发的,我们以后要发布项目,做镜像,就需要编写DockerFile文件

Docker镜像逐渐成为企业交付的标准

DockerFile:构建文件,定义了一切的步骤,即代码

Dockerlmages:通过DockerFile构建生成的镜像,最终发布和运行的产品

Docker容器:容器就是镜像运行起来提供服务的


基础镜像 scratch

DockerFile指令

FROM			# 基础镜像,一切从这里开始构建
MAINTAINER		# 镜像作者,姓名<邮箱>
RUN				# 镜像构建的时候需要执行的命令
ADD				# 步骤,添加内容,会自动解压
COPY			# 复制,将文件拷贝到镜像中
WORKDIR			# 镜像工作目录
VOLUME			# 挂载的目录
EXPOSE			# 暴露端口
ENV				# 构建时设置环境变量
CMD				# 指定容器启动时需运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT		# 指定容器启动时需运行的命令,可以追加命令,直接拼接在ENTRYPOINT命令的后面
ONBUILD			# 构建一个被继承DockerFile时运行,是一个触发指令
# 构建镜像,DockerFile文件名字随意,官方命名 Dockerfile,build 会自动寻找这个文件,就不需要 -f 指定了
docker build -f Dockerfile文件地址 -t 镜像名:[TAG] .

# 查看镜像构建历史
docker history 镜像id
FROM openjdk:8
EXPOSE 8080
COPY application.yml /app/application.yml
COPY logback-spring.xml /app/logback-spring.xml
COPY test-1.0.0.1.jar /app/test.jar
ENV APP_OPTS=""
ENV TZ="Asia/Shanghai"
WORKDIR /app
ENTRYPOINT [ "java", "-Djava.awt.headless=true", "-jar","/app/test.jar" ]

发布镜像

# 登录
docker login -u 用户名

# 给镜像生成版本号 作者/镜像名
docker tag 镜像id 镜像名:[TAG]

# 发布镜像
docker push 镜像名:[TAG]

提交的时候也是按照镜像的层级来提交的

DockerFile:构建文件,定义了一切的步骤,源代码

Dockerlmages:通过 DockerFile 构建生成的镜像,最终发布和运行的产品,可能是jar war

虚悬镜像

仓库名、标签都是<none>的镜像,俗称dangling image

# 创建
docker build .

# 单独查看
docker image ls -f dangling=true

# 删除
docker image prune

Docker网络原理

Docker0

[root@localhost /]# ip addr
# lo:本机回环地址
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
# ens33:内网地址
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:65:49:26 brd ff:ff:ff:ff:ff:ff
    inet 192.168.127.131/24 brd 192.168.127.255 scope global noprefixroute dynamic ens33
       valid_lft 1541sec preferred_lft 1541sec
    inet6 fe80::9581:3f83:6568:8151/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
# docker0:docker地址
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    link/ether 02:42:2d:3b:09:1c brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:2dff:fe3b:91c/64 scope link
       valid_lft forever preferred_lft forever
[root@localhost /]# docker exec -it tomcat 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
# docker分配的ip地址
28: eth0@if29: <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通docker容器内部
# 容器和容器之间是可以互相ping通的
# 所有的容器,不指定网络的情况下,都是docker0来路由的,docker会给容器分配一个默认的可用ip
[root@localhost /]# 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:65:49:26 brd ff:ff:ff:ff:ff:ff
    inet 192.168.127.131/24 brd 192.168.127.255 scope global noprefixroute dynamic ens33
       valid_lft 1618sec preferred_lft 1618sec
    inet6 fe80::9581:3f83:6568:8151/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:2d:3b:09:1c brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:2dff:fe3b:91c/64 scope link
       valid_lft forever preferred_lft forever
29: veth6ed8794@if28: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
    link/ether ba:47:05:c2:31:28 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::b847:5ff:fec2:3128/64 scope link
       valid_lft forever preferred_lft forever

我们每启动一个docker客器,docker就会给docker客器分配一个ip,我们只要安装了doker,就会有一个网卡docker0

桥接模式,使用的技术是 evth·pair 技术

这些容器带来的网卡,都是一对一对的

evth·pair 技术就是一对的虚拟设备接口,他们都是成对出现的,一端连着协议,一端彼此相连

正因为有这个特性,所以利用 evth·pair 充当一个桥梁,用于连接各种虚拟网络设备

OpenStac,docker容器之间的链接,OVS的连接,都是使用evth·pair技术


Docker使用的是Linux的桥接,宿主机中是一个Docker容器的网桥 docker0

Docker中所有的网络接口都是虚拟的,虚拟的转发效率高

只要容器删除,对应的一对网桥也会删除

–link

不建议使用

# 使用容器名 ping 容器
# 不能互相ping通,正向可以,反向不可以
docker run -d -P --name tomcat01 --link tomcat tomcat

# --link 就是在hosts配置中增加了一个ip与容器名的映射
[root@localhost /]# docker exec -it tomcat01 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      tomcat 69cd02104682
172.17.0.3      5f3ef2e83287

自定义网络

容器互联

网络模式

  • bridge:桥接,默认
  • none:不配置网路
  • host:和宿主机共享网络
  • container:容器网络连通,局限很大,使用极少
# --driver bridge 桥接
# --subnet 192.168.0.0/16 子网
# --gateway 192.168.0.1 网关
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 test-net

# 可以使用容器名ping 通
docker run -d -P --name tomcat01 --net test-net tomcat
docker run -d -P --name tomcat02 --net test-net tomcat

自定义网络docker已经维护好了对应关系,推荐

不同的集群使用不同的网络,保证集群是安全健康的

网络连通

# 将CONTAINER放到了NETWORK网络下,一个容器两个ip
docker network connect NETWORK CONTAINER

Nginx

docker run --name nginx -d -v /home/nginx/nginx.conf:/etc/nginx/nginx.conf:ro -p 80:80 nginx
user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;


events 
    worker_connections  1024;



http 
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    #include /etc/nginx/conf.d/*.conf;

    upstream test
        server 192.168.100.101 weight=1;
        server 192.168.100.102 weight=1;
    

    server 
        listen       80;
        server_name  localhost;

        location / 
            root   html;
            index  index.html index.htm;
            proxy_pass http://test;
        
    


IDEA整合Docker

Spring Boot 打包镜像

Docker Compose

容器编排

  • 是什么

Docker官方的开源项目,负责实现对Docker容器集群的快速编排

Docker公司推出的一个工具软件,可以管理多个Docker容器组成一个应用。需要定义一个 YAML 格式的配置文件docker-compose.yml,写好多个容器之问的调用关系。然后,只要一个命令,就能同时启动/关闭这些容器

  • 能干嘛

docker建议我们每一个容器中只运行一个服务,因为docker容器本身占用资源极少,所以最好是将每个服务单独的分割开来

但是如果需要同时部署多个服务,每个服务单独写Dockerfile、构建镜像、构建容器,工作量大,所以docker官方提供了docker-compose多服务部署的工具

Compose允许用户通过一个单独的docker-compose,yml模版文件来定义一组相关联的应用容器为一个项目 (project)

可以很容易地用一个配置文件定义一个多容器的应用,然后使用一条指令安装这个应用的所有依赖,完成构建

docker-compose 解决了容器与容器之间如何管理编排的问题

# 安装docker-compose
curl -SL "https://github.com/docker/compose/releases/download/v2.15.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 或
curl -SL https://get.daocloud.io/docker/compose/releases/download/v2.15.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

# 设置权限
chmod +x /usr/local/bin/docker-compose

# 检查是否安装成功
docker compose version

# 卸载
rm /usr/local/bin/docker-compose

一文件:docker-compose.yml

两要素:

​ 服务(service):一个个应用容器实例

​ 工程(project):由一组关联的应用容器组成的一个完整业务单元,在docker-compose.yml文件中定义


步骤:

编写Dockerfile定义各个微服务应用并构建出对应的镜像文件

使用 docker-compose.yml定义一个完整业务单元,安排好整体应用中的各个容器服务

执行docker-compose up命令来启动并运行整个应用程序,完成一键部署上线

docker-compose -h					# 查看帮助
docker-compose up					# 启动所有docker-compose服务
docker-compose up -d				# 启动所有docker-compose服务并后台运行
docker-compose down					# 停止并删陈容器、网络、卷、镜像
docker-compose exec yml里面的服务id	 # 进入容器实例内部
docker-compose exec yml里面的服务id /bin/bash
docker-compose ps					# 展示当前docker-compose编排过的运行的所有容器
docker-compose top					# 展示当前docker-compose编排过的容器进程
docker-compose logs yml里面的服务id	 # 查看容器输出日志
docker-compose config				# 检查配置
docker-compose config -q 			# 检查起置,有问题才有输出
docker-compose restart 				# 重启服务
docker-compose start				# 启动服务
docker-compose stop					# 停止服务

编排微服务

编写docker-compose.yml文件

# 指定本 yml 依从的 compose 哪个版本制定的
version

# 指定为构建镜像上下文路径
build

# 设置依赖关系
depends_on

# 指定与服务的部署和运行有关的配置。只在 swarm 模式下才会有用
deploy
version: "3.7"

services:
  mysql:
    image: mysql
    environment:
      - TZ=Asia/Shanghai
      - MYSQL_ROOT_PASSWORD=123456
    ports:
      - 3306:3306
    working_dir: /app
    restart: always
    volumes:
      - /home/mysql/conf:/etc/mysql/conf.d
      - /home/mysql/data:/var/lib/mysql
    command:
      --default-authentication-plugin=caching_sha2_password
    networks: 
      test-net:
        aliases: 
          - mysql
  test:
    image: devops.test.cn:5000/test
    environment:
      - TZ=Asia/Shanghai
    ports:
      - 80:80
    working_dir: /app
    restart: always
    volumes:
      - ./log:/app/log
      - ./application.yml:/app/application.yml
    networks: 
      test-net:
        aliases: 
          - test 
networks: 
  test-net:
    external: true

执行 docker-compose up或者执行 docker-compose up -d

Docker Swarm

集群部署

CI\\CD jenkins

流水线

CIG

CAdvisor

InfluxDB

Granfana

以上是关于Docker 学习笔记的主要内容,如果未能解决你的问题,请参考以下文章

Docker 学习笔记 Docker 仓库数据卷数据卷容器,网络基础实操。高级网络配置学习

Docker学习笔记Docker容器相关技术

Docker学习笔记(8-2)Docker - 数据卷容器

docker学习笔记2:容器操作

Docker学习笔记(4-3)Docker容器内部署静态网站

Docker学习笔记