Table of Contents

安装Kubernetes Master和Minions

验证网络

ServiceAccount错误

玩K8S

运行Kubernetes留言簿(无GCE,无DNS)

在Kubernetes上运行多节点Galera Mysql

调试器Pod

为Kubernetes设置DNS

运行Heapster监视Kubernetes容器

运行Docker Registry

为C8S卷启用Ceph

K8S缺点的思考

推荐阅读


在本文中,我安装了k8s集群,尝试设置托管真实Web服务所需的所有服务,然后进行总结。

安装Kubernetes Master和Minions

要安装Kubernetes,我遵循了Somenines的指南。注意

  • 防火墙已关闭
  • Kubernetes软件包的安装者 yum
  • 我使用Kubernetes版本1.0

我设置了一个主3小兵部署。如果使用的是vmware / virtualbox,请确保在vswitch上启用混杂模式。我没有实现HA。对于Kubernetes的HA部署,请参考官方的HA指南。我的k8s版本如下

$ kubectl version
Client Version: version.Info{Major:"1", Minor:"0+", GitVersion:"v1.0.0-290-gb2dafdaef5acea", GitCommit:"b2dafdaef5aceafad503ab56254b60f80da9e980", GitTreeState:"clean"}
Server Version: version.Info{Major:"1", Minor:"0+", GitVersion:"v1.0.0-290-gb2dafdaef5acea", GitCommit:"b2dafdaef5aceafad503ab56254b60f80da9e980", GitTreeState:"clean"}$ uname -r
3.10.0-229.el7.x86_64

在主节点上启动服务

$ for SERVICES in etcd kube-apiserver kube-controller-manager kube-scheduler; do systemctl restart $SERVICESsystemctl enable $SERVICESsystemctl status $SERVICES
done

在小仆节点上启动服务。请注意,我们需要比flanneld早启动docker,否则docker可能不会使用法兰绒网络。

$ for SERVICES in kube-proxy kubelet flanneld docker; do     # Launch flannel earilier than dockersystemctl restart $SERVICESsystemctl enable $SERVICESsystemctl status $SERVICES
done

验证网络

基本上,要让docker使用法兰绒网络,您需要添加--bip=${FLANNEL_SUBNET} --mtu=${FLANNEL_MTU}到docker daemon启动选项。但是上面的安装将自动为您完成。

source /var/run/flannel/subnet.env
docker -d --bip=${FLANNEL_SUBNET} --mtu=${FLANNEL_MTU}

使用ps -ef|grep docker检查泊坞窗守护进程选项。您应该能够看到docker需要法兰绒的Systemd单位文件

ps -ef | grep docker
cat /etc/systemd/system/docker.service.requires/flanneld.service

绒布网络运行后,每个主机上的每个容器都应使用不同的IP。他们应该能够ping通对方的IP地址。在下面使用以启动临时容器进行测试

docker run -d ubuntu:trusty /bin/bash -c "while true; do echo hello; sleep 10; done"

参考文献:[1] [2]

ServiceAccount错误

如果碰到下面的错误,取出ServiceAccount/etc/kubernetes/apiserver::KUBE_ADMISSION_CONTROL。只需删除即可ServiceAccount。(问题11222)。然后重新启动主节点。

$ kubectl create -f redis-master1.yaml
Error from server: error when creating "redis-master1.yaml": Pod "redis-master1" is forbidden: no API token found for service account default/default, retry after the token is automatically created and added to the service account

玩K8S

通过在k8s上设置一系列通用服务,我试图弄清楚如何在k8s上托管生产级别的网站。那里需要多节点数据库,卷,负载平衡,缓存(redis / memcached),dns和监视。

运行Kubernetes留言簿(无GCE,无DNS)

我正在使用kubernetes版本1.0。要在没有GCE,没有DNS的情况下仅在CentOS 7上运行留言簿。请遵循官方指南。

git clone https://github.com/kubernetes/kubernetes.git
cd kubernetes
git checkout 5adae4e4a35202abe1c130e32240d0461b3a1c36    # the version which I experimented with

创建Redis主Pod和服务

kubectl create -f examples/guestbook/redis-master-controller.yaml
kubectl get pods -o wide --all-namespaces=true
kubectl create -f examples/guestbook/redis-master-service.yaml

创建Redis奴隶

vim examples/guestbook/redis-slave-controller.yaml
...    # comment out 'value: dns', uncomment `value: env` under GET_HOSTS_FROM
kubectl create -f examples/guestbook/redis-slave-controller.yaml
kubectl create -f examples/guestbook/redis-slave-service.yaml
kubectl logs redis-slave-*    # should show successfully sync with master

创建前端控制器

vim examples/guestbook/frontend-controller.yaml
...    # comment out 'value: dns', uncomment `value: env` under GET_HOSTS_FROM
kubectl create -f examples/guestbook/frontend-controller.yaml
kubectl create -f examples/guestbook/frontend-service.yaml

要在外部公开前端服务,我使用NodePort。查看发布服务

