Docker初探

原文: Docker初探

前言

学习环境是本地虚拟机, linux版本使用CentOS 7.

由于使用最小安装方式, 在学习Docker之前, 顺带总结了下jdk安装和防火墙相关配置.

一: jdk安装

在Centos下安装jdk有多种方式, 例如手动下载tar文件解压, yum安装, rpm安装等.

这里我用yum方式安装:

  • yum list installed |grep java

    查看系统中是否已经安装jdk, 如果有安装想卸载: yum remove xxx即可.

  • yum list java-1.8.0*yum search java|grep jdk

    查看yum库中的jdk安装包.

  • yum -y install java-1.8.0-openjdk

    这里我安装jdk1.8

  • /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.141-1.b16.el7_3.x86_64

    安装完成后的默认目录

  • 验证java命令就可以了.

注意: 这种yum方式安装的是openjdk, 并不是sun jdk. 如果想要sunjdk就用安装方式.

因为这种方式使用alternatives进行版本控制, 所以在没有设置环境变量的情况下也可以执行java命令.

但是对于tomcat或其他软件要使用jdk的话就要设置环境变量了.

对于环境变量设置: 修改/etc/profile文件

#set java environment
JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.141-1.b16.el7_3.x86_64
JRE_HOME=$JAVA_HOME/jre
CLASS_PATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib
PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin
export JAVA_HOME JRE_HOME CLASS_PATH PATH

让修改生效source /etc/profile

二: 防火墙配置

CentOS 7中默认使用firewall作为防火墙, 而6.x中是iptables.

CentOS 7下防火墙的配置, 也支持iptables防火墙. 前提是需要关闭禁止firewall然后安装iptables-services.

二者不能共用.

CentOS7下Firewall防火墙配置用法详解(推荐): https://yq.aliyun.com/ziliao/94786

我觉得既然CentOS 7 中升级到了firewall防火墙, 就没必要切换iptables. 不如就用firewall.

关于firewall的配置, 首先来看两个目录:

  • 系统配置目录: /usr/lib/firewalld/services

    目录中存放定义好的网络服务和端口参数,系统参数,不能修改

  • 用户配置目录: /etc/firewalld/

自定义添加端口

firewall支持两种自定义添加的方式: 命令添加和配置文件添加.

其中, 命令添加方式也会在配置文件中体现

  • 命令添加方式:

    firewall-cmd --permanent --add-port=8050/tcp 
    
    # 指定zone: firewall中有Zone的概念, 可以将具体的端口指定到具体的zone配置文件中.
    firewall-cmd --zone=public --permanent --add-port=8050/tcp
    
    # 参数介绍:
    1. firwall-cmd:是Linux提供的操作firewall的一个工具;
    2. --permanent:表示设置为持久;
    3. --add-port:标识添加的端口;
    4. --zone=public:指定的zone为public;
    

    如果命令指定–zone=dmz, 会在dmz.xml文件中新增一条. 默认zone=public

  • 配置文件添加方式:

    /etc/firewalld/zones目录下添加xml配置, 如public.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <zone>
      <short>Public</short>
      <description>xxx</description>
      <service name="dhcpv6-client"/>
      <service name="ssh"/>
      <port protocol="tcp" port="8050"/>
      <port protocol="tcp" port="8761"/>
    </zone>
    

常用命令

firewall

# 查看firewall服务状态:
systemctl status firewalld

# 查看firewall的运行状态(running or not running):
firewall-cmd --state

# 查看防火墙规则:
firewall-cmd --list-all 

# 查看已开放的端口(--zone可以不写, 默认为public)
firewall-cmd --zone=public --list-ports
# 重启, 开启, 关闭
service firewalld restart 
service firewalld start 
service firewalld stop 
# or
systemctl [stop/stop/restart] firewalld

补充下iptables的基本使用吧

# 查看防火墙启动状态
service iptables status

# 关闭防火墙
service  iptables stop

# 启动防火墙
service  iptables start

# 查看规则列表
iptables --list-rules


