100% found this document useful (6 votes)
21 views

Instant Download Kubernetes Programming with Go: Programming Kubernetes Clients and Operators Using Go and the Kubernetes API 1st Edition Philippe Martin PDF All Chapters

Kubernetes

Uploaded by

ussieldeiicy
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (6 votes)
21 views

Instant Download Kubernetes Programming with Go: Programming Kubernetes Clients and Operators Using Go and the Kubernetes API 1st Edition Philippe Martin PDF All Chapters

Kubernetes

Uploaded by

ussieldeiicy
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 66

Download Full Version ebookmass - Visit ebookmass.

com

Kubernetes Programming with Go: Programming


Kubernetes Clients and Operators Using Go and the
Kubernetes API 1st Edition Philippe Martin

https://ebookmass.com/product/kubernetes-programming-with-
go-programming-kubernetes-clients-and-operators-using-go-
and-the-kubernetes-api-1st-edition-philippe-martin/

OR CLICK HERE

DOWLOAD NOW

Discover More Ebook - Explore Now at ebookmass.com


Instant digital products (PDF, ePub, MOBI) ready for you
Download now and discover formats that fit your needs...

Kubernetes Programming with Go: Programming Kubernetes


Clients and Operators Using Go and the Kubernetes API 1st
Edition Philippe Martin
https://ebookmass.com/product/kubernetes-programming-with-go-
programming-kubernetes-clients-and-operators-using-go-and-the-
kubernetes-api-1st-edition-philippe-martin-2/
ebookmass.com

Ansible for Kubernetes by Example: Automate Your


Kubernetes Cluster with Ansible 1st Edition Luca Berton

https://ebookmass.com/product/ansible-for-kubernetes-by-example-
automate-your-kubernetes-cluster-with-ansible-1st-edition-luca-
berton-2/
ebookmass.com

Ansible for Kubernetes by Example: Automate Your


Kubernetes Cluster with Ansible 1st Edition Luca Berton

https://ebookmass.com/product/ansible-for-kubernetes-by-example-
automate-your-kubernetes-cluster-with-ansible-1st-edition-luca-berton/

ebookmass.com

Financial Interdependence, Digitalization and


Technological Rivalries: Perspectives on Future
Cooperation and Integration in Sino-American Financial
Systems 1st ed. 2023 Edition René W.H. Van Der Linden
https://ebookmass.com/product/financial-interdependence-
digitalization-and-technological-rivalries-perspectives-on-future-
cooperation-and-integration-in-sino-american-financial-systems-1st-
ed-2023-edition-rene-w-h-van-der-lind/
ebookmass.com
The Practice of Creative Writings 3rd Edition, (Ebook PDF)

https://ebookmass.com/product/the-practice-of-creative-writings-3rd-
edition-ebook-pdf/

ebookmass.com

New Century Physics for Queensland Units 1&2 3rd Edition


Richard Walding

https://ebookmass.com/product/new-century-physics-for-queensland-
units-12-3rd-edition-richard-walding/

ebookmass.com

Saving Sorrow (Rescue Me Book 1) Kenzie Young

https://ebookmass.com/product/saving-sorrow-rescue-me-book-1-kenzie-
young/

ebookmass.com

Jews Across the Americas: A Sourcebook, 1492–Present


Adriana M. Brodsky

https://ebookmass.com/product/jews-across-the-americas-a-
sourcebook-1492-present-adriana-m-brodsky/

ebookmass.com

Her Dangerous Duke: A Steamy Second Chance Historical


Regency Romance Novel (The Duchess Deal Book 2) Tessa
Brookman
https://ebookmass.com/product/her-dangerous-duke-a-steamy-second-
chance-historical-regency-romance-novel-the-duchess-deal-book-2-tessa-
brookman/
ebookmass.com
Exercise for Frail Elders Second Edition

https://ebookmass.com/product/exercise-for-frail-elders-second-
edition/

ebookmass.com
Kubernetes
Programming
with Go
Programming Kubernetes Clients
and Operators Using Go and
the Kubernetes API

Philippe Martin
Kubernetes Programming
with Go
Programming Kubernetes Clients
and Operators Using
Go and the Kubernetes API

Philippe Martin
Kubernetes Programming with Go: Programming Kubernetes Clients and Operators
Using Go and the Kubernetes API

Philippe Martin
Blanquefort, France

ISBN-13 (pbk): 978-1-4842-9025-5 ISBN-13 (electronic): 978-1-4842-9026-2


https://doi.org/10.1007/978-1-4842-9026-2

Copyright © 2023 by Philippe Martin


This work is subject to copyright. All rights are reserved by the Publisher, whether the whole or part of the
material is concerned, specifically the rights of translation, reprinting, reuse of illustrations, recitation,
broadcasting, reproduction on microfilms or in any other physical way, and transmission or information
storage and retrieval, electronic adaptation, computer software, or by similar or dissimilar methodology now
known or hereafter developed.
Trademarked names, logos, and images may appear in this book. Rather than use a trademark symbol with
every occurrence of a trademarked name, logo, or image we use the names, logos, and images only in an
editorial fashion and to the benefit of the trademark owner, with no intention of infringement of the
trademark.
The use in this publication of trade names, trademarks, service marks, and similar terms, even if they are not
identified as such, is not to be taken as an expression of opinion as to whether or not they are subject to
proprietary rights.
While the advice and information in this book are believed to be true and accurate at the date of publication,
neither the authors nor the editors nor the publisher can accept any legal responsibility for any errors or
omissions that may be made. The publisher makes no warranty, express or implied, with respect to the
material contained herein.
Managing Director, Apress Media LLC: Welmoed Spahr
Acquisitions Editor: Divya Modi
Development Editor: James Markham
Coordinating Editor: Divya Modi
Copy Editor: Kim Burton Wiseman
Cover designed by eStudioCalamar
Cover image designed by Freepik (www.freepik.com)
Distributed to the book trade worldwide by Springer Science+Business Media New York, 1 New York Plaza,
New York, NY 10004. Phone 1-800-SPRINGER, fax (201) 348-4505, e-mail [email protected], or
visit www.springeronline.com. Apress Media, LLC is a California LLC and the sole member (owner) is
Springer Science + Business Media Finance Inc (SSBM Finance Inc). SSBM Finance Inc is a Delaware
corporation.
For information on translations, please e-mail [email protected]; for reprint,
paperback, or audio rights, please e-mail [email protected].
Apress titles may be purchased in bulk for academic, corporate, or promotional use. eBook versions and
licenses are also available for most titles. For more information, reference our Print and eBook Bulk Sales
web page at http://www.apress.com/bulk-sales.
Any source code or other supplementary material referenced by the author in this book is available to readers
on GitHub via the book's product page, located at https://github.com/Apress/Kubernetes-Programming-
with-Go-by-Philippe-Martin. For more detailed information, please visit http://www.apress.com/
source-code.
Printed on acid-free paper
To Mélina and Elsa, my constant source of truth
Table of Contents
About the Author��������������������������������������������������������������������������������������������������� xiii

About the Technical Reviewers�������������������������������������������������������������������������������xv


Acknowledgments�������������������������������������������������������������������������������������������������xvii

Introduction������������������������������������������������������������������������������������������������������������xix

Chapter 1: Kubernetes API Introduction������������������������������������������������������������������� 1


Kubernetes Platform at a Glance�������������������������������������������������������������������������������������������������� 1
OpenAPI Specification������������������������������������������������������������������������������������������������������������������� 3
Verbs and Kinds���������������������������������������������������������������������������������������������������������������������������� 5
Group-Version-Resource��������������������������������������������������������������������������������������������������������������� 6
Sub-resources������������������������������������������������������������������������������������������������������������������������������ 8
Official API Reference Documentation������������������������������������������������������������������������������������������ 9
The Deployment Documentation������������������������������������������������������������������������������������������� 10
Operations Documentation���������������������������������������������������������������������������������������������������� 12
The Pod Documentation�������������������������������������������������������������������������������������������������������� 14
One-Page Version of the Documentation������������������������������������������������������������������������������� 15
Conclusion���������������������������������������������������������������������������������������������������������������������������������� 16

Chapter 2: Kubernetes API Operations������������������������������������������������������������������� 17


Examining Requests������������������������������������������������������������������������������������������������������������������� 17
Making Requests������������������������������������������������������������������������������������������������������������������������ 18
Using kubectl as a Proxy������������������������������������������������������������������������������������������������������� 18
Creating a Resource�������������������������������������������������������������������������������������������������������������� 19
Getting Information About a Resource����������������������������������������������������������������������������������� 20
Getting the List of Resources������������������������������������������������������������������������������������������������ 20

v
Table of Contents

Filtering the Result of a List�������������������������������������������������������������������������������������������������� 21


Deleting a Resource�������������������������������������������������������������������������������������������������������������� 26
Deleting a Collection of Resources���������������������������������������������������������������������������������������� 26
Updating a Resource������������������������������������������������������������������������������������������������������������� 27
Managing Conflicts When Updating a Resource�������������������������������������������������������������������� 28
Using a Strategic Merge Patch to Update a Resource����������������������������������������������������������� 32
Applying Resources Server-side�������������������������������������������������������������������������������������������� 38
Watching Resources�������������������������������������������������������������������������������������������������������������� 44
Filtering During a Watch Session������������������������������������������������������������������������������������������� 45
Watching After Listing Resources������������������������������������������������������������������������������������������ 45
Restarting a watch Request�������������������������������������������������������������������������������������������������� 46
Allowing Bookmarks to Efficiently Restart a watch Request������������������������������������������������� 47
Paginating Results����������������������������������������������������������������������������������������������������������������� 50
Getting Results in Various Formats��������������������������������������������������������������������������������������������� 52
Getting Results as a Table����������������������������������������������������������������������������������������������������� 52
Using the YAML Format��������������������������������������������������������������������������������������������������������� 54
Using the Protobuf Format���������������������������������������������������������������������������������������������������� 54
Conclusion���������������������������������������������������������������������������������������������������������������������������������� 55

Chapter 3: Working with API Resources in Go�������������������������������������������������������� 57


API Library Sources and Import�������������������������������������������������������������������������������������������������� 57
Content of a Package������������������������������������������������������������������������������������������������������������������ 58
types.go��������������������������������������������������������������������������������������������������������������������������������� 58
register.go������������������������������������������������������������������������������������������������������������������������������ 59
doc.go������������������������������������������������������������������������������������������������������������������������������������ 60
generated.pb.go and generated.proto����������������������������������������������������������������������������������� 60
types_swagger_doc_generated.go��������������������������������������������������������������������������������������� 60
zz_generated.deepcopy.go���������������������������������������������������������������������������������������������������� 61
Specific Content in core/v1��������������������������������������������������������������������������������������������������������� 61
ObjectReference�������������������������������������������������������������������������������������������������������������������� 61
ResourceList�������������������������������������������������������������������������������������������������������������������������� 62
Taint��������������������������������������������������������������������������������������������������������������������������������������� 64

