在CoreOS集群上配置Kubernetes的方法

在本文中,我将介绍如何在CoreOS集群上设置Kubernetes。

这个博客是从英文版本翻译而来的,原文可以在这里查看。我们使用了部分机器翻译,如果有翻译错误,请指出,不胜感激。

前提条件和目标

首先,让我们从基本的CoreOS集群开始。由于阿里云已经提供了可配置的集群,因此我不会详细介绍。集群所需要的至少是一个主节点和多个工作节点。尽管在Kubernetes中,节点被赋予了专门的角色,但这些节点是兼容的。其中一个节点,即主节点,将承担控制管理和API服务器的角色。

image.png

在这个教程中,我们参考了CoreOS网站上公开的实施指南。在CoreOS集群完全设置好之后,让我们继续进行。在这里,我们将使用两个样例BareMetal节点。

主节点

将节点1设为主节点。从CoreOS节点的SSH开始。

创建名为”certs”的目录。

$ mkdir certs
$ cd certs

将以下脚本粘贴到cert_generator.sh中的certs目录中。

#!/bin/bash
# Creating TLS certs
echo "Creating CA ROOT**********************************************************************"
openssl genrsa -out ca-key.pem 2048
openssl req -x509 -new -nodes -key ca-key.pem -days 10000 -out ca.pem -subj "/CN=kube-ca"
echo "creating API Server certs*************************************************************"
echo "Enter Master Node IP address:"
read master_Ip
cat >openssl.cnf<<EOF
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = kubernetes
DNS.2 = kubernetes.default
DNS.3 = kubernetes.default.svc
DNS.4 = kubernetes.default.svc.cluster.local
IP.1 = 10.3.0.1
IP.2 = $master_Ip
EOF
openssl genrsa -out apiserver-key.pem 2048
openssl req -new -key apiserver-key.pem -out apiserver.csr -subj "/CN=kube-apiserver" -config openssl.cnf
openssl x509 -req -in apiserver.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out apiserver.pem -days 365 -extensions v3_req -extfile openssl.cnf
echo "Creating worker nodes"
cat > worker-openssl.cnf<< EOF
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[alt_names]
IP.1 = \$ENV::WORKER_IP
EOF
echo "Enter the number of worker nodes:"
read worker_node_num
for (( c=1; c<= $worker_node_num; c++ ))
do
   echo "Enter the IP Address for the worker node_$c :"
   read ip
   openssl genrsa -out kube-$c-worker-key.pem 2048
   WORKER_IP=$ip openssl req -new -key kube-$c-worker-key.pem -out kube-$c-worker.csr -subj "/CN=kube-$c" -config worker-openssl.cnf
   WORKER_IP=$ip openssl x509 -req -in kube-$c-worker.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out kube-$c-worker.pem -days 365 -extensions v3_req -extfile worker-openssl.cnf
done
echo "Creating Admin certs********************************************************"
openssl genrsa -out admin-key.pem 2048
openssl req -new -key admin-key.pem -out admin.csr -subj "/CN=kube-admin"
openssl x509 -req -in admin.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out admin.pem -days 365
echo "DONE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"

设置可执行脚本。

Note: The provided sentence is in Japanese, not Chinese. The paraphrase provided is a direct translation from Japanese to Chinese.

$ chmod +x cert_generator.sh

当执行脚本后,应该会提示输入节点的详细信息。然后,会生成用于在Kubernetes上进行安装的证书。

创建一个目录来存储生成的密钥,如下所示。

$ mkdir -p /etc/kubernetes/ssl

将certs中的以下certs复制到/etc/kubernetes/ssl中。

/etc/kubernetes/ssl/ca.pem
/etc/kubernetes/ssl/apiserver.pem
/etc/kubernetes/ssl/apiserver-key.pem

网络配置

接下来,让我们获取flannel的本地设置并将其配置为从etcd获取集群级别的配置。请创建包含以下内容的脚本,并注意以下几点。

1、请将${ADVERTISE_IP}替换为机器的公共IP。
2、请替换${ETCD_ENDPOINTS}。

FLANNELD_IFACE=${ADVERTISE_IP}
FLANNELD_ETCD_ENDPOINTS=${ETCD_ENDPOINTS}

