Docker容器

Docker使用学习

2020-02-04  本文已影响0人  我只要喝点果粒橙

轻部署,省成本,易迁移

docker和虚拟机VM的区别

一、本质上的区别:

image

VM(VMware)在宿主机器、宿主机器操作系统的基础上创建虚拟层、虚拟化的操作系统、虚拟化的仓库,然后再安装应用;

Container(Docker容器),在宿主机器、宿主机器操作系统上创建Docker引擎,在引擎的基础上再安装应用。

那么问题来了,没有操作系统,怎么运行程序?

可以在Docker中创建一个ubuntu的镜像文件,这样就能将ubuntu系统集成到Docker中,运行的应用就都是ubuntu的应用。

二、使用上的区别:

image

Size:

Startup:

宿主机、镜像与容器

宿主机器: 运行docker的机器

镜像:不可以修改内容

容器:可以修改能内容,相当于虚拟机,默认情况下彼此相互独立(容器之间可以通信)

△.可以依据镜像来创建容器,也可以封装容器为一个镜像,即容器<===>镜像

Docker命令

搜索镜像: docker search python

下载镜像: docker pull NAME

创新容器: docker run -tid (--name xxx) IMAGE ID

运行容器: docker start CONTAINER_ID

进入容器: docker attach CONTAINER_ID

退出容器: ctrl + p + q , 以ctrl + zexit将会终止容器运行

封装容器为镜像: docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

-a :提交的镜像作者;
-c :使用Dockerfile指令来创建镜像;
-m :提交时的说明文字;
-p :在commit时,将容器暂停。

容器通信-创建子节点链接中心节点: docker run -tid (--name xxx) (--link CONTAINER_NAMES) IMAGE ID

查看容器ip: cat /ect/hosts

root@b68943564e76:/# cat /etc/hosts 
127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2  test 4e02c004539e
172.17.0.3  b68943564e76

▲初次使用, ifconfig使用无效,ping也无效,原因如下

我创建的容器是拉取的Base镜像,而因为用Docker拉取的Base镜像如Centos和Ubuntu的话都是最简版本,不包含Ping工具,而对Docker进行Docker network和Docker链接操作时往往要用到Ping工具测试两个容器间的网络,此时就要用到Ping工具了,下面是Ubuntu下安装Ping工具的命令:apt-get update && apt-get install iputils-ping、安装ifconfig工具:apt install net-tools

从容器里面拷文件到宿主机

docker cp 容器名:要拷贝的文件在容器里面的路径 要拷贝到宿主机的相应路径

宿主机上执行:$ docker cp testtomcat:/usr/local/tomcat/webapps/test/js/test.js /opt

从宿主机拷文件到docker容器里面

docker cp 要拷贝的文件路径 容器名:要拷贝到容器里面对应的路径

宿主机上执行$ docker cp requirements.txt apptest:/app

▲注:容器NAME可以通过docker ps命令查看

Dockerfile指令

Dockerfile文件D一定要大写

$ docker build -t="dormanctpress/df_test2" .

  • .为Dockerfile的路径

1.FROM <image>:<tag>

2.MAINTAINER

3.RUN

4.EXPOSE

CMD

ENTRYPOINT

组合使用ENTRYPOINT和CMD: ENTRYPOINT指定命令,CMD指定默认参数

ADD&COPY

共同点

COPY

VOLUME['/data']

WORKDIR /path/to/workdir

ENV <key> <value>

USER daemon

ONBUILD

dockerfile构建过程

  1. 从基础镜像运行一个容器
  2. 执行一条指令,对容器做出修改
  3. 执行类似docker commit的操作,提交一个新的镜像层
  4. 再基于刚提交的镜像运行一个新容器
  5. 执行Dockerfile中的下一条指令,直至所有指令执行完毕

使用中间层镜像进行调试

查找错误

Dockerfile 镜像缓存

构建缓存:将之前的镜像缓存

不使用缓存docker build --no-cache

查看镜像构建的过程

查看构建过程:docker history xxx/yyy

数据卷

sudo docker run -v ~/container_data:/data -it ubuntu /bin/bash

参数说明:使用-v选项,第一个参数为宿主机目录,:后的目录为在容器中使用的目录(挂载);ubuntu为镜像

