Kubernetes 源码 (5) 最小化启动

Submitted by Lizhe on Tue, 07/07/2020 - 06:06

这里将尝试使用之前编译完的源码来构建一个最小化启动的集群

20200707020919

要运行一个最小级别的 Kubernetes 至少要包括如下三个基本组件:

  1. kubelet:在集群中每个节点上运行的代理,负责容器真正运行的核心组件
  2. kube-apiserver:Kubernetes 控制平面的组件,提供资源操作的唯一入口
  3. 容器运行时(Docker)

 

我们创建一个 minik8s 的文件夹用来实验

拷贝 kubectl 和 kubelet 两个可执行二进制文件到这个文件夹中,然后创建一个 pods 文件夹

20200707022908

启动 kubelet 来试一下

sudo ./kubelet --pod-manifest-path=pods --fail-swap-on=false

 

20200707022727

 

然后创建一个 helloworld pod

 

apiVersion: v1

kind: Pod

metadata:

  name: hello

spec:

  containers:

  - image: busybox

    name: hello

    command: ["echo", "hello world!"]

20200707024211

kubelet 进程会自动加载这个文件,并且尝试启动对应的pod,但是这里报错了

 

20200707024313

 

这是因为 Kubernetes 的 Pod 默认情况下会优先启动一个 k8s.gcr.io/pause:3.2的 pause 镜像,而该镜像由于某些原因获取不到,我们可以 --pod-infra-container-image 参数重新指定一个可以访问到的镜像:

 

sudo ./kubelet --pod-manifest-path=pods --fail-swap-on=false --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.2

 

20200707024457

20200707024522

为了启动 apiserver,要先启动一个 etcd 服务

 

apiVersion: v1

kind: Pod

metadata:

  name: etcd

  namespace: kube-system

spec:

  containers:

  - name: etcd

    command:

    - etcd

    - --data-dir=/var/lib/etcd

    image: registry.aliyuncs.com/google_containers/etcd:3.4.3-0

    volumeMounts:

    - mountPath: /var/lib/etcd

      name: etcd-data

  hostNetwork: true

  volumes:

  - hostPath:

      path: /var/lib/etcd

      type: DirectoryOrCreate

    name: etcd-data

 

20200707025749

然后来启动 apiserver

 

apiVersion: v1

kind: Pod

metadata:

  name: kube-apiserver

  namespace: kube-system

spec:

  containers:

  - name: kube-apiserver

    command:

    - kube-apiserver

    - --etcd-servers=http://127.0.0.1:2379

    image: cnych/kube-apiserver:v1.18.5

  hostNetwork: true

20200707025813

尝试一下 kubectl 命令行

20200707025950

这里没取到 pod 信息是因为缺少 kubeconfig 配置

创建 kubeconfig.yaml

 

apiVersion: v1

kind: Config

clusters:

- cluster:

    server: http://127.0.0.1:8080

  name: mink8s

contexts:

- context:

    cluster: mink8s

  name: mink8s

current-context: mink8s

重启kubelet 进程,加入 kubeconfig 参数

 

sudo ./kubelet --pod-manifest-path=pods --fail-swap-on=false --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.2 --kubeconfig=kubeconfig.yaml

 

20200707030137

 

 


 

接下来尝试在这个环境中部署一个nginx

 

创建一个 nginx yaml

 

apiVersion: v1

kind: Pod

metadata:

  name: nginx

spec:

  containers:

  - image: nginx

    name: nginx

因为没有默认的 service account ,所以会直接报错

20200707035902

 

 

创建 默认的 service account

 

apiVersion: v1

kind: ServiceAccount

metadata:

  name: default

  namespace: default

然后再重试,发现缺少token

202007040121

 

修改一下 service account 配置,关闭 token

 

apiVersion: v1

kind: ServiceAccount

metadata:

  name: default

  namespace: default

automountServiceAccountToken: false

 

20200707040742

这里可以看到 nginx pod 和 helloworld 都没有正常启动

这是因为没有调度器, scheduler 负责调度,这里直接使用 nodeName 将pod 固定到节点上,编辑 nginx.yaml

 

apiVersion: v1

kind: Pod

metadata:

  name: nginx

spec:

  containers:

  - image: nginx

    name: nginx

  nodeName: ubuntu

这里有一个点需要注意,直接 apply 会报错,需要先删除原来的 pod,再创建

20200707043420

 

调用一下 curl

./kubectl get pods -owide
./kubectl logs curl

 

apiVersion: v1

kind: Pod

metadata:

  name: curl

spec:

  containers:

  - image: curlimages/curl

    name: curl

    command: ["curl", "172.17.0.3"]

  nodeName: ubuntu

 

20200707045504

20200707044616

 


 

 

这里稍微再扩展一下,如果不使用 docker,也可以直接使用 二进制文件 启动 apiserver

 

sudo ./kube-apiserver --etcd-servers=http://127.0.0.1:2379 --service-cluster-ip-range=10.0.0.0/24

 

20200707060102