使用 k3s 在 Centos7 上运行 K8S

本文参考:

使用 k3s 在 Fedora IoT 上运行 K8S | Linux 中国

https://mp.weixin.qq.com/s?__biz=MzI1NDQwNDYyMg==&mid=2247487246&idx=1&sn=43b0ac1cba8a53dee230667bb9d2b158&chksm=e9c4fe6fdeb37779ea4a7e4d053c543a301510cf87c2c02b0aa28cd14b08f648bed9f9e005c4&mpshare=1&scene=22&srcid=#rd

一个“正常”安装的 Kubernetes(如果有这么一说的话)对于物联网来说有点沉重。K8s 的推荐内存配置,是每台机器 2GB!不过,我们也有一些替代品,其中一个新人是 k3s —— 一个轻量级的 Kubernetes 发行版。

 

Kubernetes 是一个颇受欢迎的容器编排系统。它可能最常用在那些能够处理巨大负载的强劲硬件上。不过,它也能在像树莓派 3 这样轻量级的设备上运行。让我们继续阅读,来了解如何运行它。

为什么用 Kubernetes?

虽然 Kubernetes 在云计算领域风靡一时,但让它在小型单板机上运行可能并不是常见的。不过,我们有非常明确的理由来做这件事。首先,这是一个不需要昂贵硬件就可以学习并熟悉 Kubernetes 的好方法;其次,由于它的流行性,市面上有大量应用进行了预先打包,以用于在 Kubernetes 集群中运行。更不用说,当你遇到问题时,会有大规模的社区用户为你提供帮助。

最后但同样重要的是,即使是在家庭实验室这样的小规模环境中,容器编排也确实能够使事情变得更加简单。虽然在学习曲线方面,这一点并不明显,但这些技能在你将来与任何集群打交道的时候都会有帮助。不管你面对的是一个单节点树莓派集群,还是一个大规模的机器学习场,它们的操作方式都是类似的。

K3s - 轻量级的 Kubernetes

一个“正常”安装的 Kubernetes(如果有这么一说的话)对于物联网来说有点沉重。K8s 的推荐内存配置,是每台机器 2GB!不过,我们也有一些替代品,其中一个新人是 k3s —— 一个轻量级的 Kubernetes 发行版。

K3s 非常特殊,因为它将 etcd 替换成了 SQLite 以满足键值存储需求。还有一点,在于整个 k3s 将使用一个二进制文件分发,而不是每个组件一个。这减少了内存占用并简化了安装过程。基于上述原因,我们只需要 512MB 内存即可运行 k3s,极度适合小型单板电脑!

 

环境准备:

k3s-node1

k3s-node2

在两台主机上配置hosts

cat /etc/hosts
192.168.20.102 k3s-node1
192.168.20.105 k3s-node2
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

配置防火墙,允许 6443 和 8372 端口的通信。或者,你也可以简单地运行 systemctl stop firewalld 来为这次实验关闭防火墙。

[root@k3s-node1 ~]# service firewalld status
Redirecting to /bin/systemctl status firewalld.service
● firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
   Active: inactive (dead)
     Docs: man:firewalld(1)
[root@k3s-node2 ~]# service firewalld status
Redirecting to /bin/systemctl status firewalld.service
● firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
   Active: inactive (dead)
     Docs: man:firewalld(1)

 

安装k3s,安装 k3s 非常简单。直接运行安装脚本:

[root@k3s-node1 ~]# curl -sfL https://get.k3s.io | sh -

它会下载、安装并启动 k3s。安装完成后,运行以下命令来从服务器获取节点列表:

[root@k3s-node1 ~]# kubectl get nodes
NAME        STATUS   ROLES    AGE   VERSION
k3s-node1   Ready       67s   v1.14.1-k3s.4

需要注意的是,有几个选项可以通过环境变量传递给安装脚本。这些选项可以在文档中找到。当然,你也完全可以直接下载二进制文件来手动安装 k3s。

