Docker

Docker

一、docker概述

​ docker是一种容器技术,但是容器不仅仅只有docker

​ dotcloud公司开发,2013年开源,2013年底改名docker公司,支持最好的linux版本:ubuntu(14以上)、centos7以上

​ 开发语言:Go语言(谷歌)

​ 三大支撑技术:基于内核的cgroup技术、namespace、联合分层文件系统

​ 来源于lxc (Linux container),采用三大支撑技术,建立“build shipi and run”理念

​ docker图标:

​ 集装箱:代表镜像—build 大鲸鱼:代表仓库—ship

​ 镜像是死的,需要运行它,运行后形态:容器—run

​ 广告词: build ship and run anyapp anywhere

​ 版本:分为docker ee (企业版) 和 docker ce (社区版)

先有镜像才有容器

场景 顺序 说明
常规运行容器 镜像 → 容器 必须基于已有镜像创建容器。
构建镜像 临时容器 → 新镜像 通过临时容器生成镜像,但依赖基础镜像存在。

​ 容器和虚拟机的差异对比:

​ 容器没有hypervisor这一层,没有guestos,所有容器共享操作系统内核,轻量级虚拟化,减少资源占用!!!

​ 传统型的虚拟化优势:隔离性好

​ 容器的优势:轻量、简单、效率高

​ 虚拟机在系统中形态是一台机器,容器在系统中是一个进程

​ docker架构:

​ 会有一个docker daemon进程,管理镜像(image)、容器(containers)、网络(network)、数据卷(data volume)

​ c/s架构,分为服务器端和客户端,远程管理rest api接口

​ docker平台架构:

​ 服务器、客户端、镜像、容器、仓库

​ 容器编排平台:

kubernetes(k8s) 谷歌
mesos apache
docker swarm docker公司

二、实验环境搭建

​ 1、可以联网的情况下,可以采用在线安装方式

​ 2、我们采用离线安装包的方式来安装

​ (1) 准备一台centos的虚拟机

​ 创建一台虚拟机—- 稍后安装操作系统—- 选择centos7 64位 —- 指定虚拟机的名字和位置—- cpu1 2核 —- 内存:2G —- 网络:NAT —- 创建一个新的虚拟磁盘—- 磁盘:80G 单个文件—-删除声卡、打印机—- 塞入光盘centos7-1511.iso

​ 安装操作系统—- 安装语言:英语—- 时区:亚洲上海—- 分区:I will configure partation —- 分区类型:lvm 自动分区—-/根分区调大 /home调小—-接受改变—-安装模式:最小化安装—-kdump关闭—-设置root密码和普通用户

​ (2) 服务器的基本配置

​ 1)主机名、主机名解析

​ 查看主机名 hostname 设置主机名 hostnamectl set-hostname 主机名

​ 主机名解析文件: /etc/hostname

​ 2)ip地址

​ 默认网卡 eno16777736 没有ip地址,因为网卡没有启用

​ vi /etc/sysconfig/network-scripts/ifcfg-eno16777736 ONBOOT=yes 重启网络

​ 测试网络联通性:

​ ping网关 ping物理机 ping百度

​ 由于dhcp分配的地址会变化,需要固定ip地址,修改配置文件/etc/sysconfig/network-scripts/ifcfg-eno16777736

1
2
3
4
5
6
BOOTPROTO=dhcp==>static
centos7有两个网络管理器,一个network,一个NetworkManager(默认)
NM_CONTROLED=no
IPADDR=192.168.200.191 (最后一个字段不能是0,不能是1,不能是2)
PREFIX=24(NETMASK=255.255.255.0)
GATEWAY=192.168.200.2

​ 修改完后保存,重启网络,如果物理机可以ping通,百度无法ping通,则是域名解析问题

​ vi /etc/resolv.conf

​ 添加 nameserver 192.168.200.2

​ 3)关闭防火墙、关闭selinux

​ systemctl status firewalld —查看防火墙状态

​ systemctl stop firewalld —关闭防火墙

​ systemctl disable firewalld —关闭防火墙自启

​ iptables -L —查看状态

​ selinux—三种模式:enforcing(默认)、permissiver、disabled

​ getenforce —查看selinux的模式

​ setenforce 0 —修改selinux模式,临时修改

​ vi /etc/sysconfig/selinux 修改模式enforcing —->disabled

​ 4)仓库

1、 上传Docker.tar.gz包

​ 解压 tar zxvf Docker.tar.gz,解压后多出两个目录:docker(保存的是安装包)、images(保存的是镜像)

​ 进入/etc/yum.repos.d目录,删除或移走网络源 mkdir bak 、mv C* bak

2、 创建一个本地仓库文件local.repo

1
2
3
4
5
[docker]			---仓库标签
name=docker ---仓库名
baseurl=file:///root/Docker ---仓库位置
enabled=1 ---启用仓库
gpgcheck=0 ---不做校验

验证仓库:

yum clean all —清空缓存