查看容器是否挂载了数据卷

docker inspect CONTAINER_ID可以查看容器是否挂载了数据卷

给数据卷增加权限

sudo docker run -v ~/datavolume:/data:ro -it ubuntu/bin/bash

ro是read-only

数据卷容器

命名的容器挂载数据卷,其他容器通过挂载这个容器实现数据共享,挂载数据卷的容器,就叫做数据卷容器

挂载数据卷容器的方法

docker run--volumes-from [CONTAINER NAME]

MySQL通信

>>> can't connect to MySQL server on '172.17.0.8'(111)
$ vim /etc/mvsal/my.cnf 
# 将bind-address=127.0.0.1注释掉
>>> Host '2eaf92ef2ff6'is not allowed to connect to this MySQL server
$ create user "weiwei"@"%"identified by"weijc7789"
# 创建用户
$ grant create, select, update, delete, insert on *.* to weiwei;
# 增添权限
$ mysq1-h 172.17.0.8-u weiwei-p
# 链接

redis通信

$ redis-cli -h 172.17.0.8
>>> Could not connect to Redis at 172.17.0.8:6379:Connection refused
$ vim /etc/redis /redis.conf
# 将bind-address=127.0.0.1注释掉

# 如果修改后/ect/init.d/redis-server restart后还是链接不了,重启进入容器
$ redis-cli-h 172.17.0.8-p 6379

一条命令实现停用并删除容器:

docker stop $(docker ps -q) & docker rm $(docker ps -aq)

一条命令删除所有镜像:

docker rmi `docker images -q`

一条命令删除创建失败的镜像:

docker images | sed -n '2p' | awk '{print$3}' | xargs docker rmi

附录

Dockerfile RUN,CMD,ENTRYPOINT命令区别

RUN命令执行命令并创建新的镜像层,通常用于安装软件包

CMD命令设置容器启动后默认执行的命令及其参数,但CMD设置的命令能够被docker run命令后面的命令行参数替换

ENTRYPOINT配置容器启动时的执行命令(不会被忽略,一定会被执行,即使运行 docker run时指定了其他命令)

Shell格式和Exec格式运行命令

我们可用两种方式指定 RUN、CMD 和 ENTRYPOINT 要运行的命令:Shell 格式和 Exec 格式:

CMD 和 ENTRYPOINT 推荐使用 Exec 格式,因为指令可读性更强,更容易理解。RUN 则两种格式都可以。

总结


Docker 运行python flask的web程序

1创建镜像

1.1 ubuntu16.04+python3.6

18.04卡在了PPA环节,并且git安装也没安装上,后来使用了dockerHub上搜素到的github仓库中的16.04 Xenial就解决了。

注:镜像TAG版本需要到dockerHub上才能查看,最初下载成18.04就是因为这个原因被坑了

18.04PPA问题:

aptsources.distro.NoDistroTemplateException: Error: could not find a distribution template for Ubuntu/bionic意思是18.04该PPA没有资源.bionic是版本代号,如16.04的 Xenial

⑴使用下载好的Xenial的Dockerfile进行创建镜像docker run 1604ubuntu .

为了使用国内源用阿里云,先编辑一个sources.list,放在dokcerfile同目录下,作为docker创建镜像时的上下文。

deb-src http://archive.ubuntu.com/ubuntu xenial main restricted #Added by software-properties
deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted
deb-src http://mirrors.aliyun.com/ubuntu/ xenial main restricted multiverse universe #Added by software-properties
deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted
deb-src http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted multiverse universe #Added by software-properties
deb http://mirrors.aliyun.com/ubuntu/ xenial universe
deb http://mirrors.aliyun.com/ubuntu/ xenial-updates universe
deb http://mirrors.aliyun.com/ubuntu/ xenial multiverse
deb http://mirrors.aliyun.com/ubuntu/ xenial-updates multiverse
deb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse #Added by software-properties
deb http://archive.canonical.com/ubuntu xenial partner
deb-src http://archive.canonical.com/ubuntu xenial partner
deb http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted
deb-src http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted multiverse universe #Added by software-properties
deb http://mirrors.aliyun.com/ubuntu/ xenial-security universe
deb http://mirrors.aliyun.com/ubuntu/ xenial-security multiverse

