docker入门实践

写在前面

之前看docker的时候,记录在了docx文档上,今天翻阅的时候看到了。

简介

docker有点像虚拟机技术那样,而虚拟机是模拟了全部或部分的硬件,有一整套自己的操作系统,而docker只是进程,这个进行也叫容器,隔离了linux内核有自己的空间。

注:ubuntu14的虚拟机,高版本的ubuntu操作起来估计坑应该会少一点。

安装

 sudo curl -sSL https://get.daocloud.io/docker | sh

可能遇到curl 命令不存在,使用sudo apt-get install curl安装curl命令,如果报错了一串404的话。如图:
在这里插入图片描述
可以先更新:

sudo apt-get update

然后再安装:

sudo apt-get install

curl之后再安装docker:

sudo curl -sSL https://get.daocloud.io/docker | sh

安装验证:

jonsen@ubuntu:/etc/init.d$ sudo docker version
Client:
 Version:           18.06.3-ce
 API version:       1.38
 Go version:        go1.10.3
 Git commit:        d7080c1
 Built:             Wed Feb 20 02:27:13 2019
 OS/Arch:           linux/amd64
 Experimental:      false
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

发现问题:发现没有启动。

启动命令:
ubuntu 14.04的系统:sudo /etc/init.d/docker start
ubuntu 16.04的系统:sudo systemctl status docker.service

这里是unbuntu14的虚拟机,因为18的在硬盘忘记拉出来了,这里都会以14操作。

jonsen@ubuntu:/etc/init.d$ sudo /etc/init.d/docker start
 * Docker is managed via upstart, try using service docker 

发现并没有成功?
根据提示改用service的方式启动:

sudo service docker start

查看状态:

jonsen@ubuntu:/etc/init.d$ sudo service docker status
docker start/running, process 12695

已经启动ok了。

更换加速器

jonsen@ubuntu:/etc/init.d$ sudo mkdir -p /etc/docker
jonsen@ubuntu:/etc/init.d$ sudo tee /etc/docker/daemon.json <<-'EOF'
> {
>   "registry-mirrors": ["https://oyukeh0j.mirror.aliyuncs.com"]
> }
> EOF
{
  "registry-mirrors": ["https://oyukeh0j.mirror.aliyuncs.com"]
}

国内的加速器有好多,我们使用阿里云的加速器。
https://cr.console.aliyun.com/#/imageList

重启

sudo su
root@ubuntu:/etc/docker# service docker restart
docker stop/waiting
docker start/running, process 13092

注:这里已经切换了root用户了,后面可能操作不会带sudo

安装一个hello-world项目

root@ubuntu:/etc/docker# docker pull hello-world
Using default tag: latest
latest: Pulling from library/hello-world
1b930d010525: Pull complete 

安装gitlab的项目:

docker pull sameersbn/gitlab

可以看到安装一个项目只要pull即可。

这里以一个webserver为例

root@ubuntu:/etc/docker#  docker run --name webserver -d -p 80:80 nginx
da42a076cd2fbc351e5a80e0426e4351cec52eecf8f859d7aea3f9c37b5abf38
docker: Error response from daemon: OCI runtime create failed: container_linux.go:348: starting container process caused "process_linux.go:297: copying bootstrap data to pipe caused \"write init-p: broken pipe\"": unknown.

可能遇到的问题:
由于每次安装运行服务的时候,总会报错,导致并没有运行成功。
因为之前安装了是最新版的18.06.3的版本。

jonsen@ubuntu:/etc/init.d$ sudo docker version
Client:
 Version:           18.06.3-ce
 API version:       1.38
 Go version:        go1.10.3
 Git commit:        d7080c1
 Built:             Wed Feb 20 02:27:13 2019
 OS/Arch:           linux/amd64
 Experimental:      false

Server:
 Engine:
  Version:          18.06.3-ce
  API version:      1.38 (minimum version 1.12)
  Go version:       go1.10.3
  Git commit:       d7080c1
  Built:            Wed Feb 20 02:25:38 2019
  OS/Arch:          linux/amd64
  Experimental:     false

没有以上问题的可以跳过下面一部分
核心的降级
这里为了可以使用docker,先进行一个核心的降级:

