Docker 容器
一、 什么是容器?(container)
Linux容器是与系统其他部分隔离开的一系列进程,从另一个系统镜像(文件系统)运行,并由该镜像提供支持进程所需的全部文件(环境文件)。
容器镜像包含了应用的所有依赖项,因而在从开发到测试再到生产的整个过程中,它都具有可移植性和一致性。
来源:https://www.redhat.com/zh/topics/containers/whats-a-linux-container
虚拟化使得许多操作系统可同时在单个系统上运行。
容器只能共享操作系统内核,将应用进程与系统其他部分,隔离开。
二、容器和虚拟化的区别
linux容器技术,容器虚拟化和kvm虚拟化的区别
kvm虚拟化: 需要硬件的支持,需要模拟硬件,可以运行不同的操作系统,启动时间分钟级(开机启动流程)
容器虚拟化:不需要硬件的支持。不需要模拟硬件,共用宿主机的内核,启动时间秒级(没有开机启动流程)
总结:
(1)与宿主机使用同一个内核,性能损耗小;
(2)不需要指令级模拟;
(3)容器可以在CPU核心的本地运行指令,不需要任何专门的解释机制;
(4)避免了准虚拟化和系统调用替换中的复杂性;
(5)轻量级隔离,在隔离的同时还提供共享机制,以实现容器与宿主机的资源共享。
三、容器技术的发展过程:
3.1):chroot技术,新建一个子系统
参考资料:https://www.ibm.com/developerworks/cn/linux/l-cn-chroot/
3.2):linux容器(lxc) linux container(namespaces 隔离环境 及cgroups 硬件资源限制)
四、需要使用epel源
4.1 、安装epel源
yum install epel-release -y
4.2、编译epel源配置文件
vi /etc/yum.repos.d/epel.repo
[epel]
name=Extra Packages for Enterprise Linux 7 - $basearch
baseurl=https://mirrors.tuna.tsinghua.edu.cn/epel/7/$basearch
#mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-7&arch=$basearch
failovermethod=priority
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
[epel-debuginfo]
name=Extra Packages for Enterprise Linux 7 - $basearch - Debug
baseurl=https://mirrors.tuna.tsinghua.edu.cn/epel/7/$basearch/debug
#mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-debug-7&arch=$basearch
failovermethod=priority
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
gpgcheck=1
[epel-source]
name=Extra Packages for Enterprise Linux 7 - $basearch - Source
baseurl=https://mirrors.tuna.tsinghua.edu.cn/epel/7/SRPMS
#mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-source-7&arch=$basearch
failovermethod=priority
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
gpgcheck=1
4.3 、安装 lxc
yum install lxc-* -y
yum install libcgroup* -y
yum install bridge-utils.x86_64 -y
4.4 、桥接网卡
[root@controller ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0
TYPE=Ethernet
BOOTPROTO=none
NAME=eth0
DEVICE=eth0
ONBOOT=yes
BRIDGE=br0
[root@controller ~]# cat /etc/sysconfig/network-scripts/ifcfg-br0
TYPE=Bridge
BOOTPROTO=static
NAME=br0
DEVICE=br0
ONBOOT=yes
IPADDR=10.0.0.11
NETMASK=255.255.255.0
GATEWAY=10.0.0.254
DNS1=223.5.5.5
4.5 、修改lxc默认配置
vi /etc/lxc/default.conf
修改第2行为:lxc.network.link = br0
4.6、启动cgroup
systemctl start cgconfig.service
4.7、启动lxc
systemctl start lxc.service
4.8 、创建 lxc容器
方法1:
lxc-create -t download -n centos6 -- --server mirrors.tuna.tsinghua.edu.cn/lxc-images -d centos -r 6 -a amd64
方法2:
lxc-create -t centos -n test
4.9 、为lxc容器设置root密码:
[root@controller ~]# chroot /var/lib/lxc/centos6/rootfs passwd
Changing password for user root.
New password:
BAD PASSWORD: it is too simplistic/systematic
BAD PASSWORD: is too simple
Retype new password:
passwd: all authentication tokens updated successfully.
4.10 、为容器指定ip和网关
vi /var/lib/lxc/centos7/config
lxc.network.name = eth0
lxc.network.ipv4 = 10.0.0.111/24
lxc.network.ipv4.gateway = 10.0.0.254
4.11 、启动容器
lxc-start -n centos7
五 、docker容器
Docker是通过内核虚拟化技术(namespaces及cgroups cpu、内存、磁盘io等)来提供容器的资源隔离与安全保障等。由于Docker通过操作系统层的虚拟化实现隔离,所以Docker容器在运行时,不需要类似虚拟机(VM)额外的操作系统开销,提高资源利用率。
namespace(资源隔离)
cgroup(硬件资源的限制)
docker的主要目标是"Build,Ship and Run any App,Angwhere",构建,运输,处处运行
构建:做一个docker镜像
运输:docker pull
运行:启动一个容器
每一个容器,他都有自己的根文件系统rootfs.
kvm解决了硬件和操作系统之间的依赖
docker 解决了软件和操作系统运行环境之间的依赖,能够让独立服务或应用程序在不同的环境中,得到相同的运行结果。
docker容器是一种轻量级、可移植、自包含的软件打包技术,使应用程序可以在几乎任何地方以相同的方式运行。
开发人员在自己笔记本上创建并测试好的容器,无需任何修改就能够在生产系统的虚拟机、物理服务器或公有云主机上运行。
5.1、docker的安装
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.ustc.edu.cn/docker-ce#g' /etc/yum.repos.d/docker-ce.repo
yum install docker-ce -y
5.2 、docker的主要组成部分
docker是传统的 CS架构分为 docker client和 docker server,像mysql一样
命令:docker version
[root@controller ~]# docker version
Client:
Version: 17.12.0-ce
API version: 1.35
Go version: go1.9.2
Git commit: c97c6d6
Built: Wed Dec 27 20:10:14 2017
OS/Arch: linux/amd64
Server:
Engine:
Version: 17.12.0-ce
API version: 1.35 (minimum version 1.12)
Go version: go1.9.2
Git commit: c97c6d6
Built: Wed Dec 27 20:12:46 2017
OS/Arch: linux/amd64
Experimental: false
docker info(如果要做监控)
###设置docker远程执行
systemd详解:http://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-part-two.html
####在linux-node1:
vim /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://10.0.0.11:2375
systemctl daemon-reload
systemctl restart docker.service
ps -ef检查
####在linux-node2:
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.ustc.edu.cn/docker-ce#g' /etc/yum.repos.d/docker-ce.repo
yum install docker-ce -y
docker -H 10.0.0.11 info
docker 主要组件有:镜像、容器、仓库
启动容器必须需要一个镜像,仓库用来存储docker镜像
六 、启动第一个容器
安装Nginx步骤:
官网下载Nginx源码包
创建Nginx用户
编译安装
修改配置文件,
启动
docker run -d -p 80:80 nginx
## 配置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镜像的名字(如果找不到Nginx的镜像,就会从docker hub上下载)
七 、docker的镜像管理
搜索镜像
docker search
选镜像的建议:
1,优先考虑官方
2,starts数量多
获取镜像
docker pull(push)
镜像加速器:阿里云加速器,daocloud加速器,中科大加速器,Docker 中国官方镜像加速:https://registry.docker-cn.com
docker pull centos:6.8(没有指定版本,默认会下载最新版)
##配置docker镜像加速
vi /etc/docker/daemon.json
{
"registry-mirrors": ["https://registry.docker-cn.com"]
}
第三方docker镜像仓库,使用方法:
docker pull index.tenxcloud.com/tenxcloud/httpd:latest
查看镜像
docker images
导出镜像
docker save 例子:docker image save centos > docker-centos7.4.tar.gz
删除镜像
docker rmi 例子:docker image rm centos:latest
导入镜像
docker load 例子:docker image load -i docker-centos7.4.tar.gz
八 、docker的容器管理:
docker run -d -p 80:80 nginx
run(创建并运行一个容器)
-d 放在后台
-p 端口映射
-v 源地址(宿主机):目标地址(容器)
nginx docker镜像的名字
docker run -it --name centos6 centos:6.8 /bin/sh
-it 分配交互式的终端
--name 指定容器的名字
/bin/sh覆盖容器的初始命令
启动容器
docker run image_name
docker run -it image_name CMD
docker run ==== docker create + docker start
停止容器
docker stop CONTAINER_ID
杀死容器
docker kill container_name
查看容器列表
docker ps
docker ps –a
删除容器
docker rm
批量删除容器
docker rm -f `docker ps -a -q`
进入容器
*** docker exec (会分配一个新的终端tty)
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
docker exec -it 容器id或容器名字 /bin/bash
docker attach(使用同一个终端)
docker attach [OPTIONS] CONTAINER
nsenter(安装yum install -y util-linux)
docker run -d nginx:latest (没有指定初始命令,启动容器会使用镜像默认的命令)
docker run -it nginx:latest /bin/bash (指定了初始命令,启动容器会替换镜像默认的命令)
总结:docker容器内的第一个进程必须一直处于前台运行的状态(必须夯住),否则这个容器,就会处于退出状态!
九 、docker容器的网络访问 NAT
指定映射(docker 会自动添加一条iptables规则来实现端口映射)
-p hostPort:containerPort
-p ip:hostPort:containerPort
-p ip::containerPort(随机端口)
-p hostPort:containerPort:udp
-p 81:80 –p 443:443
随机映射
docker run -P (随机端口)
十 、docker的数据卷管理
/usr/share/nginx/html
数据卷(文件或目录)
-v dst(容器的目录)
-v src(宿主机的目录):dst(容器的目录)
数据卷容器
--volumes-from 容器名或容器id
十一 、手动将容器保存为镜像
11.1):基于容器制作镜像
案例1
docker run -it -p 1022:22 centos:6.8 /bin/bash
yum install openssh-server -y
/etc/init.d/sshd start
echo "123456"|passwd --stdin root
docker commit 1d39b94c89b6 centos-ssh:v1
docker run -d -p 2022:22 centos-ssh:v1 /usr/sbin/sshd -D
docker commit 容器id或者容器的名字 新的镜像名字[:版本号可选]
案例2
docker run -it -p 1022:22 -p 80:80 centos:6.8 /bin/bash
yum install httpd
yum install openssh-server
/etc/init.d/sshd start
vi /init.sh
#!/bin/bash
/etc/init.d/httpd start
/usr/sbin/sshd -D
chmod +x /init.sh
11.2)将容器提交为镜像
docker commit oldboy centos6-ssh-httpd:v1
11.3)测试镜像功能是否可用
docker run -d -p 2022:22 -p 81:80 centos-ssh-httpd:v1 /bin/bash /init.sh
十二 、dockerfile自动构建docker镜像
dockerfile主要组成部分:
基础镜像信息 FROM:centos:6.8
制作镜像操作指令 RUN yum install openssh-server -y
容器启动时执行指令 CMD ["/bin/bash"]
dockerfile常用指令:
FROM 这个镜像的妈妈是谁?(指定基础镜像)
LABEL 告诉别人,谁负责养它?(指定维护者信息,可以没有)
RUN 你想让它干啥(在命令前面加上RUN即可)
ADD 给它点创业资金(复制文件,会自动解压)
WORKDIR 我是cd,今天刚化了妆(设置当前工作目录)
VOLUME 给它一个存放行李的地方(设置卷,挂载主机目录)
EXPOSE 它要打开的门是啥(指定对外的端口)(-P 随机端口)
CMD 奔跑吧,兄弟!(指定容器启动后的要干的事情)(容易被替换)
使用ADD的时候,ADD init.sh /init.sh(init.sh文件必须放在Dockerfile同级目录下!!!)
dockerfile其他指令:
COPY 复制文件 (复制文件,不会自动解压)
ENV 环境变量
ENTRYPOINT 容器启动后执行的命令(无法被替换,启容器的时候指定的命令,会被当成参数)
十三 、容器间的互联(--link 是单方向的!!!)
docker run -d -p 80:80 nginx
docker run -it --link nginx:web01 qstack/centos-ssh /bin/bash
ping web01
使用docker运行zabbix-server
docker run --name mysql-server -t \
-e MYSQL_DATABASE="zabbix" \
-e MYSQL_USER="zabbix" \
-e MYSQL_PASSWORD="zabbix_pwd" \
-e MYSQL_ROOT_PASSWORD="root_pwd" \
-d mysql:5.7 \
--character-set-server=utf8 --collation-server=utf8_bin
docker run --name zabbix-java-gateway -t \
-d zabbix/zabbix-java-gateway:latest
docker run --name zabbix-server-mysql -t \
-e DB_SERVER_HOST="mysql-server" \
-e MYSQL_DATABASE="zabbix" \
-e MYSQL_USER="zabbix" \
-e MYSQL_PASSWORD="zabbix_pwd" \
-e MYSQL_ROOT_PASSWORD="root_pwd" \
-e ZBX_JAVAGATEWAY="zabbix-java-gateway" \
--link mysql-server:mysql \
--link zabbix-java-gateway:zabbix-java-gateway \
-p 10051:10051 \
-d zabbix/zabbix-server-mysql:latest
docker run --name zabbix-web-nginx-mysql -t \
-e DB_SERVER_HOST="mysql-server" \
-e MYSQL_DATABASE="zabbix" \
-e MYSQL_USER="zabbix" \
-e MYSQL_PASSWORD="zabbix_pwd" \
-e MYSQL_ROOT_PASSWORD="root_pwd" \
--link mysql-server:mysql \
--link zabbix-server-mysql:zabbix-server \
-p 80:80 \
-d zabbix/zabbix-web-nginx-mysql:latest
十四 、docker registry
##普通的registry
docker run -d -p 5000:5000 --restart=always --name registry -v /opt/myregistry:/var/lib/registry registry
docker push index.tenxcloud.com/google_containers/busybox
1:10.0.0.11:5000/centos6-sshd:v3(手动给它打tag)
2:vi /etc/docker/daemon.json
{
"registry-mirrors": ["https://registry.docker-cn.com"],
"insecure-registries": ["10.0.0.11:5000"],
}
systemctl restart docker
3.docker push 10.0.0.11:5000/centos6-sshd:v3
##http带basic认证的registry
yum install httpd-tools -y
mkdir /opt/registry-var/auth/ -p
htpasswd -Bbn oldboy 123456 >> /opt/registry-var/auth/htpasswd
docker run -d -p 5000:5000 -v /opt/registry-var/auth/:/auth/ -v /opt/myregistry:/var/lib/registry -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" registry
十五 、docker-compose(单机版的容器编排工具)
yum install -y python2-pip(需要epel源)
pip install docker-compose
cd my_wordpress/
vi docker-compose.yml
version: '3'
services:
db:
image: mysql:5.7
volumes:
- /oldboy:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
ports:
- "80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
#启动
docker-compose up
#后台启动
docker-compose up -d
十六 、重启docker服务,容器全部退出的解决办法
方法一:docker run --restart=always
方法二:"live-restore": true
docker server配置文件/etc/docker/daemon.json参考
{
"registry-mirrors": ["http://b7a9017d.m.daocloud.io"],
"insecure-registries":["10.0.0.11:5000"],
"live-restore": true
}