vi
Table of Contents

Toleration������������������������������������������������������������������������������������������������������������������������������� 65
Well-Known Labels���������������������������������������������������������������������������������������������������������������� 66
Writing Kubernetes Resources in Go������������������������������������������������������������������������������������������ 67
Importing the Package���������������������������������������������������������������������������������������������������������� 67
The TypeMeta Fields�������������������������������������������������������������������������������������������������������������� 68
The ObjectMeta Fields����������������������������������������������������������������������������������������������������������� 69
Spec and Status�������������������������������������������������������������������������������������������������������������������� 76
Comparison with Writing YAML Manifests����������������������������������������������������������������������������� 76
A Complete Example������������������������������������������������������������������������������������������������������������������� 78
Conclusion���������������������������������������������������������������������������������������������������������������������������������� 83

Chapter 4: Using Common Types���������������������������������������������������������������������������� 85


Pointers��������������������������������������������������������������������������������������������������������������������������������������� 85
Getting the Reference of a Value������������������������������������������������������������������������������������������� 85
Dereferencing a Pointer��������������������������������������������������������������������������������������������������������� 86
Comparing Two Referenced Values��������������������������������������������������������������������������������������� 86
Quantities������������������������������������������������������������������������������������������������������������������������������������ 87
Parsing a String as Quantity�������������������������������������������������������������������������������������������������� 87
Using an inf.Dec as a Quantity����������������������������������������������������������������������������������������������� 88
Using a Scaled Integer as a Quantity������������������������������������������������������������������������������������� 89
Operations on Quantities������������������������������������������������������������������������������������������������������� 90
IntOrString����������������������������������������������������������������������������������������������������������������������������������� 90
Time�������������������������������������������������������������������������������������������������������������������������������������������� 92
Factory Methods�������������������������������������������������������������������������������������������������������������������� 92
Operations on Time���������������������������������������������������������������������������������������������������������������� 92
Conclusion���������������������������������������������������������������������������������������������������������������������������������� 93

Chapter 5: The API Machinery�������������������������������������������������������������������������������� 95


The Schema Package����������������������������������������������������������������������������������������������������������������� 96
Scheme��������������������������������������������������������������������������������������������������������������������������������������� 97
Initialization��������������������������������������������������������������������������������������������������������������������������� 98
Mapping������������������������������������������������������������������������������������������������������������������������������� 100

vii
Table of Contents

Conversion��������������������������������������������������������������������������������������������������������������������������� 101
Serialization������������������������������������������������������������������������������������������������������������������������� 103
RESTMapper����������������������������������������������������������������������������������������������������������������������������� 105
Kind to Resource����������������������������������������������������������������������������������������������������������������� 106
Resource to Kind����������������������������������������������������������������������������������������������������������������� 107
Finding Resources��������������������������������������������������������������������������������������������������������������� 107
The DefaultRESTMapper Implementation���������������������������������������������������������������������������� 107
Conclusion�������������������������������������������������������������������������������������������������������������������������������� 108

Chapter 6: The Client-go Library��������������������������������������������������������������������������� 109


Connecting to the Cluster��������������������������������������������������������������������������������������������������������� 110
In-cluster Configuration������������������������������������������������������������������������������������������������������� 110
Out-of-Cluster Configuration����������������������������������������������������������������������������������������������� 110
Getting a Clientset��������������������������������������������������������������������������������������������������������������������� 115
Using the Clientset�������������������������������������������������������������������������������������������������������������������� 116
Examining the Requests����������������������������������������������������������������������������������������������������������� 119
Creating a Resource������������������������������������������������������������������������������������������������������������������ 120
Getting Information About a Resource�������������������������������������������������������������������������������������� 122
Getting List of Resources���������������������������������������������������������������������������������������������������������� 123
Filtering the Result of a List������������������������������������������������������������������������������������������������������ 125
Setting LabelSelector Using the Labels Package���������������������������������������������������������������� 125
Setting Fieldselector Using the Fields Package������������������������������������������������������������������ 128
Deleting a Resource������������������������������������������������������������������������������������������������������������������ 130
Deleting a Collection of Resources������������������������������������������������������������������������������������������� 133
Updating a Resource����������������������������������������������������������������������������������������������������������������� 134
Using a Strategic Merge Patch to Update a Resource�������������������������������������������������������������� 135
Applying Resources Server-side with Patch����������������������������������������������������������������������������� 138
Server-side Apply Using Apply Configurations�������������������������������������������������������������������������� 140
Building an ApplyConfiguration from Scratch���������������������������������������������������������������������� 142
Building an ApplyConfiguration from an Existing Resource������������������������������������������������ 143

viii
Table of Contents

Watching Resources����������������������������������������������������������������������������������������������������������������� 145


Errors and Statuses������������������������������������������������������������������������������������������������������������������ 149
Definition of the metav1.Status Structure��������������������������������������������������������������������������� 149
Error Returned by Clientset Operations������������������������������������������������������������������������������� 153
RESTClient�������������������������������������������������������������������������������������������������������������������������������� 154
Building the Request����������������������������������������������������������������������������������������������������������� 154
Executing the Request��������������������������������������������������������������������������������������������������������� 161
Exploiting the Result������������������������������������������������������������������������������������������������������������ 161
Getting Result as a Table����������������������������������������������������������������������������������������������������������� 162
Discovery Client������������������������������������������������������������������������������������������������������������������������ 164
RESTMapper����������������������������������������������������������������������������������������������������������������������������� 165
PriorityRESTMapper������������������������������������������������������������������������������������������������������������ 165
DeferredDiscoveryRESTMapper������������������������������������������������������������������������������������������ 167
Conclusion�������������������������������������������������������������������������������������������������������������������������������� 167

Chapter 7: Testing Applications Using Client-go�������������������������������������������������� 169


Fake Clientset��������������������������������������������������������������������������������������������������������������������������� 170
Checking the Result of the Function������������������������������������������������������������������������������������ 171
Reacting to Actions�������������������������������������������������������������������������������������������������������������� 173
Checking the Actions����������������������������������������������������������������������������������������������������������� 177
Fake REST Client����������������������������������������������������������������������������������������������������������������������� 185
FakeDiscovery Client���������������������������������������������������������������������������������������������������������������� 188
Stubbing the ServerVersion������������������������������������������������������������������������������������������������� 189
Actions��������������������������������������������������������������������������������������������������������������������������������� 190
Mocking Resources������������������������������������������������������������������������������������������������������������� 190
Conclusion�������������������������������������������������������������������������������������������������������������������������������� 191

Chapter 8: Extending Kubernetes API with Custom Resources Definitions���������� 193


Performing Operations in Go����������������������������������������������������������������������������������������������������� 194
The CustomResourceDefinition in Detail����������������������������������������������������������������������������������� 195
Naming the Resource���������������������������������������������������������������������������������������������������������� 196
Definition of the Resource Versions������������������������������������������������������������������������������������� 197
Converting Between Versions���������������������������������������������������������������������������������������������� 198
ix
Table of Contents

Schema of the Resource����������������������������������������������������������������������������������������������������������� 199


Deploying a Custom Resource Definition���������������������������������������������������������������������������������� 201
Additional Printer Columns������������������������������������������������������������������������������������������������������� 204
Conclusion�������������������������������������������������������������������������������������������������������������������������������� 207

Chapter 9: Working with Custom Resources�������������������������������������������������������� 209


Generating a Clientset��������������������������������������������������������������������������������������������������������������� 209
Using deepcopy-gen������������������������������������������������������������������������������������������������������������ 211
Using client-gen������������������������������������������������������������������������������������������������������������������ 213
Using the Generated Clientset��������������������������������������������������������������������������������������������� 216
Using the Generated fake Clientset������������������������������������������������������������������������������������� 217
Using the Unstructured Package and Dynamic Client��������������������������������������������������������������� 217
The Unstructured Type��������������������������������������������������������������������������������������������������������� 217
The UnstructuredList Type��������������������������������������������������������������������������������������������������� 221
Converting Between Typed and Unstructured Objects�������������������������������������������������������� 223
The Dynamic Client�������������������������������������������������������������������������������������������������������������� 223
Conclusion�������������������������������������������������������������������������������������������������������������������������������� 229

Chapter 10: Writing Operators withthe Controller-­Runtime Library��������������������� 231


The Manager����������������������������������������������������������������������������������������������������������������������������� 232
The Controller��������������������������������������������������������������������������������������������������������������������������� 235
Creating a Controller����������������������������������������������������������������������������������������������������������� 236
Watching Resources������������������������������������������������������������������������������������������������������������ 237
A First Example������������������������������������������������������������������������������������������������������������������� 241
Using the Controller Builder������������������������������������������������������������������������������������������������ 244
A Second Example Using the ControllerBuilder������������������������������������������������������������������� 245
Injecting Manager Resources into the Reconciler��������������������������������������������������������������� 247
Using the Client������������������������������������������������������������������������������������������������������������������������� 250
Getting Information About a Resource��������������������������������������������������������������������������������� 250
Listing Resources���������������������������������������������������������������������������������������������������������������� 251
Creating a Resource������������������������������������������������������������������������������������������������������������ 254
Deleting a Resource������������������������������������������������������������������������������������������������������������ 254

x
Table of Contents

Deleting a Collection of Resources�������������������������������������������������������������������������������������� 255


Updating a Resource����������������������������������������������������������������������������������������������������������� 256
Patching a Resource������������������������������������������������������������������������������������������������������������ 256
Updating the Status of a Resource�������������������������������������������������������������������������������������� 259
Patching the Status of a Resource�������������������������������������������������������������������������������������� 260
Logging������������������������������������������������������������������������������������������������������������������������������������� 261
Verbosity������������������������������������������������������������������������������������������������������������������������������ 262
Predefined Values���������������������������������������������������������������������������������������������������������������� 262
Logger Name����������������������������������������������������������������������������������������������������������������������� 262
Getting the Logger from Context����������������������������������������������������������������������������������������� 263
Events��������������������������������������������������������������������������������������������������������������������������������������� 263
Conclusion�������������������������������������������������������������������������������������������������������������������������������� 265

Chapter 11: Writing the Reconcile Loop��������������������������������������������������������������� 267


Writing the Reconcile Function������������������������������������������������������������������������������������������������� 268
Checking Whether the Resource Exists������������������������������������������������������������������������������� 268
Implementing the Reconciled Resource������������������������������������������������������������������������������ 268
Simple Implementation Example����������������������������������������������������������������������������������������� 270
Conclusion�������������������������������������������������������������������������������������������������������������������������������� 275

