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.创建配置文件

1
sudo touch /etc/apt/sources.list.d/kubernetes.list

2.添加写权限

1
sudo chmod 666 /etc/apt/sources.list.d/kubernetes.list

再写入如下内容

1
deb http://mirrors.ustc.edu.cn/kubernetes/apt kubernetes-xenial main

3.执行sudo apt update

开始会出现如下错误

1

签名认证失败,需要重新生成。记住上面的NO_PUBKEYFEEA9169307EA0718B57C5C2836F4BEB

4.添加认证Key

运行如下命令,添加错误中对应的key(错误中NO_PUBKEY后面的key的后8位)

1
2
sudo gpg --keyserver keyserver.ubuntu.com --recv-keys 307EA071
sudo gpg --keyserver keyserver.ubuntu.com --recv-keys 836F4BEB

5.接着运行如下命令,看到OK,说明成功

1
2
sudo gpg --export --armor 307EA071 | sudo apt-key add -
sudo gpg --export --armor 836F4BEB | sudo apt-key add -

6.再次sudo apt update

2

禁用基础设施

1.禁用防火墙

1
sudo ufw disable

2.关闭swap

1
2
3
sudo swapoff -a 
# 永久关闭swap分区
sudo sed -i 's/.*swap.*/#&/' /etc/fstab

3.禁用selinux

1
2
3
4
5
6
7
8
9
# 安装操控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文件

添加内容如下:

1
2
3
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
vm.swappiness = 0

(2) 执行命令使修改生效

1
sudo sysctl -p /etc/sysctl.d/k8s.conf

安装k8s

1.安装Kubernetes 目前安装版本 v1.13.1

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.设置为开机自启

1
2
sudo systemctl enable kubelet && systemctl start kubelet
sudo shutdown -r now

验证k8s

1
2
kubectl get nodes
kubectl version

3

发现出现一行The connection to the server localhost:8080 was refused - did you specify the right host or port?,这个时候仅仅只是k8s安装好了,但是网络环境并没有搭建。

创建企业Kubernetes多主机集群环境

创建两个节点(两个虚拟机)

  1. 在VMWare中创建完整克隆,分别命名为UbuntuNode1UbuntuNode2

4

node配置hostname

分别对两个完整克隆的虚拟机进行如下操作

  1. 使用root用户登录
  2. 打开配置文件vim /etc/cloud/cloud.cfg
  3. 修改配置preserve_hostname: true
  4. 分别修改/etc/hostnamenode1node2,然后shutdown -r now

配置静态ip

  • master

/etc/netplan/50-cloud-init.yaml

1
2
3
4
5
6
7
8
9
10
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配置

1
netplan apply
  • node1

/etc/netplan/50-cloud-init.yaml

1
2
3
4
5
6
7
8
9
10
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配置

1
netplan apply
  • node2

/etc/netplan/50-cloud-init.yaml

1
2
3
4
5
6
7
8
9
10
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配置

1
netplan apply

修改hosts文件

注意: (Master、Node1、Node2都需要配置)

使用root用户登录

  1. 打开hosts文件 vim /etc/hosts

  2. 输入如下内容

    1
    2
    3
    192.168.117.23 master
    192.168.117.24 node1
    192.168.117.25 node2
  3. 重启机器shutdown -r now

配置Master节点

创建工作目录

1
2
$ mkdir /home/ghtwf01/working
$ cd /home/ghtwf01/working/

创建kubeadm.conf配置文件

  1. 创建k8s的管理工具kubeadm对应的配置文件,操作在home/itcast/working/目录下

使用kubeadm配置文件,通过在配置文件中指定docker仓库地址,便于内网快速部署。

生成配置文件

1
kubeadm config print init-defaults ClusterConfiguration > kubeadm.conf
  1. 修改kubeadm.conf 中的如下两项:
  • imageRepository
  • kubernetesVersion
1
2
3
4
5
6
7
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
  1. 修改kubeadm.conf中的API服务器地址,后面会频繁使用这个地址。
  • localAPIEndpoint:
1
2
3
localAPIEndpoint:
advertiseAddress: 192.168.117.23
bindPort: 6443

注意: 192.168.117.23是master主机的ip地址

  1. 配置子网网络
1
2
3
4
5
networking:
dnsDomain: cluster.local
podSubnet: 10.244.0.0/16
serviceSubnet: 10.96.0.0/12
scheduler: {}

这里的10.244.0.0/1610.96.0.0/12分别是k8s内部pods和services的子网网络,最好使用这个地址,后续flannel网络需要用到。

拉取K8s必备的模块镜像

  1. 查看一下都需要哪些镜像文件需要拉取
1
kubeadm config images list --config kubeadm.conf
  1. 拉取镜像