root@ubuntu:/etc/docker# apt-get install docker-ce=17.12.1~ce-0~ubuntu

然后删掉服务,重新安装运行:

root@ubuntu:/etc/docker# docker rm -f webserver
webserver
root@ubuntu:/etc/docker# docker run --name webserver -d -p 80:80 nginx
45d84e3d0bd19bc954ba4043e080d2c3c403024760e336de145f054b00b3cc4f
root@ubuntu:/etc/docker# docker version
Client:
Version:	17.12.1-ce

这里使用浏览器进行测试验证,发现已经把docker的运行起来了,把docker的一个nginx附加到了80的端口上。
在这里插入图片描述
然后我们进入到该容器上:

docker exec -it webserver bash

-i: 交互式操作。
-t: 终端。
/bin/bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 /bin/bash。

此时可以看到这时候多了一个nginx的容器目录:
在这里插入图片描述
修改容器:

x.html5d84e3d0bd1:/# echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index
root@45d84e3d0bd1:/# exit
exit

再次访问刚才的地址:
在这里插入图片描述
使用diff命令查看修改的目录:

root@ubuntu:/usr/share# docker diff webserver
C /root
A /root/.bash_history
C /run
A /run/nginx.pid
C /usr
C /usr/share
C /usr/share/nginx
C /usr/share/nginx/html
C /usr/share/nginx/html/index.html
C /var
C /var/cache
C /var/cache/nginx
A /var/cache/nginx/client_temp
A /var/cache/nginx/fastcgi_temp
A /var/cache/nginx/proxy_temp
A /var/cache/nginx/scgi_temp
A /var/cache/nginx/uwsgi_temp

我们可以把这个容器的改变保存下来,成为一个镜像,下次就能直接运行了。

root@ubuntu:/usr/share# docker commit \
>  --author "jonsen <jonsen.test@qq.com>" \
>     --message "修改了默认网页" \
>     webserver \
>     nginx:v2
sha256:17472653ad3e57d352e5ad61f98a80cadb9b4234abae4ef99033325e33626d28
root@ubuntu:/usr/share# docker images nginx
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               v2                  17472653ad3e        13 seconds ago      126MB
nginx               latest              540a289bab6c        2 weeks ago         126MB

访问81端口:
在这里插入图片描述
慎用 docker commit
使用docker commit虽然能保存镜像或创建镜像,但是一般情况下我们不会这么用,我们会使用Dockerfile来构建镜像。
docker commit有一些不好的地方,上面的例子也可以看出来,我只是改了一个文件,上面却显示改了很多,比如临时文件,记录命令的文件(.bash_history),还有pid文件啥的。
而且使用docker commit创建的镜像,别人也不无法知道你是如何创建的,万一里面藏着什么东西,别人都不知道,很不安全。我们接下来会使用Dockerfile来创建镜像。

Dockerfile

Dockerfile是一个纯文本文件,内容是可读的,就是把构建镜像的指令一条条放在这个文件中,然后就可以build出来一个镜像。

root@ubuntu:/usr/dorcker# mkdir mynginx
root@ubuntu:/usr/dorcker# cd mynginx/
root@ubuntu:/usr/dorcker/mynginx# touch Dockerfile
root@ubuntu:/usr/dorcker/mynginx# vi Dockerfile

输入:

FROM nginx
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html

然后保存。
执行命令:

docker build -t nginx:v3 

新建一个docker镜像,并命名为nginx:v3
查看:

docker images 

在这里插入图片描述
常用基本指令介绍:
FROM:代表的是基础镜像。
RUN:表示的是运行的命令。
ARG:设置一个参数,在build的时候由外面通过命令行参数的形式传过来。
ENV:是设置环境变量,以后这个变量可以传到docker容器内部中去。
EXPOSE:表示暴露的端口号。
WORKDIR:就是指定工作目录啦。
CMD:是容器启动的命令。

部署node应用例子

这里目录为 /usr/docker/
执行:

mkdir express-docker
cd express-docker
touch server.js
touch package.json
touch .dockerignore
touch Dockerfile

package.json:

{
  "name": "docker_demo",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {
    "express": "^4.16.1"
  }
}

server.js

