Docker笔记

因为项目需要,需要同一台机器部署多个tomcat,或者多个版本的数据库,在一个服务器上部署很不方便,之前有使用VMware创建虚拟机,后来发现使用docker部署应用确实非常方便,比WMware节省资源,而且操作简单。然后就考虑仔细学一下Docker的知识和应用。

Docker基础知识

在日常使用中,当你只想要一个应用有单独的运行环境,而不想虚拟出一个完整的计算机,不想浪费资源,也不想再配置一次环境,这就是使用Docker的优势了。

传统虚拟机与容器对比

传统虚拟机技术

虚拟机是虚拟出一套硬件,在这之上运行一个完整的操作系统,例如之前使用的VMware,指定系统镜像,然后安装操作系统,最后配置并使用应用。

在使用VMware创建虚拟机的时候,需要指定cpu核数,内存大小和磁盘空间等资源,性能也有所限制。

容器技术

容器内的应用程序直接运行在宿主机的内核上,互相隔离,容器内没有自己的内核,也没有对硬件进行虚拟,因此容器比起虚拟机更为轻便,性能也比虚拟机好。

而且一套模板可以放到不同的机器上使用,可以跨系统部署,非常方便。

Docker的底层原理

Docker是基于Google公司推出的Golang语言开发而来的,基于Linux内核的Cgroups、NameSpace,以及Union FS等技术,对进程进行封装和隔离,属于操作系统的虚拟化技术。

对进程进行封装隔离,使用Docker可以实现开发、测试、生产环境的部署一致性,极大的减少运维成本。

Docker基础组件

Docker Daemon

安装使用Docker,得先运行Docker Daemon进程,用于管理Docker,如:

  • 镜像 Images
  • 容器 Containers
  • 网络 Network
  • 数据卷 Data Volumes

Rest接口

提供和Daemon交互的API接口

Docker Client

客户端使用REST API和Docker Daemon进行访问,就是Docker提供的各种命令行操作。

image

image镜像,构建容器。将应用程序运行所需的环境,打包为镜像文件。

镜像是一个只读模板,用于创建容器,也可以通过Dockerfile文本描述镜像的内容。

镜像的概念类似于编程开发里面向对象的类,从一个基类开始(基础镜像Base Image)

构建容器的过程,就是运行镜像,生成容器实例。

Docker镜像的描述文件是Dockerfile,包含了如下的指令:

  • FORM 定义基础镜像
  • MAINTAINER 作者
  • RUN 运行Linux命令
  • ADD 添加文件/目录
  • ENV 环境变量
  • CMD 运行进程

Contaioner

容器,应用程序跑在容器中。

容器时一个镜像的运行实例,镜像>容器。

创建容器的过程

  1. 获取镜像,如docker pull centos,从镜像库拉取
  2. 使用镜像创建容器
  3. 分配文件系统,挂载一个读写层,在读写层加载镜像
  4. 分配网络/网桥接口,创建一个网络连接,让容器和宿主机通信
  5. 容器获取IP地址
  6. 执行容器命令,如bin/bash
  7. 反馈容器启动结果

Registry

Docker镜像需要进行管理,Docker提供了Registry仓库,其实他是一个容器。可以基于该容器运行私有仓库。也可以使用Docker Hub互联网共有镜像仓库

Docker Hub

官方的镜像仓库(hub.docker.com),类似于GitHub

Docker 基础命令

pull

镜像的获取,是从配置好的docker镜像站中拉取。

docker pull hiromuhota/webspoon

search

获取之前也可以查看镜像文件是否存在

docker search hiromuhota/webspoon

image

可以查看本地Docker镜像有哪些

docker image ls
docker images

rmi

删除镜像

docker rmi 5afc9cadd006(IMAGE ID)

run

docker run -d -p 8080:8080 -v D:\kettle_code\kettle_file:/app/data -v D:\kettle_code\jre:/docker-java-home/jre hiromuhota/webspoon:0.8.2.17
-d : 后台运行容器
-p : 端口映射 宿主机:容器端口,访问宿主机的端口就是访问容器对应端口

docker run -it 5afc9cadd006(IMAGE ID) bash
-i : 交互式命令操作
-t : 开启一个终端
bash : 进入容器后执行的命令,意思就是执行了bash解释器,可以执行命令
输入exit可以退出容器