对于实验和学习来说,这样已经很棒了,不过单节点的集群也不能算一个集群。幸运的是,添加另一个节点并不比设置第一个节点要难。只需要向安装脚本传递两个环境变量,它就可以找到第一个节点,而不用运行 k3s 的服务器部分。

curl -sfL https://get.k3s.io | K3S_URL=https://example-url:6443 \
  K3S_TOKEN=XXX sh -

上面的 example-url 应被替换为第一个节点的 IP 地址,或一个完全限定域名。在该节点中,(用 XXX 表示的)令牌可以在 /var/lib/rancher/k3s/server/node-token 文件中找到。

[root@k3s-node1 ~]# cat /var/lib/rancher/k3s/server/node-token
K10e75d2dfbb13cad45b1895f0e02ab3271cb9238abb54bc902b38c4da69037ffde::node:f05c806e90e81eef905959061a7a1639

在k3s-node2上执行

curl -sfL https://get.k3s.io | K3S_URL=https://k3s-node1:6443 \
K3S_TOKEN=K10e75d2dfbb13cad45b1895f0e02ab3271cb9238abb54bc902b38c4da69037ffde::node:f05c806e90e81eef905959061a7a1639 sh -
[root@k3s-node2 ~]# curl -sfL https://get.k3s.io | K3S_URL=https://k3s-node1:6443 \
> K3S_TOKEN=K10e75d2dfbb13cad45b1895f0e02ab3271cb9238abb54bc902b38c4da69037ffde::node:f05c806e90e81eef905959061a7a1639 sh -
[INFO]  Finding latest release
[INFO]  Using v0.5.0 as release
[INFO]  Downloading hash https://github.com/rancher/k3s/releases/download/v0.5.0/sha256sum-amd64.txt
[INFO]  Downloading binary https://github.com/rancher/k3s/releases/download/v0.5.0/k3s
[INFO]  Verifying binary download
[INFO]  Installing k3s to /usr/local/bin/k3s
[INFO]  Creating /usr/local/bin/kubectl symlink to k3s
[INFO]  Creating /usr/local/bin/crictl symlink to k3s
[INFO]  Creating killall script /usr/local/bin/k3s-killall.sh
[INFO]  Creating uninstall script /usr/local/bin/k3s-agent-uninstall.sh
[INFO]  env: Creating environment file /etc/systemd/system/k3s-agent.service.env
[INFO]  systemd: Creating service file /etc/systemd/system/k3s-agent.service
[INFO]  systemd: Enabling k3s-agent unit
Created symlink from /etc/systemd/system/multi-user.target.wants/k3s-agent.service to /etc/systemd/system/k3s-agent.service.
[INFO]  systemd: Starting k3s-agent

在k3s-node1检查集群

[root@k3s-node1 ~]#  kubectl get nodes
NAME        STATUS   ROLES    AGE   VERSION
k3s-node1   Ready       12m   v1.14.1-k3s.4
k3s-node2   Ready       8s    v1.14.1-k3s.4

部署一些容器

现在我们有了一个 Kubernetes 集群,我们可以真正做些什么呢?让我们从部署一个简单的 Web 服务器开始吧。

[root@k3s-node1 ~]# kubectl create deployment my-server --image nginx
deployment.apps/my-server created

这会从名为 nginx 的容器镜像中创建出一个名叫 my-server 的 部署(默认使用 docker hub 注册中心,以及 latest 标签)。

[root@k3s-node1 ~]# kubectl get pods
NAME                         READY   STATUS              RESTARTS   AGE
my-server-6889ff8bd8-rx2ll   0/1     ContainerCreating   0          109s

发现pod的状态一直为正在创建状态,利用
kubectl describe pod
查看pod创建的详细记录

