Kubernetes是什么
Kubernetes(K8s)是Google在2014年发布的一个开源项⽬,在Google的数据中心里运行着20多亿个容器,而Google十多年前就开始使用容器技术。最初,Google开发了一个叫Borg的系统(现在命名为Omega)来调度如此庞大数量多容器和工作负载。在积累了多年经验后,Google决定重写这个容器管理系统,并将其贡献到开源社区,这个项目就是Kubernetes。
Kubernetes环境搭建
操作系统:Ubuntu 18.10 Server
Docker:docker-ce 18.06
Kubernetes:Kubernetes 1.13.1
Kubernetes安装及部署
k8s安装环境准备
配置并安装k8s国内源
1.创建配置文件
sudo touch /etc/apt/sources.list.d/kubernetes.list
2.添加写权限
sudo chmod 666 /etc/apt/sources.list.d/kubernetes.list
再写入如下内容
deb http://mirrors.ustc.edu.cn/kubernetes/apt kubernetes-xenial main
3.执行sudo apt update
开始会出现如下错误
签名认证失败,需要重新生成。记住上面的NO_PUBKEYFEEA9169307EA071
和8B57C5C2836F4BEB
4.添加认证Key
运行如下命令,添加错误中对应的key(错误中NO_PUBKEY后面的key的后8位)
sudo gpg --keyserver keyserver.ubuntu.com --recv-keys 307EA071
sudo gpg --keyserver keyserver.ubuntu.com --recv-keys 836F4BEB
5.接着运行如下命令,看到OK,说明成功
sudo gpg --export --armor 307EA071 | sudo apt-key add -
sudo gpg --export --armor 836F4BEB | sudo apt-key add -
6.再次sudo apt update
禁用基础设施
1.禁用防火墙
sudo ufw disable
2.关闭swap
sudo swapoff -a
# 永久关闭swap分区
sudo sed -i 's/.*swap.*/#&/' /etc/fstab
3.禁用selinux
# 安装操控selinux的命令
$ sudo apt install -y selinux-utils
# 禁止selinux
$ setenforce 0
# 重启操作系统
$ shutdown -r now
# 查看selinux是否已经关闭
$ sudo getenforce
Disabled(表示已经关闭)
k8s系统网络配置
(1) 配置内核参数,将桥接的IPv4流量传递到iptables的链
创建/etc/sysctl.d/k8s.conf
文件
添加内容如下:
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
vm.swappiness = 0
(2) 执行命令使修改生效
sudo sysctl -p /etc/sysctl.d/k8s.conf
安装k8s
1.安装Kubernetes 目前安装版本 v1.13.1
sudo apt update && sudo apt-get install -y kubelet=1.13.1-00 kubernetes-cni=0.6.0-00 kubeadm=1.13.1-00 kubectl=1.13.1-00
2.设置为开机自启
sudo systemctl enable kubelet && systemctl start kubelet
sudo shutdown -r now
验证k8s
kubectl get nodes
kubectl version
发现出现一行The connection to the server localhost:8080 was refused - did you specify the right host or port?
,这个时候仅仅只是k8s安装好了,但是网络环境并没有搭建。
创建企业Kubernetes多主机集群环境
创建两个节点(两个虚拟机)
- 在VMWare中创建完整克隆,分别命名为
UbuntuNode1
和UbuntuNode2
给node配置hostname
分别对两个完整克隆的虚拟机进行如下操作
- 使用root用户登录
- 打开配置文件
vim /etc/cloud/cloud.cfg
- 修改配置
preserve_hostname: true
- 分别修改
/etc/hostname
为node1
和node2
,然后shutdown -r now
配置静态ip
- master
/etc/netplan/50-cloud-init.yaml
network:
ethernets:
ens33:
addresses: [192.168.117.23/24]
dhcp4: false
gateway4: 192.168.117.1
nameservers:
addresses: [192.168.117.1]
optional: true
version: 2
重启ip配置
netplan apply
- node1
/etc/netplan/50-cloud-init.yaml
network:
ethernets:
ens33:
addresses: [192.168.117.24/24]
dhcp4: false
gateway4: 192.168.117.1
nameservers:
addresses: [192.168.117.1]
optional: true
version: 2
重启ip配置
netplan apply
- node2
/etc/netplan/50-cloud-init.yaml
network:
ethernets:
ens33:
addresses: [192.168.117.25/24]
dhcp4: false
gateway4: 192.168.117.1
nameservers:
addresses: [192.168.117.1]
optional: true
version: 2
重启ip配置
netplan apply
修改hosts文件
注意: (Master、Node1、Node2都需要配置)
使用root用户登录
- 打开hosts文件
vim /etc/hosts
输入如下内容
192.168.117.23 master 192.168.117.24 node1 192.168.117.25 node2
- 重启机器
shutdown -r now
配置Master节点
创建工作目录
$ mkdir /home/ghtwf01/working
$ cd /home/ghtwf01/working/
创建kubeadm.conf配置文件
- 创建k8s的管理工具
kubeadm
对应的配置文件,操作在home/itcast/working/
目录下
使用kubeadm
配置文件,通过在配置文件中指定docker仓库地址,便于内网快速部署。
生成配置文件
kubeadm config print init-defaults ClusterConfiguration > kubeadm.conf
- 修改
kubeadm.conf
中的如下两项:
- imageRepository
- kubernetesVersion
vi kubeadm.conf
# 修改 imageRepository: k8s.gcr.io
# 改为 registry.cn-beijing.aliyuncs.com/imcto
imageRepository: registry.cn-beijing.aliyuncs.com/imcto
# 修改kubernetes版本kubernetesVersion: v1.13.0
# 改为kubernetesVersion: v1.13.1
kubernetesVersion: v1.13.1
- 修改
kubeadm.conf
中的API服务器地址,后面会频繁使用这个地址。
- localAPIEndpoint:
localAPIEndpoint:
advertiseAddress: 192.168.117.23
bindPort: 6443
注意: 192.168.117.23
是master主机的ip地址
- 配置子网网络
networking:
dnsDomain: cluster.local
podSubnet: 10.244.0.0/16
serviceSubnet: 10.96.0.0/12
scheduler: {}
这里的10.244.0.0/16
和 10.96.0.0/12
分别是k8s内部pods和services的子网网络,最好使用这个地址,后续flannel网络需要用到。
拉取K8s必备的模块镜像
- 查看一下都需要哪些镜像文件需要拉取
kubeadm config images list --config kubeadm.conf
- 拉取镜像
#下载全部当前版本的k8s所关联的镜像
kubeadm config images pull --config ./kubeadm.conf
初始化kubernetes环境
#初始化并且启动
sudo kubeadm init --config ./kubeadm.conf
更多kubeadm配置文件参数详见
kubeadm config print-defaults
启动成功输出的内容比较多,这里需要记录一下末尾内容
Your Kubernetes master has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
You can now join any number of machines by running the following on each node
as root:
kubeadm join 192.168.117.23:6443 --token abcdef.0123456789abcdef --discovery-token-ca-cert-hash sha256:9f1cbfb01e584e1b5eaf63a12aec28d71561f3f46f5770139119bf6545a8265e
按照官方提示,执行以下操作。
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
创建系统服务并启动
# 启动kubelet 设置为开机自启动
$ sudo systemctl enable kubelet
# 启动k8s服务程序
$ sudo systemctl start kubelet
验证kubernetes启动结果
- 验证输入,注意显示master状态是
NotReady
,证明初始化服务器成功
ghtwf01@master:~$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
master NotReady master 4m2s v1.13.1
- 查看当前k8s集群状态
ghtwf01@master:~$ kubectl get cs
NAME STATUS MESSAGE ERROR
scheduler Healthy ok
controller-manager Healthy ok
etcd-0 Healthy {"health": "true"}
目前只有一个master,还没有node,而且是NotReady状态,那么我们需要将node加入到master管理的集群中来。在加入之前,我们需要先配置k8s集群的内部通信网络,这里采用的是flannel网络。
部署集群内部通信flannel网络
cd $HOME/working
wget https://raw.githubusercontent.com/coreos/flannel/a70459be0084506e4ec919aa1c114638878db11b/Documentation/kube-flannel.yml
编辑这个文件,确保flannel网络是对的,找到 net-conf.json
标记的内容是否正确。
net-conf.json: |
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": "vxlan"
}
这个"10.244.0.0/16"和 ./kubeadm.conf中的podsubnet的地址要一致。
应用当前flannel配置文件
kubectl apply -f kube-flannel.yml
输出结果如下
ghtwf01@master:~/working$ kubectl apply -f kube-flannel.yml
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
serviceaccount/flannel created
configmap/kube-flannel-cfg created
daemonset.extensions/kube-flannel-ds-amd64 created
daemonset.extensions/kube-flannel-ds-arm64 created
daemonset.extensions/kube-flannel-ds-arm created
daemonset.extensions/kube-flannel-ds-ppc64le created
daemonset.extensions/kube-flannel-ds-s390x created
安装flannel网络前 执行kubectl get nodes
输出结果如下
ghtwf01@master:~$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
master NotReady master 4m2s v1.13.1
安装flannel网络后 执行kubectl get nodes
输出结果如下
ghtwf01@master:~/working$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
master Ready master 9m9s v1.13.1
此时master已经是Ready
状态了,表示已经配置成功了,那么我们就需要配置node来加入这个集群。
配置Node
确认外部环境
确认关闭swap
apt install -y selinux-utils swapoff -a
禁止selinux
setenforce 0
确认关闭防火墙
ufw disable
配置k8s集群的Node主机环境
- 启动k8s后台服务
# 启动kubelet 设置为开机自启动
$ sudo systemctl enable kubelet
# 启动k8s服务程序
$ sudo systemctl start kubelet
- 将
master
机器的/etc/kubernetes/admin.conf
传到到node1和node2
登录master
终端
#将admin.conf传递给node1
sudo scp /etc/kubernetes/admin.conf ghtwf01@192.168.117.24:/home/ghtwf01/
#将admin.conf传递给node2
sudo scp /etc/kubernetes/admin.conf ghtwf01@192.168.117.25:/home/ghtwf01/
- 登录
node1
终端,创建基础kube配置文件环境
mkdir -p $HOME/.kube
sudo cp -i $HOME/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
- 登录
node2
终端,创建基础kube配置文件环境
mkdir -p $HOME/.kube
sudo cp -i $HOME/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
node1
和node2
分别连接master
加入master集群。这里用的是kubeadm join
指令
sudo kubeadm join 192.168.117.23:6443 --token abcdef.0123456789abcdef --discovery-token-ca-cert-hash sha256:9f1cbfb01e584e1b5eaf63a12aec28d71561f3f46f5770139119bf6545a8265e
这里要注意,使用的hash应该是master
主机 kubeadm init
成功之后生成的hash码。
- 两个node主机分别应用flannel网络
将master
中的kube-flannel.yml
分别传递给两个node
节点
#将kube-flannel.yml传递给node1
sudo scp $HOME/working/kube-flannel.yml ghtwf01@192.168.117.24:/home/ghtwf01/
#将kube-flannel.yml传递给node2
sudo scp $HOME/working/kube-flannel.yml ghtwf01@192.168.117.25:/home/ghtwf01/
分别启动flannel
网络
kubectl apply -f kube-flannel.yml
- 查看node是否已经加入到k8s集群中(需要等一段时间才能ready)
ghtwf01@master:~$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
master Ready master 23m v1.13.1
node1 Ready <none> 3m37s v1.13.1
node2 Ready <none> 3m33s v1.13.1
应用实例
创建Mysql实例
定义描述文件
apiVersion: v1
kind: ReplicationController #副本控制器RC
metadata:
name: mysql #RC的名称,全局唯一
spec:
replicas: 1 #Pod副本的期待数量
selector:
app: mysql #符合目标的Pod拥有此标签
template: #根据此模板创建Pod的副本(实例)
metadata:
labels:
app: mysql #Pod副本拥有的标签,对应RC的Selector
spec:
containers: #Pod内容器的定义部分
- name: mysql #容器的名称
image: hub.c.163.com/library/mysql #容器对应的Docker image
ports:
- containerPort: 3306 #容器应用监听的端口号
env: #注入容器内的环境变量
- name: MYSQL_ROOT_PASSWORD
value: "123456"
加载ReplicationController副本控制器描述文件
创建好mysql-rc.yaml后,在master节点使用kubectl命令将它发布到k8s集群中。
kubectl create -f mysql-rc.yaml
查看Mysql实例集群状态
ghtwf01@master:~$ kubectl get pods
NAME READY STATUS RESTARTS AGE
mysql-jjbjc 0/1 ContainerCreating 0 22s
如果为Running
状态,则为mysql集群启动成功。
创建Tomcat实例
定义描述文件
apiVersion: v1
kind: ReplicationController
metadata:
name: myweb
spec:
replicas: 5 #Pod副本期待数量为5
selector:
app: myweb
template:
metadata:
labels:
app: myweb
spec:
containers:
- name: myweb
image: docker.io/kubeguide/tomcat-app:v1
ports:
- containerPort: 8080
env:
- name: MYSQL_SERVICE_HOST
value: "mysql"
- name: MYSQL_SERVICE_PORT
value: "3306"
加载RC副本描述文件
注意mysql实例 状态 Running
myweb实例状态 ContainerCreating
过几分钟myweb实例状态变成 Running
创建服务副本
apiVersion: v1
kind: Service
metadata:
name: myweb
spec:
type: NodePort
ports:
- port: 8080
nodePort: 30001
selector:
app: myweb
部署服务
kubectl create -f myweb-svc.yaml
验证
已经看到已经有一个myweb
服务已经启动
这里的IP就是CLUSTER-IP. CLUSTER-IP是和service绑定的。
这里的Port就是Service的端口号。
这里的NodePort就是Node的真实端口号。
这里的Endpoints就是容器的IP和port。
我们可以打开浏览器,输入master/node1/node2任何一个地址家30001端口都可以,访问tomcat服务。