docker基础

2019-07-16-Docker

docker

什么是docker?

Docker 是一个开源的应用容器引擎,基于Go,Docker 使用客户端-服务器 (C/S) 架构模式,使用远程API来管理和创建Docker容器。Docker 容器通过 Docker 镜像来创建。

容器是解决从一个计算环境移动到另一个计算环境时如何使软件可靠运行的问题的解决方案。这可以是从开发人员的笔记本电脑到测试环境,从临时环境到生产,从数据中心的物理机器到私有云或公共云中的虚拟机。
一个容器包含了完整的运行时环境:一个应用、这个应用所需的全部依赖、类库、其他二进制文件、配置文件,它们统一被打入了一个包中。通过将应用平台和其依赖容器化,操作系统发行版本和其他基础环境造成的差异,都被抽象掉了。

虚拟化和容器有什么不同?

传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。

docker三个基本概念:

  • 镜像(image):镜像采用分层存储 UFS,并不是传统的ISO打包,实际上是由多层文件系统联合组成。镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变后一层上的任何改变只发生在自己这一层。因此每一层尽量只包含该层需要添加的东西,任何额外的东西应该在该层构建结束前清理掉。
  • 容器(container):镜像( Image )和容器( Container )的关系,就像是面向对象程序设计中的 类 和 实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的 命名空间
  • 仓库(repository):Docker 仓库用来保存镜像,可以理解为代码控制中的代码仓库。分为公开与私有。

docker 的安装

docker官方文档

  • 安装前卸载旧版本(centos7):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    $ uname -r
    $ yum update
    $ yum remove docker \
    docker-client \
    docker-client-latest \
    docker-common \
    docker-latest \
    docker-latest-logrotate \
    docker-logrotate \
    docker-engine
  • 安装:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     $ yum install -y yum-utils \
    device-mapper-persistent-data \
    lvm2
    # 官方软件源
    $ yum-config-manager --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo

    # 国内阿里软件源
    $ yum-config-manager --add-repo \
    http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

    $ yum makecache fast
    $ yum list docker-ce --showduplicates |sort -r # 查看所有版本
    $ yum -y install docker-ce
    $ systemctl start docker
    $ systemctl enable docker
    $ docker info // docker version
    $ docker run hello-world
  • 安装前卸载旧版本(Ubuntu 18.04):

    1
    2
    3
    $ uname -r
    $ apt-get update
    $ apt-get remove docker docker-engine docker.io
  • 安装:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    $ apt-get install \
    apt-transport-https \
    ca-certificates \
    software-properties-common \
    curl
    // 官方证书及软件源
    $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
    $ apt-key fingerprint 0EBFCD88 // 验证密钥
    $ add-apt-repository \
    "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
    $(lsb_release -cs) \
    stable"

    # 国内证书及软件源(速度比较快)
    $ curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
    $ apt-key fingerprint 0EBFCD88
    $ add-apt-repository \
    "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu \
    $(lsb_release -cs) \
    stable"

    $ apt-get update
    $ apt-cache madison docker-ce # 查找docker版本
    $ apt-get install docker-ce

    $ systemctl start docker
    $ systemctl enable docker
    $ docker info # docker version
    $ docker run hello-world
  • 镜像加速(/etc/docker/daemon.json):

    1
    2
    3
    4
    5
    6
    7
    {
    "registry-mirrors": [
    "https://registry.docker-cn.com"
    "https://my5f0mvy.mirror.aliyuncs.com"
    ]
    }
    $ systemctl restart docker

docker 的使用(docker –help):

Management Commands

命令 描述
container Manage containers
image Manage images
volume Manage volumes
network Manage networks
builder Manage builds
config Manage Docker configs
engine Manage the docker engine
node Manage Swarm nodes
plugin Manage plugins
secret Manage Docker secrets
service Manage services
stack Manage Docker stacks
swarm Manage Swarm
system Manage Docker
trust Manage trust on Docker images

镜像管理(docker image):