⑵根据官方的镜像来编写自己的Dockerfile创建具有工具的Ubuntu1604

涉及交互式选择项(如下),docker build的时候会报错。设置 DEBIAN_FRONTEND=noninteractive

FROM 1604ubuntu
MAINTAINER mrli
#用ubuntu国内源替换默认源
RUN rm /etc/apt/sources.list
COPY sources.list /etc/apt/sources.list

#安装python3.6必要的包。源镜像太精简了,ip ifconfig之类的都没有。后续安装python pip也需要一些。但是build_essential似乎不必须,先去了。如果后面安装numpy之类需要gcc了,再加上
RUN apt update
#RUN apt upgrade

RUN apt install -y apt-utils apt-transport-https  vim iproute2 net-tools ca-certificates curl build-essential wget python-software-properties software-properties-common psmisc

#安装python3.6 来自第三方
RUN add-apt-repository ppa:jonathonf/python-3.6
RUN apt update
RUN apt install -y python3.6
RUN apt install -y python3.6-dev
RUN apt install -y python3.6-venv

#为3.6安装pip
RUN wget https://bootstrap.pypa.io/get-pip.py
RUN python3.6 get-pip.py

#设置默认python为python3
RUN update-alternatives --install /usr/bin/python python /usr/bin/python2 100
RUN update-alternatives --install /usr/bin/python python /usr/bin/python3 150

#和自带的3.5共存,设置python3默认为3.6
#RUN update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.5 1
RUN update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.6 2

# 更新配置
RUN update-alternatives --config python3
#print()时在控制台正常显示中文
ENV PYTHONIOENCODING=utf-8

在dockerfile所在路径下执行,建立image

docker build -t uos:1604 .

因为开头几步用了国内源,所以非常快。

1.2 开发环境

再建一个dockerfile,开头使用刚才建立的镜像uos1604

FROM uos:1604
MAINTAINER mrli

#代码复制过来后的路径
RUN mkdir /app
# 指定容器启动时执行的命令都在app目录下执行
WORKDIR /app

# 将本地app目录下的内容拷贝到容器的app目录下
COPY ./app/ /app/

# 安装nginx
RUN apt -y install nginx mysql-server 

RUN /etc/init.d/nginx start
# 替换nginx的配置
RUN rm  /etc/nginx/sites-enabled/default
RUN cp nginx.conf /etc/nginx/sites-enabled/nginx.conf

RUN pip3 install uwsgi

#安装需要的python库
# 启动nginx和uwsgi
#ENTRYPOINT pip install -r requirements.txt  -i  https://pypi.tuna.tsinghua.edu.cn/simple some-package --no-cache-dir && service nginx restart && uwsgi --ini uwsgi.ini

# 为了保证能之后进入所以最后一个命令为/bin/sh
ENTRYPOINT pip install -r requirements.txt  -i  https://pypi.tuna.tsinghua.edu.cn/simple some-package --no-cache-dir && service nginx restart && uwsgi --ini uwsgi.ini & && /bin/sh


创建uflask镜像:docker build -t uflask .

根据镜像创建运行容器:docker run -tid -p 12345:80 flaskdemo IMAGE_ID

此时就可以通过VPS的IP地址:宿主机端口访问这个应用程序

查看日志:docker logs 应用名(NAMES)docker logs flaskdemo

关于mysql的建议

mysql建议作为单独容器来跑数据库,然后远程连接数据库.或是使用数据卷

# 
# 搜索
# docker search mysql
# 拉取
# docker pull mysql:5.7
#运行
# docker run --name mysql5.7 -e MYSQL_ROOT_PASSWORD=123456 -p 3307:3306 -d mysql:5.7

2启动容器(转)

2.1手动敲docker命令

先试试用docker命令行启动容器:

docker run --name quotation_api -itd -p 5000:5000 -v /home/quotation:/code quotation_dev:latest

用到的参数分别是

--name为容器命名;

-itd 输入输出终端,后台运行

-p host端口:容器端口

  • 将宿主机5000端口的请求转发到容器5000端口,用5000是flask默认

-v host路径:容器内路径(挂载数据卷)

