Ubuntu环境的docker实践——基础操作

0.微服务与docker

以往传统的软件开发虽然也提倡模块化的开发,但是最终大多是打包成单个应用进行部署,任何模块的改动,都要重新部署整个应用。这样的方式直接导致了部署不灵活;由于所有的模块最终是融合在一起的,因此任何模块的某个问题都有可能影响整个应用的稳定性和可用性;同时也不便于整个应用功能的扩展。到目前为止,微服务已经成为了软件应用开发中使用的新兴技术。如果说十年前会用安卓开发和ios开发是一种潮流,那么现在会用微服务也是一种潮流。
docker是一个平台,开发者和系统管理员可以利用docker把某个应用逻辑构建、共享和运行在一个容器(containers)内。对于微服务,使用docker就可将一个微服务放到一个容器内,容器之间建立通信,这样多个容器同时运行,宏观上就构建出了一个完整的应用。
参考资料微服务与docker的关系

1.docker安装与验证(Ubuntu)

来源ubuntu16.04下安装docker

安装

docker官网提供了docker desktop(Windows和Mac平台),曾经在Windows平台安装,但是它运行时需要使用Windows 10的Hyper V,如果开启这个Windows功能,那么VisualBox的虚拟机将无法使用。

$ # 卸载旧的版本(如有)
$ sudo apt-get remove docker docker-engine docker-ce docker.io
$ # 安装前更新软件源
$ sudo apt-get update
$ # 安装以下包使apt可以通过HTTPS使用存储库(repository)
$ sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common
$ # 添加Docker官方的GPG密钥
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ # 设置stable存储库
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

$ # 再次更新软件源
$ sudo apt-get update
$ # 安装最新版的docker ce(Community Edition)
$ sudo apt-get install -y docker-ce

如果要安装指定版本,使用命令:

$ apt-cache madison docker-ce

列出可用的版本,第二列是版本字符串,第三列是存储库名称,它指示包来自哪个存储库,以及扩展它的稳定性级别

$ sudo apt-get install docker-ce=<VERSION>

验证

$ # 查看docker状态
$ systemctl status docker
$ # 启动docker(如果没启动)
$ sudo systemctl start docker


运行helloworld,结束安装

$ sudo docker run hello-world

2.docker的容器操作

  • docker有镜像(Image)和容器(Container)两个概念,就类似与面向对象中的类与实例的关系,容器可以看成是一个镜像运行的实例。这里先说容器的操作


如上图所示,在容器内使用ubuntu 16.04的镜像启动(也可以理解为新建,只要run一次就会生成一个不同id的容器)了一个容器实例(不同于先前安装docker时的ubuntu系统),如果镜像不存在,那么会从远程拉取(pull),启动实例后会运行/bin/bash 这个交互式shell

$ docker run -it ubuntu:16.04 /bin/bash   #加上-i 和 -t之后,就会跳出root@5a10ec8bf9a7:/#,5a10ec8bf9a7是容器的id,那么容器内的ubuntu实例就提供了一个Terminal终端和交互式shell
$ docker run -itd --name ubuntu1604fzu ubuntu:16.04 /bin/bash   #加-d参数表示将容器放在后台运行,--name后自定义容器的名字


如果容器在后台运行,需要进入容器有两种方法
方法一:

$ docker attach <容器id>  #一旦exit退出,容器就关闭

方法二:

$ docker exec -it <容器id> /bin/bash  #如果exit退出,容器仍然在后台运行

  • 之后就可以根据具体的id来管理容器
$ #查看当前正在运行的容器 
$ docker ps
$ #查看所有的容器,不论其是否正在运行
$ docker ps -a

此时就可以根据容器id(也可以使用容器name),启动/重启/关闭/删除指定容器

$ #启动
$ docker start <容器id>
$ #重启
$ docker restart <容器id>
$ #关闭
$ docker stop <容器id>
$ #删除,-f表示force,强制删除正在运行的对应id的容器
$ docker rm -f <容器1id> <容器2id> <容器3id> <容器4id> ...
$ #查看容器状态,返回一段JSON记录容器的状态
$ docker inspect <容器id>


权限问题

  • 如果直接使用docker命令遇到权限问题:Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: ......此时,可以用sudo权限执行(如前述操作),或者尝试执行下面的命令
$ #添加docker用户组
$ sudo groupadd docker
$ #将登陆用户加入到docker用户组中
$ sudo gpasswd -a $USER docker
$ #更新用户组
$ newgrp docker
$ #测试docker命令是否可以使用sudo正常使用
$ docker ps

  • 如果直接使用docker命令遇到权限告警:WARNING: Error loading config file: /home/ubuntu/.docker/config.json: open /home/ubuntu/.docker/config.json: permission denied
$ sudo groupadd docker
$ sudo gpasswd -a $USER docker
$ sudo systemctl restart docker
$ #设置目录及其所有文件的权限
$ sudo chown "$USER":"$USER" /home/"$USER"/.docker -R
$ sudo chmod g+rwx "/home/$USER/.docker" -R


3.docker的镜像操作

$ #查看镜像
$ docker images
$ #从官方新增镜像
$ docker pull <镜像类型,比如ubuntu:16.04>
$ #删除镜像
$ docker rmi <REPOSITORY:TAG>
$ #更新镜像,退出容器后运行
$ docker commit -m "<描述信息>" -a "<作者信息>"  <已修改要更新的容器id> <新的镜像名>
$ #给镜像加标签
$ docker tag <镜像id> <REPOSITORY:TAG>

更多官方镜像
有时候删除镜像会遇到报错,Error response from daemon: conflict: unable to delete c448e821713c (cannot be forced) - image has dependent child images
此时需要使用命令列出所有在指定 image 之后创建的 image 的父 image

$ docker image inspect --format='{{.RepoTags}} {{.Id}} {{.Parent}}' $(docker image ls -q --filter since=c448e821713c)  #c448e821713c是容器id

4.容器端口映射和多容器互联

端口映射

$ #参数 -p 将容器内部端口映射到主机指定ip和端口上,默认TCP协议,UDP得额外注明
$ docker run -i -t -p <主机ip>:<主机端口>:<容器内部端口>/<协议类型> training/webapp python app.py
$ #查看端口绑定情况
$ docker port <容器id或name>


上述操作运行完,终端不能再输入命令,只有ctrl c终止,此时映射就失效了,需要重新启动对应id的容器,让映射生效。

容器互联

我们使用更新的ubuntu_aliyunsrc镜像来创建容器,目前该镜像下并没有容器运行。

$ #新建docker网络,-d 指定网络类型,一般用bridge即可
$ docker network create -d <网络类型> <网络name>

具体命令说明见下图

新建一个名为net333的bridge类型的docker网络,并且在ubuntu_aliyunsrc镜像上创建两个名为subnet1和subnet2的容器,加入net333网络

subnet1和subnet2能够ping通

之后就可以在两台容器中部署各类应用实现通信了。

参考资料

2/3/4部分参考自教程

原文地址:https://www.cnblogs.com/fjlinww/p/12090308.html