命令 描述
build 构建镜像来自DockerFile
push 推送镜像到仓库
pull 拉取镜像至本地
ls 列出镜像
history 查看镜像历史
inspect 显示一个或多个镜像信息
rm 删除镜像
prune 删除虚悬镜像
tag 创建一个引用源镜像标记目标镜像
export 导出容器文件系统到tar归档文件
import 导入容器文件系统tar创建镜像
save 保存镜像
load 加载镜像来自tar归档文件或标准输入
$ docker image pull
1
2
3
4
5
6
7
8
9
10
$ docker image pull ubuntu:16.04      # 获取镜像
16.04: Pulling from library/ubuntu
bf5d46315322: Pull complete
9f13e0ac480c: Pull complete
e8988b5b3097: Pull complete
40af181810e7: Pull complete
e6f7c7e5c03e: Pull complete
Digest:
sha256:147913621d9cdea08853f6ba9116c2e27a3ceffecf3b492983ae97c3d643fbbe
Status: Downloaded newer image for ubuntu:16.04
$ docker image ls
1
2
3
4
5
6
7
8
9
10
REPOSITORY      TAG     IMAGE ID        CREATED     SIZE
redis latest 5f515359c7f8 5 days ago 183 MB
nginx latest 05a60462f8ba 5 days ago 181 MB
<none> <none> 00285df0df87 5 days ago 342 MB # 虚悬镜像

$ docker image inspect nginx:1.12 # 查看镜像信息
$ docker image rm nginx:1.12
$ docker image ls -f dangling=true # 查询虚悬镜像(filter)
$ docker image prune # 删除虚悬镜像
$ docker image export ID > ID.tar # 导出容器

容器管理(docker container)

命令 描述
create Create a new container
run 运行命令在容器中
exec 运行命令在容器中
ls 列出容器
inspect 显示容器信息
attach 将本地标准输入、输出和错误流附加到正在运行的容器
commit 据容器创建镜像
cp 拷贝文件到容器
logs 容器日志
port 列出/指定容器端口映射
stats 显示容器资源使用统计
top 显示容器运行进程
update 更新容器
stop/start 停止/启动容器
rm 删除容器
选项 描述
-i, –interractive 交互式
-t, –tty 分配伪终端
-d, –detach 后台运行容器
-p, –public list 本地端口映射至容器
-P, –publish-all 随机映射的端口到内部容器开放的网络端口
–net 网络配置
–mount mount 挂载宿主机分区至容器
-v, –volume list 挂载宿主机目录至容器
-a, –attach list 附加到运行的容器
–dns list 设置DNS
-e, –env list 设置环境变量
–env-file list 从文件读取环境变量
-h, –hostname=string 主机名
–ip=string 设置IP
–link list 添加链接到另一个容器
–restart=string 重启
–add-host list 添加其他主机到容器中
–restart=always 始终会重启容器
docker container run
1
2
3
4
5
6
7
8
9
10
11
12
13
$ docker container run -itd --name Ubuntu \ 
ubuntu:16.04 \ # 指定容器版本
bash
$ root@e7009c6ce357:/# cat /etc/os-release
NAME="Ubuntu"
VERSION="16.04.4 LTS, Trusty Tahr"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 16.04.4 LTS"
VERSION_ID="16.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
1
2
3
4
5
6
7
$ docker container start webserver
$ docker container exec -it webserver bash
root@ea4664298c21:/# ls
bin dev etc home proc sys tmp
$ docker container run -itd -p 8080:80 --name nginx01 nginx # 宿主机8080映射到容器80端口
$ docker logs nginx01 # 查看容器日志
$ docker container ps -l # 查看运行的容器

Docker将数据卷挂在至容器中三种方法实现:

