2020-12-05更新 已经把digitalocan的服务退掉了, 实在有些贵 !!!


原文内容

不知道看我博客的各位是否平时都在使用Ansible, 作为一个功能全面的运维工具, Ansible可以胜任我工作中遇到的绝大部分问题. 近期我的主要工作重心都是在Kubernetes这方面. 借这这篇博客, 我会简要描述一下Ansible解决的问题, 希望未来各位使用Kubernetes时, 可以考虑使用Ansible来管理集群.

希望读者有一些基础的Kubernetes操作经验以及Ansible使用经验.

建立Kubernetes集群

建立一个高可用的Kubernetes集群包括两个部分, etcd集群和Kubernetes集群

这个过程博客里面不讲了, 有很多博客可以看, 而且也比较完整.

我推荐两个可以快速建立和使用的Kubernetes服务吧:

  1. okteto

    https://okteto.com/

    仅需要Github帐号就可以登录, 可以获得一个简易的Kubernetes集群, 权限不多, 但是部署应用是够了. 有一点不好是免费帐号24小时会关闭容器, 但是付费帐号又很贵, 要$20一个月, 简单的使用还可以, 服务还是不要考虑了.

  2. digitalocean

    https://cloud.digitalocean.com/

    我的邀请链接: https://m.do.co/c/e02a6de85b29

    我个人比较喜欢digitalocean, 创建Kubernetes集群两个节点一个月也就$20, 而且是原生的Kubernetes环境, 考虑再三(其实完全没有考虑), 直接买了digitalocean的集群, 服务也省心.

Ingress管理

上一篇关于Ingress的介绍在这里Ingress实现的一些策略与源码阅读, 我平时使用Ingress时, 都会选择Kubernetes社区版的Ingress进行使用, 社区版的Ingress需要根据使用方状况自定义一些配置:

例如, 当我的Ingress不作为出口, 而是使用Nginx转发到Kubernetes集群中时, 需要让Ingress得到真实的客户端IP, 具体的原理请查看获取用户的真实IP 在Ingress中, 需要给出如下的配置, 我个人的解决方案是

1
2
3
4
5
6
7
8
9
10
11
12
kind: ConfigMap
apiVersion: v1
metadata:
name: nginx-configuration
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
data:
use-forwarded-headers: "true"
compute-full-forwarded-for: "true"
proxy-real-ip-cidr: "10.0.0.0/8,{{kubernetes_sub_net}}

此文件可以由ansible来生成并apply:

1
2
3
4
5
6
7
8
9
10
11
12
---
- block:
- name: upload kube-ingress.yml
template:
src: templates/ingress.yml.j2
dest: /tmp/kube-ingress_{{item.name}}.yml
with_items: '{{ cluster_ingress }}' # 不同私有集群的Ingress不同

- name: install ingress
shell: KUBECONFIG={{kubernetes_config}} kubectl apply -f /tmp/kube-ingress_{{item.name}}.yml
with_items: '{{ cluster_ingress }}' # 不同私有集群的Ingress不同
delegate_to: "{{ groups['kubernetes_masters'][0] }}"

我简要介绍一下上面的几个要点吧:

  1. KUBECONFIG={{kubernetes_config}} kubectl apply xxx

可以通过不同的kubernetes配置文件来操作不同的集群.

  1. with_items: '{{ cluster_ingress }}' # 不同私有集群的Ingress不同 这是我们的业务需求, 需要部署多个Ingress分别给不同的业务

  2. delegate_to: "{{ groups['kubernetes_masters'][0] }}"

指定这个操作仅在master角色的第一台机器中进行.

docker secret管理

Kubernetes官方文档: 从私有仓库拉取镜像.

刚开始使用Kubernetes时, 为了图省事, 是调用kubectl来创建secret的, 类似下面这样:

1
2
3
4
5
6
## Create docker-registr
## 请不要再用这样的代码了
- name: Create docker registry
shell: KUBECONFIG={{kubernetes_config}} kubectl -n {{item}} create secret docker-registry "{{ docker_registry_secret_name }}" --docker-server="{{ docker_registry_server }}" --docker-username="{{ docker_registry_username }}" --docker-password="{{ docker_registry_pwd }}" --docker-email="{{ docker_registry_email }}"
ignore_errors: true
with_items: "{{need_secret_namespaces}}"

kubectl create secret的方式, 创建密钥时问题不大, 但是想要修改密钥, 就有些麻烦了. 后来项目逐渐稳定之后, 我对这部分代码进行了更新, 不再使用create secret这样的命令式, 已经改为了声明式, 具体的部分请看代码吧:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- block:
# 创建dockerconfigjson的变量
- set_fact:
dockerconfigjson: "{{ lookup('template', './secret-json.yml.j2')|to_json}}"

# 根据dockerconfigjson变量生成yaml文件
- name: upload kube-docker-secrets.yml
template:
src: templates/docker-secrets.yml.j2
dest: /tmp/kube-docker-secrets.yml

# 进行apply操作
- name: install ocker-secretes
shell: KUBECONFIG={{kubernetes_config}} kubectl apply -f /tmp/kube-docker-secrets.yml
delegate_to: "{{ groups['kubernetes_masters'][0] }}"

secret-json.yml.j2 生成密钥文件

1
2
3
4
5
6
7
8
9
10
{
"auths": {
"{{docker_registry_server}}":{
"username": "{{docker_registry_username}}",
"password": "{{docker_registry_pwd}}",
"email": "{{docker_registry_email}}",
"auth": "{{(docker_registry_username + ':' + docker_registry_pwd)| b64encode}}"
}
}
}

docker-secrets.yml.j2 生成yaml文件, 用于apply

1
2
3
4
5
6
7
8
9
10
11
12
{% for namespace in need_secret_namespaces %}
# secret属于不同的namespace, 需要针对namespace进行处理
---
apiVersion: v1
kind: Secret
type: kubernetes.io/dockerconfigjson
metadata:
name: {{docker_registry_secret_name}}
namespace: {{namespace}}
data:
.dockerconfigjson: {{dockerconfigjson| b64encode }}
{% endfor %}

声明的方式生成secret, 一个很大的优势是: 只要配置没有改动, 你可以一直apply.

总结

这篇博客主要介绍了我在使用Kubernetes时的一些策略, 其实主要想分享的是 Ansible操作Kubernetes中secrets的部分, 网上也没什么资料, 主要就是自己探索写出来的, 希望读者有需要的时可以用的上.

虽然我用Ansible来管理Kubernetes集群, 但是也请大家了解, 上面的操作也只是在配置周边的环境, 例如配置Ingress, 存储docker secret, 真正发布应用, 也没有使用Ansible来做.

附录

针对Dockerhub的登录, 我简单增加了一个样例代码, 读者可以访问这里:

https://github.com/corvofeng/BlogCode/tree/master/ansible-kubernetes