从入门到实践 —— Docker

Docker 介绍

参考:为什么需要Docker?

Docker 是一个开源的应用容器引擎,基于 Go 语言并遵从 Apache2.0 协议开源。

主要应用场景如下:

  1. 环境隔离

    容器间环境相互独立,互不影响。类似于虚拟机,但相比于更轻量。Docker 各个容器共享一个操作系统内核,而每一个虚拟机都有一套完整的操作系统。

  2. 整体部署

    可以将一整套环境构建为镜像,进行整体部署,避免线上线下开发环境带来的各种问题,同时也极大地提高了部署效率,不再需要重复配置开发环境。

Docker 架构

Docker 的三个重要概念:

  1. 镜像(Image)

    相当于一个操作系统模板,比如官方镜像 mysql 就包含了一套完整的操作系统。

  2. 容器(Container)

    容器是镜像运行的实体,好比于 Java 中对象是类的实例。容器可以被创建、启动、暂停和停止等。

  3. 仓库(Repository)

    保存镜像的仓库,好比于 Maven 仓库用来保存依赖的 Jar 包。

Docker 使用客户端-服务器 (C/S) 架构模式,使用远程 API 来管理和创建 Docker 容器。

image
  1. Docker_Client

    通过命令行与 Docker daemon(守护进程)通信。

  2. Docker_Host

    用于执行 Docker daemon 的主机。

  3. Registry

    Docker 仓库,一个 Registry 可以包含多个 Repository 仓库。

Docker 安装

CentOS

卸载旧版本(如果存在)

yum remove docker docker-common docker-selinux docker-engine

安装依赖软件包

yum install -y yum-utils device-mapper-persistent-data lvm2

设置 yum 源

yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

安装 Docker

yum install -y docker-ce docker-ce-cli containerd.io

可能由于版本原因提示 requires containerd.io >= 1.2.2-3,先手动安装新版 containerd.io:

wget https://download.docker.com/linux/centos/7/x86_64/edge/Packages/containerd.io-1.2.6-3.3.el7.x86_64.rpm
yum -y install containerd.io-1.2.6-3.3.el7.x86_64.rpm

然后重新执行 Docker 安装命令即可。

启动并加入开机启动

systemctl start docker && systemctl enable docker

验证

docker version

镜像加速

运行 bash 命令;

curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.io

然后重启 docker 服务;

systemctl daemon-reload && systemctl restart docker

远程访问

修改 docker 服务脚本:

vi /lib/systemd/system/docker.service

ExecStart=/usr/bin/dockerd这一行的后面添加:

 -H tcp://0.0.0.0:2375

然后重启 docker 服务:

systemctl daemon-reload && systemctl restart docker

验证操作结果:

curl http://localhost:2375/version

远程访问(TLS)

上述开放远程访问存在极大的安全隐患,没有认证授权,可采用 TLS 认证完善;

#创建 Docker TLS 证书
#!/bin/bash

#相关配置信息
SERVER="106.13.180.17"
PASSWORD="123456"
COUNTRY="CN"
STATE="湖北省"
CITY="武汉市"
ORGANIZATION="公司名称"
ORGANIZATIONAL_UNIT="Dev"
EMAIL="13437104137@qq.com"

###开始生成文件###
echo "开始生成文件"

#切换到生产密钥的目录
cd /etc/docker   
#生成ca私钥(使用aes256加密)
openssl genrsa -aes256 -passout pass:$PASSWORD  -out ca-key.pem 2048
#生成ca证书,填写配置信息
openssl req -new -x509 -passin "pass:$PASSWORD" -days 3650 -key ca-key.pem -sha256 -out ca.pem -subj "/C=$COUNTRY/ST=$STATE/L=$CITY/O=$ORGANIZATION/OU=$ORGANIZATIONAL_UNIT/CN=$SERVER/emailAddress=$EMAIL"

echo "subjectAltName = IP:$SERVER" >> extfile.cnf
echo "extendedKeyUsage = serverAuth" >> extfile.cnf
#生成server证书私钥文件
openssl genrsa -out server-key.pem 2048
#生成server证书请求文件
openssl req -subj "/CN=$SERVER" -new -key server-key.pem -out server.csr
#使用CA证书及CA密钥以及上面的server证书请求文件进行签发,生成server自签证书
openssl x509 -req -days 3650 -in server.csr -CA ca.pem -CAkey ca-key.pem -passin "pass:$PASSWORD" -CAcreateserial -out server-cert.pem -extfile extfile.cnf

#生成client证书RSA私钥文件
openssl genrsa -out key.pem 2048
#生成client证书请求文件
openssl req -subj '/CN=client' -new -key key.pem -out client.csr

