PlayWithDocker-Docker新手Linux

Posted Onion94

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PlayWithDocker-Docker新手Linux相关的知识,希望对你有一定的参考价值。

引用

新手-Linux

克隆实验室仓库:

git clone https://github.com/dockersamples/linux_tweet_app

确保你有 Docker Hub 的账号 DockerID

任务1: 运行一些简单的docker容器

通过Alpine Linux容器运行单个任务

如果alpine镜像不存在本地,则自动从docker hub中拉取.

$ docker container run alpine hostname
Unable to find image ‘alpine:latest‘ locally
latest: Pulling from library/alpine
aad63a933944: Pull complete
Digest: sha256:b276d875eeed9c7d3f1cfa7edb06b22ed22b14219a7d67c52c56612330348239
Status: Downloaded newer image for alpine:latest
9cbebe6f679d

容器运行hostname命令输出值: 9cbebe6f679d
只要容器内的进程不退出, 容器会一直保持运行.本例容器运行hostname指令后退出,但docker不会立即删除容器,而是让容器以Exited状态存在.
查看所有容器状态:

$ docker container ls -all
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9cbebe6f679d alpine "hostname" 5 minutes ago Exited (0) 5 minutes ago zen_elgamal

每个容器都有唯一的ID,本例是 9cbebe6f679d
运行一个任务然后退出的容器非常有用, 例如让容器运行一个脚本, 其他人不需要知道脚本内容和配置信息,只需要执行这个容器.

运行一个交互式的Ubuntu容器

Docker容器的Linux版本不需要与宿主机Linux相同.
运行一个Ubuntu容器,以交互式方式启动
选项说明:

  • -i/--interactive: 以交互式运行
  • --tty: 开启一个虚拟终端
  • --rm: 退出后删除容器
    前两个选项用于开启和docker容器的交互,容器内的shell环境是 bash
$ docker container run -i --tty --rm ubuntu bash
Unable to find image ‘ubuntu:latest‘ locally
latest: Pulling from library/ubuntu
5bed26d33875: Pull complete
f11b29a9c730: Pull complete
930bda195c84: Pull complete
78bf9a5ad49e: Pull complete
Digest: sha256:bec5a2727be7fff3d308193cfde3491f8fba1a2ba392b7546b43a051853a341d
Status: Downloaded newer image for ubuntu:latest
root@88681c93701a:/# ls
bin dev home lib64 mnt proc run srv tmp var
boot etc lib media opt root sbin sys usr
root@88681c93701a:/# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.2 0.0 18504 3320 pts/0 Ss 08:27 0:00 bash
root 11 0.0 0.0 34400 2828 pts/0 R+ 08:27 0:00 ps aux
root@88681c93701a:/# cat /etc/issue
Ubuntu 18.04.4 LTS 
 l

root@88681c93701a:/# exit
exit

查看宿主机的版本

$ cat /etc/issue
Welcome to Alpine Linux 3.10
Kernel 
 on an m (l)

可以看到在Alpine Linux 3.10 系统的机器上允许Ubuntu 18.04.04LTS系统容器.
Linux内核容器需要允许在Linux内核的Docker主机上,Windows内核的容器需要允许在Windows的Docker主机上.

这种交互式的容器运行方式,对于构建镜像之后的检查和验证非常有用,通过这种方式可以将应用构建步骤导出为Dockerfile文件(不建议这么做).通过编写 Dockerfile 文件构建镜像更好(便于版本控制,贡献等)

后台运行的MySQL容器

后台容器是是大多数APP的运行方式.
启动mysql容器:

$ docker container run --detach --name mydb -e MYSQL_ROOT_PASSWORD=my-secret-pw mysql:latest
Unable to find image ‘mysql:latest‘ locally
latest: Pulling from library/mysql
123275d6e508: Pull complete
27cddf5c7140: Pull complete
c17d442e14c9: Pull complete
5fc78b1e06f8: Pull complete
cd38802f42bb: Pull complete
b370e336f220: Pull complete
f519d6d4d2f6: Pull complete
c52c0310cd34: Pull complete
cd74fd7796ae: Pull complete
3f08e322a29c: Pull complete
2caa0eda62a7: Pull complete
eac28354a6fe: Pull complete
Digest: sha256:7901b65a6be478f7f15348dec0440c491a364af202112c61cb3925d7fb67d8f4
Status: Downloaded newer image for mysql:latest
e52b5d513a22b5b7ca0608b88987fa358fbc0689ca53aa1e14b42750f9638d97