vim examples/guestbook/frontend-services.yaml
...    # Write `type: NodePort` under `spec`.
kubectl delete service frontend
kubectl create -f examples/guestbook/frontend-service.yaml# to see which port is mapped
kubectl describe service frontend | grep NodePort    # in my case the nodeport is 30363

你以后打开防火墙或iptables的,你应该能够从访问Web前端http://<any-minion-ip>:<nodeport>

签出redis中保存的内容

# on a k8s minion
$ docker exec -it k8s_worker.8bef144a_redis-slave-usfge_default_88895109-57a2-11e5-9a9e-005056957d30_3156e0e8 /bin/bash
$ redis-cli keys \*
1) "messages"
$ redis-cli get messages
",hello world,123,456"

或者只是通过Web浏览器获取它http://<any-minion-ip>:<nodeport>/guestbook.php?cmd=get&key=messages

在Kubernetes上运行多节点Galera Mysql

要在k8s上运行galera mysql,一种解决方案是Planet Mysql的解决方案(我认为博客内容与其代码库相比有些过时了)。检出其entrypoint.sh。关键是每个galera实例如何找到其他人的地址。Planet Mysql的解决方案使用k8s服务环境变量来定位其他主机并将其写入gcomm://。每个mysql galera实例都包含一个pod和一个服务。

我可以想到的一些解决方案,可以帮助galera mysql实例定位其对等对象,除了Planet Mysql的

  • 每个mysql galera实例都包含一个pod和一个服务。我们只是将IP地址硬编码在pod yaml中。如果一个pod掉了,我们手动填写最新的ip和启动一个新实例。
  • 我们在k8s上启动一个etcd集群,所有galera mysql实例都从etcd找到对等信息。

无论如何,我现在将使用Planet Mysql的解决方案。PS除了galera之外,要托管mysql集群,还需要在k8s上提供mysql分片解决方案,例如youtube的Vitess Mysql。

首先,下载代码库

git clone https://github.com/CaptTofu/mysql_replication_kubernetes.git
cd mysql_replication_kubernetes
git checkout f7c2bc4f411d6950ca575e804189114026b2ba69     # the version I experimented with
cd galera_sync_replication

我认为我们应该根据容器映像的entrypoint.sh将所有设置WSREP_CLUSTER_ADDRESSgcomm://每个pxc-nodeN 。

vim pxc-node1.yaml
...    # change variable WSREP_CLUSTER_ADDRESS to gcomm://
vim pxc-node2.yaml
...    # same as above
vim pxc-node3.yaml
...    # same as above

接下来,我们逐一启动galera mysql实例

kubectl create -f pxc-node1.yaml
kubectl create -f pxc-node1-service.yaml

等待第一个galera mysql实例正在运行。比下面的发射。这是因为galera mysql需要至少运行一个实例来形成集群。

kubectl create -f pxc-node2.yaml
kubectl create -f pxc-node2-service.yaml
kubectl create -f pxc-node3.yaml
kubectl create -f pxc-node3-service.yaml

验证正确性。请参阅galera mysql状态指南。

# check the pod log
kubectl logs pxc-node3# check galera mysql status
kubectl get pods -o wide
docker exec -it 98d568b88aac  /bin/bash
mysql -uroot -p
mysql> SHOW GLOBAL STATUS LIKE 'wsrep_%';    # You should be able to see cluster_size = 3# write something to mysql and check the other node reading it
...

我认为k8s服务设计可能不适用于galera mysql,redis,memcached等p2p集群。

  • 在集群中,例如galera mysql,为什么要强制为每个实例耦合一个服务?
  • 如果应用程序想要使用此类群集提供的服务(例如memcached),则需要知道它们的每个IP /主机名,因为一致的哈希,负载平衡和故障转移是在应用程序端执行的。很难仅将集群隐藏在一项服务下,该服务公开一个IP。

因此,我认为更合适的方法是从k8s外部提供这些服务,例如mysql,redis和memcached。但是,无状态Web应用程序更适合在k8s上运行。

调试器Pod

有时我需要一个简单的Pod来调试和测试与其他Pod的网络连接。这是我的豆荚yaml。

debugvm.yaml
apiVersion: v1
kind: Pod
metadata:name: debugvmlabels:name: debugvm
spec:containers:- name: debugvmimage: ubuntu:trustycommand: [ "bin/bash", "-c", "while true; do echo 'hello world'; sleep 60; done" ]

在k8s中启动后,登录到debugvm并使用nc测试到其他Pod的网络连接

docker exec -it k8s_debugvm.* /bin/bash
nc <host> <port>
运行多节点Redis以在Kubernetes上进行内存缓存
对于Web应用程序来说,使用Redis或Memcached群集作为内存中缓存非常流行。我启动一个3节点Redis集群。每个Redis都不知道其同级对象。每个redis实例都包含一个pod和一个服务。这是redis实例1
# the redis-master1.yaml
apiVersion: v1
kind: Pod
metadata:name: redis-master1labels:name: redis-master1
spec:containers:- name: redis-master1image: redisports:- containerPort: 6379# the redis-master1-service.yaml
apiVersion: v1
kind: Service
metadata:name: redis-master1labels:name: redis-master1
spec:ports:# the default redis serving port- port: 6379targetPort: 6379selector:name: redis-master1type: NodePort