命令 说明
create 创建数据卷
inspect 显示数据卷信息
ls 列出数据卷
prune 删除未归属的数据卷
rm 删除数据卷
管理volumes: Docker管理宿主机文件系统的一部分(/var/lib/docker/volumes)
1
2
3
4
5
$ docker volume create nginx-vol
$ docker volume ls
$ docker volume inspect nginx-vol
$ docker run -d -it --name=nginx-test -p 88:80 -v nginx-vol:/usr/share/nginx/html/nginx
$ docker run -d -it --name=nginx-test -p 88:80 --mount src=nginx-vol,dst=/usr/share/nginx/html nginx
清理数据卷
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ docker container stop nginx-test
$ docjer container rm nginx-test
$ docker rm -f $(docker ps -q -a) # 删除所有容器
$ docker volume rm nginx-vol

$ bind mounts: # 存储于宿主机系统的任意位置(必须先创建好挂载数据卷, 否则会报错)
$ docker run -itd --name=nginx-test --mount type=bind,src=/app/wwwroot,dst=/usr/share/nginx/html nginx

# tmpfs: 挂在存储在宿主机系统内存中, 不会写入宿主机的文件系统
$ docker image prune # 批量清理临时镜像文件
$ docker container prune # 批量清理已经停止的容器
$ docker run IMAGE env # 查看镜像支持的环境变量
$ docker kill $(docker ps -q) # 停止所有正则运行的容器
$ docker inspect --format '{{ .State.pid}} <CONTAINER ID or NAME>' # PID
$ docker inspect --format '{{ .Networkings.IPAddress}} <CONTAINER ID or NAME>' # IP

镜像构建(docker builder)

1
2
docker build -t image:1.0 -f /root/Dockerfile  # tag  
docker tag mysql:5.6 myregistry/mysql:version

搭建LNMP网站平台

  • 自定义网络

    1
    docker network create lnmp
  • 创建Mysql数据库容器

    1
    2
    3
    4
    5
    6
    7
    $ docker run -it \
    --name lnmp_mysql \
    --net lnmp \
    -p 3306:3306 \
    --mount src=mysql-vol,dst=/var/lib/mysql \
    -e MYSQL_ROOT_PASSWORD=YourPassword \
    -d mysql:5.7
  • 创建数据库

    1
    2
    $ docker exec lnmp_mysql sh \
    -c 'exec mysql -uroot -p"$MYSQL_ROOT_PASSWORD" -e "create database wordpress"'
  • 创建PHP环境

    1
    2
    3
    4
    5
    6
    $ docker run -it \
    --name lnmp_web \
    --net lnmp \
    -p 8088:80 \
    --mount type=bind,src=/$PWD/app/wwwroot, dst=/var/www/html \
    -d richarvey/nginx-php-fpm
  • 用WordPress博客做测试

    1
    2
    3
    4
    $ wget https://cn.wordpress.org/wordpress-4.7.4-zh_CN.tar.gz
    $ mkdir -p ./app/wwwroot
    $ tar -xzvf wordpress-4.7.4-zh_CN.tar.gz -C /app/wwwroot/
    http://IP:88/wordpress

搭建私有镜像仓库:

1
2
3
4
5
6
7
8
9
10
11
12
$ docker pull registry
$ docker run -d -v /opt/registry:/var/lib/registry -p 5000:5000 --restart=always --name registry registry

$ curl http://IP:5000/v2/_catalog # 客户端
$ vim /etc/docker/daemon.json
{
"registry-mirrors":["https://registry.docker-cn.com"],
"insecure-repository":["IP:5000"]
}
$ docker tag centos:6 IP:5000/centos:6 # 客户端
$ docker push IP:5000/centos:6
$ docker pull IP:5000/centos:6

Docker Hub 公共镜像仓库:

1
2
3
$ docker login
$ docker tag image username/repository:tag
$ docker push username/repository:tag

企业级Docker镜像仓库:

