Docker概述
参考
0. Docker官网 https://docs.docker.com/
1. Docker 笔记总结
5. Docker — 从入门到实践book
6. 只要一小时,零基础入门Docker 知乎
7. docker的使用及原理 知乎
8. docker walkthrough 介绍目前docker层级:container、service、swarm、stack、docker enterprise engine(docker EE)
9. 阿里云栖社区docker技术 https://yq.aliyun.com/topic/78?utm_campaign=wenzhang&utm_medium=article&utm_source=QQ-qun&utm_content=m_8922
什么是Docker?
Docker 是世界领先的软件容器平台。开发人员利用 Docker 可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用 Docker 可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用 Docker 可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为 Linux 和 Windows Server 应用发布新功能。
Docker 属于 Linux 容器的一种封装,提供简单易用的容器使用接口。它是目前最流行的 Linux 容器解决方案。Docker 将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。有了 Docker,就不用担心环境问题。
总体来说,Docker 的接口相当简单,用户可以方便地创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。
Docker核心解决的问题是利用LXC来实现类似VM的功能,从而利用更加节省的硬件资源提供给用户更多的计算资源。
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。
Docker vs VM
从下图可以看出,VM是一个运行在宿主机之上的完整的操作系统,VM运行自身操作系统会占用较多的CPU、内存、硬盘资源。Docker不同于VM,只包含应用程序以及依赖库,基于libcontainer运行在宿主机上,并处于一个隔离的环境中,这使得Docker更加轻量高效,启动容器只需几秒钟之内完成。由于Docker轻量、资源占用少,使得Docker可以轻易的应用到构建标准化的应用中。但Docker目前还不够完善,比如隔离效果不如VM,共享宿主机操作系统的一些基础库等;网络配置功能相对简单,主要以桥接方式为主;查看日志也不够方便灵活。
Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容器的创建和维护。使得 Docker 技术比虚拟机技术更为轻便、快捷。
作为一种新兴的虚拟化方式,Docker 跟传统的虚拟化方式相比具有众多的优势。Docker 容器的启动可以在秒级实现,这相比传统的虚拟机方式要快得多;Docker 对系统资源的利用率很高,一台主机上可以同时运行数千个 Docker 容器。
Docker组成
Docker基于go语言并遵从Apache2.0协议开源。Docker是CS架构,主要有两个概念:
Docker daemon
运行在宿主机上,Docker守护进程,用户通过Docker client(Docker命令)与Docker daemon交互。
Docker client
Docker 命令行工具,是用户使用Docker的主要方式,Docker client与Docker daemon通信并将结果返回给用户,Docker client也可以通过socket或者RESTful api访问远程的Docker daemon。
了解了Docker的组成,再来了解一下Docker的三个主要概念:
Docker image
镜像是只读的,镜像中包含有需要运行的文件。镜像用来创建container,一个镜像可以运行多个container;镜像可以通过Dockerfile创建,也可以从Docker hub/registry上下载。镜像可以拷贝到任何装了docker的机器上运行。
对于 Linux 而言,内核启动后,会挂载 root 文件系统为其提供用户空间支持。而 Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:16.04 就包含了完整的一套 Ubuntu 16.04 最小系统的 root 文件系统。镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。
Docker container
容器是Docker的运行组件,启动一个镜像就是一个容器,容器是一个隔离环境,多个容器之间不会相互影响,保证容器中的程序运行在一个相对安全的环境中。注意:镜像本身是只读的,容器从镜像启动时,Docker在镜像的上层创建一个可写层,镜像本身不变。
按照 Docker 最佳实践的要求,容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化。所有的文件写入操作,都应该使用 数据卷(Volume)、或者绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。
Docker repository
仓库,类似代码仓库,这里是镜像仓库,是Docker用来集中存放镜像文件的地方。注意与注册服务器(registry)区别,registry共享和管理Docker镜像,用户可以上传或者下载上面的镜像,官方地址为https://registry.hub.docker.com/,也可以搭建自己私有的Docker registry。注册服务器是存放仓库的地方,一般会有多个仓库;而仓库是存放镜像的地方,一般每个仓库存放一类镜像,每个镜像利用tag进行区分,比如Ubuntu仓库存放有多个版本(12.04/14.04等)的Ubuntu镜像。仓库名经常以 两段式路径 形式出现,比如 88yuxi/docker_hello,前者往往意味着 Docker Registry 多用户环境下的用户名,后者则往往是对应的软件名。但这并非绝对,取决于所使用的具体Docker Registry的软件或服务。
由于某些原因,在国内访问这些服务可能会比较慢。国内的一些云服务商提供了针对 Docker Hub 的镜像服务(Registry Mirror),这些镜像服务被称为加速器。常见的有 阿里云加速器、DaoCloud 加速器 等。使用加速器会直接从国内的地址下载 Docker Hub 的镜像,比直接从 Docker Hub 下载速度会提高很多。在 安装 Docker 一节中有详细的配置方法。
国内也有一些云服务商提供类似于 Docker Hub 的公开服务。比如 时速云镜像仓库、网易云镜像服务、DaoCloud 镜像市场、阿里云镜像库 等。
arm64v8镜像地址:https://hub.docker.com/u/arm64v8,可直接搜索arm64v8获取。
镜像就相当于打包好的版本,镜像启动之后运行在容器中,仓库就是装存储镜像的地方。镜像和容器的关系类似面向对象的类和对象。
Docker应用
docker安装
wget -qO- https://get.docker.com | sh
wget命令下载docker脚本到标准输出,然后通过管道sh执行,其中-O-表示打印下载内容到标准输出。
实际上从get.docker.com获取了一个脚本,然后自动运行脚本(可通过wget get.docker.com下载脚本查看其内容)。
# Executing docker install script, commit: 36b78b2 + sudo -E sh -c apt-get update -qq >/dev/null + sudo -E sh -c apt-get install -y -qq apt-transport-https ca-certificates curl >/dev/null + sudo -E sh -c curl -fsSL "https://download.docker.com/linux/ubuntu/gpg" | apt-key add -qq - >/dev/null Warning: apt-key output should not be parsed (stdout is not a terminal) + sudo -E sh -c echo "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic edge" > /etc/apt/sources.list.d/docker.list + [ ubuntu = debian ] + sudo -E sh -c apt-get update -qq >/dev/null + sudo -E sh -c apt-get install -y -qq --no-install-recommends docker-ce >/dev/null + sudo -E sh -c docker version Client: Version: 18.06.1-ce API version: 1.38 Go version: go1.10.3 Git commit: e68fc7a Built: Tue Aug 21 17:24:51 2018 OS/Arch: linux/amd64 Experimental: false Server: Engine: Version: 18.06.1-ce API version: 1.38 (minimum version 1.12) Go version: go1.10.3 Git commit: e68fc7a Built: Tue Aug 21 17:23:15 2018 OS/Arch: linux/amd64 Experimental: false If you would like to use Docker as a non-root user, you should now consider adding your user to the "docker" group with something like: sudo usermod -aG docker wang Remember that you will have to log out and back in for this to take effect! WARNING: Adding a user to the "docker" group will grant the ability to run containers which can be used to obtain root privileges on the docker host. Refer to https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface for more information.
当要以非root用户可以直接运行docker时,需要执行 sudo usermod -aG docker wang 命令,然后重新登陆,否则会有如下报错:
wang@ubuntu:~/docker$ docker run hello-world docker: Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post http://%2Fvar%2Frun%2Fdocker.sock/v1.38/containers/create: dial unix /var/run/docker.sock: connect: permission denied. See 'docker run --help'.
运行测试程序hello-world
wang@ubuntu:~/docker$ docker run hello-world Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world d1725b59e92d: Pull complete Digest: sha256:0add3ace90ecb4adbf7777e9aacf18357296e799f81cabc9fde470971e499788 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服务启动:
# service命令的用法
$ sudo service docker start
# systemctl命令的用法
$ sudo systemctl start docker
默认情况下Docker的存放位置为/var/lib/docker。Docker 的配置文件可以设置大部分的后台进程参数,在各个操作系统中的存放位置不一致,在 Ubuntu 中的位置是:/etc/default/docker,在 CentOS 中的位置是:/etc/sysconfig/docker。
arm64v8下安装docker和docker-compose:
apt-get install docker.io
apt-get install docker-compose
docker-compose需要和docker版本匹配,系统默认的docker-compose版本较低:
apt-get install python-pip
pip install –upgrade pip
pip install docker-compose==1.17.0
注:pip安装时经常出错,是因为docker-compose是用python开发的,不同版本的docker-compose对python版本有要求。可参考pypi中docker-compose需求:https://pypi.org/project/docker-compose/
Centos下直接安装docker-compose指定版本:
wget -qO- https://get.docker.com | sh yum install -y epel-release yum install python-pip pip install --upgrade pip pip install docker-compose==1.24.1 # docker --version Docker version 19.03.8, build afacb8b # docker-compose --version docker-compose version 1.24.1, build 4667896
docker命令基础
docker run ubuntu:15.10 /bin/echo 'hello world'
参数解析:
run:与前面的docker组合来运行一个容器
ubuntu:15.10指定要运行的镜像,docker首先从本地主机上查找镜像是否存在,如果不存在docker就会从镜像仓库docker hub下载公共镜像。
/bin/echo 'hello world':在启动的容器里执行的命令。
以上命令完整的意思:docker以Ubuntu15.10镜像创建一个新容器,然后在容器里执行/bin/echo 'hello world',然后输出结果。
docker run -i -t ubuntu:15.10 /bin/bash
参数解析:
-t:在新容器内指定一个伪终端或终端。
-i:允许对容器内的标准输入(STDIN)进行交互。
查看当前系统Docker信息
docker info
Docker加速
因为国内连接 Docker 的官方仓库很慢,因此我们在日常使用中会使用Docker 中国加速器。通过 Docker 官方镜像加速,中国区用户能够快速访问最流行的 Docker 镜像。该镜像托管于中国大陆,本地用户现在将会享受到更快的下载速度和更强的稳定性,从而能够更敏捷地开发和交付 Docker 化应用。
Docker 中国官方镜像加速可通过registry.docker-cn.com访问。该镜像库只包含流行的公有镜像,私有镜像仍需要从美国镜像库中拉取。
修改系统中docker对应的配置文件即可,如下:
vi /etc/docker/daemon.json #添加后 { "registry-mirrors": ["https://registry.docker-cn.com"], "live-restore": true }
镜像操作
搜索镜像
docker image search ubuntu
从官方注册服务器(hub.docker.com)的仓库中pull下centos的镜像,每个仓库会有多个镜像,用tag标识,如果不加tag,默认使用latest镜像:
镜像的操作命令一般以docker image开头,有时image可以省略。
拉取docker镜像
docker image pull image_name
查看宿主机上的镜像,Docker镜像保存在/var/lib/docker目录下:
docker image ls
删除镜像
docker image rm docker.io/tomcat:7.0.77-jre7 或者 docker image rm b39c68b7af30
容器操作
容器的操作命令一般以docker container开头,一般container可以省略。
查看当前有哪些容器正在运行
docker ps 或 docker container ls ; docker ps和docker container ls 等价
查看所有容器
docker ps -a 或 docker container ls --all
docker ps -q ;仅仅显示容器IDs
启动、停止、重启容器命令
docker start container_name/container_id
docker stop container_name/container_id
docker restart container_name/container_id
docker stop $(docker ps -q) ;停用全部运行中的容器
终止容器
docker kill container_name/container_id
后台启动一个容器后,如果想进入到这个容器,可以使用attach命令
docker attach container_name/container_id
docker exec -t -i $container_id $cmd ;可以执行一个运行中的容器中的任何命令,并打开与STDIN的交互
删除容器的命令
docker rm container_name/container_id
docker rm $(docker ps -aq) ;删除全部容器
启动一个容器使用docker run
docker run -i -t ubuntu /bin/bash 启动一个容器
docker run -i -t --rm ubuntu /bin/bash --rm表示容器退出后立即删除该容器
docker run -t -i --name test_container ubuntu /bin/bash --name指定容器的名称,否则会随机分配一个名称
docker run -t -i --net=host ubuntu /bin/bash --net=host容器以Host方式进行网络通信
docker run -t -i -v /host:/container ubuntu /bin/bash -v绑定挂在一个Volume,在宿主机和Docker容器中共享文件或目录
docker run -d ubuntu sleep 10 -d参数表示daemon,即运行守护进程。
容器提交docker commit
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
使用docker commit可以将container的变化作为一个新的镜像,比如:
xzs@host:~(0)$ docker commit -m="test docker commit" 50a1261f7a8b docker_test
55831c956ebf46a1f9036504abb1b29d7e12166f18f779cccce66f5dc85de38e
xzs@host:~(0)$ docker images | grep docker_test
docker_test latest 55831c956ebf 10 seconds ago 290.7 MB
将一个容器(运行中或者Exit状态都可以) 做一次commit,就可以做成一个本地镜像, 这种方式做镜像比较方便,但是项目的其它成员就不太清楚这个镜像的具体生成细节,不易维护。
容器自启动
docker run --restart always --name mynginx -d nginx
# 多个参数值选择 no 不自动重启容器. (默认值) on-failure 容器发生error而退出(容器退出状态不为0)重启容器,可以指定重启的最大次数,如:on-failure:10 unless-stopped 在容器已经stop掉或Docker stoped/restarted的时候才重启容器 always 在容器已经stop掉或Docker stoped/restarted的时候才重启容器,手动stop的不算
如果容器已经被创建,我们想要修改容器的重启策略
docker update --restart no mynginx
注:容器只有在成功启动后restart policy才能生效。这里的"成功启动"是指容器处于up至少10秒且已经处于docker监管。这是避免没有成功启动的容器陷入restart的死循环。
注:如果手动stop一个容器,容器设置的restart policy将会被忽略,除非Docker守护进程重启或者容器手动重启;这是避免了如果重启策略设置了always,如果不忽略policy那么容器无法手动停止。
镜像制作
制作镜像有两种方式:docker commit和Dockerfile。docker commit方式参考“容器操作”部分。
可以用dockerfile创建一个镜像,dockfile格式详见官网:https://docs.docker.com/engine/reference/builder/,可参考:https://www.douban.com/note/731171619/命令解析
# comment
INSTRUCTION arguments
Dockeefile必须“FROM”指令开头。
以创建一个Django程序为例,Dockerfile如下所示:
xzs@host:/tmp/docker(0)$ cat Dockerfile # 说明该镜像以哪个镜像为基础 FROM ubuntu:12.04 # 构建者的基本信息 MAINTAINER Your Name # 在build这个镜像时执行的操作 RUN apt-get update RUN apt-get install -y python-software-properties python-pip ADD myproject /opt/code RUN pip install -r /opt/code/requirement.txt
交叉编译mosquitto后制作docker:
#Dockerfile FROM armhf/ubuntu:latest #COPY bin sbin lib include /usr/ COPY bin /usr/bin COPY sbin /usr/sbin COPY lib /usr/lib COPY include /usr/include CMD ["/usr/sbin/mqtt_random_nopasswd"]
写完Dockerfile,在Dockerfile所在目录执行docker build创建镜像:
docker build -t docker_test . 或
docker build -t docker_test -f dockerfile .
注:docker会删除中间层创建的容器,但不会删除中间层镜像,所以可以使用docker run运行一个中间层容器,从而查看每一步构建后的镜像状态,这样就可以进行调试。
注:docker在构建过程中会将之前构建的镜像看做缓存。当第一次构建的时候,构建过程会比较慢,而在此进行相同的构建的时候,会看见using cache字样,表示使用了缓存,构建过程也非常快。
如果不想使用构建缓存,则在docker build中使用—no-cache选项。还可以在Dockerfile中使用ENV REFRESH_DATE 2018-01-01来制定缓存刷新时间,更改这个时间,就会让后面的命令不使用缓存。
注:docker中的所有应用后应该是前台执行,容器里面没后台服务的概念。对于容器而言,其启动程序就是容器应用进程,容器就是为了主进程而存在的,主进程退出,容器就失去意义,所以退出,其他辅助进程不是它所关心的。一般初学者将CMD写为CMD service nginx start.然后容器执行就退出了。可以加tail命令,tail可阻塞,挂起一个主进程,类似前台启动。
上传镜像
将制作的镜像上传到private registry:
docker tag docker_test docker.example.com/test
docker push docker.example.com/test
也可上传到公共仓库hub.docker.com,首先要登录:
wang@ubuntu:~/docker$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: wyuxi
Password:
WARNING! Your password will be stored unencrypted in /home/wang/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
wang@ubuntu:~/docker$ docker push docker_hello
The push refers to repository [docker.io/library/docker_hello]
b5965ff8f7d7: Preparing
5d34ba700229: Preparing
76c033092e10: Preparing
2146d867acf3: Preparing
ae1f631f14b7: Preparing
102645f1cf72: Waiting
denied: requested access to the resource is denied
wang@ubuntu:~/docker$ docker push wyuxi/docker_hello
The push refers to repository [docker.io/wyuxi/docker_hello]
b5965ff8f7d7: Pushed
5d34ba700229: Pushed
76c033092e10: Pushed
2146d867acf3: Pushed
ae1f631f14b7: Pushed
102645f1cf72: Pushed
latest: digest: sha256:6e233688bfb2a07dabf40e29182eeaed48e146b5848241eba36909d500658477 size: 1564
注:docker镜像名必须以用户名开头才能上传到相应账号下。
注:docker push中包含了镜像仓库的地址,默认为docker.io。
注:docker官方默认registry地址为docker.io,官方镜像通过用户名library来区分,如docker.io/library/hello-world,若下载dockerhub官方镜像,则docker.io/library可以省略。
端口映射
docker可以通过Dockerfile在制作镜像时暴露一些端口出来,如web的80端口。 那么就需要在宿主机中指定一个端口映射到容器中的端口。
使用-P参数让容器启动时自动分配宿主机的端口到容器的端口,小写的-p可以显示指定主机端口。
当使用 -P 标记时,Docker 会随机映射一个 49000~49900 的端口到内部容器开放的网络端口。
docker run -d -P(大写) $image_name [$cmd]
docker run -d -p(小写) 主机端口:容器暴露的端口 $image_name [$cmd]
-p 则可以指定要映射的端口,并且,在一个指定端口上只可以绑定一个容器。支持的格式有
ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort。
wang@ubuntu:~$docker run -it -p 80:10000 88yuxi/docker_hello /bin/bash
wang@ubuntu:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0640558f1132 88yuxi/docker_hello "/bin/bash" 2 minutes ago Up 2 minutes 0.0.0.0:80->10000/tcp stupefied_mcnulty
wang@ubuntu:~$ docker port 064055
10000/tcp -> 0.0.0.0:80
文件映射
容器中产生的文件随着容器被删除也会被删除,这时有3种方法来持久化数据:
1. 容器删除前做一次commit,将容器的最新状态及数据做成一个镜像,然后更新到镜像仓库。
2. 使用这里说的文件映射,将主机中的一个目录映射到容器中,这种方法有很多使用场景,如在宿主机上看到容器的log文件,或者将mysql的data数据关联到宿主机的某个目录下,这样即使是容器被删,数据还是保留着的。
docker run -v 主机目录:容器目录 $image_name [$cmd]
注意-v的两个目录都需要为绝对路径。
3. 使用数据卷(volume)。数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。因此,使用数据卷后,容器删除或者重新运行之后,数据却不会丢失。数据卷 的使用,类似于 Linux 下对目录或文件进行 mount,镜像中的被指定为挂载点的目录中的文件会隐藏掉,能显示看的是挂载的 数据卷。
环境变量
-e后面可以指定一些环境变量值,在容器运行的时候可以读到这些变量,容器的启动脚本可以使用这些变量做一些宏替换等操作,达到读取启动参数的目的。
docker run -e VAR_1=xxx -e VAR_2=yyy $image_name [$cmd]
更改环境变量HOSTNAME为wang,增加启动参数ARGS变量。
docker run -it -e HOSTNAME=wang -e ARGS="-a -p -l wang" 88yuxi/docker_hello /bin/bash
容器连接
容器1: docker run --name container_1_name ...
容器2: docker run --link container_1_name:container_1_name_in_container2 ...
这样容器2就可以读到容器1的所有环境变量, 以及一些暴露出去的端口信息等。 这种连接方式有效的避免了将一些变量暴露到这两个容器之外。
举例:官方的phpmyadmin镜像与mysql数据库就使用这种方式进行关联:
docker run --name mysql -e MYSQL_ROOT_PASSWORD=my_password -d mysql
docker run --link mysql:mysql -p 1234:80 nazarpc/phpmyadmin
Docker网络
Docker默认使用birdge桥接方式与容器通信,启动Docker后,宿主机上会产生docker0这样一个虚拟网络接口, docker0不是一个普通的网络接口, 它是一个虚拟的以太网桥,可以为绑定到docker0上面的网络接口自动转发数据包,这样可以使容器与宿主机之间相互通信。每次Docker创建一个容器,会产生一对虚拟接口,在宿主机上执行ifconfig,会发现多了一个类似veth****这样的网络接口,它会绑定到docker0上,由于所有容器都绑定到docker0上,容器之间也就可以通信。每个container的缺省路由是宿主机上docker0的ip,容器中的默认网关跟docker0的地址是一样的。当容器退出之后,veth*虚拟接口也会被销毁。
除bridge方式,Docker还支持host、container、none三种网络通信方式,使用其它通信方式,只要在Docker启动时,指定--net参数即可,比如:
docker run -i -t --net=host ubuntu /bin/bash
host方式可以让容器无需创建自己的网络协议栈,而直接访问宿主机的网络接口,在容器中执行ip addr会发现与宿主机的网络配置是一样的,host方式让容器直接使用宿主机的网络接口,传输数据的效率会更加高效,避免bridge方式带来的额外开销,但是这种方式也可以让容器访问宿主机的D-bus等网络服务,可能会带来意想不到的安全问题,应谨慎使用host方式;container方式可以让容器共享一个已经存在容器的网络配置; none方式不会对容器的网络做任务配置,需要用户自己去定制。
docker网络可参考:聊一聊Docker网络通信
Ubuntu docker无法联网
运行官方的Ubuntu docker镜像无法联网,ping通外网,也不能使用apt-get install安装软件。
apt-get update
apt install net-tools # ifconfig
apt install iputils-ping # ping
apt install iproute2 #ip
运行apt-get update后可安装相关软件:
root@f95b68790d41:/# apt-get update Get:1 http://security.ubuntu.com/ubuntu bionic-security InRelease [83.2 kB] Get:2 http://security.ubuntu.com/ubuntu bionic-security/multiverse amd64 Packages [1364 B] Get:3 http://security.ubuntu.com/ubuntu bionic-security/universe amd64 Packages [113 kB] Get:4 http://security.ubuntu.com/ubuntu bionic-security/main amd64 Packages [237 kB] Get:5 http://archive.ubuntu.com/ubuntu bionic InRelease [242 kB] Get:6 http://archive.ubuntu.com/ubuntu bionic-updates InRelease [88.7 kB] Get:7 http://archive.ubuntu.com/ubuntu bionic-backports InRelease [74.6 kB] Get:8 http://archive.ubuntu.com/ubuntu bionic/universe amd64 Packages [11.3 MB] Get:4 http://security.ubuntu.com/ubuntu bionic-security/main amd64 Packages [237 kB] Get:9 http://archive.ubuntu.com/ubuntu bionic/multiverse amd64 Packages [186 kB] Get:10 http://archive.ubuntu.com/ubuntu bionic/restricted amd64 Packages [13.5 kB] Get:11 http://archive.ubuntu.com/ubuntu bionic/main amd64 Packages [1344 kB] Get:12 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 Packages [542 kB] Get:13 http://archive.ubuntu.com/ubuntu bionic-updates/restricted amd64 Packages [10.8 kB] Get:14 http://archive.ubuntu.com/ubuntu bionic-updates/universe amd64 Packages [726 kB] Get:15 http://archive.ubuntu.com/ubuntu bionic-updates/multiverse amd64 Packages [6161 B] Get:16 http://archive.ubuntu.com/ubuntu bionic-backports/universe amd64 Packages [2975 B] Fetched 14.9 MB in 3min 0s (83.2 kB/s) Reading package lists... Done
Docker网络命令
其中有些命令选项只有在 Docker 服务启动的时候才能配置,而且不能马上生效。
-b BRIDGE 或 --bridge=BRIDGE 指定容器挂载的网桥
--bip=CIDR 定制 docker0 的掩码
-H SOCKET... 或 --host=SOCKET... Docker 服务端接收命令的通道
--icc=true|false 是否支持容器之间进行通信
--ip-forward=true|false 请看下文容器之间的通信
--iptables=true|false 是否允许 Docker 添加 iptables 规则
--mtu=BYTES 容器网络中的 MTU
下面2个命令选项既可以在启动服务时指定,也可以在启动容器时指定。在 Docker 服务启动的时候指定则会成为默认值,后面执行 docker run 时可以覆盖设置的默认值。
--dns=IP_ADDRESS... 使用指定的DNS服务器
--dns-search=DOMAIN... 指定DNS搜索域
最后这些选项只有在 docker run 执行时使用,因为它是针对容器的特性内容。
-h HOSTNAME 或 --hostname=HOSTNAME 配置容器主机名
--link=CONTAINER_NAME:ALIAS 添加到另一个容器的连接
--net=bridge|none|container:NAME_or_ID|host 配置容器的桥接模式
-p SPEC 或 --publish=SPEC 映射容器端口到宿主主机
-P or --publish-all=true|false 映射容器所有端口到宿主主机
Docker API
docker原生支持API获取docker信息,操作docker。参考:Develop with Docker Engine SDKs and API
API最新版本为v1.39,可通过docker version获取API version,v1.39 API文档:https://docs.docker.com/engine/api/v1.39/#
curl --unix-socket /var/run/docker.sock -X GET http:/v1.39/containers/json curl --unix-socket /var/run/docker.sock -X GET http:/containers/json curl --unix-socket /var/run/docker.sock -X GET http:/containers/64c13a583880/stats curl --unix-socket /var/run/docker.sock -X GET http:/containers/64c13a583880/stats?stream=false
Docker原生集群管理
Docker提供了原生的cluster管理方案:swarm,且具备完整容器栈管理:containers -> services -> swarms -> stacks
参考:docker walkthrough https://docs.docker.com/get-started/
Docker使用技巧
获取当前docker容器的IP和端口:
docker inspect -f='{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}} - {{.HostConfig.PortBindings}}' $(docker ps -aq)
docker日志
可通过如下命令查看实时日志:
docker logs -f -t --since=“2017-05-31” --tail=10 dockername
linux下,容器日志一般存放在/var/lib/docker/containers/container_id/
下面, 以-json.log结尾。
清理日志
nginx: image: nginx:1.12.1 restart: always logging: driver: “json-file” options: max-size: “5g”
全局设置/etc/docker/daemon.json:
vim /etc/docker/daemon.json { "registry-mirrors": ["http://f613ce8f.m.daocloud.io"], "log-driver":"json-file", "log-opts": {"max-size":"500m", "max-file":"3"} }