对于redis实例2和3,只需将更1改为2或即可3。Web应用程序要使用3个Redis实例作为缓存集群,需要自己执行一致的哈希并选择要访问的Redis实例。如果使用PHP,lib Predis可以做到这一点。

为什么我需要在每个Redis实例上附加一个k8s服务?客户端需要知道redis实例的每个IP并执行一致的哈希。但是,一个k8s服务仅在IP上公开。对于需要客户端分片/负载平衡/故障转移或任何客户端人员的群集,客户端需要了解更多IP。默认的k8s服务模型不太适合。

为Kubernetes设置DNS

Kuberetes可以使用dns服务进行服务发现。参见官方文档。DNS是一个k8s插件。我按照本指南设置了dns。该cluster_dns地址应在/ etc / kubernetes / apiserver KUBE_SERVICE_ADDRESSES中指定的范围内。

# on each kubelet server# add '--cluster_dns=10.254.0.10 --cluster_domain=cluster.local' to KUBELET_ARGS
vim /etc/kubernetes/kubelet# restate kubelet
systemctl daemon-reload
systemctl restart kubelet

启动dns服务,下面是清单。从k8s repo复制和编辑。

apiVersion: v1
kind: Service
metadata:name: kube-dnsnamespace: defaultlabels:k8s-app: kube-dnskubernetes.io/cluster-service: "true"kubernetes.io/name: "KubeDNS"
spec:selector:k8s-app: kube-dnsclusterIP: 10.254.0.10ports:- name: dnsport: 53protocol: UDP- name: dns-tcpport: 53protocol: TCP

启动dns pod,下面是清单。在设置之前,我尝试了几种不同的清单。

这是从这里复制和编辑的。不要使用它。它的问题12534。

apiVersion: v1
kind: ReplicationController
metadata:name: kube-dnsnamespace: defaultlabels:k8s-app: kube-dnskubernetes.io/cluster-service: "true"
spec:replicas: 1selector:k8s-app: kube-dnstemplate:metadata:labels:k8s-app: kube-dnskubernetes.io/cluster-service: "true"spec:dnsPolicy: "Default"  # Don't use cluster DNS.containers:- name: etcdimage: quay.io/coreos/etcd:latestcommand: ["/etcd","--listen-client-urls","http://127.0.0.1:2379,http://127.0.0.1:4001","--advertise-client-urls","http://127.0.0.1:2379,http://127.0.0.1:4001",]- name: kube2skyimage: gcr.io/google_containers/kube2sky:1.11args: [# entrypoint = "/kube2sky","-domain=cluster.local",]- name: skydnsimage: kubernetes/skydns:2014-12-23-001args: [# entrypoint = "/skydns","-machines=http://localhost:4001","-addr=0.0.0.0:53","-domain=cluster.local",]ports:- name: dnscontainerPort: 53protocol: UDP

这是从k8s repo版本复制并编辑的。它具有相同的问题12534。

apiVersion: v1
kind: ReplicationController
metadata:name: kube-dns-v9namespace: defaultlabels:k8s-app: kube-dnsversion: v9kubernetes.io/cluster-service: "true"
spec:replicas: 1selector:k8s-app: kube-dnsversion: v9template:metadata:labels:k8s-app: kube-dnsversion: v9kubernetes.io/cluster-service: "true"spec:containers:- name: etcdimage: gcr.io/google_containers/etcd:2.0.9resources:limits:cpu: 100mmemory: 50Micommand:- /usr/local/bin/etcd- -data-dir- /var/etcd/data- -listen-client-urls- http://127.0.0.1:2379,http://127.0.0.1:4001- -advertise-client-urls- http://127.0.0.1:2379,http://127.0.0.1:4001- -initial-cluster-token- skydns-etcdvolumeMounts:- name: etcd-storagemountPath: /var/etcd/data- name: kube2skyimage: gcr.io/google_containers/kube2sky:1.11resources:limits:cpu: 100mmemory: 50Miargs:# command = "/kube2sky"- -domain=cluster.local- name: skydnsimage: gcr.io/google_containers/skydns:2015-03-11-001resources:limits:cpu: 100mmemory: 50Miargs:# command = "/skydns"- -machines=http://localhost:4001- -addr=0.0.0.0:53- -domain=cluster.local.ports:- containerPort: 53name: dnsprotocol: UDP- containerPort: 53name: dns-tcpprotocol: TCPlivenessProbe:httpGet:path: /healthzport: 8080scheme: HTTPinitialDelaySeconds: 30timeoutSeconds: 5readinessProbe:httpGet:path: /healthzport: 8080scheme: HTTPinitialDelaySeconds: 1timeoutSeconds: 5- name: healthzimage: gcr.io/google_containers/exechealthz:1.0resources:limits:cpu: 10mmemory: 20Miargs:- -cmd=nslookup kubernetes.default.svc.cluster.local localhost >/dev/null- -port=8080ports:- containerPort: 8080protocol: TCPvolumes:- name: etcd-storageemptyDir: {}dnsPolicy: Default  # Don't use cluster DNS.

