2、Docker基础用法

容器镜像:https://hub.docker.com/

Docker架构图:  https://ruby-china.org/topics/22004

Docker使用客户端-服务器(client-server)架构模式。Docker客户端会与Docker守护进程进行通信。Docker守护进程会处理复杂繁重的任务,例如建立、运行、发布你的Docker容器。

Docker客户端和守护进程可以运行在同一个系统上,当然你也可以使用Docker客户端去连接一个远程的Docker守护进程。Docker客户端和守护进程之间通过socket或者RESTful API进行通信。

Docker_host端运行一个子程序:Docker_daemon即守护进程,所以运行docker_daemon的进程的服务器就是守护进程服务器。docker_daemon可以监听在套接字上,为了安全,docker_daemon默认只提供本机的unix socket文件的套接字,支持三种类型的套接字:ipv4+端口、ipv6+端口、UNIX Socket file(本地文件),docker_daemon只监听了第三种套接字即本地文件,像mysql只监听了127.0.0.1,所以docker_daemon只允许客户端是本地的。

镜像是分层构建的,需要把镜像下载到本地用以共享,镜像需要在docker主机的本地存储。

由于所有镜像都是只读的,所以启动容器时都是基于镜像来启动,在已有镜像的基础上,为容器创建一个专用的可写层,从而来启动一个容器。

Docker有两个主要的部件:

Docker: 开源的容器虚拟化平台。

Docker Hub: 用于分享、管理Docker容器的Docker SaaS平台。

Docker守护进程

如上图所示,Docker守护进程运行在一台主机上。用户并不直接和守护进程进行交互,而是通过Docker客户端间接和其通信。

Docker客户端

Docker客户端,实际上是docker的二进制程序,是主要的用户与Docker交互方式。它接收用户指令并且与背后的Docker守护进程通信,如此来回往复。

Docker的内部

要理解Docker的内部构建,必须知道以下三种部件:

  • Docker镜像 (Docker images)
  • Docker仓库 (Docker registeries)
  • Docker容器(Docker containers)

Docker镜像

Docker镜像是一个只读的模板。举个例子,一个镜像可以包含一个运行在Apache上的Web应用和其使用的Ubuntu操作系统。

镜像是用来创建容器的。Docker提供了简单的来建立新的镜像或者升级现有的镜像,你也可以下载别人已经创建好的镜像。Docker镜像是Docker的构造部分。

镜像是分层构建的,需要把镜像下载到本地用以共享,镜像需要在docker主机的本地存储。

由于所有镜像都是只读的,所以启动容器时都是基于镜像来启动,在已有镜像的基础上,为容器创建一个专用的可写层,从而来启动一个容器。

Docker仓库

Docker仓库用来保存镜像。可以理解为代码控制中的代码仓库。同样的,Docker仓库也有公有和私有的概念。

公有的Docker仓库名字是Docker Hub。Docker Hub提供了庞大的镜像集合供使用。这些镜像可以是你自己创建的,或者你也可以在别人的镜像基础上创建。Docker仓库是Docker的分发部分。

Docker对象  https://docs.docker.com/engine/docker-overview/

使用Docker时,可以创建和使用图像,容器,网络,卷,插件和其他对象。可以对对象进行增、删、改、查。

Docker容器

Docker容器和文件夹很类似。一个Docker容器包含了所有的某个应用运行所需要的环境。每一个Docker容器都是从Docker镜像创建的。

Docker容器可以运行、开始、停止、移动和删除。每一个Docker容器都是独立和安全的应用平台。Docker容器是Docker的运行部分。

Docker Registry  http://dockone.io/article/104

1、提供镜像存储的仓库

2、提供用户获取镜像时的认证功能

3、提供当前服务器提供的所有服务器的搜索索引

Docker Registry有很多仓库,一个仓库有一个名称,一个仓库只存放一个应用程序的镜像。比如nginx程序,但是nginx会有不同的版本,所以nginx的不同版本都存放在同一个仓库中,这个仓库名称就是应用程序名称:nginx。 

nginx仓库中会存放nginx不同版本:nginx1.10、nginx1.12等,如何标记不同版本的镜像呢?是通过为每一个镜像额外添加一个组件:标签。

所以用  仓库名 + 标签  才能唯一标识一个镜像。如果访问镜像时只给了仓库名,而没有标签,默认是最新标签。

对于程序而言,奇数是开发板,而偶数是稳定版。 

Docker容器是如何工作的

