kubernetes多节点部署解析

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介:

注:以下操作均基于centos7系统。

安装ansible

ansilbe可以通过yum或者pip安装,由于kubernetes-ansible用到了密码,故而还需要安装sshpass:

pip install ansible
wget http://sourceforge.net/projects/sshpass/files/latest/download
tar zxvf download
cd sshpass-1.05
./configure && make && make install

配置kubernetes-ansible

# git clone https://github.com/eparis/kubernetes-ansible.git
# cd kubernetes-ansible

# #在group_vars/all.yml中配置用户为root
# cat group_vars/all.yml | grep ssh
ansible_ssh_user: root

# # Each kubernetes service gets its own IP address. These are not real IPs. 
# # You need only select a range of IPs which are not in use elsewhere in your
# # environment. This must be done even if you do not use the network setup 
# # provided by the ansible scripts.
# cat group_vars/all.yml | grep kube_service_addresses
kube_service_addresses: 10.254.0.0/16

# #配置root密码
# echo "password" > ~/rootpassword

配置master、etcd和minion的IP地址:

# cat inventory
[masters]
192.168.0.7

[etcd]
192.168.0.7

[minions]
# kube_ip_addr为该minion上Pods的地址池,默认为/24掩码
192.168.0.3  kube_ip_addr=10.0.1.1 
192.168.0.6  kube_ip_addr=10.0.2.1

测试各机器连接并配置ssh key:

# ansible-playbook -i inventory ping.yml #这个命令会输出一些错误信息,可忽略
# ansible-playbook -i inventory keys.yml

目前kubernetes-ansible对依赖处理的还不是很全面,需要先手动配置下:

# # 安装iptables
# ansible all -i inventory --vault-password-file=~/rootpassword -a 'yum -y install iptables-services'
# # 为CentOS 7添加kubernetes源
# ansible all -i inventory --vault-password-file=~/rootpassword -a 'curl https://copr.fedoraproject.org/coprs/eparis/kubernetes-epel-7/repo/epel-7/eparis-kubernetes-epel-7-epel-7.repo -o /etc/yum.repos.d/eparis-kubernetes-epel-7-epel-7.repo'
# # 配置ssh,防止ssh连接超时
# sed -i "s/GSSAPIAuthentication yes/GSSAPIAuthentication no/g" /etc/ssh/ssh_config 
# ansible all -i inventory --vault-password-file=~/rootpassword -a 'sed -i "s/GSSAPIAuthentication yes/GSSAPIAuthentication no/g" /etc/ssh/ssh_config'
# ansible all -i inventory --vault-password-file=~/rootpassword -a 'sed -i "s/GSSAPIAuthentication yes/GSSAPIAuthentication no/g" /etc/ssh/sshd_config'
# ansible all -i inventory --vault-password-file=~/rootpassword -a 'systemctl restart sshd'

配置docker网络,实际上就是创建kbr0网桥、为网桥配置ip并配置路由:

# ansible-playbook -i inventory hack-network.yml  

PLAY [minions] **************************************************************** 

GATHERING FACTS *************************************************************** 
ok: [192.168.0.6]
ok: [192.168.0.3]

TASK: [network-hack-bridge | Create kubernetes bridge interface] ************** 
changed: [192.168.0.3]
changed: [192.168.0.6]

TASK: [network-hack-bridge | Configure docker to use the bridge inferface] **** 
changed: [192.168.0.6]
changed: [192.168.0.3]

PLAY [minions] **************************************************************** 

GATHERING FACTS *************************************************************** 
ok: [192.168.0.6]
ok: [192.168.0.3]

TASK: [network-hack-routes | stat path=/etc/sysconfig/network-scripts/ifcfg-{{ ansible_default_ipv4.interface }}] *** 
ok: [192.168.0.6]
ok: [192.168.0.3]

TASK: [network-hack-routes | Set up a network config file] ******************** 
skipping: [192.168.0.3]
skipping: [192.168.0.6]

TASK: [network-hack-routes | Set up a static routing table] ******************* 
changed: [192.168.0.3]
changed: [192.168.0.6]

