默认的 DC/OS Kubernetes 包安装为尝试服务提供合理的默认设置。 此页面描述了许多选项,可以启用选择性功能或允许您更改 分配给 Kubernetes 集群的资源。
先决条件
为了使用默认参数运行框架,您的集群至少必须有一个专用代理以及运行下表所述任务所需的可用资源:
每个集群的实例 | 每个 CPU 的实例 | 每个实例的 Mem (MB) | 每个实例的磁盘空间 (MB) | |
---|---|---|---|---|
Package scheduler | 1 | 1 | 1024 | - |
etcd | 1 | 0.5 | 1024 | 3072 for data, 512 for logs |
kube-apiserver | 1 | 0.5 | 1024 | - |
kube-scheduler | 1 | 0.5 | 512 | - |
kube-controller-manager | 1 | 0.5 | 512 | - |
kube-proxy | 1 | 0.1 | 512 | - |
kubelet | 1 | 3 | 3072 | 10240 |
如果需要高可用性,则必须启用kubernetes.high_availability
包选项,且建议至少使用三个私有代理。在高可用性模式运行任务需以下资源:
每个集群的实例 | 每个 CPU 的实例 | 每个实例的 Mem (MB) | 每个实例的磁盘空间 (MB) | |
---|---|---|---|---|
包调度器 | 1 | 1 | 1024 | - |
etcd | 3 | 0.5 | 1024 | 3072 用于数据,512 用于日志 |
kube-apiserver | 3 | 0.5 | 1024 | - |
kube-scheduler | 3 | 0.5 | 512 | - |
kube-controller-manager | 3 | 0.5 | 512 | - |
kube-proxy | 1 | 0.1 | 512 | - |
kubelet | 1 | 3 | 3072 | 10240 |
更改 Kubernetes 节点资源规格
如上表所示,默认是 3 个 CPU、3GB RAM 和 10GB 磁盘。但是,kubelet
和容器运行时将保留 1 个 CPU 和 1GB RAM。这意味着每个 Kubernetes 节点都有 2 个 CPU、2GB RAM 和 10GB 磁盘,可分配给 Kubernetes pod。
有关详细信息,请阅读 Kubernetes node-allocatable 的官方文档。
DC/OS Kubernetes 允许您单独指定公用节点和专用节点的资源。
例如,我们要请求两个带 1 个 CPU、1 GB RAM 和 512 MB 磁盘的专用 Kubernetes 节点以及一个带 1 个 CPU、1GB RAM 和 512MB 磁盘的公用 Kubernetes 节点 。
创建 JSON 选项文件,或编辑现有的文件:
{
"kubernetes": {
"node_count": 2,
"reserved_resources": {
"kube_cpus": 1,
"kube_mem": 1024,
"kube_disk": 512
},
"public_node_count": 1,
"public_reserved_resources": {
"kube_cpus": 1,
"kube_mem": 1024,
"kube_disk": 512
},
}
}
假设您将文件保存为 options.json
,按如下方式安装包:
dcos package install kubernetes --options=options.json
更改 Kubernetes 节点数量
DC/OS Kubernetes 允许您指定集群中的专用和公用 Kubernetes 节点数量。
专用节点
默认的专用节点计数为 1。要更改此值,请在 JSON 选项文件中指定 kubernetes.node_count
,如下所示。
例如,我们要请求 10 个专用 Kubernetes 节点。
创建 JSON 选项文件,或编辑现有的文件:
{
"kubernetes": {
"node_count": 10
}
}
假设您将文件保存为 options.json
,按如下方式安装包:
dcos package install kubernetes --options=options.json
公用节点
默认的公用节点计数为 0。要更改此值,请在 JSON 选项文件中指定 kubernetes.public_node_count
,如下所示。
例如,我们要在之前前 10 个专用 Kubernetes 节点的基础上请求 2 个额外的 Kubernetes 节点。
按如下方式编辑现有选项文件:
{
"kubernetes": {
"node_count": 10,
"public_node_count": 2
}
}
布局约束
布局约束允许您自定义 DC/OS 集群中部署服务的位置。布局约束使用 Marathon 运营商 语法。例如,[["hostname", "UNIQUE"]]
确保每个代理最多部署一个 Pod。
通用任务是指定要对其进行部署的白名单系统列表。为此,请使用以下语法用于布局约束:
[["hostname", "LIKE", "10.0.0.159|10.0.1.202|10.0.3.3"]]
选项示例:
{
"kubernetes": {
"control_plane_placement": "[[\"disk\",\"IS\",\"fast-ssd\"]]",
"node_placement": "[\"hostname\",\"UNIQUE\"]",
"public_node_placement": "[\"hostname\",\"UNIQUE\"]"
}
}
更新布局约束
集群更改,那么您的布局约束也会更改。但是,已经运行的 pod 将不会受到布局约束变化的影响。这是因为更改布局约束可能使正在运行的 pod 的当前布局失效,而且 pod 不会被自动迁移,因为这种操作具有破坏性。我们建议使用以下程序更新 Pod 的布局约束:
- 更新服务中的布局约束定义。
- 针对每个受影响的 pod,一次执行一个 pod 替换。这将(破坏性地)移动 Pod 使其符合新的布局约束。
TLS
该包可在可能的情况下为共同身份认证和通信加密强制执行 TLS。如下,您可以找到有关它何地、何时、如何发生的更多详细信息。
加密和共同身份认证
用于共同身份认证和通信加密的 TLS 实施为:
etcd
集群 peer - 仅启用加密,而不是共同身份认证,因为etcd
不会基于所提供的主机名,而是基于 IP 地址上验证 peer 证书 peer 视为 peer 或 DC/OS 不支持的 DNS SRV 发现。etcd
client-server - 同时启用加密和共同身份认证。唯一就位的客户端 是kube-apiserver
,这意味着 Kubernetes API 和etcd
之间的通信可靠。- 所有 Kubernetes 组件均启用加密和共同身份认证,包括
kube-apiserver
、kube-scheduler
、kube-controller-manager
、kube-proxy
和kubelet
。 - 所有都包含(必须)插件,包括按需备份/恢复,尊重针对 Kubernetes API 的共同身份认证。
TLS 开源 vs 企业 DC/OS
TLS 工件,如密钥对(私和公)以及证书的创建、签名和交换,是用于证明实体(例如,人、组织、应用程序等等)的身份,目的在于建立信任。要建立此信任,则需要公钥基础架构或 PKI。过去,此包只有在 DC/OS Enterprise 上运行时才完全支持 TLS,因为只有此版本提供 PKI 所需的机制:
- DC/OS CA - 集中化证书授权 (CA) 用于验证和最终签署证书签名请求 (CSR)。
- DC/OS 密码 - 一种向包组件分配 TLS 工件的集中、安全方式,例如,Kubernetes 组件和 在同一 DC/OS 集群中的其他应用程序。
- DC/OS 服务帐户 - 我们的包和 应用程序所需,以对上述服务进行身份认证。
开源 DC/OS 不提供此类功能。问题是我们如何在开源 DC/OS 上实施 TLS? 答案如下图所示:
图 1. TLS 设计
利用企业 DC/OS PKI
为了在设置 TLS 时充分利用 DC/OS Enterprise PKI 基础架构,需要有权限管理 CA 和密码的 服务账户。在安装 Kubernetes 包之前, 必须 进行配置。
为了配置此类服务帐户,首先需要安装 DC/OS Enterprise CLI。然后,执行以下操作:
dcos security org service-accounts keypair private-key.pem public-key.pem
dcos security org service-accounts delete kubernetes
dcos security org service-accounts create -p public-key.pem -d 'Kubernetes service account' kubernetes
dcos security secrets delete kubernetes/sa
dcos security secrets create-sa-secret private-key.pem kubernetes kubernetes/sa
dcos security org groups add_user superusers kubernetes
下一步,您需要 授予 服务帐户正确的权限。
所需权限为:
dcos:mesos:master:framework:role:<service name>-role create
dcos:mesos:master:task:user:root create
dcos:mesos:agent:task:user:root create
dcos:mesos:master:reservation:role:<service name>-role create
dcos:mesos:master:reservation:principal:<service name> delete
dcos:mesos:master:volume:role:<service name>-role create
dcos:mesos:master:volume:principal:<service name> delete
dcos:service:marathon:marathon:services:/ create
dcos:service:marathon:marathon:services:/ delete
dcos:secrets:default:/<service name>/* full
dcos:secrets:list:default:/<service name> read
dcos:adminrouter:ops:ca:rw full
dcos:adminrouter:ops:ca:ro full
dcos:mesos:master:framework:role:slave_public/<service name>-role create
dcos:mesos:master:framework:role:slave_public/<service name>-role read
dcos:mesos:master:reservation:role:slave_public/<service name>-role create
dcos:mesos:master:volume:role:slave_public/<service name>-role create
dcos:mesos:master:framework:role:slave_public read
dcos:mesos:agent:framework:role:slave_public read
其中 <service name>
是要安装的服务的名称, e.g. kubernetes
。
最后,您需要告诉包安装程序您刚刚创建的服务帐户,以及 如何查找其凭据。创建 JSON 选项文件,或编辑现有的文件:
{
"service": {
"service_account": "kubernetes",
"service_account_secret": "kubernetes/sa"
}
}
假设您将文件保存为 options.json
,按如下方式安装包:
dcos package install kubernetes --options=options.json
当您有代理时
某些用户可以在其 DC/OS 集群和互联网之间进行代理设置。这导致安装此包出现问题,即无法运行 kube-dns
以及其他插件 pod。以下是此类故障的示例:
Normal Created 5m (x2502 over 8d) kubelet, kube-node-5-kubelet.kubernetes.mesos Created container
Normal Started 5m (x2502 over 8d) kubelet, kube-node-5-kubelet.kubernetes.mesos Started container
Normal Pulled 5m (x2501 over 8d) kubelet, kube-node-5-kubelet.kubernetes.mesos Container image "gcr.io/google_containers/k8s-dns-dnsmasq-nanny-amd64:1.14.5" already present on machine
Warning BackOff 3m (x32719 over 8d) kubelet, kube-node-5-kubelet.kubernetes.mesos Back-off restarting failed container
Warning Unhealthy 3m (x10009 over 8d) kubelet, kube-node-5-kubelet.kubernetes.mesos Liveness probe failed: Get http://9.0.6.3:10054/healthcheck/dnsmasq: net/http: request canceled (Client.Timeout exceeded while awaiting headers)
Normal Pulled 3m (x2645 over 8d) kubelet, kube-node-5-kubelet.kubernetes.mesos Container image "gcr.io/google_containers/k8s-dns-sidecar-amd64:1.14.5" already present on machine
Normal Created 3m (x2646 over 8d) kubelet, kube-node-5-kubelet.kubernetes.mesos Created container
Normal Killing 3m (x2502 over 8d) kubelet, kube-node-5-kubelet.kubernetes.mesos Killing container with id docker://dnsmasq:pod "kube-dns-2102953216-qwvtn_kube-system(fd285861-ce3a-11e7-9ca9-005056945d21)" container "dnsmasq" is unhealthy, it will be killed and re-created.
(...)
这里的问题是,kubelet
无法 HTTP GET kube-dns
用于活跃度和准备度探测的端点,因此容器始终在重新启动。但为什么会发生这种情况呢? 设置 HTTP_PROXY
和/或
DC/OS 代理上的 HTTPS_PROXY
导致 kubelet
任务继承相同的值,因此强制 kubelet
尝试和使用代理来进入其管理的容器。
解决方案是,指定另一个环境变量,NO_PROXY
,以便 kubelet
知道不应该使用 Kubernetes pod 容器的 HTTP GET 代理,例如,将 NO_PROXY
值设置到 Kubernetes pod 覆盖子网,NO_PROXY=9.0.0.0/8
。
当使用 10.100.0.0/16 时
默认情况下,Kubernetes 集群将使用 10.100.0.0/16
作为服务 CIDR。
如果是这种情况,则需要对 Kubernetes 集群服务 CIDR 进行更改。
创建 JSON 选项文件,或编辑现有的文件:
{
"kubernetes": {
"service_cidr": "<YOUR_CIDR_HERE>"
}
}
假设您将文件保存为 options.json
,按如下方式安装包:
dcos package install kubernetes --options=options.json
启用云提供商集成
Kubernetes 为选择性集成提供许多公用和专用云提供商。
目前,此包支持:
以下,您将找到有关如何选择性地让您的 Kubernetes 集群 与云提供商集成。
AWS
IAM 政策和标签
每个节点的 IAM 策略需要针对 Kubernetes 正确就位,以利用 与 AWS 集成的优势。
以下是允许您成功集成的 IAM 政策示例:
{
"Resource": "*",
"Action": [
"ec2:CreateTags",
"ec2:DescribeInstances",
"ec2:CreateVolume",
"ec2:DeleteVolume",
"ec2:AttachVolume",
"ec2:DetachVolume",
"ec2:DescribeVolumes",
"ec2:DescribeVolumeStatus",
"ec2:DescribeVolumeAttribute",
"ec2:CreateSnapshot",
"ec2:CopySnapshot",
"ec2:DeleteSnapshot",
"ec2:DescribeSnapshots",
"ec2:DescribeSnapshotAttribute",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:CreateRoute",
"ec2:CreateSecurityGroup",
"ec2:DeleteSecurityGroup",
"ec2:DeleteRoute",
"ec2:DescribeRouteTables",
"ec2:DescribeSubnets",
"ec2:DescribeSecurityGroups",
"ec2:ModifyInstanceAttribute",
"ec2:RevokeSecurityGroupIngress",
"elasticloadbalancing:AttachLoadBalancerToSubnets",
"elasticloadbalancing:ApplySecurityGroupsToLoadBalancer",
"elasticloadbalancing:CreateLoadBalancer",
"elasticloadbalancing:CreateLoadBalancerPolicy",
"elasticloadbalancing:CreateLoadBalancerListeners",
"elasticloadbalancing:ConfigureHealthCheck",
"elasticloadbalancing:DeleteLoadBalancer",
"elasticloadbalancing:DeleteLoadBalancerListeners",
"elasticloadbalancing:DescribeLoadBalancers",
"elasticloadbalancing:DescribeLoadBalancerAttributes",
"elasticloadbalancing:DetachLoadBalancerFromSubnets",
"elasticloadbalancing:DeregisterInstancesFromLoadBalancer",
"elasticloadbalancing:ModifyLoadBalancerAttributes",
"elasticloadbalancing:RegisterInstancesWithLoadBalancer",
"elasticloadbalancing:SetLoadBalancerPoliciesForBackendServer"
],
"Effect": "Allow"
}
另外,需要指定标签以及密钥 KubernetesCluster
。
确保此标签的值在 AWS 帐户的所有标签中都是唯一值
并应用到与节点关联的自动扩展和安全组:
{
"Tags" : [
{
"Key" : "KubernetesCluster",
"Value" : "kubernetes-cluster"
}
]
}
为了启用 AWS 云提供商集成,您必须将 kubernetes.cloud_provider
选项添加到包选项 JSON 文件:
{
"kubernetes": {
"cloud_provider": "aws"
}
}
假设您将文件保存为 options.json
,按如下方式安装包:
dcos package install kubernetes --options=options.json
StorageClass
配置 为了能够为您的 pod 请求存储,您必须在安装包之后至少创建一个 StorageClass
资源。在执行此操作之前,强烈建议您要大体上
熟悉 Amazon EBS、Kubernetes
存储类,
而且要对
AWS 特定选项
特别熟悉。
举个例子,要使用
通用固态硬盘
卷作为您集群中卷的默认存储类型,您必须创建
以下 StorageClass
资源:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: ssd
annotations:
storageclass.kubernetes.io/is-default-class: "true"
labels:
kubernetes.io/cluster-service: "true"
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp2
storageclass.kubernetes.io/is-default-class: "true"
注解
保证每个没有特性存储类的 PersistentVolumeClaim
会使用您刚刚定义的 ssd
类。当然,
除默认设置外,您可以根据需要创建多个存储类。举个
例子,要为非频繁访问的数据创建类,您可以创建
以下 StorageClass
资源:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: cold-hdd
labels:
kubernetes.io/cluster-service: "true"
provisioner: kubernetes.io/aws-ebs
parameters:
type: sc1
要使用 pod 中的 cold-hdd
存储类,您必须首先创建
参照该存储类的 PersistentVolumeClaim
:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: http-archive
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 500Gi
storageClassName: cold-hdd
最后,您必须参照 pod 中的 PersistentVolumeClaim
,您将
准备就绪:
apiVersion: v1
kind: Pod
metadata:
name: http-archive
spec:
containers:
- name: nginx
image: nginx:1.12.2-alpine
ports:
- containerPort: 80
name: http
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: data
volumes:
- name: data
persistentVolumeClaim:
claimName: http-archive
Ingress
支持
Ingress
资源在 Kubernetes 中很特别,并不包含管理它的
内置控制器。这与
PersistentVolumeClaim
或 LoadBalancer
-类型 Service
等资源相反,
其 Kubernetes 包含内置控制器和与云提供商的集成。
因此,要使用 Ingress
AWS 中的资源,您必须部署自定义
ingress 控制器。请参阅
Ingress
文档,以了解有关在您的
集群中设置 ingress 的示例和重要信息。