kubernetes须要存储不少东西,像它自己的节点信息,组件信息,还有经过kubernetes运行的pod,deployment,service等等。都须要持久化。etcd就是它的数据中心。生产环境中为了保证数据中心的高可用和数据的一致性,通常会部署最少三个节点。咱们这里以学习为主就只在主节点部署一个实例。node
若是你的环境已经有了etcd服务(不论是单点仍是集群),能够忽略这一步。前提是你在生成配置的时候填写了本身的etcd endpoint哦~nginx
etcd的二进制文件和服务的配置咱们都已经准备好,如今的目的就是把它作成系统服务并启动。docker
#把服务配置文件copy到系统服务目录 $ cp ~/kubernetes-starter/target/master-node/etcd.service /lib/systemd/system/ #enable服务 $ systemctl enable etcd.service #建立工做目录(保存数据的地方) $ mkdir -p /var/lib/etcd # 启动服务 $ service etcd start # 查看服务日志,看是否有错误信息,确保服务正常 $ journalctl -f -u etcd.service $ etcdctl -C http://10.0.94.112:2379 cluster-health member 8e9e05c52164694d is healthy: got healthy result from http://10.0.94.112:2379 cluster is healthy
kube-apiserver是Kubernetes最重要的核心组件之一,主要提供如下的功能api
生产环境为了保证apiserver的高可用通常会部署2+个节点,在上层作一个lb作负载均衡,好比haproxy。因为单节点和多节点在apiserver这一层说来没什么区别,因此咱们学习部署一个节点就足够啦安全
APIServer的部署方式也是经过系统服务。部署流程跟etcd彻底同样,再也不注释bash
$ cp target/master-node/kube-apiserver.service /lib/systemd/system/ $ systemctl enable kube-apiserver.service $ systemctl daemon-reload $ service kube-apiserver start $ journalctl -f -u kube-apiserver
[Unit]
Description=Kubernetes API Server
...
[Service]
#可执行文件的位置
ExecStart=/home/michael/bin/kube-apiserver \
#非安全端口(8080)绑定的监听地址 这里表示监听全部地址
--insecure-bind-address=0.0.0.0 \
#不使用https
--kubelet-https=false \
#kubernetes集群的虚拟ip的地址范围
--service-cluster-ip-range=10.68.0.0/16 \
#service的nodeport的端口范围限制
--service-node-port-range=20000-40000 \
#不少地方都须要和etcd打交道,也是惟一能够直接操做etcd的模块
--etcd-servers=http://192.168.1.102:2379\
...网络
Controller Manager由kube-controller-manager和cloud-controller-manager组成,是Kubernetes的大脑,它经过apiserver监控整个集群的状态,并确保集群处于预期的工做状态。 kube-controller-manager由一系列的控制器组成,像Replication Controller控制副本,Node Controller节点控制,Deployment Controller管理deployment等等 cloud-controller-manager在Kubernetes启用Cloud Provider的时候才须要,用来配合云服务提供商的控制app
controller-manager、scheduler和apiserver 三者的功能紧密相关,通常运行在同一个机器上,咱们能够把它们当作一个总体来看,因此保证了apiserver的高可用便是保证了三个模块的高可用。也能够同时启动多个controller-manager进程,但只有一个会被选举为leader提供服务。负载均衡
经过系统服务方式部署less
$ cp target/master-node/kube-controller-manager.service /lib/systemd/system/ $ systemctl enable kube-controller-manager.service $ service kube-controller-manager start $ journalctl -f -u kube-controller-manager
[Unit]
Description=Kubernetes Controller Manager
...
[Service]
ExecStart=/home/michael/bin/kube-controller-manager \
#对外服务的监听地址,这里表示只有本机的程序能够访问它
--address=127.0.0.1 \
#apiserver的url
--master=http://127.0.0.1:8080\
#服务虚拟ip范围,同apiserver的配置
--service-cluster-ip-range=10.68.0.0/16 \
#pod的ip地址范围
--cluster-cidr=172.20.0.0/16 \
#下面两个表示不使用证书,用空值覆盖默认值
--cluster-signing-cert-file= \
--cluster-signing-key-file= \
...
kube-scheduler负责分配调度Pod到集群内的节点上,它监听kube-apiserver,查询还未分配Node的Pod,而后根据调度策略为这些Pod分配节点。咱们前面讲到的kubernetes的各类调度策略就是它实现的。
经过系统服务方式部署
$ cp target/master-node/kube-scheduler.service /lib/systemd/system/ $ systemctl enable kube-scheduler.service $ service kube-scheduler start $ journalctl -f -u kube-scheduler
[Unit]
Description=Kubernetes Scheduler
...
[Service]
ExecStart=/home/michael/bin/kube-scheduler \
#对外服务的监听地址,这里表示只有本机的程序能够访问它
--address=127.0.0.1 \
#apiserver的url
--master=http://127.0.0.1:8080\
...
Calico实现了CNI接口,是kubernetes网络方案的一种选择,它一个纯三层的数据中心网络方案(不须要Overlay),而且与OpenStack、Kubernetes、AWS、GCE等IaaS和容器平台都有良好的集成。 Calico在每个计算节点利用Linux Kernel实现了一个高效的vRouter来负责数据转发,而每一个vRouter经过BGP协议负责把本身上运行的workload的路由信息像整个Calico网络内传播——小规模部署能够直接互联,大规模下可经过指定的BGP route reflector来完成。 这样保证最终全部的workload之间的数据流量都是经过IP路由的方式完成互联的。
calico是经过系统服务+docker方式完成的
$ cp target/all-node/kube-calico.service /lib/systemd/system/ $ systemctl enable kube-calico.service $ service kube-calico start $ journalctl -f -u kube-calico
查看容器运行状况
$ docker ps CONTAINER ID IMAGE COMMAND CREATED ... 4d371b58928b calico/node:v2.6.2 " start_runit " 3 hours ago...
查看节点运行状况
$ calicoctl node status Calico process is running. IPv4 BGP status +---------------+-------------------+-------+----------+-------------+ | PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO | +---------------+-------------------+-------+----------+-------------+ | 192.168.1.103 | node-to-node mesh | up | 13:13:13 | Established | +---------------+-------------------+-------+----------+-------------+ IPv6 BGP status No IPv6 peers found.
查看端口BGP 协议是经过TCP 链接来创建邻居的,所以能够用netstat 命令验证 BGP Peer
$ netstat -natp | grep ESTABLISHED | grep 179 tcp 0 0 192.168.1.102:60959 192.168.1.103:179 ESTABLISHED 29680/bird
查看集群ippool状况
$ calicoctl get ipPool -o yaml - apiVersion: v1 kind: ipPool metadata: cidr: 172.20.0.0/16 spec: nat-outgoing: true
[Unit]
Description=calico node
...
[Service]
#以docker方式运行
ExecStart=/usr/bin/docker run --net=host --privileged --name=calico-node \
#指定etcd endpoints(这里主要负责网络元数据一致性,确保Calico网络状态的准确性)
-e ETCD_ENDPOINTS=http://192.168.1.102:2379\
#网络地址范围(同上面ControllerManager)
-e CALICO_IPV4POOL_CIDR=172.20.0.0/16 \
#镜像名,为了加快你们的下载速度,镜像都放到了阿里云上
registry.cn-hangzhou.aliyuncs.com/imooc/calico-node:v2.6.2
kubectl是Kubernetes的命令行工具,是Kubernetes用户和管理员必备的管理工具。 kubectl提供了大量的子命令,方便管理Kubernetes集群中的各类功能。
使用kubectl的第一步是配置Kubernetes集群以及认证方式,包括:
咱们这没有安全相关的东西,只须要设置好api-server和上下文就好啦:
#指定apiserver地址(ip替换为你本身的api-server地址) kubectl config set-cluster kubernetes --server=http://10.0.94.112:8080 #指定设置上下文,指定cluster kubectl config set-context kubernetes --cluster=kubernetes #选择默认的上下文 kubectl config use-context kubernetes
经过上面的设置最终目的是生成了一个配置文件:~/.kube/config,固然你也能够手写或复制一个文件放在那,就不须要上面的命令了。
每一个工做节点上都运行一个kubelet服务进程,默认监听10250端口,接收并执行master发来的指令,管理Pod及Pod中的容器。每一个kubelet进程会在API Server上注册节点自身信息,按期向master节点汇报节点的资源使用状况,并经过cAdvisor监控节点和容器的资源。
经过系统服务方式部署,但步骤会多一些,具体以下:
#确保相关目录存在 $ mkdir -p /var/lib/kubelet $ mkdir -p /etc/kubernetes $ mkdir -p /etc/cni/net.d #复制kubelet服务配置文件 $ cp target/worker-node/kubelet.service /lib/systemd/system/ #复制kubelet依赖的配置文件 $ cp target/worker-node/kubelet.kubeconfig /etc/kubernetes/ #复制kubelet用到的cni插件配置文件 $ cp target/worker-node/10-calico.conf /etc/cni/net.d/ $ systemctl enable kubelet.service $ service kubelet start $ journalctl -f -u kubelet
kubelet.service
[Unit]
Description=Kubernetes Kubelet
[Service]
#kubelet工做目录,存储当前节点容器,pod等信息
WorkingDirectory=/var/lib/kubelet
ExecStart=/home/michael/bin/kubelet \
#对外服务的监听地址
--address=192.168.1.103 \
#指定基础容器的镜像,负责建立Pod 内部共享的网络、文件系统等,这个基础容器很是重要:K8S每个运行的 POD里面必然包含这个基础容器,若是它没有运行起来那么你的POD 确定建立不了
--pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/imooc/pause-amd64:3.0 \
#访问集群方式的配置,如api-server地址等
--kubeconfig=/etc/kubernetes/kubelet.kubeconfig \
#声明cni网络插件
--network-plugin=cni \
#cni网络配置目录,kubelet会读取该目录下得网络配置
--cni-conf-dir=/etc/cni/net.d \
#指定 kubedns 的 Service IP(能够先分配,后续建立 kubedns 服务时指定该 IP),--cluster-domain 指定域名后缀,这两个参数同时指定后才会生效
--cluster-dns=10.68.0.2 \
...
kubelet.kubeconfig
kubelet依赖的一个配置,格式看也是咱们后面常常遇到的yaml格式,描述了kubelet访问apiserver的方式
apiVersion: v1
clusters:
- cluster:
#跳过tls,便是kubernetes的认证
insecure-skip-tls-verify: true
#api-server地址
server:http://192.168.1.102:8080
...
10-calico.conf
calico做为kubernets的CNI插件的配置
{ "name": "calico-k8s-network", "cniVersion": "0.1.0", "type": "calico", <!--etcd的url--> "etcd_endpoints": "http://192.168.1.102:2379", "logevel": "info", "ipam": { "type": "calico-ipam" }, "kubernetes": { < !--api-server的url--> "k8s_api_root": "http://192.168.1.102:8080" } }
到这里最基础的kubernetes集群就能够工做了。下面咱们就来试试看怎么去操做,控制它。 咱们从最简单的命令开始,尝试一下kubernetes官方的入门教学:playground的内容。了解如何建立pod,deployments,以及查看他们的信息,深刻理解他们的关系。
#经常使用命令 237 kubectl version 238 kubectl get nodes 239 kubectl get --help 241 kubectl run kubernetes-bootcamp --image=jocatalin/kubernetes-bootcamp:v1 --port=8080 242 kubectl get deployments 243 kubectl get pods 244 kubectl get pods -o wide 245 docker ps 246 kubectl get deployments 248 kubectl delete deployments kubernetes-bootcamp 250 kubectl run kubernetes-bootcamp --image=jocatalin/kubernetes-bootcamp:v1 --port=8080 255 docker ps 256 journalctl -f 259 kubectl describe deploy kubernetes-bootcamp 260 kubectl proxy 262 kubectl scale deploy kubernetes-bootcamp --replicas=4 266 kubectl scale deploy kubernetes-bootcamp --replicas=2 269 kubectl describe deploy 272 kubectl set image deploy kubernetes-bootcamp kubernetes-bootcamp=jocatalin/kubernetes-bootcamp:v2 274 kubectl rollout status deploy kubernetes-bootcamp 277 kubectl rollout undo deploy kubernetes-bootcamp nginx-pod.yaml文件 apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80 284 kubectl create -f ~/services/nginx-pod.yaml 285 curl http://localhost:8001/api/v1/proxy/namespaces/default/pods/nginx/ nginx-deployment.yaml apiVersion: apps/v1beta1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 2 template: metadata: labels: app: nignx spec: containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80 323 kubectl create -f ~/services/nginx-deployment.yaml 324 kubectl get pods -l app=nginx 235 kubectl get deployment -n kube-system
每台工做节点上都应该运行一个kube-proxy服务,它监听API server中service和endpoint的变化状况,并经过iptables等来为服务配置负载均衡,是让咱们的服务在集群外能够被访问到的重要方式。
经过系统服务方式部署:
#确保工做目录存在 $ mkdir -p /var/lib/kube-proxy #复制kube-proxy服务配置文件 $ cp target/worker-node/kube-proxy.service /lib/systemd/system/ #复制kube-proxy依赖的配置文件 $ cp target/worker-node/kube-proxy.kubeconfig /etc/kubernetes/ $ systemctl enable kube-proxy.service $ service kube-proxy start $ journalctl -f -u kube-proxy
kube-proxy.service
[Unit]
Description=Kubernetes Kube-Proxy Server ...
[Service]
#工做目录
WorkingDirectory=/var/lib/kube-proxy
ExecStart=/home/michael/bin/kube-proxy \
#监听地址
--bind-address=192.168.1.103 \
#依赖的配置文件,描述了kube-proxy如何访问api-server
--kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig \
...
kube-proxy.kubeconfig配置了kube-proxy如何访问api-server,内容与kubelet雷同,再也不赘述。
刚才咱们在基础集群上演示了pod,deployments。下面就在刚才的基础上增长点service元素。
423 kubectl expose deploy kubernetes-bootcamp --type="NodePort" --target-port=8080 --port=80 424 kubectl get services 425 curl 10.0.94.182:39741 426 kubectl get pods -o wide 427 kubectl get services server01 # docker exec -it cc6aa3fc38a0 bash 1 curl 10.68.34.35 2 curl 172.20.60.133 428 vi ~/services/nginx-service.yaml apiVersion: v1 kind: Service metadata: name: nginx-service spec: ports: - port: 8080 targetPort: 80 nodePort: 20000 selector: app: nginx type: NodePort 429 kubectl create -f ~/services/nginx-service.yaml 430 kubectl get services 431 curl 10.0.94.182:20000
kube-dns为Kubernetes集群提供命名服务,主要用来解析集群服务名和Pod的hostname。目的是让pod能够经过名字访问到集群内服务。它经过添加A记录的方式实现名字和service的解析。普通的service会解析到service-ip。headless service会解析到pod列表。
经过kubernetes应用的方式部署kube-dns.yaml文件基本与官方一致(除了镜像名不一样外)。 里面配置了多个组件,之间使用”---“分隔
#到kubernetes-starter目录执行命令 $ kubectl create -f target/services/kube-dns.yaml
请直接参考配置文件中的注释。
这了主要演示增长kube-dns后,经过名字访问服务的原理和具体过程。演示启动dns服务和未启动dns服务的经过名字访问状况差异。