# 编辑规则
vim /etc/sysconfig/iptables
# 加入一行
-A INPUT -p tcp -m state --state NEW -m tcp --dport 25 -j ACCEPT

# 保存,重启防火墙
service iptables restart

三: docker

安装方式一

# docker安装: 
yum install -y docker-io

这里docker也可以, 网上有说centos7以上用docker, 我这里用docker-io也没问题

# 启动
systemctl start docker

# 设置开机启动
systemctl enable docker
# 查看docker信息
docker info 

# 查看版本信息
docker version

安装方式二

上面介绍了一键的安装方式, 这里推荐使用官方的安装方式

官方文档: https://docs.docker.com/install/linux/docker-ce/centos/

卸载
$ sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-selinux \
                  docker-engine-selinux \
                  docker-engine
$ sudo rm -rf /var/lib/docker
安装
  • 安装相关工具类

    $ sudo yum install -y yum-utils \
      device-mapper-persistent-data \
      lvm2
    
  • 配置docker仓库

    $ sudo yum-config-manager \
        --add-repo \
        https://download.docker.com/linux/centos/docker-ce.repo
    
  • 安装docker

    $ sudo yum install docker-ce
    

在第二步配置docker仓库错误:

Loaded plugins: fastestmirror
adding repo from: https://download.docker.com/linux/centos/docker-ce.repo
grabbing file https://download.docker.com/linux/centos/docker-ce.repo to /etc/yum.repos.d/docker-ce.repo
Could not fetch/save url https://download.docker.com/linux/centos/docker-ce.repo to file /etc/yum.repos.d/docker-ce.repo
: [Errno 14] curl#35 - "TCP connection reset by pe

这是由于国内访问不到docker官方镜像的缘故, 可以通过aliyun的源来完成

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

镜像

在线拉取: http://hub.docker.com 中查找需要的镜像

docker search xxx命令查找docker.io上的镜像

  • 例如Mysql镜像: 使用docker pull mysql , 会默认从docker.io中拉取.

Tip: docker.io太慢可以用国内的镜像仓库hub.daocloud.io, 或使用daocloud加速器

离线安装: 拷贝tar包至文件中: docker load <./xxx.tar

列出当前镜像: docker images

打包镜像: docker save >./mysql123.tar docker

容器

docker create: image(unioned read file system) -> container(unioned RW file system)
容器创建. 在镜像创建一个容器后加了一层读写层

docker start: 在容器(container)之上启动一个可使用的进程空间, 执行后会进入Created状态

docker create -p 3308:3306 --name mysql2 -e MYSQL_ROOT_PASSWORD=root docker.io/mysql:5.7.14
docker start [container id]

docker run来启动容器

该命令实际包含两个命令: docker createdocker start

# 例如启动两个mysql
docker run -d -p 3306:3306 --name mysql1 -e MYSQL_ROOT_PASSWORD=root docker.io/mysql:5.7.14
docker run -d -p 3308:3306 --name mysql2 -e MYSQL_ROOT_PASSWORD=root docker.io/mysql:5.7.14

参数解释:

-d: 后台运行
-p: 对外暴露的端口
-e: 环境参数
--name: 指定容器名(不指定的话系统随机分配name名)

# 查看容器(加-a表示包括运行和非运行所有状态的)
docker ps -a
# 停止
docker stop [id]

# 删除容器(-f:强制)
docker rm -f  [id]  

# 删除镜像
docker rmi [imageID]

注意: 容器在运行状态时: 可以强制删除容器, 但不能强制删除镜像.

进入容器: docker exec -it [container name or conteiner id] /bin/bash

数据卷

容器中管理数据主要有两种方式:

数据卷(Data Volumes)

数据卷容器(Data Volumes Dontainers)

数据卷管理示例
docker run -d -it --name=centos1 -v /root/dbdata:/test/dbdata docker.io/centos:7.2.1511
# 参数解释
-v: 挂载一个本地的目录到容器中作为数据卷.
例如: -v /xx:/yy: 将容器中的目录/yy挂载到机器中/xx中

这里我遇到过一个问题: Permission denied