docker run -it --rm 5afc9cadd006(IMAGE ID) bash
--rm : 容器退出时删除该容器

exec

docker exec -it 5afc9cadd006(IMAGE ID) bash
exec : 进入正在运行的容器内

ps

查看有哪些容器在运行

docker ps

stop

停止容器

docker stop 84587c4e049a(CONTAINER ID)

start

启动容器

docker start 84587c4e049a(CONTAINER ID)

info

查看Docker服务信息

Docker info

其中有信息Docker Root Dir: /var/lib/docker,这就是Docker的数据目录。

ls /var/lib/docker/image/overlay2/imagedb/content/sha256/ -l 这就是Docker镜像存储目录。

这些文件的作用是记录镜像和容器的配置关系。

Docker 生命周期

Docker的镜像原理

在获取镜像的时候,发现下载了多行信息,最终获得了一个完整的镜像文件。

就像linux操作系统,是由linux的内核+发行版。

利用Docker容器,可以获取不同的发行版镜像,然后基于改镜像运行各种容器使用。

当我们获取docker镜像的时候,并不是获取完整版,只是获取发行版。镜像就是一个发行版的作用,我们只需要准备好一个Linux内核,在上层使用不同的发行版就可以了。这样就可以自由的使用各个版本系统,兼容多种环境。

Docker是一层一层搭建起来的下层是上层的父级。

镜像分层的好处之一就是共享资源,例如有多个镜像都来自同一个base镜像,那么在Docker host只需要存储一份base镜像。

base镜像提供的是rootfs服务,也就是Linux的基础文件系统。如/etc /opt /目录下的各种文件。

即使多个容器共享一个base镜像,某个容器修改了base镜像的内容,例如修改/etc/下的配置文件,其他容器的/etc/下内容是不会被修改的,修改动作只限制在单个容器内,这就是容器的写入时复制特性(Copy-on-write)

  • 添加文件:在容器中创建文件时,新文件会被添加到容器中。
  • 读取文件:在容器中读取某个文件时,Docker会从上往下依次在各个镜像中查找此文件。一旦找到,立刻将其复制到容器层,然后打开并读入内存。
  • 修改文件:在容器中修改已存在的文件时,Docker会从上往下依次在各个镜像层查找此文件。一旦找到,立即将其复制到修改器,修改掉。
  • 删除文件:在容器中删除文件时,Docker也是从上往下一次在镜像层中查找此文件,找到后,会在容器层中记录下此删除操作。(只是记录删除操作)

Docker镜像的内容

Docker镜像层级管理的方式大大便捷了Docker镜像的分发和存储,Docker hub是全世界的镜像仓库。

  • Docker镜像代表一个容器的文件系统内容
  • 镜像层级技术属于联合文件系统UnionFS
  • 容器是一个动态的环境,每一层镜像里的文件都会落实到容器环境里

Dockerfile

自定义Docker镜像的每一层应用

Docker镜像管理操作

获取镜像

  1. 从Docker Hub获取镜像
  2. 本地镜像导出、导入
  3. 私有的Docker仓库

搜索Docker Hub的镜像

docker search 镜像名
-- 下载镜像
docker pull 镜像名

查看镜像

Docker images
Docker images centos
可以指定具体的名称
Docker images -q
-q 也就是 --quiet 只列出镜像的id

可以格式化显示镜像

docker images --format "{{.ID}}--{{.Repository}}"

5afc9cadd006--webspoon_image
c8bfa64b5b20--hiromuhota/webspoon
f5fead3018a5--hiromuhota/webspoon

以表格形式显示

docker images --format "table {{.ID}}\t{{.Repository}}\t{{.Tag}}"

IMAGE ID       REPOSITORY            TAG
5afc9cadd006   webspoon_image        latest
c8bfa64b5b20   hiromuhota/webspoon   latest
f5fead3018a5   hiromuhota/webspoon   0.8.2.17

删除镜像

删除镜像的时候,可以根据镜像的id、名称、摘要等方式删除。

删除之前可以查看当前有哪些容器在执行,或者哪些容器执行过

docker ps
docker ps -a
也可以组合使用命令参数,q就是之前说的只显示id
docker ps -aq
-- 删除容器记录
docker rm f8eec38b8873
-- 删除镜像,删除时,镜像不能有被依赖的容器记录
docker rmi hello-world
-- 指定id的前三位也可以删除
docker rmi d2c