选项说明:

  • --detach: 使容器在后台运行
  • --name: 指定容器的别名
  • -e: 使用环境遍历设置mysql root用户密码(永远不要在生产环境这么做)
    查看运行中的容器:
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e52b5d513a22 mysql:latest "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 3306/tcp, 33060/tcp mydb

使用两个Docker内建的指令(logs,top)查看容器运行情况

#查看输出日志
$ docker container logs mydb
2020-04-17 08:42:01+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.19-1debian10 started.
2020-04-17 08:42:01+00:00 [Note] [Entrypoint]: Switching to dedicated user ‘mysql‘
2020-04-17 08:42:01+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.19-1debian10 started.
2020-04-17 08:42:02+00:00 [Note] [Entrypoint]: Initializing database files
2020-04-17T08:42:02.065539Z 0 [Warning] [MY-011070] [Server] ‘Disablingsymbolic links using --skip-symbolic-links (or equivalent) is the default. Consider not using this option as it‘ is deprecated and will be removed in a future release.
2020-04-17T08:42:02.065651Z 0 [System] [MY-013169] [Server] /usr/sbin/mysqld (mysqld 8.0.19) initializing of server in progress as process 43
2020-04-17T08:42:04.904103Z 5 [Warning] [MY-010453] [Server] root@localhost is created with an empty password ! Please consider switching off the --initialize-insecure option.
2020-04-17 08:42:07+00:00 [Note] [Entrypoint]: Database files initialized
2020-04-17 08:42:07+00:00 [Note] [Entrypoint]: Starting temporary server
2020-04-17T08:42:08.178144Z 0 [Warning] [MY-011070] [Server] ‘Disablingsymbolic links using --skip-symbolic-links (or equivalent) is the default. Consider not using this option as it‘ is deprecated and will be removed in a future release.
2020-04-17T08:42:08.178264Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.19) starting as process 93
2020-04-17T08:42:08.796812Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
2020-04-17T08:42:08.798557Z 0 [Warning] [MY-011810] [Server] Insecure configuration for --pid-file: Location ‘/var/run/mysqld‘ in the path is accessible to all OS users. Consider choosing a different directory.
2020-04-17T08:42:08.833680Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: ‘8.0.19‘ socket: ‘/var/run/mysqld/mysqld.sock‘ port: 0 MySQL Community Server - GPL.
2020-04-17 08:42:08+00:00 [Note] [Entrypoint]: Temporary server started.
2020-04-17T08:42:08.872465Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Socket: ‘/var/run/mysqld/mysqlx.sock‘
Warning: Unable to load ‘/usr/share/zoneinfo/iso3166.tab‘ as time zone.Skipping it.
Warning: Unable to load ‘/usr/share/zoneinfo/leap-seconds.list‘ as timezone. Skipping it.
Warning: Unable to load ‘/usr/share/zoneinfo/zone.tab‘ as time zone. Skipping it.
Warning: Unable to load ‘/usr/share/zoneinfo/zone1970.tab‘ as time zone. Skipping it.

2020-04-17 08:42:14+00:00 [Note] [Entrypoint]: Stopping temporary server
2020-04-17T08:42:14.401778Z 10 [System] [MY-013172] [Server] Received SHUTDOWN from user root. Shutting down mysqld (Version: 8.0.19).
2020-04-17T08:42:15.868534Z 0 [System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.0.19) MySQL Community Server - GPL.
2020-04-17 08:42:16+00:00 [Note] [Entrypoint]: Temporary server stopped

2020-04-17 08:42:16+00:00 [Note] [Entrypoint]: MySQL init process done.Ready for start up.

2020-04-17T08:42:17.023006Z 0 [Warning] [MY-011070] [Server] ‘Disablingsymbolic links using --skip-symbolic-links (or equivalent) is the default. Consider not using this option as it‘ is deprecated and will be removed in a future release.
2020-04-17T08:42:17.023225Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.19) starting as process 1
2020-04-17T08:42:17.572987Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
2020-04-17T08:42:17.575746Z 0 [Warning] [MY-011810] [Server] Insecure configuration for --pid-file: Location ‘/var/run/mysqld‘ in the path is accessible to all OS users. Consider choosing a different directory.
2020-04-17T08:42:17.598966Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: ‘8.0.19‘ socket: ‘/var/run/mysqld/mysqld.sock‘ port: 3306 MySQL Community Server - GPL.
2020-04-17T08:42:17.685955Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Socket: ‘/var/run/mysqld/mysqlx.sock‘ bind-address:‘::‘ port: 33060
#查看运行进程
$ docker container top mydb
PID USER TIME COMMAND
22501 999 0:02 mysqld

