在学习Kubernetes之前,我们有必要先了解一下Docker。
Docker 是世界领先的软件容器平台。开发人员利用 Docker 可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用 Docker 可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用 Docker 可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为 Linux 和 Windows Server 应用发布新功能。
Docker 属于 Linux 容器的一种封装,提供简单易用的容器使用接口。它是目前最流行的 Linux 容器解决方案。Docker 将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。有了 Docker,就不用担心环境问题。
总体来说,Docker 的接口相当简单,用户可以方便地创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。
Docker 最初是 dotCloud 公司创始人 Solomon Hykes 在法国期间发起的一个公司内部项目,它是基于 dotCloud 公司多年云服务技术的一次革新,并于 2013 年 3 月以 Apache 2.0 授权协议开源,主要项目代码在 GitHub 上进行维护。Docker 项目后来还加入了 Linux 基金会,并成立推动 开放容器联盟(OCI)。
Docker 自开源后受到广泛的关注和讨论,至今其 GitHub 项目已经超过 4 万 6 千个星标和一万多个 fork。甚至由于 Docker 项目的火爆,在 2013 年底,dotCloud 公司决定改名为 Docker。Docker 最初是在 Ubuntu 12.04 上开发实现的;Red Hat 则从 RHEL 6.5 开始对 Docker 进行支持;Google 也在其 PaaS 产品中广泛应用 Docker。
Kubernetes,因为首尾字母中间有8个字符,所以被简写成 K8s。
K8s 是底层资源与容器间的一个抽象层,如果和单机架构类比,可以算作是一个分布式时代的 Linux。
K8s 是 Google 开源的容器集群管理系统。在 Docker 技术的基础上,为容器化的应用提供部署运行、资源调度、服务发现和动态伸缩等一系列完整功能,提高了大规模容器集群管理的便捷性。
K8s 是一个完备的分布式系统支撑平台,具有完备的集群管理能力,多层次的安全防护和准入机制、多租户应用支撑能力、透明的服务注册和发现机制、內建负载均衡器、强大的故障发现和自我修复能力、服务滚动升级和在线扩容能力、可扩展的资源自动调度机制以及多粒度的资源配额管理能力。同时 K8s 提供完善的管理工具,涵盖了包括开发、部署测试、运维监控在内的各个环节。
Kubernetes 特点有:
1.可移植:支持公有云,私有云,混合云;
2.可扩展:模块化,热插拨,可组合;
3.自愈:自动替换,自动重启,自动复制,自动扩展。
K8s 涉及到的基本概念非常多,这里只是简单过一下,不一个一个介绍,详细信息可以直接查文档或 Google。
准备工作
1.所有服务器节点安装docker-ce
这里省略了docker的安装步骤,自行百度,安装结束后,输入docker version,如果出现以下提示说明安装成功。
[root@k8s-master-1 k8s-deploy]# docker version
Client:
Version: 17.03.2-ce
API version: 1.27
Go version: go1.7.5
Git commit: f5ec1e2
Built: Tue Jun 27 02:21:36 2017
OS/Arch: linux/amd64
Server:
Version: 17.03.2-ce
API version: 1.27 (minimum version1.12)
Go version: go1.7.5
Git commit: f5ec1e2
Built: Tue Jun 27 02:21:36 2017
OS/Arch: linux/amd64
Experimental: false
2.所有服务器节点安装kubeadm
首先我们要配置好阿里云的国内源,执行如下命令:
cat < /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
EOF
之后,执行以下命令来重建yum缓存:
yum -y install epel-releaseyum
clean all
yum makecache
接下来需要安装指定版本的Kubeadm(这里要安装指定版本,因为后续依赖的镜像由于有墙无法拉取,这里我们只有指定版本的镜像)
yum -y install kubelet-1.11.0-0
yum -y install kubeadm-1.11.0-0
yum -y install kubectl-1.11.0-0
yum -y install kubernetes-cni
执行命令启动Kubeadm服务并设置为开机启动:
systemctl enable kubelet && systemctl start kubelet
3.配置 Kubeadm 所用到的镜像
因为有墙,我们无法访问到 Google 的镜像库,所以我们需要执行以下脚本来从 Docker Hub 仓库中获取相同的镜像,并且更改 TAG 让其变成与 Google 拉去镜像一致。
新建一个 Shell 脚本,内容如下
#docker.sh
#!/bin/bash
images=(kube-proxy-amd64:v1.11.0 kube-scheduler-amd64:v1.11.0 kube-controller-manager-amd64:v1.11.0 kube-apiserver-amd64:v1.11.0 etcd-amd64:3.2.18 coredns:1.1.3 pause-amd64:3.1 kubernetes-dashboard-amd64:v1.8.3 k8s-dns-sidecar-amd64:1.14.9 k8s-dns-kube-dns-amd64:1.14.9 k8s-dns-dnsmasq-nanny-amd64:1.14.9 )
for imageName in ${images[@]} ;
do
docker pull keveon/$imageNamedocker tag keveon/ i m a g e N a m e k 8 s . g c r . i o / imageName k8s.gcr.io/ imageNamek8s.gcr.io/imageName
docker rmi keveon/$imageName
done
docker tag da86e6ba6ca1 k8s.gcr.io/pause:3.1
保存后使用chmod命令赋予脚本执行权限
chmod 777 ./docker.sh
执行脚本拉取镜像
sh docker.sh
关闭swap
swapoff -a
关闭selinux
sed -i ‘s/SELINUX=permissive/SELINUX=disabled/’ /etc/sysconfig/selinux
#第二条命令
setenforce 0
关闭防火墙
systemctl disable firewalld.service && systemctl stop firewalld.service
配置转发参数
#配置转发相关参数,否则可能会出错
cat < /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
vm.swappiness=0
EOF
#第二条命令
sysctl --system
以上完成了k8s集群部署的准备工作
重启kubeadm
systemctl restart kubelet
master主节点进行以下操作
初始化镜像,执行以下命令:
kubeadm init --kubernetes-version=v1.11.0 #这里是之前所安装K8S的版本号 --pod-network-cidr=10.244.0.0/16 #这里填写集群所在网段(flannel默认支持的网段)
安装结束后,最后一行会出现如下命令
kubeadm join 192.168.10.100:6443 --token t69z6h.lr2etdbg9mfx5r15 --discovery-token-ca-cert-hash sha256:90e3a748c0eb4cb7058f3d0ee8870ee5d746214ab0589b5e841fd5d68fec8f00
证明集群主节点安装成功,这里要记得保存这条命令,以便之后各个节点加入集群
配置kubetl认证信息
export KUBECONFIG=/etc/kubernetes/admin.conf
#持久化可进行以下命令
echo “export KUBECONFIG=/etc/kubernetes/admin.conf” >> ~/.bash_profile
安装flanel网络
依次执行以下命令:
mkdir -p /etc/cni/net.d/
cat < /etc/cni/net.d/10-flannel.conf
{
“name”: “cbr0”,
“type”: “flannel”,
“delegate”: {
“isDefaultGateway”: true
}
}
EOF
mkdir /usr/share/oci-umount/oci-umount.d -p
mkdir /run/flannel/
cat < /run/flannel/subnet.env
FLANNEL_NETWORK=10.244.0.0/16
FLANNEL_SUBNET=10.244.1.0/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=true
EOF
新建一个flannel.yml文件:
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: flannel
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- apiGroups:
- ""
resources:
- nodes
verbs:
- list
- watch
- apiGroups:
- ""
resources:
- nodes/status
verbs:
- patch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: flannel
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: flannel
subjects:
- kind: ServiceAccount
name: flannel
namespace: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: flannel
namespace: kube-system
---
kind: ConfigMap
apiVersion: v1
metadata:
name: kube-flannel-cfg
namespace: kube-system
labels:
tier: node
app: flannel
data:
cni-conf.json: |
{
"name": "cbr0",
"type": "flannel",
"delegate": {
"isDefaultGateway": true
}
}
net-conf.json: |
{
"Network": "10.244.0.0/16", #这里换成集群所在的网段
"Backend": {
"Type": "vxlan"
}
}
---
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: kube-flannel-ds
namespace: kube-system
labels:
tier: node
app: flannel
spec:
template:
metadata:
labels:
tier: node
app: flannel
spec:
hostNetwork: true
nodeSelector:
beta.kubernetes.io/arch: amd64
tolerations:
- key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
serviceAccountName: flannel
initContainers:
- name: install-cni
image: quay.io/coreos/flannel:v0.9.1-amd64
command:
- cp
args:
- -f
- /etc/kube-flannel/cni-conf.json
- /etc/cni/net.d/10-flannel.conf
volumeMounts:
- name: cni
mountPath: /etc/cni/net.d
- name: flannel-cfg
mountPath: /etc/kube-flannel/
containers:
- name: kube-flannel
image: quay.io/coreos/flannel:v0.9.1-amd64
command: [ "/opt/bin/flanneld", "--ip-masq", "--kube-subnet-mgr" ]
securityContext:
privileged: true
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
volumeMounts:
- name: run
mountPath: /run
- name: flannel-cfg
mountPath: /etc/kube-flannel/
volumes:
- name: run
hostPath:
path: /run
- name: cni
hostPath:
path: /etc/cni/net.d
- name: flannel-cfg
configMap:
name: kube-flannel-cfg
执行:
kubectl create -f ./flannel.yml
默认情况下,master节点不参与工作负载,但如果希望安装出一个all-in-one的k8s环境,则可以执行以下命令,让master节点成为一个node节点:
kubectl taint nodes --all node-role.kubernetes.io/master-
执行之后,运行以下命令,查看节点信息:
kubectl get nodes
会看到如下的输出:
NAME STATUS ROLES AGE VERSION
k8s-master-1 Ready master 45d v1.11.0
以上说明k8s集群master几点部署成功
部署节点node
进入节点机器之后,直接执行之前保存好的命令
kubeadm join 192.168.10.100:6443 --token t69z6h.lr2etdbg9mfx5r15 --discovery-token-ca-cert-hash sha256:90e3a748c0eb4cb7058f3d0ee8870ee5d746214ab0589b5e841fd5d68fec8f00
执行完后会看到:
[preflight] running pre-flight checks
[WARNING RequiredIPVSKernelModulesAvailable]: the IPVS proxier will not be used, because the following required kernel modules are not loaded: [ip_vs_wrr ip_vs_sh ip_vs ip_vs_rr] or no builtin kernel ipvs support: map[ip_vs_rr:{} ip_vs_wrr:{} ip_vs_sh:{} nf_conntrack_ipv4:{} ip_vs:{}]
you can solve this problem with following methods:
1. Run 'modprobe -- ' to load missing kernel modules;
2. Provide the missing builtin kernel ipvs support
I0725 09:59:27.929247 10196 kernel_validator.go:81] Validating kernel version
I0725 09:59:27.929356 10196 kernel_validator.go:96] Validating kernel config
[discovery] Trying to connect to API Server "192.168.10.100:6443"
[discovery] Created cluster-info discovery client, requesting info from "https://192.168.10.100:6443"
[discovery] Requesting info from "https://192.168.10.100:6443" again to validate TLS against the pinned public key
[discovery] Cluster info signature and contents are valid and TLS certificate validates against pinned roots, will use API Server "192.168.10.100:6443"
[discovery] Successfully established connection with API Server "192.168.10.100:6443"
[kubelet] Downloading configuration for the kubelet from the "kubelet-config-1.11" ConfigMap in the kube-system namespace
[kubelet] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[preflight] Activating the kubelet service
[tlsbootstrap] Waiting for the kubelet to perform the TLS Bootstrap...
[patchnode] Uploading the CRI Socket information "/var/run/dockershim.sock" to the Node API object "k8s-node1" as an annotation
This node has joined the cluster:
* Certificate signing request was sent to master and a response
was received.
* The Kubelet was informed of the new secure connection details.
Run 'kubectl get nodes' on the master to see this node join the cluster.
说明节点部署成功
到主节点输入如下命令
kubectl get nodes
可以看到如下输出
NAME STATUS ROLES AGE VERSION
k8s-master-1 Ready master 45d v1.11.0
k8s-node-1 Ready < none> 45d v1.11.0
k8s-node-2 Ready < none> 45d v1.11.0
说明k8s集群部署成功
下篇博客将介绍dashboard可视化ui搭建,prometheus监控预警部署,以及如何优雅的部署后端微服务。