docker 入门

docker容器

镜像是只读的,基于镜像启动一个容器,这个容器才是可写的

1、docker安装

rm -fr /etc/yum.repos.d/local.repo
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo
sed -i 's#download.docker.com#mirrors.tuna.tsinghua.edu.cn/docker-ce#g' /etc/yum.repos.d/docker-ce.repo
yum install docker-ce -y

2、docker的主要组成部分

  • docker是传统的CS架构分为docker client和docker server,和mysql一样

    [root@docker01 ~]# docker version
    Client:
     Version:           18.09.6
     API version:       1.39
     Go version:        go1.10.8
     Git commit:        481bc77156
     Built:             Sat May  4 02:34:58 2019
     OS/Arch:           linux/amd64
     Experimental:      false
    
    Server: Docker Engine - Community
     Engine:
      Version:          18.09.6
      API version:      1.39 (minimum version 1.12)
      Go version:       go1.10.8
      Git commit:       481bc77
      Built:            Sat May  4 02:02:43 2019
      OS/Arch:          linux/amd64
      Experimental:     false
    

    如果做监控的话,主要使用:docker info

    docker主要组件有:镜像、容器、仓库, 网络,存储

    启动容器必须需要一个镜像,仓库中只存储镜像:容器---镜像---仓库
    

3、启动第一个容器

##配置docker镜像加速
vi /etc/docker/daemon.json
{
  "registry-mirrors": ["https://registry.docker-cn.com"]
}	

docker run -d -p 80:80 nginx
run	(创建并运行一个容器)
-d	 放在后台
-p	 端口映射
nginx	 docker镜像的名字

4、docker的镜像管理

  • 搜索镜像

    docker search 镜像名
        选镜像的建议:
        1,优先考虑官方
        2,stars数量多
    

  • 获取镜像

    docker pull(push)
    	镜像加速器:
    	阿里云加速器,daocloud加速器,中科大加速器,Docker 中国官方镜像加速:https://registry.docker-cn.com
    	
    官方pull	    docker pull centos:6.8(没有指定版本,默认会下载最新版)
    私有仓库pull	docker pull daocloud.io/huangzhichong/alpine-cn:latest 
    
    ##配置docker镜像加速
    vi /etc/docker/daemon.json
    {
      "registry-mirrors": ["https://registry.docker-cn.com"]
    }	
    

  • 管理镜像

    查看镜像列表
    	docker images  			## 等价于:docker image  ls
    删除镜像
    	docker rmi  例子:docker image rm centos:latest
    导出镜像
    	docker save  例子:docker image save centos > docker-centos7.4.tar.gz
    导入镜像
    	docker load  例子:docker image load -i docker-centos7.4.tar.gz
    

5、docker的容器管理

docker run -d -p 80:80 nginx:latest  
    run(创建并运行一个容器)
    -d 放在后台
    -p 端口映射
    -v  源地址(宿主机):目标地址(容器)
    nginx :	docker镜像的名字
    
docker run -it --name centos6 centos:6.9 /bin/bash
    -it   分配交互式的终端
    --name 指定容器的名字
    /bin/bash覆盖容器的初始命令

  • 容器管理

    创建并运行容器
    	docker run image_name
    	docker run -it image_name CMD
    	## docker run == docker create  + docker start
    停止容器
    	docker stop CONTAINER_ID
    启动容器
    	docker start CONTAINER_ID
    杀死容器
    	docker kill container_name
    查看容器列表
    	docker ps	: 列出正在运行的容器
    	docker ps –a : 列出所有容器
    	docker ps -a -l : 查看最后一个创建的容器
    	docker ps -a --no-trunc : 查看容器的详细信息
    	docker ps -a -q : 只显示容器的id
        
    查看容器日志
    	docker logs CONTAINER_ID
        
    进入容器(目的,调试,排错)
    ***	docker exec  (会分配一个新的终端tty)
    		docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
    		
        docker exec -it  容器id或容器名字 /bin/bash(/bin/sh)
    		
    	docker attach(使用同一个终端)
    		docker attach [OPTIONS] CONTAINER
    		
    删除容器
    	docker rm
    批量删除容器
        docker rm -f `docker ps -a -q`
    	
    总结:(*********)
    	docker容器内的第一个进程(初始命令)必须一直处于前台运行的状态(必须夯住),否则这个容器,就会处于	退出状态!
    
    业务在容器中运行:夯住,启动服务
    

