容器介绍 什么是容器? 容器就是在隔离的环境运行的一个进程,如果进程停止,容器就会销毁。隔离的环境拥有自己的系统文件,ip地址,主机名等
容器和虚拟化的区别 linux容器技术,容器虚拟化和kvm虚拟化的区别
kvm虚拟化: 需要硬件的支持,需要模拟硬件,可以运行不同的操作系统,启动时间分钟级(开机启动流程)
linux开机启动流程:
bios开机硬件自检
根据bios设置的优先启动项boot 网卡 硬盘 u盘 光驱
读取mbr引导 UEFI(gpt分区) mbr硬盘分区信息,内核加载路径
加载内核
启动第一个进程init systemd(centos7),如果是centos6,/sbin/init
系统初始化完成
运行服务 。。。
容器启动流程:
共用宿主机内核
容器的第一个进程直接运行服务,损耗少,启动快,性能高
容器虚拟化:不需要硬件的支持。不需要模拟硬件,共用宿主机的内核,启动时间秒级(没有开机启动流程)
总结:
与宿主机使用同一个内核,性能损耗小;
不需要指令级模拟;
容器可以在CPU核心的本地运行指令,不需要任何专门的解释机制;
避免了准虚拟化和系统调用替换中的复杂性;
轻量级隔离,在隔离的同时还提供共享机制,以实现容器与宿主机的资源共享。
容器技术的发展过程:
chroot技术,新建一个子系统(拥有自己完整的系统文件),类似与windows的沙箱
linux容器(lxc) linux container(namespaces 命名空间 隔离环境 及cgroups 资源限制)
cgroups 限制一个进程能够使用的资源。cpu,内存,硬盘io
kvm虚拟机:资源限制(1cpu 1G 20G)
安装使用lxc 编译epel源配置文件 1 2 3 4 5 6 7 8 9 10 11 12 13 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo yum install epel-release -y mv /etc/yum.repos.d/epel.repo /etc/yum.repos.d/epel.repo.backupmv /etc/yum.repos.d/epel-testing.repo /etc/yum.repos.d/epel-testing.repo.backupwget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
安装lxc 1 2 3 yum install lxc-* -y yum install libcgroup* -y yum install bridge-utils.x86_64 -y
手动配置桥接网卡 lxc是基于Ubuntu开发的,需要自己 手动配置桥接网卡
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 cat /etc/sysconfig/network-scripts/ifcfg-eth0 echo 'TYPE=Ethernet BOOTPROTO=none NAME=eth0 DEVICE=eth0 ONBOOT=yes BRIDGE=virbr0' > /etc/sysconfig/network-scripts/ifcfg-eth0echo 'TYPE=Bridge BOOTPROTO=static NAME=virbr0 DEVICE=virbr0 ONBOOT=yes IPADDR=10.0.0.11 NETMASK=255.255.255.0 GATEWAY=10.0.0.254 DNS1=180.76.76.76' >/etc/sysconfig/network-scripts/ifcfg-virbr0systemctl restart network
启动cgroup 1 systemctl start cgconfig.service
启动lxc 1 systemctl start lxc.service
创建lxc容器 1 2 3 4 5 6 lxc-create -t download -n centos6 -- --server mirrors.tuna.tsinghua.edu.cn/lxc-images -d centos -r 6 -a amd64 lxc-create -t centos -n test
为lxc容器设置root密码: 1 chroot /var/lib/lxc/test/rootfs passwd
为容器指定ip和网关 1 2 3 4 5 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
启动容器
Docker介绍 Docker是通过进程虚拟化技术(namespaces及cgroups cpu、内存、磁盘io等)来提供容器的资源隔离与安全保障等。由于Docker通过操作系统层的虚拟化实现隔离,所以Docker容器在运行时,不需要类似虚拟机(VM)额外的操作系统开销,提高资源利用率。
namespace 资源隔离
cgroups 进程的资源限制
kvm 虚拟磁盘文件,资源隔离
kvm 资源限制,—cpus —memory
docker 初期把lxc二次开发,libcontainer
docker的主要目标是”Build,Ship and Run any App,Angwhere”,构建,运输,处处运行
构建:做一个docker镜像
运输:docker pull
运行:启动一个容器
每一个容器,他都有自己的系统文件rootfs.
kvm解决了硬件和操作系统之间的依赖 kvm独立的虚拟磁盘,xml配置文件
docker解决了软件和操作系统环境之间的依赖,能够让独立服务或应用程序在不同的环境中,得到相同的运行结果。 docker镜像有自己的文件系统。
docker容器是一种轻量级、可移植、自包含的软件打包技术,使应用程序可以在几乎任何地方以相同的方式运行。开发人员在自己笔记本上创建并测试好的容器,无需任何修改就能够在生产系统的虚拟机、物理服务器或公有云主机上运行。
Docker安装 准备两台机器:
centos7 2G 10.0.0.11 docker01 host解析
centos7 2G 10.0.0.12 docker02 host解析
docker的安装方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 rm -fr /etc/yum.repos.d/local.repocurl -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 systemctl daemon-reload systemctl restart docker find /var/cache/yum/x86_64/7/ -name "*" .rpm find /var/cache/yum/x86_64/7/ -name "*" .rpm | xargs -i mv {} docker_rpm
docker命令自动补全需要安装yum install -y bash-completion
软件包
启动第一个容器 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 vi /etc/docker/daemon.json { "registry-mirrors" : ["https://registry.docker-cn.com" ] } systemctl restart docker docker run -d -p 80:80 nginx run(创建并运行一个容器) -d 放在后台 -p 端口映射 nginx docker镜像的名字
docker的镜像管理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 docker search 选镜像的建议: 1,优先考虑官方 2,stars数量多 docker pull docker pull centos:6.8(没有指定版本,默认会下载最新版) docker pull daocloud.io/huangzhichong/alpine-cn:latest
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 docker images docker image ls docker rmi docker save docker load
docker的容器管理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 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 指定容器的名字 docker inspect centos7 docker run image_name docker run -it image_name /bin/bash docker stop CONTAINER_ID docker kill container_name docker ps docker ps –a docker ps -a -l docker ps -a --no-trunc docker exec docker exec [OPTIONS] CONTAINER COMMAND [ARG...] docker exec -it 容器id 或容器名字 /bin/bash docker attach(使用同一个终端) docker attach [OPTIONS] CONTAINER docker rm container_id docker rm -f `docker ps -a -q` 总结:docker容器内的第一个进程(初始命令)必须一直处于前台运行的状态(必须夯住),否则这个容器,就会处于退出状态! 业务在容器中运行:夯住,启动服务
docker容器的网络访问(端口映射) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 docker0:172.17.0.1 jumpserver:172.17.0.2 nginx:172.17.0.3 指定映射(docker 会自动添加一条iptables规则来实现端口映射) -p hostPort:containerPort -p ip:hostPort:containerPort 多个容器都想使用80端口 ifconfig eth0:1 10.0.0.101/24 up -p ip::containerPort(随机端口) -p hostPort:containerPort:udp -p 81:80 –p 443:443 可以指定多个-p 随机映射 docker run -P (随机端口) 通过iptables来实现的端口映射 sysctl net.ipv4.ip_forward=1 sysctl -a | grep ipv4 | grep forward
docker的数据卷管理 1 2 3 4 5 6 7 8 9 10 11 /usr/share/nginx/html docker run -d -p 80:80 -v /opt/web:/usr/share/nginx/html nginx:latest 做目录的持久化 数据卷(文件或目录) -v 卷名:/data -v src(宿主机的目录):dst(容器的目录) 数据卷容器 --volumes-from(跟某一个已经存在的容器挂载相同的卷)
手动将容器保存为镜像 制作单服务的镜像 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 docker commit 容器id 或者容器的名字 新的镜像名字[:版本号可选] 1):基于容器制作镜像,启动一个基础容器 docker run -it centos:6.9 2)在容器中安装服务,安装支持sshd的服务。 yum provides sshd yum install openssh-server -y service sshd restart echo '123' |passwd --stdin root 3) 把已经安装好服务的容器,提交为镜像 docker container commit 容器名字或id centos6-ssh:v1 4) 测试镜像功能是否可用 docker run -d -p 1022:22 centos6-ssh:v1 docker run -d -p 1022:22 centos6-ssh:v1 /usr/sbin/sshd -D
做一个支持多服务的镜像,ssh+nginx 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 1) 启动一个基础容器 docker run -it -p 80:80 -p 1023:22 centos6-ssh:v1 /bin/bash 2) 在容器中安装nginx服务 curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo yum install nginx -y service nginx start 3)把已经安装好服务的容器,提交为镜像 docker commit 容器名字 centos6_ssh_nginx:v1 4)测试 docker run -d -p 1024:22 -p 81:80 centos6_ssh_nginx:v1 /usr/sbin/sshd -D .... vi /init.sh service sshd restart nginx -g 'deamon off' docker commit 容器名字 centos6_ssh_nginx:v2 docker run -d -p 1025:22 -p 82:80 centos6_ssh_nginx:v2 /bin/bash /init.sh
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 docker exec -it 容器名称 /bin/bash vi /init.sh echo "$SSH_PWD " |passwd --stdin rootservice sshd restart nginx -g 'deamon off' docker commit 容器名字 centos6_ssh_nginx:v3 docker run -d -p 1026:22 -p -e "SSH_PWD=cwz@qq.com" 85:80 centos6_ssh_nginx:v3 /bin/bash /init.sh vi /init.sh if [ -z $SSH_PWD ];then SSH_PWD=123 fi echo "$SSH_PWD " |passwd --stdin rootservice sshd restart nginx -g 'deamon off'
dockerfile自动构建docker镜像 类似ansible剧本,大小几kb 而手动做镜像:大小几百M,传输不便
dockerfile 支持自定义容器的初始命令
dockerfile主要组成部分:
基础镜像信息 FROM centos:6.9
制作镜像操作指令 RUN yum install openssh-server -y
容器启动时执行指令 CMD [“/bin/bash”]
制作dockerfile 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 mkdir /opt/dockerfilecd /opt/dockerfilemkdir centos6_sshcd centos6_ssh vim dockerfile FROM centos:6.9 RUN yum install openssh-server -y RUN service sshd restart RUN echo '123' |passwd --stdin root CMD ["/usr/sbin/sshd" , "-D" ] docker build -t centos6_ssh:v2 /opt/dockerfile/centos6_ssh/dockerfile
自动构建镜像的步骤
手动构建一遍
编写dockerfile
构建镜像
测试
每当起一个临时容器的时候会有三个文件覆盖进来:/etc/hosts
/etc/hostname
/etc/resolv.conf
,所以想要用镜像加速,可以把命令写在一个RUN里面,因为RUN会起一个临时容器,这个容器有自己的主机名、host解析等。
1 2 3 4 5 6 7 FROM centos:6.9 RUN echo '192.168.1.102 mirrors.aliyun.com' >> /etc/hosts && curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo && yum install openssh-server -y RUN service sshd restart RUN echo '123' |passwd --stdin root CMD ["/usr/sbin/sshd" , "-D" ]
构建支持多服务的dockerfile 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 FROM centos:6.9 RUN echo '192.168.1.102 mirrors.aliyun.com' >> /etc/hosts && curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo && curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo && yum install openssh-server nginx -y RUN service sshd restart RUN echo '123' |passwd --stdin root ADD init.sh /init.sh CMD ["/usr/sbin/sshd" , "/init.sh" ] vi /init.sh service sshd restart nginx -g 'deamon off'
dockerfile指令 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 dockerfile常用指令: FROM 这个镜像的妈妈是谁?(指定基础镜像) MAINTAINER 告诉别人,谁负责养它?(指定维护者信息,可以没有) LABLE 描述,标签 RUN 你想让它干啥(在命令前面加上RUN即可) ADD 给它点创业资金(会自动解压tar) 制作docker基础的系统镜像 WORKDIR 我是cd ,今天刚化了妆(设置当前工作目录) VOLUME 给它一个存放行李的地方(设置卷,挂载主机目录) EXPOSE 它要打开的门是啥(指定对外的端口)(-P 随机端口) 做随机端口映射 CMD 奔跑吧,兄弟!(指定容器启动后的要干的事情)(容易被替换) dockerfile其他指令: COPY 复制文件(不会解压)rootfs.tar.gz ENV 环境变量 ENTRYPOINT 容器启动后执行的命令(无法被替换,启容器的时候指定的命令,会被当成参数)
小例子 制作一个kodexplorer网盘 docker镜像。nginx + php-fpm(或者httpd + php)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 docker run -it -p 80:80 centos:6.9 /bin/bash echo '192.168.1.102 mirrors.aliyun.com' >> /etc/hosts curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo yum install php -y service httpd start cd /var/www/htmlcurl -o kodexplorer4.40.zip http://static.kodcloud.com/update/download/kodexplorer4.40.zip yum install unzip -y unzip kodexplorer4.40.zip chown -R apache:apache . yum install php-gd php-mbstring -y service httpd restart
编写dockerfile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 FROM centos:6.9 RUN echo '192.168.1.102 mirrors.aliyun.com' >> /etc/hosts && curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo && yum install unzip php php-gd php-mbstring -y WORKDIR /var/www/html ADD kodexplorer4.40.zip . RUN unzip kodexplorer4.40.zip RUN chown -R apache:apache . EXPOSE 80 ADD init.sh /init.sh ENTRYPOINT ["/bin/bash" , "/init.sh" ] vi init.sh service httpd restart tail -F /var/log/httpd/access_log
构建镜像:
1 2 3 4 docker build -t kod:v1 . docker run -d -p 80:80 kod:v1
docker镜像的分层 kvm 链接克隆,具有写时复制的特性
镜像分层的好处:复用,节省磁盘空间,相同的内容只需加载一份到内存。 修改dockerfile之后,再次构建速度快
容器间的互联 使用—link 是单方向的!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 docker run -it --link 要连接的容器的名字:web(起一个别名) centos6_ssh:v2 /bin/bash docker run -d -p 80:80 nginx docker run -it --link quirky_brown:web01 centos6_ssh:v2 /bin/bash ping web01 lb ---> nginx 172.17.0.4 --> db01 172.17.0.3 --> nfs01 172.17.0.2
docker registry(私有仓库) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 docker run -d -p 5000:5000 --restart=always --name registry -v /opt/myregistry:/var/lib/registry registry 上传镜像到私有仓库步骤: a:给镜像打标签 docker tag centos6-sshd:v3 10.0.0.11:5000/centos6-sshd:v3 b:上传镜像到私有仓库 docker push 10.0.0.11:5000/centos6-sshd:v3 如果遇到报错: The push refers to repository [10.0.0.11:5000/centos6.9_ssh] Get https://10.0.0.11:5000/v2/: http: server gave HTTP response to HTTPS client 解决方法: vim /etc/docker/daemon.json { "insecure-registries" : ["10.0.0.11:5000" ] } systemctl restart docker vim /etc/docker/daemon.json { "insecure-registries" : ["10.0.0.11:5000" ] } systemctl restart docker docker run -d 10.0.0.11:5000/centos6-sshd:v3 yum install httpd-tools -y mkdir /opt/registry-var/auth/ -phtpasswd -Bbn cwz 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 login 10.0.0.11:5000
https://www.qstack.com.cn/archives/350.html
1 2 3 4 5 6 7 { "registry-mirrors" : [ "https://docker.mirrors.ustc.edu.cn" , "https://registry.docker-cn.com" ] }
重启docker服务,容器全部退出的解决办法 1 2 3 4 5 6 7 8 9 10 11 docker run -d --restart=always nginx:latest vi /etc/docker/daemon.json { "registry-mirrors" : ["http://b7a9017d.m.daocloud.io" ], "insecure-registries" :["10.0.0.11:5000" ], "live-restore" : true }
Docker Machine远程给其他宿主机安装docker服务 没什么用
1 2 3 Docker Machine 二进制 10.0.0.11 10.0.0.12 免密码登陆 从docker的官网下载二进制的包,去安装docker 10.0.0.13 免密码登陆
Docker网络类型 1 2 3 4 5 6 7 8 9 10 11 12 docker run -it --network none centos6.9:v1 docker run -it --network host centos6.9:v1 docker run -it centos6.9:v1 docker run -it --network container:f19b913ddca7 centos6.9:v1
Docker跨主机容器之间的通信macvlan 默认一个物理网卡,只有一个物理地址,虚拟多个mac地址
准备两台主机,使用相同的容器
docker01 10.0.0.11
docker02 10.0.0.12
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 docker network ls docker network create --driver macvlan --subnet 10.0.0.0/24 --gateway 10.0.0.254 -o parent=eth0 macvlan_1 ip link set eth1 promisc on docker run -it --network macvlan_1 --ip=10.0.0.200 centos6.9_ssh:v1 /bin/bash ping 10.0.0.12
macvlan适合把虚拟机环境迁移到容器环境。
Dcoker跨主机容器通信之overlay 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 1)准备工作 docker01上: docker run -d -p 8500:8500 --restart=always -h consul --name consul progrium/consul -server -bootstrap 设置容器的主机名 docker01上: vim /etc/docker/daemon.json { "hosts" :["tcp://0.0.0.0:2376" ,"unix:///var/run/docker.sock" ], "cluster-store" : "consul://10.0.0.11:8500" , "cluster-advertise" : "10.0.0.11:2376" } docker02上: vim /etc/docker/daemon.json { "hosts" :["tcp://0.0.0.0:2376" ,"unix:///var/run/docker.sock" ], "cluster-store" : "consul://10.0.0.12:8500" , "cluster-advertise" : "10.0.0.12:2376" } vim /usr/lib/systemd/system/docker.service systemctl daemon-reload systemctl restart docker 2)创建overlay网络 docker network create -d overlay --subnet 172.16.1.0/24 --gateway 172.16.1.254 d1 3)启动容器测试 docker run -it --network d1 --name web01 centos6.9_ssh:v1 每个容器有两块网卡,eth0实现容器间的通讯,eth1实现容器访问外网
docker-compose(单机版的容器编排工具) 能一次性启动多个容器,并且能够编排启动顺序
1 2 yum install -y python3-pip(需要epel源) pip3 install docker-compose(默认pypi源在国外)
需要写一个配置文件,是docker-compose.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 mkdir /opt/wordpress & cd /opt/wordpressvi docker-compose.yml version: '3' services: db: image: mysql:5.7 volumes: - db_data:/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 volumes: - web_data:/var/www/html ports: - "80:80" restart: always environment: WORDPRESS_DB_HOST: db:3306 WORDPRESS_DB_USER: wordpress WORDPRESS_DB_PASSWORD: wordpress volumes: db_data: web_data: docker-compose up docker-compose up -d docker-compose down
docker企业级镜像仓库harbor(vmware 中国团队) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 第一步:安装docker和docker-compose 第二步:下载harbor-offline-installer-v1.8.6.tgz 第三步:上传到/opt,并解压 tar xf harbor-offline-installer-v1.8.6.tgz cd harbor/第四步:修改harbor.cfg配置文件 hostname = 10.0.0.11 harbor_admin_password = 123456 第五步:执行install.sh ./instasll.sh
浏览器访问ip地址
上传docker容器的时候注意添加白名单
1 2 3 vi /etc/docker/daemon.json "insecure-registries" : ["192.168.40.131" ]