Harbor是VMware开源的企业级Dockers Registry项目, 项目地址, 创建自签名证书, yum install openssl, 路径/etc/pki/tls/certs/Makefile利用make命令生成自签名证书

  • 安装Docker
  • 安装docker-compose
  • 自签TLS证书

    • 证书生成
      1
      2
      openssl req -newkey rsa:4096 -nodes -sha256 -keyout ca.key -x509 -days 365 -out ca.crt  # 生成证书  
      openssl req -newkey rsa:4096 -nodes -sha256 -keyout yourdomain.com.key -out yourdomain.com.csr" # 生成证书请求
  • Harbor安装与配置

    • Harbor离线包地址
    • 配置文件vim harbor.cfg
      1
      2
      3
      4
      5
      hostname = IP或者yourdomain.com
      ui_url_protocol = https/http
      harbor_admin_password = Harboe123456 # 默认密码
      ssl_cert = /data/cert/server.crt
      ssl_cert = /data/cert/server.key
    • ./prepare && ./install.sh # 安装ving启动Harbor
    • docker-compose ps # 查看运行状态, /var/log/harbor
  • Docker主机访问Harbor

Docker 三剑客

docker-compose:

Docker Compose 可以轻松、高效的管理容器,它是一个用于定义和运行多容器 Docker 的应用程序工具

  • 安装:
    1
    2
    3
    4
    5
    6
    $ curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
    $ chmod +x /usr/local/bin/docker-compose
    $ ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
    $ docker-compose -v

    $ curl -L https://raw.githubusercontent.com/docker/compose/1.8.0/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose # bash 补全
使用Django:
  • 使用Docker Compose 配置运行Django/PostgreSQL应用

  • 应用运行在Docker容器里, 通过Dockerfile文件指定Docker容器要安装内容(构建镜像)

    1
    2
    3
    4
    5
    6
    7
    FROM python:3
    ENV PYTHONUNBUFFERD 1
    RUN mkdir /code
    WORKDIR /code
    ADD requirements.txt /code/
    RUN pip install -r requirements.txt
    ADD . /code/
  • requirements.txt 指明依赖包:

    1
    2
    Django>=1.8,<2.0
    psycopg2
  • docker-compose.yml文件将所有相关文件关联:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    version: "3"
    services:
    db:
    image: postgres
    web:
    build: .
    command: python3 manage.py runserver 0.0.0.0:8000
    volumes:
    - .:/code
    ports:
    - "8000:8000"
    links:
    - db
  • $ docker-compose run web django-admin.py startproject django_example .

    • 替换django_example/settings.py的节点信息:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      DATABASES = {
      'default': {
      'ENGINE': 'django.db.backends.postgresql',
      'NAME': 'postgres',
      'USER': 'postgres',
      'HOST': 'db',
      'PORT': 5432,
      }
      }
      $ docker-compose up
    1
      
构建WordPress:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
version: "3"
services:

db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
volumes:
db_data:

构建ELK

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
version: '2.2'
services:
cerebro:
image: lmenezes/cerebro:0.8.3
container_name: cerebro
ports:
- "9000:9000"
command:
- -Dhosts.0.host=http://elasticsearch:9200
networks:
- es7net
kibana:
image: kibana:7.8.0
container_name: kibana7
environment:
- I18N_LOCALE=zh-CN
- XPACK_GRAPH_ENABLED=true
- TIMELION_ENABLED=true
- XPACK_MONITORING_COLLECTION_ENABLED="true"
ports:
- "5601:5601"
networks:
- es7net
elasticsearch:
image: elasticsearch:7.8.0
container_name: es7_01
environment:
- cluster.name=geektime
- node.name=es7_01
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
- discovery.seed_hosts=es7_01,es7_02
- cluster.initial_master_nodes=es7_0,es7_02
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- es7data1:/usr/share/elasticsearch/data
ports:
- 9200:9200
networks:
- es7net
elasticsearch2:
image: elasticsearch:7.8.0
container_name: es7_02
environment:
- cluster.name=geektime
- node.name=es7_02
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
- discovery.seed_hosts=es7_01,es7_02
- cluster.initial_master_nodes=es7_01,es7_02
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- es7data2:/usr/share/elasticsearch/data
networks:
- es7net
volumes:
es7data1:
driver: local
es7data2:
driver: local
networks:
es7net:
driver: bridge