'use strict';
const express = require('express');
// Constants
const PORT = 8889;
const HOST = '0.0.0.0';
// App
const app = express();
app.get('/', async(req, res) => {
  res.send('Hello world1\n');
});
app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`);

Dockerfile:

#制定node镜像的版本
FROM node:latest
#声明作者
MAINTAINER onsen
#移动当前目录下面的文件到app目录下
COPY . /app/
#进入到app目录下面,类似cd
WORKDIR /app
#安装依赖
RUN npm install
#对外暴露的端口
EXPOSE 8889
#程序启动脚本
CMD ["npm", "start"]

.dockerignore:

# Logs
logs
*.log
npm-debug.log*

# Runtime data
pids
*.pid
*.seed

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# node-waf configuration
.lock-wscript

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules
jspm_packages

# Optional npm cache directory
.npm

# Optional REPL history
.node_repl_history
.idea
.node_modules
node_modules
.vscode

在命令行上执行打包(注:后面的点不能忽略了):
docker build -t express_docker .
在这里插入图片描述
等待安装完毕后执行后台运行:

docker run -d -p 8889:8889 --name express_docker express_docker 

设置docker自动重启
修改server.js:

'use strict';
const express = require('express');
require('./utils');
// Constants
const PORT = 8889;
const HOST = '0.0.0.0';
// App
const app = express();
app.get('/', async(req, res) => {
  res.send('Hello world1\n');
  setTimeout(function(){
        console.info(aa);
  },2000)
});
app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`);

重启docker并更新:

docker container update --restart=always 容器名字

如果成功没有启动过的话:

docker run --restart=always -d -p 8889:8889 --name express_docker express_docker

查看日志

docker logs -f -tail 100 express_docker 

访问127.0.0.1:8889,这里是使用浏览器,如图:
在这里插入图片描述
因为程序访问后两秒后就会报一个模拟的错误,如下图:
在这里插入图片描述
可以看到,报错日志自动退出后,再使用:

docker ps

查看,容器又启动起来了。

使用pm2维护node
修改Dockerfile:

#制定node镜像的版本
FROM node:latest
#声明作者
MAINTAINER onsen
#移动当前目录下面的文件到app目录下
COPY . /app/
#进入到app目录下面,类似cd
WORKDIR /app
#安装依赖
RUN npm install
#对外暴露的端口
EXPOSE 8889
#程序启动脚本
#CMD ["npm", "start"]
RUN npm install pm2 -g 
CMD ["pm2-runtime","server.js","-i","2", "--watch", "--name", "myapp"] 

删除掉之前建立的容器,可能用到:
docker stop <容器名>
docker rm <容器名>
docker rmi <容器image id>

root@ubuntu:/usr/dorcker/express_docker# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                    PORTS                    NAMES
0119f838abe2        a8bb429e3a5a        "docker-entrypoint.s…"   5 minutes ago       Up 4 minutes              0.0.0.0:8889->8889/tcp   express_docker
b99024f811fe        docker_demo         "npm start"              12 hours ago        Up 12 hours               0.0.0.0:9000->3000/tcp   stupefied_clarke
9fadc8ea7d03        training/postgres   "su postgres -c '/us…"   15 hours ago        Up 15 hours               5432/tcp                 db1
bc48f74c2092        training/postgres   "echo Data-only cont…"   15 hours ago        Exited (0) 15 hours ago                            dbdata
c2841ff00e6d        nginx               "nginx -g 'daemon of…"   15 hours ago        Up 15 hours               0.0.0.0:80->80/tcp       webserver
root@ubuntu:/usr/dorcker/express_docker# docker stop express_docker
express_docker
root@ubuntu:/usr/dorcker/express_docker# docker rm express_docker
express_docker
root@ubuntu:/usr/dorcker/express_docker# docker run -d -p 8889:8889 --name express_docker express_docker
1606b78e66dabef5817fe077fa74818dea06cf55b867c1a7e31a7f09a94b8f14
root@ubuntu:/usr/dorcker/express_docker# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
express_docker      latest              45e2e40bb21c        52 seconds ago      972MB
<none>              <none>              a8bb429e3a5a        6 minutes ago       972MB
docker_demo         latest              3e6b13bae720        12 hours ago        69.7MB
nginx               v2                  17472653ad3e        19 hours ago        126MB
node                latest              1a77bcb355eb        4 days ago          933MB
sameersbn/gitlab    latest              0d004485cc7b        7 days ago          2.59GB
nginx               latest              540a289bab6c        2 weeks ago         126MB
hello-world         latest              fce289e99eb9        10 months ago       1.84kB
node                8.9-alpine          406f227b21f5        20 months ago       68.1MB
training/postgres   latest              6fa973bb3c26        5 years ago         365MB
root@ubuntu:/usr/dorcker/express_docker# docker rmi a8bb429e3a5a
root@ubuntu:/usr/dorcker/express_docker# docker exec -it express_docker bash