[root@k3s-node1 k3s]# kubectl describe pods
Name:               my-server-6889ff8bd8-rx2ll
Namespace:          default
Priority:           0
PriorityClassName:  
Node:               k3s-node2/192.168.20.105
Start Time:         Sat, 01 Jun 2019 15:44:33 +0800
Labels:             app=my-server
                    pod-template-hash=6889ff8bd8
Annotations:        
Status:             Pending
IP:
Controlled By:      ReplicaSet/my-server-6889ff8bd8
Containers:
  nginx:
    Container ID:
    Image:          nginx
    Image ID:
    Port:           
    Host Port:      
    State:          Waiting
      Reason:       ContainerCreating
    Ready:          False
    Restart Count:  0
    Environment:    
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-gprt4 (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             False
  ContainersReady   False
  PodScheduled      True
Volumes:
  default-token-gprt4:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-gprt4
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type     Reason                  Age                     From                Message
  ----     ------                  ----                    ----                -------
  Normal   Scheduled               17m                     default-scheduler   Successfully assigned default/my-server-6889ff8bd8-rx2ll to k3s-node2
  Warning  FailedCreatePodSandBox  12m (x8 over 17m)       kubelet, k3s-node2  Failed create pod sandbox: rpc error: code = Unknown desc = failed to get sandbox image "k8s.gcr.io/pause:3.1": failed to pull image "k8s.gcr.io/pause:3.1": failed to resolve image "k8s.gcr.io/pause:3.1": no available registry endpoint: failed to do request: Head https://k8s.gcr.io/v2/pause/manifests/3.1: dial tcp 108.177.125.82:443: i/o timeout
  Warning  FailedCreatePodSandBox  2m31s (x11 over 9m38s)  kubelet, k3s-node2  Failed create pod sandbox: rpc error: code = Unknown desc = failed to get sandbox image "k8s.gcr.io/pause:3.1": failed to pull image "k8s.gcr.io/pause:3.1": failed to resolve image "k8s.gcr.io/pause:3.1": no available registry endpoint: failed to do request: Head https://k8s.gcr.io/v2/pause/manifests/3.1: dial tcp 108.177.125.82:443: i/o timeout
  Warning  FailedCreatePodSandBox  25s (x3 over 109s)      kubelet, k3s-node2  Failed create pod sandbox: rpc error: code = Unknown desc = failed to get sandbox image "k8s.gcr.io/pause:3.1": failed to pull image "k8s.gcr.io/pause:3.1": failed to resolve image "k8s.gcr.io/pause:3.1": no available registry endpoint: failed to do request: Head https://k8s.gcr.io/v2/pause/manifests/3.1: dial tcp 74.125.203.82:443: i/o timeout

发现无法访问gcr.io.

注意:通过journalctl工具,我发现无法获取node资源的一个最最重要的问题就是通过最后对docker服务的检查发现其中的每个pod的pause container为从gcr.io上下载的,而由于屏蔽了中国的访问,故需要我们手动下载缺少的镜像,缺少的pause镜像为3.1版本的在docker hub上进行搜索,我最终找到了一个3.1版本的pause(docker.io/kubernetes/pause 为3.0版本的,故我没有选择该image

[root@k3s-node1 ~]# mkdir /certs
[root@k3s-node1 ~]# cd /certs
[root@k3s-node1 certs]# openssl req -subj "/C=CN/ST=BeiJing/L=Dongcheng/CN=k8s.gcr.io" -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout registry.key -out registry.crt
Generating a 2048 bit RSA private key
...+++
.................................+++
writing new private key to 'registry.key'
-----

[root@k3s-node1 certs]# cat /certs/registry.crt >> /etc/pki/tls/certs/ca-bundle.crt

安装docker

[root@k3s-node1 ~]# yum install -y docker
[root@k3s-node1 ~]# systemctl enable docker
[root@k3s-node1 ~]# systemctl start docker
[root@k3s-node1 ~]# 

接取镜像:

[root@k3s-node1 ~]# docker pull  docker.io/rancher/pause-amd64:3.1
[root@k3s-node1 ~]# docker tag docker.io/rancher/pause-amd64:3.1 k8s.gcr.io/pause:3.1

修改hosts

[root@k3s-node1 ~]# cat /etc/hosts
192.168.20.102 k8s.gcr.io

安装ca.cert,这一步不做会出现 

x509: certificate signed by unknown authority

 

mkdir /etc/docker/certs.d/k8s.gcr.io/
cp /certs/registry.crt /etc/docker/certs.d/k8s.gcr.io/ca.crt

重新启动docker

[root@k3s-node1 ~]# systemctl restart docker

建立registry

[root@k3s-node1 ~]# docker run -d -p 443:443 --restart=always --name registry -v /certs:/certs -e REGISTRY_HTTP_ADDR=0.0.0.0:443 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/registry.crt -e REGISTRY_HTTP_TLS_KEY=/certs/registry.key registry:2
84e9e6c39eb55a47c66b6964c65e7505bbeb13fa0b1d6d0a6115c74130526c0a

查看dockers日志,tls handsharke error不用理。

[root@k3s-node1 certs]# docker logs registry
time="2019-06-01T13:23:18.951071701Z" level=warning msg="No HTTP secret provided - generated random secret. This may cause problems with uploads if multiple registries are behind a load-balancer. To provide a shared secret, fill in http.secret in the configuration file or set the REGISTRY_HTTP_SECRET environment variable." go.version=go1.11.2 instance.id=c85c09e2-c1fd-409e-b971-1e08ff4c503b service=registry version=v2.7.1
time="2019-06-01T13:23:18.951230536Z" level=info msg="redis not configured" go.version=go1.11.2 instance.id=c85c09e2-c1fd-409e-b971-1e08ff4c503b service=registry version=v2.7.1
time="2019-06-01T13:23:18.951273123Z" level=info msg="Starting upload purge in 36m0s" go.version=go1.11.2 instance.id=c85c09e2-c1fd-409e-b971-1e08ff4c503b service=registry version=v2.7.1
time="2019-06-01T13:23:18.972833753Z" level=info msg="using inmemory blob descriptor cache" go.version=go1.11.2 instance.id=c85c09e2-c1fd-409e-b971-1e08ff4c503b service=registry version=v2.7.1
time="2019-06-01T13:23:18.973733421Z" level=info msg="listening on [::]:443, tls" go.version=go1.11.2 instance.id=c85c09e2-c1fd-409e-b971-1e08ff4c503b service=registry version=v2.7.1
2019/06/01 13:23:24 http: TLS handshake error from 192.168.20.102:48180: remote error: tls: bad certificate
2019/06/01 13:23:28 http: TLS handshake error from 192.168.20.102:48182: remote error: tls: bad certificate

打标签,上传


[root@k3s-node1 certs]# docker push k8s.gcr.io/pause:3.1
The push refers to a repository [k8s.gcr.io/pause]
e17133b79956: Pushed
3.1: digest: sha256:fcaff905397ba63fd376d0c3019f1f1cb6e7506131389edbcb3d22719f1ae54d size: 527

查看kubectl

[root@k3s-node1 certs]# kubectl get all
NAME                             READY   STATUS              RESTARTS   AGE
pod/my-server-6889ff8bd8-mzsxq   0/1     ContainerCreating   0          4h11m

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.43.0.1            443/TCP   6h1m

NAME                        READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/my-server   0/1     1            0           4h11m

NAME                                   DESIRED   CURRENT   READY   AGE
replicaset.apps/my-server-6889ff8bd8   1         1         0       4h11m
[root@k3s-node1 certs]# kubectl delete deployment.apps/my-server
deployment.apps "my-server" deleted
[root@k3s-node1 certs]# kubectl get all
NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.43.0.1            443/TCP   6h1m

还有些问题,迟些处理。

你可能感兴趣的:(DOCKER,LINUX,Kubernetes)