这可能会导致容器中映射的目录无权限打开, 或者启动容器后是exited状态.

可以通过docker logs [container id]查看日志.

原因是SELinux导致的. 这货的访问控制策略相当复杂, 很多运维人员的建议都是将他关闭.
查看SELinux状态: /usr/sbin/sestatusgetenforce
关闭: vi /etc/selinux/config 文件, 将SELINUX=enforcing值改为 disabled, 需要重启.

  • 在启动centos1容器后, 在宿主机/root/dbdata和容器/test/dbdata中的任何操作都会互相映射, 相当于一份数据的备份.
  • 关闭或者删除centos1容器后, 宿主机数据依然在, 也可以启动多个容器, 映射数据卷目录中的数据.

示例: mysql数据备份

docker run -d -p 3307:3306 \
-v /mysql/data:/var/lib/mysql  \
-v /mysql/config:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=root \
--name mysqldb1 \
docker.io/mysql:5.7.14

这里如果再启一个mysqldb2测试, mysqldb1状态是run, 启动mysqldb2后, 会出现mysqldb2异常关闭或连接不通的现象.

所以再启动mysqldb2容器时候, mysqldb1不能是run的状态, 因为在-v参数中都有对/mysql/data目录的读写操作.

数据卷容器

数据卷容器: 其实就是一个正常容器, 专门用来提供数据卷供其他容器挂载.

如果你有持续更新的数据需要在容器之间共享. 那么可以创建数据卷容器.

  1. 创建创建一个数据卷容器 data_container

    docker run -it -d -v /dbdata --name data_container docker.io/centos:7.2.1511

  2. 创建centos1, centos2 两个容器, 并挂载data_container容器中的数据卷.

    docker run -it -d --volumes-from data_container --name centos1 docker.io/centos:7.2.1511
    docker run -it -d --volumes-from data_container --name centos2 docker.io/centos:7.2.1511
    

然后这两个容器中都能够共享到数据卷目录/dbdata和其中的数据了.

关于-v参数:

  • 在创建数据卷容器时, -v /dbdata 或 -v /root/dbdata:/dbdata都可以.

    前者只在数据卷容器中创建dbdata目录, 不和本地宿主机映射.

    后者会在本地宿主机也有映射的目录/root/dbdata.

关于--volumes-from参数:

  • 所挂载数据卷的容器自己并不需要保持在运行状态.

  • 可以使用多个, 从而实现从多个容器中挂载多个数据卷.

  • 可以从其他已经挂载了数据卷的容器来挂载数据卷.

利用数据卷容器进行数据迁移备份
  • 备份
# 将数据卷容器(data_container)中的数据备份到宿主机的当前目录
docker run --volumes-from data_container -v $(pwd):/backup --name worker docker.io/centos:7.2.1511 tar cvf /backup/backup.tar /dbdata 

这条命令包含以下几个步骤:

  1. 首先利用centos镜像创建了一个容器worker.

  2. 使用--volumes-from来让worker容器挂载data_container容器的数据卷(即dbdata数据卷).

  3. 使用-v $(pwd):/backup参数来挂载本地的当前目录到worker容器的/backup目录.

  4. worker容器启动后, 使用了tar cvf /backup/backup.tar /dbdata命令来将/dbdata下内容备份为容器

    内的/backup/backup.tar, 即也映射到宿主主机当前目录(pwd)下的backup.tar.

执行成功后在宿主机的当前目录下执行tar xvf backup.tar后看到看到/dbdata备份内容.

  • 恢复
  1. 创建一个带有数据卷的容器:

    docker run -d -it -v /dbdata --name db docker.io/centos:7.2.1511

  2. 创建另外一个新的容器, 挂载db的容器, 并解压备份文件bakup.tar到所挂载的容器卷中.

    docker run --volumes-from db -v $(pwd):/backup docker.io/centos:7.2.1511 tar xvf /backup/backup.tar
    

这样就将宿主机当前目录下的backup.tar恢复到db容器:/dbdata路径下了.

Dockerfile

如何使用Dockerfile构建一个应用程序的镜像.