一个Docker容器包含了一个操作系统、用户添加的文件和元数据(meta-data)。我们可以看到,每个容器都是从镜像建立的。镜像告诉Docker容器内包含了什么,当容器启动时运行什么程序,还有许多配置数据。Docker镜像是只读的。当Docker运行一个从镜像建立的容器,它会在镜像顶部添加一个可读写的层,应用程序可以在这里运行。

当你运行docker容器时发生了什么

不论你使用docker命令或者是RESTful API,Docker客户端都会告诉Docker守护进程运行一个容器。

$ sudo docker run -i -t ubuntu /bin/bash

让我们来分析这个命令。Docker客户端使用docker命令来运行,run参数表明客户端要运行一个新的容器。Docker客户端要运行一个容器需要告诉Docker守护进程的最小参数信息是:

  • 这个容器从哪个镜像创建,这里是ubuntu,基础的Ubuntu镜像。
  • 在容器中要运行的命令,这里是/bin/bash,在容器中运行Bash shell。

那么运行这个命令之后在底层发生了什么?

按照顺序,Docker做了这些事情:

  • 拉取ubuntu镜像: Docker检查ubuntu镜像是否存在,如果在本地没有该镜像,Docker会从Docker Hub下载。如果镜像已经存在,Docker会使用它来创建新的容器。
  • 创建新的容器: 当Docker有了这个镜像之后,Docker会用它来创建一个新的容器。
  • 分配文件系统并且挂载一个可读写的层: 容器会在这个文件系统中创建,并且一个可读写的层被添加到镜像中。
  • 分配网络/桥接接口: 创建一个允许容器与本地主机通信的网络接口。
  • 设置一个IP地址: 从池中寻找一个可用的IP地址并且添加到容器上。
  • 运行你指定的程序: 运行指定的程序。
  • 捕获并且提供应用输出: 连接并且记录标准输出、输入和错误让你可以看到你的程序是如何运行的。

你现在拥有了一个运行着的容器!从这里开始你可以管理你的容器,与应用交互,应用完成之后,可以停止或者删除你的容器。

安装及使用docker

镜像:https://mirrors.tuna.tsinghua.edu.cn/

docker软件包 https://mirrors.tuna.tsinghua.edu.cn/centos/7/extras/x86_64/Packages/   但是版本比较老

清华大学的docker的repo文件:https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/

此版本比较新:https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/7/x86_64/stable/Packages/

# cd /etc/yum.repos.d/

# wget https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo  下载repo文件

# vim docker-ce.repo   //由于此文件中指向的docker版本比较老,所以对此文件进行修改

:%a@https://download.docker.com/@https://mirrors.tuna.tsinghua.edu.cn/docker-ce/@

yum.repos.d]# yum repolist

# yum install docker-ce   //如果用老版本的话就是yum install docker

docker程序环境:

环境配置文件:
   /etc/sysconfig/docker-network
   /etc/sysconfig/docker-storage
   /etc/sysconfig/docker
Unit File:
   /usr/lib/systemd/system/docker.service
Docker Registry 配置文件:
   /etc/containers/registries.conf
docker-ce:
   配置文件:/etc/docker/daemon.json   //这个文件默认是不存在的,需要自己创建

Docker镜像加速:为了下载镜像速度较快,需要定义一个镜像加速器

Docker 中国官方镜像加速  https://www.docker-cn.com/registry-mirror   较慢

阿里云加速器

把下面这段话加进到/etc/docker/daemon.json文件中去

{  
"registry-mirrors": ["https://registry.docker-cn.com"]   
}

//上述是json函数的数组,key是registry-mirrors,是https://registry.docker-cn.com,值可以有多个,用","隔开

# mkdir /etc/docker

# vim /etc/docker/daemon.json //添加此段话

{
"registry-mirrors": ["https://registry.docker-cn.com"]
}

# systemctl start docker.service

# docker version  //查看docker版本

Client:
Version: 18.09.2
API version: 1.39
Go version: go1.10.6
Git commit: 6247962
Built: Sun Feb 10 04:13:27 2019
OS/Arch: linux/amd64
Experimental: false

Server: Docker Engine - Community
Engine:
Version: 18.09.2
API version: 1.39 (minimum version 1.12)
Go version: go1.10.6
Git commit: 6247962
Built: Sun Feb 10 03:47:25 2019
OS/Arch: linux/amd64
Experimental: false

# docker info   //查看更为详细的docker信息