Docker Machine

负责在多种平台上快速安负责在多种平台上快速安装Docker环境, 驱动类型(virtualbox--linux/Win, xhyve--MacOS, hyperv--Win)
Win安装Docker for Windows后, 不能安装virtualbox, 选择 hyperv

  • 安装:

    1
    2
    3
    $ sudo curl -L https://github.com/docker/machine/releases/download/v0.13.0/docker-machine-`uname -s`-`uname -m` > /usr/local/bin/docker-machine
    $ sudo chmod +x /usr/local/bin/docker-machine
    $ docker-machine -v
  • 使用:

    1
    2
    3
    4
    5
    6
    7
    8
    $ docker-machine create -d virtualbox test \  # 创建test Docker主机 -d --driver
    --engine-opt dns=114.114.114.114 \
    --engine-registry-mirror https://registry.docker-cn.com \
    --virtualbox-memory 2048 \
    --virtualbox-cpu-count 2
    $ docker-machine ls
    $ docker-machine env test # env 命令来让后续操作对象都是目标主机
    $ docker-machine ssh test # 登录到主机

Docker Swarm:

提供 Docker 容器集群服务,是 Docker 官方对容器云生态进行支持的核心方案, 用户可以将多个 Docker 主机封装为单个大型的虚拟 Docker 主机,快速打造一套容器云平台
Docker 1.12 Swarm mode 已经内嵌入 Docker 引擎, 成为了 docker 子命令 docker swarm
Swarm 是使用 SwarmKit 构建的 Docker 引擎内置(原生)的集群管理和编排工具.

  • 节点:

    • manager 节点: 用于 Swarm 集群的管理, docker swarn作用仅限于管理节点执行, Swarm集群可以有多个管理节点, 但仅只能有一个leader管理节点;
    • worker 节点: 是任务执行节点, 管理节点将服务 ( service ) 下发至工作节点执行;
    • 服务(Services): 指一组任务的集合,服务定义了任务的属性
      • replicated services: 按照一定规则在各个工作节点上运行指定个数的任务
      • global services: 每个工作节点上运行一个任务
    • 任务(Task): Swarm 中的最小的调度单位,目前来说就是一个单一的容器
  • 创建Swarm集群

    • 初始化Swarm集群(管理节点):
    1
    2
    3
    4
    5
    6
    $ docker swarm init --advertise-addr IP   # --advertise-addr 指定IP
    Swarm initialized: current node (dxn1zf6l61qsb1josjja83ngz) is now a manager.

    To add a worker to this swarm, run the following command:
    docker swarm join --token \ SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c \ 192.168.99.100:2377
    To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
    • 增加工作节点:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    $ docker-machine create -d virtualbox worker1
    $ docker-machine ssh worker1
    docker@worker1:~$ docker swarm join --token\ SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c \ 192.168.99.100:2377

    This node joined a swarm as a worker.

    $ docker-machine create -d virtualbox worker2
    $ docker-machine ssh worker2
    docker@worker1:~$ docker swarm join --token\ SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c \ 192.168.99.100:2377

    This node joined a swarm as a worker.

    $ docker node ls # 查看集群
    ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
    03g1y59jwfg7cf99w4lt0f662 worker2 Ready Active
    9j68exjopxe7wfl6yuxml7a7j worker1 Ready Active
    dxn1zf6l61qsb1josjja83ngz * manager1 Ready Active Leader
  • 部署服务(docker service):

    1
    2
    3
    4
    5
    $ docker service create --replicas 3 -p 80:80 --name nginx nginx:1.13.7-alpine  
    $ docker service ls
    $ docker service ps # 查看某个服务的详情
    $ docker service logs nginx # 查看某个服务的日志
    $ docker service rm nginx

docker基础
https://anyu967.github.io/posts/5ae6092.html
作者
anyu967
发布于
2019年7月16日
许可协议