quotation_dev:latest 最后是使用的镜像名(前面刚用dockerfile build出来的)

然后进入容器

docker attach quotation_api

用python3 main.py启动flask,OK。

这样flask运行在docker里了。

在host改代码,可以看见docker的控制台在更新,和在host一样了。(使用数据卷)

2.2使用dock-compose

如果没有安装先进行安装apt install docker-compose

dock-compose用来管理多个container的运行,特别适合1个host上跑多个container的情况。

得天独厚,docker官网上dock-compose的gettingstarted文档就是flask的(说明flask+docker代表了先进生产力的前进方向O Yeah!),看完了基本就能用了。

dock-compose采用yaml作为配置文件。查了一下,yaml参考了xml和json,以及python的语法,采用了python之缩进,无XML之标记,无json之括号,无字符串之引号。特别适合作为配置文件用。

建立docker-compose.yaml文件(无镜像,但有dockerfile):

version: '2' # 表示该 Docker-Compose 文件使用的是 Version 2 file
services:
  docker-demo:  # 指定服务名称
    build: .  # 指定 Dockerfile 所在路径
    ports:    # 指定端口映射
      - "9000:8761"

建立docker-compose.yaml文件(已有镜像):

version: "3"

services:
  quotation_api:    # 指定服务名称
    image: quotation_dev:latest  # 指定镜像
    volumes:        # 选择数据卷
      - /home/quotation:/code
    ports:          # 端口映射
      - "5000:5000"
    command: python3 main.py    # 执行命令

基本对应手动敲的docker命令,最后还省了敲python3 main.py。

当然如果是部署,这句可以用CMD 写进Dockfile。但是开发过程,文件名之类的会改变,比如最终部署运行用可能是gunicorn+wsgi.py,所以还是写在dockerfile外面比较方便

运行,在控制台执行:docker-compose updocker-compose up -d // 后台启动并运行容器

docker-compose更多介绍

坑点记录

docker容器启动后马上退出解决方案

dokcerfile中的最后一个命令不能在后台执行,不然会启动后马上退出

原因

Docker容器同时只能管理一个进程,如果这个进程退出那么容器也就退出了,但这不表示容器只能运行一个进程(其他进程可在后台运行),但是要使容器不退出必须有一个前台执行的进程。

解决方法

脚本中最后一个进程一定要用前台运行方式即在进程最后不加&(&表示后台运行),否则容器会退出。

如何正确的使用docker attach

Q:由于执行着uwsgi --ini uwsig.ini命令,用户就无法直接进入到容器中去,docker attach CONTAINER_id 就会一直卡着。

A: attach早已过时了,可用: docker exec -it containerID /bin/bash,一开始使用的是/bin/sh然后还是一直卡住.但是/bin/bash是可以的

附Uuntu版本代号:

版本号 代号 发布时间
18.04 Bionic Beaver(仿生海狸) 即将发布2018年4月(LTS)
17.10 Artful Aardvark(机灵的土豚) 2017年10月
16.04 LTS Xenial Xerus 好客的非洲地松鼠 即将发布 2016/4
15.10 Wily Werewolf 狡诈的狼人 2015/10/22
15.04 Vivid Vervet 活泼的小猴 2015/04/23
14.10 Utopic Unicorn 乌托邦独角兽 2014/10/23
14.04 LTS Trusty Tahr 值得信赖的塔尔羊 2014/04/18
13.10 Saucy Salamander 活泼的蝾螈 2013/10/17
13.04 Raring Ringtail 铆劲浣熊 2013/04/25
12.10 Quantal Quetzal 缤纷的绿咬鹃 2012/10/18
12.04 LTS Precise Pangolin 精准的穿山甲 2012/04/26
11.10 Oneiric Ocelot 有梦的虎猫 2011/10/13
11.04 Unity成为默认桌面环境 Natty Narwhal 敏捷的独角鲸 2011/04/28
10.10 Maverick Meerkat 标新立异的的狐獴 2010/10/10
10.04 LTS Lucid Lynx 清醒的猞猁 2010/04/29
9.10 Karmic Koala 幸运的无尾熊 2009/10/29
9.04 Jaunty Jackalope 活泼的兔子 2009/04/23
8.10 Intrepid Ibex 无畏的高地山羊 2008/10/30
8.06 官方查不到此版本发布信息 Haughty Husky 骄傲的哈士奇 2008/06/07
8.04 LTS Hardy Heron 坚强的苍鹭 2008/04/24
7.10 Gutsy Gibbon 勇敢的长臂猿 2007/10/18
7.04 Feisty Fawn 烦躁不安的小鹿 2007/04/19
6.10 Edgy Eft 尖利的小蜥蜴 2006/10/26
6.06 LTS Dapper Drake 整洁的公鸭 2006/06/01
5.10 Breezy Badger 活泼的獾 2005/10/13
5.04 Hoary Hedgehog 白发得刺猬 2005/04/08
**4.10 **初始发布版本 Warty Warthog 多疣的疣猪 2004/10/20