在研究了Guybrush的解决方案之后。我拼凑了一件作品。关键是缺少命令选项,-kube_master_url=http://<your-master-host-ip>:8080该选项可防止kube2sky访问kubernetes主节点,并在12534中引发错误。简单。

apiVersion: v1
kind: ReplicationController
metadata:name: kube-dns-v9namespace: defaultlabels:k8s-app: kube-dnsversion: v9kubernetes.io/cluster-service: "true"
spec:replicas: 1selector:k8s-app: kube-dnsversion: v9template:metadata:labels:k8s-app: kube-dnsversion: v9kubernetes.io/cluster-service: "true"spec:containers:- name: etcdimage: gcr.io/google_containers/etcd:2.0.9resources:limits:cpu: 100mmemory: 50Micommand:- /usr/local/bin/etcd- -data-dir- /var/etcd/data- -listen-client-urls- http://127.0.0.1:2379,http://127.0.0.1:4001- -advertise-client-urls- http://127.0.0.1:2379,http://127.0.0.1:4001- -initial-cluster-token- skydns-etcdvolumeMounts:- name: etcd-storagemountPath: /var/etcd/data- name: kube2skyimage: gcr.io/google_containers/kube2sky:1.11resources:limits:cpu: 100mmemory: 50Miargs:# command = "/kube2sky"- -kube_master_url=http://10.62.98.245:8080- -domain=cluster.local- name: skydnsimage: gcr.io/google_containers/skydns:2015-03-11-001resources:limits:cpu: 100mmemory: 50Miargs:# command = "/skydns"- -machines=http://localhost:4001- -addr=0.0.0.0:53- -domain=cluster.local.ports:- containerPort: 53name: dnsprotocol: UDP- containerPort: 53name: dns-tcpprotocol: TCPlivenessProbe:httpGet:path: /healthzport: 8080scheme: HTTPinitialDelaySeconds: 30timeoutSeconds: 5readinessProbe:httpGet:path: /healthzport: 8080scheme: HTTPinitialDelaySeconds: 1timeoutSeconds: 5- name: healthzimage: gcr.io/google_containers/exechealthz:1.0resources:limits:cpu: 10mmemory: 20Miargs:- -cmd=nslookup kubernetes.default.svc.cluster.local localhost >/dev/null- -port=8080ports:- containerPort: 8080protocol: TCPvolumes:- name: etcd-storageemptyDir: {}dnsPolicy: Default  # Don't use cluster DNS.

要验证dns是否有效,我遵循了本指南。首先,您检查每个Pod日志以进行验证。但是如果您可以忽略此错误

skydns: falling back to default configuration, could not read from etcd: 100: Key not found (/skydns) [2]

之后,创建一个busybox窗格

# busybox.yaml
apiVersion: v1
kind: Pod
metadata:name: busyboxnamespace: default
spec:containers:- image: busyboxcommand:- sleep- "3600"imagePullPolicy: IfNotPresentname: busyboxrestartPolicy: Always

在pod运行之后,运行以下命令,您应该会看到

$ kubectl exec busybox -- nslookup kubernetes
Server:    10.254.0.10
Address 1: 10.254.0.10Name:      kubernetes
Address 1: 10.254.0.1$ kubectl exec busybox -- nslookup kubernetes.default.svc.cluster.local
Server:    10.254.0.10
Address 1: 10.254.0.10Name:      kubernetes.default.svc.cluster.local
Address 1: 10.254.0.1

运行Heapster监视Kubernetes容器

我遵循官方指南来设置Heapster。

git clone https://github.com/kubernetes/heapster.git
kubectl create -f deploy/kube-config/influxdb/

如果您遇到以下错误

Error from server: error when creating "deploy/kube-config/influxdb/grafana-service.json": Service "monitoring-grafana" is forbidden: Namespace kube-system does not exist
Error from server: error when creating "deploy/kube-config/influxdb/heapster-controller.json": ReplicationController "heapster" is forbidden: Namespace kube-system does not exist
Error from server: error when creating "deploy/kube-config/influxdb/heapster-service.json": Service "heapster" is forbidden: Namespace kube-system does not exist
Error from server: error when creating "deploy/kube-config/influxdb/influxdb-grafana-controller.json": ReplicationController "infludb-grafana" is forbidden: Namespace kube-system does not exist
Error from server: error when creating "deploy/kube-config/influxdb/influxdb-service.json": Service "monitoring-influxdb" is forbidden: Namespace kube-system does not exist

这是因为您的k8s没有kube-system命名空间。解决方案是将所有内容都更改kube-systemdefault每个清单。

Heapster依靠k8s dns来工作。开始安装Heapster之前,必须先在k8s中启用dns。在这里发现类似的问题。