接下来,您将如下所示创建一个包含上述设置的drop-in文件夹:
/etc/systemd/system/flanneld.service.d/40-ExecStartPre-symlink.conf

[Service]
ExecStartPre=/usr/bin/ln -sf /etc/flannel/options.env /run/flannel/options.env

Docker的配置

为了管理集群的Pod网络,需要在flannel中配置Docker。需要确保在Docker启动之前先运行flannel。让我们尝试应用systemd的附加配置文件,即在路径/etc/systemd/system/docker.service.d/40-flannel.conf中进行配置。

[Unit]
Requires=flanneld.service
After=flanneld.service
[Service]
EnvironmentFile=/etc/kubernetes/cni/docker_opts_cni.env

执行Docker CNI选项文件,并启动/etc/kubernetes/cni/docker_opts_cni.en。

DOCKER_OPT_BIP=""
DOCKER_OPT_IPMASQ=""

如果使用flannel网络,请使用以下命令进行flannel CNI的设置。

/etc/kubernetes/cni/net.d/10-flannel.conf
{
    "name": "podnet",
    "type": "flannel",
    "delegate": {
        "isDefaultGateway": true
    }
}

Kubelet单元的创建
Kubelet负责启动和停止Pod以及其他机器级任务。它将使用先前安装的TLS证书与在主节点上运行的API服务器进行通信。

创建/etc/systemd/system/kubelet.service。

1、请将${ADVERTISE_IP}替换为该节点的公共IP。
2、请将${DNS_SERVICE_IP}替换为10.3.0.10。

[Service]
Environment=KUBELET_VERSION=v1.5.1_coreos.0
Environment="RKT_OPTS=--uuid-file-save=/var/run/kubelet-pod.uuid \
  --volume var-log,kind=host,source=/var/log \
  --mount volume=var-log,target=/var/log \
  --volume dns,kind=host,source=/etc/resolv.conf \
  --mount volume=dns,target=/etc/resolv.conf"
ExecStartPre=/usr/bin/mkdir -p /etc/kubernetes/manifests
ExecStartPre=/usr/bin/mkdir -p /var/log/containers
ExecStartPre=-/usr/bin/rkt rm --uuid-file=/var/run/kubelet-pod.uuid
ExecStart=/usr/lib/coreos/kubelet-wrapper \
  --api-servers=http://127.0.0.1:8080 \
  --register-schedulable=false \
  --cni-conf-dir=/etc/kubernetes/cni/net.d \
  --network-plugin=cni \
  --container-runtime=docker \
  --allow-privileged=true \
  --pod-manifest-path=/etc/kubernetes/manifests \
  --hostname-override=${ADVERTISE_IP} \
  --cluster_dns=${DNS_SERVICE_IP} \
  --cluster_domain=cluster.local
ExecStop=-/usr/bin/rkt stop --uuid-file=/var/run/kubelet-pod.uuid
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

kube-apiserver的Pod设置

API服务器负责处理大部分工作负载,并且执行大多数的活动。API服务器是无状态的,它处理请求并提供反馈,并在需要时将结果存储到etcd中。

创建 etc/kubernetes/manifests/kube-apiserver.yaml 文件。

1、请将${ETCD_ENDPOINTS}替换为CoreOS主机。
2、请将${SERVICE_IP_RANGE}替换为10.3.0.0.0/24。
3、请将${ADVERTISE_IP}替换为此节点的公共IP地址。

apiVersion: v1
kind: Pod
metadata:
  name: kube-apiserver
  namespace: kube-system