镜像管理

批量删除镜像用法(Linux)

docker rmi  `docker images -aq`
-- 批量删除容器
docker rm  `docker images -aq`

导出镜像

导出的镜像为压缩文件,可以发给其他人使用。

docker commit

导出镜像的命令

docker image save hiromuhota/webspoon > /home/data/webspoon.tgz

导入镜像的命令

docker image load -i /home/data/webspoon.tgz

查看镜像信息

docker image inspect 镜像id

列出的就是镜像的json信息。

Docker 容器管理

docker run 的命令等于创建+启动

docker run 镜像名,如果镜像不存在本地,则会在线下载该镜像。

注意:容器内的进程必须处于前台运行状态,否则容器就会直接退出

如果容器内什么都没做,那么容器也会挂掉。

  • 运行一个挂掉的容器,比如
docker run contos

这个写法,会产生多个容器记录,每运行一次就生成一条,因为容器中没有程序在运行,所以直接挂掉了。可以通过docker ps查看所有容器运行情况。

  • 运行容器且进入容器内,且在容器内执行某个命令
docker run -it contos sh
  • 开启一个容器执行某个程序,属于前台运行,会卡住一个终端-
docker run contos ping baidu.com
  • 运行一个活着的容器,docker ps可以看到的容器

-d : 参数,让容器在后台执行(针对宿主机而言)

docker run -d contos ping baidu.com
  • 其他运行的参数

–rm :容器挂掉后自动被删除(docker ps -a看不到)

-v 宿主机路径:容器路径 : 数据目录映射

–name :容器命名

docker run -d --rm --name baidu contos ping baidu.com
  • 查看容器日志
docker logs 容器id

docker logs -f 容器id 这就是刷新日志
  • 进入正在运行的容器控件内
docker exec -it 容器id bash

exit可以退出

  • 查看容器详细信息,用于高级调试
docker container inspect 容器id
  • 容器的端口映射

-p 宿主机端口:容器端口

-P :随机端口映射

docker run -d -p 82:80 --name lmk_nginx nginx

查看容器内的端口转发情况

docker port 容器id
  • 容器的提交
docker commit 容器id 新的镜像名(一般是dockerhub账号/镜像名)

DockerFile

定制Docker镜像的方式有两种

  • 手动修改容器内容,导出新的镜像
  • 基于DockerFile自行编写指令,基于指令流程创建镜像

主要组成部分

  • 基础镜像信息FROM contos:7.1
  • 制作镜像操作指令RUN yum install openssh-server -y
  • 容器启动时执行命令 CMD [“/bin/bash”]

DockerFile指令

例如,我们要基于容器运行Mysql

  1. 运行宿主机
  2. 安装docker容器软件
  3. 获取Mysql镜像即可,docker pull mysql:tag(这个镜像无法自由控制,该mysql的基础镜像是什么发行版,我们获取的镜像就是什么发行版,这是别人定制好的,下载的是debain,如果想要换成contos7的发行版,就要自定义)
  4. 直接运行该镜像,通过端口映射,运行mysql, docker run mysql:5.7(容器能够运行,必须在容器内,有一个进程在前台运行,该容器内,有mysql在前台运行)
  5. 访问宿主机的一个映射端口,访问到容器内的mysql

FROM

指定基础镜像

MAINTAINER

指定维护者信息,可以没有

RUN

在命令前面加上RUN即可

ADD

添加宿主机的文件到容器内,COPY文件,自动解压

源文件可以是一个URL,此时,docker引擎会下载该链接,放入目标路径,且权限自动设置为600,如果这不是期望结果,还需要加一层RUN指令进行调整。

源文件是一个URL,而且是一个压缩包,不会解压缩,需要加RUN命令自己解压

源文件是一个压缩文件可以解压,但是只有gzip、bzip2、xz、tar可以自动解压。

ADD mp.tar /home/
RUN linux 命令

COPY

复制文件,作用和ADD是一样的,都是添加宿主机的文件到容器内。不解压

copy map.py /home/

-- 支持多个文件,也可以使用通配符,语法要满足Golang的filepath.Match
copy map* /tmp/cc?.txt. /home/

-- COPY指令可以保留源文件的元数据,如权限、访问时间等等。