NOTIFIED: [network-hack-routes | apply changes] ******************************* 
changed: [192.168.0.6]
changed: [192.168.0.3]

NOTIFIED: [network-hack-routes | upload script] ******************************* 
changed: [192.168.0.6]
changed: [192.168.0.3]

NOTIFIED: [network-hack-routes | run script] ********************************** 
changed: [192.168.0.3]
changed: [192.168.0.6]

NOTIFIED: [network-hack-routes | remove script] ******************************* 
changed: [192.168.0.3]
changed: [192.168.0.6]

PLAY RECAP ******************************************************************** 
192.168.0.3                : ok=10   changed=7    unreachable=0    failed=0   
192.168.0.6                : ok=10   changed=7    unreachable=0    failed=0  

最后,在所有节点安装并配置kubernetes:

ansible-playbook -i inventory setup.yml

执行完成后可以看到kube相关的服务都在运行了:

# # 服务运行状态
# ansible all -i inventory -k -a 'bash -c "systemctl | grep -i kube"'
SSH password: 
192.168.0.3 | success | rc=0 >>
kube-proxy.service                                                                                     loaded active running   Kubernetes Kube-Proxy Server
kubelet.service                                                                                        loaded active running   Kubernetes Kubelet Server

192.168.0.7 | success | rc=0 >>
kube-apiserver.service                                                      loaded active running   Kubernetes API Server
kube-controller-manager.service                                             loaded active running   Kubernetes Controller Manager
kube-scheduler.service                                                      loaded active running   Kubernetes Scheduler Plugin

192.168.0.6 | success | rc=0 >>
kube-proxy.service                                                                                     loaded active running   Kubernetes Kube-Proxy Server
kubelet.service                                                                                        loaded active running   Kubernetes Kubelet Server


# # 端口监听状态
# ansible all -i inventory -k -a 'bash -c "netstat -tulnp | grep -E \"(kube)|(etcd)\""'
SSH password: 
192.168.0.7 | success | rc=0 >>
tcp        0      0 192.168.0.7:7080        0.0.0.0:*               LISTEN      14486/kube-apiserve 
tcp        0      0 127.0.0.1:10251         0.0.0.0:*               LISTEN      14544/kube-schedule 
tcp        0      0 127.0.0.1:10252         0.0.0.0:*               LISTEN      14515/kube-controll 
tcp6       0      0 :::7001                 :::*                    LISTEN      13986/etcd          
tcp6       0      0 :::4001                 :::*                    LISTEN      13986/etcd          
tcp6       0      0 :::8080                 :::*                    LISTEN      14486/kube-apiserve 

192.168.0.3 | success | rc=0 >>
tcp        0      0 192.168.0.3:10250       0.0.0.0:*               LISTEN      9500/kubelet        
tcp6       0      0 :::46309                :::*                    LISTEN      9524/kube-proxy     
tcp6       0      0 :::48500                :::*                    LISTEN      9524/kube-proxy     
tcp6       0      0 :::38712                :::*                    LISTEN      9524/kube-proxy     

192.168.0.6 | success | rc=0 >>
tcp        0      0 192.168.0.6:10250       0.0.0.0:*               LISTEN      9474/kubelet        
tcp6       0      0 :::52870                :::*                    LISTEN      9498/kube-proxy     
tcp6       0      0 :::57961                :::*                    LISTEN      9498/kube-proxy     
tcp6       0      0 :::40720                :::*                    LISTEN      9498/kube-proxy  

 

执行下面的命令看看服务是否都是正常的

# curl -s -L http://192.168.0.7:4001/version # check etcd
etcd 0.4.6
# curl -s -L http://192.168.0.7:8080/api/v1beta1/pods  | python -m json.tool # check apiserve
{
    "apiVersion": "v1beta1",
    "creationTimestamp": null,
    "items": [],
    "kind": "PodList",
    "resourceVersion": 8,
    "selfLink": "/api/v1beta1/pods"
}
# curl -s -L http://192.168.0.7:8080/api/v1beta1/minions  | python -m json.tool # check apiserve
# curl -s -L http://192.168.0.7:8080/api/v1beta1/services  | python -m json.tool # check apiserve
# kubectl get minions
NAME
192.168.0.3
192.168.0.6