然后重新build,之后再像上面一样启动起来容器,进入容器,查看pm2命令,如图:
在这里插入图片描述
进入容器使用pm2 logs myapp查看日志,使用浏览器访问127.0.0.1:8889。两秒后,收到了报错,pm2重启了node项目。

注:网上有人说容器中部署了pm2再用pm2管理node项目,如果项目报错重启,会导致容器重启,然而这里的实践发现,pm2重启了node的项目并没有导致容器重启。

链接数据库例子
这里以mysql为例:
如果需要查看版本镜像,可以查阅https://hub.docker.com/这里直接安装最新版本的mysql。
执行安装:

docker pull mysql
docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=password -d mysql

在这里插入图片描述
进行容器中查看mysql:

root@ubuntu:/usr/dorcker# docker exec -it mysql bash
root@db3b62dedbc7:/# mysql --version

在这里插入图片描述

root@db3b62dedbc7:/#  mysql -u root -p
mysql> use mysql

mysql 8.0 默认使用 caching_sha2_password 身份验证机制 —— 从原来的 mysql_native_password 更改为 caching_sha2_password。

mysql> ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'password';

通过ip访问确认链接:
在这里插入图片描述
192.168.42.133是我本地虚拟机的ip,具体以自己实践结果为准。
我们知道如果需要链接到一个数据库的话需要知道该数据库的地址:
获取该容器的ip,进行数据库的链接

root@ubuntu:/usr/dorcker# docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' mysql
172.17.0.6

注:具体的ip以自己机器上的准。

新建链接数据库的测试文件:

root@ubuntu:/usr/dorcker/express_docker# touch utils.js

utils.js:

var mysql      = require('mysql');
var connection = mysql.createConnection({
  host     : '172.17.0.6',
  user     : 'root',
  password : 'password'
});

connection.connect(function(err) {
  if (err) {
    console.error('error connecting: ' + err.stack);
    return;
  }

  console.log('connected as id ' + connection.threadId);
});

修改express_docker 容器的文件package.json:

{
  "name": "docker_demo",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {
    "express": "^4.16.1",
    "mysql": "^2.17.1"
  }
}

server.js:

'use strict';
const express = require('express');
require('./utils');
// Constants
const PORT = 8889;
const HOST = '0.0.0.0';
// App
const app = express();
app.get('/', async(req, res) => {
  res.send('Hello world1\n');
  setTimeout(function(){
        console.info(aa);
  },2000)
});
app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`);

重启build Dockerfile文件,运行,查看日志:
在这里插入图片描述
可以看到mysql是链接成功了。

docker Compose简单介绍

docker Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。
安装:

 sudo pip install -U docker-compose

如果不行的话,可以尝试手动安装:

sudo curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

1.24.1为版本号,可以更改为其它版本。
将可执行权限应用于二进制文件:

sudo chmod +x /usr/local/bin/docker-compose

创建软链:

 sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose

测试安装成功?

docker-compose --version

实例:安装gitlab
拉取镜像:

docker pull sameersbn/gitlab

下载docker-compose.yml文件

mkdir gitlab
cd gitlab
wget https://raw.githubusercontent.com/sameersbn/docker-gitlab/master/docker-compose.yml

打开这个文件,把它的内容按照你自己的需要修改,比如改改github登录的配置信息,邮件发送的配置信息等。
执行:

docker-compose up

感谢

写文不易,GitHub求start一颗,https://github.com/onsenOnly,共勉进步,谢谢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值