Kubernetes实践一(安装篇)

网上有很多在Ubuntu上使用KubeAdm来安装Kubernetes的文章,但很多的都因为Kubernetes版本的升级导致过时了,但大部分步骤都是大同小异,我也把自己在安装kubernetes中的步骤记录下来,安装过程中遇到了些问题,通过google也都能找到解决方法。主要是需要配置国内镜像,我选择的是aliyun的kubernetes镜像。

安装环境

  • 操作系统:Ubuntu 18.04.3 LTS
  • Docker版本:18.09.7
  • Kubenetes版本:v1.21.0
  • KubeAdm版本:v1.21

集群环境

  • 一个master节点,机器名master-node,只充当master角色
  • 一个worker节点,机器名work01

什么是KubeAdm

kubeadm 是一个工具包,可帮助您以简单,合理安全和可扩展的方式引导最佳实践Kubernetes群集。它还支持为您管理[Bootstrap Tokens并升级/降级群集。kubeadm的目标是建立一个通过Kubernetes一致性测试Kubernetes Conformance tests的最小可行集群 ,但不会安装其他功能插件,比如Kubernetes Dashboard, 监控方案,以及特定云平台的扩展都不属于KebuAdm的范畴。Kubeadm 提供了 kubeadm init 和 kubeadm join 的工具,作为创建 Kubernetes 集群的 “快捷途径” 的最佳实践。

安装步骤

Docker安装

在master和所有的node节点上都需要安装

第一步,更新系统软件包
sudo apt-get update
第二步,安装Docker
sudo apt-get install docker.io
第三步,验证安装
docker ––version
第四步,开机启动Docker
sudo systemctl enable docker
第五步,检查Docker状态
sudo systemctl status docker
第六步,启动Docker

如果Docker没有启动,运行下面的命令启动Docker

sudo systemctl start docker
第四步(可选)

网上说docker hub国内网络访问有问题,因此需要配置切换docker下载源为国内镜像站,由于我的环境访问外网无障碍,因此没有配置这一步也不影响后面的功能。如果有网络问题,需要编辑/etc/docker/daemon.json文件添加国内镜像。另外,有提到需要修改cgroups为systemd,这一步我也没有修改,后续功能也正常,所以这一步我没有验证。编辑daemon.json文件

sudo vi /etc/docker/daemon.json

添加如下国内镜像和修改cgroup

{
  "registry-mirrors": [
    "https://dockerhub.azk8s.cn",
    "https://reg-mirror.qiniu.com",
    "https://quay-mirror.qiniu.com"
  ],
  "exec-opts": [ "native.cgroupdriver=systemd" ]
}

在每个工作节点上重复上述步骤

安装kubeadm, kubelet, kubectl

在master和所有的node节点上都需要安装
关于kubelet和kubectl的作用,学习过k8s的同学应该都已经接触过。

  • kubelet,kubelet 的主要功能就是定时从某个地方获取节点上 pod/container 的期望状态(运行什么容器、运行的副本数量、网络或者存储如何配置等等),并调用对应的容器平台接口达到这个状态。kubelet也负责容器的健康检测,如果容器运行出错,就要根据设置的重启策略进行处理。kubelet 还需要监控所在节点的资源使用情况,并定时向 master 报告。kubelet 使用 [cAdvisor]进行资源使用率的监控。
  • kubectl,k8s 的命令行工具,是与API Server交互的工具。
第一步,安装apt-transport-https
apt-get update && apt-get install -y apt-transport-https
第二步,下载 gpg 密钥
curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
第三步,添加 k8s 阿里镜像源
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF
第四步,更新源列表
apt-get update
第五步,下载 kubectl,kubeadm以及 kubelet
apt-get install -y kubelet kubeadm kubectl

这一步需要花很长时间,依赖于你的网络环境。

第六步,检查版本
kubeadm version

在每个工作节点上重复上述步骤

配置部署环境

关闭 swap 内存

这个swap其实可以类比成 windows 上的虚拟内存,它可以让服务器在内存吃满的情况下可以保持低效运行,而不是直接卡死。但是 k8s 的较新版本都要求关闭swap。所以咱们直接动手,修改/etc/fstab文件:

sudo vi /etc/fstab

在我机器上的内容如下,

UUID=28f0aada-c587-430c-a4fc-81bd8a78f596 / ext4 defaults 0 0
/swap.img       none    swap    sw      0       0
/dev/sdb1 /var/lib/docker ext4 defaults 0 2

将第三行/dev/sdb1 /var/lib/docker ext4 defaults 0 2注释即可。也可以临时关闭swap,但机器重启后就会出错。临时关闭命令,

sudo swapoff –a
修改机器名

为了使得集群名字易读和以后便于维护,建议为机器设置合理的机器名。我使用下面的命令分别为master节点和worker节点命名。
在master机器上运行以下命令:

sudo hostnamectl set-hostname master-node

在worker机器上运行以下命令:

sudo hostnamectl set-hostname worker01

初始化master节点

这一步只需要在master节点上运行

运行初始化命令

sudo kubeadm init --pod-network-cidr=10.244.0.0/16

这个是 k8s 采用的节点网络,因为我们将要使用flannel作为 k8s 的网络,所以这里填10.244.0.0/16就好。此外我们可以使用--kubernetes-version这个参数来指定要部署的 k8s 版本的,一般不用填,会使用最新的版本。这一步也会花费比较长时间,它的主要完成的工作包括:

Preflight检查

Preflight检查确定这台机器可以用来部署 Kubernetes。这一步检查,包括:

  • Linux 内核的版本必须是否是 3.10 以上?
  • Linux Cgroups 模块是否可用?
  • 机器的 hostname 是否标准?在 Kubernetes 项目里,机器的名字以及一切存储在 Etcd 中的 API 对象,都必须使用标准的 DNS 命名(RFC 1123)。
  • 用户安装的 kubeadm 和 kubelet 的版本是否匹配?
  • 机器上是不是已经安装了 Kubernetes 的二进制文件?
  • Kubernetes 的工作端口 10250/10251/10252 端口是不是已经被占用?
  • ip、mount 等 Linux 指令是否存在?
  • Docker 是否已经安装?
生成各种证书

在通过了 Preflight Checks 之后,kubeadm 要为你做的,是生成 Kubernetes 对外提供服务所需的各种证书和对应的目录。Kubernetes 对外提供服务时,除非专门开启“不安全模式”,否则都要通过 HTTPS 才能访问 kube-apiserver。这就需要为 Kubernetes 集群配置好证书文件。
kubeadm 为 Kubernetes 项目生成的证书文件都放在 Master 节点的 /etc/kubernetes/pki 目录下。在这个目录下,最主要的证书文件是 ca.crt 和对应的私钥 ca.key。此外,用户使用 kubectl 获取容器日志等 streaming 操作时,需要通过 kube-apiserver 向 kubelet 发起请求,这个连接也必须是安全的。kubeadm 为这一步生成的是 apiserver-kubelet-client.crt 文件,对应的私钥是 apiserver-kubelet-client.key。我机器下生成的证书文件如下:

total 68
drwxr-xr-x 3 root root 4096 May  8 06:09 .
drwxr-xr-x 4 root root 4096 May  8 06:09 ..
-rw-r--r-- 1 root root 1289 May  8 06:09 apiserver.crt
-rw-r--r-- 1 root root 1155 May  8 06:09 apiserver-etcd-client.crt
-rw------- 1 root root 1675 May  8 06:09 apiserver-etcd-client.key
-rw------- 1 root root 1679 May  8 06:09 apiserver.key
-rw-r--r-- 1 root root 1164 May  8 06:09 apiserver-kubelet-client.crt
-rw------- 1 root root 1679 May  8 06:09 apiserver-kubelet-client.key
-rw-r--r-- 1 root root 1066 May  8 06:09 ca.crt
-rw------- 1 root root 1675 May  8 06:09 ca.key
drwxr-xr-x 2 root root 4096 May  8 06:09 etcd
-rw-r--r-- 1 root root 1078 May  8 06:09 front-proxy-ca.crt
-rw------- 1 root root 1679 May  8 06:09 front-proxy-ca.key
-rw-r--r-- 1 root root 1119 May  8 06:09 front-proxy-client.crt
-rw------- 1 root root 1675 May  8 06:09 front-proxy-client.key
-rw------- 1 root root 1679 May  8 06:09 sa.key
-rw------- 1 root root  451 May  8 06:09 sa.pub
为 Master 组件生成 Pod 配置文件

Kubernetes 有三个 Master 组件 kube-apiserver、kube-controller-manager、kube-scheduler,而它们都会被使用 Pod 的方式部署。

生成一个 bootstrap token

只要持有这个 token,任何一个安装了 kubelet 和 kubadm 的节点,都可以通过 kubeadm join 加入到这个集群当中。这个 token 的值和使用方法,会在 kubeadm init 结束后被打印出来
如果出现如下界面,恭喜你master节点成功的初始化了

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 159.99.100.88:6443 --token exkevu.lr9iq11eh6slyqqw --discovery-token-ca-cert-hash sha256:80e0c9375340f635f33feb7cbd5931365bd0c9e0a5d3b4f065e74699d3e7ed4e

这个提示信息了,告诉了后面的工作节点加入到k8s中的步骤,如果忘记了token,可以使用以下的命令来显示join命令:

kubeadm token create --print-join-command

它会再次显示join的命令如下:

kubeadm join 159.99.100.88:6443 --token exkevu.lr9iq11eh6slyqqw --discovery-token-ca-cert-hash sha256:80e0c9375340f635f33feb7cbd5931365bd0c9e0a5d3b4f065e74699d3e7ed4e

配置 kubectl 工具

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

部署 flannel 网络

使用以下命令创建flannel网络

sudo kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

运行此命令成功后,会提示网络创建成功,使用以下命令可以检测

kubectl get pods --all-namespaces

输出如下的pod列表,其中有flannel相关的pod。

NAMESPACE     NAME                                  READY   STATUS    RESTARTS   AGE
kube-system   coredns-558bd4d5db-gbjgs              1/1     Running   0          2d3h
kube-system   coredns-558bd4d5db-p2k5k              1/1     Running   0          2d3h
kube-system   etcd-master-node                      1/1     Running   0          2d3h
kube-system   kube-apiserver-master-node            1/1     Running   0          2d3h
kube-system   kube-controller-manager-master-node   1/1     Running   0          2d3h
kube-system   kube-flannel-ds-2cbfp                 1/1     Running   0          2d3h
kube-system   kube-flannel-ds-cw8tf                 1/1     Running   0          2d3h
kube-system   kube-proxy-fm9xl                      1/1     Running   0          2d3h
kube-system   kube-proxy-l4l95                      1/1     Running   0          2d3h
kube-system   kube-scheduler-master-node            1/1     Running   1          2d3h

worker节点加入到集群

在工作节点上运行命令

kubeadm join 159.99.100.88:6443 --token exkevu.lr9iq11eh6slyqqw --discovery-token-ca-cert-hash sha256:80e0c9375340f635f33feb7cbd5931365bd0c9e0a5d3b4f065e74699d3e7ed4e

查看node节点的状态

kubectl get nodes
NAME          STATUS   ROLES                  AGE     VERSION
master-node   Ready    control-plane,master   2d19h   v1.21.0
worker01      Ready    <none>                 2d19h   v1.21.0

完成上述步骤后,一个单master节点和多工作节点的集群就搭建完成。

测试集群

使用一个简n'g单的nginx服务来测试集群是否正常工作。

部署nginx deployment

创建nginx-deployment.yaml文件
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 4
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9

应用yaml文件
kubectl apply -f nginx-deployment.yaml
查看deployment
kubectl get deployments
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   4/4     4            4           2d19h
查看pods
kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-7cd7fc4dbf-fqq5c   1/1     Running   0          23h
nginx-deployment-7cd7fc4dbf-m7xfn   1/1     Running   0          23h
nginx-deployment-7cd7fc4dbf-tp4wn   1/1     Running   0          23h
nginx-deployment-7cd7fc4dbf-xnpcj   1/1     Running   0          23h

部署nginx service

创建文件 nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  labels:
    app: nginx
spec:
  selector:
    app: nginx
  ports:
  - name: nginx-port
    protocol: TCP
    port: 80
    nodePort: 32600
    targetPort: 80
  type: NodePort
应用yaml文件
kubectl apply -f nginx-service.yaml
查看服务
kubectl get services -o wide
NAME            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE     SELECTOR
kubernetes      ClusterIP   10.96.0.1      <none>        443/TCP        2d19h   <none>
nginx-service   NodePort    10.103.9.200   <none>        80:32600/TCP   24h     app=nginx
访问服务
  • 使用cluster ip访问(集群环境下访问)
curl http://10.103.9.200
  • 使用nodeport访问(可以在非集群环境下访问)
    我集群机器ip是159.99.100.88(master),159.99.100.89(worker01)
curl http://159.99.100.88:32600
curl http://159.99.100.89:32600

能正常访问nginx的主页说明k8s所有功能都正常。

参考文章

主要是参考下面的几篇博文的内容

推荐阅读更多精彩内容