Containers: 0
 Running: 0
 Paused: 0
 Stopped: 0
Images: 0
Server Version: 18.09.2
Storage Driver: overlay2
 Backing Filesystem: xfs
 Supports d_type: true
 Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: bridge host macvlan null overlay
 Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 9754871865f7fe2f4e74d43e2fc7ccd237edcbce
runc version: 09c8266bf2fcf9519a651b04ae54c967b9ab86ec
init version: fec3683
Security Options:
 seccomp
  Profile: default
Kernel Version: 3.10.0-957.el7.x86_64
Operating System: CentOS Linux 7 (Core)
OSType: linux
Architecture: x86_64
CPUs: 6
Total Memory: 3.692GiB
Name: node1
ID: LFHI:LTRE:6TA4:CJHP:HHPO:AAIH:I54H:NMPR:CJ4I:SKAI:CAQV:7GRP
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
 127.0.0.0/8
Registry Mirrors:
 https://registry.docker-cn.com/
Live Restore Enabled: false
Product License: Community Engine

# docker  //可以查看docker的子命令

# docker container --help   //现在单独管理

Docker命令: http://dockone.io/article/102    http://www.runoob.com/docker/docker-command-manual.html

Alpine简介   https://yeasy.gitbooks.io/docker_practice/cases/os/alpine.html

下载镜像

# docker image pull nginx:1.14-alpine   //下载nginx的alpine镜像

# docker image ls    //显示镜像

# docker pull busybox

# docker image ls --help

启动容器

# docker container --help   //容器命令

# docker container ls

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

   容器ID     基于哪个镜像启动的容器    在容器中运行的命令                                               容器映射的端口

COMMAND:容器中运行的命令,docker容器是为了运行单个程序的,当基于一个镜像启动一个程序的时候运行哪个程序呢?每个镜像都有定义默认运行的程序。但是也可以修改默认程序。

# docker run --help  http://www.runoob.com/docker/docker-run-command.html

Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

# docker network ls

NETWORK ID          NAME                DRIVER              SCOPE
5ebae7e509fa        bridge              bridge              local   如果不指定,则默认此
b255b50dc21e        host                host                local
db26f5263d07        none                null                local

Docker network 

https://www.ibm.com/developerworks/cn/linux/l-docker-network/index.html    

https://docs.docker.com/network/

启动的容器会自动拥有inet 172.17.0.1网络中的地址,并且是nat桥,即可以进行地址转换,通过inet 192.168.128.131与外界通信,可以请求出去,但无法进来。

# ifconfig  

docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.128.131  netmask 255.255.255.0  broadcast 192.168.128.255
        inet6 fe80::f528:9792:1744:13a7  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:ee:53:1e  txqueuelen 1000  (Ethernet)
        RX packets 109521  bytes 75247038 (71.7 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 161663  bytes 335973137 (320.4 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Docker run 命令

OPTIONS说明:

  • -a stdin: 指定标准输入输出内容类型,可选 STDIN/STDOUT/STDERR 三项;

  • -d: 后台运行容器,并返回容器ID;

  • -i: 以交互模式运行容器,通常与 -t 同时使用;

  • -p: 端口映射,格式为:主机(宿主)端口:容器端口

  • -t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;

  • --name="nginx-lb": 为容器指定一个名称;

  • --dns 8.8.8.8: 指定容器使用的DNS服务器,默认和宿主一致;

  • --dns-search example.com: 指定容器DNS搜索域名,默认和宿主一致;

  • -h "mars": 指定容器的hostname;

  • -e username="ritchie": 设置环境变量;

  • --env-file=[]: 从指定文件读入环境变量;

  • --cpuset="0-2" or --cpuset="0,1,2": 绑定容器到指定CPU运行;

  • -m :设置容器使用内存最大值;

  • --net="bridge": 指定容器的网络连接类型,支持 bridge/host/none/container:<name|id> 四种类型;

  • --link=[]: 添加链接到另一个容器;

  • --expose=[]: 开放一个端口或一组端口;

实例

使用docker镜像nginx:latest以后台模式启动一个容器,并将容器命名为mynginx。

docker run --name mynginx -d nginx:latest

使用镜像nginx:latest以后台模式启动一个容器,并将容器的80端口映射到主机随机端口。

docker run -P -d nginx:latest

使用镜像 nginx:latest,以后台模式启动一个容器,将容器的 80 端口映射到主机的 80 端口,主机的目录 /data 映射到容器的 /data。

docker run -p 80:80 -v /data:/data -d nginx:latest

绑定容器的 8080 端口,并将其映射到本地主机 127.0.0.1 的 80 端口上。

$ docker run -p 127.0.0.1:80:8080/tcp ubuntu bash

使用镜像nginx:latest以交互模式启动一个容器,在容器内执行/bin/bash命令。

runoob@runoob:~$ docker run -it nginx:latest /bin/bash
root@b8573233d675:/#

/ # exit   //退出容器,再次查看时,此容器处于停滞状态

# docker container start -ai busybox    //启动之前创建的容器

# docker rm busybox   //容器停止之后可以删除

# docker ps -a   //再次查看时就没有此容器了

创建nginx容器

# docker run --name web1 -d nginx:1.14-alpine    //即使本地没有镜像也无所谓,会自动下载镜像到本地的

# docker ps   //nginx容器已经启动了
CONTAINER ID        IMAGE               COMMAND                  CREATED          STATUS           PORTS     NAMES
3ecb4f5d9a10        nginx:1.14-alpine   "nginx -g 'daemon of??   2 minutes ago    Up 2 minutes     80/tcp    web1
nginx -g 'daemon of??  //这里创建nginx容器时,是将程序跑在后台的,所以会出现这种问题。在容器中运行任何程序都不要运行在后台,
因为一个容器就是为了运行一个程序,如果这个程序还要在后台运行,那么这个容器就没有程序运行了,
那么没有程序运行容器就会结束,它是唯一进程,是支撑容器的骨架

# docker inspect web1   //查看容器web1的相关信息

{
        "Id": "3ecb4f5d9a109c5714718c81acf592890c9cd6bcee95d0f1e50b103689af1bc0",
        "Created": "2019-02-15T08:45:44.059155956Z",
        "Path": "nginx",
        "Args": [
            "-g",
            "daemon off;"
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 35189,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2019-02-15T08:45:44.947856586Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
。。。
"Networks": { "bridge": { "IPAMConfig": null, "Links": null, "Aliases": null, "NetworkID": "5ebae7e509fa740a57623ec16baa50026135b09c7c98485cbe9784a272e7bdda", "EndpointID": "2bd43ccab59dee023a35dd28cfdc1238dc9e0ee032b5c42daca6f5bf2351ec90", "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 } }

# curl 172.17.0.2   //访问nginx的web页面

# docker run --name kvstor1 -d redis:4-alpine

Unable to find image 'redis:4-alpine' locally    //本地没有此镜象,就下载
4-alpine: Pulling from library/redis
6c40cc604d8e: Already exists 
e42672a2ca6a: Pull complete 
823e4275fef6: Pull complete 
0c49a8a142d3: Pull complete 
62c3ab7a67af: Pull complete 
d8e4fee2dbc2: Pull complete 
Digest: sha256:99c3c1e02e5e794d7309003d4f5d045cba0b94911b9b3a2659bb15e8f4261954
Status: Downloaded newer image for redis:4-alpine
da481ee71e4581928a9c56b975561ddc4f0c8d7e4b627fcb087acf99e60336f5
# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS               NAMES
da481ee71e45        redis:4-alpine      "docker-entrypoint.s??   About a minute ago   Up About a minute   6379/tcp            kvstor1   //正在运行
3ecb4f5d9a10        nginx:1.14-alpine   "nginx -g 'daemon of??   35 minutes ago       Up 34 minutes       80/tcp              web1

# docker container exec --help    //访问redis容器,需要有redis客户端,此镜象自带客户端,所以可以绕过容器的边界登陆进去。

Usage: docker container exec [OPTIONS] CONTAINER COMMAND [ARG...]

# docker exec -it kvstor1 /bin/sh   //

/data # ps
PID   USER     TIME  COMMAND
    1 redis     0:01 redis-server
   12 root      0:00 /bin/sh
   17 root      0:00 ps
/data # netstat -tunlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      -
tcp        0      0 :::6379                 :::*                    LISTEN      -
/data # exit

关于容器的日志,由于一个容器只运行了单个程序,所以就直接把日志发送到了控制台上了,而不是保存在文件中

# docker logs web1   //查看web1容器的日志
     172.17.0.1 - - [15/Feb/2019:09:10:42 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-" 

Docker容器状态的转换和相关常用命令

 

原文地址:https://www.cnblogs.com/hanshanxiaoheshang/p/10387226.html