服务计算||docker
服务计算
使用环境:CentOS 7 3.10.0-957.21.3.el7.x86_64
-
安装 Docker
直接使用yum安装
需要先卸载较旧版本的Docker
yum remove -y docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-selinux \ docker-engine-selinux \ docker-engine
安装命令
yum install -y yum-utils device-mapper-persistent-data lvm2 yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo yum install -y docker-ce
启动docker
systemctl start docker
运行helloworld
docker run hello-world
一开始失败,因为没有安装这个给镜像,然后系统会安装镜像
-
运行第一个容器
docker run -d -p 80:80 httpd
结果
[aaa@qq.com ~]$ sudo docker run -d -p 80:80 httpd Unable to find image 'httpd:latest' locally latest: Pulling from library/httpd 000eee12ec04: Pull complete 32b8712d1f38: Pull complete f1ca037d6393: Pull complete c4bd3401259f: Pull complete 51c60bde4d46: Pull complete Digest: sha256:ac6594daaa934c4c6ba66c562e96f2fb12f871415a9b7117724c52687080d35d Status: Downloaded newer image for httpd:latest 10eaa3f5c32a639f7a07c5b2ec1bf7a0c54ca4216645ee3a515ca0e6ff1e5d2e
下面我们可以通过浏览器验证容器是否正常工作。在浏览器中输入 http://http://192.168.122.1/
-
了解docker命令
[aaa@qq.com ~]$ sudo docker --help [sudo] chen 的密码: Usage: docker [OPTIONS] COMMAND A self-sufficient runtime for containers Options: --config string Location of client config files (default "/root/.docker") -c, --context string Name of the context to use to connect to the daemon (overrides DOCKER_HOST env var and default context set with "docker context use") -D, --debug Enable debug mode -H, --host list Daemon socket(s) to connect to -l, --log-level string Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") (default "info") --tls Use TLS; implied by --tlsverify --tlscacert string Trust certs signed only by this CA (default "/root/.docker/ca.pem") --tlscert string Path to TLS certificate file (default "/root/.docker/cert.pem") --tlskey string Path to TLS key file (default "/root/.docker/key.pem") --tlsverify Use TLS and verify the remote -v, --version Print version information and quit Management Commands: builder Manage builds config Manage Docker configs container Manage containers context Manage contexts engine Manage the docker engine image Manage images network Manage networks node Manage Swarm nodes plugin Manage plugins secret Manage Docker secrets service Manage services stack Manage Docker stacks swarm Manage Swarm system Manage Docker trust Manage trust on Docker images volume Manage volumes Commands: attach Attach local standard input, output, and error streams to a running container build Build an image from a Dockerfile commit Create a new image from a container's changes cp Copy files/folders between a container and the local filesystem create Create a new container diff Inspect changes to files or directories on a container's filesystem events Get real time events from the server exec Run a command in a running container export Export a container's filesystem as a tar archive history Show the history of an image images List images import Import the contents from a tarball to create a filesystem image info Display system-wide information inspect Return low-level information on Docker objects kill Kill one or more running containers load Load an image from a tar archive or STDIN login Log in to a Docker registry logout Log out from a Docker registry logs Fetch the logs of a container pause Pause all processes within one or more containers port List port mappings or a specific mapping for the container ps List containers pull Pull an image or a repository from a registry push Push an image or a repository to a registry rename Rename a container restart Restart one or more containers rm Remove one or more containers rmi Remove one or more images run Run a command in a new container save Save one or more images to a tar archive (streamed to STDOUT by default) search Search the Docker Hub for images start Start one or more stopped containers stats Display a live stream of container(s) resource usage statistics stop Stop one or more running containers tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE top Display the running processes of a container unpause Unpause all processes within one or more containers update Update configuration of one or more containers version Show the Docker version information wait Block until one or more containers stop, then print their exit codes Run 'docker COMMAND --help' for more information on a command.
-
Docker 客户端
最常用的 Docker 客户端是
docker
命令。通过docker
我们可以方便地在 Host 上构建和运行容器。docker
支持很多操作(子命令),后面会逐步用到。除了
docker
命令行工具,用户也可以通过 REST API 与服务器通信。Docker 服务器
Docker daemon 是服务器组件,以 Linux 后台服务的方式运行。
Docker daemon 运行在 Docker host 上,负责创建、运行、监控容器,构建、存储镜像。
默认配置下,Docker daemon 只能响应来自本地 Host 的客户端请求。如果要允许远程客户端请求,需要在配置文件中打开 TCP 监听,步骤如下:
- 编辑配置文件 /etc/systemd/system/multi-user.target.wants/docker.service,在环境变量
ExecStart
后面添加-H tcp://0.0.0.0
,允许来自任意 IP 的客户端连接。
如果使用的是其他操作系统,配置文件的位置可能会不一样。 - 重启 Docker daemon。
- 服务器 IP 为 192.168.56.102,客户端在命令行里加上 -H 参数,即可与远程服务器通信。
info
子命令用于查看 Docker 服务器的信息
- 编辑配置文件 /etc/systemd/system/multi-user.target.wants/docker.service,在环境变量
-
docker组件如何协作
[aaa@qq.com ~]$ sudo docker run -d -p 80:80 httpd //ocker 客户端执行 docker run 命令。 Unable to find image 'httpd:latest' locally //Docker daemon 发现本地没有 httpd 镜像。 latest: Pulling from library/httpd //daemon 从 Docker Hub 下载镜像。 000eee12ec04: Pull complete 32b8712d1f38: Pull complete f1ca037d6393: Pull complete c4bd3401259f: Pull complete 51c60bde4d46: Pull complete Digest: sha256:ac6594daaa934c4c6ba66c562e96f2fb12f871415a9b7117724c52687080d35d Status: Downloaded newer image for httpd:latest //下载完成,镜像 httpd 被保存到本地。 10eaa3f5c32a639f7a07c5b2ec1bf7a0c54ca4216645ee3a515ca0e6ff1e5d2e //Docker daemon 启动容器。
docker images
[aaa@qq.com ~]$ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE httpd latest 2ae34abc2ed0 4 weeks ago 165MB hello-world latest fce289e99eb9 12 months ago 1.84kB [aaa@qq.com ~]$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 10eaa3f5c32a httpd "httpd-foreground" 10 minutes ago Up 10 minutes 0.0.0.0:80->80/tcp hopeful_kare [aaa@qq.com ~]$
-
hello-world 最小的镜像
[aaa@qq.com ~]$ sudo docker pull hello-world Using default tag: latest latest: Pulling from library/hello-world Digest: sha256:4fe721ccc2e8dc7362278a29dc660d833570ec2682f4e4194f4ee23e415e1064 Status: Image is up to date for hello-world:latest docker.io/library/hello-world:latest [aaa@qq.com ~]$ sudo dockers images hello-world sudo: dockers:找不到命令 [aaa@qq.com ~]$ sudo docker images hello-world REPOSITORY TAG IMAGE ID CREATED SIZE hello-world latest fce289e99eb9 12 months ago 1.84kB [aaa@qq.com ~]$
[aaa@qq.comase ~]$ sudo docker run hello-world 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/ [aaa@qq.com ~]$
hello-world 的 Dockerfile 内容如下:
只有短短三条指令。
- FROM scratch
此镜像是从白手起家,从 0 开始构建。 - COPY hello /
将文件“hello”复制到镜像的根目录。 - CMD ["/hello"]
容器启动时,执行 /hello
镜像 hello-world 中就只有一个可执行文件 “hello”,其功能就是打印出 “Hello from Docker …” 等信息。
/hello 就是文件系统的全部内容,连最基本的 /bin,/usr, /lib, /dev 都没有。
- FROM scratch
-
base镜像
base 镜像有两层含义:
- 不依赖其他镜像,从 scratch 构建。
- 其他镜像可以之为基础进行扩展。
下载镜像:
docker pull centos
[aaa@qq.com ~]$ sudo docker pull centos Using default tag: latest latest: Pulling from library/centos 729ec3a6ada3: Pull complete Digest: sha256:f94c1d992c193b3dc09e297ffd54d8a4f1dc946c37cbeceb26d35ce1647f88d9 Status: Downloaded newer image for centos:latest docker.io/library/centos:latest
查看镜像信息:
[aaa@qq.com ~]$ sudo docker images centos [sudo] chen 的密码: REPOSITORY TAG IMAGE ID CREATED SIZE centos latest 0f3e07c0138f 2 months ago 220MB
-
构建镜像
docker commit 命令是创建新镜像最直观的方法,其过程包含三个步骤:
\1. 运行容器
\2. 修改容器
\3. 将容器保存为新的镜像
-
第一步, 运行容器
-it
参数的作用是以交互模式进入容器,并打开终端。412b30588f4a
是容器的内部 ID。[aaa@qq.com ~]$ sudo docker run -it ubuntu Unable to find image 'ubuntu:latest' locally latest: Pulling from library/ubuntu 2746a4a261c9: Pull complete 4c1d20cdee96: Pull complete 0d3160e1d0de: Pull complete c8e37668deea: Pull complete Digest: sha256:250cc6f3f3ffc5cdaa9d8f4946ac79821aafb4d3afc93928f0de9336eba21aa4 Status: Downloaded newer image for ubuntu:latest aaa@qq.com:/#
-
安装 vi
aaa@qq.com:/# vim bash: vim: command not found
确认 vi 没有安装。
更新apt-get
apt-get update apt-get install vim -y
-
保存为新镜像
在新窗口中查看当前运行的容器docker ps
[aaa@qq.com ~]$ sudo docker ps [sudo] chen 的密码: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 1d759aafe85c ubuntu "/bin/bash" 9 minutes ago Up 9 minutes trusting_mcclintock 10eaa3f5c32a httpd "httpd-foreground" 41 minutes ago Up 41 minutes 0.0.0.0:80->80/tcp hopeful_kare
docker commit执行 docker commit 命令将容器保存为镜像。
新镜像命名为
ubuntu-with-vi
。[aaa@qq.com ~]$ sudo docker commit trusting_mcclintock ubuntu-with-vi sha256:7353f9cbdc6df58e0b1d35a02311da47e51b436916f79f43c56187fd0862615d [aaa@qq.com ~]$ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu-with-vi latest 7353f9cbdc6d 13 seconds ago 152MB ubuntu latest 549b9b86cb8d 8 days ago 64.2MB httpd latest 2ae34abc2ed0 4 weeks ago 165MB centos latest 0f3e07c0138f 2 months ago 220MB hello-world latest fce289e99eb9 12 months ago 1.84kB [aaa@qq.com ~]$
查看新镜像的属性。从 size 上看到镜像因为安装了软件而变大了。
从新镜像启动容器,验证 vi 已经可以使用。
-
-
Dockerfile 构建镜像
创建dockerfile文件
touch Dockerfile
Dockerfile文件内容
运行
docker build -t ubuntu-with-vi-dockerfile .
安装成功
查看熟悉
docker images
[aaa@qq.com ~]# sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu-with-vi-dockerfile latest 79e6c9a350a0 36 seconds ago 286MB ubuntu-with-vi latest 7353f9cbdc6d 27 minutes ago 152MB ubuntu latest 549b9b86cb8d 8 days ago 64.2MB httpd latest 2ae34abc2ed0 4 weeks ago 165MB centos latest 0f3e07c0138f 2 months ago 220MB hello-world latest fce289e99eb9 12 months ago 1.84kB [aaa@qq.com ~]#
-
镜像的缓存特性
在前面的 Dockerfile 中添加一点新内容,往镜像中复制一个文件:
-
调试dockerfile
-
RUN vs CMD vs ENTRYPOINT
-
使用公共 Registry
-
首先得在 Docker Hub 上注册一个账号。
-
在 Docker Host 上登录。
[aaa@qq.com ~]# docker login -u chentf5 Password: WARNING! Your password will be stored unencrypted in /root/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded
-
修改镜像的 repository 使之与 Docker Hub 账号匹配。
Docker Hub 为了区分不同用户的同名镜像,镜像的 registry 中要包含用户名,完整格式为:[username]/xxx:tag
我们通过docker tag
命令重命名镜像。[aaa@qq.com ~]# docker tag httpd chentf5/httpd:v1 [aaa@qq.com ~]# docker images chentf5/httpd REPOSITORY TAG IMAGE ID CREATED SIZE chentf5/httpd v1 2ae34abc2ed0 4 weeks ago 165MB [aaa@qq.com ~]# docker push chentf5/httpd:v1
注:Docker 官方自己维护的镜像没有用户名,比如 httpd。
-
通过 docker push 将镜像上传到 Docker Hub。
Docker 会上传镜像的每一层。因为 cloudman6/httpd:v1 这个镜像实际上跟官方的 httpd 镜像一模一样,Docker Hub 上已经有了全部的镜像层,所以真正上传的数据很少。同样的,如果我们的镜像是基于 base 镜像的,也只有新增加的镜像层会被上传。如果想上传同一 repository 中所有镜像,省略 tag 部分就可以了,例如:
docker push cloudman6/httpd[aaa@qq.com ~]# docker push chentf5/httpd:v1 The push refers to repository [docker.io/chentf5/httpd] 3596c568ff88: Mounted from library/httpd 0b56a8e92b13: Mounted from library/httpd 133d2fad03ff: Pushed 83c5929f7818: Mounted from library/httpd 831c5620387f: Pushed v1: digest: sha256:f8a3e48d46d2b90386636264c2024173d30be1443aac88faf3da455fce15ce72 size: 1367
-
登录 https://hub.docker.com,在Public Repository 中就可以看到上传的镜像。
如果要删除上传的镜像,只能在 Docker Hub 界面上操作。
-
这个镜像可被其他 Docker host 下载使用了。
-
-
搭建本地 Registry
启动 registry 容器。
[aaa@qq.com ~]# docker run -d -p 5000:5000 -v /myregistry:/var/lib/registry registry:2 Unable to find image 'registry:2' locally 2: Pulling from library/registry c87736221ed0: Pull complete 1cc8e0bb44df: Pull complete 54d33bcb37f5: Pull complete e8afc091c171: Pull complete b4541f6d3db6: Pull complete Digest: sha256:8004747f1e8cd820a148fb7499d71a76d45ff66bac6a29129bfdbfdc0154d146 Status: Downloaded newer image for registry:2 79b55188a9f044c43623a7b8eb8d2f9668e57be90cee63191d7fa392816a92ae
通过
docker tag
重命名镜像,使之与 registry 匹配。[aaa@qq.com ~]# docker tag chentf5/httpd:v1 127.0.0.1:5000/chentf5/httpd:v1 [aaa@qq.com ~]# sudo docker push 127.0.0.1:5000/chentf5/httpd:v1 The push refers to repository [127.0.0.1:5000/chentf5/httpd]
通过
docker pull
上传镜像。The push refers to repository [127.0.0.1:5000/chentf5/httpd] 3596c568ff88: Pushed 0b56a8e92b13: Pushed 133d2fad03ff: Pushed 83c5929f7818: Pushed 831c5620387f: Pushed v1: digest: sha256:f8a3e48d46d2b90386636264c2024173d30be1443aac88faf3da455fce15ce72 size: 1367
删除下载镜像
[aaa@qq.com ~]# sudo docker rmi 127.0.0.1:5000/chentf5/httpd:v1 Untagged: 127.0.0.1:5000/chentf5/httpd:v1 Untagged: 127.0.0.1:5000/chentf5/aaa@qq.com:f8a3e48d46d2b90386636264c2024173d30be1443aac88faf3da455fce15ce72 [aaa@qq.com ~]# sudo docker pull 127.0.0.1:5000/chentf5/httpd:v1 v1: Pulling from chentf5/httpd Digest: sha256:f8a3e48d46d2b90386636264c2024173d30be1443aac88faf3da455fce15ce72 Status: Downloaded newer image for 127.0.0.1:5000/chentf5/httpd:v1 127.0.0.1:5000/chentf5/httpd:v1 [aaa@qq.com ~]#
-
如何自定义容器网络?
我们可通过 bridge 驱动创建类似前面默认的 bridge 网络,例如:
我们可通过 bridge 驱动创建类似前面默认的 bridge 网络,例如:
[aaa@qq.com ~]# docker network create --driver bridge my_net adabae7d3d5132c0f2997c20270b2263ec28940ae40b7e793473a453cb4eeded
查看一下当前 host 的网络结构变化:
[aaa@qq.com ~]# brctl show bridge name bridge id STP enabled interfaces br-85876ba1d740 8000.02420b24ffcf no br-adabae7d3d51 8000.0242c6bcde10 no docker0 8000.0242e4bbc687 no veth8c07daf vethfbf021f virbr0 8000.525400fe55f8 yes virbr0-nic [aaa@qq.com ~]# docker network inspect my_net
新增了一个网桥
br-eaed97dc9a77
,这里eaed97dc9a77
正好新建 bridge 网络my_net
的短 id。执行docker network inspect
查看一下my_net
的配置信息:[aaa@qq.com ~]# docker network inspect my_net [ { "Name": "my_net", "Id": "adabae7d3d5132c0f2997c20270b2263ec28940ae40b7e793473a453cb4eeded", "Created": "2019-12-27T18:46:31.254486254+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.19.0.0/16", "Gateway": "172.19.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": {}, "Options": {}, "Labels": {} } ]
这里 172.18.0.0/16 是 Docker 自动分配的 IP 网段。
我们可以自己指定 IP 网段吗?
答案是:可以。只需在创建网段时指定
--subnet
和--gateway
参数:[aaa@qq.com ~]# docker network create --driver bridge --subnet 172.22.16.0/24 --gateway 172.22.16.1 my_net2 86adb34f823b0541d9e0821a605c0505bb609d789cfff3b42e434cd2262c23e4 [aaa@qq.com ~]# docker nerwork inspect my_net2 docker: 'nerwork' is not a docker command. See 'docker --help' [aaa@qq.com ~]# docker network inspect my_net2 [ { "Name": "my_net2", "Id": "86adb34f823b0541d9e0821a605c0505bb609d789cfff3b42e434cd2262c23e4", "Created": "2019-12-27T18:48:50.212167647+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.22.16.0/24", "Gateway": "172.22.16.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": {}, "Options": {}, "Labels": {} } ]
这里我们创建了新的 bridge 网络
my_net2
,网段为 172.22.16.0/24,网关为 172.22.16.1。与前面一样,网关在my_net2
对应的网桥br-5d863e9f78b6
上:[aaa@qq.com ~]# ifconfig br-86adb34f823b br-86adb34f823b: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 inet 172.22.16.1 netmask 255.255.255.0 broadcast 172.22.16.255 ether 02:42:07:d5:77:45 txqueuelen 0 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
容器要使用新的网络,需要在启动时通过
--network
指定:[aaa@qq.com ~]# docker run -it --network=my_net2 busybox Unable to find image 'busybox:latest' locally docker: Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: TLS handshake timeout. See 'docker run --help'. [aaa@qq.com ~]# docker run -it --network=my_net2 busybox Unable to find image 'busybox:latest' locally docker: Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: TLS handshake timeout. See 'docker run --help'.
这里一直失败。。。
容器分配到的 IP 为 172.22.16.2。
到目前为止,容器的 IP 都是 docker 自动从 subnet 中分配,我们能否指定一个静态 IP 呢?
答案是:可以,通过
--ip
指定。注:只有使用
--subnet
创建的网络才能指定静态 IP。my_net
创建时没有指定--subnet
,如果指定静态 IP 报错如下:
上一篇: SpringMVC的返回值类型
推荐阅读
-
phpmyadmin报错原因及解决办法:无法在发生异常时创建会话,请检查 PHP 或网站服务器日志,并正确配置 PHP 安装
-
PHP跨平台获取服务器IP地址自定义函数分享,phpip自定义函数_PHP教程
-
开发一款app,php做服务端,有一个功能是附近的人和发布动态的时候发布自己的定位,php世界有啥好的方案去做这些吗?
-
MySQL创办计算字段MySQL系列(五)
-
PHP实现Amazon简单邮件服务SMTP_PHP教程
-
php计算整个目录大小的方法_PHP
-
curl 分页获取十几万的数据 服务器超时,如何解决?
-
java利用jsch实现sftp上传一个目录下的所有文件到Linux服务器
-
Mysql服务无法启动的1067错误解决_MySQL
-
ssh 客户端连接服务器超时 配置连接时间 保持活跃状态