什么是 Docker

2013 年 dotCloud 公司

使用 Google 公司推出的 Go 语言 进行开发

容器技术的兴起源于 PaaS 技术的普及

Docker 项目通过“容器镜像”,解决了应用打包这个根本性难题

由于云端与本地服务器环境不同,应用的打包过程,一直是使用 PaaS 时最“痛苦”的一个步骤

Cloud Native 的基石

和虚拟机相比

硬件虚拟化

传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程

操作系统虚拟化

容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟
基于 Linux 内核的 Cgroups,Namespace,以及 OverlayFS 类的 Union FS 等技术
容器的本质是一种特殊的进程
“敏捷”和“高性能”是容器相较于虚拟机最大的优势
隔离得不彻底,比如时间
如果你不对容器使用资源做限制,有可能同一台宿主机上的容器会互相影响

镜像必须与 Docker 宿主机系统架构一致

Linux x86_64 架构的系统中只能使用 Linux x86_64 的镜像创建容器
Windows、MacOS 除外,其使用了 binfmt_misc 提供了多种架构支持

为什么要使用 Docker?

更高效的利用系统资源

更快速的启动时间

一致的运行环境

持续交付和部署(CI/CD)

提高了自动化能力
开发人员职能下沉,更接近生产环境
开发和运维的界限越来越小
在更多倾向于使用云端架构的公司或者团队中,传统运维的生存空间越来越小
开发要懂运维的知识,运维也要向开发靠拢

更轻松的迁移

更轻松的维护和扩展

基本概念

镜像

相当于是一个 rootfs(根文件系统)

分层存储

每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层

删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除

每一层尽量只包含该层需要添加的东西,任何额外的东西应该在该层构建结束前清理掉

可以用之前构建好的镜像作为基础层

容器

镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的 类 和 实例

容器是镜像运行时的实例

拥有自己的 root 文件系统、自己的网络配置、自己的进程空间,自己的用户 ID 空间

每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层

容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡

容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化

最核心的三步

启用 Linux Namespace 配置

设置指定的 Cgroups 参数

切换进程的根目录(Change Root)

仓库

公开 Docker Registry

官方的 Docker Hub

CoreOS 的 Quay.io

Google 的 Google Container Registry

阿里、网易

私有 Docker Registry

Harbor

Sonatype Nexus

获取 Docker

https://docs.docker.com/engine/install/

常用命令

获取镜像 docker pull

docker pull nginx

列出镜像 docker images

构建镜像 docker build

docker build -t batizhao/mysql .

推送镜像 docker push

docker push batizhao/mysql

删除镜像 docker rmi

Docker 镜像的导入 docker load 和导出 docker save

容器:docker run、docker stop、docker exec、docker rmi、docker logs

https://docs.docker.com/engine/reference/commandline/images/

数据管理

允许你将宿主机上指定的目录或者文件,挂载到容器里面进行读取和修改操作

挂载主机目录

docker run -v /host/webapp:/opt/webapp:ro
docker run --mount type=bind,source=/host/webapp,target=/opt/webapp,readonly

数据卷

docker volume create my-vol
docker run --mount source=my-vol,target=/opt/webapp

数据卷 可以在容器之间共享和重用,多个容器可以同时以只读或者读写的方式挂载

可以把容器中的数据存储在宿主机之外的地方,比如云存储、NFS

docker volume create --driver local
--opt type=nfs
--opt o=addr=192.168.1.1,rw
--opt device=:/path/to/dir
foo

对 数据卷 的修改会立马生效

对 数据卷 的更新,不会影响镜像

如果挂载一个空的数据卷到容器中的一个非空目录中,那么这个目录下的文件会被复制到数据卷中

如果挂载一个非空的数据卷到容器中的一个目录中,那么容器中的目录中会显示数据卷中的数据;如果原来容器中的目录中有数据,那么这些原始数据会被隐藏掉

数据卷 默认会一直存在,即使容器被删除

使用网络

端口映射

docker run -d -p 5000:5000 training/webapp python app.py

创建网络

docker network create -d bridge my-net

加入网络

docker run -it --rm --name busybox1 --network my-net busybox sh
docker run -it --rm --name busybox2 --network my-net busybox sh

Docker Compose

使用 Dockerfile 定制镜像

Dockerfile 中的每个原语执行后,都会生成一个对应的镜像层

docker build -t batizhao/alpine .

Sending build context to Docker daemon 2.048kB

Step 1/4 : FROM alpine
latest: Pulling from library/alpine
cbdbe7a5bc2a: Pull complete
Digest: sha256:9a839e63dad54c3a6d1834e29692c8492d93f90c59c978c1ed79109ea4fb9a54
Status: Downloaded newer image for alpine:latest
---> f70734b6a266
Step 2/4 : LABEL maintainer="batizhao 

演示 tomcat 项目

Docker Compose

Compose 项目由 Python 编写

调用了 Docker 服务提供的 API 来对容器进行管理

服务 (service):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例

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

演示 haproxy 项目

Docker Swarm

构建 Docker 集群

管理 (manager) 节点和工作 (worker) 节点

一个 Swarm 集群可以有多个管理节点,但只有一个管理节点可以成为 leader,leader 通过 raft 协议实现

内置 kv 存储功能,提供了众多的新特性,比如:具有容错能力的去中心化设计、内置服务发现、负载均衡、动态伸缩、滚动更新

创建集群

docker swarm init