spec:
  hostNetwork: true
  containers:
  - name: kube-apiserver
    image: quay.io/coreos/hyperkube:v1.5.1_coreos.0
    command:
    - /hyperkube
    - apiserver
    - --bind-address=0.0.0.0
    - --etcd-servers=${ETCD_ENDPOINTS}
    - --allow-privileged=true
    - --service-cluster-ip-range=${SERVICE_IP_RANGE}
    - --secure-port=443
    - --advertise-address=${ADVERTISE_IP}
    - --admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota
    - --tls-cert-file=/etc/kubernetes/ssl/apiserver.pem
    - --tls-private-key-file=/etc/kubernetes/ssl/apiserver-key.pem
    - --client-ca-file=/etc/kubernetes/ssl/ca.pem
    - --service-account-key-file=/etc/kubernetes/ssl/apiserver-key.pem
    - --runtime-config=extensions/v1beta1/networkpolicies=true
    - --anonymous-auth=false
    livenessProbe:
      httpGet:
        host: 127.0.0.1
        port: 8080
        path: /healthz
      initialDelaySeconds: 15
      timeoutSeconds: 15
    ports:
    - containerPort: 443
      hostPort: 443
      name: https
    - containerPort: 8080
      hostPort: 8080
      name: local
    volumeMounts:
    - mountPath: /etc/kubernetes/ssl
      name: ssl-certs-kubernetes
      readOnly: true
    - mountPath: /etc/ssl/certs
      name: ssl-certs-host
      readOnly: true
  volumes:
  - hostPath:
      path: /etc/kubernetes/ssl
    name: ssl-certs-kubernetes
  - hostPath:
      path: /usr/share/ca-certificates
    name: ssl-certs-host

kube-proxy Pod的设置

与API服务器一样,执行负责将流量导向服务和Pod的代理。代理通过与API服务器定期通信来提供最新的信息。代理支持集群内的主节点和工作节点。

可以直接从创建/etc/kubernetes/manifests/kube-proxy.yaml开始,无需进行其他设置。

apiVersion: v1
kind: Pod
metadata:
  name: kube-proxy
  namespace: kube-system
spec:
  hostNetwork: true
  containers:
  - name: kube-proxy
    image: quay.io/coreos/hyperkube:v1.5.1_coreos.0
    command:
    - /hyperkube
    - proxy
    - --master=http://127.0.0.1:8080
    securityContext:
      privileged: true
    volumeMounts:
    - mountPath: /etc/ssl/certs
      name: ssl-certs-host
      readOnly: true
  volumes:
  - hostPath:
      path: /usr/share/ca-certificates
    name: ssl-certs-host

kube-controller-manager的配置

我们将创建一个名为/etc/kubernetes/manifests/kube-controller-manager.yaml的文件,该文件将使用存储在磁盘中的TLS证书。

apiVersion: v1
kind: Pod
metadata:
  name: kube-controller-manager
  namespace: kube-system
spec:
  hostNetwork: true
  containers:
  - name: kube-controller-manager
    image: quay.io/coreos/hyperkube:v1.5.1_coreos.0
    command:
    - /hyperkube
    - controller-manager
    - --master=http://127.0.0.1:8080
    - --leader-elect=true
    - --service-account-private-key-file=/etc/kubernetes/ssl/apiserver-key.pem
    - --root-ca-file=/etc/kubernetes/ssl/ca.pem
    resources:
      requests:
        cpu: 200m
    livenessProbe:
      httpGet:
        host: 127.0.0.1
        path: /healthz
        port: 10252
      initialDelaySeconds: 15
      timeoutSeconds: 15
    volumeMounts:
    - mountPath: /etc/kubernetes/ssl
      name: ssl-certs-kubernetes
      readOnly: true
    - mountPath: /etc/ssl/certs
      name: ssl-certs-host
      readOnly: true
  hostNetwork: true
  volumes:
  - hostPath:
      path: /etc/kubernetes/ssl
    name: ssl-certs-kubernetes
  - hostPath:
      path: /usr/share/ca-certificates
    name: ssl-certs-host

kube-scheduler Pod的配置设置。

然后,设置调度程序,跟踪API的非计划Pod,分配机器,并将该决策更新到AP中。

创建 etc/kubernetes/manifests/kube-scheduler.yaml 文件。

apiVersion: v1
kind: Pod
metadata:
  name: kube-scheduler
  namespace: kube-system
spec:
  hostNetwork: true
  containers:
  - name: kube-scheduler
    image: quay.io/coreos/hyperkube:v1.5.1_coreos.0
    command:
    - /hyperkube
    - scheduler
    - --master=http://127.0.0.1:8080
    - --leader-elect=true
    resources:
      requests:
        cpu: 100m
    livenessProbe:
      httpGet:
        host: 127.0.0.1
        path: /healthz
        port: 10251
      initialDelaySeconds: 15
      timeoutSeconds: 15

读取已变动的单位

让系统重新扫描所有已实施的更改点。

$ sudo systemctl daemon-reload

Flannel网络的设置