docker-compose使用[转]

docker-compose常见命令

docker-compose ps
docker-compose logs
docker-compose port eureka 8761
docker-compose build
docker-compose start eureka
docker-compose stop eureka
docker-compose rm eureka
docker-compose up
docker-compose kill eureka
docker-compose scale user=3 movie=3
docker-compose run web bash

docker-compose.yml 字段含义

build: ./dir
---------------
build:
    context: ./dir
    dockerfile: Dockerfile
    args:
        buildno: 1
command: bundle exec thin -p 3000
----------------------------------
command: [bundle,exec,thin,-p,3000]
dns: 8.8.8.8
------------
dns:
    - 8.8.8.8
    - 9.9.9.9
dns_search: example.com
------------------------
dns_search:
    - dc1.example.com
    - dc2.example.com
environment:
    RACK_ENV: development
    SHOW: 'ture'
-------------------------
environment:
    - RACK_ENV=development
    - SHOW=ture
env_file: .env
---------------
env_file:
    - ./common.env
expose:
    - "3000"
    - "8000"
image: java
network_mode: "bridge"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]"
ports:   # 暴露端口信息  - "宿主机端口:容器暴露端口"
- "8763:8763"
- "8763:8763"
links:    # 指定服务名称:别名 
    - docker-compose-eureka-server:compose-eureka
volumes:
  - /lib
  - /var
--no-color          单色输出,不显示其他颜.
-f, --follow        跟踪日志输出,就是可以实时查看日志
-t, --timestamps    显示时间戳
--tail              从日志的结尾显示,--tail=200

更新容器

links

version: '2'
services:
    web:
        build: .
        links:
            - "db:database"
    db:
        image: postgres

docker stop containerID,以后再重新启动时报错

Error response from daemon: driver failed programming external connectivity on endpoint app (3c0c01ac6b42b7a420644fc2b4debfbbcc0e1d2e74e6294155c28aca82f794c4):  (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 12345 -j DNAT --to-destination 172.17.0.2:80 ! -i docker0: iptables: No chain/target/match by that name.

A: 重启docker即可:systemctl restart docker

再开启你的容器: docker run xxxxdocker start xxx

查看docker容器的运行日志

docker logs containerID

docker端口映射到宿主机后外网仍无法访问容器的web

A:

# 解决办法:
$ sudo vi /etc/sysctl.conf
或者
$ sudo  vi /usr/lib/sysctl.d/00-system.conf
# 添加如下代码:
net.ipv4.ip_forward=1

重启network服务
$ sudo systemctl restart network

查看是否修改成功
$ sudo sysctl net.ipv4.ip_forward

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

安装

由于ubuntu维护的docker版本比较老,所以建议使用docker自己维护的版本

法一:

较为麻烦

apt-get update
apt-get install-y apt-transport-https
echo deb https://get.docker.com/ubuntu docker main>/etc/apt/
sources.list.d/docker.list
# 添加仓库的key
$apt-key adv--keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9
#安装
$ apt-get update
$ apt-get install -y lxc-docker

法二:

docker简易安装方法->脚本

# 如果没有安装curl,先安装curl
$ sudo apt-get install -y curl
# 淘汰!
$ curl -sSL https://get.docker.com/ubuntu/ | sudo sh
# 推荐用wget
$ wget -qO- https://get.docker.com/ | sh
上一篇下一篇

猜你喜欢

热点阅读