如果您检查heapster pod日志,发现heapster通过以下错误保持崩溃

$ kubectl logs heapster-yrh5i
...
open /var/run/secrets/kubernetes.io/serviceaccount/token: no such file or directory

问题在于,heapster缺少用于访问apiserver的serviceaccount。请参阅本指南。我的解决方案是“使用仅用于垃圾箱的服务帐户”。首先,在下面运行以创建服务帐户

cat <EOF | kubectl create -f -
apiVersion: v1
kind: ServiceAccount
metadata:name: heapster
EOF

之后,需要添加serviceAccount: "heapster"--source=kubernetes:http://kubernetes-ro?inClusterConfig=false&useServiceAccount=true&auth=规范。

"spec": {"serviceAccount": "heapster","containers": [{"image": "kubernetes/heapster:v0.18.0","name": "heapster","command": ["/heapster","--source=kubernetes:http://kubernetes-ro?inClusterConfig=false&useServiceAccount=true&auth=","--sink=influxdb:http://monitoring-influxdb:8086"]}]
}

如果遇到以下错误

$ kubectl logs heapster-yrh5i
...
Failed to list *api.Node: Get http://kubernetes-ro/api/v1/nodes: dial tcp: lookup kubernetes-ro: no such host
Failed to list *api.Namespace: Get http://kubernetes-ro/api/v1/namespaces: dial tcp: lookup kubernetes-ro: no such host
Failed to list *api.Pod: Get http://kubernetes-ro/api/v1/pods?fieldSelector=spec.nodeName%21%3D: dial tcp: lookup kubernetes-ro: no such host

这是因为上面kubernetes-ro的DNS无法解析。尝试kubectl exec busybox -- nslookup kubernetes-ro验证。该线程指示kubernetes-ro已弃用。因此将其更改为<kubeneters-master-ip>:8080(我希望我可以避免对IP进行硬编码)。

{"apiVersion": "v1","kind": "ReplicationController","metadata": {"labels": {"k8s-app" : "heapster","name": "heapster","version": "v6"},"name": "heapster","namespace": "default"},"spec": {"replicas": 1,"selector": {"k8s-app": "heapster","version": "v6"},"template": {"metadata": {"labels": {"k8s-app": "heapster","version": "v6"}},"spec": {"serviceAccount": "heapster","containers": [{"image": "kubernetes/heapster:v0.18.0","name": "heapster","command": ["/heapster","--source=kubernetes:http://10.62.98.245:8080?inClusterConfig=false&useServiceAccount=true&auth=","--sink=influxdb:http://monitoring-influxdb:8086","-v=20"]}]}}}
}

接下来,我需要更改每个服务清单。将服务类型更改为“ NodePort”。这样,即使没有GCD负载平衡器,我仍然可以从外部访问它们。重新启动所有服务。

