社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  docker

Docker 从入门到掉坑

Java知音 • 4 年前 • 359 次点击  

点击上方“Java知音”,选择“置顶公众号”

技术文章第一时间送达!

Docker 介绍

简单的对docker进行介绍,可以把它理解为一个应用程序执行的容器。但是docker本身和虚拟机还是有较为明显的出入的。我大致归纳了一下,可以总结为以下几点:


docker自身也有着很多的优点,关于它的优点,可以总结为以下几项:


安装docker

从 2017 年 3 月开始 docker 在原来的基础上分为两个分支版本: Docker CE 和 Docker EE。

Docker CE 即社区免费版,Docker EE 即企业版,强调安全,但需付费使用。

首先我们需要移除旧的docker版本:

$ sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-selinux \
                  docker-engine-selinux \
                  docker-engine

接着我们需要安装一些必要的系统工具:

sudo yum install -y yum-utils device-mapper-persistent-data lvm2

接下来我们需要添加软件源信息:

sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

更新 yum 缓存:




    
sudo yum makecache fast

验证容器

上边的操作都是一些准备操作,如果步骤过程中没有出现什么异常的话,后边就可以安装docker了

sudo yum -y install docker-ce

安装完毕之后便是开启docker后台服务步骤:

sudo systemctl start docker

当我们的docker镜像下载完毕之后,默认会有个helloworld的镜像用于测试:

测试运行 hello-world

[root@runoob ~]# docker run hello-world

由于本地没有hello-world这个镜像,所以会下载一个hello-world的镜像,并在容器内运行。

关于docker的镜像和容器介绍

容器的本质就是进程,不同的容器有着自己独立的root文件系统,网络配置,一个隔离的空间。容器一旦消失,则里面包含的数据也会发生丢失。容器里面所有的存储信息都应该使用数据卷或者其他形式。数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。因此,使用数据卷后,容器删除或者重新运行之后,数据却不会丢失。

Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。

docker安装nginx

初步安装完了docker之后便开始进入一些实战环节吧

首先我们需要在docker里面pull相关的nginx镜像:

一开始宿主机并没有启动docker容器,需要启动docker服务

service docker start

然后pull镜像下来,并且启动

docker run -d -p 80:80 --restart=always nginx:latest

参数讲解:-d 后台启动 -p 宿主机的80端口映射容器的80端口。测试一下相关页面,成功则如下图:


接下来我们可以查看一下镜像标签


docker images

这个命令查询出来的只是镜像的id,但是我们无法根据镜像id进入容器中,进入容器需要有容器的id才可以:

于是可以通过这个命令来查看容器的id:

docker ps

然后进入容器修改信息
进入容器的命令有很多种,这里推荐可以使用这种类型:

docker exec -it 999318c7d567 /bin/bash

通过选择相应的tag-id进入容器,进入到容器里面之后,会发现里面仿佛就是一个新的linux操作系统:

如何关闭docker容器?

比较简单,这里不多说,自己操作就懂了

docker kill 4591552a4185

文件拷贝

懂得了基本的docker容器操作之后,我们来试试如何上传文件到docker容器中,这个需要和宿主机进行文件交换才可以。

首先我们需要拿到容器id的全称:

[root@localhost html]# docker ps 
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
0d4173ecf31f        nginx:latest        "nginx -g 'daemon of…"   9 minutes ago       Up 9 minutes        0.0.0.0:80->80/tcp   sleepy_gould

[root@localhost html]# docker inspect -f '{{.Id}}' 0d4173ecf31f
0d4173ecf31f894e234ae9eb3d9eddd1b9d10b7af5c46608679fe11918af9644

然后将文件拷贝进入docker容器中:

[root@localhost html]# docker cp /opt/html/user_login.html 0d4173ecf31f894e234ae9eb3d9eddd1b9d10b7af5c46608679fe11918af9644:/root/user_login.html
[root@localhost html]#

接下来的操作就比较简单了,查看到移动的页面即可:

root@0d4173ecf31f:/usr/share/nginx/html# ls
50x.html  index.html  user_login.html
root@0d4173ecf31f:/usr/share/nginx/html#

接下来的基本都是常规操作了,进入我们的nginx配置中:

root@0d4173ecf31f:/etc/nginx# vi nginx.conf 
bash: vi: command not found
root@0d4173ecf31f:/etc/nginx#

发现没有vi命令,需要下载安装

在使用docker容器时,有时候里边没有安装vi,敲vi命令时提示说:vi: command not found,这个时候就需要安装vi,可是当你敲apt-get install vi命令时,提示:

Reading package lists... Done  
Building dependency tree         
Reading state information... Done  
E: Unable to locate package vi

这时候需要敲:apt-get update,这个命令的作用是:同步 /etc/apt/sources.list 和 /etc/apt/sources.list.d 中列出的源的索引,这样才能获取到最新的软件包。等更新完毕以后再敲命令:apt-get install vi命令即可。