6、docker容器的网络访问(端口映射)

如果不做端口映射,外网无法直接访问容器上的服务

指定映射(docker 会自动添加一条iptables规则来实现端口映射)
	-p hostPort:containerPort	
	-p ip:hostPort:containerPort  # 多个容器都想使用80端口
	
	-p ip::containerPort	# (随机端口)
	-p hostPort:containerPort:udp	# 使用udp开启端口映射
	-p 81:80 –p 443:443 	# 可以指定多个-p
	
eg:
	docker run -d -p 80:80 nginx	# 将宿主机的80端口映射到容器的80端口
	docker run -d -p 10.0.0.51:80:80 nginx	# 将宿主机10.0.0.51的80端口映射到容器的80 端口
	docker run -d -p  10.0.0.100::53 nginx	# 将宿主机的10.0.0.100分配的随机端口映射到容器的80

随机映射
	docker run -P (随机端口)
还可以通过iptables来实现的端口映射

ps:
	查看随机端口的分配范围:(内核参数)
		sysctl -a|grep net.ipv4|grep 'range'


7、docker的数据卷管理

-v (volume):将宿主机的某个目录挂载的容器

/usr/share/nginx/html			# nginx默认站点目录
-v  /opt/xiaoniao:/usr/share/nginx/html

持久化
数据卷(文件或目录)
	-v 卷名:/data
	-v src(宿主机的目录):dst(容器的目录)
	当src不是一个路径,只是一个名词,则docker会给该容器创建一个卷,可以用 docker volume ls 查看卷
	

    docker volume ls	# 列出所有卷
    docker volume inspect 卷名		# 查看该卷的详细信息,里面有该卷的挂载点

小练习:

​ 基于nginx启动一个容器,监听80和81,访问80,出现nginx默认欢迎首页,访问81,出现我们自定义的html文件。

​ 提示: -p 80:80 -p 81:81 -v xxx:xxx -v xxx:xxxx
​ 基于nginx多端口的多站点:

方法一:需要进入容器
    1、创建并运行一个容器,如下:
        docker run -it -p 80:80 -p 81:81 -v /opt/dailyfresh/:/data nginx:latest /bin/bash
    2、进入容器配置nginx,/etc/nginx/ ,查看nginx收集站点的配置,即include配置。如下:
        include /etc/nginx/conf.d/*.conf;	#表示nginx的所有站点配置都在该路径下,并且都是以.conf结尾
    3、在/etc/nginx/conf.d/目录下默认有个default.conf文件,该文件就是nginx的默认欢迎信息配置文件,期中默认监听端口是80。我们需要新建一个.conf文件,将监听端口改为81,root为站点目录,修改为我们自定义的/data目录。
    4、启动nginx
        直接在命令行输入 nginx
        
方法二:无需进入容器
	1、直接在宿主机的挂载目录下生成nginx站点配置文件
        echo 'server {
            listen       81;
            server_name  localhost;
            location / {
                root   /data;
                index  index.html index.htm;
        	}
        }' > /opt/dailyfresh.conf
	2、创建容器:
		docker run -d -p 80:80 -p81:81 -v /opt/dailyfresh:/data -v /opt/dailyfresh.conf:/etc/nginx/conf.d/dailyfresh.conf nginx:latest /bin/bash

8、手动将容器保存为镜像

做一个基础镜像:

以一个支持ssh登录的镜像为例

1、启动一个基础容器

docker run -it centso:6		

ps:
linux最小的发行版:alpine,后期如果觉得centos镜像太大,可以使用alpine代替,alpine:一个超小的linux系统
安装软件工具:
	centos:yum
	alpine:apk

2、在容器中安装服务

安装openssh-server包,sshd服务在openssh-server中
	yum install openssh-server -y
	
	# 查看一个服务属于哪个包:(eg: sshd服务)
		yum provides sshd

3、启动服务

1、service sshd start
# 该服务启动后会在 /ect/ssh/ 下生成三个密钥对(key,pub),如下:
	[root@2734cc65d85d /]# ll /etc/ssh/
     total 152
    -rw------- 1 root root 125811 Apr  9 14:32 moduli
    -rw------- 1 root root    672 Jun 15 06:38 ssh_host_dsa_key			
    -rw-r--r-- 1 root root    590 Jun 15 06:38 ssh_host_dsa_key.pub
    -rw------- 1 root root    963 Jun 15 06:38 ssh_host_key
    -rw-r--r-- 1 root root    627 Jun 15 06:38 ssh_host_key.pub
    -rw------- 1 root root   1675 Jun 15 06:38 ssh_host_rsa_key
    -rw-r--r-- 1 root root    382 Jun 15 06:38 ssh_host_rsa_key.pub
    -rw------- 1 root root   3879 Apr  9 14:32 sshd_config
	该密钥对就是为了支持ssh登录,如果将这三个密钥对删除,则无法进行ssh登录
	
2、手动创建root密码	
由于该容器使用的是纯净版的centos6,使得系统没有root密码,我们需要手动创建一个root密码
	echo '123'|passwd --stdin root
	# 这是就可以使用ssh连接容器了,eg:ssh root@172.17.0.2

4、把已经安装好服务的容器,提交为镜像

1、退出容器但不关闭当前容器
	Ctrl+P+Q
2、提交为镜像
	docker container commit 2734cc65d85d centos6_ssh:v1
3、查看当前镜像中是否有2中提交的镜像
	docker images

5、测试镜像的功能

1、使用该镜像创建一个容器
	docker run -d -p 1022:22 centos6_ssh:v1 /usr/sbin/sshd -D
	# 这里的端口映射不能是用 22:22 ,因为宿主机的22端口已被占用

2、在本地通过ssh访问容器
	ssh root@10.0.0.51 1022

做一个多服务镜像

手动制作一个支持ssh+nginx的镜像

1、启动一个基础容器

docker run -it -p 80:80 -p 1024:22 centos6_ssh:v1 /bin/bash
# 由于使用的是之前提交的新镜像来创建容器,这样就不用再安装ssh服务了

ps:每次启动一个docker容器,系统会覆盖三个文件,都会将宿主机的三个文件挂载到该容器上
	/dev/sda3 on /etc/resolv.conf type xfs (rw,relatime,attr2,inode64,noquota)	#dns,使容器能上网
    /dev/sda3 on /etc/hostname type xfs (rw,relatime,attr2,inode64,noquota)	# 主机名
    /dev/sda3 on /etc/hosts type xfs (rw,relatime,attr2,inode64,noquota) # 将主机名解析为容器IP地址


2、安装服务

yum install nginx -y	

3、将这2个服务的启动写成一个脚本

问:为什么要有这一步?				
答:由于我们制作的是多服务的镜像,那么当我们使用制作好的镜像进行创建容器时,我们需要将这2个服务都给启动,		但是创建容器命令的最后一个参数,只能指定一条命令,如:
	docker run -d -p 1022:22 centos6_ssh:v1 /usr/sbin/sshd -D
	这样的话我们就只能启动其中一个服务,另一个服务则无法访问。那么我们只能通过一条命令将2个服务都给启动,所	以,最好的方法就是在容器提交成镜像前,在容器中写一个脚本

## 如果依赖的镜像没有设置root密码,则我们还需要手动创建root密码:
	echo '123'|password --stdin root

  • 编写启动多服务的脚本

    该脚本中需要启动的服务,最后一个服务需要被夯住,前面的服务不能被夯住,否则从被夯住服务起,后面的服务都将无法启动。

    或者使用万能方法:所有服务都正常启动,在最后一行加上:tail -f [日志路径] # 日志路径可选

    vi /init.sh

    #!/bin/bash
    
    service sshd restart
    nginx -g 'daemon off;'
    

4、提交为镜像

1、退出容器但不关闭当前容器
	Ctrl+P+Q
2、提交为镜像 (不管容器时在运行中,还是已经挂了,只要容器没有被删除就可以提交为镜像)
	docker container commit cb0761b79a73 centos6_ssh_nginx:v2
3、查看当前镜像中是否有2中提交的镜像
	docker images

5、测试镜像功能

1、使用该镜像创建一个容器
	docker run -d -p 1025:22 -p 81:80 centos6_ssh_nginx:v2 /bin/bash /init.sh
	
	# 为什么使用/bin/bash 启动脚本,因为我们在创建完脚本后没有给脚本执行权限,所以使用/bin/bash 启动脚本

自定义容器镜像的密码

  • 修改启动服务的脚本

    vi /init.sh # 该脚本表示,如果不设置密码,则使用默认密码 123456

    #!/bin/bash
    if [ -z $SSH_PWD ];then
    	SSH_PWD=123456
    fi
    echo "$SSH_PWD"|passwd --stdin root
    service sshd restart
    nginx -g 'daemon off;'
    

  • 创建容器时,加上环境变量参数

    docker run -d -p 1025:22 -p 81:80 -e "SSH_PWD=1q2w3e4r"centos6_ssh_nginx:v2 /bin/bash /init.sh
    
    -e 是 --env的简写,二者都表示environment,环境变脸
    ## 环境变量就是执行:env ,后里面所有的参数,如下:
    	[root@docker01 ~]# env | grep SSH
        SSH_CLIENT=10.0.0.1 2831 22
        SSH_TTY=/dev/pts/0
        SSH_CONNECTION=10.0.0.1 2831 10.0.0.51 22
    
    	这里只显示了过滤后的环境变量,我们可以通过export 和 unset 来添加或删除环境变量
    
    申明环境变量:
    	export SSH_PWD=123456 
    	查看环境变量:
    		[root@docker01 ~]# env | grep SSH
    		SSH_CLIENT=10.0.0.1 2831 22
    		SSH_TTY=/dev/pts/0
    		SSH_PWD=123456			# 新增的环境变量
    		SSH_CONNECTION=10.0.0.1 2831 10.0.0.51 22
    		
    取消环境变量:
    	unset SSH_PWD
    	查看环境变量:		
    		[root@docker01 ~]# env | grep SSH
             SSH_CLIENT=10.0.0.1 2831 22
             SSH_TTY=/dev/pts/0
             SSH_CONNECTION=10.0.0.1 2831 10.0.0.51 22
    		### 新增的SSH_PWD已经被删除了
    	
    

9、dockerfile自动构建docker镜像

  • 我们可以通过创建dockerfile文件来自动创建docker镜像
  • dockerfile 支持自定义容器的初始命令

dockerfile主要组成部分:

基础镜像信息    	FROM  centos:6.9
制作镜像操作指令   	RUN yum install openssh-server -y
容器启动时执行指令 	CMD ["/bin/bash"]

dockerfile常用指令:

FROM 	这个镜像的妈妈是谁?(指定基础镜像)
MAINTAINER 	告诉别人,谁负责养它?(指定维护者信息,可以没有)	# 一般不用,不重要无需关注	 
LABLE      描述,标签		# 一般不用,不重要无需关注	 

RUN 	你想让它干啥(在命令前面加上RUN即可)
ADD 	将宿主机上的某个文件copy到dockerfile(会自动解压tar),制作docker基础的系统镜像
WORKDIR 	设置当前工作目录,进入容器的当前目录(默认目录是根目录)
	eg:
		WORKDIR /opt		# 这样,进入容器后的当前路径就是/opt/
VOLUME 	给它一个存放行李的地方(设置卷,挂载主机目录)	# 一般不用,不重要无需关注
EXPOSE 	它要打开的门是啥(指定对外的端口)(-P 随机端口)
	当我们使用自己构建的镜像运行容器时,-P 就无法指定随机端口,这时我们可以在dockerfile中加入EXPOSE来为我	们的容器来指定随机端口,以下是dockerfile中配置EXPOSE的使用示例:
	EXPOSE 22 80	# 表示给容器的22和80端口随机分配映射端口
CMD 	指定容器的初始命令(指定容器启动后的要干的事情)(容易被替换)

dockerfile 的其他指令:

COPY 复制文件(不会解压)rootfs.tar.gz
ENV  环境变量
	示例:
		ENV SSH_PWD 123456	# 创建环境变量SSH_PWD,并给其赋值 123456
		当我们运行容器没有指定密码时,默认密码就是环境变量中的密码
		当我们使用 -e 指定了密码,则会将环境变量SSH_PWD的值替换为
ENTRYPOINT  容器启动后执行的命令(无法被替换,启容器的时候指定的命令,会被当成参数)
	当我们运行容器(docker run)时,指定了初始命令,则dockerfile中CMD 指定的初始命令会被覆盖
		但,如果我们在dockerfile中用ENTRYPOINT将CMD替换掉,则在运行容器时指定的初始命令无效,依旧使用		dockerfile中的初始命令
	
	小结:
		ENTRYPOINT:当我们项目上线后,防止用户更改初始命令导致容器无法运行
		CMD :利于我们调试
	建议:
		开发调试阶段使用CMD,上线使用ENTRYPOINT
        
dockerfile健康检查:
	https://www.qstack.com.cn/

通过dockerfile构建一个最简单的docker镜像

1、创建dockerfile文件
​ 先创建一个文件夹,该文件夹名建议写成我们将要构建的镜像名,然后在改文件夹下创建一个dockerfile文件,这里文件名必须是dockerfile

2、编写dockerfile

FROM centos:6
RUN echo '192.168.0.102 mirrors.aliyum.com' >>/etc/hosts
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo
RUN yum install openssh-server -y
RUN service sshd restart
RUN echo '123' |passwd --stdin root
CMD ["/usr/sbin/sshd","-D"]

3、构建镜像

docker build -t centos6_ssh:v2 ./
参数说明:
	-t	指定镜像的名称合版本
	./	dockerfile的路径(这里可以是相对路劲也可以是绝对路径,这里使用了相对路径)

4、使用 docker images 查看新构建的镜像

5、测试

1、使用新创将的镜像启动一个容器:
	docker run -d -p 1024:22 centos6_ssh:v2
	# 由于我们在dockerfile中写了 CMD ,即指定了容器的初始命令,所以这里不用再次指定
	
2、查看镜像的初始命令
	docker ps -a -l
	
3、ssh登录容器进行验证
	ssh root@10.0.0.51 -p 1024

自动构建镜像的步骤:

1、手动构建一个镜像		# 直接编写dockerfiel很难考虑到每个步骤,以及所依赖的模块
2、编写dockerfile		# 参考手动构建镜像的历史命令
3、构建镜像
4、测试

排错:
	容器死了:docker logs 容器ID
	容器存活:docker run -it image_name CMD

练习:

​ 写一个dockerfile,制作一个kodexplorer网盘docker镜像。nginx + php-fpm (httpd + php)

1、手动构建:(基于apache)

1、创建一个容器
	docker run -it -p 80:80 centos:6.9 /bin/bash
	
2、换Base源(目的是为了安装服务时下载速度快),这一也步可以省略不做
	curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo
	
3、安装php服务
	yum install php -y
	
4、下载kodexplorer并解压	
	cd /var/www/html	(php默认的站点目录)
	wget http://static.kodcloud.com/update/download/kodexplorer4.40.zip
	yum install unzip -y	(解压发现没有unzip,于是安装unzip)
	unzip kodexplorer4.40.zip
	chown -R apache:apache .
	
5、测试:
	在浏览器测试,输入:10.0.0.51/index.php
	发现错误,缺少这2个包: php-gd、php-mbstring 
	安装 yum install php-gd php-mbstring -y
	重新测试 ==> 正常

2、编写dockerfile

将手动构建的命令整合,如下:

dockerfile

FROM centos:6.9
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo && \
yum install php unzip php-gd php-mbstring -y	# 将所有包放在一起安装
WORKDIR /var/www/html/	# 手动构建使用cd切换到站点目录,这里我们使用dockerfile命令指定工作目录
ADD kodexplorer4.40.zip .	# ADD将宿主机上的文件添加到docker
RUN unzip kodexplorer4.40.zip
RUN chown -R apache:apache .
ADD init.sh /init.sh
EXPOSE 80	# 更加规范
ADD test.sh /test.sh	# 健康检查脚本
ENTRYPOINT ["/bin/bash","/init.sh"]		# 将CMD换成ENTRYPOINT

启动脚本

init.sh

#!/bin/bash

service httpd restart
tail -F /var/log/httpd/access_log

3、构建镜像

docker build -t kod:v1 .

4、测试

1、使用新构建的镜像创建一哥容器
	docker run -d -p 81:80 kod:v1
2、浏览器验证:10.0.0.51:81/index.php

10、镜像分层

posted @ 2019-07-02 19:15  python余生之路  阅读(294)  评论(0编辑  收藏  举报
ヾ(≧O≦)〃嗷~