我們已經提到 etcd 保存 Flannel 集群級別的設定。因此,讓我們先設置一下 Pod 網路的 IP 範圍。由於 etcd 已經運行,現在是設置的最佳時機。或者,您可以先啟動 etcd 再進行設置。

1、将10.2.0.0/16替换为$POD_NETWORK进行配置。
2、将$ETCD_SERVER替换为$ETCD_ENDPOINTS的URL(http://ip:port)进行配置。

$ curl -X PUT -d "value={\"Network\":\"$POD_NETWORK\",\"Backend\":{\"Type\":\"vxlan\"}}" "$ETCD_SERVER/v2/keys/coreos.com/network/config"

为使更改生效,需要重启flannel。这将最终导致docker守护进程的重启,可能会影响容器的执行。

$ sudo systemctl start flanneld
$ sudo systemctl enable flanneld

启动Kubelet

现在已经完成了所有的设置,kubelet已经准备就绪可以启动了。此外,还将启动并执行控制器、调度器、代理和Pod API服务器的清单。

$ sudo systemctl start kubelet

请确保在重新启动后kubelet能够成功启动。

$ sudo systemctl enable kubelet

工作节点

对于工作节点,首先需要创建一个目录,然后将生成的SSL密钥放置在工作节点上。

$ mkdir -p /etc/kubernetes/ssl

将certs复制到/etc/kubernetes/ssl目录下。

/etc/kubernetes/ssl/ca.pem
/etc/kubernetes/ssl/kube-1-worker-apiserver.pem
/etc/kubernetes/ssl/kube-1-worker-apiserver-key.pem

网络配置

请如之前一样,从 /etc/flannel/options.env 获取 flannel 的本地设置,并将 etcd 存储集群级别的配置。请复制该文件并进行必要的调整。

1、请将${ADVERTISE_IP}替换为机器的公网IP。
2、请替换${ETCD_ENDPOINTS}。

FLANNELD_IFACE=${ADVERTISE_IP}
FLANNELD_ETCD_ENDPOINTS=${ETCD_ENDPOINTS}

创建一个用于在flannel重新启动时使用上述配置的附加文件,路径为/etc/systemd/system/flanneld.service.d/40-ExecStartPre-symlink.conf。

[Service].
ExecStartPre=/usr/bin/ln -sf /etc/flannel/options.env /run/flannel/options.env

Docker的配置设置.

接下来,我们将设置Docker使用flannel来管理集群的Pod网络。实施方法与之前所述的类似,需要在Docker启动之前启动flannel。

在这里我们尝试应用一个 systemd 的 drop-in,路径为 /etc/systemd/system/docker.service.d/40-flannel.conf。

[Unit]
Requires=flanneld.service
After=flanneld.service
[Service]
EnvironmentFile=/etc/kubernetes/cni/docker_opts_cni.env

以类似/etc/kubernetes/cni/docker_opts_cni.env的方式启动Docker CNI Options文件。

DOCKER_OPT_BIP=""
DOCKER_OPT_IPMASQ=""

如果依赖于Flannel Network,请按照以下方式进行Flannel CNI的配置:/etc/kubernetes/cni/net.d/10-flannel.conf。

{
    "name": "podnet",
    "type": "flannel",
    "delegate": {
        "isDefaultGateway": true
    }
}

创建Kubelet单元

让我们在Worker节点上创建以下kubelet服务。

创建/etc/systemd/system/kubelet.service。

将${ADVERTISE_IP}替换为节点的公共IP。

请将${DNS_SERVICE_IP}替换为10.3.0.10。

请将${MASTER_HOST}替换。

Environment=KUBELET_VERSION=v1.5.1_coreos.0
Environment="RKT_OPTS=--uuid-file-save=/var/run/kubelet-pod.uuid \
  --volume dns,kind=host,source=/etc/resolv.conf \
  --mount volume=dns,target=/etc/resolv.conf \
  --volume var-log,kind=host,source=/var/log \
  --mount volume=var-log,target=/var/log"
ExecStartPre=/usr/bin/mkdir -p /etc/kubernetes/manifests
ExecStartPre=/usr/bin/mkdir -p /var/log/containers
ExecStartPre=-/usr/bin/rkt rm --uuid-file=/var/run/kubelet-pod.uuid
ExecStart=/usr/lib/coreos/kubelet-wrapper \
  --api-servers=${MASTER_HOST} \
  --cni-conf-dir=/etc/kubernetes/cni/net.d \
  --network-plugin=cni \
  --container-runtime=docker \
  --register-node=true \
  --allow-privileged=true \
  --pod-manifest-path=/etc/kubernetes/manifests \
  --hostname-override=${ADVERTISE_IP} \
  --cluster_dns=${DNS_SERVICE_IP} \
  --cluster_domain=cluster.local \
  --kubeconfig=/etc/kubernetes/worker-kubeconfig.yaml \
  --tls-cert-file=/etc/kubernetes/ssl/worker.pem \
  --tls-private-key-file=/etc/kubernetes/ssl/worker-key.pem
ExecStop=-/usr/bin/rkt stop --uuid-file=/var/run/kubelet-pod.uuid
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

kubeproxy Pod的配置

创建etc/kubernetes/manifests/kube-proxy.yaml文件。

apiVersion: v1
kind: Pod
metadata:
  name: kube-proxy
  namespace: kube-system
spec:
  hostNetwork: true
  containers:
  - name: kube-proxy
    image: quay.io/coreos/hyperkube:v1.5.1_coreos.0
    command:
    - /hyperkube
    - proxy
    - --master=${MASTER_HOST}
    - --kubeconfig=/etc/kubernetes/worker-kubeconfig.yaml
    securityContext:
      privileged: true
    volumeMounts:
    - mountPath: /etc/ssl/certs
      name: "ssl-certs"
    - mountPath: /etc/kubernetes/worker-kubeconfig.yaml
      name: "kubeconfig"
      readOnly: true
    - mountPath: /etc/kubernetes/ssl
      name: "etc-kube-ssl"
      readOnly: true
  volumes:
  - name: "ssl-certs"
    hostPath:
      path: "/usr/share/ca-certificates"
  - name: "kubeconfig"
    hostPath:
      path: "/etc/kubernetes/worker-kubeconfig.yaml"
  - name: "etc-kube-ssl"
    hostPath:
      path: "/etc/kubernetes/ssl"

kubeconfig的配置

为了让Kubernetes组件能够安全地进行通信,我们使用kubeconfig来定义身份验证设置。在这个特定的用例中,kubelet和proxy会根据加载的配置来与API进行通信。

首先创建一个文件。创建/etc/kubernetes/worker-kubeconfig.yaml。

/etc/kubernetes/worker-kubeconfig.yaml
apiVersion: v1
kind: Config
clusters:
- name: local
  cluster:
    certificate-authority: /etc/kubernetes/ssl/ca.pem
users:
- name: kubelet
  user:
    client-certificate: /etc/kubernetes/ssl/worker.pem
    client-key: /etc/kubernetes/ssl/worker-key.pem
contexts:
- context:
    cluster: local
    user: kubelet
  name: kubelet-context
current-context: kubelet-context

服务开始

工人服务的准备工作已经完成。

读取更改的内容

让系统重新扫描磁盘以更新所做的更改。

$ sudo systemctl daemon-reload

启动kubelet和flannel。

启动kubelet并启动代理。

$ sudo systemctl start flanneld
$ sudo systemctl start kubelet

每次启动时都会强制启动服务。

$ sudo systemctl enable flanneld
Created symlink from /etc/systemd/system/multi-user.target.wants/flanneld.service to /etc/systemd/system/flanneld.service.
$ sudo systemctl enable kubelet
Created symlink from /etc/systemd/system/multi-user.target.wants/kubelet.service to /etc/systemd/system/kubelet.service.
To check the health of the kubelet systemd unit that we created, run systemctl status kubelet.service.

結果

在座的各位,恭喜您读到这里。您可以轻松地在CoreOS集群上设置并运行Kubernetes。有关Kubernetes的更多详细信息,请参考本教程的其他文章。需要注意的是,请确保正确修改IP地址并在集群上运行。辛苦了。

你有阿里云的账号吗?注册一个账号,免费试用40多款产品。有关详细信息,请参考开始使用阿里云。

阿里巴巴云拥有两个数据中心在日本,并拥有超过60个可用区域,是亚太地区第一大云基础设施提供商(2019年加特纳)。更多阿里巴巴云的详细信息请点击这里。阿里巴巴云日本官方页面。

广告
将在 10 秒后关闭
bannerAds