Chapter 12: Testing the Reconcile Loop��������������������������������������������������������������� 277


The envtest Package����������������������������������������������������������������������������������������������������������������� 277
Installing envtest Binaries��������������������������������������������������������������������������������������������������� 277
Using envtest����������������������������������������������������������������������������������������������������������������������� 278
Defining a ginkgo Suite������������������������������������������������������������������������������������������������������������� 279
Writing the Tests����������������������������������������������������������������������������������������������������������������������� 283
Test 1����������������������������������������������������������������������������������������������������������������������������������� 284
Test 2����������������������������������������������������������������������������������������������������������������������������������� 285
Test 3����������������������������������������������������������������������������������������������������������������������������������� 285
Test 4����������������������������������������������������������������������������������������������������������������������������������� 285
Conclusion�������������������������������������������������������������������������������������������������������������������������������� 290

xi
Table of Contents

Chapter 13: Creating an Operator with Kubebuilder�������������������������������������������� 291


Installing Kubebuilder��������������������������������������������������������������������������������������������������������������� 291
Creating a Project��������������������������������������������������������������������������������������������������������������������� 291
Adding a Custom Resource to the Project�������������������������������������������������������������������������������� 293
Building and Deploying Manifests�������������������������������������������������������������������������������������������� 295
Running the Manager Locally��������������������������������������������������������������������������������������������������� 295
Personalizing the Custom Resource����������������������������������������������������������������������������������������� 296
Editing the Go Structures���������������������������������������������������������������������������������������������������� 297
Enabling the Status Subresource���������������������������������������������������������������������������������������� 297
Defining Printer Columns����������������������������������������������������������������������������������������������������� 297
Regenerating the Files�������������������������������������������������������������������������������������������������������� 298
Implementing the Reconcile Function�������������������������������������������������������������������������������������� 299
Adding RBAC Annotations��������������������������������������������������������������������������������������������������������� 299
Deploying the Operator on the Cluster�������������������������������������������������������������������������������������� 300
Creating a New Version of the Resource����������������������������������������������������������������������������������� 301
Defining a New Version������������������������������������������������������������������������������������������������������� 302
Implementing Hub and Convertible������������������������������������������������������������������������������������� 303
Setting Up the webhook������������������������������������������������������������������������������������������������������ 305
Updating kustomization Files���������������������������������������������������������������������������������������������� 306
Using Various Versions�������������������������������������������������������������������������������������������������������� 306
Conclusion�������������������������������������������������������������������������������������������������������������������������������� 308

Index��������������������������������������������������������������������������������������������������������������������� 309

xii
About the Author
Philippe Martin has been working with Kubernetes for
five years, first by creating an Operator to deploy video
CDNs into the cloud, later helping companies deploy their
applications into Kubernetes, then writing a Client to help
developers work in a Kubernetes environment. Philippe
has passed the CKAD, CKA, and CKS certifications. He has
extensive experience with distributed systems and open-
source software: he started his career 20 years ago creating
thin clients based on the Linux kernel and open-­source
components. He is currently working at Red Hat on the
Development Tools team.
Philippe has been active in the development of Kubernetes, especially its
documentation, and participates in the translation of the official documentation into
French, has edited two reference books about the Kubernetes API and kubectl, and is
responsible for the French translation of the Kubernetes Dashboard. He participated in
Google Season of Docs to create the new Kubernetes API Reference section of the official
documentation and is maintaining it.

xiii
About the Technical Reviewers
Bartosz Majsak writes code for fun and profit while proudly
wearing a red fedora (also known as the Red Hat). He has
been long-time open-source contributor and Java developer
turned into Golang aficionado. Bartosz is overly enthusiastic
about coffee, open source, and speaking at conferences,
not necessarily in that order. One thing that perhaps proves
he is not a total geek is his addiction to alpine skiing (and
running).

Prasanth is a Blockchain Certified Professional, Professional


Scrum Master, and Microsoft Certified Trainer who is
passionate about helping others learn how to use and gain
benefits from the latest technologies. He is a thought leader
and practitioner in Blockchain, Cloud, and Scrum. He also
handles the Agile Methodology, Cloud, and Blockchain
technology community initiatives within TransUnion
through coaching, mentoring, and grooming techniques.
Prasanth is an adjunct professor and a technical speaker.
He was selected as a speaker at the China International
Industry Big Data Expo 2018 by the Chinese government and also was invited to the
International Blockchain Council by the Government of Telangana and Goa. In addition,
he received accolades from the Chinese government for his presentation at China
International Industry Big Data Expo 2018. Prasanth has published his Patent, entitled
“Digital Educational Certificate Management System Using IPFS-Based Blockchain.”
To date, he has interacted extensively, reaching more than 50,000 students,
mostly within the technical domain. Prasanth is a working group member of the
CryptoCurrency Certification Consortium, the Scrum Alliance, the Scrum Organization,
and the International Institute of Business Analysis.

xv
Acknowledgments
I would like to thank the whole Anevia “CDN” team who started working with me on
Kubernetes back in 2018: David, Ansou, Hossam, Yassine, Étienne, Jason, and Michaël.
Special thanks to Damien Lucas for initiating this project and for having trusted us with
this challenge.
My discovery of Kubernetes has been much easier and pleasant thanks to the TGIK
channel and its numerous episodes, hosted by Joe Beda, Kris Nova, and many others.
Plus, thanks to all the Kubernetes community for such a great ecosystem!

xvii
Introduction
Back in 2017, I was working for a company building video streaming software. At the end
of that year, a small team, including me, got assigned a new job to work on deploying
the Video CDN developed by the company on Kubernetes. We decided to explore the
concept of Custom Resources and Operators to deploy this CDN.
The current Kubernetes release was 1.9, the concept of Custom Resource Definition
had just been released in 1.7, and the sample-controller repository was the only
documentation we knew of to help build an Operator. The Kubernetes ecosystem,
being especially lively, had tools appearing in the following months, specifically the
Kubebuilder SDK. Thus, our project was launched.
From that moment on, I spent numerous days exploring how to build Operators and
other programs interacting with the Kubernetes API. But the damage was done: I had
started to learn Kubernetes programming from specific to general, and it took me a long
time to fully understand the innards of the Kubernetes API.
I have written this book in the hope that it can teach new Kubernetes developers how
to program, from general to specific, with the Kubernetes API in Go.

Chapters at a Glance
The target reader for this book has some experience working with REST APIs, accessing
them either by HTTP or using clients for specific languages; and has some knowledge of
the Kubernetes platform, essentially as a user—for example, some experience deploying
such APIs or frontend applications with the help of YAML manifests.

• Chapter 1 of the book explores the Kubernetes API and how it


implements the principles of REST. It especially focuses on the
Group-Version-Resource organization and the Kind concept
proposed by the API.
• Chapter 2 continues by covering the operations proposed by the API
and the details of each operation, using the HTTP protocol.

xix
Introduction

• Chapters 3 to 5 describe the common and “low-level” Go libraries to


work with the Kubernetes API: the API and API Machinery Libraries.

• Chapters 6 and 7 cover the Client-go Library—the high-level library


to work with the Kubernetes API in Go—and how to unit test code
using this library.

At this point in the book, the reader should be comfortable with building Go
applications working with native resources of the Kubernetes API.

• Chapters 8 and 9 introduce the concept of Custom Resources and


how to work with them in Go.

• Chapters 10 to 12 cover the implementation of Kubernetes Operators


using the controller-runtime library.

• Chapter 13 explores the Kubebuilder SDK, a tool to help develop and


deploy Kubernetes Operators.

By the end of the book, the reader should be able to start building Kubernetes
operators in Go and have a very good understanding of what happens behind the scenes.

xx
CHAPTER 1

Kubernetes API
Introduction
Kubernetes is a platform to orchestrate containers operating in the declarative mode.
There are one-thousand-and-one ways to describe how the Kubernetes platform is
constructed. This book focuses on programming with the platform.
The entry point of the Kubernetes platform is the API. This chapter explores the
Kubernetes architecture by highlighting the central role of the Kubernetes API. It then
focuses on the HTTP REST nature of the Kubernetes API, and on the extensions added to
organize the many resources managed by it.
Finally, you will learn how to navigate the reference documentation effectively to be
able to extract the maximum quantity of useful information daily.

Kubernetes Platform at a Glance


On one side of the chain, the user declares the high-level resources to build applications
to deploy: Deployments, Ingresses, and so on.
In the middle, controllers are activated to transform these resources into low-level
resources (Pods), and the scheduler distributes these resources into nodes. On the other
side of the chain, the node agents deploy the low-level resources onto nodes.
The main elements of the Kubernetes platform (commonly called the control-plane)
are highlighted in Figure 1-1 and described in the following:

1. The API server – this is the central point on the control-plane; the
user and the various pieces of the control-plane contact this API to
create, get, delete, update, and watch resources.

2. The etcd database – this is only accessible by the API Server, is


used to persist the data relative to resources.

1
© Philippe Martin 2023
P. Martin, Kubernetes Programming with Go, https://doi.org/10.1007/978-1-4842-9026-2_1
Chapter 1 Kubernetes API Introduction

3. The Controller manager – this runs the controllers that transform


high-level resources declared by the user into low-level resources
to be deployed on nodes. The controllers are connected to the API
Server, watching for high-level resources and creating, deleting,
and updating low-level resources to satisfy the specifications
declared in high-level resources.

4. Scheduler – this distributes the low-level resources on the various


nodes. The Scheduler is connected to the API Server to watch for
unaffected resources and connect them to nodes.

5. Kubelet – this is an agent running on all nodes of the cluster,


and each agent manages the workloads affected to its node. The
kubelet is connected to the API Server to watch for Pods resources
affected to its node and to deploy the associated containers using
the local container runtime.

6. Kube proxy – this is an agent running on all nodes of the cluster,


and each agent manages the network configurations affected to
its node. The kube proxy is connected to the API Server to watch
for Service resources and to configure associated network rules on
its node.

2
Chapter 1 Kubernetes API Introduction

etcd
Kubectl
---

Control-plane
cre
at watch
de e set
up lete,
d
Controllers
wa ate
tch
API Server crea
te
te
dele te
a
upd
tch
wa

wa ate
tch
up
d
Kubelet
watch

Scheduler
no Kube-proxy
de
s

Figure 1-1. The architecture of Kubernetes

O
 penAPI Specification
