Docker 初级实战

1. 安装 Docker;

安装

# 阿里云帮助文档参考:
# https://yq.aliyun.com/articles/110806?spm=a2c1q.8351553.0.0.11b720beQRyGTx
# 官网安装参考:https://docs.docker.com/install/linux/docker-ce/centos/

# 安装依赖插件
yum install -y yum-utils device-mapper-persistent-data lvm2

# 设置即将安装的是稳定版仓库
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

# 查看仓库中所有的 docker 版本(可选操作)
yum list docker-ce --showduplicates | sort -r

# 安装
yum install docker-ce -y

# 启动 docker 并设置开机启动
systemctl start docker
systemctl enable docker

# docker 安装时默认创建了 docker 用户组
# 将普通用户加入 docker 用户组就可以不使用 sudo 来操作 docker
sudo usermod -aG docker [用户名]

# 退出控制台重新登录,或者
newgrp - docker 

下载镜像、安装外部容器

## 参考资料
# 官网内置镜像访问:https://hub.docker.com
# 阿里云镜像:https://promotion.aliyun.com/ntms/act/kubernetes.html#latest

## 操作:
# 设置镜像加速器:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
	# 此处为 aliyun 给出的地址
  	"registry-mirrors": ["https://xxx.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

# 镜像搜索:https://cr.console.aliyun.com/cn-hangzhou/instances/images
# 搜索:lxepoo/apache-php5
# 拉取镜像
docker pull registry.cn-hangzhou.aliyuncs.com/lxepoo/apache-php5
# 查看当前镜像
docker images
# 返回
REPOSITORY                                             TAG                 IMAGE ID            CREATED             SIZE
registry.cn-hangzhou.aliyuncs.com/lxepoo/apache-php5   latest              e121d5f99e1e        3 years ago         448MB
# 启动容器
# run:把镜像放入容器中(只在第一次运行)
# -d:启动容器后台运行,并返回 ID
# -p:把容器的 80 端口映射到宿主机(虚拟机)的 8080
# docker run -d -p 8080:80 [REPOSITORY / IMAGE ID]
docker run -d -p 8080:80 e121d5f99e1e

# 列出当前正在运行的容器
docker ps
# 返回
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
a7c0c9d48aa3        e121d5f99e1e        "/usr/bin/supervisord"   21 seconds ago      Up 15 seconds       0.0.0.0:8080->80/tcp   peaceful_brahmagupta

# 停止容器
# docker stop [CONTAINER ID]
docker stop a7c0c9d48aa3

# 查看所有容器(包括已经停止的)
docker ps -a
# 返回
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS               NAMES
a7c0c9d48aa3        e121d5f99e1e        "/usr/bin/supervisord"   12 minutes ago      Exited (0) 6 seconds ago                       peaceful_brahmagupta

# 重新启动容器
docker start a7c0c9d48aa3

# 防火墙打开 8080 端口
iptables -I INPUT -p tcp --dport 8080 -j ACCEPT

# 常见错误:IPv4 forwarding is disabled. Networking will not work.
# 解决办法:
# 修改 Linux 内核参数配置文件,可在运行时修改某些内核参数,使之永久生效
vim /etc/sysctl.conf
# 加入以下代码
net.ipv4.ip_forward=1
# 保存并退出后执行
systemctl restart network

2. 容器基本操作;

2.1 拉取镜像、创建、操作容器、执行命令;

  • 在生产环境里使用,肯定是要自己定制镜像。可以下载一个官方的纯镜像再加上自己的配置。一般来说是不会直接拿别人的镜像直接使用的,因为别人可能在镜像里放入一些文件、或者做一些手脚,我们很难去分辨。所以一般自己去定制一个镜像
  • 搜索官方 CentOS 镜像:https://cr.console.aliyun.com/cn-hangzhou/instances/images?search=centos
    在这里插入图片描述
# 拉取 CentOS 官方镜像
docker pull centos

# 查看当前容器
docker images
# 返回
REPOSITORY                                             TAG                 IMAGE ID            CREATED             SIZE
centos                                                 latest              470671670cac        7 weeks ago         237MB
registry.cn-hangzhou.aliyuncs.com/lxepoo/apache-php5   latest              e121d5f99e1e        3 years ago         448MB

# 查看基本说明
docker run --help

# docker run 命令,可以把镜像放到容器里面来进行运行
# 在启动容器之前,只需要运行一次就可以
# run 并不代表启动容器,而是操作镜像去放到 docker 中去产生一个容器
# 之前下载的镜像里面没有 Apache,也没有 PHP,所以使用交互式操作方式
# -i:打开 stdin,用于和容器进行交互,通常和 -t 同时使用
# -t:为容器创建虚拟终端,就可以登录终端,通常和 -i 同时使用(类似 Termius 操作 Linux)
# --name [name]:为容器指定一个名称
# *另:所谓的镜像,都是官方或者第三方(包括我们自己)把操作系统和一些必要的软件提前装好
# docker 起到隔离的作用,把操作系统隔离起来,每个镜像都可以快速的移植和部署自己的项目
docker run -i -t --name myos1 centos

# 此时已经进入了容器,ls 查看容器里面的内容
# 这就是官方给我们创建好的操作系统
[root@9d38d2bef7aa /]# ls

# 按 Ctrl + D 退出容器,运行 docker ps,什么都没有
# 并不是容器被删掉了,而是没有在运行,可以通过 docker ps -a 查看所有容器(包括已经退出的)
docker ps -a
# 重新启动
docker start myos1
docker ps
# 返回
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
9d38d2bef7aa        centos              "/bin/bash"         2 days ago          Up 7 seconds                            myos1
# COMMAND 代表如果不做任何的参数,自动会启动容器里面的 "/bin/bash",它是默认的命令
# 之后在启动容器的时候可以加入自定义的命令
# IMAGE 表示依赖的镜像是 centos

# 再次进入容器,好比通过终端登录容器
# 参考:https://docs.docker.com/engine/reference/commandline/attach/
docker attach myos1
exit

# 组合命令
# -a:只能打开容器的输出流
# -i:打开容器的输出
docker start -a -i myos1
exit

# docker exec:在运行中的容器中执行命令
# 往容器里写入 test 文件
docker start myos1
docker attach myos1
echo "test" >> test
cat test
exit

# test 文件存在于容器里,重启后也不会被删掉
docker start myos1
docker exec myos1 cat test
exit
# 返回 test

# 直接进入容器
# 和 attach 进入容器一样
docker exec -it myos1 /bin/bash
exit
# 此时 docker ps,容易没有被退出

2.2 Dockerfile 的使用、创建 Apache 镜像、启动容器访问外部网站;

回顾

# 查看镜像
docker images
# 返回
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              470671670cac        8 weeks ago         237MB
# TAG 为 lastest,表示最新版本
# 操作 docker run -it centos,会创建一个新的镜像也叫 centos,只是 TAG 不一样
# 一般情况下 REPOSITORY 不写,会自动去取 :latest,这是一个标签,不代表一定是最新的

根据镜像设置容器的基本功能

# 要部署网站,安装一些软件
# 如果用 attach 进入,各种 yum,会发现很多权限问题

# 利用 Dockerfile 创建一个镜像
# Dockerfile 可以理解为一个配置文件,这个配置文件在构建镜像的时候可以放入一些命令
# 之前的 centos 镜像,如果要安装 Apache,PHP 等,需要使用 Dockerfile 对里面的内容进行初始化
# 官方文档:https://docs.docker.com/engine/reference/run/

# 案例:譬如 PHP 的开发人员,可能要用到 Apache(httpd),直接构建出一个环境容器
## 2.2.1 先创建一个空文件夹,cd 进入
cd /home/[当前用户]
mkdir build
cd build

## 2.2.2 然后创建一个文件叫做 Dockerfile(注意大小写)
# 注释:
# FROM:后面跟:名称:标签,定位到当前镜像。从一个已有的空的纯净的镜像去创建一个新镜像
# RUN:代表创建新镜像去执行哪些命令,可以写很多个 RUN
# EXPOSE 80:暴露 80 端口,在外部就可以把 80 映射到宿主机里某一个端口,在外部就能访问
# 容器是通过 EXPOSE 命令暴露端口的,不像外面的宿主机通过防火墙暴露端口
touch Dockerfile
vim Dockerfile
# 插入内容如下
FROM centos:latest
RUN yum -y install httpd
RUN systemctl enable httpd.service
EXPOSE 80
# 保存退出

## 2.2.3 再根据 Dockerfile 去创建一个新的镜像(不是容器)
# docker build 命令:读取 Dockerfile 创建镜像
# -t:指定镜像名称
# centos:httpd 为名称:标签
# 注意有个点,代表当前文件夹
docker build -t centos:httpd .
# 也可以指定 Dockerfile
docker build -f /home/[当前用户]/build/Dockerfile .

## 2.2.4 查看镜像
docker images
# 返回两个镜像
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
centos              httpd               6a4051ec9ae9        About a minute ago   283MB
centos              latest              470671670cac        8 weeks ago          237MB

## 2.2.5 启动容器
# -d 后台运行,-p 映射端口
# 注意参数位置不要乱写
docker run -d -p 8080:80 --name myhttpd centos:httpd
# 发现无法启动,docker ps -a 发现 STATUS 为 Exited
# docker start myhttpd ,依然无法启动(因为权限问题)
# 如果用 Ubuntu 镜像就启动成功了,但是 centos 镜像由于权限问题无法启动(并没有报错)
# 删除容器
docker rm myhttpd

# 以交互方式进入,启动
docker run -i -t -p 8080:80 --name myhttpd centos:httpd

# 使用 exec 或者 attach 交互
docker exec -it myhttpd /bin/bash

# 进入容器后,启动 Apache
systemctl start httpd
# 报错可能:Operation not permitted
# 报错可能:System has not been booted with systemd as init system (PID 1). Can't operate.

## 2.2.6 解决权限问题
# --privileged:给容器加特权,否则交互式方式进入容器无法操作一些比如修改内核、修改系统参数、启动服务等
# 不需要加 -i 和 -t 了,因为需要在容器启动的时候运行 /usr/sbin/init,加了也启动不了 /bin/bash
# 最后的命令时指在启动容器时执行命令 /usr/sbin/init
# 参考文档:
# https://docs.docker.com/engine/reference/commandline/run/#capture-container-id-cidfile
# https://github.com/moby/moby/issues/7459
# https://developers.redhat.com/blog/2014/05/05/running-systemd-within-docker-container/
docker run --privileged -d -p 8080:80 --name myhttpd centos:httpd /usr/sbin/init

# 进入容器
docker exec -it myhttpd /bin/bash

# 操作
systemctl status httpd

# 在 Dockerfile 一次性搞定
# CMD 只能写一个命令
FROM centos:latest
RUN yum -y install httpd
RUN systemctl enable httpd.service
CMD /usr/sbin/init
EXPOSE 80

## 2.2.7 查看容器日志
docker logs [容器id]

2.3 容器与主机间的数据共享;

如果开发好网站之后,如何把网站文件部署到容器里面,是拷贝进去、还是通过 sshd,让外部直接去连容器?这两种方式都是可以的,但是一般不这么做

# 一些知识:
# 之前通过 yum 安装的Apache(httpd),默认配置文件在 /etc/httpd/conf/httpd.conf
# 根据默认的配置文件内容,默认的网站目录指向 /var/www/html/

# docker run -v 参数:给容器和主机之间进行一个映射
# 在容器里面创建一个挂载点,可以把当前主机已经存在的实体磁盘目录挂载到容器的某一个目录
# 2.3.1 准备工作:停掉之前的容器,并删除
# 2.3.2 在主机上创建一个目录叫 /home/php/myweb
# 之前的启动参数命令是 docker run --privileged -d -p 8080:80 --name myhttpd centos:httpd /usr/sbin/init
# 在这基础上加一个 -v 参数
#(最后一段 /usr/bin/init 不需要了,已经写进 Dockerfile 里)
docker run --privileged -d -p 8080:80 --name myhttpd \
-v /home/code/myweb:/var/www/html centos:httpd /usr/sbin/init
# 在容器中设置了一个挂载点 /var/www/html,并将主机上的 /home/php/web/ 目录映射到/var/www/html 下
# 这时候在容器中操作该目录、或者在主机中操作,两边都是实时同步的

2.4 拷贝 JDK 配置 JAVA 环境;

JDK 需要通过 Dockerfile 的方式拷贝到容器里。也可以通过映射的方式,但是运行环境部分应该固化在环境里面。因为镜像可能会被发布到阿里云或者其它镜像源上。

# 2.4.1 主机下载 jdk1.8.0_121 解压版

# 2.4.2 主机配置环境变量,JDK 才能生效
# 修改 /etc/profile,加入以下内容
export JAVA_HOME=/usr/local/jdk1.8.0_121
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

# 2.4.3 Docker 配置 JAVA 环境
# 新建文件夹
cd /home/[当前用户]
mkdir build_jdk
cd build_jdk

# 下载好的 jdk1.8.0_121 拷贝到当前目录
cp /usr/local/jdk1.8.0_121 /home/[当前用户]/build_jdk
# 创建 Dockerfile
vim Dockerfile
# 写入以下内容(使用之前的镜像基础)
FROM centos:httpd
COPY jdk1.8.0_121 /usr/local/jdk1.8.0_121/
ENV JAVA_HOME=/usr/local/jdk1.8.0_121
ENV PATH $JAVA_HOME/bin:$PATH
ENV CLASSPATH .:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
CMD /usr/sbin/init
# 保存后退出,执行
docker build -t centos:jdk .

# 启动
docker run --privileged -d -p 8080:80 --name myjdk \
-v /home/code/myweb:/var/www/html centos:jdk

2.5 Docker 可编程性、配置远程连接;

一些概念

# 之前在执行 build 命令的时候
docker build -t centos:jdk .
# 返回
build context to Docker daemon 123MB
# 是通过 Docker 守护进程(daemon)运行的,不是 CLI 客户端命令
# 第一次运行的时候会把整个上下文的文件夹内容(context)发送给守护进程(daemon)

# Docker 本身是一个 CS 架构的程序,有 Client 也有 Server
# 技术上把 daemon 作为守护进程,也就是**服务端**
# 在执行 docker images 时,出现了所有 images 的时候
# 那不是直接操作服务端,而是 Docker 给客户端发送一个命令
# 这个命令的执行是 Docker 客户端执行的(docker 官方老外给的客户端)
# 这个客户端一旦执行 docker images,就可以在内部程序里面调用 Docker 服务端 API
# 除了使用本机的 Docker 客户端,还可以自己写客户端程序调用

# Docker 服务端提供了一系列 REST API(Docker Remote API)
# 敲入 docker 命令时实际上是通过 API 和 Docker 服务端进行交互的

# 参考文档:https://docs.docker.com/engine/api/sdk/
# 官网说明:Docker API 是一个 RESTful API,可以使用 HTTP client,比如 wget 或者 curl
# 所以在执行 docker build -t centos:jdk . 的时候,会把当前文件夹内容作为上下文,默认会去寻找 Dockerfile
# 这个 Dockerfile 也可以指定,不一定要用默认的
# 如果当前文件夹出现其它文件或者文件夹,会把它们一次性的发送给服务端,类似开发网站程序,前端调用后端内容
# 前端是一个按钮,点了按钮之后,当前本地浏览器下的文件发送给服务端,得到文件后才可以进行处理

# Docker 提供了三种基本的连接方式
# 第一种为默认连接方式(本机链接方式,同 Mysql 一样)
unix:///var/run/docker/sock
tcp://host:port
fd://socketfd

# 查看连接方式
ps -ef | grep docker

配置远程访问

# 查看 docker.service 和 docker.sock 所在位置
find / -name docker.service
find / -name docker.sock

# 编辑(注意服务进程一般都有 “d” 在结尾)
vim /lib/systemd/system/docker.service 
# 修改 ExecStart=/usr/sbin/dockerd -H fd:// $DOCKER_OPTS 为如下
# 意思是本机使用 unix 连接,外部连接使用 tcp
ExecStart=/usr/sbin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock

# 保存退出 重启 Docker(守护进程重新加载)
systemctl daemon-reload
systemctl restart docker

# 重新查看连接方式
ps -ef | grep docker

# 连接参考:https://docs.docker.com/engine/api/sdk/examples/

2.6 Docker管理工具 portainer、创建 MySql 容器并外部连接;

管理工具 portainer

# portainer 本身也是容器,需要拉取镜像
docker pull portainer/portainer

# 运行容器(使用后台运行)
docker run -d -p 9010:9000 -v /var/run/docker.sock:/var/run/docker.sock \
-v /opt/portainer:/data --name mydocker portainer/portainer

# 宿主机访问:http://localhost:9010/#/init/admin

3. Nginx 负载均衡;

发布了125 篇原创文章 · 获赞 13 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/hualaoshuan/article/details/104736199
今日推荐