镜像是Docker的三大核心概念之一。
Docker运行容器前需要本地存在对应的镜像,如果镜像不存在本地,Docker会尝试先从默认镜像仓库下载,用户也可以通过配置,使用自定义的镜像仓库。
1、获取镜像
镜像是Docker运行容器的前提。
通常情况下我们可以通过使用docker pull命令从网上下载镜像。该命令的格式为docker pull NAME[:TAG]。对于Docker镜像来说,如果不指定TAG,则会默认选择latest标签,即下载仓库中最新版本的镜像。
从Docker Hub的Ubuntu仓库下载一个最新的Ubuntu操作系统的镜像:
$sudo docker pull ubuntu
ubuntu:latest:The image you are pulling has been verified
d497ad3926c8:Downloading [======> ] 25.14MB/201.06 MB 51m14s
ccb62158e970:Download complete
e791be0477f2:Download complete
3680052c0f5c:Download complete
22093c35d77b:Download complete
5506de2b643b:Download complete
该命令实际上下载的就是ubuntu:latest镜像,目前最新的14.04版本的镜像。
另外我们也可以通过指定标签来下载特定版本的某一个镜像,例如14.04标签的镜像。
$sudo docker pull ubuntu:14.04
以上两条命令实际上都相当于$sudo docker pull registry.hub.docker.com/ubuntu:latest命令,
即从默认的注册服务器registry.hub.docker.com中的ubuntu仓库来下载标记为latest的镜像。
下载镜像到本地后,即可随时使用该镜像了,例如利用该镜像创建一个容器,在其中运行bash应用。
$sudo docker run -t -i ubuntu /bin/bash
root@fe7fc4bd8fc9:/#
2、查看镜像信息
使用docker images命令可以列出本地主机上已有的镜像。
例如,下面的命令列出了本地从官方下载的ubuntu镜像:
在列出的信息中,可以看到几个字段信息:
来自于哪个仓库,比如ubuntu仓库
镜像的标签信息,比如latest
镜像的ID号(唯一)
创建时间
镜像大小
其中镜像的ID信息十分重要,它唯一标识了镜像。
为了方便在后续工作中使用这个镜像,还可以使用docker tag命令为本地镜像添加新的标签。例如添加一个新的ubuntu:latest镜像标签如下:
$sudo docker tag dl.dockerpool.com:5000/ubuntu:latest ubuntu:latest
另外,不同标签额镜像的ID是完全一致的,说明它们实际上指向了同一个镜像文件,只是别名不同而已。标签在这里起到了引用或快捷方式的作用。
使用docker inspect命令可以获取该镜像的详细信息。
inspect命令返回的是一个JSON格式的消息,如果我们只要其中一项内容时,可以使用-f参数来指定,例如,获取镜像的Architecture信息:
$sudo docker inspect -f {{".Architecture"}} 550
amd64
在指定镜像ID的时候,通常使用该ID的前若干个字符组成的可区分字符串来替代完整的ID。
3、搜寻镜像
使用docker search命令可以搜索远程仓库中共享的镜像,默认搜索Docker Hub官方仓库中的镜像。用法为docker search TERM,支持的参数包括:
--automated=flase仅显示自动创建的镜像
--no-trunc=flase 输出信息不截断显示。
-s,--stars=0 指定仅显示评价为指定星级以上的镜像。
例如,搜索带mysql关键字的镜像如下所示:
$sudo docker search mysql
可以看到返回了很多包含关键字的镜像,其中包括镜像名字,描述,星级(表示该镜像的受欢迎的程度)、是否官方创建,是否自动创建等。
默认的输出结果将按照星级评价进行排序。
官方的镜像说明是官方组创建和维护的,automated资源则允许用户验证镜像的来源和内容。
4、删除镜像
(1)使用镜像的标签删除镜像
使用docker rmi命令可以删除镜像,命令格式为docker rmi IMAGE [IMAGE...],其中IMAGE可以为标签或ID。
例如,要删除掉dl.dockerpool.com:5000/ubuntu:latest镜像,可以使用如下命令:
$sudo docker rmi dl.dockerpool.com:5000/ubuntu
Untagged:dl.dockerpool.com:5000/ubuntu:latest
这里可能会有人担心本地的ubuntu:latest镜像是否会受到此命令的影响。无需担心,当同一个镜像拥有多个标签的时候,docker rmi命令只是删除了该镜像多个标签中的指定标签而已,并不影响镜像文件。
因此上述操作相当于只是删除了镜像5506de2b643b的一个标签而已。
为保险起见,再次查看本地的镜像,发现ubuntu:latest镜像仍然存在:
$sudo docker images
但当镜像只剩下一个标签的时候就要小心了,此时再使用docker rmi命令会彻底删除该镜像。
(2)使用镜像ID删除镜像
当使用docker rmi命令后面跟上镜像的ID时,会尝试删除所有指向该镜像的标签,然后删除该镜像文件本身。
注意,当有该镜像创建的容器存在时,镜像文件默认是无法被删除的,例如:
先利用ubuntu镜像创建一个简单的容器,输出一句话“hello! I am here!”:
$sudo docker run ubuntu echo 'hello! I am here!'
hello! I am here!
使用docker ps -a命令可以看到本机上存在的所有容器
试图删除该镜像,Docker会提示有容器正在运行,无法删除:
$sudo docker rmi ubuntu
如果要强行删除镜像,可以使用-f参数:
$sudo docker rmi -f ubuntu
不过不推荐使用-f参数来强制删除一个存在容器依赖的镜像,因为这样往往会造成一些遗留的问题。
再次使用docker images查看本地的镜像列表,会发现一个标签为<none>的临时镜像,原来被强制删除的镜像换了新的ID继续存在系统中。
因此,正确的做法是,先删除依赖该镜像的所有容器,再来删除镜像。
(1)搜索可用的centos的Docker镜像
docker search <image>:在docker index中搜索image
docker search centos
这样就可以搜索出在Docker Hub上所有带centos的公共的可用镜像
(2)下载centos镜像(拉取镜像)
docker pull centos:latest
查看镜像
docker images:列出images
docker images -a:列出所有的images(包含历史)
docker images --tree :显示镜像的所有层(layer)
docker rmi <image ID>:删除一个或多个image
(3)启动一个容器
docker run -it centos:latest /bin/bash(基于centos镜像启动了一个容器)
Docker允许启动一个伪tty终端,使用交互运行的方式启动一个容器,所用到的参数为:-t -i
centos为基础镜像,首先Docker会检查本地是否有centos镜像,如果没有就会连接官方维护的Docker Hub Regustry查看,一旦有就会下载该镜像并将其保存在本地宿主机中。
容器命名(名称必须唯一)
用上述方法启动容器,Docker会为我们创建的每一个容器自动生成一个随机的名字,如果想自己命名,可以用--name标志来实现。
sudo docker run --name Luffy -it centos /bin/bash
查看容器
docker ps :列出当前所有正在运行的Container
docker ps -l:列出最近一次启动的container
docker ps -a :列出所有的container(包含历史,即运行过的container)
docker ps -q :列出最近一次运行的container ID
退出
exit
输入exit就可以返回到centos宿主机的命令行提示符了,一旦退出容器,/bin/bash命令也就结束了,容器也随之停止了运行。
再次启动容器
docker start/stop/restart <container> :开启/停止/重启container
docker start [container_id]:再次运行某个container(包括历史container)
docker run -i -t <image> /bin/bash :使用image创建container并进入交互模式, login shell是/bin/bash
docker run -i -t -p <host_port:contain_port> :映射 HOST端口到容器,方便外部访问容器内服务,host_port可以省略,省略表示把 container_port映射到一个动态端口。
注:使用start是启动已经创建过得container,使用run则通过image开启一个新的container。
进入容器
docker exec -it <name/ID> bin/bash
删除容器
docker rm <container...> :删除一个或多个container
docker rm -f <>:删除一个正在运行的容器
docker rm `docker ps -a -q` :删除所有的container
docker ps -a -q | xargs docker rm:同上,删除所有的container
删除镜像
docker rmi <镜像名或ID>
进入容器
docker attach ****(容器ID或名)
连接一个正在运行的container实例(即实例必须为start状态,可以多个窗口同时attach 一个container实例)容器的主机名就是该容器的ID
将容器封装为一个镜像
docker commit 6c4b67800f97(为容器名/ID) node:node1(为新的镜像名)
基于新镜像运行容器
docker run -it -d -p 88:80 --name test1 node:node1 /bin/bash
-p为端口映射
1、登陆docker hut官方网站:https://hub.docker.com/
2、search centos
3、docker pull centos:7.2.1511
4、创建Dockerfile文件:
[root@vmhost centos7.2]# cat Dockerfile
FROM centos:7.2.1511
MAINTAINER wanghongwei(wanghongwei@4paradigm.com)
RUN yum install -y expect \
&& yum install -y openssh-clients openssh-server sudo rsync vim libaio strace wget telnet lsof lvm2 psmisc net-tools \
&& /usr/bin/ssh-keygen -A \
&& yum clean all
RUN useradd work
RUN echo 123456 | passwd --stdin root
RUN echo work123 | passwd --stdin work
ADD jdk-8u121-linux-x64.tar.gz /home/work
#ENTRYPOINT ["/root/docker/images/centos7.2"]
5、创建docker镜像:Dockerfile文件在当前路径时用. 标示就可以,如果不在使用绝对路径
docker build -t 4paradigm/centos:7.2 .
6、启动容器脚本:
[root@vmhost prophet2.0]# cat prophet-3.sh
#!/bin/bash -xv
HOST_NAME=prophet-3
HOST_IP=172.27.4.5
GATEWAY=172.27.0.1
ISO_PATH=/root/iso
VOLUME_PATH=/home/whwstar/volume/prophet3
image=4paradigm/centos:7.2
if [ `docker ps -a | grep $HOST_NAME | wc -l` -eq 0 ];then
mkdir -p $VOLUME_PATH
docker run -itd -h $HOST_NAME --name=$HOST_NAME --net=none -v $ISO_PATH:$ISO_PATH -v $VOLUME_PATH:/home/work $image /bin/bash
pipework br0 $HOST_NAME $HOST_IP/20@$GATEWAY
docker exec -d $HOST_NAME /usr/sbin/sshd -D
elif [ `docker ps -a | grep prophet-01 | wc -l` -eq 1 ];then
docker start $HOST_NAME
pipework br0 $HOST_NAME $HOST_IP/20@$GATEWAY
docker exec -d $HOST_NAME /usr/sbin/sshd -D
else
echo "docker start exception"
fi
Docker-利用dockerfile来搭建tomcat服务的方法
常用参数:
FROM命令。用法,FROM <image>:<tag>。FROM命令告诉docker我们构建的镜像是以哪个(发行版)镜像为基础的
RUN命令。用法RUN <command>。RUN 后面接要执行的命令,比如,我们想在镜像中安装vim,只需在Dockfile中写入RUN yum install -y vim
ENV命令。用法,ENV <key> <value>。ENV命令主要用于设置容器运行时的环境变量
ADD命令。用法,ADD <src> <dest>。ADD主要用于将宿主机中的文件添加到镜像中
首先建一个目录构建我们的环境。
mkdir test/web
上传tomcat和jdk到该目录下。
[root@wls12c web]$ ls
apache-tomcat-7.0.70.tar.gz jdk-7u80-linux-x64.tar.gz
编辑Dockerfile
vim Dockerfile
#pull down centos image
FROM centos
MAINTAINER test@test.com
#copy jdk and tomcat into image
ADD ./apache-tomcat-7.0.70.tar.gz /root
ADD ./jdk-7u80-linux-x64.tar.gz /root
#set environment variable
ENV JAVA_HOME /root/jdk1.7.0_80
ENV PATH $JAVA_HOME/bin:$PATH
#define entry point which will be run first when the container starts up
ENTRYPOINT /root/apache-tomcat-7.0.70/bin/startup.sh && tail -F /root/apache-tomcat-7.0.70/logs/catalina.out
构建镜像
[root@wls12c web]$ docker build -t keven/centos:tomcat-centos --rm=true .
Sending build context to Docker daemon 470.4 MB
Sending build context to Docker daemon
Step 0 : FROM centos
---> d83a55af4e75
Step 1 : MAINTAINER test@test.com
---> Running in 955747d64da5
---> 1619dc8f6d58
................
70/logs/catalina.out
---> Running in fe48acf12d70
---> 52076383f11b
Removing intermediate container fe48acf12d70
Successfully built 52076383f11b
-t 选择指定生成镜像的用户名,仓库名和tag
--rm=true指定在生成镜像过程中删除中间产生的临时容器。
查看新产生的镜像
[root@wls12c web]$ docker images keven/centos
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
keven/centos tomcat-centos 52076383f11b 19 minutes ago 516.6 MB
运行镜像
[root@wls12c web]$ docker run -d -p 8090:8080 5207
8260fa22aa32126f613a6b64f121e78545ceae01da58c61396968bfafeda3706
-p指定主机80端口与容器8080端口进行绑定
-d 指定容器运行后与当前tty分离,后台运行
5207是镜像的ID前4位。
通过 http://宿主机IP:8090,即可看见我们熟悉的tomcat首页了。
另外还有一种自动映射主机端口的启动方法
[root@wls12c web]$ docker run -d -p 8080 --name myweb 520
de39869a8c560e5e0cf48fc6022c05ed9f9a145bdafb897767fa468dc24ebfff
[root@wls12c web]$ docker port de3
8080/tcp -> 0.0.0.0:32768
[root@wls12c web]$
这样就要通过http://宿主机IP:32768访问了。
Docker使用Dockerfile创建支持ssh服务自启动的容器镜像
首先创建一个Dockerfile文件,文件内容如下
# 选择一个已有的os镜像作为基础
FROM centos:centos6
# 镜像的作者
MAINTAINER Fanbin Kong "kongxx@hotmail.com"
# 安装openssh-server和sudo软件包,并且将sshd的UsePAM参数设置成no
RUN yum install -y openssh-server sudo
RUN sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config
# 添加测试用户admin,密码admin,并且将此用户添加到sudoers里
RUN useradd admin
RUN echo "admin:admin" | chpasswd
RUN echo "admin ALL=(ALL) ALL" >> /etc/sudoers
# 下面这两句比较特殊,在centos6上必须要有,否则创建出来的容器sshd不能登录
RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
# 启动sshd服务并且暴露22端口
RUN mkdir /var/run/sshd
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]
Dockerfile文件有自己的语法和命令,具体可以参考Docker的官方文档。
2. 有了Dockerfile文件以后,就可以根据Dockerfile来创建image文件了,在Dockerfile所在的目录
下,运行下面的命令
sudo docker build -t centos6-ssh .
命令成功后,就会创建一个名字为centos6-ssh的image,可以使用“sudo docker images”来查看。
3. 此时就可以根据上面创建出来的image文件来创建自己的容器了,下面的命令会创建一个名字为“mytest”的容器。
sudo docker run -d -P --name=mytest centos6-ssh
4. 有了容器,就可以测试我们的ssh服务了。
4.1 运行“sudo docker inspect mytest”,查看当前启动容器IP地址,然后运行下面的命令来测试
ssh admin@<容器IP>
4.2 另外,也可以通过docker的端口映射来访问, 使用“sudo docker port mytest 22”查看当前容器的22端口对应的宿主机器的端口,然后通过下面的命令来访问
ssh admin@<宿主机器IP> -p <宿主机器端口>
Dockerfile
FROM 基础镜像
MAINTAINER 维护这信息
RUN 运行什么命令,在命令前面加上RUN
ADD 往里面加点文件,copy文件,会自动解压
WORKDIR 当前的工作目录
VOLUME 目录挂载
EXPOSE 开放的端口
RUN 进程要一直运行
实战:构建nginx
wget http://xiazai.jb51.net/201611/yuanma/nginx-1.9.3(jb51.net).rar
wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.38.tar.gz
#This is My first Dockerfile#version 1.0
#Author: hh
#Base image 基础镜像
FROM centos
#MAINTAINER 维护者信息
MAINTAINER hh Wang
#ADD
ADD pcre-8.38.tar.gz /usr/local/srcADD nginx-1.9.3.tar.gz /usr/local/src
#RUN
RUN yum -y install wget gcc gcc-c++ make openssl openssl-devel
RUN useradd -s /sbin/nologin -M www
#WORKDIR
WORKDIR /usr/local/src/nginx-1.9.3
RUN ./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_ssl_module --with-http_stub_status_module \
--with-pcre=/usr/local/src/pcre-8.38 && make && make install
RUN echo "daemon off;">>/usr/local/nginx/conf/nginx.conf
#ENV定义环境变量
ENV PATH /usr/local/nginx/sbin:$PATH
#EXPOSE 映射端口
EXPOSE 80 CMD ["nginx"]
docker build -t whh/nginx-file:v1 .
docker run -d -it -p 93:80 --name nginx whh/nginx-file:v1
下面再看下dockerfile 的使用
通过docker build命令可以建立镜像。
通常需要文本文件Dockerfile,例子如下:
from hub.c.163.com/library/nginx ----基于的镜像
run echo "hello world" >/etc/nginx/index.xml ----追加到index.html 末尾
expose 80 ---暴露80端口
cmd 'nginx' ----启动nginx服务
保存后,运行 docker build -t mynginx:1.0 .
然后运行 docker images ,查看到所构建的镜像。
通过 docker run -d -p 8082:80 --name nginx_web mynginx:1.0
最后通过 http://ip:8081 访问到nginx的index.html的内容
容器内部像linux一样操作,然后提交容器成镜像
Dokcerfile提交镜像
一
创建一个容器
[root@web01 ~]#docker run --name mynginx01 -it centos
[root@web01 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
84bcc294325b nginx "nginx -g 'daemon off" 3 seconds ago Up 3 seconds
2.此时已经进入容器
yum -y install wget
wget -O /etc/yum.repos.d/epel.repo
yum -y install nginx
vim /etc/nginx /nginx.conf
...
daemon off;
退出
3,制作镜像
[root@web01 ~]# docker commit -m "mynginx01" be750c11ab1e mynginx/mynginx:v1
sha256:5143358c3833b4ee5a40b847d86dee072dc7c0bade9358e7d83323d6349784b0
[root@web01 ~]#
mynginx/mynginx:v1 仓库/镜像名称:版本标签
[root@web01 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mynginx/mynginx v1 5143358c3833 41 seconds ago 340.1 MB
二.Dokcerfile制作镜像
[root@web01 dockerfile]# cat Dockerfile
FROM centos
MAINTAINER liuhaixiao
RUN yum -y install wget
RUN rpm -ivh http://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm
RUN wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
RUN yum clean all && yum install nginx -y
RUN echo "daemon off;" >>/etc/nginx/nginx.conf
ADD index.html /usr/share/nginx/html/index.html
EXPOSE 80
CMD ["nginx"]
[root@web01 dockerfile]# cat index.html
hello liuhx
[root@web01 dockerfile]# pwd
/root/dockerfile
[root@web01 dockerfile]#
构建镜像
cd /root/dockerfile
Docker build -t mynginx/mynginx03:03 ./
[root@web01 dockerfile]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mynginx/mynginx03 v3 8c81f51923e5 2 minutes ago 374.6 MB
启动容器:
[root@web01 dockerfile]# docker run -d --name nginx007 -p 86:80 mynginx/mynginx03:v3
6f2501177ac00e064b22c6c3045b973dc41935e82180753a21a14f3224f5f323
写dockerfile
[root@web01 sshddockerfile]# cat Dockerfile
FROM centos
MAINTAINER liuhaixiao
RUN yum -y install wget
RUN rm -rf /etc/yum.repos.d/*
RUN wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
RUN yum clean all
RUN yum install -y openssh-server sudo
RUN sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config
RUN useradd admin
RUN echo "admin:admin" | chpasswd
RUN echo "admin ALL=(ALL) ALL" >> /etc/sudoers
RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
# 启动sshd服务并且暴露22端口
RUN mkdir /var/run/sshd
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]
[root@web01 sshddockerfile]#
2.创建镜像
docker build -t sshddocker ./
3.查看镜像
[root@web01 sshddockerfile]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
sshddocker latest 73204ab652dd 12 minutes ago 323.2 MB
4.根据此镜像启动一个容器
docker run -d --name mysshdcontainer IP:23:22 sshddocker
5.查看生成的容器
[root@web01 sshddockerfile]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f4620f5dd045 sshddocker "/usr/sbin/sshd -D" 6 minutes ago Up 6 minutes IP:23->22/tcp mysshdcontainer
[root@web01 sshddockerfile]#
6.远程登录测试
[root@web02 ~]# ssh admin@59.110.25.215 -p 23
admin@59.110.25.215's password:
[admin@f4620f5dd045 ~]$
[admin@f4620f5dd045 ~]$ sudo -i
[sudo] password for admin:
[root@f4620f5dd045 ~]# pwd
/root
7.查看容器的IP
yum -y install net-tools
[root@f4620f5dd045 ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.0.2 netmask 255.255.240.0 broadcast 0.0.0.0
inet6 fe80::42:c0ff:fea8:2 prefixlen 64 scopeid 0x20<link>
ether 02:42:c0:a8:00:02 txqueuelen 0 (Ethernet)
RX packets 814 bytes 377183 (368.3 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 565 bytes 64761 (63.2 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 0 (Local Loopback)
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
[root@f4620f5dd045 ~]#
制作支持ssh的docker镜像
宿主机系统版本: centos 6.7
宿主机内核版本:3.10.5-12.1.x86_64
docker 版本: Docker version 1.7.1, build 786b29d/1.7.1
创建过程:
1.启动镜像:
[root@localhost ~]# docker run -it centos /bin/bash
2.安装openssh服务
[root@75a1929a2637 /]# yum -y install openssh-server
3.创建 /var/run/sshd/目录,要不然sshd服务启动会报错
[root@75a1929a2637 /]# mkdir /var/run/sshd/
4.启动sshd服务
[root@75a1929a2637 /]# /usr/sbin/sshd -D &
WARNING: 'UsePAM no' is not supported in Red Hat Enterprise Linux and may cause several problems. (1)
Could not load host key: /etc/ssh/ssh_host_rsa_key (2)
Could not load host key: /etc/ssh/ssh_host_ecdsa_key
Could not load host key: /etc/ssh/ssh_host_ed25519_key
启动是会提示以上信息,(1)表示:修改了sshd_conf文件中的UsePAM yes 改成UsePAM no
[root@75a1929a2637 /]#cat /etc/ssh/sshd_config|grep UsePA
UsePAM no
(2)表示:没有主机的公私秘钥,重新生成密钥
[root@75a1929a2637 /]# rm -rf ssh*key
[root@75a1929a2637 /]# ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
[root@75a1929a2637 /]# ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key
[root@75a1929a2637 /]# ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key
如果没有生成密钥在远程连接的时候也会报错。报主机密钥不匹配错误:Read from socket failed: Connection reset by peer
秘钥文件是根据sshd_conf 配置文件相对应的,可以先查看配置文件在设置相同的密钥
#HostKey /etc/ssh/ssh_host_key
# HostKeys for protocol version 2
HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
5.取消pam登录限制,注释掉#session required pam_loginuid.so,原先没有注释掉
[root@75a1929a2637 /]#cat /etc/pam.d/sshd
#session required pam_loginuid.so
6.验证端口是否开启
[root@75a1929a2637 /]# ps -ef |grep sshd
root 18 1 0 01:43 ? 00:00:00 /usr/sbin/sshd -D
root 30 1 0 01:59 ? 00:00:00 grep --color=auto sshd
7.通过宿主机端口扫描查看sshd端口状态
[root@localhost ~]# nmap 172.17.0.10 -p 22
PORT STATE SERVICE
22/tcp open ssh
8.宿主机生成公钥并且导入到容器中
[root@localhost ~]# ssh-keygen -t rsa
会在/root/.ssh/会生成密钥文件和私钥文件 id_rsa,id_rsa.pub或id_dsa,id_dsa.pub
将 .pub 文件复制到容器的 .ssh 目录,并且将内容导入到~/.ssh/authorized_keys
[root@localhost .ssh]# mkdir /root/.ssh/
[root@localhost .ssh]# cat authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAyFRgchNdCzAUN7FNWdwDxLtFvW5521mMX4r57DCPADtrclyGcnlljxcqFHAYtyyDGmNA8ASrYxiH+0FPe+6BI2U32yNUorLOfsB1VlgMpEx6Xq9g3VFUMo7HLNNgOsj0hBnKlsrWt9VZhQ9rkW8ncof+M0CabP4mNDp7xuKX/AmGvweNapYusDiK3hEoUF9lEKYFyztk85PqNNDSzRZgqulQSYZYCfdz2KO+GJnlDoTfOGB1ShVbNO1Rjo1LpK8jrnSTTubIJMaPGtA/khagbKHhW/+AhFjcGezs2ZJ8pAUqHmeksoBM0smSsiE8F3tZxO39YqOOoxfWWHrxA7/8Nw== root@localhost.localdomain
[root@75a1929a2637 /]# cat /root/.ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAyFRgchNdCzAUN7FNWdwDxLtFvW5521mMX4r57DCPADtrclyGcnlljxcqFHAYtyyDGmNA8ASrYxiH+0FPe+6BI2U32yNUorLOfsB1VlgMpEx6Xq9g3VFUMo7HLNNgOsj0hBnKlsrWt9VZhQ9rkW8ncof+M0CabP4mNDp7xuKX/AmGvweNapYusDiK3hEoUF9lEKYFyztk85PqNNDSzRZgqulQSYZYCfdz2KO+GJnlDoTfOGB1ShVbNO1Rjo1LpK8jrnSTTubIJMaPGtA/khagbKHhW/+AhFjcGezs2ZJ8pAUqHmeksoBM0smSsiE8F3tZxO39YqOOoxfWWHrxA7/8Nw== root@localhost.localdomain
9.编辑ssh服务启动脚本并赋予执行权限
[root@localhost ~]# cat run.sh
#!/bin/bash
/usr/sbin/sshd -D &
[root@localhost ~]# chmod 755 run.sh
10.保存镜像
[root@localhost ~]# docker commit 75a1929a2637 sshd04
11.运行镜像,设置端口映射
[root@localhost ~]#docker run -d -p 11126:22 sshd04 /usr/sbin/sshd -D
[root@localhost ~]# docker ps
d0dc7862e8c9 sshd04 "/usr/sbin/sshd -D" 16 hours ago Up 16 hours 0.0.0.0:11126->22/tcp furious_morse
[root@localhost ~]# ssh 192.168.30.133 -p 11126
[root@d0dc7862e8c9 ~]#
[root@d0dc7862e8c9 ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.9 netmask 255.255.0.0 broadcast 0.0.0.0
远程登录成功
附:dockerfile 文件
#this is docker sshdimages
FROM centos
MAINTAINER chenyongtao
RUN yum clean all
RUN yum -y install net-tools*
RUN yum -y install openssh-server
RUN mkdir /var/run/sshd
RUN sed -i 's/session required pam_loginuid.so/#session required pam_loginuid.so/g' /etc/pam.d/sshd
RUN rm -rf ssh*key
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
RUN ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key
RUN ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key
RUN mkdir /root/.ssh/
COPY ./id_rsa.pub /root/.ssh/id_rsa.pub
COPY ./authorized_keys /root/.ssh/authorized_keys
COPY ./run.sh /root/run.sh
EXPOSE 22
CMD /usr/sbin/sshd -D
以centos为基础,目的使用ssh服务远程连接docker容器
环境:宿主机centos7,直接搜索docker的centos镜像,下载最新版本
1、先安装docker:yum install -y epel-release
yum install -y docker
2、启动docker: systemctl start docker.service
3、使用ps查看docker是否启动
ps aux |grep docker
4、下载centos的docker镜像
docker pull centos下载最新版本
此时的镜像里除了基础的centos系统外,没有其他服务及工具
5、启动centos容器
docker run -it --name=centos-ssh centos /bin/bash
6、进入到容器中,升级并安装ssh组件
yum -y update
yum -y install openssh-server
7、编辑sshd的配置文件/etc/ssh/sshd_config,将其中PAM参数设置为no
UsePAM yes ---》 UsePAM no
UsePrivilegeSeparation sandbox -----》 UsePrivilegeSeparation no
8、在宿主机中生成密钥对,把生成的公钥文件内容复制到容器的/root/.ssh/authorized_keys里
如果没有请创建。
ssh-keygen -t rsa直接回车即可,查看公钥内容,并复制到容器中
cat /root/.ssh/id_rsa.pub
9、设置容器root密码
echo "root:123456"|chpasswd
10、启动sshd服务并退出容器
/usr/sbin/sshd -D
如果报错如下:
Could not load host key: /etc/ssh/ssh_host_rsa_key
Could not load host key: /etc/ssh/ssh_host_ecdsa_key
Could not load host key: /etc/ssh/ssh_host_ed25519_key
执行如下命令
ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N ""
ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N ""
ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N ""
exit
如果sshd服务启动时报错
[root@e813dfb36be9 /]# systemctl status sshd.service
Failed to get D-Bus connection: Operation not permitted
可以用这个命令
/usr/sbin/sshd &
11、生成支持ssh的新centos镜像
首先查看容器docker ps -a
生成镜像
docker commit e813dfb36be9 sshd-centos
此时生成一个名为sshd-centos的镜像
docker images查看
12、运行该镜像并启动sshd服务
docker run -p 10022:22 -d sshd-centos /usr/sbin/sshd -D
说明: 10022是宿主机的和容器的通讯端口,外面窗口(局域网)通过访问地址
ssh root@宿主机IP 10022(IP和端口之间有空格,不是:)就能进入容器
1、制做JAVA运行环境镜像
我的基础镜像是基于官网centos 7.2版本制作,没有可以提前下载好
#docker pull docker.io/centos
[root@R210 ~]# mkdir -p /opt/Dockerfile/JRE1.7
[root@R210 ~]# cd /opt/Dockerfile/JRE1.7
[root@R210 jre1.7]# ls
Dockerfile server-jre-7u80-linux-x64.tar.gz
[root@R210 jre1.7]# cat Dockerfile
FROM centos:latest
MAINTAINER yy
ENV JAVA_VERSION "7u80"
ENV JDK_VERSION "1.7.0_80"
RUN rpm --rebuilddb \
&& yum --setopt=tsflags=nodocs -y install \
net-tools \
&& rm -rf /var/cache/yum/* && yum clean all
#RUN rpm --import http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-7 \
# && yum update && yum install net-tools -y \
RUN mkdir -p /usr/lib/jvm
COPY server-jre-${JAVA_VERSION}-linux-x64.tar.gz /usr/lib/jvm/server-jre-${JAVA_VERSION}-linux-x64.tar.gz
RUN cd /usr/lib/jvm \
&& tar -zxvf server-jre-${JAVA_VERSION}-linux-x64.tar.gz \
&& rm -rf /usr/lib/jvm/server-jre-${JAVA_VERSION}-linux-x64.tar.gz \
&& ln -s /usr/lib/jvm/jdk${JDK_VERSION}/bin/java /bin/ \
&& cd /usr/lib/jvm/jdk${JDK_VERSION} \
&& find . -type f -name '*.html' -delete \
&& find . -type f -name 'COPYRIGHT' -delete \
&& find . -type f -name 'LICENSE' -delete \
&& find . -type f -name 'NOTICE' -delete \
&& find . -type f -name '3RDPARTY' -delete \
&& find . -type f -name '*.txt' -delete \
&& find . -type f -name '*.bat' -delete \
#jre包可以再做精简
2.制作生产环境Tomcat镜像
[root@R210 ~]# mkdir -p /opt/Dockerfile/tomcat7
[root@R210 ~]# cd /opt/Dockerfile/tomcat7
[root@R210 tomcat7]# ls
apache-tomcat-7.0.70.tar.gz Dockerfile
[root@R210 tomcat7]# cat Dockerfile
FROM java7:7u80
MAINTAINER yy
ENV TOMCAT_VERSION 7.0.70
ENV CATALINA_HOME /tomcat
ENV APP_DIR ${CATALINA_HOME}/webapps/
RUN rpm --rebuilddb \
&& yum --setopt=tsflags=nodocs -y install \
apr tomcat-native \
&& rm -rf /var/cache/yum/* && yum clean all
#RUN wget -q https://archive.apache.org/dist/tomcat/tomcat-${TOMCAT_MAJOR_VERSION}/v${TOMCAT_MINOR_VERSION}/bin/apache-tomcat-${TOMCAT_MINOR_VERSION}.tar.gz
#https://archive.apache.org/dist/tomcat/tomcat-7/v7.0.70/bin/apache-tomcat-7.0.70.tar.gz
COPY apache-tomcat-${TOMCAT_VERSION}.tar.gz apache-tomcat-{TOMCAT_VERSION}.tar.gz
RUN tar zxf apache-tomcat-*.tar.gz && \
rm apache-tomcat-*.tar.gz && \
mv apache-tomcat* tomcat && \
rm -rf tomcat/webapps/* && \
sed -i '/protocol="AJP\/1.3"/d' /tomcat/conf/server.xml
EXPOSE 8080
ENTRYPOINT ["/tomcat/bin/catalina.sh","run"]
ONBUILD ADD . ${APP_DIR}
制作镜像
[root@R210 tomcat7]#docker build -t tomcat7:7.0.70 .
从镜像启动一个tomcat容器,把测试程序部署到/www/app1/webapps下从浏览器访问
[root@R210 ]# docker run -d -p 8002:8080 --name mytomcat7 -v
/www/app1/webapps/:/tomcat/webapps tomcat7:7.0.70
3.制作数据库mariadb镜像
[root@XSMM mk_mariadb]# ls
Dockerfile mariadb-func.sh mariadb.repo run.sh
[root@XSMM-WEB mk_mariadb]# cat Dockerfile
FROM centos:latest
MAINTAINER yy
ENV TZ "Asia/Shanghai"
ENV TERM xterm
COPY mariadb.repo /etc/yum.repos.d/
RUN \
yum update -y && \
yum install -y epel-release && \
yum install -y MariaDB-server hostname net-tools pwgen && \
yum clean all && \
rm -rf /var/lib/mysql/* && \
rm -rf /var/cache/yum/*
COPY mariadb-func.sh /
COPY run.sh /
RUN chmod 755 *.sh
VOLUME ["/var/lib/mysql"]
EXPOSE 3306
CMD ["/run.sh"]
[root@XSMM-WEB mk_mariadb]# cat mariadb-func.sh
#!/bin/sh
#########################################################
# 循环检测数据库进程是否正常启动、服务是否可用 #
#########################################################
function wait_for_db() {
set +e
echo "等待数据库启动..."
while true; do
if grep "ready for connections" $ERROR_LOG; then
break;
else
echo "继续等待数据库启动完成..." && sleep 1
fi
done
set -e
}
#########################################################
# 关闭数据库进程
#########################################################
function terminate_db() {
local pid=$(cat $VOLUME_HOME/mysql.pid)
echo "捕获进程信号&关闭数据库进程..."
kill -TERM $pid
while true; do
if tail $ERROR_LOG | grep -s -E "mysqld .+? ended" $ERROR_LOG; then
break;
else sleep 0.5;
fi
done
}
#########################################################
#如果数据目录为空,调用 mysql_install_db 脚本生成默认库
# 全局变量:
# $VOLUME_HOME
# $ERROR_LOG
#########################################################
function install_db() {
if [ ! -d $VOLUME_HOME/mysql ]; then
echo "=> 数据目录 $VOLUME_HOME为空,数据库未初始化..."
echo "=> 正在安装 MariaDB..."
mysql_install_db --user=mysql > /dev/null 2>&1
echo "=> MariaDB 安装完成!"
else
echo "=> 使用已经存在数据目录文件."
fi
#########################################################
# 移除之前容器运行留下的日志文件,保留当前容器生成的日志
#########################################################
if [ -f $ERROR_LOG ]; then
echo "----------------- Previous error log -----------------"
tail -n 20 $ERROR_LOG
echo "----------------- Previous error log ends -----------------" && echo
mv -f $ERROR_LOG "${ERROR_LOG}.old";
fi
touch $ERROR_LOG && chown mysql $ERROR_LOG
}
#########################################################
# 创建用户
# 变量:
# $MARIADB_USER
# $MARIADB_PASS
#########################################################
function create_mysql_user() {
echo "Creating DB admin user..." && echo
local users=$(mysql -s -e "SELECT count(User) FROM mysql.user WHERE User='$MARIADB_USER'")
if [[ $users == 0 ]]; then
echo "=> Creating MariaDB user '$MARIADB_USER' with '$MARIADB_PASS' password."
mysql -uroot -e "CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY '$MARIADB_PASS'"
else
echo "=> User '$MARIADB_USER' exists, updating its password to '$MARIADB_PASS'"
mysql -uroot -e "SET PASSWORD FOR '$MARIADB_USER'@'%' = PASSWORD('$MARIADB_PASS')"
fi;
mysql -uroot -e "GRANT ALL PRIVILEGES ON *.* TO '$MARIADB_USER'@'%' WITH GRANT OPTION"
echo "========================================================================"
echo " 可以使用以下命令连接 MariaDB Server: "
echo " mysql -u$MARIADB_USER -p$MARIADB_PASS -h<host> "
echo " "
echo " 出于安全考虑,应该修改上述密码,root可以在本地无密码登陆建议设置密码 "
echo "========================================================================"
}
#########################################################
# 显示数据库状态
#########################################################
function show_db_status() {
echo "Showing DB status..." && echo
mysql -uroot -e "status"
}
#########################################################
# 清理数据库,删除test库和无密码用户
#########################################################
function secure_and_tidy_db() {
echo "删除test库和无密码用户..."
mysql -uroot -e "DROP DATABASE IF EXISTS test"
mysql -uroot -e "DELETE FROM mysql.user where User = ''"
#########################################################
# 设置root用户只能从本地登陆
#########################################################
mysql -uroot -e "DELETE FROM mysql.user where User = 'root' AND Host NOT IN ('127.0.0.1','::1')"
mysql -uroot -e "DELETE FROM mysql.proxies_priv where User = 'root' AND Host NOT IN ('127.0.0.1','::1')"
echo "设置root用户只能从本地登陆完成!"
}
[root@XSMM-WEB mk_mariadb]# cat run.sh
#!/bin/bash
set -e
set -u
source ./mariadb-func.sh
# 用户指定数据库用户名,不提供默认为mysql,并随机生成密码
MARIADB_USER=${MARIADB_USER:="mysql"}
MARIADB_PASS=${MARIADB_PASS:-$(pwgen -s 12 1)}
# 指定其它必要环境变量
VOLUME_HOME="/var/lib/mysql"
ERROR_LOG="$VOLUME_HOME/$HOSTNAME.err"
MYSQLD_PID_FILE="$VOLUME_HOME/$HOSTNAME.pid"
# Trap INT and TERM signals to do clean DB shutdown
trap terminate_db SIGINT SIGTERM
#调用install_db函数
install_db
# 输出所有信息到终端
tail -F $ERROR_LOG &
#将数据库启动到后台运行并记录PID
/usr/bin/mysqld_safe &
MYSQLD_SAFE_PID=$!
wait_for_db
secure_and_tidy_db
show_db_status
create_mysql_user
#不在终止这个脚本直到数据库进程mysqld_safe正常退出
wait $MYSQLD_SAFE_PID
[root@XSMM-WEB mk_mariadb]# cat mariadb.repo
# MariaDB 10.1 CentOS repository list - created 2016-01-06 02:19 UTC
# http://mariadb.org/mariadb/repositories/
[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.1/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1
#创建镜像
[root@XSMM mk_mariadb]# docker build -t mariadb10 .
#docker run --name mydb -d -p 3306:3306 -v /mydata/mysql/:/var/lib/mysql mariadb10
...
---> Running in 35b0398fbeb8
---> d353c6e1e33b
Removing intermediate container 35b0398fbeb8
Step 12 : CMD /run.sh
---> Running in 7248c5e14559
---> 538b64e6987d
Removing intermediate container 7248c5e14559
Successfully built 538b64e6987d
[root@XSMM]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mariadb10 latest 538b64e6987d 4 minutes ago 1.111 GB
centos7-ssh latest 104c3f5a710c 7 days ago 504.1 MB
centos6 latest ba7961b610e2 7 days ago 194.6 MB
docker.io/tomcat latest 3c90608ca58a 8 days ago 357.4 MB
docker.io/centos/redis latest a4b79297fc55 2 weeks ago 405.6 MB
docker.io/centos latest 970633036444 5 weeks ago 196.7 MB
#从镜像生成一个mariadb容器
[root@XSMM]# docker run --name mydb -d -p 3306:3306 -v /mydata/mysql/:/var/lib/mysql mariadb10
7eb4b284406bfb497ee0addf8cda153ab91013f3f9fc3357d856c68ea8a6e658
#查看容器日志
[root@XSMM]# docker logs mydb
=> 使用已经存在数据目录文件.
等待数据库启动...
继续等待数据库启动完成...
160910 01:07:05 mysqld_safe Logging to '/var/lib/mysql/7eb4b284406b.err'.
160910 01:07:05 mysqld_safe Starting mysqld daemon with databases from /var/lib/mysql
...
2016-09-10 1:07:06 139756268353664 [Note] /usr/sbin/mysqld: ready for connections.
Version: '10.1.17-MariaDB' socket: '/var/lib/mysql/mysql.sock' port: 3306 MariaDB Server
2016-09-10 1:07:06 139756268353664 [Note] /usr/sbin/mysqld: ready for connections.
删除test库和无密码用户...
设置root用户只能从本地登陆完成!
Showing DB status...
Creating DB admin user...
=> Creating MariaDB user 'mysql' with 'tMEpSbAy0lIK' password.
========================================================================
可以使用以下命令连接 MariaDB Server:
mysql -umysql -ptMEpSbAy0lIK -h<host>
出于安全考虑,应该修改上述密码,root可以在本地无密码登陆建议设置密码
========================================================================
[root@XSMM]# mysql -umysql -ptMEpSbAy0lIK
1
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
#连接数据测试
[root@XSMM]# mysql --protocol=tcp -umysql -ptMEpSbAy0lIK
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 10
Server version: 10.1.17-MariaDB MariaDB Server
Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
+--------------------+
3 rows in set (0.01 sec)
MariaDB [(none)]>