The Kubernetes API is an HTTP REST API. The Kubernetes team provides a specification
for this API in the OpenAPI format, either in v2 format at https://github.com/
kubernetes/kubernetes/tree/master/api/openapi-spec or in Kubernetes v1.24,
in v3 format, at https://github.com/kubernetes/kubernetes/tree/master/api/
openapi-spec/v3.
These specifications also are accessible from the API Server at these paths:
/openapi/v2 and /openapi/v3.
An OpenAPI specification is made up of various parts and, among these, are a list of
paths and a list of definitions. The paths are the URLs you use to request this API, and
for each path, the specification gives the distinct operations such as get, delete, or post.
Then for each operation, the specification indicates what are the parameters and body
format for the request, and what are the possible response codes and associated body
format for the response.

3
Chapter 1 Kubernetes API Introduction

The parameters and bodies for requests and responses can be either simple types
or, more generally, structures containing data. The list of definitions includes data
structures that help build the parameters and bodies for the operations’ requests and
responses.
Figure 1-2 is a simplified view of a specification for a User API. This API can accept
two different paths: /user/{userId} and /user. The first path, /user/{userId}, can accept
two operations, get and delete, respectively, to receive information about a specific user,
given its user ID; and to delete information about a specific user, given its user ID. The
second path, /user, can accept a single operation, post, to add a new user, given its
information.
In this API, a definition of a structure User is given, describing the information for a
user: its ID, first name, and last name. This data structure is used in the response body of
the get operation on the first path, and in the request body of the post operation on the
second path.

4
Chapter 1 Kubernetes API Introduction