WORKDIR

设置当前工作目录,更改工作目录,类似cd。

WORKDIR /opt

USER

用于改变环境,用于切换用户

USER root
USER lmk

VOLUME

设置卷,挂载主机目录

容器再运行时,应该保证存储层不写入任何数据,运行在容器内产生的数据,我们推荐时挂载,写入到宿主机上,进行维护。

-- 将容器内的/data文件夹,在容器运行时,改目录挂载为匿名卷,任何向该目录写入数据的操作,都不会被容器记录,保证容器存储层无状态理念。
VOLUME /data 

-- Dockerfile
FROM centos
MAINTAINER LMK
VOLUME ["/data1","/data2"]
-- 该容器运行是,这两个目录自动和宿主机做好映射关系

-- 运行该镜像
docker run 32d
-- 可以使用docker inspect查看信息
docker inspect 32d

EXPOSE

指定对外的端口

帮助使用该镜像的人快速理解该容器的端口业务

docker port 容器
docker run -p 宿主机端口:容器端口
docker run -P 
-- 随机端口

CMD

指定容器启动后要干的事情

用法:CMD [“参数1″,”参数2”]

在指定了entrypoint指令后,用CMD指定具体参数

docker不是虚拟机,容器就是一个进程,既然是进程,那么程序在启动的时候就需要指定运行参数,这就是CMD指令的作用。

例如:

centos镜像默认的CMD是/bin/bash,直接docker run -it centos会直接进入bash解释器。

也可以启动容器的时候指定参数,docker run -it centos cat /etc/os-release

CMD ["cat","/etc/os-release"]

需要注意的是,docker不是虚拟机的概念,虚拟机里的程序运行,基本上都是后台运行,利用systemctl运行,但是容器内没有后台进程的概念,必须前台运行。

容器就是为了主程序存在的,主进程如果退出了,容器就毫无意义

例如

CMD systemctl start nginx
-- 这样的写法是错误的,容器会立即退出

-- 因为systemctl start nginx是希望以守护进程形式启动nginx,且CMD命令会转化为
CMD ["sh","-c","systemctl start nginx"]
-- 这样的命令主进程是sh解释器,执行完毕后会立刻结束,因此容器就退出了

-- 因此正确的方法是:
CMD ["nginx","-g","daemon off;"]

ENTRYPOINT

容器启动后执行的命令

ENTRYPOINT 和 RUN指令一样,分两种形式

  • exec
  • shell

作用和CMD一样,都是在指定容器启动程序以及参数。

当指定了ENTRYPOINT 之后,CMD指令的语义就有了变化,变成了把CMD的内容当作参数传递给ENTRYPOINT指令。

例如

-- 准备一个Dockerfile
FROM centos:7.8.2003
RUN rpm --rebuilddb && yum install epel-release -y
RUN rpm --rebuilddb && yum install curl -y
CMD ["curl","-s","http://ipinfo.io/ip"]

-- CMD等同于
docker run my_centos curl -s http://ipinfo.io/ip

-- 构建镜像
docker build .
-- 修改镜像名
docker tag 3dd centos_curl
-- 查看镜像
docker images
-- 生成容器
docker run centos_curl

-- 如果再想传入一个参数
docker run centos_curl pwd
-- 就会输出当前路径,该形式会覆盖镜像中的CMD,就好比把docker镜像当作一个环境执行后面的命令。

-- 如果想要正确的传入一个参数
-- 办法1:给容器传入新的完整命令
docker run my_centos curl -s http://ipinfo.io/ip -I
-- 办法2(正确方式),修改Dockerfile,使用ENTRYPOINT 
FROM centos:7.8.2003
RUN rpm --rebuilddb && yum install epel-release -y
RUN rpm --rebuilddb && yum install curl -y
ENTRYPOINT ["curl","-s","http://ipinfo.io/ip"]

-- 重新构建镜像

ENV

环境变量,无论再镜像构建时,和容器运行时,都可以使用。

-- Dockerfile脚本中
ENV NAME="LMK"
ENV MYSQL_VERSION=5.7

-- 后面所有的操作可以通过$NAME获取变量的值,维护dockerfile的时候更友好。

ARG

也是设置环境变量,只是用于构建镜像设置的变量,容器运行的时候就不能使用了。

DockerFile实践