部署apache服务

首先创建一个Pod:

# cat ~/apache.json
{
  "id": "fedoraapache",
  "kind": "Pod",
  "apiVersion": "v1beta1",
  "desiredState": {
    "manifest": {
      "version": "v1beta1",
      "id": "fedoraapache",
      "containers": [{
        "name": "fedoraapache",
        "image": "fedora/apache",
        "ports": [{
          "containerPort": 80,
          "hostPort": 80
        }]
      }]
    }
  },
  "labels": {
    "name": "fedoraapache"
  }
}

# kubectl create -f apache.json
# kubectl get pod fedoraapache
NAME                IMAGE(S)            HOST                LABELS              STATUS
fedoraapache        fedora/apache       192.168.0.6/        name=fedoraapache   Waiting

# #由于镜像下载较慢,因而Waiting持续的时间会比较久,等镜像下好后就会很快起来了
# kubectl get pod fedoraapache
NAME                IMAGE(S)            HOST                LABELS              STATUS
fedoraapache        fedora/apache       192.168.0.6/        name=fedoraapache   Running

# #到192.168.0.6机器上看看容器状态
# docker ps
CONTAINER ID        IMAGE                     COMMAND             CREATED             STATUS              PORTS                NAMES
77dd7fe1b24f        fedora/apache:latest      "/run-apache.sh"    31 minutes ago      Up 31 minutes                            k8s_fedoraapache.f14c9521_fedoraapache.default.etcd_1416396375_4114a4d0   
1455249f2c7d        kubernetes/pause:latest   "/pause"            About an hour ago   Up About an hour    0.0.0.0:80->80/tcp   k8s_net.e9a68336_fedoraapache.default.etcd_1416396375_11274cd2  
# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
fedora/apache       latest              2e11d8fd18b3        7 weeks ago         554.1 MB
kubernetes/pause    latest              6c4579af347b        4 months ago        239.8 kB
# iptables-save | grep 2.2
-A DOCKER ! -i kbr0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 10.0.2.2:80
-A FORWARD -d 10.0.2.2/32 ! -i kbr0 -o kbr0 -p tcp -m tcp --dport 80 -j ACCEPT
# curl localhost  # 说明Pod启动OK了,并且端口也正常
Apache

Replication Controllers

Replication Controllers保证足够数量的容器运行,以便均衡负载,并保证服务高可用:

A replication controller combines a template for pod creation (a “cookie-cutter” if you will) and a number of desired replicas, into a single API object. The replica controller also contains a label selector that identifies the set of objects managed by the replica controller. The replica controller constantly measures the size of this set relative to the desired size, and takes action by creating or deleting pods.

# cat replica.json 
{
  "id": "apacheController",
  "kind": "ReplicationController",
  "apiVersion": "v1beta1",
  "labels": {"name": "fedoraapache"},
  "desiredState": {
    "replicas": 3,
    "replicaSelector": {"name": "fedoraapache"},
    "podTemplate": {
      "desiredState": {
         "manifest": {
           "version": "v1beta1",
           "id": "fedoraapache",
           "containers": [{
             "name": "fedoraapache",
             "image": "fedora/apache",
             "ports": [{
               "containerPort": 80,
             }]
           }]
         }
       },
       "labels": {"name": "fedoraapache"},
      },
  }
}

# kubectl create -f replica.json 
apacheController

# kubectl get replicationController
NAME                IMAGE(S)            SELECTOR            REPLICAS
apacheController    fedora/apache       name=fedoraapache   3

# kubectl get pod
NAME                                   IMAGE(S)            HOST                LABELS              STATUS
fedoraapache                           fedora/apache       192.168.0.6/        name=fedoraapache   Running
cf6726ae-6fed-11e4-8a06-fa163e3873e1   fedora/apache       192.168.0.3/        name=fedoraapache   Running
cf679152-6fed-11e4-8a06-fa163e3873e1   fedora/apache       192.168.0.3/        name=fedoraapache   Running