echo "extendedKeyUsage=clientAuth" > extfile.cnf
#生成client自签证书(根据上面的client私钥文件、client证书请求文件生成)
openssl x509 -req -days 3650 -in client.csr -CA ca.pem -CAkey ca-key.pem  -passin "pass:$PASSWORD" -CAcreateserial -out cert.pem -extfile extfile.cnf

#更改密钥权限
chmod 0400 ca-key.pem key.pem server-key.pem
#更改密钥权限
chmod 0444 ca.pem server-cert.pem cert.pem
#删除无用文件
rm client.csr server.csr

echo "生成文件完成"
###生成结束###

同时修改 docker 服务脚本:

vi /lib/systemd/system/docker.service

修改ExecStart=/usr/bin/dockerd这一行为:

ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock \
         --tlsverify \
         --tlscacert=/etc/docker/ca.pem \
         --tlscert=/etc/docker/server-cert.pem \
         --tlskey=/etc/docker/server-key.pem \
         -H tcp://0.0.0.0:2376

重启 docker;

systemctl daemon-reload && systemctl restart docker

连接验证;

docker --tlsverify --tlscacert=/etc/docker/ca.pem   --tlscert=/etc/docker/cert.pem --tlskey=/etc/docker/key.pem -H tcp://106.13.180.17:2376 version

注意服务 IP 填写自己对应的主机 IP。

Hello World

docker run hello-world

运行 hello-world 镜像,先在本地主机查找,不存在则从镜像仓库中拉取。

[root@localhost ~]# docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
1b930d010525: Pull complete 
Digest: sha256:9572f7cdcee8591948c2963463447a53466950b3fc15a247fcad1917ca215a2f
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

常用命令

参考:Docker 命令大全

docker run ubuntu:15.10 /bin/echo "Hello world"

运行一个 ubuntu 容器,版本号为 15.10,并执行 /bin/echo "hello world"。

docker exec -it centos /bin/bash

进入一个 name 为 centos 的容器,并且跳转到该容器 bash 终端。

可选项

  1. -i

    交互式操作,通常和 -t 组合使用;

  2. -t

    在新容器内指定一个伪终端;

  3. -d

    后台运行;

  4. -e

    设置环境变量;

  5. -p

    端口映射,主机端口:容器端口

容器

  1. ps

    获取容器列表;

  2. run

    指定镜像运行一个容器;

  3. start/stop/restart

    启动、停止或重启一个容器;

  4. rm

    删除容器;

  5. exec

    在容器内执行命令;

  6. logs

    获取容器内的日志;

镜像

  1. images

    获取本地镜像列表;

  2. rmi

    删除本地镜像;

部分 <none>:<none> 的镜像没有任何引用,可以通过 docker rmi $(docker images -f "dangling=true" -q) 清除。

实践

时间同步

通常宿主机和 docker 容器机器时间不一致,可采取外部挂载解决;

-v /etc/localtime:/etc/localtime:ro

MySQL 安装

安装

创建一个 mysql 容器,映射本机端口 3306 至容器,并初始化密码为 123456;

docker run -d --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql

数据持久化

每次重新创建 mysql 容器相关数据会被初始化,可以通过 -v 指定挂载路径;

docker run -d --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -v /docker/mysql/data:/var/lib/mysql mysql

添加远程用户

进入 mysql 容器 bash 终端交互;

docker exec -it mysql /bin/bash

连接 mysql 服务;

mysql -uroot -p123456

执行下面 SQL;

create user 'caojiantao'@'%' identified with mysql_native_password by '123456';
grant all privileges on *.* to 'caojiantao'@'%' with grant option;
flush privileges;

SpringBoot 部署(Idea)

Docker 连接

image

如果 docker 远程连接采用 TLS 连接,那么首先将服务器的ca.pemcert.pemkey.pem三个文件下载到本地D:\docker目录,然后如图设置 docker 连接;

image

Dockerfile

新建 Dockerfile 文件,用来构建镜像,放在项目的根目录;

FROM java:8
ADD "/target/docker-0.0.1-SNAPSHOT.jar" "app.jar"
EXPOSE 8080
ENTRYPOINT [ "java", "-jar", "app.jar" ]

镜像部署

增加镜像部署配置,注意最底部 Maven 命令,clean package -DskipTests,用来生成构建镜像需要的 jar 包;

image

外部挂载

通常需要挂载“项目配置”、“静态资源”和“服务日志”几个目录,通过 idea 也能很方便的操作,通过上图中的Bind mounts设置;

image
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容