将应用程序的jpa.jar和Dockerfile文件拷贝到/root/trainning目录下

Dockerfile的内容如下:

# 指定基础image, 要放在前面, 因为后续的指令有依赖域这个image
FROM java:8u102-jdk

# 指定镜像创建者信息
MAINTAINER thank

# 构建指令, RUN可以运行任何被基础image支持的命令
RUN  mkdir /app

# 构建指令, ADD <src> <dest> 从宿主机的src路径拷贝文件到容器中的dest路径
ADD . /app

# 指定容器需要映射到宿主机器的端口
EXPOSE 8888

# 设置container启动时执行的操作
ENTRYPOINT ["java","-jar","/app/jpa.jar","--spring.profiles.active=prod"]

docker build -t jpa:1.0 .: 用当前目录.中的内容构建一个名叫jpa:1.0的镜像.

执行命令后, 会看到以下输出, 每一层都对应Dockerfile文件中定义的指令.

Sending build context to Docker daemon  27.7 MB
Step 1 : FROM java:8u102-jdk
 ---> 69a777edb6dc
Step 2 : RUN mkdir /app
 ---> Running in 6779b11de804
 ---> 44fc7d80f5f6
Removing intermediate container 6779b11de804
Step 3 : ADD . /app
 ---> c419c4d34889
Removing intermediate container 00fa44dcbc4e
Step 4 : EXPOSE 8888
 ---> Running in bb4e70a56e04
 ---> 24e66dd52ee1
Removing intermediate container bb4e70a56e04
Step 5 : ENTRYPOINT java -jar /app/jpa.jar --spring.profiles.active=prod
 ---> Running in b5cbcfce01b1
 ---> 45e74f2c2173
Removing intermediate container b5cbcfce01b1
Successfully built 45e74f2c2173

执行成功后, 该应用程序镜像就构建出来了.

接下来可以启动容器来验证.

docker run -d --name myapp --link mysql:mysql -p 8901:8888 jpa:1.0

参数解释: 
--link mysql:mysql
前面的mysql是mysql容器名. 
后面的mysql是别名, 对应应用程序中的spring.datasource.url=jdbc:mysql://mysql:3306/test中的mysql机器名

-p 8901:8888
前面: 对外暴露的端口号(外界访问的)
后面: 程序容器内暴露的端口号

Docker-compose

Compose是Docker的服务编排工具,主要用来构建基于Docker的复杂应用,Compose 通过一个配置文件来管理多个Docker容器,非常适合组合使用多个容器进行开发的场景

安装方式: https://github.com/docker/compose/releases

docker-compose up

curl -L https://github.com/docker/compose/releases/download/1.8.0-rc1/docker-compose-uname -s-uname -m > /usr/local/bin/docker-compose

chmod +x /usr/local/bin/docker-compose

待续...


问题记录:

问题一

systemctl start docker时报错

有些机器上会出现, 有些不会

通过systemctl status docker.service -l查看详细错误

Error starting daemon: SELinux is not supported with the overlay2 graph driver on this kernel. 
Either boot into a newer kernel or disable selinux in docker (--selinux-enabled=false)

意思是说, 此linux的内核中的SELinux不支持 overlay2 graph driver ,解决方法有两个,要么启动一个新内核,要么就在docker里禁用selinux,--selinux-enabled=false

解决方法:
vi /etc/sysconfig/docker

--selinux-enabled改为--selinux-enabled=false

问题二

我碰到过在虚拟机中启动一个容器时 报出: WARNING: IPv4 forwarding is disabled. Networking will not work.

虽然容器起来了, 但是导致端口转发了, 外部无法访问:

解决办法:

vi /etc/sysctl.conf

或者

vi /usr/lib/sysctl.d/00-system.conf

添加如下代码:

net.ipv4.ip_forward=1

重启network服务

systemctl restart network

查看是否修改成功

sysctl net.ipv4.ip_forward

如果返回为“net.ipv4.ip_forward = 1”则表示成功了

推荐一个解决Docker学习中的疑难杂症: Docker问答录

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

推荐阅读更多精彩内容