可以看到,已经有三个容器在运行了。

Services

通过Replication Controllers已经有多个Pod在运行了,但由于每个Pod都分配了不同的IP,并且随着系统运行这些IP地址有可能会变化,那问题来了,如何从外部访问这个服务呢?这就是service干的事情了。

A Kubernetes service is an abstraction which defines a logical set of pods and a policy by which to access them - sometimes called a micro-service. The goal of services is to provide a bridge for non-Kubernetes-native applications to access backends without the need to write code that is specific to Kubernetes. A service offers clients an IP and port pair which, when accessed, redirects to the appropriate backends. The set of pods targetted is determined by a label selector.

As an example, consider an image-process backend which is running with 3 live replicas. Those replicas are fungible - frontends do not care which backend they use. While the actual pods that comprise the set may change, the frontend client(s) do not need to know that. The service abstraction enables this decoupling.

Unlike pod IP addresses, which actually route to a fixed destination, service IPs are not actually answered by a single host. Instead, we use iptables (packet processing logic in Linux) to define “virtual” IP addresses which are transparently redirected as needed. We call the tuple of the service IP and the service port the portal. When clients connect to the portal, their traffic is automatically transported to an appropriate endpoint. The environment variables for services are actually populated in terms of the portal IP and port. We will be adding DNS support for services, too.

# cat service.json 
{
  "id": "fedoraapache",
  "kind": "Service",
  "apiVersion": "v1beta1",
  "selector": {
    "name": "fedoraapache",
  },
  "protocol": "TCP",
  "containerPort": 80,
  "port": 8987
}
# kubectl create -f service.json 
fedoraapache
# kubectl get service
NAME                LABELS              SELECTOR                                  IP                  PORT
kubernetes-ro                           component=apiserver,provider=kubernetes   10.254.0.2          80
kubernetes                              component=apiserver,provider=kubernetes   10.254.0.1          443
fedoraapache                            name=fedoraapache                         10.254.0.3          8987

# # 切换到minion上
# curl 10.254.0.3:8987
Apache

也可以为service配置一个公网IP,前提是要配置一个cloud provider。目前支持的cloud provider有GCE、AWS、OpenStack、ovirt、vagrant等。

For some parts of your application (e.g. your frontend) you want to expose a service on an external (publically visible) IP address. To achieve this, you can set the createExternalLoadBalancer flag on the service. This sets up a cloud provider specific load balancer (assuming that it is supported by your cloud provider) and also sets up IPTables rules on each host that map packets from the specified External IP address to the service proxy in the same manner as internal service IP addresses.

注:对Openstack的支持是使用rackspace开源的github.com/rackspace/gophercloud来做的,

Health Check

Currently, there are three types of application health checks that you can choose from:
HTTP Health Checks - The Kubelet will call a web hook. If it returns between 200 and 399, it is considered success, failure otherwise.
Container Exec - The Kubelet will execute a command inside your container. If it returns “ok” it will be considered a success.
* TCP Socket - The Kubelet will attempt to open a socket to your container. If it can establish a connection, the container is considered healthy, if it can’t it is considered a failure.
In all cases, if the Kubelet discovers a failure, the container is restarted.

The container health checks are configured in the “LivenessProbe” section of your container config. There you can also specify an “initialDelaySeconds” that is a grace period from when the container is started to when health checks are performed, to enable your container to perform any necessary initialization.

Here is an example config for a pod with an HTTP health check:

kind: Pod
apiVersion: v1beta1
desiredState:
manifest:
version: v1beta1
id: php
containers:
- name: nginx
image: dockerfile/nginx
ports:
- containerPort: 80
# defines the health checking
livenessProbe:
# turn on application health checking
enabled: true
type: http
# length of time to wait for a pod to initialize
# after pod startup, before applying health checking
initialDelaySeconds: 30
# an http probe
httpGet:
path: /_status/healthz
port: 8080