"spec": {"type": "NodePort",

通过外部NodePort映射访问Grafana。用户名和密码为admin:admin。登录Grafana后,添加类型为InfluxDB 0.8.x,url http://monitoring-influxdb:8086,数据库名称为“ k8s”的数据源,数据库用户名和密码为root:root。

如果遇到以下错误,heapster将无法解析monitoring-influxdb,但是busybox仍然可以。那真是怪了。

$ kubectl logs heapster -k30m4
...
failed to sync data to sinks - encountered the following errors: Post http://monitoring-influxdb:8086/db/k8s/series?u=root&p=root&time_precision=s: dial tcp: lookup monitoring-influxdb: no such host ;
Post http://monitoring-influxdb:8086/db/k8s/series?u=root&p=root&time_precision=m: dial tcp: lookup monitoring-influxdb: no such host# try troubleshooting. why busybox can resolve dns, but heapster cannot?
$ kubectl exec heapster-k30m4 -- nslookup monitoring-influxdb
Server:    (null)
nslookup: can't resolve 'monitoring-influxdb': Try again
Address 1: ::1 localhost
Address 2: 127.0.0.1 localhost$ kubectl exec busybox -- nslookup monitoring-influxdb
Server:    10.254.0.10
Address 1: 10.254.0.10Name:      monitoring-influxdb
Address 1: 10.254.113.143$ kubectl exec heapster-k30m4 -- nslookup monitoring-influxdb 10.254.0.10
Server:    10.254.0.10
Address 1: 10.254.0.10nslookup: can't resolve 'monitoring-influxdb': Try again$ kubectl exec busybox -- nslookup monitoring-influxdb 10.254.0.10
Server:    10.254.0.10
Address 1: 10.254.0.10Name:      monitoring-influxdb
Address 1: 10.254.113.143# check skydns log, found
$ kubectl logs kube-dns-v9-f9j9m skydns
...
skydns: can not forward, name too short (less than 2 labels): `monitoring-influxdb.'

我没有找到原因和解决方案。但是有一个解决方法,让我们直接将主机名写到/ etc / hosts中。

kubectl exec heapster-fk6xo -- /bin/sh -c 'echo ${MONITORING_INFLUXDB_SERVICE_HOST} monitoring-influxdb >> /etc/hosts'
kubectl exec infludb-grafana-9wosh -- /bin/sh -c 'echo ${MONITORING_INFLUXDB_SERVICE_HOST} monitoring-influxdb >> /etc/hosts'

现在,如果您检查堆日志,它应该可以正常工作。按照本指南,让我们回到Grafana来设置仪表板。示例查询在这里,但已经过时了。可以在influxdb上运行的一些查询是

select derivative(value/1000000) from "cpu/usage_ns_cumulative" where $timeFilter and container_name = 'pxc-node1' group by time($interval) order asc
select mean(value/1024/1024) from "memory/usage_bytes_gauge" where $timeFilter and container_name = 'pxc-node1' group by time($interval) order asc

有关如何使用influxdb的提示(在其门户网站上)

  • root:root是集群管理员。创建数据库用户(管理员权限)并在访问数据库之前使用该用户登录。
  • 不要将数据库用户设置为与集群管理员同名。否则会产生奇怪的许可。(天哪,这花了我很多时间进行故障排除)
  • 用户list series看我们有什么表
  • 带有特殊字符的系列名称,例如cpu/limit_gauge,应使用引号引起来,例如select * "cpu/limit_gauge" limit 10
  • where子句中的字段名称应用单引号引起来,例如where container_name = 'pxc-node1'

在我设置Heapster时,无法收集容器网络io指标(始终为零)

  • 知道问题待解决。在centos上docker stats <container-id>无法捕获网络io。

也无法在Heapster中收集磁盘io指标

  • 知道问题。堆当前不拉磁盘io。
  • 可以通过查询kubelet stats api(例如)来检索原始磁盘IO curl 'http://<kubelet-ip>:10255/stats/default/pxc-node2/e2cf51fc-586e-11e5-9a9e-005056957d30/pxc-node2' | python -m json.tool。该网址中的ID号可以在docker ps容器名称中找到。
  • 另一种方法是查询docker daemon套接字,例如echo -e "GET /containers/<container-id>/stats HTTP/1.1\r\n" | nc -U /var/run/docker.sock | grep -e "^[[:space:]]*{.*}"。看到这篇文章。
  • 要了解diskio指标的含义,请注意,磁盘分区以Major:Minor号命名(lsblk请参见)。看这里。

运行Docker Registry

如果要构建自己的映像并在k8s上运行它们,则需要一个docker Registry。我在主节点上启动了Docker注册表,只需一行代码,请参阅官方指南。

docker run -d -p 5000:5000 --name registry registry:2

docker注册表应该现在正在运行。为了允许dockerd使用“不安全”的Docker注册表,我们需要--insecure-registry <docker-registry>:5000在每个节点上添加到/ etc / sysconfig / docker :: OPTIONS。dockerd然后重新启动。

为C8S卷启用Ceph

Ceph为k8提供持久的批量服务。接下来,我将使k8s将ceph用作卷后端。

安装Ceph

我获取了一个新的centos7 VM,在其上安装了一个1节点的ceph。首先,请确保

  • Kubernetes主节点和ceph节点无需密钥即可相互ssh
  • Kubernetes主节点可以解析ceph节点的主机名
  • ceph-deploy工具应在安装ceph的单独节点上运行

安装ceph-deploy工具

# on kube master node
yum install -y ceph-deploy
mkdir -p ~/workspace/ceph/
cd ~/workspace/ceph

在ceph节点上安装并启动ceph。跟随官方教程

# on kube master node
# clean old installation
ceph-deploy purgedata <ceph-node>
ceph-deploy forgetkeys
#ceph-deploy purge    # to purge the ceph packages too# install ceph
ceph-deploy install <ceph-node># create the cluster
ceph-deploy new <ceph-node># change ceph config
vim ./ceph.conf
...    # add `osd pool default size = 1`# launch monitor
ceph-deploy mon create-initial# launch osd
ceph-deploy disk list <ceph-node>
ceph-deploy osd prepare <ceph-node>:sdb
ceph-deploy osd activate <ceph-node>:/dev/sdb1# push admin keys to the ceph node so that I can login without specifying monitor address and key file
ceph-deploy admin <ceph-node>

验证ceph的健康状态。

# on the ceph node
# test ceph healthy status
ceph health
ceph pg dump# test ceph read write
ceph osd pool create data 128
echo hello world $(date) > test.txt
rados put test test.txt --pool data
rados get test test.txt.out --pool data
cat test.txt.out

接下来,在每个k8s节点上启用cephrbd客户端

# on kube master node
# install ceph so that `rbd` is installed
ceph-deploy install 127.0.0.1 <kubelet1-ip> <kubelet2-ip> <kubelet3-ip># copy ceph admin keys to each node
cd ~/workspace/ceph
ceph-deploy admin 127.0.0.1 <kubelet1-ip> <kubelet2-ip> <kubelet3-ip>

验证rbd是否正常工作

# on a randomly picked up k8s node
rbd create foo --size 1024
modprobe rbd
rbd map foomkfs.ext4 -m0 /dev/rbd/rbd/foo
mkdir /mnt/test-ceph-block-device
mount /dev/rbd/rbd/foo /mnt/test-ceph-block-device
cd /mnt/test-ceph-block-device
echo hello world $(date) > test.txt
cd ..
umount /dev/rbd/rbd/foo# on another k8s node
modprobe rbd
rbd map foo
mkdir /mnt/test-ceph-block-device
mount /dev/rbd/rbd/foo /mnt/test-ceph-block-device
cd /mnt/test-ceph-block-device
cat test.txt    # here should print what we `echo` before
cd ..
umount /dev/rbd/rbd/foo

在K8S中启用Ceph

遵循官方指南。首先确保/etc/ceph/ceph.client.admin.keyring每个k8s节点上都有k8s可以向ceph进行身份验证的操作系统。

vol1在使用k8s之前,我们需要创建该卷并对其进行mkfs。

# on kube master node
rbd create vol1 --size 1024 --pool data
mkfs.ext4 -m0 /dev/rbd/data/vol1
rbd unmap /dev/rbd/data/vol1

接下来,我们创建一个忙碌的Pod来装载该卷。吊舱清单如下。开始于kubectl create -f busyboxv.yaml

# busyboxv.yaml
apiVersion: v1
kind: Pod
metadata:name: busyboxvnamespace: default
spec:containers:- image: busyboxcommand:- sleep- "3600"imagePullPolicy: IfNotPresentname: busyboxvvolumeMounts: - mountPath: /mnt/rbdname: rbdpdvolumes:- name: rbdpdrbd: monitors: - <ceph-node>:6789pool: dataimage: vol1user: adminkeyring: /etc/ceph/ceph.client.admin.keyringfsType: ext4readOnly: falserestartPolicy: Always

我们在busyboxv pod卷中写入一些文件

# on kube master node
kubectl exec busyboxv -- sh -c 'echo hello world $(date) > /mnt/rbd/hello.txt'
kubectl exec busyboxv -- sh -c 'cat /mnt/rbd/hello.txt'

接下来,杀死豆荚。测试卷中的数据是否持久

# on kube master node
kubectl delete pod busyboxv
sleep 5
rbd map vol1 --pool data
mkdir -p /mnt/rbd/data/vol1
mount /dev/rbd/data/vol1 /mnt/rbd/data/vol1
cat /mnt/rbd/data/vol1/hello.txt
umount /dev/rbd/data/vol1
rbd unmap /dev/rbd/data/vol1

因此,k8s pod可以通过这种方式使用ceph卷。现在我们有了持久的数据存储。

K8S缺点的思考

乍一看,Kubernetes看起来很简单。但是,根据这些天的经验,如果您想设置完整的Web服务,尤其是当您不在GCE(Google Cloud Engine)上运行时,我发现k8缺少许多关键功能:

  • 如果我想使用外部或自定义负载均衡器(例如HAProxy)怎么办?Openstack具有LBaaS。但我希望在k8s中看到它。K8s服务可以进行负载平衡,但它不是功能齐全的负载平衡器。在GCE上运行k8s时,GCE为您提供了外部负载均衡器。但是,如果您自己运行k8s,则没有它。通过在Google上搜索,我发现人们已经开始为k8s建立自己的LB。

  • 许多人在虚拟机上运行k8。VM覆盖网络和法兰绒覆盖网络将实际流量覆盖两次。这导致性能下降。Openstack Kuryr试图解决此问题。到那时,在Magnum上运行k8绝对是一个优势。

  • 多租户需要网络分离。通过k8s网络模型,如果使用法兰绒,它将实际上连接每个容器,就好像它们在同一网络中一样。对于企业安全而言,这是不可接受的。但是,Openstack Neutron允许用户创建至少三个由L3分隔的网络,并通过路由器进行连接。

  • 经典的k8s服务模型将一组Pod隐藏在服务后面,并向用户公开一个IP。但是,许多现实生活中的服务实际上并不适合该模型。下面的例子。解决方案是使用无头服务。参见[1] [2]。但是,用户仍然需要实现自己的服务发现并执行IP注册。它并不是真正的自动化。

    • Memcached或Redis作为缓存集群。客户端执行一致的哈希并决定要访问哪个Memcached或Redis实例。客户端需要知道每个实例的IP。如果您将整个Memcached或Redis群集隐藏在一项服务下,则不可能。一种解决方法是将每个实例附加到服务。

    • Mysql Galera群集。以类似的方式,客户端需要知道mysql实例的每个IP,以便它可以在一个实例关闭时进行故障转移。在k8s服务模型中,如果您将整个Mysql Galera群集隐藏在一项服务(同样在IP上)下,则不可能。

推荐阅读

《kubernetes(K8s):管理云平台中多个主机上的容器化的应用》

在CentOS 7上安装使用Kubernetes:管理云平台多个主机上的容器化应用相关推荐

  1. 磁盘管理来安装linux,Linux_在CentOS系统中安装quota来管理磁盘配额,在网络管理的工作中,由于硬 - phpStudy...

    在CentOS系统中安装quota来管理磁盘配额 在网络管理的工作中,由于硬盘的资源是有限的,常常需要为多用户的服务器设定用户的linux磁盘配额.这个功能对公用的多用户服务器(免费的或者收费的)来说 ...

  2. kubernetes(K8s):管理云平台中多个主机上的容器化的应用

    目录 kubernetes简介 Kubernetes生态 Kubernetes概述 Kubernetes官网 kubernetes简介 kubernetes,简称K8s,是用8代替8个字符" ...

  3. CentOS 7一键安装Seafile搭建私有云存储

    Seafile 是一款开源企业云盘,和Owncloud类似,个人感觉Seafile更加稳定,搭建也很简单,为了方便,xiaoz写了一个一键脚本,方便快速搭建自己的私有云. 环境要求 CentOS 7 ...

  4. 如何在公司标准电脑上安装统计联网直报平台证书并正常工作?

    如何在公司标准电脑上安装统计联网直报平台证书并正常工作? ©Lander Zhang 专注外企按需IT基础架构运维服务,IT Helpdesk 实战培训践行者 https://blog.51cto.c ...

  5. OpenStack推出最新版本Newton,显著提升单一云平台 对虚拟化、裸机和容器的管理...

    2016年10月10日-北京- OpenStack社区日前发布其命名为"Newton"的第14个版本.OpenStack是用于构建云的部署最广泛的开源软件.此次推出的新功能包括:I ...

  6. 云计算示范项目_瑞松科技基于工业互联网的设备运维及工艺管理云平台成功入选2020年工业互联网试点示范项目...

    2020年12月28日,工业和信息化部发布2020年工业互联网试点示范项目名单公示,瑞松科技申报项目<基于工业互联网的设备运维及工艺管理云平台>成功入选试点示范项目平台集成创新应用方向,再 ...

  7. 安科瑞电气能耗管理云平台在大型公建能耗监测平台的应用

    安科瑞产品支持,请关注公众号acrelcqy 摘要:从2007年开始,为贯彻落实国家节能减排的要求.各省市地区纷纷开始建设针对国家机关办公建筑与大型公共建筑的能耗监测平台,将国家机关办公建筑与大型公共 ...

  8. 【开源】ESP32怎样连接NEO6M模块接收GPS数据并显示在oled小屏幕上并可上传数据至Onenet云平台

    esp32连接neo6m在oled上显示定位数据 第一部分 ESP32怎样连接NEO6M模块接收GPS数据并显示在oled小屏幕上并可上传数据至Onenet云平台 一.软件部分 安装Arduino 我 ...

  9. 在SAP云平台ABAP编程环境上编写第一段ABAP程序

    距2017年秋季的SAP TechEd大会上一位大佬Björn Goerke,SAP's Chief Technology Officer宣布了SAP Cloud Platform即将支持ABAP至今 ...

最新文章

  1. 记录理解程度、一篇至少读3遍,吴恩达建议这样读论文
  2. 千万别中招!手把手教你复现Log4j2漏洞!
  3. mysql主从复制、redis基础、持久化和主从复制
  4. 懒人 IDEA 插件推荐: EasyCode 一键帮你生成所需代码~
  5. Python Django 设置和获取Cookie代码示例
  6. SynchronousQueue详解
  7. canpro脚本_AE/PR脚本-创建编辑导入导出专业字幕脚本 Subtitle Pro 2.8.0 + 使用教程...
  8. 为对象添加方法mothod
  9. java 返回js_如何基于java或js获取URL返回状态码
  10. Redis Config Set 命令
  11. spring boot整合shiro继承redis_Springboot+Shiro+redis整合
  12. linux libz-dev,Linux-based Development
  13. pandas删除某大于 数_详解pandas如何去掉、过滤数据集中的某些值或者某些行?...
  14. ZZCMS 2022版白盒审计
  15. 第十五讲:达索系统锂电池行业解决方案在线直播 | 达索系统百世慧
  16. 计算机多功能解说词,音乐教室解说词
  17. 3D打印机T3升级corexy  制作过程(一)
  18. node 安装(新)
  19. C++ STL set容器
  20. 软件测试就是点点点?你想的太简单了......

热门文章

  1. java ee 员工管理系统,fb3492 javaEE_原生Servlet_MySql企业员工信息管理系统的设计与实现,java源码含论文与答辩PPT...
  2. 【echart】showLoading hideLoading 无数据时显示正在加载
  3. Matlab绘制箕舌线
  4. 升级AndroidStudio3.4问题汇总
  5. 给DIV设置高度百分百
  6. Android 关于在Activity中监听ListView
  7. xcode5+未能安装到模拟器
  8. .Net事件委托备忘
  9. awk if 不包含_linux三剑客之awk
  10. 淄博神爱计算机官网,【最美教师】张萍:大爱无言 育人无声