通过Dockerfile,构建nginx镜像,且运行容器后,生成的页面,内容为hello world

-- 创建一个Dockerfile,名称不能改,只能叫Dockerfile
FROM nginx
RUN echo '<meta charset= utf8>hello world'
/usr/share/nginx/html/index.html

-- 构建Dockerfile
-- 首先进入Dockerfile所在路径
docker build .

-- 修改镜像名
docker tag bs3 my_nginx

--运行该镜像
docker run -d -p 80:80 my-nginx

构建一个镜像网站

  1. nginx,修改首页内容,html网站就跑起来了,是一个web server,提供web服务,提供网关,限流等。
  2. web framework,web框架,一般由开发,通过某个开发语言,基于某个web框架,自己开发一个web站点,类似python的django框架

大概操作:

  1. 接下来就使用python语言,基于flask web框架,开发一个站点,写一个后端的网站代码
  2. 开发dockerfile,部署该代码,生成镜像
  3. 其他人基于该镜像,docker run就能再电脑上跑这个网站。

具体操作

在宿主机下,准备一个目录,准备好dockerfile,你的代码,写一个flask的python代码flask.py

#coding:utf8
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
  return "hello docker"
if __name__=="__main__":
  app.rum(hoet='0.0.0.0', port=8080)

2. 编写dockerfile

touch Dockerfile(这里代码和Docker处于同一个目录下为例)

FROM centos:7.8.2003
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo;
RUN curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo;
RUN yum makecache fast;
RUN yum install python3-devel python3-pip -y
RUN pip3 install -i https://pypi.douban.com/simple flask
COPY flask.py /opt
WORKDIR /opt
EXPOSE 8080
CMD ["python3", "flask.py"]

3. 构建镜像

docker build –no-cache -t ‘lmk212/my_flask_web’

–no-cache:不使用旧的缓存,重新生成缓存

4. 运行镜像,生成容器

docker run -d –name my_flask_web1 -p 90:8080 lmk212/my_flask_web

5. 访问宿主机,查看网站是否运行

http://172.0.0.1:90/

6. 修改网站的内容,程序是跑在容器中的

  • 修改宿主机的代码,以及dockerfile,重新构建
  • 进入到以及运行的容器内,修改代码,重启容器即可

使用docker exec -it 3dx bash 可以进入容器

Docker compose

docker compose是一个容器编排工具(自动化部署、管理)

可以在单台linux服务器上运行多个docker容器

docker-compose使用yaml文件来配置所有要运行的docker容器,该yaml文件的默认名称为docker-compose.yml

安装流程

# 安装
curl -L https://github.com/docker/compose/releases/download/1.23.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

# 授予执行权限
sudo chmod +x /usr/local/bin/docker-compose

# 验证安装
docker-compose --version

使用案例

创建yml文件

首先在一个文件夹中创建docker-compose.yml文件,写入相关的内容。

version: '3.8'

services:
  zookeeper:
    image: confluentinc/cp-zookeeper:latest # Zookeeper 通常向下兼容,保持最新问题不大
    hostname: zookeeper
    container_name: zookeeper
    ports:
      - "2181:2181"
    environment:
      ZOOKEEPER_CLIENT_PORT: 2181
      ZOOKEEPER_TICK_TIME: 2000
    networks:
      - kafka-net

  kafka:
    image: confluentinc/cp-kafka:7.5.0 # <--- 将此处替换为明确支持 Zookeeper 的旧版本
    # 或者尝试 confluentinc/cp-kafka:7.4.0
    hostname: kafka
    container_name: kafka
    ports:
      - "9092:9092"
    depends_on:
      - zookeeper
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_LISTENERS: PLAINTEXT://kafka:29092,PLAINTEXT_HOST://0.0.0.0:9092
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:9092
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
      KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
      KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
      # KAFKA_PROCESS_ROLES: broker # <--- 移除此行,旧版本通常不需要
    networks:
      - kafka-net

networks:
  kafka-net:
    driver: bridge

networks:
  kafka-net:
    driver: bridge

创建启动容器

在对应文件夹中,运行docker-compose

# 创建容器
docker-compose up -d
# -d: 后台运行所有服务。
# 启动、停止、重启容器
docker-compose start
docker-compose stop
docker-compose restart

查看容器

docker-compose ps -a

停止和清理

docker-compose down

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