现在docker有了,nginx镜像也开启了,就可以对nginx的配置做修改了。

docker里面安装redis

首先还是老规矩,pull镜像




    
[root@izwz9ic9ggky8kub9x1ptuz docker]# docker pull redis:4.0

拉取镜像结束之后,内容如下:

[root@izwz9ic9ggky8kub9x1ptuz docker]# docker pull redis:4.0
4.0: Pulling from library/redis
b8f262c62ec6: Pull complete 
93789b5343a5: Pull complete 
49cdbb315637: Pull complete 
e244975d5eb1: Pull complete 
25dca704d939: Pull complete 
db11ecc9cf34: Pull complete 
Digest: sha256:615b872e3af387206b62ffe66c1052f1653ed31b3afcfaa292a9244c92f2007a
Status: Downloaded newer image for redis:4.0
docker.io/library/redis:4.0

ok,基本镜像有了,那么就直接开启容器吧

这里我们修改了宿主机的端口号为8879映射容器里面的6379哈。

[root@izwz9ic9ggky8kub9x1ptuz /]
docker run -p 8879:6379 
 -v $PWD/data:/data  
 -v $PWD/conf/redis.conf:/etc/redis/redis.conf  
 --privileged=true
 --name myredis 
 -d redis:4.0 redis-server /etc/redis/redis.conf

参数解释

  • -p 8879:8879: 将容器的8879端口映射到主机的6379端口

  • -v $PWD/data:/data : 将主机中当前目录下的data挂载到容器的/data

  • redis-server —appendonly yes : 在容器执行redis-server启动命令,并打开redis持久化配置

启动完毕之后,一切都开始正常运行了。

进入容器,开始检测redis是否正常:

这里建议开启redis的时候最好在宿主机做一份redis配置文件,映射到容器里面,不然进入容器中根本找不到相应的redis配置文件,很痛苦。

docker里面安装MySQL

这部分的内容比较简单,只需要将镜像拉下来即可:

docker run --name 【容器名】 -e MYSQL_ROOT_PASSWORD=【mysql密码】 -d -i -p 3309:3306 mysql:5.7.24

然后等待一段时间,终于我们的MySQL容器安装好了:


容器的内存资源消耗情况
由于我购买的是一台小型的服务器,相关的配置如下所示,所以在给各个运行的容器进行资源分配的时候需要考虑到每个docker容器占用的资源情况。


目前已经搭建了mysql容器,redis容器,还有一个nginx容器,如果再添加一个java应用的话,目测跑java容器需要至少500m左右的内存大小来支撑。

通过使用docker stats命令来看当前服务器的内存,由于平日的访问量并不高,可以给当前的mysql,redis分配小一些内存资源:

这时候可以采用docker的update命令来对内存大小进行管理分配:

docker update -m 350m  --memory-swap -1  mysqlserver

--memory-swap -1 参数是指不让容器和宿主机进行内存交换,如果需要则需要额外调整,
设置下内存的限制之后结果如下:

docker容器启动失败分析实战

在配置docker新容器的时候,例如说给mysql配置my.cnf文件的某些属性,需要重启容器才能生效。但是有时候可能因为手误,导致配置出现异常,容器重启失败,这个时候该怎么办呢?

这个时候最简单粗暴的方式就是,将该容器先rm掉,然后重新安装,但是这样的操作过于暴力化,万一容器里面还有其他重要数据,直接rm操作不可取。

其实docker本质也是安装在宿主机里面的,所以相应的配置文件在宿主机里面也能找到痕迹,这里记录了之前我掉坑的一些补救方式:

docker inspect [容器名称]

通过该命令可以查看到容器的内部配置属性信息:


这时候我们可以查看到一个叫做MergedDir的目录文件夹,进入该文件夹的上一级目录,


 cd /var/lib/docker/overlay2/f4ab9eff7a18f20f977595af38f5eb273127e0de8845a42fe71fa9b8850a988b

接着我们查看该目录下结构,会发现一个叫做diff的文件夹


带着好奇心,一步一步地进入到文件夹的内部,就会找到之前在docker容器中配置的mysql文件了,手动将原先的配置修改回来,容器便重启成功了。


END

Java面试题专栏

【01期】Spring,SpringMVC,SpringBoot,SpringCloud有什么区别和联系?

【02期】你能说说Spring框架中Bean的生命周期吗?

【03期】如何决定使用 HashMap 还是 TreeMap?

【04期】分库分表之后,id 主键如何处理?

【05期】消息队列中,如何保证消息的顺序性?

【06期】单例模式有几种写法?

【07期】Redis中是如何实现分布式锁的?

【08期】说说Object类下面有几种方法呢?

【09期】说说hashCode() 和 equals() 之间的关系?

【10期】Redis 面试常见问答



我知道你 “在看

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/49221
 
359 次点击