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

开始会出现如下错误

1.png

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

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

2.png

禁用基础设施

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

3.png

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

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

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

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

4.png

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

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用户登录

  1. 打开hosts文件 vim /etc/hosts
  2. 输入如下内容

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

配置Master节点

创建工作目录

$ mkdir /home/ghtwf01/working
$ cd /home/ghtwf01/working/

创建kubeadm.conf配置文件

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

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

生成配置文件

kubeadm config print init-defaults ClusterConfiguration > kubeadm.conf
  1. 修改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
  1. 修改kubeadm.conf中的API服务器地址,后面会频繁使用这个地址。
  • localAPIEndpoint:
localAPIEndpoint:
  advertiseAddress: 192.168.117.23
  bindPort: 6443
注意: 192.168.117.23是master主机的ip地址
  1. 配置子网网络
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. 查看一下都需要哪些镜像文件需要拉取
kubeadm config images list --config kubeadm.conf
  1. 拉取镜像
#下载全部当前版本的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启动结果

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

确认外部环境

  1. 确认关闭swap

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

    setenforce 0
  3. 确认关闭防火墙

    ufw disable

配置k8s集群的Node主机环境

  1. 启动k8s后台服务
# 启动kubelet 设置为开机自启动
$ sudo systemctl enable kubelet
# 启动k8s服务程序
$ sudo systemctl start kubelet
  1. 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/
  1. 登录node1终端,创建基础kube配置文件环境
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配置文件环境
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指令
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节点

#将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 
  1. 查看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副本描述文件

5.png

注意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

验证

6.png

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

7.png

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

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

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

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

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

8.png