1
2
#下载全部当前版本的k8s所关联的镜像
kubeadm config images pull --config ./kubeadm.conf

初始化kubernetes环境

1
2
#初始化并且启动
sudo kubeadm init --config ./kubeadm.conf

更多kubeadm配置文件参数详见

1
kubeadm config print-defaults

启动成功输出的内容比较多,这里需要记录一下末尾内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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

按照官方提示,执行以下操作。

1
2
3
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

创建系统服务并启动

1
2
3
4
# 启动kubelet 设置为开机自启动
$ sudo systemctl enable kubelet
# 启动k8s服务程序
$ sudo systemctl start kubelet

验证kubernetes启动结果

  1. 验证输入,注意显示master状态是NotReady,证明初始化服务器成功
1
2
3
ghtwf01@master:~$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
master NotReady master 4m2s v1.13.1
  1. 查看当前k8s集群状态
1
2
3
4
5
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网络

1
2
cd $HOME/working
wget https://raw.githubusercontent.com/coreos/flannel/a70459be0084506e4ec919aa1c114638878db11b/Documentation/kube-flannel.yml

编辑这个文件,确保flannel网络是对的,找到 net-conf.json标记的内容是否正确。

1
2
3
4
5
6
net-conf.json: |
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": "vxlan"
}

这个”10.244.0.0/16”和 ./kubeadm.conf中的podsubnet的地址要一致。

应用当前flannel配置文件

1
kubectl apply -f kube-flannel.yml 

输出结果如下

1
2
3
4
5
6
7
8
9
10
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输出结果如下

1
2
3
ghtwf01@master:~$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
master NotReady master 4m2s v1.13.1

安装flannel网络后 执行kubectl get nodes输出结果如下

1
2
3
ghtwf01@master:~/working$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
master Ready master 9m9s v1.13.1

此时master已经是Ready状态了,表示已经配置成功了,那么我们就需要配置node来加入这个集群。

配置Node

确认外部环境

  1. 确认关闭swap

    1
    2
    apt install -y selinux-utils
    swapoff -a
  2. 禁止selinux

    1
    setenforce 0
  3. 确认关闭防火墙

    1
    ufw disable

配置k8s集群的Node主机环境

  1. 启动k8s后台服务
1
2
3
4
# 启动kubelet 设置为开机自启动
$ sudo systemctl enable kubelet
# 启动k8s服务程序
$ sudo systemctl start kubelet
  1. master机器的/etc/kubernetes/admin.conf传到到node1和node2

登录master终端

1
2
3
4
#将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/
  1. 登录node1终端,创建基础kube配置文件环境
1
2
3
mkdir -p $HOME/.kube
sudo cp -i $HOME/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
  1. 登录node2终端,创建基础kube配置文件环境
1
2
3
mkdir -p $HOME/.kube
sudo cp -i $HOME/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
  1. node1node2分别连接master加入master集群。这里用的是kubeadm join指令
1
sudo kubeadm join 192.168.117.23:6443 --token abcdef.0123456789abcdef --discovery-token-ca-cert-hash sha256:9f1cbfb01e584e1b5eaf63a12aec28d71561f3f46f5770139119bf6545a8265e

这里要注意,使用的hash应该是master主机 kubeadm init成功之后生成的hash码。

  1. 两个node主机分别应用flannel网络

master中的kube-flannel.yml分别传递给两个node节点

1
2
3
4
#将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网络

1
kubectl apply -f kube-flannel.yml 
  1. 查看node是否已经加入到k8s集群中(需要等一段时间才能ready)
1
2
3
4
5
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实例

定义描述文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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集群中。

1
kubectl create -f mysql-rc.yaml

查看Mysql实例集群状态

1
2
3
ghtwf01@master:~$ kubectl get pods
NAME READY STATUS RESTARTS AGE
mysql-jjbjc 0/1 ContainerCreating 0 22s

如果为Running状态,则为mysql集群启动成功。

创建Tomcat实例

定义描述文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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副本描述文件

5

注意mysql实例 状态 Running

myweb实例状态 ContainerCreating

过几分钟myweb实例状态变成 Running

创建服务副本

1
2
3
4
5
6
7
8
9
10
11
apiVersion: v1
kind: Service
metadata:
name: myweb
spec:
type: NodePort
ports:
- port: 8080
nodePort: 30001
selector:
app: myweb

部署服务

1
kubectl create -f myweb-svc.yaml

验证

6

已经看到已经有一个myweb服务已经启动

7

这里的IP就是CLUSTER-IP. CLUSTER-IP是和service绑定的。

这里的Port就是Service的端口号。

这里的NodePort就是Node的真实端口号。

这里的Endpoints就是容器的IP和port。

我们可以打开浏览器,输入master/node1/node2任何一个地址家30001端口都可以,访问tomcat服务。

8