前言
昨天有一位搞 DBA 同学问我会不会用 Docker。Ta 想要在上面跑一个 Oracle 实例。整个过程非常流畅,写篇文章备用。 :)
前言
昨天有一位搞 DBA 同学问我会不会用 Docker。Ta 想要在上面跑一个 Oracle 实例。整个过程非常流畅,写篇文章备用。 :)
当你最后投入容器的怀抱,发现它能解决很多问题,而且还具有众多的优点:
第一:它是不可变的 – 操作系统,库版本,配置,文件夹和应用都是一样的。您可以使用通过相同QA测试的镜像,使产品具有相同的表现。
第二:它是轻量级的 – 容器的内存占用非常小。不需要几百几千MB,它只要对主进程分配内存再加上几十MB。
第三:它很快速 – 启动一个容器与启动一个单进程一样快。不需要几分钟,您可以在几秒钟内启动一个全新的容器。
但是,许多用户依然像对待典型的虚拟机那样对待容器。但是他们都忘记了除了与虚拟机相似的部分,容器还有一个很大的优点:它是一次性的。
容器的 准则 :
“容器是临时的”。
这个特性“本身”促使用户改变他们关于使用和管理容器的习惯;我将会向您解释在容器中不应该做这些事,以确保最大地发挥容器的作用。
1. 不要在容器中存储数据 – 容器可能被停止,销毁,或替换。一个运行在容器中的程序版本1.0,应该很容易被1.1的版本替换且不影响或损失数据。有鉴于此,如果你需要存储数据,请存在卷中,并且注意如果两个容器在同一个卷上写数据会导致崩溃。确保你的应用被设计成在共享数据存储上写入。
2. 不要将你的应用发布两份 – 一些人将容器视为虚拟机。他们中的大多数倾向于认为他们应该在现有的运行容器里发布自己的应用。在开发阶段这样是对的,此时你需要不断地部署与调试;但对于质量保证与生产中的一个连续部署的管道,你的应用本该成为镜像的一部分。记住:容器应该保持不变。
3. 不要创建超大镜像 – 一个超大镜像只会难以分发。确保你仅有运行你应用/进程的必需的文件和库。不要安装不必要的包或在创建中运行更新(yum更新)。
4. 不要使用单层镜像 – 要对分层文件系统有更合理的使用,始终为你的操作系统创建你自己的基础镜像层,另外一层为安全和用户定义,一层为库的安装,一层为配置,最后一层为应用。这将易于重建和管理一个镜像,也易于分发。
5. 不要为运行中的容器创建镜像 – 换言之,不要使用“docker commit”命令来创建镜像。这种创建镜像的方法是不可重现的也不能版本化,应该彻底避免。始终使用Dockerfile或任何其他的可完全重现的S2I(源至镜像)方法。
6. 不要只使用“最新”标签 – 最新标签就像Maven用户的“快照”。标签是被鼓励使用的,尤其是当你有一个分层的文件系统。你总不希望当你2个月之后创建镜像时,惊讶地发现你的应用 无法运行,因为最顶的分层被非向后兼容的新版本替换,或者创建缓存中有一个错误的“最新”版本。在生产中部署容器时应避免使用最新。
7. 不要在单一容器中运行超过一个进程 – 容器能完美地运行单个进程(http守护进程,应用服务器,数据库),但是如果你不止有一个进程,管理、获取日志、独立更新都会遇到麻烦。
8. 不要在镜像中存储凭据。使用环境变量 –不要将镜像中的任何用户名/密码写死。使用环境变量来从容器外部获取此信息。有一个不错的例子是postgres镜像。
9. 使用非root用户运行进程 – “docker容器默认以root运行。(…)随着docker的成熟,更多的安全默认选项变得可用。现如今,请求root对于其他人是危险的,可能无法在所有环境中可用。你的镜像应该使用USER指令来指令容器的一个非root用户来运行。”(来自 Docker镜像作者指南)
10. 不要依赖IP地址 – 每个容器都有自己的内部IP地址,如果你启动并停止它地址可能会变化。如果你的应用或微服务需要与其他容器通讯,使用任何命名与(或者)环境变量来从一个容器传递合适信息到另一个。
环境介绍
操作系统: CentOS Linux release 7.3.1611 (Core)
Kubernetes 版本: 1.5.2
Etcd 版本: 3.2.7
Docker 版本: 1.12.6
Flannel 版本: 0.7.1
主机信息
Role service Hostname IP Address
Master kube-APIServer kubelet proxy etcd k8s-master.suzf.net 172.16.9.50
Node1 kubelet proxy flannel docker k8s-node1.suzf.net 172.16.9.60
Node2 kubelet proxy flannel docker k8s-node2.suzf.net 172.16.9.70
准备工作
关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
关闭selinux
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
setenforce 0
Master 安装与配置
Etcd 安装与配置
yum install etcd -y
PS: 本文并没有搭建etcd集群,如果需要参见官方搭建etcd集群的指导教程。
yum安装的etcd默认配置文件在/etc/etcd/etcd.conf。
编辑配置文件
# grep -v ^# /etc/etcd/etcd.conf
ETCD_NAME=k8s
ETCD_DATA_DIR="/var/lib/etcd/k8s.etcd"
ETCD_LISTEN_PEER_URLS="http://172.16.9.50:2380"
ETCD_LISTEN_CLIENT_URLS="http://172.16.9.50:4001,http://localhost:4001"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://172.16.9.50:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://172.16.9.50:4001"
启动 etcd 服务
# systemctl start etcd.service
查看健康状态
# etcdctl cluster-health
member 9026e369ffe8e114 is healthy: got healthy result from http://172.16.9.50:4001
cluster is healthy
查看成员列表
# etcdctl member list
9026e369ffe8e114: name=k8s peerURLs=http://172.16.9.50:2380 clientURLs=http://172.16.9.50:4001 isLeader=true
Kube Master 安装与配置
yum install kubernetes -y
修改Master节点kubernetes的全局配置文件 /etc/kubernetes/config
# grep -v '^#\|^$' /etc/kubernetes/config
KUBE_LOGTOSTDERR="--logtostderr=true"
KUBE_LOG_LEVEL="--v=2"
KUBE_ALLOW_PRIV="--allow-privileged=false"
KUBE_MASTER="--master=http://127.0.0.1:8080"
修改Master节点kubernetes apiserver的配置文件 /etc/kubernetes/apiserver
# grep -v '^#\|^$' /etc/kubernetes/config
KUBE_LOGTOSTDERR="--logtostderr=true"
KUBE_LOG_LEVEL="--v=2"
KUBE_ALLOW_PRIV="--allow-privileged=false"
KUBE_MASTER="--master=http://127.0.0.1:8080"
[root@monkey ~]# grep -v '^#\|^$' /etc/kubernetes/apiserver
KUBE_API_ADDRESS="--insecure-bind-address=0.0.0.0"
KUBE_API_PORT="--port=8080"
KUBELET_PORT="--kubelet-port=10250"
KUBE_ETCD_SERVERS="--etcd-servers=http://172.16.9.50:4001"
KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=192.168.0.0/16"
KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota"
启动Master节点的相关服务:etcd、kube-apiserver、kube-scheduler、kube-controller-manager,并将这些服务设为开机自动启动。
for SRV in etcd kube-apiserver kube-scheduler kube-controller-manager;
do
sudo systemctl start ${SRV}
sudo systemctl enable ${SRV}
sudo systemctl status ${SRV}
done
在Master节点修改etcd的配置,设定Node中flannel所使用的子网范围为192.168.1.0 ~ 192.168.60.0(每一个Node节点都有一个独立的flannel子网)。
# etcdctl mk /suzf.net/network/config '{"Network":"192.168.0.0/16", "SubnetMin": "192.168.1.0", "SubnetMax": "192.168.60.0"}'
{"Network":"192.168.0.0/16", "SubnetMin": "192.168.1.0", "SubnetMax": "192.168.60.0"}
Node 安装与配置
yum install kubernetes-node docker flannel -y
修改Node上flannel的配置/etc/sysconfig/flanneld,设定etcd的相关信息,其中172.16.9.50 为master的IP地址。
Flannel 网络配置
# grep -v '^#\|^$' /etc/sysconfig/flanneld
FLANNEL_ETCD_ENDPOINTS="http://172.16.9.50:4001"
FLANNEL_ETCD_PREFIX="/suzf.net/network"
Kube node 配置
# grep -v '^#\|^$' /etc/kubernetes/config
KUBE_LOGTOSTDERR="--logtostderr=true"
KUBE_LOG_LEVEL="--v=0"
KUBE_ALLOW_PRIV="--allow-privileged=false"
KUBE_MASTER="--master=http://172.16.9.50:8080"
# grep -v '^#\|^$' /etc/kubernetes/kubelet
KUBELET_ADDRESS="--address=0.0.0.0"
KUBELET_PORT="--port=10250"
KUBELET_HOSTNAME=""
KUBELET_API_SERVER="--api-servers=http://172.16.9.50:8080"
KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=registry.access.redhat.com/rhel7/pod-infrastructure:latest"
KUBELET_ARGS=""
在Node上启动相关服务:flanneld、docker、kube-proxy、kubelet,并将这些服务设为开机自启动
for SRV in flanneld docker kube-proxy kubelet;
do
sudo systemctl start ${SRV}
sudo systemctl enable ${SRV}
sudo systemctl status ${SRV}
done
在Master节点查看k8s集群状态
# kubectl get nodes -o wide
NAME STATUS AGE EXTERNAL-IP
horse.suzf.net Ready 6d <none>
zebra Ready 7m <none>
查看flannel子网分配情况
# etcdctl ls /suzf.net/network/subnets
/suzf.net/network/subnets/192.168.53.0-24
/suzf.net/network/subnets/192.168.42.0-24
在Node节点通过ip a查看flannel和docker网桥的网络配置信息,确认是否与etcd中/coreos.com/network/subnets的信息一致。
Together we will ensure that Kubernetes is a strong and open container management framework for any application and in any environment, whether in a private, public or hybrid cloud. --Urs Hölzle, GoogleKubernetes 作为Docker生态圈中重要一员,是Google多年大规模容器管理技术的开源版本,是产线实践经验的最佳表现。如Urs Hölzle所说,无论是公有云还是私有云甚至混合云,Kubernetes将作为一个为任何应用,任何环境的容器管理框架无处不在。正因为如此,目前受 到各大巨头及初创公司的青睐,如Microsoft、VMWare、Red Hat、CoreOS、Mesos等,纷纷加入给Kubernetes贡献代码。随着Kubernetes社区及各大厂商的不断改进、发 展,Kuberentes将成为容器管理领域的领导者。 接下来我们一起探索Kubernetes是什么、能做什么以及怎么做。