初识docker—创建WEB应用容器1python+flask

Docker 客户端

docker 客户端非常简单 ,我们可以直接输入 docker 命令来查看到 Docker 客户端的所有命令选项。

runoob@runoob:~# docker

可以通过命令 docker command --help 更深入的了解指定的 Docker 命令使用方法。

例如我们要查看 docker stats 指令的具体使用方法:

runoob@runoob:~# docker stats --help

运行一个web应用

前面我们运行的容器并没有一些什么特别的用处。

接下来让我们尝试使用 docker 构建一个 web 应用程序。

我们将在docker容器中运行一个 Python Flask 应用来运行一个web应用。

runoob@runoob:~# docker run -d -P training/webapp python app.py

参数说明:

  • -d:让容器在后台运行。
  • -P:将容器内部使用的网络端口映射到我们使用的主机上。

    自我练习

    [root@CentOS1611 multi-user.target.wants]# docker ps

    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

    [root@CentOS1611 multi-user.target.wants]# docker images

    REPOSITORY TAG IMAGE ID CREATED SIZE

    hello-world latest 05a3bd381fc2 5 weeks ago 1.84kB

    [root@CentOS1611 multi-user.target.wants]# docker run -d -P training/webapp python app.py

    Unable to find image 'training/webapp:latest' locally

    latest: Pulling from training/webapp

    e190868d63f8: Pull complete

    909cd34c6fd7: Pull complete

    0b9bfabab7c1: Pull complete

    a3ed95caeb02: Pull complete

    10bbbc0fc0ff: Pull complete

    fca59b508e9f: Pull complete

    e7ae2541b15b: Pull complete

    9dd97ef58ce9: Pull complete

    a4c1b0cb7af7: Pull complete

    Digest: sha256:06e9c1983bd6d5db5fba376ccd63bfa529e8d02f23d5079b8f74a616308fb11d

    Status: Downloaded newer image for training/webapp:latest

    e318b989ecc3917d14c834c2e80c26046c1c64bd92522b365185652eca265438

    [root@CentOS1611 multi-user.target.wants]#

     

    查看 WEB 应用容器

    使用 docker ps 来查看我们正在运行的容器

    runoob@runoob:~$ docker ps

    这里多了端口信息。

    PORTS

    0.0.0.0:32769->5000/tcp

    Docker 开放了 5000 端口(默认 Python Flask 端口)映射到主机端口 32769 上。

    这时我们可以通过浏览器访问WEB应用

    我们也可以指定 -p 标识来绑定指定端口。

    runoob@runoob:~$ docker run -d -p 5000:5000 training/webapp python app.py

    docker ps查看正在运行的容器

    容器内部的 5000 端口映射到我们本地主机的 5000 端口上。

     

     

    自我练习

     

    [root@CentOS1611 multi-user.target.wants]# docker ps

    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

    e318b989ecc3 training/webapp "python app.py" 5 minutes ago Up 5 minutes 0.0.0.0:32768->5000/tcp determined_poitras

    [root@CentOS1611 multi-user.target.wants]#

     

    此时我们需要知道这个容器的IP和端口号,从上图可以知道端口号是32768.

    想知道网络信息,可以使用Inspect和network ls查看。看是否是与宿主机是一个IP

    也可以用命令查看详情

    [root@CentOS1611 multi-user.target.wants]# docker inspect e318b989

    [

    {

    "Id": "e318b989ecc3917d14c834c2e80c26046c1c64bd92522b365185652eca265438",

    "Created": "2017-10-19T09:37:11.706960417Z",

    "Path": "python",

    "Args": [

    "app.py"

    ],

    "State": {

    "Status": "running",

    "Running": true,

    "Paused": false,

    "Restarting": false,

    "OOMKilled": false,

    "Dead": false,

    "Pid": 8408,

    "ExitCode": 0,

    "Error": "",

    "StartedAt": "2017-10-19T09:37:11.923778391Z",

    "FinishedAt": "0001-01-01T00:00:00Z"

    },

    "Image": "sha256:6fae60ef344644649a39240b94d73b8ba9c67f898ede85cf8e947a887b3e6557",

    "ResolvConfPath": "/var/lib/docker/containers/e318b989ecc3917d14c834c2e80c26046c1c64bd92522b365185652eca265438/resolv.conf",

    "HostnamePath": "/var/lib/docker/containers/e318b989ecc3917d14c834c2e80c26046c1c64bd92522b365185652eca265438/hostname",

    "HostsPath": "/var/lib/docker/containers/e318b989ecc3917d14c834c2e80c26046c1c64bd92522b365185652eca265438/hosts",

    "LogPath": "/var/lib/docker/containers/e318b989ecc3917d14c834c2e80c26046c1c64bd92522b365185652eca265438/e318b989ecc3917d14c834c2e80c26046c1c64bd92522b365185652eca265438-json.log",

    "Name": "/determined_poitras",

    "RestartCount": 0,

    "Driver": "overlay",

    "MountLabel": "",

    "ProcessLabel": "",

    "AppArmorProfile": "",

    "ExecIDs": null,

    "HostConfig": {

    "Binds": null,

    "ContainerIDFile": "",

    "LogConfig": {

    "Type": "json-file",

    "Config": {}

    },

    "NetworkMode": "default",

    "PortBindings": {},

    "RestartPolicy": {

    "Name": "no",

    "MaximumRetryCount": 0

    },

    "AutoRemove": false,

    "VolumeDriver": "",

    "VolumesFrom": null,

    "CapAdd": null,

    "CapDrop": null,

    "Dns": [],

    "DnsOptions": [],

    "DnsSearch": [],

    "ExtraHosts": null,

    "GroupAdd": null,

    "IpcMode": "",

    "Cgroup": "",

    "Links": null,

    "OomScoreAdj": 0,

    "PidMode": "",

    "Privileged": false,

    "PublishAllPorts": true,

    "ReadonlyRootfs": false,

    "SecurityOpt": null,

    "UTSMode": "",

    "UsernsMode": "",

    "ShmSize": 67108864,

    "Runtime": "runc",

    "ConsoleSize": [

    0,

    0

    ],

    "Isolation": "",

    "CpuShares": 0,

    "Memory": 0,

    "NanoCpus": 0,

    "CgroupParent": "",

    "BlkioWeight": 0,

    "BlkioWeightDevice": null,

    "BlkioDeviceReadBps": null,

    "BlkioDeviceWriteBps": null,

    "BlkioDeviceReadIOps": null,

    "BlkioDeviceWriteIOps": null,

    "CpuPeriod": 0,

    "CpuQuota": 0,

    "CpuRealtimePeriod": 0,

    "CpuRealtimeRuntime": 0,

    "CpusetCpus": "",

    "CpusetMems": "",

    "Devices": [],

    "DeviceCgroupRules": null,

    "DiskQuota": 0,

    "KernelMemory": 0,

    "MemoryReservation": 0,

    "MemorySwap": 0,

    "MemorySwappiness": -1,

    "OomKillDisable": false,

    "PidsLimit": 0,

    "Ulimits": null,

    "CpuCount": 0,

    "CpuPercent": 0,

    "IOMaximumIOps": 0,

    "IOMaximumBandwidth": 0

    },

    "GraphDriver": {

    "Data": {

    "LowerDir": "/var/lib/docker/overlay/486c8e9e565be0450b7af95e3ee4e64f3175864e812b3963bd82d0674362e72d/root",

    "MergedDir": "/var/lib/docker/overlay/eb9d82883cf23ee5f87943ff645256abb0f69f6333a6e07ae3f2d1bc20f19c36/merged",

    "UpperDir": "/var/lib/docker/overlay/eb9d82883cf23ee5f87943ff645256abb0f69f6333a6e07ae3f2d1bc20f19c36/upper",

    "WorkDir": "/var/lib/docker/overlay/eb9d82883cf23ee5f87943ff645256abb0f69f6333a6e07ae3f2d1bc20f19c36/work"

    },

    "Name": "overlay"

    },

    "Mounts": [],

    "Config": {

    "Hostname": "e318b989ecc3",

    "Domainname": "",

    "User": "",

    "AttachStdin": false,

    "AttachStdout": false,

    "AttachStderr": false,

    "ExposedPorts": {

    "5000/tcp": {}

    },

    "Tty": false,

    "OpenStdin": false,

    "StdinOnce": false,

    "Env": [

    "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

    ],

    "Cmd": [

    "python",

    "app.py"

    ],

    "Image": "training/webapp",

    "Volumes": null,

    "WorkingDir": "/opt/webapp",

    "Entrypoint": null,

    "OnBuild": null,

    "Labels": {}

    },

    "NetworkSettings": {

    "Bridge": "",

    "SandboxID": "d11c77eff37a27d80323d2c95b2c59b2a4a472d3ae908095302dc8c1e2478c4f",

    "HairpinMode": false,

    "LinkLocalIPv6Address": "",

    "LinkLocalIPv6PrefixLen": 0,

    "Ports": {

    "5000/tcp": [

    {

    "HostIp": "0.0.0.0",

    "HostPort": "32768"

    }

    ]

    },

    "SandboxKey": "/var/run/docker/netns/d11c77eff37a",

    "SecondaryIPAddresses": null,

    "SecondaryIPv6Addresses": null,

    "EndpointID": "46c8c004298140857b84a51b0a3aa146030e176132aa40ea2c71c6c05fe1edcb",

    "Gateway": "172.17.0.1",

    "GlobalIPv6Address": "",

    "GlobalIPv6PrefixLen": 0,

    "IPAddress": "172.17.0.2",

    "IPPrefixLen": 16,

    "IPv6Gateway": "",

    "MacAddress": "02:42:ac:11:00:02",

    "Networks": {

    "bridge": {

    "IPAMConfig": null,

    "Links": null,

    "Aliases": null,

    "NetworkID": "b9e1d951899da3c16ba5dc6686b54e85c9c49842c3c23d5e3573c1f196b625a7",

    "EndpointID": "46c8c004298140857b84a51b0a3aa146030e176132aa40ea2c71c6c05fe1edcb",

    "Gateway": "172.17.0.1",

    "IPAddress": "172.17.0.2",

    "IPPrefixLen": 16,

    "IPv6Gateway": "",

    "GlobalIPv6Address": "",

    "GlobalIPv6PrefixLen": 0,

    "MacAddress": "02:42:ac:11:00:02",

    "DriverOpts": null

    }

    }

    }

    }

    ]

    [root@CentOS1611 multi-user.target.wants]#

    [root@CentOS1611 multi-user.target.wants]# docker network ls

    NETWORK ID NAME DRIVER SCOPE

    b9e1d951899d bridge bridge local

    7577a140f2d2 host host local

    d4edaa484e93 none null local

     

    由此可以采用桥连接,与宿主机是一个IP,连接验证如下

    网络端口的快捷方式

    通过docker ps 命令可以查看到容器的端口映射,docker还提供了另一个快捷方式:docker port,使用 docker port 可以查看指定 ID或者名字)容器的某个确定端口映射到宿主机的端口号。

    上面我们创建的web应用容器ID:7a38a1ad55c6 名字为:determined_swanson

    我可以使用docker port 7a38a1ad55c6 docker port determined_swanson来查看容器端口的映射情况

    runoob@runoob:~$ docker port 7a38a1ad55c6

    5000/tcp -> 0.0.0.0:5000

    runoob@runoob:~$ docker port determined_swanson

    5000/tcp -> 0.0.0.0:5000

    查看WEB应用程序日志

    docker logs [ID或者名字] 可以查看容器内部的标准输出。

    runoob@runoob:~$ docker logs -f 7a38a1ad55c6

    * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)

    192.168.239.1 - - [09/May/2016 16:30:37] "GET / HTTP/1.1" 200 -

    192.168.239.1 - - [09/May/2016 16:30:37] "GET /favicon.ico HTTP/1.1" 404 -

    -f:表示实时输出。 dokcer logs 像使用 tail -f 一样来输出容器内部的标准输出。(补充:tail –f的意思是什么?tail 命令从指定点开始将文件写到标准输出.使用tail命令的-f选项可以方便的查阅正在改变的日志文件,tail -f filename会把filename里最尾部的内容显示在屏幕上,并且不但刷新,使你看到最新的文件内容用于显示指定文件末尾内容,不指定文件时,作为输入信息进行处理。常用查看日志文件。)

    从上面,我们可以看到应用程序使用的是 5000 端口并且能够查看到应用程序的访问日志。

    自我练习

    宿主机是10.24.11.52,

    查看WEB应用程序日志,下面显示的10.24.12.109是刚才访问过这个应用程序的IP地址。

    [root@CentOS1611 /]# docker ps

    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

    e318b989ecc3 training/webapp "python app.py" 23 minutes ago Up 23 minutes 0.0.0.0:32768->5000/tcp determined_poitras

    [root@CentOS1611 /]# docker logs -f e318b989ecc3

    * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)

    10.24.12.109 - - [19/Oct/2017 09:56:37] "GET / HTTP/1.1" 200 -

    10.24.12.109 - - [19/Oct/2017 09:56:37] "GET /favicon.ico HTTP/1.1" 404 -

    10.24.12.109 - - [19/Oct/2017 09:57:14] "GET / HTTP/1.1" 200 -

    10.24.12.109 - - [19/Oct/2017 09:57:15] "GET /favicon.ico HTTP/1.1" 404 -

     

    [root@CentOS1611 /]#

     

     

     

    查看WEB应用程序容器的进程

    我们还可以使用 docker top 来查看容器内部运行的进程

    runoob@runoob:~$ docker top determined_swanson

    检查WEB应用程序

    使用 docker inspect 来查看Docker的底层信息。它会返回一个 JSON 文件记录着 Docker 容器的配置和状态信息。

    runoob@runoob:~$ docker inspect determined_swanson

    [

    {

    "Id": "7a38a1ad55c6914b360b565819604733db751d86afd2575236a70a2519527361",

    "Created": "2016-05-09T16:20:45.427996598Z",

    "Path": "python",

    "Args": [

    "app.py"

    ],

    "State": {

    "Status": "running",

    ......

    停止WEB应用容器

    runoob@runoob:~$ docker stop determined_swanson

    determined_swanson

    重启WEB应用容器

    已经停止的容器,我们可以使用命令 docker start 来启动。

    runoob@runoob:~$ docker start determined_swanson

    determined_swanson

    docker ps -l 查询最后一次创建的容器:

    正在运行的容器,我们可以使用 docker restart 命令来重启

    移除WEB应用容器

    我们可以使用 docker rm 命令来删除不需要的容器

    runoob@runoob:~$ docker rm determined_swanson

    determined_swanson

    删除容器时,容器必须是停止状态,否则会报如下错误

    runoob@runoob:~$ docker rm determined_swanson

    Error response from daemon: You cannot remove a running container 7a38a1ad55c6914b360b565819604733db751d86afd2575236a70a2519527361. Stop the container before attempting removal or use -f

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