yum repo list —查看仓库

yum list —列出仓库的所有安装包

3、升级内核,以及参数优化

​ 升级前内核版本:3.10.0-327.el7.x86_64 版本查看命令:cat /etc/os-release 内核版本查看:uname -a

​ yum upgrade -y 升级内核

​ reboot重启

​ 升级后的内核版本:3.10.0-1062.7.1.el7.x86_64

​ 注意:升级内核之后,网络源仓库文件会重新生成,需要重新删除(rm -f Cent*)

​ 加载防火墙模块 modprobe br_netfilter

​ vi /etc/sysctl.conf 内核参数优化配置文件

1
2
3
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1

​ sysctl -p 加载以上三行

4、安装启动docker

1
yum install docker-ce docker-ce-cli containerd-io -y

​ 启动Docker: systemctl start docker

​ systemctl enable docker

​ 验证实验环境:

​ Docker服务端:systemctl status docker

​ Docker客户端:docker –help 

docker命令分为两类:管理命令(一组)、直接使用的命令

docker image ls ——列出当前的镜像(管理命令)

1
REPOSITORY(仓库镜像名)	TAG(标签)	IMAGE ID(id)	CREATED(创建时间)	SIZE(大小)

三、镜像和容器

镜像:

​ 查看镜像:docker images(docker image ls)

​ 删除镜像:docker rmi 镜像名 (-f 强制删除)—–如果镜像被某个容器使用,则不能删除!(解决:1.删除容器再删除镜像 2.使用-f 选项强制删除)

​ 删除没有使用的镜像(虚悬镜像): docker image prune