SDWKV
XVHU^XVHU,G`
JHW
SDUDPHWHUV
XVHU,GLQWHJHU
UHTXHVW%RG\ HPSW\
UHVSRQVHV

8VHU
GHOHWH
SDUDPHWHUV
XVHU,GLQWHJHU
UHTXHVW%RG\ HPSW\
UHVSRQVHV
 HPSW\
XVHU
SRVW
SDUDPHWHUV HPSW\
UHTXHVW%RG\8VHU
UHVSRQVHV

8VHU
GHILQLWLRQV
8VHU
,'LQWHJHU
)LUVW1DPHVWULQJ
/DVW1DPHVWULQJ

Figure 1-2. A simplified user API specification

V
 erbs and Kinds
The Kubernetes API adds two concepts to this specification: the Kubernetes API Verbs
and the Kubernetes Kinds.

5
Chapter 1 Kubernetes API Introduction

The Kubernetes API Verbs are mapped directly to the operations in the OpenAPI
specification. The defined verbs are get, create, update, patch, delete, list, watch, and
deletecollection. The correspondence with the HTTP verbs can be found in Table 1-1.

Table 1-1. Correspondence Between


Kubernetes API Verbs and HTTP Verbs
Kubernetes API Verb HTTP Verb

get GET
create POST
update PUT
patch PATCH
delete DELETE
list GET
watch GET
deletecollection DELETE

The Kubernetes Kinds are a subset of the definitions in the OpenAPI specification.
When requests are made to the Kubernetes API, data structures are exchanged through
the bodies of requests and responses. These structures share common fields, apiVersion
and kind, to help the participants of the request recognize these structures.
If you wanted to make your User API manage this Kind concept, the User structure
would contain two additional fields, apiVersion and kind—for example, with values v1
and User. To determine whether a definition in the Kubernetes OpenAPI specification
is a Kubernetes Kind, you can look at the x-kubernetes-group-version-kind field of the
definition. If this field is defined, the definition is a kind, and it gives you the values of the
apiVersion and kind fields.

Group-Version-Resource
The Kubernetes API is a REST API, and as a result of that it manages Resources, and the
paths to manage these resources follow the REST naming conventions—that is, by using
a plural name to identify a resource and by grouping these resources.

6
Chapter 1 Kubernetes API Introduction

Because the Kubernetes API manages hundreds of resources, they are grouped
together, and because the API evolves, the resources are versioned. For these reasons,
each resource belongs to a given Group and Version, and each resource is uniquely
identified by a Group-Version-Resource, commonly known as GVR.
To find the various resources in the Kubernetes API, you can browse the OpenAPI
specification to extract the distinct paths. Legacy resources (e.g., pods or nodes) will
have been introduced early in the Kubernetes API and all belong to the group core and
the version v1.
The paths to manage legacy resources cluster-wide follow the format /api/
v1/<plural_resource_name>—for example, /api/v1/nodes to manage nodes. Note
that the core group is not represented in the path. To manage resources in a given
namespace, the path format is /api/v1/namespaces/<namespace_name>/<plural_
resource_name>—for example, /api/v1/namespaces/default/pods to manage pods in
the default namespace.
Newer resources are accessible through paths following the format
/apis/<group>/<version>/<plural_resource_name> or /apis/<group>/<version>/
namespaces/<namespace_name>/<plural_resource_name>.
To summarize, the formats of the various paths to access resources are:

• /api/v1/<plural_name> – to access legacy non-namespaced


resources

Ex: /api/v1/nodes to access non-namespaced nodes resources

or

To access legacy namespaced resources cluster-wide

Ex: /api/v1/pods to access pods across all namespaces

• /api/v1/namespaces/<ns>/<plural_name> – to access legacy


namespaced resources in a specific namespace

Ex: /api/v1/namespaces/default/pods to access pods in the default


namespace

• /apis/<group>/<version>/<plural_name> – to access non-­


namespaced resources in specific group and version

Ex: /apis/storage.k8s.io/v1/storageclasses to access non-­


namespaced storageclasses (group storage.k8s.io, version v1)

7
Chapter 1 Kubernetes API Introduction

or

To access namespaced resources cluster-wide

Ex: /apis/apps/v1/deployments to access deployments across all


namespaces

• /apis/<group>/<version>/namespaces/<ns>/<plural_name> – to
access namespaced resources in a specific namespace

Ex: /apis/apps/v1/namespaces/default/deployments to access


deployments (group apps, version v1) in the default namespace

Sub-resources
Following the REST API convention, the resources can have sub-resources. A sub-­
resource is a resource that belongs to another and can be accessed by specifying its
name after the name of the resource, as follows:

• /api/v1/<plural>/<res-name>/<sub-resource>
Ex: /api/v1/nodes/node1/status

• /api/v1/namespaces/<ns>/<plural>/<res-name>/<sub-resource>
Ex: /api/v1/namespaces/ns1/pods/pod1/status

• /apis/<group>/<version>/<plural>/<res-name>/<sub-resource>
Ex: /apis/storage.k8s.io/v1/volumeattachments/volatt1/status

• /apis/<grp>/<v>/namespaces/<ns>/<plural>/<name>/<sub-res>
Ex: /apis/apps/v1/namespaces/ns1/deployments/dep1/status

Most Kubernetes resources have a status sub-resource. You can see, when writing
operators, that the operator needs to update the status sub-resource to be able to
indicate the state of this resource observed by the operator. The operations that can
be executed in the status sub-resource are get, patch, and update. The Pod has more
sub-resources, including attach, binding, eviction, exec, log, portforward, and proxy.
These sub-resources are useful for getting information about a specific running pod, or
executing some specific operation on a running pod, and so on.

8
Chapter 1 Kubernetes API Introduction

The resources that can Scale (i.e., deployments, replicasets, etc.) have a scale sub-­
resource. The operations that can be executed in the scale sub-resource are get, patch,
and update.

Official API Reference Documentation


The official reference documentation of the API can be found at https://kubernetes.
io/docs/reference/kubernetes-api/. The resources managed by the API are first
grouped together by category (i.e., workloads, storage, etc.), and for each category, you
can obtain a list of resource names with a short description (Figure 1-3).

Figure 1-3. The Kubernetes resources grouped by category

Note that these categories are not part of the Kubernetes API definition but are used
in this website to help inexperienced users find their way into the multitude of available
resources.

9
Chapter 1 Kubernetes API Introduction

To be precise, the name displayed is not the resource name in the REST sense, but
the associated principal kind, as shown in Figure 1-4. For example, when managing
Pods, the resource name used in the REST paths is pods (i.e., lowercase and plural), and
the definition used to exchange information about Pods during HTTP requests is named
Pod (i.e., uppercase and singular). Note that other kinds can be associated with the same
resource. In the example in this chapter, the PodList kind (used to exchange information
about Lists of Pods) also exists.

Figure 1-4. The resources for a specific category, with a short description

The Deployment Documentation


Let’s explore the reference page for the Deployment available at this address:
https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/
deployment-v1/. The title of the page, Deployment, is the principal kind associated with
the deployments resource shown in Figure 1-5.

10
Chapter 1 Kubernetes API Introduction

Figure 1-5. The Deployment documentation page

The apiVersion indicated in the header can help you write a YAML manifest for a
Deployment resource because you need to specify, for each resource in a Kubernetes
manifest, the apiVersion and kind.
In this case, you know the manifest for a deployment will start with the following:

apiVersion: apps/v1
kind: Deployment

The next header line indicates the import to use when writing Go code. In Chapter 3,
you will see how to use this import when describing resources in Go.

After the header, a list of structure definitions is described, also accessible from the
table of contents for the Deployment documentation page in Figure 1-6. The first one is
the principal kind of the resource, optionally followed by structure definitions that are
used in fields of the first kind.

11
Chapter 1 Kubernetes API Introduction

Figure 1-6. Table of contents for the Deployment documentation page

For example, the Deployment kind contains a spec field, of type DeploymentSpec,
which is described later. Note that DeploymentSpec is not a structure directly
exchanged during HTTP requests, and for that, it is not a kind and does not contain kind
or apiVersion fields.
Following the principal kind, and its associated definitions, other kinds associated
with the resource are displayed. In this case, the DeploymentList kind.

Operations Documentation
The next subject in the API Documentation for a resource is the list of possible
operations on this resource or its sub-resources, also accessible from the table of
contents page (see Figure 1-6). By examining the details for the create operation to
Create a Deployment, as shown in Figure 1-7, you can see the HTTP Request verb and
path to use, the parameters to pass during the request, and the possible responses. The
HTTP verb to use for the request is POST and the path is ­/apis/apps/v1/namespaces/
{namespace}/deployments.

12
Chapter 1 Kubernetes API Introduction

Figure 1-7. Details for a “create” Deployment operation

The {namespace} part of the path indicates a path parameter, which is to be


replaced by the name of the namespace on which you want to create the deployment.
You can specify the query parameters: dryRun, fieldManager, fieldValidation, and
pretty. These parameters will follow the path with the format path?dryRun=All.
The body of the request must be a Deployment kind. When using kubectl, you are
writing Kubernetes Manifests that contain this body. In Chapter 3, you will see how to
build the body in Go. The possible HTTP codes for the responses are: 200, 201, 202, and
401; and for the 2xx codes, the response body will contain a Deployment kind.

13
Chapter 1 Kubernetes API Introduction

The Pod Documentation


Some structures contain many fields. For them, the Kubernetes API documentation
categorizes the fields. An example is the documentation of the Pod resource.
The documentation page for the Pod resource first contains the description for the
principal kind, Pod, followed by the description of the PodSpec structure. The PodSpec
structure contains about 40 fields. To help you understand the relationships between
these fields and to simplify their exploration, they are arranged into categories. The
PodSpec fields’ categories are the following: Containers, Volumes, Scheduling, Lifecycle,
and so on.
Additionally, for fields containing nested fields, descriptions of them are generally
displayed inline to avoid a back and forth between structure descriptions. For complex
structures, however, the description is reported subsequently on the page, and a link is
present next to the field name to be able to access it easily.
This is always the case for the Spec and Status structures because they are very
commonly found in almost all the resources. In addition, this is the case for some
structures used in the Pod kind—for example, Container, EphemeralContainer,
LifecycleHandler, NodeAffinity, and so on.
Some structures used in several resources are placed in the Common Definitions
section, and a link is present next to the field name to access it easily. In Figure 1-8, you
can see the Containers category inside the description of the PodSpec structure.

14
Chapter 1 Kubernetes API Introduction

Figure 1-8. Extract of the PodSpec structure documentation

You also can see that the fields, containers and initContainers, are of the same
type as Container, which is described later on the page and is accessible with a link.
The imagePullSecrets field is of type LocalObjectReference, which is described in the
Common Definitions section and also is accessible through a link.

One-Page Version of the Documentation


Another version of the API Reference documentation exists and is presented on a single
page. This version covers all the versions of the resources served by a Kubernretes
version (not just the latest one). This version (if you want, change the last part of the path
to navigate to another Kubernetes version) can be found at the following URL:
https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/

15
Chapter 1 Kubernetes API Introduction

Conclusion
In this chapter, you have been able to discover the architecture of the Kubernetes
platform, and that the API Server plays a central role. The Kubernetes API is an HTTP
REST API, and the resources are categorized into various versioned groups.
Kinds are specific structures used to exchange data between the API server and the
clients. You can browse, using the official Kubernetes website, the API specifications
in a human-readable form to discover the structure of the various resources and
kinds, the different operations available for each resource and sub-resource, and their
associated verbs.

16
CHAPTER 2

Kubernetes API Operations


The previous chapter described that the Kubernetes API follows REST principles and
enables users to manipulate resources.
In this chapter, you will learn how to perform various operations by making HTTP
requests directly. During your daily work, you probably will not have to interact directly
with the HTTP layer, but it is important to understand how the API works at this level so
that you can understand how to use more easily it with a higher-level library.

Examining Requests
Before starting to write your own HTTP requests, you can examine with kubectl which
requests are used when executing kubectl commands. This can be achieved by using
the verbose flag, -v, with a value greater than or equal to 6. Table 2-1 shows which
information is displayed at each level.
For example, if you want to know the URL that is called when getting pods for all
namespaces, you can use the following command:

$ kubectl get pods --all-namespaces -v6


loader.go:372] Config loaded from file:  /home/user/.kube/config
round_trippers.go:553] GET https://192.168.1.194:6443/api/v1/pods?limit=500
200 OK in 745 milliseconds

17
© Philippe Martin 2023
P. Martin, Kubernetes Programming with Go, https://doi.org/10.1007/978-1-4842-9026-2_2
Chapter 2 Kubernetes API Operations

In the output of the command, you can see that the path used is /api/v1/pods. Or,
when getting pods in a specific namespace, you can see that the path used is /api/v1/
namespaces/default/pods:

$ kubectl get pods --namespace default -v6


loader.go:372] Config loaded from file:  /home/user/.kube/config
round_trippers.go:553] GET https://192.168.1.194:6443/api/v1/namespaces/
default/pods?limit=500 200 OK in 138 milliseconds

Table 2-1. Verbosity Levels


Level Method Request Events Request Response Response Curl Body
and URL timing timing headers status headers cmd length

-v 6 yes yes – – – – – 0
-v 7 yes – – yes yes – – 0
-v 8 yes – – yes yes yes - ≤ 1024
-v 9 yes yes yes – – yes yes ≤
10240
-v 10 yes yes yes – – yes yes ∞

Making Requests
This section examines all the possible operations you can do with Kubernetes resources.

Using kubectl as a Proxy


You must be authenticated to make requests to the Kubernetes API of a cluster, unless
your cluster accepts unauthentified requests, which is unlikely.
A way to run authenticated HTTP requests is to use kubectl as a proxy to make it deal
with the authentication. For this, the kubectl proxy command can be used:

$ kubectl proxy
Starting to serve on 127.0.0.1:8001

18
Chapter 2 Kubernetes API Operations

On a new terminal, you can now run your HTTP requests without any
authentication. Next, a HOST variable to access the proxy is defined:

$ HOST=http://127.0.0.1:8001

Creating a Resource
You can create a new resource by first creating a Kubernetes manifest describing this
resource—for example, to create a Pod, you can write:

$ cat > pod.yaml <<EOF


apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - image: nginx
    name: nginx
EOF

You then need to pass the resource description into the body of a POST request (note
that the -X POST flag can be omitted because the --data-binary flag is being used). For
example, to create a pod resource use:

$ curl $HOST/api/v1/namespaces/project1/pods
    -H "Content-Type: application/yaml"
    --data-binary @pod.yaml

This is equivalent to running the kubectl command:

$ kubectl create --namespace project1 -f pod.yaml -o json

Note that the namespace is not indicated in the pod.yaml file. If you add it, you must
specify the same namespace in the YAML file and in the path, or you will get an error—
that is, the namespace of the provided object does not match the namespace sent on the
request.

19
Chapter 2 Kubernetes API Operations

Getting Information About a Resource


You can obtain information about a specific resource using a GET request and passing its
name as a parameter (and its namespace if it is a namespaced resource) in the path. In
this example, you will request the information for the pod named nginx in the project1
namespace:

$ curl -X GET
    $HOST/api/v1/namespaces/project1/pods/nginx

This will return information about the resource in the JSON format, using the kind
associated with this resource as a structure; in this example, it is a Pod kind. This is
equivalent to running the kubectl command:

$ kubectl get pods --namespace project1 nginx -o json

Getting the List of Resources


For namespaced resources, you can get the list of resources either cluster-wide or in a
specific namespace. For non-namespaced resources, you can get the list of resources. In
any case, you will use a GET request.

Cluster-wide
To get the list of resources cluster-wide, for namespaced or non-namespaced resources;
for example, for the pod resource, use the following:

$ curl $HOST/api/v1/pods

This will return information about the list of pods in all namespaces, using a PodList
kind. This is equivalent to running the kubectl command:

$ kubectl get pods --all-namespaces -o json

In a Specific namespace


To get the list of resources in a specific namespace, you need to indicate the namespace
in the path; for example, for the pod resource, use this:

$ curl $HOST/api/v1/namespaces/project1/pods

20
Chapter 2 Kubernetes API Operations

This will return information about the list of pods in the project1 namespace, using a
PodList kind. This is equivalent to running the kubectl command:

$ kubectl get pods --namespace project1 -o json

Filtering the Result of a List


When running a list request, you get as a result the complete list of resources of this kind,
in the specified namespace or cluster-wide, depending on your request.
You may want to filter the result. The most common way to filter resources in
Kubernetes is to use labels. For this, resources need to have defined labels; then, during
a list request, you can define some label selectors. It also is possible to filter resources
based on a limited set of fields by using field selectors.

Using Label Selectors


All Kubernetes resources can define labels. For example, when creating pods, you can
define some labels with kubectl:

$ kubectl run nginx1 --image nginx --labels mylabel=foo


$ kubectl run nginx2 --image nginx --labels mylabel=bar

This results in pods with labels defined in the metadata part of the resource:

$ kubectl get pods nginx1 -o yaml


apiVersion: v1
kind: Pod
metadata:
  labels:
    mylabel: foo
  name: nginx1
[...]

$ kubectl get pods nginx2 -o yaml


apiVersion: v1
kind: Pod
metadata:
  labels:

21
Chapter 2 Kubernetes API Operations

    mylabel: bar
  name: nginx2
[...]

Now, when running a list request, you can define some label selectors to filter these
resources by using the labelSelector query parameter, which can contain a comma-­
separated list of selectors.

• Select all the resources defining a specific label, no matter its value;
for example, the mylabel label:

$ curl $HOST/api/v1/namespaces/default/pods?
labelSelector=mylabel

• Select all resources not defining a specific label; for example, the
mylabel label:

$ curl $HOST/api/v1/namespaces/default/pods?
labelSelector=\!mylabel

Note the exclamation point (!) before the label name—the backslash character (\)
is being used because the exclamation point is a special character for the shell.

• Select all resources defining a label with a specific value; for example,
mylabel having the value foo:

$ curl $HOST/api/v1/namespaces/default/pods?
labelSelector=mylabel==foo

or

$ curl $HOST/api/v1/namespaces/default/pods?
labelSelector=mylabel=foo

• Select all resources defining a label with a value different from a


specific one; for example, the label mylabel having a value different
from foo:

22
Chapter 2 Kubernetes API Operations

$ curl $HOST/api/v1/namespaces/default/pods?
labelSelector=mylabel\!=foo

Note the exclamation point (!) before the equal sign (=)—the backslash character
(\) is being used because the exclamation point is a special character for the shell.

• Select all resources defining a label with a value in a set of values; for
example, the label mylabel having one of the values foo or baz:

$ curl $HOST/api/v1/namespaces/default/pods?
labelSelector=mylabel+in+(foo,baz)

Note the plus characters (+) that encodes spaces in the URL. The original selector
being: mylabel in (foo,baz).

• Select all resources defining a label with a value not in a set of


values; for example, the label mylabel having a value different from
foo or baz:

$ curl $HOST/api/v1/namespaces/default/pods?
labelSelector=mylabel+notin+(foo,baz)

Note the plus characters (+) that encodes spaces in the URL. The original selector
being: mylabel not in (foo,baz).

You can combine several selectors by separating them with a comma. This will act as
an AND operator. For example, to select all resources with a label mylabel defined and a
label otherlabel being equal to bar, you can use the following label selector:

$ curl $HOST/api/v1/namespaces/default/pods?
labelSelector=mylabel,otherlabel==bar

23
Random documents with unrelated
content Scribd suggests to you:
Opposite to Hernando stood a man equally handsome in face and
figure, equally calm and stately, but with a strange sweet light in his
eyes as they rested on the poor startled Indians standing huddled
together, scarcely knowing as yet whether to rejoice or no, at their
rescue from the hands of the Cempoallan priests.
Montoro's father had died because he dared to plead for the life of
the Jew. Montoro had a deep hidden gratitude in his heart, that he
had been thus able to offer his life for the lives of these poor helpless
Indians. And with this thanksgiving in his heart he spoke, and the
babel of confused voices ceased.
Cabrera stepped up beside his companion, saying coolly—
"Well, General, here am I also. I cannot say with Diego that I will
acknowledge the justice of the threatened punishment, or that I
would accept it, if I could see my way on any side to doing the other
thing; but—as it is—"
A shrug of the shoulders finished the sentence, and then there was a
silence. The native servant and interpreter crept to Montoro's feet,
clasping them, and entreating to be returned to the stone of sacrifice
if otherwise his deliverer must die. The native woman hid her face in
her robe, and kneeling before Cortes wept there silently.
At last Alvarado stepped forward impetuously, and exclaimed—
"Hernando Cortes, those two comrades of ours have risked their
lives to save the blood of a Christian from being poured out to the
honour of a heathen god! Is the order of a Spanish leader like the
law of the Medes and Persians—one that altereth not? Those two
have broken your command; according to that, it is admitted, their
lives are forfeited. Can it be that they are to pay the penalty!"
As he concluded with that passionate demand, a sudden brilliant
smile for one instant passed over the face of Cortes like a lightning
flash. Then it was sternly set as before, as his lips opened to reply.
The soldiers had been subsiding into quietness before, now they
were hushed into an intense expectancy that seemed as though it
could be felt. The words with which their attention was rewarded
were few enough.
"You ask me, Don Pedro de Alvarado, if those two of our Spanish
brethren yonder are to die. I say yes, if any of you, their brethren, will
shoot them. Montoro, may I crave that private audience with you that
I lost this afternoon?"
Juan de Cabrera sprang forward with raised hands, and shoulders
almost up to his ears. Even the Indians forgot their apprehensions
and laughed. He bestowed a most horrible-looking, wide-mouthed
grin upon them, and then drew his face to an almost impossible
length, as he continued his way to Cortes, groaning out—
"Oh, General! don't you please to need a private audience with me
also? That fellow, Don Gonzalo there, is quite beside himself with
longing to try the new gun he hath just received from the armourer. I
shiver with fear."
"Then take a doze of sleep to cure thee," was the laughing reply,
"and get Father Olmedo to shrive thee first for thy sin of
disobedience. I had needs be a schoolmaster rather than a general,
to rule great overgrown boys like thee."
Then Cortes turned to a quieter region of the temple, and with his
officers held deep counsel as to next proceedings. Although he
spared his two followers from the mingled motives of prudence,
friendship, and admiration, he felt somewhat bitterly that their
romantic act of generosity had greatly complicated the position of
affairs. Yesterday he had feared enmity, now he was sure of it.
"As strongly as we hold to our faith," he said gravely, "so I have ere
now discovered do they hold to theirs. As resolutely as we would
avenge an insult to our Lord, so will these heathen endeavour to
avenge the insult put upon their gods of wood and clay. We must be
prepared."
As the dawn grew full, Cortes, with his usual decisive energy,
determined suddenly to know the worst at once; not to act on the
defensive as he had first planned, but to issue forth immediately, and
complete the desecration, already so boldly begun, of the heathen
altars of Cempoalla.
"We have come hither," he exclaimed in animated tones to his
followers, "to burn the idols of this polluted land, and to raise the
sacred standard of the cross. Let us delay the glorious task no
longer. In the name of the Holy Faith I go."
"In the name of the Holy Faith lead on, we follow you," shouted back
the small, undaunted army with one acclaim; and in another minute,
in firm, close array, the Spaniards had issued forth from their
enclosure.
They had not made much way when an Indian scout flew back to
them, with heels winged with fear, to say that the Cacique himself, at
the head of his troops, was advancing to their encounter.
"All the better," muttered Cabrera. "Saves our steps, and my boots
are something the worse for wear."
But before proceeding to extremities the two leaders called a parley:
the Indian chief to expostulate on the violence done his gods in
return for his great hospitality; and Cortes to desire that he and his
subjects would hear from Father Olmedo a discourse, to prove that
his gods were no gods, that it was no more possible to do them
dishonour than to show respect or disrespect to an old tree-stump,
and to teach them the principles of Divine truth.
With a fine courtesy the Indian Cacique gave consent, even while
burning under a sense of wrong; and something he must have
gleaned through the interpreter of the required teaching, for he
replied with dignity—
"Know this, ye white-faces, that it seemeth to me we have not much
to learn from you, beyond that faithlessness that you would have us
show to our gods. We too believe in a supreme Creator and Lord of
the universe—that God by whom we live and move and have our
being; the Giver of all good gifts, almighty, omnipresent, omniscient,
perfect. We too believe in a future life—a heaven and a hell. We too
believe in the virtues of temperance, charity, self-denial; and that of
ourselves, being born in sin, we are capable of no good thing. We
too are admitted into fellowship with the supreme Lord of all things
by the rite of baptism. The lips and bosoms of our infants are
sprinkled with water, and we beseech the Lord to permit the holy
drops to wash away the sin that was given to them before the
foundation of the world, so that they may be born anew. We too pray
for grace to keep peace with all, to bear injuries with humility, trusting
to the Almighty to avenge us."
The fine old Cacique ceased, and in breathless amazement the
Spaniards gazed at the Indian who had thus made confession of a
faith so strangely in accord with their own, so utterly unexpected.
"And with these sublime truths," murmured Father Olmedo with wide
eyes, "there is mingled the awful Polytheism, the ghastly idol-
worship that revels in human sacrifices. This is verily the devil's
work, transforming himself into the likeness of an angel of light that
his worship may gain in glory."
Another thought came to Montoro de Diego. Imagination travels as
the lightning, flashing from one end of the earth to the other. As
Montoro stood there, in one of the flower-decked squares of the
Indian town of Cempoalla, his spirit was hovering above the wide
piazza of the Spanish city of Saragossa. It was the day, so
imagination told him, of an Auto da Fé.
Slowly entering the square came the long procession—priests of the
true holy Catholic faith who had learnt 'God is love,' incense-bearers,
candle-bearers, and all the troop of satellites.
In Montoro de Diego's dream-ears were sounding the solemn
cadences of the chants, as the procession moved slowly, solemnly
along. Then, in the centre of the long imposing train he saw a dismal
spectacle. Clad in the yellow garments of scorn and contumely,
adorned for shame's sake and derision with scarlet flames and so-
called devils, limped and crawled along the racked and wrenched,
and twisted and scorched victims of the Inquisition, passing along to
be burnt alive, in the name of religion, at those stakes at the four
corners of the great piazza.
And as the Romish priest, Father Olmedo, thought of the Indian idol
sacrifices, and murmured, "Verily this is the devil's work, uniting
sublime truths with the blackest iniquity," Montoro thought of the
Autos da Fé, and murmured to himself—
"If the one be the devil's work, is not the other likewise?"
At a future day the same question was asked by an Indian captive in
Spain, asked with indignant scorn, and answered by himself—
"Ay, verily. Either both are of the gods—our sacrifices of blood and
yours of fire—or both are of the devil. And ye, proud Spaniards, had
done well to purge your own land, before ye laid waste our countries,
and destroyed our nations, to remove the mote that lay in our eyes."
But we must return to Cempoalla, and pass by dreams and
dreamers for the present, for there is once more a sudden sound
and stir borne along upon the air. The Cacique and his army raise
their heads, grasp their arrows more firmly, and look expectant.
The Spaniards close up together again, lay their hands on their
sword-hilts, and wait.
CHAPTER XXXI.
ONCE FOR ALL—THEY SHALL CEASE.
The number of priests in the capital of the empire of Mexico itself
amounted, at the time of the conquest, to very many thousands—five
thousand for the immense chief teocalli, or house of God, alone.
These priests were gathered together in great establishments, where
a most rigorous discipline was maintained, much after the fashion of
Roman Catholic institutions. And as with the empire itself, so was it,
in a lesser degree, with the empire's tributaries. In those also chiefs
and people endeavoured to make their peace with heaven, as in the
old world, by such immense endowments of lands and riches as
tended naturally to swell the ranks of a race so well provided for, and
regarded with such supreme reverence.
The smiling territory of Cempoalla was as well provided as its
neighbours, with these numerous ministers of a religion that so
strangely blended bloodthirsty superstition with exalted faith and
enlightenment.
Juan de Cabrera fondly supposed that in slaying a man whom he
honestly looked upon as a murderer of the blackest die, deserving
death, he had rid that city, at any rate, of its one hideously-skilful
executioner, and, as he put it, "that no more of that sort of work could
go on for the present, either in their presence or their absence." But
he made a most tremendous mistake.
"The king is dead. Long live the king."
The priest-executioner-in-chief had fallen, before the altar of the god
he had served with such dreadful fidelity. He had died yesterday, to-
day he had a successor burning with ardour to avenge him by
increased sacrifices, to atone for those deferred, and to prove his
own consummate skill in the detestable work.
"If only," was his fierce wild prayer—"if only the one invisible,
supreme God would grant that some of the sacrilegious, infidel white
faces might fall into the hands of the Cempoallan warriors, that they
themselves might be offered up as peace-offerings to the insulted
Huitzilopotchli!"
Were his prayer granted there was no doubt that the morose and
gloomy-natured priest would not spare also to inflict upon the
prisoners some prior tortures, ingenious enough in their barbarous
cruelty to have excited the admiring envy of the most savage of
Inquisitors.
But meantime he had other business on hand—sacrifices truly, but
sacrifices drawn from the families of his own nation; and, moreover,
sacrifices of such a nature that, had he been as wise as he was
ruthless, he would have delayed their attempted offering until those
white-faces had left his land. They were just the last drops needed to
fill the Spaniards' cup of boiling indignation full to overflowing.
Exquisitely fertile and luxuriant as the whole district of Cempoalla
looked to the Spanish eyes, so wearied with the barren tracts of
sand, and marshy swamps of their recent station, there had in reality
been a considerable time of drought lately, and the Indians were
beginning to have fears for some of their harvests. Tlaloc, the god of
rain, whose symbol of a cross had so disconcerted Cabrera and
Father Olmedo, had to be propitiated.
For some days past a solemn festival had been decreed in his
honour. The victims were bought for the altar, the invitation to the
faithful was announced, and, although a priest had been slain in the
night, the imperious god of rain must not be deprived of his offerings
in the morning. Thence the sounds which had so suddenly arrested
all speech and movement of the two armies, Christian and heathen,
met together in the great square of the city.
The waiting and suspense were short. The sounds of musical
instruments and of a wild melodious chant drew rapidly nearer. They
reached the square, and the Spaniards turned wondering eyes upon
each other.
"The procession of the Fête Dieu!" exclaimed Cabrera in
bewilderment.
"One might well suppose so," returned Montoro, almost equally
surprised.
Cortes turned with rapid questionings to Doña Marina, the native
captive princess and his interpreter.
Passing across the further end of the square, on the way to Tlaloc's
temple, were lines of sable-robed priests, trains of flower-decked
youths and maidens from the priests' seminaries, crowds of devout
worshippers; and in the midst of all, borne aloft in view of every eye,
a number of lovely children, tiny creatures scarcely beyond the days
of infancy, dressed in bright-hued festal robes, wreathed with
flowers, and seated in gay litters, around each of which gathered
groups of chanting priests, and the parents who had sold them.
Wide-eyed and dumb with wonder were some of these little ones.
And on them the priests frowned. Others, startled, terrified, with tiny,
helpless arms outstretched to their miserable, deluded mothers,
were drowned in tears, choking with piteous sobbings. And on them
the priests cast pitiless smiles, and sang and danced with wilder
fervour than before. Those tears were of good omen for the god's
acceptance of his worshippers' prayers. Dry-eyed sacrifices were
fruitless ones.[7]
But the exacting god was to have no sacrifice that day, dry-eyed or
otherwise.
The procession was passing on, when at length Hernan Cortes, with
a horror-stricken shout of comprehension, raised his head from Doña
Marina, and turning to face his followers exclaimed, in a voice that
literally trembled with passion and haste:
"Comrades! look yonder. See ye that sight? See ye those helpless
babes, decked out thus bravely as the heathen nations of old were
wont to deck four-footed beasts for sacrifice? Those babes are sold
for sacrifice by a black, well-nigh incredible bigotry. Twenty minutes
hence, without your succour, their innocent hearts will have been
plucked from out their riven breasts, as offerings to that
blasphemous god who pollutes the sign of our redemption. Say,
comrades, shall this thing be?"
The men started a step forward with cheeks aflame.
"No!" exclaimed Alvarado. "By St. Jago and our good swords, no!"
"No!" echoed the whole band, as though with one voice.
"No!" cried Cabrera, impetuously. "Not if we have to put every man in
Cempoalla to the sword to deliver them."
And with these exclamations it seemed, for one moment, as though
the Spaniards were going to rush forward pell-mell, and effect a
rescue. But Cortes raised his hand and checked them. There was
time yet to proceed more peaceably. He turned back to the Cacique.
"You see," he began.
"I see there is another of those red-cloaked demons yonder,"
muttered Cabrera in a tone of bitter loathing to Montoro.
But the low aside formed no interruption to the General, who
continued, with determination—
"You see, my followers and I have one heart in this matter. And I, for
my part, am resolved that within this hour the idol gods shall be
destroyed. Use your authority to stay yonder procession on its
further course to sin, and thus hinder bloodshed."
But even before his words were ended it became evident that force
must effect, if possible, what persuasion could not do. The Cacique's
reply to the imperative demand was a swift signal to his army. It was
obeyed as swiftly.
The Indian warriors gathered up from all sides, with shrill cries and
clashing of weapons. The priests began to rush on with the litters
and their wailing occupants, towards the temple, for the
consummation of the sacrifice. The Spaniards, with Montoro de
Diego at their head, flew forward, moved to too heart-sickened a pity
to wait any longer upon the rule of orders. And soon the whole
square and the entire route to the temple was one scene of wild
uproar. The priests, in their sombre cotton robes, and dishevelled
tresses matted with blood flowing over their shoulders, rushing
frantically amongst their warrior brethren, urging them on to the fray,
and calling upon them to protect their gods from violation.
All was war and tumult where so lately had been peace and friendly
brotherhood.
Cortes took his usual prompt and decided measures. While Montoro
led the rescue party, and ceased not his determined onslaught until
he had delivered the infants back to arms that, in the new turn of
affairs, were stretched out readily enough to receive them again,
Cortes, by a bold manœuvre, and the firing off of those terror-
speaking guns, gained possession of the great Cacique himself and
of some of his principal subjects, including the chief priests.
"Now," he authoritatively commanded once more, and with a better
chance of being obeyed. "Now, Nezahualth, you and your people are
in my power. Give orders that not another arrow is shot this day, or
disobedience shall cost you all your lives."
"The gods will protect us," exclaimed a frenzied priest.
Cortes turned upon him with a cold, haughty glance.
"Did the gods protect thy brethren yesternight? The Spaniards were
two to a multitude, and the Spaniards' God gave them victory. Thy
god gave his followers up to disgrace and death!"
Whatever effect these words of reminder had upon the Totonac
priest, they had a powerful one upon the Totonac chieftain, the
Cacique of Cempoalla. With a sudden lowering of his lofty head, he
dropped his face into his hands, and exclaimed bitterly that the white
men must work their will, and the gods must avenge themselves.
"Even so," said Cortes sternly. "Thus it must be, for from this hour,
once for all, their idols shall be destroyed from this city, and the
human sacrifices shall cease."
This settled the matter. The Christians were not slow in availing
themselves of the Cacique's submission to the inevitable.
At a signal from Cortes fifty soldiers darted off to the chief temple,
sprang up the great stone stairway as eagerly as Montoro de Diego
and Cabrera had done the night before, entered the building on the
summit, the walls of which were black with human gore, tore the
huge wooden idols from their foundations, and dragged them to the
edge of the terrace.
The fantastic forms and features of these symbolic idols meant
nothing to the Spaniards' eyes but outward and visible
representations of the hideous lineaments of Satan. With the
greatest alacrity, cheered on by Cabrera, the soldiers rolled the
colossal monsters down the steps of the pyramid, amidst the
triumphant shouts of their own companions, and the groans and
lamentations of the awe-struck natives, who forthwith gave up all
hopes of the coming harvest in despair.
The work was finally crowned by the burning of the images in the
presence of the assembled, startled multitudes. That finishing touch
proved a wise one. Hitherto, during the work of desecration, the
Totonacs had waited in trembling expectation of some fearful
exhibition of their insulted god's great power and glory. But now.
Poor impotent deities! they had not been able even to prevent the
profanation of their shrines, the destruction of their own
representations.
"What think ye of your gods now?" asked Pedro de Alvarado
contemptuously, as he spurned a heap of the smouldering ashes
with his foot, and turned his scornful eyes upon a group of humbled
priests beside him.
"Verily they be fine gods," added Father Juan Diaz, ever ready to hit
those who were down. "As able, i' faith, to help ye as to assert their
own dignity."
So began the priests and people of Cempoalla, apparently, to think
themselves. With bowed heads and dejected steps they left those
humiliating mounds of ashes. The day of solemn festival was turned
into a day of turmoil and mourning.
The people of that fair land of Mexico had received their first trample
under the iron heel of the conqueror. In their abject dejection they
aided in the business of their own humiliation.
By Cortes' orders a number of the Totonacs cleansed the floor and
walls of the teocalli from their foul impurities; a fresh coating of
stucco was laid on them by the native masons, and an altar was
raised, surmounted by a lofty cross, and hung with garlands of roses.
"And now, my friends," exclaimed Cortes, addressing the multitudes
assembled around the base of the pyramid temple, watching
proceedings with a stupefied wonder—"and now, put by your sad
thoughts and your saddened countenances, for a brighter day has
dawned for you than you have ever known hitherto. I have spoilt one
procession, but I will make you full amends with another and more
glorious."
With the easy vivacity and changeableness of the semi-civilized
nature, the Indians roused up at the Spanish General's new tones of
cheerful friendship, and greeted his short speech with shouts of
approval, smiles, and nods, which received full reply. Sternness had
done its work; he was quite ready now to be as joyous and cordial
and brotherly as they would let him. They went from one extreme to
the other—from animal-like ferocity to childlike docility, owing to the
weakness of their nature. But Cortes, from the dark brows of the
resolute victor who would be obeyed, to the courteous, agreeable
friend, from policy, and an almost unequalled power of self-
command. He promised the procession, and it was soon formed.
Once more Spaniards and Indians assembled in the great square.
Side by side, no longer conqueror and captive, but host and guest
once more, moved on with calm and stately steps the two leaders,
the tall, slender Spaniard, the tall, corpulent Indian chief. Following
them came the two armies, in the same brotherly union. Then the
Totonac priests, no longer wearing their dismal black garments with
those suggestive dark-hued stains upon them, but clothed in white
robes, and, like their brother Christian priests, bearing great lighted
candles in their hands; while an image of the Virgin, little less roughly
made in those days than the idols so lately deposed, but half-
smothered under the sweet-scented, brilliant burden of flowers, was
borne aloft, and, as the procession climbed the steps of the temple,
was deposited above the altar, and a solemn mass, performed by
Father Olmedo, concluded the great ceremony, instead of a bloody
sacrifice.
"At the same time," murmured Montoro to a companion late that
night, as he paced the courtyard of the Spanish encampment—"at
the same time, methinks, these poor creatures can but credit us with
the cruel insolence of strength, which has destroyed their idols to
make way for our own. They had a cross which they adored; we
have cast it down to erect our own. They had idols which they
reverenced; we have burnt their images but to set up another."
"Even so," replied the good priest, in the same low tones. "My fears
go with your thoughts—that they must have strange doubts as to our
honesty."
"We preach against idols, and yet have them," added Montoro. "I
wonder if our work this day has done much good for the salvation of
souls?"
"It has done some good for the salvation of bodies, at any rate,"
broke in Juan de Cabrera from his sentry post, opposite to which the
two friends had paused in the interest of their conversation. "It is
thanks wholly and solely to thee, all throughout, Toro, that that
hapless little company of babies is alive to-night. And so, my long-
faced friend, instead of looking solemn as an old crow, thou shouldst
be the merriest fellow in the company."
"Ho, there!" cried the voice of a fourth comer on the scene. "Who
talks of merriment, I would know, forsooth, at this sleepy hour of the
night, and with never an honest bit of gambling allowed to pass the
watch hours by. For my part, I feel glum as a sulky bear."
"Then keep thy distance," was the retort. "For this sultry weather
makes me suspicious that my bones may be in a dried-up state, and
somewhat too easily crackable, my very esteemed Señor Velasquez
de Leon."
Montoro laughed.
"Didst say, Juan, bones or brains were crackable?"
"Both—or meant to," said the young man. "My bones, and Leon's
brains. But come, Leon, hast thou not come to relieve guard? for that
Toro there, thief that he is, robbed me of my rest last night, and I
shall fall asleep on the march to-morrow."
"Better not," replied Velasquez, with a warning shake of the head.
"Be advised in time, lest thou mightest get left behind, and then thou
wouldst assuredly be raised by the Totonac priests to the honour of
the post of one of their lost gods. Thy beauty matches to a marvel
that of their striking god of war."
"I'll match him in the striking trait on thee then, at any rate," cried
Cabrera, as he raised his arm. But the next instant it was caught,
and held fast for a moment in a good firm grip before it was let go.
"How now, my crack-brained schoolboy?" said the laughing voice of
the General. "Hast had not enough of brawls during the past day to
last thee even over one night? Keep thy blows for the turbulent
spirits we may meet on the road to Mexico."
CHAPTER XXXII.
ON THE ROAD TO MEXICO.
Such magnificent and royal gifts of gold and silver, of precious
stones and precious stuffs, of birds and animals, of jeweller's work
and the marvellous feather work, feather fans and feather tapestries,
costly shields and beautiful embroidery, had been forwarded, by the
hands of ambassadors, from the Emperor of Mexico to the Spanish
camp, that the Spaniards, from Cortes down to the meanest soldier,
had the most exalted ideas of the wealth and power of the new-
found empire.
"For my part," remarked Juan de Cabrera one day during the march
—"for my part, I have serious thoughts of giving up the worn-out old
country, and setting up my tent for the future in this new fairy-land.
Gold and fruit and flowers, and food for the trouble of accepting it,
are things just suited to my quiet tastes."
Montoro laughed.
"Few of thy friends will doubt thy word for it, Juan. But how about
that promise to thy new, bright-eyed bride, the princess of Cempoalla
—that she should reign as the queen of beauty not long hence in
thine own old city of Madrid?"
"Umph!" ejaculated Cabrera with a slight shrug. "For the promise—
well, seest thou it was no vow, bound for honour's sake to be kept—
nought but a passing word to a woman. And since she hath me, I
doubt not she will have little care for aught else."
"Hearken to him, O ye birds!" cried Alvarado. "Thy vanity doth but
outdo thy faithlessness, thou black-crested cockatoo. But knowest
thou, I shall be fairly content, for my part, when we are indeed in
Mexico's great capital, Tenochtitlan; for I grow tired of this marching
with one's head watching all ways at once during the day, and taking
sleep at night like a dog, with one eye open."
"Ay, and worse than a dog—with one's hand on one's sword
besides," added Cabrera.
Montoro raised his eyebrows as he looked from one to the other of
his companions.
"Think ye then, that once in the island city all your cares and
anxieties will be at an end?"
"If they do," put in Gonzalo de Sandoval, "I can tell them so thinks
not the General himself. Methinks, for all his assumption of cool
confidence, that his black locks grow something touched with grey of
late."
"And mine also," said Alvarado with a toss of his yellow locks. "But
from want of a siesta, and not from any dread of what these poor
helpless, red-skinned creatures are likely to do to us."
But even the bold Alvarado and the careless Cabrera felt, a few days
later, that confidence, and a feeling of security, were not much more
certain of acquirement in a town than amid the uncertain perils of the
high-way. Meantime their easy and bloodless victory at Cempoalla
had taught both officers and men, for the most part, a good-natured
contempt for the natives; and this sentiment was increased by the
friendliness hitherto shown them on their route, whenever they were
able to come fairly to speech with the Indians.
Alvarado and Cabrera in particular might be pardoned for their
impatience, at what they considered something of overmuch
watchfulness, for the sunny hair and blue eyes of the one, and the
merry face of the other, had hitherto won them smiles and
Benjamin's portions from all they met.
However, even before entering a town, the various members of that
small army were to learn that their General's prudence was wiser
than their own impatience of the discipline.
Between the territory of Cempoalla and Mexico lay the fine little
warlike, independent republic of Tlascala, governed by a council
elected by their tribes, and united by the strongest bonds of
patriotism, and mutual hatred to their powerful and aggressive
neighbour, the Emperor of Mexico.[8]
Fierce and revengeful, high-spirited and independent, Cortes
decided, as soon as he heard of them, that they were the very
auxiliaries to be desired in the contemplated conquest. For every
step he now made towards the heart of the great empire, gave him
fresh evidence of what an astoundingly bold thing he was doing, in
adventuring himself and his handful of enfeebled men in such a
magnificent enterprise.
"But with some few thousands of these enemies of Mexico, these
Tlascalans," he said one evening towards the end of August, when a
halt had been called for the night—"with their aid at our back, Diego,
we shall go forward right merrily, methinks."
Montoro looked grave. To say truth, the many human sacrifices he
had witnessed of late, and the awfully numerous traces of others
discovered along the route, had caused some temporary wavering in
his sympathies. Just for the time he was not quite sure if he did not
think his Spanish sword would, after all, be well employed in slaying
some of the bloodthirsty beings who offered up, in sacrifices to their
abominable idols, girls and boys and little children, and then held
ghastly feastings on their flesh.
He had begun to feel a loathing indignation for these wretched
believers in a gross superstition, which made him a more welcome
confidant for Cortes than was usual. He was quite ready to have his
five hundred valiant Spanish companions reinforced by a few times
that number of the natives. But he had heard news from his
interpreter, during the day's march, that made him doubtful if such a
reinforcement were altogether so likely as the General appeared to
think.
"What does thy face mean, Diego, since thy tongue says nought?"
asked Hernando Cortes after a few moments' silence. "Forgive me,
but it looks nigh as long as yon merry madcap Cabrera is wont to call
it."
Montoro smiled slightly. But he grew earnest enough the next instant
as he said—
"Cortes, I fear me that thy face also will lengthen when I tell thee that
the Tlascalans are meditating war with us, I believe, rather than
peace."
"How sayest thou, Toro?" exclaimed that impetuous fellow,
Velasquez de Leon. "Sayest thou the rascals have a mind to feel the
touch of a good Toledo blade or two? I' faith, under those
circumstances it is for them, not us, to draw the long faces, so I warn
them."
"And I warn you," said Cortes seriously, "that it is for both to do so.
But what is it that you have learnt, Diego? or rather, what reason is
given you for these worthy warriors' bad feeling? They are at such
enmity with the Mexicans, that one had some right, truly, to count
with confidence upon their friendship."
"And I fully believe would have also had it," was the reply, "had you
but given any proof that your sentiments towards this emperor bore
any likeness to their own. But——"
"Well?" came the rather impatient query; "but what? Although I have
not told the Mexicans themselves such things as should lead them to
shut their ways against us, I have let their foes know fairly well that I
am ready to aid all complainants to redress their wrongs."
"You have told them so, that is true," said Montoro, once more with a
slight smile. "The Tlascalans also admit so much; but, as they say
with some astuteness, your deeds are at variance with your words.
You have exchanged many valuable gifts with their powerful
adversary, you have entertained many of his ambassadors, and you
now propose as a friend to visit him in his capital."
"Moreover," put in Father Olmedo, "I learn from your own interpreter,
Doña Marina, that they hold us in terrible abhorrence for our hasty
and unexplained desecration of the altars of Cempoalla, a place with
which they are on terms of peace."
Cortes sprang to his feet angrily.
"That is the best deed I have performed in my life, and it shall
receive many a repetition. Preachments are no part of a soldier's
duties. It shall be mine to destroy the pollutions of the land; you,
father, can take the task of preaching it into purity with such suave
slowness as you please. Meantime, to put these rumours respecting
those Tlascalans yonder to the test. We will send an embassy
forthwith to demand a passage through their territories to Mexico."
"Send me," exclaimed Velasquez de Leon eagerly.
"And me," cried Juan de Cabrera, delighted at the prospect of real
action. He preferred using his arms to watching by them, and so did
most of his companions.
But Cortes was too politic to accept the offers. The number of his
fearless and trusty knights was small enough without risking the lives
of any of them needlessly. Some of the chief men among the
Cempoallans had accompanied the Spaniards on their march, and of
these Cortes chose out four, and sent them to their neighbours,
charged with his amicable demand.
Three or four days passed, and those messengers had not returned.
Matters began to look serious. Montoro, with his native interpreter,
and both in disguise, penetrated some distance one early morning
into the unknown dominions. They returned to the camp with the
startling intelligence that the ambassadors had been seized as
traitors to their country's cause, and renegades from the true faith,
and were within a short time to be sacrificed as peace-offerings to
the insulted gods.
Instantly the whole camp was astir. The Cempoallans tremblingly
anxious to deliver their friends from the indignity of the fate awaiting
them; Cortes strongly determined that such a blot should not fall
upon his expedition, in the person of his allies.
There was no need to urge despatch in preparations. Each man of
the force, native and Spaniard alike, was burning to set forth against
the new foe. The foe was equally ready.
But amongst these strange people of the new world were some of
the sentiments supposed to belong wholly to the old world's chivalry.
Just as the army was about to set out from its quarters, on that
morning of the thirtieth of August, 1519, a long train of people was
observed approaching from the distance, bearing an ensign of
peace.
Cortes called a halt of his own followers. He and Montoro de Diego,
and Father Olmedo, felt most thankful for the turn affairs appeared to
have taken, thus at the very twelfth hour. Alvarado and Velasquez,
with a good many of their like-minded comrades, it is true, were
nothing at all so well contented. They had been living on very short
commons the past few days, fare as meagre and unsatisfying as
possible, and they regarded the punishment of the unfriendly
republicans as a probable means of replenishing their scanty larders.
However, as it turned out, neither content nor discontent had any
present foundation. The Tlascalans had also, on their part, it was
true, sent an embassage, and a well-laden one. But, although the
messengers brought a good deal with them that was acceptable, a
request for peace was not one of the offerings.
As the train came near, it was discovered that abundant supplies of
food of all kinds were being brought to the half-famished little army.
But before they were presented, and to leave no doubt on the
Spaniards' minds as to the motives of the gift, one fierce, slim warrior
advanced before the company of food-bearers, and with a haughty,
undaunted bearing that extorted the respect even of his haughty
hearers, he exclaimed—
"See, poor starved-out creatures of a starved-out land, although we
refuse entrance to the impious enemies of our gods, we would not
that ye should think we grudge, or have need to grudge, you of the
bounties that your God, it seems, denies you.
"The Republic of Tlascala sends you food, and in abundance—meat
and bread. Eat, and be satisfied. The warriors of Tlascala scorn to
attack an enemy enfeebled with disease, faint with hunger. Victory
over such would be a vain one. We affront not our gods with
famished victims, neither do we deign to feast upon an emaciated
prey."
Welcome to our website – the ideal destination for book lovers and
knowledge seekers. With a mission to inspire endlessly, we offer a
vast collection of books, ranging from classic literary works to
specialized publications, self-development books, and children's
literature. Each book is a new journey of discovery, expanding
knowledge and enriching the soul of the reade

Our website is not just a platform for buying books, but a bridge
connecting readers to the timeless values of culture and wisdom. With
an elegant, user-friendly interface and an intelligent search system,
we are committed to providing a quick and convenient shopping
experience. Additionally, our special promotions and home delivery
services ensure that you save time and fully enjoy the joy of reading.

Let us accompany you on the journey of exploring knowledge and


personal growth!

ebookmass.com

You might also like