尽管MySQL正在运行,但是除非显式发布网络端口(端口映射),否则主机流量无法和容器互通.

使用docker container exec指令传递命令到容器内部执行:

$ docker exec -it mydb mysql --user=root --password=my-scret-pw --version
mysql: [Warning] Using a password on the command line interface can be insecure.
mysql Ver 8.0.19 for Linux on x86_64 (MySQL Community Server - GPL)

或启动一个交互式shell环境后再执行命令

$ docker exec -it mydb sh
# mysql -uroot -p=my-scret-pw --version
mysql: [Warning] Using a password on the command line interface can be insecure.
mysql Ver 8.0.19 for Linux on x86_64 (MySQL Community Server - GPL)
# exit

任务2: 使用Docker打包并运行自定义的APP

了解如何使用Dockerfile文件构建镜像.
本节通过Dockerfile创建一个简单的nginx Web站点.

构建简单web站点镜像

[node1] (local) root@192.168.0.18 ~
$ cd linux_tweet_app
[node1] (local) root@192.168.0.18 ~/linux_tweet_app
$ cat Dockerfile
FROM nginx:latest

COPY index.html /usr/share/nginx/html
COPY linux.png /usr/share/nginx/html

EXPOSE 80 443

CMD ["nginx", "-g", "daemon off;"]

看下Dockerfile的几行命令:

  • FROM: 指定镜像的基础镜像 nginx:latest
  • COPY: 从Docker主机复制已知位置的文件到镜像
  • EXPOSE: 说明该镜像使用的端口,文档标识
  • CMD: 指定从镜像运行容器时的命令和参数
    配置下DOCKERID环境变量,然后使用docker image build构建镜像:
  • --tag: 指定镜像的名称和版本号
  • .: 表示从当前目录构建.(工作目录)
[node1] (local) root@192.168.0.18 ~/linux_tweet_app
$ export DOCKERID=onion2docker
[node1] (local) root@192.168.0.18 ~/linux_tweet_app
$ echo $DOCKERID
onion2docker
[node1] (local) root@192.168.0.18 ~/linux_tweet_app
$ docker image build --tag $DOCKERID/linux_tweet_app:1.0 .
Sending build context to Docker daemon 110.1kB
Step 1/5 : FROM nginx:latest
latest: Pulling from library/nginx
123275d6e508: Already exists
9a5d769f04f8: Pull complete
faad4f49180d: Pull complete
Digest: sha256:4d947aef8841aed19cc0896a38e12d49d50feba7f583998a164ffeb31e655919
Status: Downloaded newer image for nginx:latest
 ---> 5a8dfb2ca731
Step 2/5 : COPY index.html /usr/share/nginx/html
 ---> eb22926b30dd
Step 3/5 : COPY linux.png /usr/share/nginx/html
 ---> 78953c6d8951
Step 4/5 : EXPOSE 80 443
 ---> Running in 3041e2761ad1
Removing intermediate container 3041e2761ad1
 ---> b7bf4ba858b9
Step 5/5 : CMD ["nginx", "-g", "daemon off;"]
 ---> Running in f451976b0b0d
Removing intermediate container f451976b0b0d
 ---> da9b6949d169
Successfully built da9b6949d169
Successfully tagged onion2docker/linux_tweet_app:1.0

使用docker container run运行创建的镜像,为了能访问容器站点,需要使用--publish host_port:container_port发布端口,这样主机流量就会转发到容器

$ docker container run --detach --publish 80:80 --name linux_tweet_app $DOCKERID/linux_tweet_app:1.0
01442c7d448de9083cae035734577494b6e89d5a91ac08dcf9a4c1a4198020c3
$ curl -is "http://localhost"
HTTP/1.1 200 OK
Server: nginx/1.17.9
Date: Fri, 17 Apr 2020 09:20:34 GMT
Content-Type: text/html
Content-Length: 1595
Last-Modified: Fri, 17 Apr 2020 07:59:22 GMT
Connection: keep-alive
ETag: "5e9961da-63b"
Accept-Ranges: bytes
......

关闭容器:

$ docker container rm --force linux_tweet_app
linux_tweet_app
[node1] (local) root@192.168.0.18 ~/linux_tweet_app
$ docker container ls -al
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e52b5d513a22 mysql:latest "docker-entrypoint.s…" 41 minutes ago Up 41 minutes 3306/tcp, 33060/tcp mydb