​ 清空所有镜像:` docker rmi docker images -qa``

​ 获取镜像:

​ 1)已经有docker镜像包,可以导入

​ 导入镜像:docker load -i xxxxx.tar(镜像tar包文件)

​ 2)从查看中拉取镜像—— dockerhub —– 全世界最大的镜像仓库

​ 拉取镜像:docker pull 镜像名:标签

​ 解决办法:国内镜像加速

​ vi /etc/docker/daemon.json

1
2
3
4
5
{        

"registry-mirrors":["http://hammal.staronearth.win","https://ccr.ccs.tencentyun.com"]

}

systemctl daemon-reload

systemctl restart docker

容器:

查看当前的容器: docker ps (列出当前在运行的容器) -a(列出所有的容器)

删除容器:docker rm 容器名(id)—– 如果容器在运行,则不能删除

清空所有容器:docker rm -f ‘docker ps -qa’
删除关闭的容器:docker container prune

解决办法:1.先stop再删除 2.-f 强制删除

创建容器:docker run [option 选项]镜像名 [命令]

创建一个交互式容器:创建后直接进入到容器中

​ docker run -it –name 容器名 镜像名

​ -i:可以交互(interactive) -t:分配一个虚拟终端(tty)

​ –name:容器名字

​ –rm: 当容器退出时自动删除容器 (用于测试)

​ -h(–hostname):指定容器的主机名

​ 退出容器:exit —- 退出后容器会关闭!!

创建一个守护式容器:创建后没有进入容器

​ docker run -itd –name 容器名 镜像名

​ -d: 后台运行

进入容器:—-后台在运行

方式一:docker attach 容器名 (不推荐)

​ 问题:退出时 exit —-导致容器被关闭———-正确的退出方式:ctrl+p、q

方式二:docker exec -it 容器名 /bin/bash (推荐)

​ exit退出容器不会关闭容器

案例:

​ 使用nginx镜像启动容器:

​ docker run -itd –name webserver -p 80:80 nginx

选项: -p:端口映射 宿主机端口:容器端口

​ -p:讲端口映射到宿主机随机端口

​ nginx服务端口:80

​ nginx服务的首页位置: /usr/share/nginx/html/index.html

​ 修改nginx首页的内容 :

1
echo '<h1>hello,i am your first container!!!</a>' > index.html 

案例:显示nginx服务修改后的首页:
使用nginx镜像启动容器:
docker run -itd –name webserver -p 80:80 nginx
选项: -p: 端口映射 宿主机端口:容器端口
-P: 将容器端口映射到宿主机随机端口
nginx服务端口: 80
nginx服务的首页位置: /usr/share/nginx/html/index.html
修改nginx首页的内容

1
echo '<h1>hello, i am your first container!!!</h1>' > index.html 

容器的生命周期:

​ docker run ——创建容器

​ docker start 容器名 ——启动容器

​ docker stop 容器名 ——停止容器

​ docker restart 容器名 ——重启容器

​ docker pasue 容器名 ——暂停容器(暂停的容器无法进入)

​ docker unpause 容器名 ——取消暂停

​ docker rm 容器名 ——删除容器

容器其它使用的命令:

1
2
3
4
5
6
docker exec	------	不进入容器,使用一些命令操作
docker logs -f 容器名 ------ 获取容器的日志
docker top 容器名 ------ 查看容器进程
docker stats ------查看容器占用资源情况
docker inspect docker对象 ------查看docker对象的底层信息(json格式的配置信息)
docker inspect -f {{.NetworkSettings.IPAddress}} webserver ------获取格式化信息

四、数据卷

​ 解决:容器中的数据生命周期是依赖于容器的生命周期,需要实现数据的持久化(脱离容器的生命周期)

​ 1.容器与宿主机之间的数据拷贝

​ docker cp 容器名:容器内文件路径 拷贝到 宿主机的路径 —- 容器–>宿主机

​ docker cp 宿主机的文件路径: 容器名:容器内文件路径 —-宿主机–>容器

​ 2.使用数据卷

​ bind-mount:在容器创建时创建卷——容器目录与宿主机某个目录“绑定”

​ 分为两类:

​ 1)绑定挂载卷:同时指定容器中的目录和宿主机中的目录

​ 2)docker指定挂载卷:只指定容器中的目录,宿主机目录由docker指定

​ docker run —- 选项

​ -v:创建容器时,创建数据卷

​ –volume-from 容器名:使用指定容器的卷

​ –mount:创建

​ docker run -it –name c1 -v /wjfdata busybox :创建一个docker指定挂载卷

​ docker inspect c1:

            "Mounts": [
        {
            "Type": "volume",
            "Name": "a2378a97ca0ec91ed0e73382c8dcac4cb9fab4329de15120d45e8997a811d43e",
            "Source": "/var/lib/docker/volumes/a2378a97ca0ec91ed0e73382c8dcac4cb9fab4329de15120d45e8997a811d43e/_data",
            "Destination": "/wjfdata",
            "Driver": "local",
            "Mode": "",
            "RW": true,
            "Propagation": ""
        }
    ],

​ 删除创建了数据卷的容器:docker rm -vf 容器名

​ docker run -it –name c1 -v /data/volume/c1:/wjfdata busybox :创建一个绑定挂载卷(宿主机目录:容器目录)

1
2
3
4
5
6
7
8
9
10
"Mounts": [
{
"Type": "bind",
"Source": "/data/volueme/c1",
"Destination": "/wjfdata",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],

​ 删除容器后,重建新容器同时获取原数据

​ docker run -it –name c2 -v /data/volume/c1:/wjfdata busybox

​ 案例1:创建容器实现nginx服务,要求不进入容器中,修改主页内容

1
2
3
mkdir /root/html
docker run -itd --name wjf1 -p 80:80 -v /root/html:/usr/share/nginx/html nginx
echo 'Hello,World!' > /root/html/index.html

​ 案例2:容器与容器之间共享数据卷:将两个容器的目录与同一宿主机目录绑定即可

1
2
docker run -it --name test1 -v /data/volume/test1:/data busybox
docker run -it --name test2 -v /data/volume/test1:/wjfdata centos

​ 案例3:三个容器同时提供nginx服务,访问到相同的页面(模拟集群,负载均衡)

1
2
3
4
5
6
docker run -itd --name web1 -p 81:80 -v /usr/share/nginx/html nginx
docker run -itd --name web2 -p 82:80 --volumes-from web1 nginx
docker run -itd --name web3 -p 83:80 --volumes-from web1 nginx
docker exec -it web1 bash
cd /usr/share/nginx/html/
echo 'hello,i am web1' > index.html

​ volume:单独创建卷

​ dockerr volume ls —— 列出数据卷

​ docker volume create 卷名 ——创建数据卷

​ docker volume inspect 卷名 ——查看卷的详细信息

​ docker run -it –name c1 –mount source=myvol,target=/jxdata busybox ——挂载卷到容器

​ docker run -it –name c3 –mount source=myvol,target=/data busybox — ——同一个卷可以挂载到不同容器

​ docker volume rm myvol(docker volume prune)

​ ——删除卷(卷没有使用)

五、容器网络

​ 搭建环境后,会默认创建一个网桥docker0,ip地址172.17.0.1/16,会下发ip地址给容器,172.17.0.2/16,172.17.0.3/16

​ 创建容器时,会创建一对接口,一端在宿主机(认为连接到docker0,接口vethXXX),另一端在容器中eth0

​ 非集群环境有三种网络:bridge(默认)、host、none

​ 列出网络:docker network ls

​ 查看网络信息:docker network inspect bridge

​ 创建一个无网络的容器:docker run -it –name c3 –network none busybox(做数据处理)

​ 创建网络:docker network create -d bridge testnetwork ——创建一个新的网桥

​ 连接一个容器到网络:docker network connect 网络名 容器名 ——相当于为容器添加另一个网卡

​ 将容器从网络断开:docker network disconnecte 网络名 容器名

​ 删除网络:docker network rm 网络名(docker network prune) 如果网络被容器使用,则先删除容器

​ 练习:

​ 创建一个网络:wjf-net,网段:10.0.0.0/16

​ 创建两个容器:con1、con2 ——使用bridge网络

​ 创建第三个容器:con3 ——使用wjf-net网络

​ 验证联通性:使三个容器可以互通

1
2
3
4
5
6
7
8
9
10
11
12
13
步骤:
docker network create --driver bridge --subnet 10.0.0.0/16 xxx-net
docker run -itd --name con1 --network bridge busybox
docker run -itd --name con2 --network bridge busybox
docker run -itd --name con3 --network xxx-net busybox

复制终端在另一个窗口打开(复制两次):
进入容器:docker exec -it 容器id /bin/sh
查看各个容器ip: ip ad
用con1 ping con2的ip
docker network connect bridge con3 给con3添加一块网卡连接到bridge
随后进入con3查看con3容器的ip地址
回到con1 ping con2 ,ping con3

​ 案例1:容器互联

​ 作用:容器与容器之间如果通过ip地址访问有问题,实现ip的无关性!!!

​ docker run 选项:

​ –link 链接

​ docker run -itd –name host1 centos 第一个容器

​ docker run -itd –name host2 –link host1:brother centos 将第二个容器链接到第一个容器 —— 要链接的容器名:别名

​ 进入host2,可以使用别名(主机名)访问host1

​ 案例2:联盟式容器

​ 容器与容器之间共享同一个网络名称空间

​ docker run -it –name c2 –network container:c1 busybox 创建容器c2时使用c1的网络名称空间

​ c1: /# echo ‘hello,i am c1 container’ > /tmp/index.html

​ /# httpd -h /tmp

​ c2: /# wget -O –q 127.0.0.1

​ 案例3:容器与宿主机共享同一个网络名称空间

​ docker run -it –name c3 –network host busybox

​ 不需要网络地址转换,直接使用宿主机的网络空间

六、镜像制作

​ 为什么需要? ——之前所有的容器都是使用别人的镜像创建的,有问题?

​ 1)别人的镜像未必适用

​ 2)开发人员,需要把源代码打包到镜像

​ 方式一:容器提交为镜像 ——docker commit

​ 案例:将nginx服务的首页的内容打包到镜像中

​ 1.需要拉取原始镜像—nginx原始镜像

​ 2.需要使用原始镜像启动一个容器

​ docker run -itd –name web -p 80:80 nginx

​ 3.在容器中修改

​ 进入容器,修改首页

​ docker diff 容器名:容器对镜像所做的修改

​ 4.把容器提交为新的镜像

​ docker commit –author 作者 –message 镜像信息 容器名 镜像名:将容器提交为镜像

​ docker history 镜像名:查看镜像的历史信息

​ 5.使用新镜像创建容器,进行测试

​ docker run -itd –name web3 -p 82:80 nginx:v2

​ 案例2:制作tomcat镜像

​ 方式一:

​ 1.拉取基础镜像——centos原始镜像

​ 2.使用基础镜像创建一个容器

​ docker run -it –nam mycentos centos

​ 3.在容器中修改

​ 1)上传jdk和tomcat安装包

​ 2)通过docker cp将安装包拷贝到容器中

​ docker cp jdk-8u161-linux-x64.tar.gz mycentos:/root

​ docker cp apache-tomcat-7.0.47.tar.gz mycentos:/root

​ 3)安装jdk

​ tar -zxvf jdk-8u161-linux-x64.tar.gz -C /usr/local/

​ 4)配置jdk的环境变量

​ 编辑/etc/profile添加两行:

1
2
JAVA_HOME=/usr/local/jdk1.8.0_161
export PATH=$JAVA_HOME/bin:$PATH

​ 加载:source /etc/profile

​ 检查:java -version

​ 5) 安装tomcat

​ tar -zxvf apache-tomcat-7.0.47.tar.gz -C /usr/local/

​ 6)配置tomcat环境变量

​ vi /usr/local/apache-tomcat-7.0.47/bin/setclasspath.sh

​ 添加两行:

1
2
export JAVA_HOME=/usr/local/jdk1.8.0_161
export JRE_HOME=/usr/local/jdk1.8.0_161/jre

​ 4.将容器提交为新的镜像

​ docker commit –author “cloud01” –message “my tomcat image” mycentos mytomcat

​ 5.测试镜像

​ docker run -itd –name t1 -p 8888:8080 mytomcat (tomcat的服务端口是8080)

​ docker exec t1 /usr/local/apache-tomcat-7.0.47/bin/startup.sh 启动tomcat

​ 方式二:通过Dockerfile文件来构建镜像 —-docker build

​ 1.创建一个文件夹,进入文件夹

​ 2.在文件夹中拉取hello

1
wget https://github.com/docker-library/hello-world/raw/refs/heads/master/amd64/hello-world/hello

​ 3.修改hello权限 chmod +x hello

​ 4.编辑Dockerfile文件

1
2
3
4
5
FROM scratch

COPY hello /

CMD [“/hello”]

​ 5.使用docker build 构建镜像

1
docker build -t myhello:1.0

​ 6.测试

1
docker run myhello:1.0 .

Dockerfile指令: man dockerfile

1
2
3
4
5
6
7
8
9
10
11
FROM 基本镜像	---第1行
MAINTAINER ---指定镜像创建者信息、邮箱
RUN ---基本镜像所支持的命令
CMD ---容器启动时执行的命令 ---类似ENTRYPOINT
USER ---指定用户 (默认用户root)
EXPOSE ---暴露端口
ENV ---环境变量
ADD ---添加文件 (类似COPY) 不同在于可以解压缩,可以添加远程文件
VOLUME ---创建 数据卷
WORKDIR ---切换工作目录
ONBUILD ---在子镜像执行的命令

案例2:通过Dockerfile文件构建nginx服务镜像

​ 1.创建一个文件夹,并进入文件夹

​ 2.创建一个文件夹,并进入文件夹

​ 3.编辑Dockerfile文件

1
2
3
4
5
6
7
8
#Version:0.0.1
FROM ubuntu:14.04 ---基本镜像
MAINTAINER James Turnbull "[email protected]" ---维护者信息、邮箱
RUN apt-get update ---更新仓库
apt-get install -y nginx ---安装nginx
RUN echo 'Hi,I am in your containe' > /usr/share/nginx/html/index.html --修改首页内容
EXPOSE 80 ---暴露端口
CMD ["nginx","-g","daemon off;"] ---容器执行的命令

​ 4.构建镜像

1
docker build -t cloud01/static_web .

​ 5.测试

1
docker run -itd --name web -p 8080:80 cloud01/static_web

​ 访问http://192.168.200.191

七、仓库

​ 镜像的ship:

​ 方式一:镜像的 导入和导出,导出为文件,手动拷贝,人工携带

​ 1) 将容器导出为文件,到目标机再导入

1
2
3
4
docker run -it --name c1 alpine	创建一个容器
docker export -o 导出的tar文件 容器名 ---- 将容器导出为tar文件 ---docker export -o export.tar c1
docker import tar 文件路径 导入后镜像名:标签 --- 将tar文件导入为镜像 ---docker import -m 'import test' export.tar myalpine
docker run -it myalpine sh 验证

​ 2) 镜像的保存和加载

1
2
3
docker save -o	保存的tar文件名 镜像名	---将镜像保存为tar文件
docker load -i tar文件名 ---将文件加载为镜像
docker run myhello:1.0 验证

​ 方式二:建立仓库,通过网络来传递镜像

​ 镜像的完整表示:注册服务器/仓库/镜像名:版本,世界上最大的镜像仓库:dockerhub — docker.io/library/mysql:latest

​ 私有仓库:

​ dockerhub、阿里云等平台注册后可以建立一个小的个人仓库,容量比较小

​ docker push 镜像名 —推送镜像

​ 默认是: docker.io/library/mytomcat :不能推送

​ docker tag 镜像名 改标签后的镜像名 — 为镜像打标签

​ docker login 登录

​ 阿里云仓库使用—注册—容器镜像服务—管理控制台—个人版—创建命名空间—创建镜像仓库—本地仓库

登录:docker login –username=aliyun3676574592 crpi-hwsvpr2co34f3mnv.cn-guangzhou.personal.cr.aliyuncs.com

改标签:docker tag afa23431513f crpi-hwsvpr2co34f3mnv.cn-guangzhou.personal.cr.aliyuncs.com/wjfns_cloud01/wjfrepo_cloud01:v1

推送镜像到仓库:docker push crpi-hwsvpr2co34f3mnv.cn-guangzhou.personal.cr.aliyuncs.com/wjfns_cloud01/wjfrepo_cloud01:v1

从仓库拉取镜像: docker pull crpi-hwsvpr2co34f3mnv.cn-guangzhou.personal.cr.aliyuncs.com/wjfns_cloud01/wjfrepo_cloud01:v1

私有仓库:(harbor—VMware中国区团队—带图形界面)

​ 创建私有仓库:镜像registry 获取registry:

​ 1)docker load -i registry.tar

​ 2)docker pull registry

​ docker run -d -v /opt/registry:/var/lib/registry –restart=always –name registry -p 5000:5000 registry 创建仓库

验证:curl http://localhost:5000/v2

案例:模拟公共仓库与私有仓库的联动

1.模拟开发人员,从公共仓库拉取镜像,镜像启动为容器,提交容器为修改后的镜像

1
2
docker run -it --name a1 alpine	启动容器,修改内容
docker commit -a "cloud01" -m "dev work" a1 alpinetest 提交容器为新的镜像

2.开发人员将镜像推送到企业私有仓库

​ 修改镜像标签:docker tag alpinetest 192.168.200.191:5000/alpinetest

​ 修改/etc/docker/daemon.json,添加一行”insecure-registries”:[“192.168.200.191:5000”]

1
2
3
4
{
"registry-mirrors":["http://hammal.staronearth.win","https://mirror.ccs.tencentyun.com"],
"insecure-registries":["192.168.200.191:5000"]
}

systemctl daemon-reload

systemctl restart docker

docker push 192.168.200.191:5000/alpinetest 推送镜像到私有仓库

验证:curl http://192.168.200.191:5000/v2/_catalog

3.模拟测试人员,从私有仓库拉取开发人员推送的镜像做测试

​ docker pull 192.168.200.191:5000/alpinetest 私有仓库拉取镜像

​ docker run -it 192.168.200.191:5000/alpinetest 测试

八、docker swarm

​ 容器编排平台:

​ kubernetes —谷歌

​ mesos —apache社区

​ swarm(本身是群集的意思) —docker自己

​ docker swarm:将多个装有docker的docker engine 聚合成一个大的docker engine,对外提供统一的服务

​ docker swarm特点:

​ 1.docker engine可以平滑切换,不需要改动

​ 2.学习成本低,轻量级,简单

​ 3.与docker是同一家公司,兼容性好

​ docker swarm 架构:

​ 管理节点(swarm manager):— 管理集群(项目经理),也可以多个

​ scheduler — 任务调度

​ discovery service — 服务发现

​ 工作节点(swarm worker): — 干活 (程序员),多个

​ 完成任务 — 启动容器

​ 集群整体提供 — 服务(service)

​ docker swarm 搭建:

​ 规划:一个管理节点、两个工作节点构建集群

​ 管理节点: 192.168.200.191/24 manager

​ 工作节点: 192.168.200.192/24 worker1

​ 192.168.200.193/24 worker2

步骤:

​ 1.准备3台虚拟机

​ 1)需要修改网卡 eno16777736 — ens33

1
mv ifcfg-eno16777736 ifcfg-ens33

​ 2)修改配置文件中的NAME、DEVICE为ens33,修改IP地址,删除文件

1
rm /etc/udev/rules.d/90-eno-fix.rules

​ 3)修改 /etc/resolv.conf

1
nameserver 192.168.200.2

​ 4)重启网络ping网关和外网(百度)

2.创建集群

1
2
3
4
5
6
7
docker swarm init --advertise-addr 192.168.200.191(在管理节点上执行)
docker node ls ----查看集群中的节点
docker network ls ----查看网络---overlay覆盖性网络
docker swarm join --token SWMTKN-1-0qr3ygyif46pe7px50wlnuwu6938bu4suhrodkt6xni123pl0k-dph7cq41s7bmo4qkdgk85kpr9 192.168.200.191:2377 ---作为工作节点加入集群
docker swarm leave ---退出集群
docker swarm join-token worker|manager ---以管理节点/工作节点的身份加入集群
docker node rm r9j5cdbkpil31d6aavm9ub2kw---删除集群的节点

docker swarm 使用:

​ 部署服务:

1
2
3
4
5
6
7
8
9
10
docker service ls ---列出服务
docker service create --replicas 1 --name helloworld alpine ping docker.com 创建服务
--replicas 任务数
--name 服务名
alpine 镜像名
ping docker.com 命令
docker service inspect 服务名 --- 查看服务的底层详细信息
docker service ps 服务名 ---查看服务的任务调度情况
docker service scale 服务名=副本数量 --- 设置服务的副本数
docker service rm 服务名 --- 删除服务

案例:在集群中部署nginx服务

1.创建一个基于overlay的覆盖性网络my-swarm-network

​ docker network create -d overlay –subnet 172.16.0.0/24 my-swarm-network

2.在集群中创建nginx的服务

​ docker service create –network my-swarm-network –name my-web -p 8080:80 –replicas 2 nginx

3.访问192.168.200.191:8080、192.168.200.192:8080、192.168.200.193:8080

​ 集群中任何节点都可以访问到

案例扩展:在集群中部署修改了首页的nginx服务

​ 1.启动容器

​ docker run -itd –name webserver -p 80:80 nginx

​ 2.修改首页

​ 3.容器提交为镜像

​ docker commit webserver mynginx

​ 4.导出镜像为文件 (4-6可以使用私有仓库解决)

​ docker save -o mynginx.tar mynginx

​ 5.拷贝文件到工作节点

​ scp mynginx.tar root@worker1:/root scp mynginx.tar root@worker2:/root

​ 6.导入镜像

​ docker load -i mynginx.tar

​ 7.访问192.168.200.191:8080、192.168.200.192:8080、192.168.200.193:8080

​ 所有节点都可以访问到hello,i am new page

九、docker-compose

​ 有了镜像,就可以通过docker run 启动容器,或者docker service create 创建服务

​ 在微服务架构中,存在问题:涉及的服务数量巨多!

​ docker-compose— 多服务架构的编排工具(解决的是多个服务统一的编排和部署),通过配置文件进行统一的编排 与Dockerfile类似,

Dockerfile 针对的是一个镜像一个容器
docker-compost 针对的是多个镜像多个服务

下载Docker-compose

1
curl -L https://github.com/docker/compose/releases/download/1.24.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

设置docker-compose执行权限:

1
chmod +x docker-compose

卸载docker-compose:

1
rm /usr/local/bin/docker-compose

案例:使用docker-compose部署wordpress服务

1.准备两个镜像

1
2
docker pull mysql:5.7
docker pull wordpress

2.创建一个目录,进入目录,创建一个docker-compose.yml文件

3.编辑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
version: '3'
services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: wordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
ports:
- "8081:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
volumes:
db_data:

4.docker-compose up 启动

​ 查看:docker-compose ps ——列出容器

5.访问 ——宿主机ip:8081

扩展任务:docker-compose在集群上部署wordpress

​ docker stack deploy –compose-file docker-compose.yml stack1 —部署

​ 注意之前的网络xxx-net要删掉,如果某台工作节点无法访问请重启

​ 查看:

​ docker stack ls —查看stack

​ docker stack services stack1 —查看服务

​ docker stack ps stack1 —查看状态

十、docker可视化管理工具

​ 对docker的管理更加直观

​ docker ui —— 本地的图形化管理工具

​ pottainer:需要登录,安全性更好

安装:

1
2
1.docker pull uifd/ui-for-docker	---拉取镜像
2.docker run -d -p 9001:9000 -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer ---启动容器

访问:宿主机ip:9001

十一、Kubernetes简介与安装

介绍:谷歌内部项目borg系统——2015年开源

主要功能:

​ 自我修复——容器崩溃后会自动重启、重建(保活)

​ 弹性伸缩——自动根据需要调整容器的数量(动态扩缩)

​ 服务发现——自动发现所依赖的服务(服务自发现)

​ 负载均衡——多个容器可以平均分配资源(均衡调度)

​ 版本回退——新版本有bug自动退回原版本(智能回滚)

​ 存储编排——根据需求创建存储卷(按需存储)

Kubernetes组件:

控制节点(master) 集群的管理
Apiserver 集群的管理入口
Scheduler 计算资源的调度情况
Controller-manger 负责具体任务的调度
etcd 存储资源对象的信息
工作节点(node) 干活
Kubelet 工作节点上接受任务
docker 负责容器操作
kubeporxy 复杂的服务的对外访问

Kubernetes搭建规划:

​ 两个节点:

​ master 控制节点 ip:192.168.200.210/24
​ node 工作节点 ip:192.168.200.211/24

​ 步骤:

​ 基础环境准备:

​ 1、准备两台虚拟机

​ 2、配置虚拟机的主机名和IP

​ 3、上传k8s.tar文件到/root目录下

​ 4、解压,不要加-z选项 tar xvf K8S.tar

​ 5、删除网络源——463个包

​ cd /etc/yum.repo.d

​ mkdir bak mv C*bak
​ vi local.repo

1
2
3
4
5
[kubernetes]
name=kubernetes
baseurl=file:///root/Kubernetes
gpgcheck=0
enabled=1

​ yum clean all

​ yum repolist

​ yum upgrade -y

​ 6、升级内核

​ 7、配置主机映射

​ 8、配置防火墙及SELinux,重启(再次删除网络源)

​ 9、关闭Swap

sed -i “s//dev/mapper/centos-swap/#/dev/dev/mapper/centos-swap/g” /etc/fstab

​ 10、配置时间同步

1
2
3
4
5
6
7
8
9
10
sed -i 's/^server/#&/' /etc/chrony.conf
cat >>/etc//chrony.conf<<EOF
local stratum 10
server master iburst
allow all
EOF

systemctl enable chronyd && systemctl restart chronyd
timedatectl set-ntp true
chronyc sources

​ 11、配置路由转发

在所有节点执行以下操作:

1
2
3
4
5
6
7
8
cat << EOF | tee /etc/sysctl.d/K8S.conf
net.ipv4.ip_forward=1
net.bridge.bridge-nf-call-ip6ttables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF

modprobe br_netfilter
sysctl -p /etc/sysctl.d/K8S.conf

​ 12、配置IPVS

在所有节点执行以下操作:

1
2
3
4
5
6
7
8
9
10
11
cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
modprobe --ip_vs
modprobe --ip_vs_rr
modprobe --ip_vs_wrr
modprobe --ip_vs_sh
modprobe --nf_conntrack_ipv4
EOF

chmod 755 /etc/sysconfig/modules/ipvs.modules
bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack_ipv4
1
lsmod | grep -e ip_vs -e nf_conntrack_ipv4

yum install -y yum-utils device-mapper-persistent-data lvm2

yum install docker-ce-18.09.6 docker-ce-cli-18.09.6 containerd.io -y

systemctl daemon-reload

systemctl restart docker

systemctl enable docker

​ 13、安装Docker

​ 所有节点安装Docker,启动Docker引擎并设置开机自启。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# yum install -y yum-utils device-mapper-persistent-data lvm2
# yum install docker-ce-18.09.6 docker-ce-cli-18.09.6 containerd.io -y
# mkdir -p /etc/docker
# tee /etc/docker/daemon.json <<-'EOF'
{
"exec-opts": ["native.cgroupdriver=systemd"]
}
EOF
# systemctl daemon-reload
# systemctl restart docker
# systemctl enable docker
# ./kubernetes_base.sh

# docker info |grep Cgroup
Cgroup Driver: system

​ 14、安装Kubernetes集群

​ 所有节点安装Kubernetes工具并启动Kubelet。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
(1)安装工具
# yum install -y kubelet-1.14.1 kubeadm-1.14.1 kubectl-1.14.1
# systemctl enable kubelet && systemctl start kubelet
// 此时启动不成功正常,后面初始化的时候会变成功
(2)初始化Kubernetes集群
登录Master节点,初始化Kubernetes集群。
kubeadm init --apiserver-advertise-address 192.168.200.210 --kubernetes-version="v1.14.1" --pod-network-cidr=10.16.0.0/16 --image-repository=registry.aliyuncs.com/google_containers
///若配置错IP地址需重置 kubeadm 集群配置:kubeadm reset -f

要开始使用集群,您需要以普通用户身份运行以下命令:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
配置Kubernetes网络
kubectl apply -f yaml/kube-flannel.yaml
Node节点加入集群
kubeadm join 192.168.200.210:6443 --token 7dmbm3.xk406p0d3j29yuq5 \
--discovery-token-ca-cert-hash sha256:922f82bff830208eff14f026697414f546c9b7f6586916e7b5fce79f38279021
安装Dashboard :使用kubectl apply命令安装Dashboard
kubectl apply -f yaml/kubernetes-dashboard.yaml
kubectl create -f yaml/dashboard-a dminuser.yaml
检查所有Pod状态
kubectl get pods -n kube-system
输入地址(https://192.168.200.210:30000),即可访问Kubernetes Dashboard
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
登录Kubernetes Dasboard需要输入令牌,通过以下命令获取访问Dashboard的认证令牌
[root@master ~]# kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep kubernetes-dashboard-admin-token | awk '{print $1}')
Name: kubernetes-dashboard-admin-token-x9xc2
Namespace: kube-system
Labels: <none>
Annotations: kubernetes.io/service-account.name: kubernetes-dashboard-admin
kubernetes.io/service-account.uid: ee541c31-3630-11f0-b9da-000c29ee48c5

Type: kubernetes.io/service-account-token

Data
====
namespace: 11 bytes
token: eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJrdWJlcm5ldGVzLWRhc2hib2FyZC1hZG1pbi10b2tlbi14OXhjMiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJrdWJlcm5ldGVzLWRhc2hib2FyZC1hZG1pbiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6ImVlNTQxYzMxLTM2MzAtMTFmMC1iOWRhLTAwMGMyOWVlNDhjNSIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlLXN5c3RlbTprdWJlcm5ldGVzLWRhc2hib2FyZC1hZG1pbiJ9.Oprys3U-tADUp4W73-S4F3toMGcYCkAiTm41TYHcRMutNG1Uln1ojyduQXFuHFPNWDvawPnQE2Z6VPRvDrXTLBdzf_McFG_dO_BNm4r6WDiVT8Kdtj3lMzfVlBpMxv4ONFrud_RrxRZ84QOOXYy3nTbEoZNm_jCsljcEkmA5v9XJeHn0nYi6Tf_BnHzfyitYGFUAAju84H3E6LEK0nwUJWfwGOzED-QUJmS71gGN88bpE5FOlOFI-Ln66Iqhv9UnA5uMXZ_aScrBy27IFQOPuo_C2z2b7eFCbG_r-3TgATN6Frj1EIwhX9WHgzX3STIvWUDBYOTUzpr6OKtK7SZLXg
ca.crt: 1025 bytes

配置Kuboard

1
2
[root@master ~]# kubectl create -f yaml/kuboard.yaml 
在浏览器输入地址http://192.168.200.210:31000,即可进入Kuboard的认证界面,在Token文本框中输入令牌后可进入Kuboard控制台

集群测试:在kubernets部署nginx

kubectl create deploy nginx –image=nginx:1.14-alpine —创建

kubectl get pod —查看

kubectl expose deployment nginx –port=80 –type=NodePort —暴露端口

http://192.168.200.210:31090 / http://192.168.200.211:31090/ 访问

十二、Kubernetes资源管理

​ 在Kubernetes中,一切皆为资源!!

​ 资源:pod(容器跑在pod中)、pod控制器(管理pod,分为不同的类型)、service(提供服务访问)、存储(数据持久化)

​ yaml语言:

​ 类似于xml、json的标记性语言,强调以数据为中心

​ 语法:使用缩进表示层级关系

​ 缩进空格的个数不重要,对其即可表示同一层级

# 表示注释
后面加空格

​ 数据类型:

​ 纯量:不可再分的值(布尔值、整数、浮点数、null、字符串、时间日期······)