使用 Kind 构建离线集群安装包

Kind(Kubernetes in Docker) 是一个 Kubernetes 孵化项目,它使用 Docker 为节点进行 Kubernetes 的快速部署,可以方便的搭建 Kubernetes 集群,虽然简单,但也是通过 Kubernetes 一致性认证的安装器,因此用来做测试还是比较可靠的。

按照社区的一贯德行,安装过程虽然只要有个 Docker 就可以了,但是对网络有严重的依赖。在 Workshop 之类的场合,会受到很大限制。这种情况下,有一个离线包就会非常方便了。

获取安装文件

本文会从一个新安装的 CentOS Mini 服务器为例,逐个步骤展示构建离线 Kind 安装包的过程。最后再安装一个

这里假设这个服务器有“优秀”的互联网连接。

Docker 离线包

首先我们要为 Docker 的离线安装准备好 RPM 包,新建一个目录 rpms,用来下载安装包:

$ yum install --downloadonly --downloaddir=./rpms \
    yum-utils device-mapper-persistent-data lvm2

执行完毕之后,会在 rpms 目录中找到 Docker 的依赖包,接下来获取 Docker 的 RPM。

$ yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo
$ yum --downloadonly --downloaddir=./rpms \
    install docker-ce docker-ce-cli containerd.io  

如此就获得了 Docker 自身以及所有的依赖 RPM 包。可以使用 rpm 直接安装。并启动 Docker 服务。

Kubeadm 和 Kubectl

根据官方文档

$ cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF

$ yum install --downloadonly --downloaddir=./rpms \
kubectl kubeadm --disableexcludes=kubernetes

这里做了一点修改:不再安装 kubelet,也不启动服务,仅用于获取安装包。

获取镜像

使用 rpm 安装 kubeadm,开始获取安装所需的所有镜像:

$ kubeadm config images list --kubernetes-version=v1.15.3
k8s.gcr.io/kube-apiserver:v1.15.3
k8s.gcr.io/kube-controller-manager:v1.15.3
k8s.gcr.io/kube-scheduler:v1.15.3
k8s.gcr.io/kube-proxy:v1.15.3
k8s.gcr.io/pause:3.1
k8s.gcr.io/etcd:3.3.10
k8s.gcr.io/coredns:1.3.1

拿到列表了就可以逐个拉取处理镜像,这里给个小脚本:

#!/bin/sh
for image in `kubeadm config images list --kubernetes-version=$1`
do
  image_name=`echo ${image} | sed "s/k8s.gcr.io.//g"`
  docker pull "${image}"
  docker tag "${image}" "${image_name}"
  file_name="${image_name}.tgz"
  docker save "${image_name}" | gzip > "${file_name}"
  docker rmi "${image}"
  docker rmi "${image_name}"
done

这样我们就有了所有 Kubeadm 所需的镜像。另外我们还需要两个辅助镜像:kindest/node:v1.15.3 以及 registry:2.7.1

CFSSL 和 Kind

$ wget https://github.com/kubernetes-sigs/kind/releases/download/v0.5.1/kind-linux-amd6
$ wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
$ wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64

这样我们已经获得了所有安装所需的文件。可以进入离线步骤了。

安装

RPM 安装

把前面获得的 Kubectl 安装起来。

签发证书

使用 CFSSL 生成证书,首先生成 CA。

ca-csr.json

{
    "CN": "Kubernetes CA",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "ca": {
       "expiry": "87600h"
    }
}

cfssl gencert -initca ca-csr.json | cfssljson -bare ca 生成 CA 证书。

把证书加入信任列表:

$ update-ca-trust enable
$ cp ca.pem /etc/pki/ca-trust/source/anchors/
$ update-ca-trust extract

更新之后,需要重启 Docker 服务,让 Docker 也信任这一 CA。

然后是生成镜像库所需的服务器证书:

config.json

{
    "signing": {
        "default": {
            "expiry": "87600h"
        },
        "profiles": {
            "server": {
                "expiry": "87600h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "server auth",
                    "client auth"
                ]
            },
            "user": {
                "expiry": "87600h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "client auth"
                ]
            }
        }
    }
}

server.json