rm --force: 强制终止容器并永久移除容器
在生产环境可以用docker container stop优雅终止容器,然后使用docker container rm永久移除

任务3: 修改运行中的web站点

开发阶段, 文件的频繁变更需要反复构建容器, 为此可以使用目录卷将源代码挂在到容器.
使用绑定挂载bind mount可以将主机的文件或目录挂在到在同一主机上运行的容器中.

启动WEB APP容器并挂载本地目录

--mount:挂载选项

 docker container run  --detach  --publish 80:80  --name linux_tweet_app  --mount type=bind,source="$(pwd)",target=/usr/share/nginx/html  $DOCKERID/linux_tweet_app:1.0

添加Html文件查看效果

$ echo Hello > hello.html
$ curl http://localhost/hello.html
Hello

注意,虽然修改了本地挂载文件,但是对镜像没有影响

更新镜像

为持久化变更,可以更新版本好后重新构建镜像

$ rm index.html && mv hello.html index.html
$ docker image build --tag $DOCKERID/linux_tweet_app:2.0 .
Sending build context to Docker daemon 111.1kB
Step 1/5 : FROM nginx:latest
 ---> e791337790a6
Step 2/5 : COPY index.html /usr/share/nginx/html
 ---> Using cache
 ---> 9bba0d45248c
Step 3/5 : COPY linux.png /usr/share/nginx/html
 ---> Using cache
 ---> 883fb1e0aad3
Step 4/5 : EXPOSE 80 443
 ---> Using cache
 ---> fd0d7f3d1eec
Step 5/5 : CMD ["nginx", "-g", "daemon off;"]
 ---> Using cache
 ---> a14d46c7844c
Successfully built a14d46c7844c
Successfully tagged onion2docker/linux_tweet_app:2.0

$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
onion2docker/linux_tweet_app 1.0 a14d46c7844c 6 minutes ago 127MB
onion2docker/linux_tweet_app 2.0 a14d46c7844c 6 minutes ago 127MB
nginx latest e791337790a6 3 hours ago 127MB

#测试新的镜像
$ docker container run --detach --publish 8080:80 --name linux_tweet_app_2 $DOCKERID/linux_tweet_app:2.0
247d3c34e4c38ac646ac4372226103a981155b5fb8bdaa9dd5e4b10d86e1687c
$ curl http://localhost:8080/
Hello

发布镜像到Docker Hub仓库

#查看本地镜像文件
$ docker image ls -f reference="$DOCKERID/*"
REPOSITORY TAG IMAGE ID CREATED SIZE
onion2docker/linux_tweet_app 3.0 3e44efad81c9 4 minutes ago 127MB
onion2docker/linux_tweet_app 1.0 a14d46c7844c 17 minutes ago 127MB
onion2docker/linux_tweet_app 2.0 a14d46c7844c 17 minutes ago 127MB

#登录Docker Hub
$ docker login
#输入账户密码
...
#推送镜像
$ docker image push $DOCKERID/linux_tweet_app:1.0
The push refers to repository [docker.io/onion2docker/linux_tweet_app]
04b796a00591: Pushed
19a921f8822c: Pushed
be91fceb796e: Mounted from library/nginx
919b6770519b: Mounted from library/nginx
b60e5c3bcef2: Mounted from library/nginx
1.0: digest: sha256:88a0a760eda7e92e956273eba39e74f9ac47730d22e71b38d0e67282424ff3aa size: 1363

$ docker image push $DOCKERID/linux_tweet_app:2.0
The push refers to repository [docker.io/onion2docker/linux_tweet_app]
04b796a00591: Layer already exists
19a921f8822c: Layer already exists
be91fceb796e: Layer already exists
919b6770519b: Layer already exists
b60e5c3bcef2: Layer already exists
2.0: digest: sha256:88a0a760eda7e92e956273eba39e74f9ac47730d22e71b38d0e67282424ff3aa size: 1363

以上是关于PlayWithDocker-Docker新手Linux的主要内容,如果未能解决你的问题,请参考以下文章

web前段课程学习 新手总结 2016.9.1 需记内容概要

selenium 学习笔记 ---新手学习记录 问题总结(java)

jQuery - 遍历隐藏的 li 元素

如何居中对齐 li 内的图像?

仅更改某些 li 元素的列表样式[关闭]

如何在 Selenium WebDriver 中获取“ul”类的所有“li”元素