本文转自feisky博客园博客,原文链接:http://www.cnblogs.com/feisky/p/4108477.html,如需转载请自行联系原作者

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
11天前
|
缓存 Kubernetes Docker
GitLab Runner 全面解析:Kubernetes 环境下的应用
GitLab Runner 是 GitLab CI/CD 的核心组件,负责执行由 `.gitlab-ci.yml` 定义的任务。它支持多种执行方式(如 Shell、Docker、Kubernetes),可在不同环境中运行作业。本文详细介绍了 GitLab Runner 的基本概念、功能特点及使用方法,重点探讨了流水线缓存(以 Python 项目为例)和构建镜像的应用,特别是在 Kubernetes 环境中的配置与优化。通过合理配置缓存和镜像构建,能够显著提升 CI/CD 流水线的效率和可靠性,助力开发团队实现持续集成与交付的目标。
|
11天前
|
Kubernetes Linux 虚拟化
入门级容器技术解析:Docker和K8s的区别与关系
本文介绍了容器技术的发展历程及其重要组成部分Docker和Kubernetes。从传统物理机到虚拟机,再到容器化,每一步都旨在更高效地利用服务器资源并简化应用部署。容器技术通过隔离环境、减少依赖冲突和提高可移植性,解决了传统部署方式中的诸多问题。Docker作为容器化平台,专注于创建和管理容器;而Kubernetes则是一个强大的容器编排系统,用于自动化部署、扩展和管理容器化应用。两者相辅相成,共同推动了现代云原生应用的快速发展。
69 11
|
1月前
|
存储 Kubernetes 容器
K8S部署nexus
该配置文件定义了Nexus 3的Kubernetes部署,包括PersistentVolumeClaim、Deployment和服务。PVC请求20Gi存储,使用NFS存储类。Deployment配置了一个Nexus 3容器,内存限制为6G,CPU为1000m,并挂载数据卷。Service类型为NodePort,通过30520端口对外提供服务。所有资源位于`nexus`命名空间中。
|
2月前
|
Kubernetes Cloud Native 微服务
云原生入门与实践:Kubernetes的简易部署
云原生技术正改变着现代应用的开发和部署方式。本文将引导你了解云原生的基础概念,并重点介绍如何使用Kubernetes进行容器编排。我们将通过一个简易的示例来展示如何快速启动一个Kubernetes集群,并在其上运行一个简单的应用。无论你是云原生新手还是希望扩展现有知识,本文都将为你提供实用的信息和启发性的见解。
|
2月前
|
Kubernetes 监控 API
深入解析Kubernetes及其在生产环境中的最佳实践
深入解析Kubernetes及其在生产环境中的最佳实践
89 1
|
2月前
|
运维 Kubernetes Cloud Native
Kubernetes云原生架构深度解析与实践指南####
本文深入探讨了Kubernetes作为领先的云原生应用编排平台,其设计理念、核心组件及高级特性。通过剖析Kubernetes的工作原理,结合具体案例分析,为读者呈现如何在实际项目中高效部署、管理和扩展容器化应用的策略与技巧。文章还涵盖了服务发现、负载均衡、配置管理、自动化伸缩等关键议题,旨在帮助开发者和运维人员掌握利用Kubernetes构建健壮、可伸缩的云原生生态系统的能力。 ####
|
2月前
|
监控 Cloud Native 持续交付
云原生技术深度解析:重塑现代应用开发与部署范式####
本文深入探讨了云原生技术的核心概念、关键技术组件及其在现代软件开发中的重要性。通过剖析容器化、微服务架构、持续集成/持续部署(CI/CD)等关键技术,本文旨在揭示云原生技术如何促进应用的敏捷性、可扩展性和高可用性,进而推动企业数字化转型进程。不同于传统摘要仅概述内容要点,本部分将融入具体案例分析,直观展示云原生技术在实际应用中的显著成效与挑战应对策略,为读者提供更加丰富、立体的理解视角。 ####
|
2月前
|
存储 Kubernetes Devops
Kubernetes集群管理和服务部署实战
Kubernetes集群管理和服务部署实战
82 0
|
2月前
|
存储 Kubernetes 调度
深度解析Kubernetes中的Pod生命周期管理
深度解析Kubernetes中的Pod生命周期管理
|
2月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
108 2

热门文章

最新文章

推荐镜像

更多