{
    "CN": "Registry",
    "hosts": [
      "127.0.0.1","10.211.55.10"
    ]
}

接下来签发证书:

$ cfssl gencert -ca ca.pem -ca-key ca-key.pem -config=config.json \
     -profile=server server.json | cfssljson -bare registry

这里的 IP 地址要跟本地地址对应。

启动镜像库

使用 docker load -i,载入了 registry 镜像,把仓库运行起来:

#!/bin/sh
docker run -d \
   --name="registry2" \
   -v "$(pwd)/storage":/var/lib/registry \
   -p 5000:5000 \
  -v "$(pwd)/certs":/certs \
  -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/registry.pem \
  -e REGISTRY_HTTP_TLS_KEY=/certs/registry-key.pem \
   --restart=always \
   registry:2.7.1

如此就在 5000 端口启动了一个镜像库。

推送镜像到私库

把前面的所有镜像都载入 Docker,Tag 之后推入私库,最后在私库里就有了一系列的镜像,例如 10.211.55.10:5000/pause:3.1

安装集群

为了能够使用私库的镜像,要对 Kind 进行一点配置:

kind: Cluster
apiVersion: kind.sigs.k8s.io/v1alpha3
kubeadmConfigPatches:
- |
  apiVersion: kubeadm.k8s.io/v1beta2
  kind: ClusterConfiguration
  metadata:
    name: config
  networking:
    serviceSubnet: 10.0.0.0/16
  imageRepository: 10.211.55.10:5000
  nodeRegistration:
    kubeletExtraArgs:
      pod-infra-container-image: 10.211.55.10:5000/pause:3.1
- |
  apiVersion: kubeadm.k8s.io/v1beta2
  kind: InitConfiguration
  metadata:
    name: config
  networking:
    serviceSubnet: 10.0.0.0/16
  imageRepository: 10.211.55.10:5000
nodes:
- role: control-plane
$ kind create cluster --image kindest/node:v1.15.3
Creating cluster "kind" ...
 ✓ Ensuring node image (kindest/node:v1.15.3) 🖼
 ✓ Preparing nodes 📦
 ✓ Creating kubeadm config 📜
 ✓ Starting control-plane 🕹️
 ✓ Installing CNI 🔌
 ✓ Installing StorageClass 💾
Cluster creation complete. You can now use the cluster with:

export KUBECONFIG="$(kind get kubeconfig-path --name="kind")"

如此这般,Kind 集群就启动了。我们可以测试一下:

$ export KUBECONFIG="$(kind get kubeconfig-path --name="kind")"
$ kubectl get pods --all-namespaces
NAMESPACE     NAME                                         READY   STATUS    RESTARTS   AGE
kube-system   coredns-5c98db65d4-lkg92                     1/1     Running   0          72m
kube-system   coredns-5c98db65d4-rhv7g                     1/1     Running   0          72m
kube-system   etcd-kind-control-plane                      1/1     Running   0          71m
kube-system   kindnet-892gh                                1/1     Running   1          72m
kube-system   kube-apiserver-kind-control-plane            1/1     Running   0          71m
kube-system   kube-controller-manager-kind-control-plane   1/1     Running   0          71m
kube-system   kube-proxy-nd4ml                             1/1     Running   0          72m
kube-system   kube-scheduler-kind-control-plane            1/1     Running   0          71m

离线环境下部署镜像

Kind 提供了一个 load 命令,可以把镜像载入所有“节点”,例如:

$ kind load docker-image 10.211.55.10:5000/registry:2.7.1
$ kubectl run registry --image=10.211.55.10:5000/registry:2.7.1 --replicas=2
$ kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
deployment.apps/registry created
$ kubectl get pods
NAME                        READY   STATUS    RESTARTS   AGE
registry-6b7648c4f4-g8zxr   1/1     Running   0          24s

后记

很明显,这些步骤是可以自动化的,只需要分发一个安装包,就能够很方便的快速部署、删除一整套的 Kubernetes,可以用随需部署的方式完成环境的搭建和删除。

Avatar
崔秀龙

简单,是大师的责任;我们凡夫俗子,能做到清楚就很不容易了。

相关

下一页
上一页
comments powered by Disqus