Swarm initialized: current node (0o9duggu853r2jl3xakjlgde9) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-5tco5mtool9s709ne5f5n6zdte8jd09b5srcawwz4kpnoxql1j-1qkzo493fivjyjuwzxjg0k85n 172.31.21.148:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

docker node ls

ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
0o9duggu853r2jl3xakjlgde9 * k8s-148 Ready Active Leader 19.03.5
sn3hbvcm10nhbwr32nj5qvdjw k8s-175 Ready Active 19.03.5
2dxmt7y0l13sjkqvbktvp3s1n k8s-176 Ready Active 19.03.5
btfdk4h3u6tf9nqiap51qx7rg k8s-177 Ready Active 19.03.5

管理集群

docker node ls

ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
0o9duggu853r2jl3xakjlgde9 * k8s-148 Ready Active Leader 19.03.5
sn3hbvcm10nhbwr32nj5qvdjw k8s-175 Ready Active 19.03.5
2dxmt7y0l13sjkqvbktvp3s1n k8s-176 Ready Active 19.03.5
btfdk4h3u6tf9nqiap51qx7rg k8s-177 Ready Active 19.03.5

docker service create --replicas 3 -p 80:80 --name nginx nginx:1.16-alpine
docker service ls
docker service ps nginx
docker service scale nginx=4
docker service scale nginx=2

滚动更新

docker service update --image nginx:1.17-alpine nginx

回滚

docker service rollback nginx

使用 compose 文件

Docker Engine of version 1.13.0 or later
Docker Compose version 1.10 or later
Compose file of version “3.0” or above

演示 python 项目

docker stack deploy --compose-file docker-compose.yml stackdemo
docker stack services stackdemo
docker stack ps stackdemo
docker service logs -f stackdemo_web
docker stack rm stackdemo

开发实践

启动 MySQL Docker 容器

docker run -itd -e MYSQL_ROOT_PASSWORD=passw0rd -e MYSQL_ROOT_HOST=% -e MYSQL_DATABASE=iwamp2 -p 3306:3306 --name=mysql batizhao/mysql:latest

Tomcat Docker 容器连接宿主机 MySQL

docker run -itd -p 9000:8080 --name iwamp2 -v /Users/batizhao/Downloads/web:/opt/tomcat/webapps --add-host='iwamp2.dev:172.17.0.1' batizhao/tomcat:9

Tomcat Docker 容器连接 MySQL Docker 容器

docker run -it -p 9000:8080 --name iwamp2 -v /Users/batizhao/Downloads/web:/opt/tomcat/webapps --link mysql:iwamp2.dev batizhao/tomcat:9

Tomcat Docker 容器连接物理 Oracle 数据库

docker run -itd -p 9000:8080 --name iwamp -v /Users/batizhao/Downloads/web:/opt/tomcat/webapps --add-host='iwamp.dev:172.31.21.216' batizhao/tomcat:9

镜像加速

"registry-mirrors": [
"https://registry.docker-cn.com",
"https://hub-mirror.c.163.com"
]

How to keep your images small

Where and how to persist application data

Use volumes to store container data

Use CI/CD for testing and deployment

Use Docker Engine, not Use Docker Desktop

Always run an NTP client on the Docker host

演示 titans-ims 项目

CI/CD 实践

Jenkins Pipeline

Git Push

Git Clone <- GitLab

Build Maven Package

Build Docker Image

Push Docker Image -> harbor or nexus

Run App

假设不考虑数据库,如果是 Docker 环境如何做?

Sent Email Notification

监控和告警

Prometheus 负责收集数据

Grafana 负责展示数据

微信、钉钉、邮件 负责告警

App 日志汇聚

问题诊断

docker history
docker logs
docker exec
docker pause
docker top
docker stats
docker inspect

Arthas

docker exec -it  ${containerId} /bin/bash -c "wget https://alibaba.github.io/arthas/arthas-boot.jar && java -jar arthas-boot.jar"

方案落地

Docker + Docker Compose

建议在一些小型项目进行尝试,逐渐积累 Docker 的底层运营经验

采用静态调度的方式,比如 Ansible 或 Shell 脚本

为了 100% 自动化,还是需要搭建 CI/CD 流水线

使用本地存储或者集中存储,基本不影响原先的存储方式,采用卷方式挂载

这种方式数据库等有状态服务也可以容器化

Docker + Docker Swarm

在容器编排领域,Swarm 占据 5% 左右的市场份额

适合中型项目,以及对 Docker 有一定经验的团队

拥有动态调度、容错能力、服务发现、负载均衡、动态伸缩、滚动更新等特性的多机集群

需要搭建 CI/CD 流水线

使用集中存储或者分布式存储,采用卷方式挂载

Docker + Kubernetes

在容器编排领域,Kubernetes 占据接近 80% 的市场份额

Kubernetes 为解决应用上云(即云原生应用)而生

Kubernetes 让容器应用进入大规模工业生产,是容器编排系统的事实标准

大型项目,对 Docker 及 Kubernetes 有经验的团队

完善的生态系统

对自动化要求非常高,需要搭建 CI/CD 流水线

分布式存储,采用 PV、PVC、StorageClass 的方式挂载

延伸

Kubernetes/Mesos

Service Mesh

Cloud Native Computing Foundation (CNCF)


标题:Docker 入门及实战
作者:TravelEngineers
地址:https://www.mycitymemory.com/articles/2020/05/06/1588766786011.html
版权声明:转载请注明博文地址,尊重作者劳动成果。
作者简介:坐标魔都,一枚爱旅行爱摄影的攻城狮。愿攻城拔寨的路上,你不用996,也不再孤单,加油。

添加新评论